From f1a206ba03c5b6fba2672754d09cc649a60beeb8 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 20 Aug 2019 18:17:14 -0700 Subject: Revert "Remove sequential extension" This reverts commit 091bf4a18b2f4bf84fe62b61577c88d961468b3c. --- backends/aiger/xaiger.cc | 299 ++++++++++++++++++++++++++++++++++++---- frontends/aiger/aigerparse.cc | 35 ++++- passes/techmap/abc9.cc | 88 +++++++++--- techlibs/xilinx/abc_map.v | 97 +++++++++++++ techlibs/xilinx/abc_model.v | 89 ++++++++++++ techlibs/xilinx/abc_unmap.v | 119 ++++++++++++++++ techlibs/xilinx/abc_xc7.box | 41 ++++++ techlibs/xilinx/cells_sim.v | 24 ++-- techlibs/xilinx/synth_xilinx.cc | 6 +- 9 files changed, 730 insertions(+), 68 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 0d69e0f13..d02997da4 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -76,25 +76,32 @@ void aiger_encode(std::ostream &f, int x) struct XAigerWriter { Module *module; + bool zinit_mode; SigMap sigmap; + dict init_map; pool input_bits, output_bits; - dict not_map, alias_map; + dict not_map, ff_map, alias_map; dict> and_map; vector> ci_bits; vector> co_bits; + vector ff_bits; dict arrival_times; vector> aig_gates; - vector aig_outputs; + vector aig_latchin, aig_latchinit, aig_outputs; int aig_m = 0, aig_i = 0, aig_l = 0, aig_o = 0, aig_a = 0; dict aig_map; dict ordered_outputs; + dict ordered_latches; vector box_list; bool omode = false; + //dict init_inputs; + //int initstate_ff = 0; + int mkgate(int a0, int a1) { aig_m++, aig_a++; @@ -137,7 +144,7 @@ struct XAigerWriter return a; } - XAigerWriter(Module *module, bool holes_mode=false) : module(module), sigmap(module) + XAigerWriter(Module *module, bool zinit_mode, bool holes_mode=false) : module(module), zinit_mode(zinit_mode), sigmap(module) { pool undriven_bits; pool unused_bits; @@ -160,6 +167,14 @@ struct XAigerWriter for (auto wire : module->wires()) { + if (wire->attributes.count("\\init")) { + SigSpec initsig = sigmap(wire); + Const initval = wire->attributes.at("\\init"); + for (int i = 0; i < GetSize(wire) && i < GetSize(initval); i++) + if (initval[i] == State::S0 || initval[i] == State::S1) + init_map[initsig[i]] = initval[i] == State::S1; + } + bool keep = wire->attributes.count("\\keep"); for (int i = 0; i < GetSize(wire); i++) @@ -203,6 +218,12 @@ struct XAigerWriter // box ordering, but not individual AIG cells dict> bit_drivers, bit_users; TopoSort toposort; + struct flop_data_t { + IdString d_port; + IdString q_port; + int q_arrival; + }; + dict flop_data; bool abc_box_seen = false; for (auto cell : module->selected_cells()) { @@ -241,25 +262,86 @@ struct XAigerWriter log_assert(!holes_mode); + if (cell->type == "$__ABC_FF_") + { + SigBit D = sigmap(cell->getPort("\\D").as_bit()); + SigBit Q = sigmap(cell->getPort("\\Q").as_bit()); + unused_bits.erase(D); + undriven_bits.erase(Q); + alias_map[Q] = D; + continue; + } + RTLIL::Module* inst_module = module->design->module(cell->type); if (inst_module && inst_module->attributes.count("\\abc_box_id")) { abc_box_seen = true; - 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); + toposort.node(cell->name); + + auto r = flop_data.insert(std::make_pair(cell->type, flop_data_t{IdString(), IdString(), 0})); + if (r.second && inst_module->attributes.count("\\abc_flop")) { + IdString &abc_flop_d = r.first->second.d_port; + IdString &abc_flop_q = r.first->second.q_port; + for (auto port_name : inst_module->ports) { + auto wire = inst_module->wire(port_name); + log_assert(wire); + if (wire->attributes.count("\\abc_flop_d")) { + if (abc_flop_d != IdString()) + log_error("More than one port has the 'abc_flop_d' attribute set on module '%s'.\n", log_id(cell->type)); + abc_flop_d = port_name; + } + if (wire->attributes.count("\\abc_flop_q")) { + if (abc_flop_q != IdString()) + log_error("More than one port has the 'abc_flop_q' attribute set on module '%s'.\n", log_id(cell->type)); + abc_flop_q = port_name; + + auto it = wire->attributes.find("\\abc_arrival"); + if (it != wire->attributes.end()) { + if (it->second.flags != 0) + log_error("Attribute 'abc_arrival' on port '%s' of module '%s' is not an integer.\n", log_id(wire), log_id(cell->type)); + r.first->second.q_arrival = it->second.as_int(); + } } + } + if (abc_flop_d == IdString()) + log_error("'abc_flop_d' attribute not found on any ports on module '%s'.\n", log_id(cell->type)); + if (abc_flop_q == IdString()) + log_error("'abc_flop_q' attribute not found on any ports on module '%s'.\n", log_id(cell->type)); + } + + auto abc_flop_d = r.first->second.d_port; + if (abc_flop_d != IdString()) { + SigBit d = cell->getPort(abc_flop_d); + SigBit I = sigmap(d); + if (I != d) + alias_map[I] = d; + unused_bits.erase(d); + + auto abc_flop_q = r.first->second.q_port; + SigBit q = cell->getPort(abc_flop_q); + SigBit O = sigmap(q); + if (O != q) + alias_map[O] = q; + undriven_bits.erase(O); + ff_bits.emplace_back(q); + + auto arrival = r.first->second.q_arrival; + if (arrival) + arrival_times[q] = arrival; + } - if (port_wire->port_output) - for (auto bit : sigmap(conn.second)) - bit_drivers[bit].insert(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 (port_wire->port_output) + for (auto bit : sigmap(conn.second)) + bit_drivers[bit].insert(cell->name); } } else { @@ -466,6 +548,7 @@ struct XAigerWriter log_warning("Treating a total of %d undriven bits in %s like $anyseq.\n", GetSize(undriven_bits), log_id(module)); } + init_map.sort(); if (holes_mode) { struct sort_by_port_id { bool operator()(const RTLIL::SigBit& a, const RTLIL::SigBit& b) const { @@ -481,6 +564,7 @@ struct XAigerWriter } not_map.sort(); + ff_map.sort(); and_map.sort(); aig_map[State::S0] = 0; @@ -492,12 +576,77 @@ struct XAigerWriter aig_map[bit] = 2*aig_m; } + for (auto bit : ff_bits) { + aig_m++, aig_i++; + log_assert(!aig_map.count(bit)); + aig_map[bit] = 2*aig_m; + } + + dict ff_aig_map; for (auto &c : ci_bits) { RTLIL::SigBit bit = std::get<0>(c); aig_m++, aig_i++; - aig_map[bit] = 2*aig_m; + auto r = aig_map.insert(std::make_pair(bit, 2*aig_m)); + if (!r.second) + ff_aig_map[bit] = 2*aig_m; } + //if (zinit_mode) + //{ + // for (auto it : ff_map) { + // if (init_map.count(it.first)) + // continue; + // aig_m++, aig_i++; + // init_inputs[it.first] = 2*aig_m; + // } + //} + + //for (auto it : ff_map) { + // aig_m++, aig_l++; + // aig_map[it.first] = 2*aig_m; + // ordered_latches[it.first] = aig_l-1; + // if (init_map.count(it.first) == 0) + // aig_latchinit.push_back(2); + // else + // aig_latchinit.push_back(init_map.at(it.first) ? 1 : 0); + //} + + //if (!init_inputs.empty()) { + // aig_m++, aig_l++; + // initstate_ff = 2*aig_m+1; + // aig_latchinit.push_back(0); + //} + + //if (zinit_mode) + //{ + // for (auto it : ff_map) + // { + // int l = ordered_latches[it.first]; + + // if (aig_latchinit.at(l) == 1) + // aig_map[it.first] ^= 1; + + // if (aig_latchinit.at(l) == 2) + // { + // int gated_ffout = mkgate(aig_map[it.first], initstate_ff^1); + // int gated_initin = mkgate(init_inputs[it.first], initstate_ff); + // aig_map[it.first] = mkgate(gated_ffout^1, gated_initin^1)^1; + // } + // } + //} + + //for (auto it : ff_map) { + // int a = bit2aig(it.second); + // int l = ordered_latches[it.first]; + // if (zinit_mode && aig_latchinit.at(l) == 1) + // aig_latchin.push_back(a ^ 1); + // else + // aig_latchin.push_back(a); + //} + + //if (!init_inputs.empty()) + // aig_latchin.push_back(1); + for (auto &c : co_bits) { RTLIL::SigBit bit = std::get<0>(c); std::get<4>(c) = ordered_outputs[bit] = aig_o++; @@ -509,6 +658,11 @@ struct XAigerWriter aig_outputs.push_back(bit2aig(bit)); } + for (auto bit : ff_bits) { + aig_o++; + aig_outputs.push_back(ff_aig_map.at(bit)); + } + if (output_bits.empty()) { aig_o++; aig_outputs.push_back(0); @@ -523,6 +677,8 @@ struct XAigerWriter int aig_obcjf = aig_obcj; log_assert(aig_m == aig_i + aig_l + aig_a); + log_assert(aig_l == GetSize(aig_latchin)); + log_assert(aig_l == GetSize(aig_latchinit)); log_assert(aig_obcjf == GetSize(aig_outputs)); f << stringf("%s %d %d %d %d %d", ascii_mode ? "aag" : "aig", aig_m, aig_i, aig_l, aig_o, aig_a); @@ -533,6 +689,15 @@ struct XAigerWriter for (int i = 0; i < aig_i; i++) f << stringf("%d\n", 2*i+2); + //for (int i = 0; i < aig_l; i++) { + // if (zinit_mode || aig_latchinit.at(i) == 0) + // f << stringf("%d %d\n", 2*(aig_i+i)+2, aig_latchin.at(i)); + // else if (aig_latchinit.at(i) == 1) + // f << stringf("%d %d 1\n", 2*(aig_i+i)+2, aig_latchin.at(i)); + // else if (aig_latchinit.at(i) == 2) + // f << stringf("%d %d %d\n", 2*(aig_i+i)+2, aig_latchin.at(i), 2*(aig_i+i)+2); + //} + for (int i = 0; i < aig_obc; i++) f << stringf("%d\n", aig_outputs.at(i)); @@ -550,6 +715,15 @@ struct XAigerWriter } else { + //for (int i = 0; i < aig_l; i++) { + // if (zinit_mode || aig_latchinit.at(i) == 0) + // f << stringf("%d\n", aig_latchin.at(i)); + // else if (aig_latchinit.at(i) == 1) + // f << stringf("%d 1\n", aig_latchin.at(i)); + // else if (aig_latchinit.at(i) == 2) + // f << stringf("%d %d\n", aig_latchin.at(i), 2*(aig_i+i)+2); + //} + for (int i = 0; i < aig_obc; i++) f << stringf("%d\n", aig_outputs.at(i)); @@ -582,14 +756,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()); @@ -605,7 +779,7 @@ struct XAigerWriter //for (auto bit : output_bits) // write_o_buffer(0); - if (!box_list.empty()) { + if (!box_list.empty() || !ff_bits.empty()) { RTLIL::Module *holes_module = module->design->addModule("$__holes__"); log_assert(holes_module); @@ -671,13 +845,41 @@ 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()); + int mergeability_class = 1; + for (auto bit : ff_bits) { + write_r_buffer(mergeability_class++); + write_i_buffer(arrival_times.at(bit, 0)); + //write_o_buffer(0); + } + f << "r"; std::string buffer_str = r_buffer.str(); int32_t buffer_size_be = to_big_endian(buffer_str.size()); f.write(reinterpret_cast(&buffer_size_be), sizeof(buffer_size_be)); f.write(buffer_str.data(), buffer_str.size()); + std::stringstream s_buffer; + auto write_s_buffer = std::bind(write_buffer, std::ref(s_buffer), std::placeholders::_1); + write_s_buffer(ff_bits.size()); + for (auto bit : ff_bits) { + auto it = bit.wire->attributes.find("\\init"); + if (it != bit.wire->attributes.end()) { + auto init = it->second[bit.offset]; + if (init == RTLIL::S1) { + write_s_buffer(1); + continue; + } + } + write_s_buffer(0); + } + f << "s"; + buffer_str = s_buffer.str(); + buffer_size_be = to_big_endian(buffer_str.size()); + f.write(reinterpret_cast(&buffer_size_be), sizeof(buffer_size_be)); + f.write(buffer_str.data(), buffer_str.size()); + if (holes_module) { log_push(); @@ -713,7 +915,7 @@ struct XAigerWriter Pass::call(holes_design, "clean -purge"); std::stringstream a_buffer; - XAigerWriter writer(holes_module, true /* holes_mode */); + XAigerWriter writer(holes_module, false /*zinit_mode*/, true /* holes_mode */); writer.write_aiger(a_buffer, false /*ascii_mode*/); delete holes_design; @@ -751,7 +953,9 @@ struct XAigerWriter void write_map(std::ostream &f, bool verbose_map) { dict input_lines; + dict init_lines; dict output_lines; + dict latch_lines; dict wire_lines; for (auto wire : module->wires()) @@ -772,10 +976,30 @@ 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; + auto it = init_map.find(b); + if (it != init_map.end()) + init = it->second ? 1 : 0; + output_lines[o] += stringf("output %d %d %s %d\n", o - GetSize(co_bits), i, log_id(wire), init); continue; } + //if (init_inputs.count(sig[i])) { + // int a = init_inputs.at(sig[i]); + // log_assert((a & 1) == 0); + // init_lines[a] += stringf("init %d %d %s\n", (a >> 1)-1, i, log_id(wire)); + // continue; + //} + + //if (ordered_latches.count(sig[i])) { + // int l = ordered_latches.at(sig[i]); + // if (zinit_mode && (aig_latchinit.at(l) == 1)) + // latch_lines[l] += stringf("invlatch %d %d %s\n", l, i, log_id(wire)); + // else + // latch_lines[l] += stringf("latch %d %d %s\n", l, i, log_id(wire)); + // continue; + //} + if (verbose_map) { if (aig_map.count(sig[i]) == 0) continue; @@ -791,6 +1015,10 @@ struct XAigerWriter f << it.second; log_assert(input_lines.size() == input_bits.size()); + init_lines.sort(); + for (auto &it : init_lines) + f << it.second; + int box_count = 0; for (auto cell : box_list) f << stringf("box %d %d %s\n", box_count++, 0, log_id(cell->name)); @@ -802,6 +1030,10 @@ struct XAigerWriter if (omode && output_bits.empty()) f << "output " << output_lines.size() << " 0 $__dummy__\n"; + latch_lines.sort(); + for (auto &it : latch_lines) + f << it.second; + wire_lines.sort(); for (auto &it : wire_lines) f << it.second; @@ -822,6 +1054,10 @@ struct XAigerBackend : public Backend { log(" -ascii\n"); log(" write ASCII version of AIGER format\n"); log("\n"); + log(" -zinit\n"); + log(" convert FFs to zero-initialized FFs, adding additional inputs for\n"); + log(" uninitialized FFs.\n"); + log("\n"); log(" -map \n"); log(" write an extra file with port and latch symbols\n"); log("\n"); @@ -832,6 +1068,7 @@ struct XAigerBackend : public Backend { void execute(std::ostream *&f, std::string filename, std::vector args, RTLIL::Design *design) YS_OVERRIDE { bool ascii_mode = false; + bool zinit_mode = false; bool verbose_map = false; std::string map_filename; @@ -844,6 +1081,10 @@ struct XAigerBackend : public Backend { ascii_mode = true; continue; } + if (args[argidx] == "-zinit") { + zinit_mode = true; + continue; + } if (map_filename.empty() && args[argidx] == "-map" && argidx+1 < args.size()) { map_filename = args[++argidx]; continue; @@ -862,7 +1103,7 @@ struct XAigerBackend : public Backend { if (top_module == nullptr) log_error("Can't find top module in current design!\n"); - XAigerWriter writer(top_module); + XAigerWriter writer(top_module, zinit_mode); writer.write_aiger(*f, ascii_mode); if (!map_filename.empty()) { diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc index e8ee487e5..7a467b91e 100644 --- a/frontends/aiger/aigerparse.cc +++ b/frontends/aiger/aigerparse.cc @@ -732,12 +732,19 @@ void AigerReader::parse_aiger_binary() void AigerReader::post_process() { pool seen_boxes; - unsigned ci_count = 0, co_count = 0; + pool flops; + unsigned ci_count = 0, co_count = 0, flop_count = 0; for (auto cell : boxes) { RTLIL::Module* box_module = design->module(cell->type); log_assert(box_module); + bool is_flop = false; if (seen_boxes.insert(cell->type).second) { + if (box_module->attributes.count("\\abc_flop")) { + log_assert(flop_count < flopNum); + flops.insert(cell->type); + is_flop = true; + } auto it = box_module->attributes.find("\\abc_carry"); if (it != box_module->attributes.end()) { RTLIL::Wire *carry_in = nullptr, *carry_out = nullptr; @@ -777,6 +784,8 @@ void AigerReader::post_process() carry_out->port_id = ports.size(); } } + else + is_flop = flops.count(cell->type); // NB: Assume box_module->ports are sorted alphabetically // (as RTLIL::Module::fixup_ports() would do) @@ -803,7 +812,25 @@ void AigerReader::post_process() rhs.append(wire); } - cell->setPort(port_name, rhs); + if (!is_flop || port_name != "\\$pastQ") + cell->setPort(port_name, rhs); + } + + if (is_flop) { + RTLIL::Wire *d = outputs[outputs.size() - flopNum + flop_count]; + log_assert(d); + log_assert(d->port_output); + d->port_output = false; + + RTLIL::Wire *q = inputs[piNum - flopNum + flop_count]; + log_assert(q); + log_assert(q->port_input); + q->port_input = false; + + flop_count++; + module->connect(q, d); + cell->set_bool_attribute("\\abc_flop"); + continue; } } @@ -907,6 +934,10 @@ void AigerReader::post_process() } } log_debug(" -> %s\n", log_id(wire)); + int init; + mf >> init; + if (init < 2) + wire->attributes["\\init"] = init; } else if (type == "box") { RTLIL::Cell* cell = module->cell(stringf("$__box%d__", variable)); diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 919c4ce53..29929f80b 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -551,7 +551,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri dict abc_box; vector boxes; for (auto cell : module->selected_cells()) { - if (cell->type.in(ID($_AND_), ID($_NOT_))) { + if (cell->type.in(ID($_AND_), ID($_NOT_), ID($__ABC_FF_))) { module->remove(cell); continue; } @@ -651,6 +651,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri cell->attributes = mapped_cell->attributes; } + auto abc_flop = mapped_cell->attributes.count("\\abc_flop"); for (auto &conn : mapped_cell->connections()) { RTLIL::SigSpec newsig; for (auto c : conn.second.chunks()) { @@ -663,15 +664,17 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri } cell->setPort(conn.first, newsig); - if (cell->input(conn.first)) { - for (auto i : newsig) - bit2sinks[i].push_back(cell); - for (auto i : conn.second) - bit_users[i].insert(mapped_cell->name); + if (!abc_flop) { + if (cell->input(conn.first)) { + for (auto i : newsig) + bit2sinks[i].push_back(cell); + for (auto i : conn.second) + bit_users[i].insert(mapped_cell->name); + } + if (cell->output(conn.first)) + for (auto i : conn.second) + bit_drivers[i].insert(mapped_cell->name); } - if (cell->output(conn.first)) - for (auto i : conn.second) - bit_drivers[i].insert(mapped_cell->name); } } @@ -1167,6 +1170,7 @@ struct Abc9Pass : public Pass { assign_map.set(mod); if (!dff_mode || !clk_str.empty()) { + design->selection_stack.emplace_back(false); RTLIL::Selection& sel = design->selection_stack.back(); sel.select(mod); @@ -1194,6 +1198,13 @@ struct Abc9Pass : public Pass { std::map> cell_to_bit, cell_to_bit_up, cell_to_bit_down; std::map> bit_to_cell, bit_to_cell_up, bit_to_cell_down; + pool seen_cells; + struct flop_data_t { + IdString clk_port; + IdString en_port; + }; + dict flop_data; + for (auto cell : all_cells) { clkdomain_t key; @@ -1214,20 +1225,57 @@ struct Abc9Pass : public Pass { } } - 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()); + decltype(flop_data)::iterator it; + if (seen_cells.insert(cell->type).second) { + RTLIL::Module* inst_module = design->module(cell->type); + if (!inst_module) + continue; + + if (!inst_module->attributes.count("\\abc_flop")) + continue; + + IdString abc_flop_clk, abc_flop_en; + for (auto port_name : inst_module->ports) { + auto wire = inst_module->wire(port_name); + log_assert(wire); + if (wire->attributes.count("\\abc_flop_clk")) { + if (abc_flop_clk != IdString()) + log_error("More than one port has the 'abc_flop_clk' attribute set on module '%s'.\n", log_id(cell->type)); + abc_flop_clk = port_name; + } + if (wire->attributes.count("\\abc_flop_en")) { + if (abc_flop_en != IdString()) + log_error("More than one port has the 'abc_flop_en' attribute set on module '%s'.\n", log_id(cell->type)); + abc_flop_en = port_name; + } + } + + if (abc_flop_clk == IdString()) + log_error("'abc_flop_clk' attribute not found on any ports on module '%s'.\n", log_id(cell->type)); + if (abc_flop_en == IdString()) + log_error("'abc_flop_en' attribute not found on any ports on module '%s'.\n", log_id(cell->type)); + + it = flop_data.insert(std::make_pair(cell->type, flop_data_t{abc_flop_clk, abc_flop_en})).first; } - 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 { + it = flop_data.find(cell->type); + if (it == flop_data.end()) + continue; } - else - continue; + const auto &data = it->second; + + auto jt = cell->parameters.find("\\CLK_POLARITY"); + if (jt == cell->parameters.end()) + log_error("'CLK_POLARITY' is not a parameter on module '%s'.\n", log_id(cell->type)); + bool this_clk_pol = jt->second.as_bool(); + + jt = cell->parameters.find("\\EN_POLARITY"); + if (jt == cell->parameters.end()) + log_error("'EN_POLARITY' is not a parameter on module '%s'.\n", log_id(cell->type)); + bool this_en_pol = jt->second.as_bool(); + + key = clkdomain_t(this_clk_pol, assign_map(cell->getPort(data.clk_port)), this_en_pol, assign_map(cell->getPort(data.en_port))); unassigned_cells.erase(cell); expand_queue.insert(cell); diff --git a/techlibs/xilinx/abc_map.v b/techlibs/xilinx/abc_map.v index 121862692..a760b3d6d 100644 --- a/techlibs/xilinx/abc_map.v +++ b/techlibs/xilinx/abc_map.v @@ -20,6 +20,103 @@ // ============================================================================ +module FDRE (output reg Q, input C, CE, D, R); + parameter [0:0] INIT = 1'b0; + parameter [0:0] IS_C_INVERTED = 1'b0; + parameter [0:0] IS_D_INVERTED = 1'b0; + parameter [0:0] IS_R_INVERTED = 1'b0; + wire \$nextQ ; + \$__ABC_FDRE #( + .INIT(INIT), + .IS_C_INVERTED(IS_C_INVERTED), + .IS_D_INVERTED(IS_D_INVERTED), + .IS_R_INVERTED(IS_R_INVERTED), + .CLK_POLARITY(!IS_C_INVERTED), + .EN_POLARITY(1'b1) + ) _TECHMAP_REPLACE_ ( + .D(D), .Q(\$nextQ ), .\$pastQ (Q), .C(C), .CE(CE), .R(R) + ); + \$__ABC_FF_ abc_dff (.D(\$nextQ ), .Q(Q)); +endmodule +module FDRE_1 (output reg Q, input C, CE, D, R); + parameter [0:0] INIT = 1'b0; + wire \$nextQ ; + \$__ABC_FDRE_1 #( + .INIT(|0), + .CLK_POLARITY(1'b0), + .EN_POLARITY(1'b1) + ) _TECHMAP_REPLACE_ ( + .D(D), .Q(\$nextQ ), .\$pastQ (Q), .C(C), .CE(CE), .R(R) + ); + \$__ABC_FF_ abc_dff (.D(\$nextQ ), .Q(Q)); +endmodule + +module FDCE (output reg Q, input C, CE, D, CLR); + parameter [0:0] INIT = 1'b0; + parameter [0:0] IS_C_INVERTED = 1'b0; + parameter [0:0] IS_D_INVERTED = 1'b0; + parameter [0:0] IS_CLR_INVERTED = 1'b0; + wire \$nextQ , \$currQ ; + \$__ABC_FDCE #( + .INIT(INIT), + .IS_C_INVERTED(IS_C_INVERTED), + .IS_D_INVERTED(IS_D_INVERTED), + .IS_CLR_INVERTED(IS_CLR_INVERTED), + .CLK_POLARITY(!IS_C_INVERTED), + .EN_POLARITY(1'b1) + ) _TECHMAP_REPLACE_ ( + .D(D), .Q(\$nextQ ), .\$pastQ (Q), .C(C), .CE(CE), .CLR(CLR) + ); + \$__ABC_FF_ abc_dff (.D(\$nextQ ), .Q(\$currQ )); + \$__ABC_ASYNC abc_async (.A(\$currQ ), .S(CLR), .Y(Q)); +endmodule +module FDCE_1 (output reg Q, input C, CE, D, CLR); + parameter [0:0] INIT = 1'b0; + wire \$nextQ , \$currQ ; + \$__ABC_FDCE_1 #( + .INIT(INIT), + .CLK_POLARITY(1'b0), + .EN_POLARITY(1'b1) + ) _TECHMAP_REPLACE_ ( + .D(D), .Q(\$nextQ ), .\$pastQ (Q), .C(C), .CE(CE), .CLR(CLR) + ); + \$__ABC_FF_ abc_dff (.D(\$nextQ ), .Q(\$currQ )); + \$__ABC_ASYNC abc_async (.A(\$currQ ), .S(CLR), .Y(Q)); +endmodule + +module FDPE (output reg Q, input C, CE, D, PRE); + parameter [0:0] INIT = 1'b0; + parameter [0:0] IS_C_INVERTED = 1'b0; + parameter [0:0] IS_D_INVERTED = 1'b0; + parameter [0:0] IS_PRE_INVERTED = 1'b0; + wire \$nextQ , \$currQ ; + \$__ABC_FDPE #( + .INIT(INIT), + .IS_C_INVERTED(IS_C_INVERTED), + .IS_D_INVERTED(IS_D_INVERTED), + .IS_PRE_INVERTED(IS_PRE_INVERTED), + .CLK_POLARITY(!IS_C_INVERTED), + .EN_POLARITY(1'b1) + ) _TECHMAP_REPLACE_ ( + .D(D), .Q(\$nextQ ), .\$pastQ (Q), .C(C), .CE(CE), .PRE(PRE) + ); + \$__ABC_FF_ abc_dff (.D(\$nextQ ), .Q(\$currQ )); + \$__ABC_ASYNC abc_async (.A(\$currQ ), .S(PRE), .Y(Q)); +endmodule +module FDPE_1 (output reg Q, input C, CE, D, PRE); + parameter [0:0] INIT = 1'b0; + wire \$nextQ , \$currQ ; + \$__ABC_FDPE_1 #( + .INIT(INIT), + .CLK_POLARITY(1'b0), + .EN_POLARITY(1'b1) + ) _TECHMAP_REPLACE_ ( + .D(D), .Q(\$nextQ ), .\$pastQ (Q), .C(C), .CE(CE), .PRE(PRE) + ); + \$__ABC_FF_ abc_dff (.D(\$nextQ ), .Q(\$currQ )); + \$__ABC_ASYNC abc_async (.A(\$currQ ), .S(PRE), .Y(Q)); +endmodule + module RAM32X1D ( output DPO, SPO, input D, diff --git a/techlibs/xilinx/abc_model.v b/techlibs/xilinx/abc_model.v index e3e9686b5..7162bd213 100644 --- a/techlibs/xilinx/abc_model.v +++ b/techlibs/xilinx/abc_model.v @@ -26,6 +26,94 @@ module \$__XILINX_MUXF78 (output O, input I0, I1, I2, I3, S0, S1); : (S0 ? I1 : I0); endmodule +module \$__ABC_FF_ (input C, D, output Q); +endmodule + +(* abc_box_id = 1000 *) +module \$__ABC_ASYNC (input A, S, output Y); +endmodule + +(* abc_box_id=1001, lib_whitebox, abc_flop *) +module \$__ABC_FDRE ((* abc_flop_q, abc_arrival=303 *) output Q, + (* abc_flop_clk *) input C, + (* abc_flop_en *) input CE, + (* abc_flop_d *) input D, + input R, \$pastQ ); + parameter [0:0] INIT = 1'b0; + parameter [0:0] IS_C_INVERTED = 1'b0; + parameter [0:0] IS_D_INVERTED = 1'b0; + parameter [0:0] IS_R_INVERTED = 1'b0; + parameter CLK_POLARITY = !IS_C_INVERTED; + parameter EN_POLARITY = 1'b1; + assign Q = (R ^ IS_R_INVERTED) ? 1'b0 : (CE ? (D ^ IS_D_INVERTED) : \$pastQ ); +endmodule + +(* abc_box_id=1002, lib_whitebox, abc_flop *) +module \$__ABC_FDRE_1 ((* abc_flop_q, abc_arrival=303 *) output Q, + (* abc_flop_clk *) input C, + (* abc_flop_en *) input CE, + (* abc_flop_d *) input D, + input R, \$pastQ ); + parameter [0:0] INIT = 1'b0; + parameter CLK_POLARITY = 1'b0; + parameter EN_POLARITY = 1'b1; + assign Q = R ? 1'b0 : (CE ? D : \$pastQ ); +endmodule + +(* abc_box_id=1003, lib_whitebox, abc_flop *) +module \$__ABC_FDCE ((* abc_flop_q, abc_arrival=303 *) output Q, + (* abc_flop_clk *) input C, + (* abc_flop_en *) input CE, + (* abc_flop_d *) input D, + input CLR, \$pastQ ); + parameter [0:0] INIT = 1'b0; + parameter [0:0] IS_C_INVERTED = 1'b0; + parameter [0:0] IS_D_INVERTED = 1'b0; + parameter [0:0] IS_CLR_INVERTED = 1'b0; + parameter CLK_POLARITY = !IS_C_INVERTED; + parameter EN_POLARITY = 1'b1; + assign Q = (CE && !(CLR ^ IS_CLR_INVERTED)) ? (D ^ IS_D_INVERTED) : \$pastQ ; +endmodule + +(* abc_box_id=1004, lib_whitebox, abc_flop *) +module \$__ABC_FDCE_1 ((* abc_flop_q, abc_arrival=303 *) output Q, + (* abc_flop_clk *) input C, + (* abc_flop_en *) input CE, + (* abc_flop_d *) input D, + input CLR, \$pastQ ); + parameter [0:0] INIT = 1'b0; + parameter CLK_POLARITY = 1'b0; + parameter EN_POLARITY = 1'b1; + assign Q = (CE && !CLR) ? D : \$pastQ ; +endmodule + +(* abc_box_id=1005, lib_whitebox, abc_flop *) +module \$__ABC_FDPE ((* abc_flop_q, abc_arrival=303 *) output Q, + (* abc_flop_clk *) input C, + (* abc_flop_en *) input CE, + (* abc_flop_d *) input D, + input PRE, \$pastQ ); + parameter [0:0] INIT = 1'b0; + parameter [0:0] IS_C_INVERTED = 1'b0; + parameter [0:0] IS_D_INVERTED = 1'b0; + parameter [0:0] IS_PRE_INVERTED = 1'b0; + parameter CLK_POLARITY = !IS_C_INVERTED; + parameter EN_POLARITY = 1'b1; + assign Q = (CE && !(PRE ^ IS_PRE_INVERTED)) ? (D ^ IS_D_INVERTED) : \$pastQ ; +endmodule + +(* abc_box_id=1006, lib_whitebox, abc_flop *) +module \$__ABC_FDPE_1 ((* abc_flop_q, abc_arrival=303 *) output Q, + (* abc_flop_clk *) input C, + (* abc_flop_en *) input CE, + (* abc_flop_d *) input D, + input PRE, \$pastQ ); + parameter [0:0] INIT = 1'b0; + parameter CLK_POLARITY = 1'b0; + parameter EN_POLARITY = 1'b1; + assign Q = (CE && !PRE) ? D : \$pastQ ; +endmodule + (* abc_box_id=2000 *) module \$__ABC_LUTMUX6 (input A, input [5:0] S, output Y); endmodule @@ -33,6 +121,7 @@ endmodule module \$__ABC_LUTMUX7 (input A, input [6:0] S, output Y); endmodule + module \$__ABC_RAM32X1D ( // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L957 (* abc_arrival=1153 *) output DPO, SPO, diff --git a/techlibs/xilinx/abc_unmap.v b/techlibs/xilinx/abc_unmap.v index 779fc5aac..d00d27e2e 100644 --- a/techlibs/xilinx/abc_unmap.v +++ b/techlibs/xilinx/abc_unmap.v @@ -20,6 +20,125 @@ // ============================================================================ +module \$__ABC_ASYNC (input A, S, output Y); + assign Y = A; +endmodule + +module \$__ABC_FDRE (output Q, + input C, + input CE, + input D, + input R, \$pastQ ); + parameter [0:0] INIT = 1'b0; + parameter [0:0] IS_C_INVERTED = 1'b0; + parameter [0:0] IS_D_INVERTED = 1'b0; + parameter [0:0] IS_R_INVERTED = 1'b0; + parameter CLK_POLARITY = !IS_C_INVERTED; + parameter EN_POLARITY = 1'b1; + + FDRE #( + .INIT(INIT), + .IS_C_INVERTED(IS_C_INVERTED), + .IS_D_INVERTED(IS_D_INVERTED), + .IS_R_INVERTED(IS_R_INVERTED), + ) _TECHMAP_REPLACE_ ( + .D(D), .Q(Q), .C(C), .CE(CE), .R(R) + ); +endmodule + +module \$__ABC_FDRE_1 (output Q, + input C, + input CE, + input D, + input R, \$pastQ ); + parameter [0:0] INIT = 1'b0; + parameter CLK_POLARITY = 1'b0; + parameter EN_POLARITY = 1'b1; + assign Q = R ? 1'b0 : (CE ? D : \$pastQ ); + + FDRE_1 #( + .INIT(INIT), + ) _TECHMAP_REPLACE_ ( + .D(D), .Q(Q), .C(C), .CE(CE), .R(R) + ); +endmodule + +module \$__ABC_FDCE (output Q, + input C, + input CE, + input D, + input CLR, \$pastQ ); + parameter [0:0] INIT = 1'b0; + parameter [0:0] IS_C_INVERTED = 1'b0; + parameter [0:0] IS_D_INVERTED = 1'b0; + parameter [0:0] IS_CLR_INVERTED = 1'b0; + parameter CLK_POLARITY = !IS_C_INVERTED; + parameter EN_POLARITY = 1'b1; + + FDCE #( + .INIT(INIT), + .IS_C_INVERTED(IS_C_INVERTED), + .IS_D_INVERTED(IS_D_INVERTED), + .IS_CLR_INVERTED(IS_CLR_INVERTED), + ) _TECHMAP_REPLACE_ ( + .D(D), .Q(Q), .C(C), .CE(CE), .CLR(CLR) + ); +endmodule + +module \$__ABC_FDCE_1 (output Q, + input C, + input CE, + input D, + input CLR, \$pastQ ); + parameter [0:0] INIT = 1'b0; + parameter CLK_POLARITY = 1'b0; + parameter EN_POLARITY = 1'b1; + + FDCE_1 #( + .INIT(INIT), + ) _TECHMAP_REPLACE_ ( + .D(D), .Q(Q), .C(C), .CE(CE), .CLR(CLR) + ); +endmodule + +module \$__ABC_FDPE (output Q, + input C, + input CE, + input D, + input PRE, \$pastQ ); + parameter [0:0] INIT = 1'b0; + parameter [0:0] IS_C_INVERTED = 1'b0; + parameter [0:0] IS_D_INVERTED = 1'b0; + parameter [0:0] IS_PRE_INVERTED = 1'b0; + parameter CLK_POLARITY = !IS_C_INVERTED; + parameter EN_POLARITY = 1'b1; + + FDPE #( + .INIT(INIT), + .IS_C_INVERTED(IS_C_INVERTED), + .IS_D_INVERTED(IS_D_INVERTED), + .IS_PRE_INVERTED(IS_PRE_INVERTED), + ) _TECHMAP_REPLACE_ ( + .D(D), .Q(Q), .C(C), .CE(CE), .PRE(PRE) + ); +endmodule + +module \$__ABC_FDPE_1 (output Q, + input C, + input CE, + input D, + input PRE, \$pastQ ); + parameter [0:0] INIT = 1'b0; + parameter CLK_POLARITY = 1'b0; + parameter EN_POLARITY = 1'b1; + + FDPE_1 #( + .INIT(INIT), + ) _TECHMAP_REPLACE_ ( + .D(D), .Q(Q), .C(C), .CE(CE), .PRE(PRE) + ); +endmodule + module \$__ABC_LUTMUX6 (input A, input [5:0] S, output Y); assign Y = A; endmodule diff --git a/techlibs/xilinx/abc_xc7.box b/techlibs/xilinx/abc_xc7.box index 61b89b8af..c08af6320 100644 --- a/techlibs/xilinx/abc_xc7.box +++ b/techlibs/xilinx/abc_xc7.box @@ -38,6 +38,47 @@ CARRY4 4 1 10 8 592 540 520 356 - 512 548 292 - 228 580 526 507 398 385 508 528 378 380 114 +# Box to emulate async behaviour of FD[CP]* +# Inputs: A S +# Outputs: Y +$__ABC_ASYNC 1000 0 2 1 +0 764 + +# The following FD*.{CE,R,CLR,PRE) are offset by 46ps to +# reflect the -46ps Tsu +# https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L237-L251 +# https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L265-L277 + +# Inputs: C CE D R \$pastQ +# Outputs: Q +FDRE 1001 1 5 1 +0 151 0 446 0 + +# Inputs: C CE D R \$pastQ +# Outputs: Q +FDRE_1 1002 1 5 1 +0 151 0 446 0 + +# Inputs: C CE CLR D \$pastQ +# Outputs: Q +FDCE 1003 1 5 1 +0 151 806 0 0 + +# Inputs: C CE CLR D \$pastQ +# Outputs: Q +FDCE_1 1004 1 5 1 +0 151 806 0 0 + +# Inputs: C CE D PRE \$pastQ +# Outputs: Q +FDPE 1005 1 5 1 +0 151 0 806 0 + +# Inputs: C CE D PRE \$pastQ +# Outputs: Q +FDPE_1 1006 1 5 1 +0 151 0 806 0 + # SLICEM/A6LUT # Box to emulate comb/seq behaviour of RAMD{32,64} and SRL{16,32} # Inputs: A S0 S1 S2 S3 S4 S5 diff --git a/techlibs/xilinx/cells_sim.v b/techlibs/xilinx/cells_sim.v index d879a56ee..1ab718ccc 100644 --- a/techlibs/xilinx/cells_sim.v +++ b/techlibs/xilinx/cells_sim.v @@ -211,8 +211,7 @@ endmodule `endif -module FDRE ((* abc_arrival=303 *) output reg Q, - input C, CE, D, R); +module FDRE (output reg Q, input C, CE, D, R); parameter [0:0] INIT = 1'b0; parameter [0:0] IS_C_INVERTED = 1'b0; parameter [0:0] IS_D_INVERTED = 1'b0; @@ -224,8 +223,7 @@ module FDRE ((* abc_arrival=303 *) output reg Q, endcase endgenerate endmodule -module FDSE ((* abc_arrival=303 *) output reg Q, - input C, CE, D, S); +module FDSE (output reg Q, input C, CE, D, S); parameter [0:0] INIT = 1'b1; parameter [0:0] IS_C_INVERTED = 1'b0; parameter [0:0] IS_D_INVERTED = 1'b0; @@ -237,8 +235,7 @@ module FDSE ((* abc_arrival=303 *) output reg Q, endcase endgenerate endmodule -module FDCE ((* abc_arrival=303 *) output reg Q, - input C, CE, D, CLR); +module FDCE (output reg Q, input C, CE, D, CLR); parameter [0:0] INIT = 1'b0; parameter [0:0] IS_C_INVERTED = 1'b0; parameter [0:0] IS_D_INVERTED = 1'b0; @@ -252,8 +249,7 @@ module FDCE ((* abc_arrival=303 *) output reg Q, endcase endgenerate endmodule -module FDPE ((* abc_arrival=303 *) output reg Q, - input C, CE, D, PRE); +module FDPE (output reg Q, input C, CE, D, PRE); parameter [0:0] INIT = 1'b1; parameter [0:0] IS_C_INVERTED = 1'b0; parameter [0:0] IS_D_INVERTED = 1'b0; @@ -267,29 +263,25 @@ module FDPE ((* abc_arrival=303 *) output reg Q, endcase endgenerate endmodule -module FDRE_1 ((* abc_arrival=303 *) output reg Q, - input C, CE, D, R); +module FDRE_1 (output reg Q, input C, CE, D, R); parameter [0:0] INIT = 1'b0; initial Q <= INIT; always @(negedge C) if (R) Q <= 1'b0; else if(CE) Q <= D; endmodule -module FDSE_1 ((* abc_arrival=303 *) output reg Q, - input C, CE, D, S); +module FDSE_1 (output reg Q, input C, CE, D, S); parameter [0:0] INIT = 1'b1; initial Q <= INIT; always @(negedge C) if (S) Q <= 1'b1; else if(CE) Q <= D; endmodule -module FDCE_1 ((* abc_arrival=303 *) output reg Q, - input C, CE, D, CLR); +module FDCE_1 (output reg Q, input C, CE, D, CLR); parameter [0:0] INIT = 1'b0; initial Q <= INIT; always @(negedge C, posedge CLR) if (CLR) Q <= 1'b0; else if (CE) Q <= D; endmodule -module FDPE_1 ((* abc_arrival=303 *) output reg Q, - input C, CE, D, PRE); +module FDPE_1 (output reg Q, input C, CE, D, PRE); parameter [0:0] INIT = 1'b1; initial Q <= INIT; always @(negedge C, posedge PRE) if (PRE) Q <= 1'b1; else if (CE) Q <= D; diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index b9c4df82f..d28cd2428 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -379,6 +379,8 @@ struct SynthXilinxPass : public ScriptPass std::string techmap_args = "-map +/techmap.v -map +/xilinx/cells_map.v"; if (widemux > 0) techmap_args += stringf(" -D MIN_MUX_INPUTS=%d", widemux); + if (abc9) + techmap_args += " -map +/xilinx/ff_map.v"; run("techmap " + techmap_args); run("clean"); } @@ -409,9 +411,11 @@ struct SynthXilinxPass : public ScriptPass // has performed any necessary retiming if (!nosrl || help_mode) run("shregmap -minlen 3 -init -params -enpol any_or_none", "(skip if '-nosrl')"); - std::string techmap_args = "-map +/xilinx/lut_map.v -map +/xilinx/ff_map.v"; + std::string techmap_args = "-map +/xilinx/lut_map.v"; if (abc9) techmap_args += " -map +/xilinx/abc_unmap.v"; + else + techmap_args += " -map +/xilinx/ff_map.v"; run("techmap " + techmap_args); run("dffinit -ff FDRE Q INIT -ff FDCE Q INIT -ff FDPE Q INIT -ff FDSE Q INIT " "-ff FDRE_1 Q INIT -ff FDCE_1 Q INIT -ff FDPE_1 Q INIT -ff FDSE_1 Q INIT"); -- cgit v1.2.3 From 11cb5fab004c005c6d674494b1486ee501037c5c Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 27 Sep 2019 17:00:19 -0700 Subject: Fix typo --- kernel/rtlil.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 1d380135b..f42f5430f 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1528,7 +1528,7 @@ std::vector RTLIL::Module::selected_wires() const std::vector RTLIL::Module::selected_cells() const { std::vector result; - result.reserve(wires_.size()); + result.reserve(cells_.size()); for (auto &it : cells_) if (design->selected(this, it.second)) result.push_back(it.second); -- cgit v1.2.3 From fe722b737ce3dfd359d4f37fb558371c07e6a19c Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 27 Sep 2019 17:44:01 -0700 Subject: Add -select option to aigmap --- passes/techmap/aigmap.cc | 46 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 40 insertions(+), 6 deletions(-) diff --git a/passes/techmap/aigmap.cc b/passes/techmap/aigmap.cc index 1d5e1286b..2ecb2f35a 100644 --- a/passes/techmap/aigmap.cc +++ b/passes/techmap/aigmap.cc @@ -27,6 +27,7 @@ struct AigmapPass : public Pass { AigmapPass() : Pass("aigmap", "map logic to and-inverter-graph circuit") { } void help() YS_OVERRIDE { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); log(" aigmap [options] [selection]\n"); log("\n"); @@ -36,10 +37,15 @@ struct AigmapPass : public Pass { log(" -nand\n"); log(" Enable creation of $_NAND_ cells\n"); log("\n"); + log(" -select\n"); + log(" Overwrite replaced cells in the current selection with new $_AND_,\n"); + log(" $_NOT_, and $_NAND_, cells\n"); + + log("\n"); } void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE { - bool nand_mode = false; + bool nand_mode = false, select_mode = false; log_header(design, "Executing AIGMAP pass (map logic to AIG).\n"); @@ -50,6 +56,10 @@ struct AigmapPass : public Pass { nand_mode = true; continue; } + if (args[argidx] == "-select") { + select_mode = true; + continue; + } break; } extra_args(args, argidx, design); @@ -62,6 +72,7 @@ struct AigmapPass : public Pass { dict stat_not_replaced; int orig_num_cells = GetSize(module->cells()); + pool new_sel; for (auto cell : module->selected_cells()) { Aig aig(cell); @@ -75,6 +86,8 @@ struct AigmapPass : public Pass { if (aig.name.empty()) { not_replaced_count++; stat_not_replaced[cell->type]++; + if (select_mode) + new_sel.insert(cell->name); continue; } @@ -95,19 +108,33 @@ struct AigmapPass : public Pass { SigBit A = sigs.at(node.left_parent); SigBit B = sigs.at(node.right_parent); if (nand_mode && node.inverter) { - bit = module->NandGate(NEW_ID, A, B); + bit = module->addWire(NEW_ID); + auto gate = module->addNandGate(NEW_ID, A, B, bit); + if (select_mode) + new_sel.insert(gate->name); + goto skip_inverter; } else { pair key(node.left_parent, node.right_parent); if (and_cache.count(key)) bit = and_cache.at(key); - else - bit = module->AndGate(NEW_ID, A, B); + else { + bit = module->addWire(NEW_ID); + auto gate = module->addAndGate(NEW_ID, A, B, bit); + if (select_mode) + new_sel.insert(gate->name); + } } } - if (node.inverter) - bit = module->NotGate(NEW_ID, bit); + if (node.inverter) { + SigBit new_bit = module->addWire(NEW_ID); + auto gate = module->addNotGate(NEW_ID, bit, new_bit); + bit = new_bit; + if (select_mode) + new_sel.insert(gate->name); + + } skip_inverter: for (auto &op : node.outports) @@ -142,6 +169,13 @@ struct AigmapPass : public Pass { for (auto cell : replaced_cells) module->remove(cell); + + if (select_mode) { + log_assert(!design->selection_stack.empty()); + RTLIL::Selection& sel = design->selection_stack.back(); + sel.selected_members[module->name] = std::move(new_sel); + } + } } } AigmapPass; -- cgit v1.2.3 From dc154c39a8d296c0ed7619168d7b4eda95e2fbe0 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 27 Sep 2019 17:45:49 -0700 Subject: Fix infinite recursion --- backends/aiger/xaiger.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index cc0857896..4045e8811 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -314,7 +314,7 @@ struct XAigerWriter SigBit d = cell->getPort(abc_flop_d); SigBit I = sigmap(d); if (I != d) - alias_map[I] = d; + alias_map[d] = I; unused_bits.erase(d); auto abc_flop_q = r.first->second.q_port; -- cgit v1.2.3 From 313d2478e922f33685ee744c5b287ae3bf530645 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 27 Sep 2019 18:41:04 -0700 Subject: Split ABC9 based on clocking only, add "abc_mergeability" attr for en --- passes/techmap/abc9.cc | 116 ++++++++++++------------------------------------- 1 file changed, 28 insertions(+), 88 deletions(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 97d4c5ef3..64841d873 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -68,9 +68,6 @@ 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 abc_name) { return stringf("$abc$%d$%s", map_autoidx, abc_name.c_str()+1); @@ -244,7 +241,7 @@ struct abc_output_filter }; void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::string script_file, std::string exe_file, - bool cleanup, vector lut_costs, bool dff_mode, std::string clk_str, + bool cleanup, vector lut_costs, bool /*dff_mode*/, std::string /*clk_str*/, bool /*keepff*/, std::string delay_target, std::string /*lutin_shared*/, bool fast_mode, bool show_tempdir, std::string box_file, std::string lut_file, std::string wire_delay, const dict &box_lookup @@ -253,39 +250,6 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri 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] = '_'; @@ -357,18 +321,6 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri fprintf(f, "%s\n", abc_script.c_str()); fclose(f); - if (dff_mode || !clk_str.empty()) - { - if (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); @@ -383,13 +335,9 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri if (count_output) { - design->selection_stack.emplace_back(false); - RTLIL::Selection& sel = design->selection_stack.back(); - sel.select(module); - handle_loops(design); - Pass::call(design, "aigmap"); + Pass::call(design, "aigmap -select"); //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); @@ -414,8 +362,6 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri design->remove(design->module(ID($__abc9__))); #endif - design->selection_stack.pop_back(); - // Now 'unexpose' those wires by undoing // the expose operation -- remove them from PO/PI // and re-connecting them back together @@ -909,7 +855,7 @@ struct Abc9Pass : public Pass { #endif std::string script_file, clk_str, box_file, lut_file; std::string delay_target, lutin_shared = "-S 1", wire_delay; - bool fast_mode = false, dff_mode = false, keepff = false, cleanup = true; + bool fast_mode = false, /*dff_mode = false,*/ keepff = false, cleanup = true; bool show_tempdir = false; vector lut_costs; markgroups = false; @@ -1118,20 +1064,6 @@ struct Abc9Pass : public Pass { assign_map.set(mod); - if (!dff_mode || !clk_str.empty()) { - - design->selection_stack.emplace_back(false); - RTLIL::Selection& sel = design->selection_stack.back(); - sel.select(mod); - - abc9_module(design, mod, script_file, exe_file, cleanup, lut_costs, false, clk_str, keepff, - delay_target, lutin_shared, fast_mode, show_tempdir, - box_file, lut_file, wire_delay, box_lookup); - - design->selection_stack.pop_back(); - continue; - } - CellTypes ct(design); std::vector all_cells = mod->selected_cells(); @@ -1141,8 +1073,8 @@ struct Abc9Pass : public Pass { std::set expand_queue_up, next_expand_queue_up; std::set expand_queue_down, next_expand_queue_down; - typedef tuple clkdomain_t; - std::map> assigned_cells; + typedef pair clkdomain_t; + std::map> assigned_cells; std::map assigned_cells_reverse; std::map> cell_to_bit, cell_to_bit_up, cell_to_bit_down; @@ -1154,9 +1086,12 @@ struct Abc9Pass : public Pass { IdString en_port; }; dict flop_data; + typedef clkdomain_t endomain_t; + std::map mergeability_class; for (auto cell : all_cells) { clkdomain_t key; + endomain_t key2; for (auto &conn : cell->connections()) for (auto bit : conn.second) { @@ -1175,6 +1110,7 @@ struct Abc9Pass : public Pass { } } + // TODO: Generate this outside decltype(flop_data)::iterator it; if (seen_cells.insert(cell->type).second) { RTLIL::Module* inst_module = design->module(cell->type); @@ -1225,15 +1161,20 @@ struct Abc9Pass : public Pass { log_error("'EN_POLARITY' is not a parameter on module '%s'.\n", log_id(cell->type)); bool this_en_pol = jt->second.as_bool(); - key = clkdomain_t(this_clk_pol, assign_map(cell->getPort(data.clk_port)), this_en_pol, assign_map(cell->getPort(data.en_port))); + key = clkdomain_t(this_clk_pol, assign_map(cell->getPort(data.clk_port))); 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[key].insert(cell->name); assigned_cells_reverse[cell] = key; + + key2 = endomain_t(this_en_pol, assign_map(cell->getPort(data.en_port))); + auto r = mergeability_class.emplace(key2, mergeability_class.size() + 1); + auto YS_ATTRIBUTE(unused) r2 = cell->attributes.insert(std::make_pair(ID(abc_mergeability), r.first->second)); + log_assert(r2.second); } while (!expand_queue_up.empty() || !expand_queue_down.empty()) @@ -1249,7 +1190,7 @@ struct Abc9Pass : public Pass { if (unassigned_cells.count(c)) { unassigned_cells.erase(c); next_expand_queue_up.insert(c); - assigned_cells[key].push_back(c); + assigned_cells[key].insert(c->name); assigned_cells_reverse[c] = key; expand_queue.insert(c); } @@ -1266,7 +1207,7 @@ struct Abc9Pass : public Pass { if (unassigned_cells.count(c)) { unassigned_cells.erase(c); next_expand_queue_up.insert(c); - assigned_cells[key].push_back(c); + assigned_cells[key].insert(c->name); assigned_cells_reverse[c] = key; expand_queue.insert(c); } @@ -1289,7 +1230,7 @@ struct Abc9Pass : public Pass { if (unassigned_cells.count(c)) { unassigned_cells.erase(c); next_expand_queue.insert(c); - assigned_cells[key].push_back(c); + assigned_cells[key].insert(c->name); assigned_cells_reverse[c] = key; } bit_to_cell[bit].clear(); @@ -1299,28 +1240,27 @@ struct Abc9Pass : public Pass { expand_queue.swap(next_expand_queue); } - clkdomain_t key(true, RTLIL::SigSpec(), true, RTLIL::SigSpec()); + clkdomain_t key(true, RTLIL::SigSpec()); for (auto cell : unassigned_cells) { - assigned_cells[key].push_back(cell); + assigned_cells[key].insert(cell->name); 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))); + log(" %d cells in clk=%s%s\n", GetSize(it.second), + std::get<0>(it.first) ? "" : "!", log_signal(std::get<1>(it.first))); + design->selection_stack.emplace_back(false); 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(), "$", + RTLIL::Selection& sel = design->selection_stack.back(); + sel.selected_members[mod->name] = std::move(it.second); + abc9_module(design, mod, script_file, exe_file, cleanup, lut_costs, false, "$", keepff, delay_target, lutin_shared, fast_mode, show_tempdir, box_file, lut_file, wire_delay, box_lookup); assign_map.set(mod); } + design->selection_stack.pop_back(); } assign_map.clear(); -- cgit v1.2.3 From cfa6dd61ef79fb16abd83164b1e013c0a5a2a63a Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 27 Sep 2019 18:41:43 -0700 Subject: Use abc_mergeability attr for "r" extension --- backends/aiger/xaiger.cc | 124 +++++++++++++++++++++++++---------------------- 1 file changed, 66 insertions(+), 58 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 4045e8811..4df97bd52 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -85,7 +85,7 @@ struct XAigerWriter dict> and_map; vector> ci_bits; vector> co_bits; - vector ff_bits; + vector> ff_bits; dict arrival_times; vector> aig_gates; @@ -319,11 +319,12 @@ struct XAigerWriter auto abc_flop_q = r.first->second.q_port; SigBit q = cell->getPort(abc_flop_q); - SigBit O = sigmap(q); - if (O != q) - alias_map[O] = q; - undriven_bits.erase(O); - ff_bits.emplace_back(q); + log_assert(q == sigmap(q)); + undriven_bits.erase(q); + auto it = cell->attributes.find(ID(abc_mergeability)); + log_assert(it != cell->attributes.end()); + ff_bits.emplace_back(q, it->second.as_int()); + cell->attributes.erase(it); auto arrival = r.first->second.q_arrival; if (arrival) @@ -343,56 +344,57 @@ struct XAigerWriter for (auto bit : sigmap(conn.second)) bit_drivers[bit].insert(cell->name); } + + continue; } - 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); - } + 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) { - int arrival = 0; - if (port_wire) { - auto it = port_wire->attributes.find("\\abc_arrival"); - if (it != port_wire->attributes.end()) { - if (it->second.flags != 0) - log_error("Attribute 'abc_arrival' on port '%s' of module '%s' is not an integer.\n", log_id(port_wire), log_id(cell->type)); - arrival = it->second.as_int(); - } + } + if (is_output) { + int arrival = 0; + if (port_wire) { + auto it = port_wire->attributes.find("\\abc_arrival"); + if (it != port_wire->attributes.end()) { + if (it->second.flags != 0) + log_error("Attribute 'abc_arrival' on port '%s' of module '%s' is not an integer.\n", log_id(port_wire), log_id(cell->type)); + arrival = it->second.as_int(); } + } - for (auto b : c.second) { - 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 (arrival) - arrival_times[b] = arrival; - } + 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 (arrival) + arrival_times[b] = arrival; } } } @@ -540,12 +542,15 @@ struct XAigerWriter undriven_bits.erase(bit); if (!undriven_bits.empty() && !holes_mode) { + bool whole_module = module->design->selected_whole_module(module->name); undriven_bits.sort(); for (auto bit : undriven_bits) { - log_warning("Treating undriven bit %s.%s like $anyseq.\n", log_id(module), log_signal(bit)); + if (whole_module) + 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 (whole_module) + log_warning("Treating a total of %d undriven bits in %s like $anyseq.\n", GetSize(undriven_bits), log_id(module)); } init_map.sort(); @@ -576,7 +581,8 @@ struct XAigerWriter aig_map[bit] = 2*aig_m; } - for (auto bit : ff_bits) { + for (const auto &i : ff_bits) { + const SigBit &bit = i.first; aig_m++, aig_i++; log_assert(!aig_map.count(bit)); aig_map[bit] = 2*aig_m; @@ -663,7 +669,8 @@ struct XAigerWriter aig_outputs.push_back(bit2aig(bit)); } - for (auto bit : ff_bits) { + for (auto &i : ff_bits) { + const SigBit &bit = i.first; aig_o++; aig_outputs.push_back(ff_aig_map.at(bit)); } @@ -853,9 +860,9 @@ struct XAigerWriter auto write_r_buffer = std::bind(write_buffer, std::ref(r_buffer), std::placeholders::_1); log_debug("flopNum = %d\n", GetSize(ff_bits)); write_r_buffer(ff_bits.size()); - int mergeability_class = 1; - for (auto bit : ff_bits) { - write_r_buffer(mergeability_class++); + for (const auto &i : ff_bits) { + write_r_buffer(i.second); + const SigBit &bit = i.first; write_i_buffer(arrival_times.at(bit, 0)); //write_o_buffer(0); } @@ -869,7 +876,8 @@ struct XAigerWriter std::stringstream s_buffer; auto write_s_buffer = std::bind(write_buffer, std::ref(s_buffer), std::placeholders::_1); write_s_buffer(ff_bits.size()); - for (auto bit : ff_bits) { + for (const auto &i : ff_bits) { + const SigBit &bit = i.first; auto it = bit.wire->attributes.find("\\init"); if (it != bit.wire->attributes.end()) { auto init = it->second[bit.offset]; -- cgit v1.2.3 From 6b9f90de789b1d0daf93ac1d2b608b057e7ca272 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 27 Sep 2019 17:00:19 -0700 Subject: Fix typo --- kernel/rtlil.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 1d380135b..f42f5430f 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1528,7 +1528,7 @@ std::vector RTLIL::Module::selected_wires() const std::vector RTLIL::Module::selected_cells() const { std::vector result; - result.reserve(wires_.size()); + result.reserve(cells_.size()); for (auto &it : cells_) if (design->selected(this, it.second)) result.push_back(it.second); -- cgit v1.2.3 From 79b6edb6397c530a7304eb4334f95324a4208aba Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Sat, 28 Sep 2019 23:48:17 -0700 Subject: Big rework; flop info now mostly in cells_sim.v --- backends/aiger/xaiger.cc | 155 ++++++++++++--------- frontends/aiger/aigerparse.cc | 19 ++- passes/techmap/abc9.cc | 143 +++++++++---------- techlibs/xilinx/abc_map.v | 77 ++++++----- techlibs/xilinx/abc_model.v | 90 +----------- techlibs/xilinx/abc_unmap.v | 122 +---------------- techlibs/xilinx/abc_xc7.box | 22 ++- techlibs/xilinx/cells_sim.v | 294 +++++++++++++++++++++++++++++++++------- techlibs/xilinx/synth_xilinx.cc | 4 +- 9 files changed, 485 insertions(+), 441 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 4df97bd52..5d41d49b9 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -81,11 +81,11 @@ struct XAigerWriter dict init_map; pool input_bits, output_bits; - dict not_map, ff_map, alias_map; + dict not_map, /*ff_map,*/ alias_map; dict> and_map; vector> ci_bits; vector> co_bits; - vector> ff_bits; + dict ff_bits; dict arrival_times; vector> aig_gates; @@ -218,13 +218,8 @@ struct XAigerWriter // box ordering, but not individual AIG cells dict> bit_drivers, bit_users; TopoSort toposort; - struct flop_data_t { - IdString d_port; - IdString q_port; - int q_arrival; - }; - dict flop_data; bool abc_box_seen = false; + std::vector flop_boxes; for (auto cell : module->selected_cells()) { if (cell->type == "$_NOT_") @@ -269,6 +264,8 @@ struct XAigerWriter unused_bits.erase(D); undriven_bits.erase(Q); alias_map[Q] = D; + auto r = ff_bits.insert(std::make_pair(D, 0)); + log_assert(r.second); continue; } @@ -278,59 +275,6 @@ struct XAigerWriter toposort.node(cell->name); - auto r = flop_data.insert(std::make_pair(cell->type, flop_data_t{IdString(), IdString(), 0})); - if (r.second && inst_module->attributes.count("\\abc_flop")) { - IdString &abc_flop_d = r.first->second.d_port; - IdString &abc_flop_q = r.first->second.q_port; - for (auto port_name : inst_module->ports) { - auto wire = inst_module->wire(port_name); - log_assert(wire); - if (wire->attributes.count("\\abc_flop_d")) { - if (abc_flop_d != IdString()) - log_error("More than one port has the 'abc_flop_d' attribute set on module '%s'.\n", log_id(cell->type)); - abc_flop_d = port_name; - } - if (wire->attributes.count("\\abc_flop_q")) { - if (abc_flop_q != IdString()) - log_error("More than one port has the 'abc_flop_q' attribute set on module '%s'.\n", log_id(cell->type)); - abc_flop_q = port_name; - - auto it = wire->attributes.find("\\abc_arrival"); - if (it != wire->attributes.end()) { - if (it->second.flags != 0) - log_error("Attribute 'abc_arrival' on port '%s' of module '%s' is not an integer.\n", log_id(wire), log_id(cell->type)); - r.first->second.q_arrival = it->second.as_int(); - } - } - } - if (abc_flop_d == IdString()) - log_error("'abc_flop_d' attribute not found on any ports on module '%s'.\n", log_id(cell->type)); - if (abc_flop_q == IdString()) - log_error("'abc_flop_q' attribute not found on any ports on module '%s'.\n", log_id(cell->type)); - } - - auto abc_flop_d = r.first->second.d_port; - if (abc_flop_d != IdString()) { - SigBit d = cell->getPort(abc_flop_d); - SigBit I = sigmap(d); - if (I != d) - alias_map[d] = I; - unused_bits.erase(d); - - auto abc_flop_q = r.first->second.q_port; - SigBit q = cell->getPort(abc_flop_q); - log_assert(q == sigmap(q)); - undriven_bits.erase(q); - auto it = cell->attributes.find(ID(abc_mergeability)); - log_assert(it != cell->attributes.end()); - ff_bits.emplace_back(q, it->second.as_int()); - cell->attributes.erase(it); - - auto arrival = r.first->second.q_arrival; - if (arrival) - arrival_times[q] = arrival; - } - for (const auto &conn : cell->connections()) { auto port_wire = inst_module->wire(conn.first); if (port_wire->port_input) { @@ -345,6 +289,8 @@ struct XAigerWriter bit_drivers[bit].insert(cell->name); } + if (inst_module->attributes.count("\\abc9_flop")) + flop_boxes.push_back(cell); continue; } @@ -403,6 +349,45 @@ struct XAigerWriter } if (abc_box_seen) { + dict> flop_q; + for (auto cell : flop_boxes) { + auto r = flop_q.insert(std::make_pair(cell->type, std::make_pair(IdString(), 0))); + SigBit d; + if (r.second) { + for (const auto &conn : cell->connections()) { + const SigSpec &rhs = conn.second; + if (!rhs.is_bit()) + continue; + if (!ff_bits.count(rhs)) + continue; + r.first->second.first = conn.first; + Module *inst_module = module->design->module(cell->type); + Wire *wire = inst_module->wire(conn.first); + log_assert(wire); + auto jt = wire->attributes.find("\\abc_arrival"); + if (jt != wire->attributes.end()) { + if (jt->second.flags != 0) + log_error("Attribute 'abc_arrival' on port '%s' of module '%s' is not an integer.\n", log_id(wire), log_id(cell->type)); + r.first->second.second = jt->second.as_int(); + } + d = rhs; + log_assert(d == sigmap(d)); + break; + } + } + else + d = cell->getPort(r.first->second.first); + + auto it = cell->attributes.find(ID(abc9_mergeability)); + log_assert(it != cell->attributes.end()); + ff_bits.at(d) = it->second.as_int(); + cell->attributes.erase(it); + + auto arrival = r.first->second.second; + if (arrival) + arrival_times[d] = arrival; + } + for (auto &it : bit_users) if (bit_drivers.count(it.first)) for (auto driver_cell : bit_drivers.at(it.first)) @@ -498,6 +483,29 @@ struct XAigerWriter } } } + + if (box_module->get_bool_attribute("\\abc9_flop")) { + IdString port_name = "\\$currQ"; + RTLIL::Wire* w = box_module->wire(port_name); + SigSpec rhs = cell->getPort(port_name); + log_assert(GetSize(w) == GetSize(rhs)); + + int offset = 0; + 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, cell, port_name, offset++, 0); + unused_bits.erase(b); + } + } + box_list.emplace_back(cell); } @@ -569,7 +577,7 @@ struct XAigerWriter } not_map.sort(); - ff_map.sort(); + //ff_map.sort(); and_map.sort(); aig_map[State::S0] = 0; @@ -850,6 +858,28 @@ struct XAigerWriter } } + if (box_module->get_bool_attribute("\\abc9_flop")) { + log_assert(holes_cell); + IdString port_name = "\\$currQ"; + Wire* w = box_module->wire(port_name); + SigSpec rhs = cell->getPort(port_name); + log_assert(GetSize(w) == GetSize(rhs)); + SigSpec port_wire; + Wire *holes_wire; + 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); + } + port_wire.append(holes_wire); + } + holes_cell->setPort(w->name, port_wire); + } + write_h_buffer(box_inputs); write_h_buffer(box_outputs); write_h_buffer(box_module->attributes.at("\\abc_box_id").as_int()); @@ -861,6 +891,7 @@ struct XAigerWriter log_debug("flopNum = %d\n", GetSize(ff_bits)); write_r_buffer(ff_bits.size()); for (const auto &i : ff_bits) { + log_assert(i.second > 0); write_r_buffer(i.second); const SigBit &bit = i.first; write_i_buffer(arrival_times.at(bit, 0)); diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc index 7a467b91e..439311230 100644 --- a/frontends/aiger/aigerparse.cc +++ b/frontends/aiger/aigerparse.cc @@ -740,7 +740,7 @@ void AigerReader::post_process() bool is_flop = false; if (seen_boxes.insert(cell->type).second) { - if (box_module->attributes.count("\\abc_flop")) { + if (box_module->attributes.count("\\abc9_flop")) { log_assert(flop_count < flopNum); flops.insert(cell->type); is_flop = true; @@ -811,12 +811,18 @@ void AigerReader::post_process() } rhs.append(wire); } - - if (!is_flop || port_name != "\\$pastQ") - cell->setPort(port_name, rhs); + cell->setPort(port_name, rhs); } if (is_flop) { + Wire* port = box_module->wire("\\$currQ"); + log_assert(port); + 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); @@ -827,9 +833,10 @@ void AigerReader::post_process() log_assert(q->port_input); q->port_input = false; + auto ff = module->addCell(NEW_ID, "$__ABC_FF_"); + ff->setPort("\\D", d); + ff->setPort("\\Q", q); flop_count++; - module->connect(q, d); - cell->set_bool_attribute("\\abc_flop"); continue; } } diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 64841d873..a5d823139 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -536,8 +536,10 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri cell_stats[mapped_cell->type]++; RTLIL::Cell *existing_cell = nullptr; - if (mapped_cell->type == ID($lut)) { - if (GetSize(mapped_cell->getPort(ID::A)) == 1 && mapped_cell->getParam(ID(LUT)) == RTLIL::Const::from_string("01")) { + if (mapped_cell->type.in(ID($lut), ID($__ABC_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); @@ -564,7 +566,8 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri cell->attributes = mapped_cell->attributes; } - auto abc_flop = mapped_cell->attributes.count("\\abc_flop"); + RTLIL::Module* box_module = design->module(mapped_cell->type); + auto abc_flop = box_module && box_module->attributes.count("\\abc9_flop"); for (auto &conn : mapped_cell->connections()) { RTLIL::SigSpec newsig; for (auto c : conn.second.chunks()) { @@ -1073,29 +1076,18 @@ struct Abc9Pass : public Pass { std::set expand_queue_up, next_expand_queue_up; std::set expand_queue_down, next_expand_queue_down; - typedef pair clkdomain_t; - std::map> assigned_cells; - std::map assigned_cells_reverse; + std::map> assigned_cells; + std::map assigned_cells_reverse; std::map> cell_to_bit, cell_to_bit_up, cell_to_bit_down; std::map> bit_to_cell, bit_to_cell_up, bit_to_cell_down; - pool seen_cells; - struct flop_data_t { - IdString clk_port; - IdString en_port; - }; - dict flop_data; - typedef clkdomain_t endomain_t; + typedef std::pair endomain_t; std::map mergeability_class; for (auto cell : all_cells) { - clkdomain_t key; - endomain_t key2; - for (auto &conn : cell->connections()) - for (auto bit : conn.second) { - bit = assign_map(bit); + for (auto bit : assign_map(conn.second)) if (bit.wire != nullptr) { cell_to_bit[cell].insert(bit); bit_to_cell[bit].insert(cell); @@ -1108,72 +1100,68 @@ struct Abc9Pass : public Pass { bit_to_cell_up[bit].insert(cell); } } - } - - // TODO: Generate this outside - decltype(flop_data)::iterator it; - if (seen_cells.insert(cell->type).second) { - RTLIL::Module* inst_module = design->module(cell->type); - if (!inst_module) - continue; - - if (!inst_module->attributes.count("\\abc_flop")) - continue; - - IdString abc_flop_clk, abc_flop_en; - for (auto port_name : inst_module->ports) { - auto wire = inst_module->wire(port_name); - log_assert(wire); - if (wire->attributes.count("\\abc_flop_clk")) { - if (abc_flop_clk != IdString()) - log_error("More than one port has the 'abc_flop_clk' attribute set on module '%s'.\n", log_id(cell->type)); - abc_flop_clk = port_name; - } - if (wire->attributes.count("\\abc_flop_en")) { - if (abc_flop_en != IdString()) - log_error("More than one port has the 'abc_flop_en' attribute set on module '%s'.\n", log_id(cell->type)); - abc_flop_en = port_name; - } - } - if (abc_flop_clk == IdString()) - log_error("'abc_flop_clk' attribute not found on any ports on module '%s'.\n", log_id(cell->type)); - if (abc_flop_en == IdString()) - log_error("'abc_flop_en' attribute not found on any ports on module '%s'.\n", log_id(cell->type)); + auto inst_module = design->module(cell->type); + if (!inst_module || !inst_module->attributes.count("\\abc9_flop")) + continue; - it = flop_data.insert(std::make_pair(cell->type, flop_data_t{abc_flop_clk, abc_flop_en})).first; - } - else { - it = flop_data.find(cell->type); - if (it == flop_data.end()) - continue; + auto derived_name = inst_module->derive(design, cell->parameters); + auto derived_module = design->module(derived_name); + log_assert(derived_module); + Pass::call_on_module(design, derived_module, "proc"); + SigMap derived_sigmap(derived_module); + + Wire *currQ = derived_module->wire("\\$currQ"); + if (currQ == NULL) + log_error("'\\$currQ' is not a wire present in module '%s'.\n", log_id(cell->type)); + log_assert(!currQ->port_output); + if (!currQ->port_input) { + currQ->port_input = true; + derived_module->ports.push_back(currQ->name); + currQ->port_id = GetSize(derived_module->ports); +#ifndef NDEBUG + derived_module->check(); +#endif } - const auto &data = it->second; - - auto jt = cell->parameters.find("\\CLK_POLARITY"); - if (jt == cell->parameters.end()) - log_error("'CLK_POLARITY' is not a parameter on module '%s'.\n", log_id(cell->type)); - bool this_clk_pol = jt->second.as_bool(); - - jt = cell->parameters.find("\\EN_POLARITY"); - if (jt == cell->parameters.end()) - log_error("'EN_POLARITY' is not a parameter on module '%s'.\n", log_id(cell->type)); - bool this_en_pol = jt->second.as_bool(); + SigSpec pattern; + SigSpec with; + for (auto &conn : cell->connections()) { + Wire *first = derived_module->wire(conn.first); + log_assert(first); + SigSpec second = assign_map(conn.second); + log_assert(GetSize(first) == GetSize(second)); + pattern.append(first); + with.append(second); + } - key = clkdomain_t(this_clk_pol, assign_map(cell->getPort(data.clk_port))); + Wire *abc9_clock_wire = derived_module->wire("\\$abc9_clock"); + if (abc9_clock_wire == NULL) + log_error("'\\$abc9_clock' is not a wire present in module '%s'.\n", log_id(cell->type)); + SigSpec abc9_clock = derived_sigmap(abc9_clock_wire); + abc9_clock.replace(pattern, with); + for (const auto &c : abc9_clock.chunks()) + log_assert(!c.wire || c.wire->module == mod); + + Wire *abc9_control_wire = derived_module->wire("\\$abc9_control"); + if (abc9_control_wire == NULL) + log_error("'\\$abc9_control' is not a wire present in module '%s'.\n", log_id(cell->type)); + SigSpec abc9_control = derived_sigmap(abc9_control_wire); + abc9_control.replace(pattern, with); + for (const auto &c : abc9_control.chunks()) + log_assert(!c.wire || c.wire->module == mod); unassigned_cells.erase(cell); expand_queue.insert(cell); expand_queue_up.insert(cell); expand_queue_down.insert(cell); - assigned_cells[key].insert(cell->name); - assigned_cells_reverse[cell] = key; + assigned_cells[abc9_clock].insert(cell->name); + assigned_cells_reverse[cell] = abc9_clock; - key2 = endomain_t(this_en_pol, assign_map(cell->getPort(data.en_port))); - auto r = mergeability_class.emplace(key2, mergeability_class.size() + 1); - auto YS_ATTRIBUTE(unused) r2 = cell->attributes.insert(std::make_pair(ID(abc_mergeability), r.first->second)); + endomain_t key(cell->type, abc9_control); + auto r = mergeability_class.emplace(key, mergeability_class.size() + 1); + auto YS_ATTRIBUTE(unused) r2 = cell->attributes.insert(std::make_pair(ID(abc9_mergeability), r.first->second)); log_assert(r2.second); } @@ -1182,7 +1170,7 @@ struct Abc9Pass : public Pass { if (!expand_queue_up.empty()) { RTLIL::Cell *cell = *expand_queue_up.begin(); - clkdomain_t key = assigned_cells_reverse.at(cell); + SigSpec key = assigned_cells_reverse.at(cell); expand_queue_up.erase(cell); for (auto bit : cell_to_bit_up[cell]) @@ -1199,7 +1187,7 @@ struct Abc9Pass : public Pass { if (!expand_queue_down.empty()) { RTLIL::Cell *cell = *expand_queue_down.begin(); - clkdomain_t key = assigned_cells_reverse.at(cell); + SigSpec key = assigned_cells_reverse.at(cell); expand_queue_down.erase(cell); for (auto bit : cell_to_bit_down[cell]) @@ -1222,7 +1210,7 @@ struct Abc9Pass : public Pass { while (!expand_queue.empty()) { RTLIL::Cell *cell = *expand_queue.begin(); - clkdomain_t key = assigned_cells_reverse.at(cell); + SigSpec key = assigned_cells_reverse.at(cell); expand_queue.erase(cell); for (auto bit : cell_to_bit.at(cell)) { @@ -1240,7 +1228,7 @@ struct Abc9Pass : public Pass { expand_queue.swap(next_expand_queue); } - clkdomain_t key(true, RTLIL::SigSpec()); + SigSpec key; for (auto cell : unassigned_cells) { assigned_cells[key].insert(cell->name); assigned_cells_reverse[cell] = key; @@ -1248,8 +1236,7 @@ struct Abc9Pass : public Pass { log_header(design, "Summary of detected clock domains:\n"); for (auto &it : assigned_cells) - log(" %d cells in clk=%s%s\n", GetSize(it.second), - std::get<0>(it.first) ? "" : "!", log_signal(std::get<1>(it.first))); + log(" %d cells in clk=%s\n", GetSize(it.second), log_signal(it.first)); design->selection_stack.emplace_back(false); for (auto &it : assigned_cells) { diff --git a/techlibs/xilinx/abc_map.v b/techlibs/xilinx/abc_map.v index 9f96d16be..056f66bbb 100644 --- a/techlibs/xilinx/abc_map.v +++ b/techlibs/xilinx/abc_map.v @@ -26,27 +26,23 @@ module FDRE (output reg Q, input C, CE, D, R); parameter [0:0] IS_D_INVERTED = 1'b0; parameter [0:0] IS_R_INVERTED = 1'b0; wire \$nextQ ; - \$__ABC_FDRE #( + FDRE #( .INIT(INIT), .IS_C_INVERTED(IS_C_INVERTED), .IS_D_INVERTED(IS_D_INVERTED), - .IS_R_INVERTED(IS_R_INVERTED), - .CLK_POLARITY(!IS_C_INVERTED), - .EN_POLARITY(1'b1) + .IS_R_INVERTED(IS_R_INVERTED) ) _TECHMAP_REPLACE_ ( - .D(D), .Q(\$nextQ ), .\$pastQ (Q), .C(C), .CE(CE), .R(R) + .D(D), .Q(\$nextQ ), .\$currQ (Q), .C(C), .CE(CE), .R(R) ); \$__ABC_FF_ abc_dff (.D(\$nextQ ), .Q(Q)); endmodule module FDRE_1 (output reg Q, input C, CE, D, R); parameter [0:0] INIT = 1'b0; wire \$nextQ ; - \$__ABC_FDRE_1 #( - .INIT(|0), - .CLK_POLARITY(1'b0), - .EN_POLARITY(1'b1) + FDRE_1 #( + .INIT(|0), ) _TECHMAP_REPLACE_ ( - .D(D), .Q(\$nextQ ), .\$pastQ (Q), .C(C), .CE(CE), .R(R) + .D(D), .Q(\$nextQ ), .\$currQ (Q), .C(C), .CE(CE), .R(R) ); \$__ABC_FF_ abc_dff (.D(\$nextQ ), .Q(Q)); endmodule @@ -57,28 +53,24 @@ module FDCE (output reg Q, input C, CE, D, CLR); parameter [0:0] IS_D_INVERTED = 1'b0; parameter [0:0] IS_CLR_INVERTED = 1'b0; wire \$nextQ , \$currQ ; - \$__ABC_FDCE #( + FDCE #( .INIT(INIT), .IS_C_INVERTED(IS_C_INVERTED), .IS_D_INVERTED(IS_D_INVERTED), - .IS_CLR_INVERTED(IS_CLR_INVERTED), - .CLK_POLARITY(!IS_C_INVERTED), - .EN_POLARITY(1'b1) + .IS_CLR_INVERTED(IS_CLR_INVERTED) ) _TECHMAP_REPLACE_ ( - .D(D), .Q(\$nextQ ), .\$pastQ (Q), .C(C), .CE(CE), .CLR(CLR) + .D(D), .Q(\$nextQ ), .\$currQ (Q), .C(C), .CE(CE), .CLR(CLR) ); \$__ABC_FF_ abc_dff (.D(\$nextQ ), .Q(\$currQ )); - \$__ABC_ASYNC abc_async (.A(\$currQ ), .S(CLR), .Y(Q)); + \$__ABC_ASYNC abc_async (.A(\$currQ ), .S(CLR ^ IS_CLR_INVERTED), .Y(Q)); endmodule module FDCE_1 (output reg Q, input C, CE, D, CLR); parameter [0:0] INIT = 1'b0; wire \$nextQ , \$currQ ; - \$__ABC_FDCE_1 #( - .INIT(INIT), - .CLK_POLARITY(1'b0), - .EN_POLARITY(1'b1) + FDCE_1 #( + .INIT(INIT) ) _TECHMAP_REPLACE_ ( - .D(D), .Q(\$nextQ ), .\$pastQ (Q), .C(C), .CE(CE), .CLR(CLR) + .D(D), .Q(\$nextQ ), .\$currQ (Q), .C(C), .CE(CE), .CLR(CLR) ); \$__ABC_FF_ abc_dff (.D(\$nextQ ), .Q(\$currQ )); \$__ABC_ASYNC abc_async (.A(\$currQ ), .S(CLR), .Y(Q)); @@ -90,33 +82,56 @@ module FDPE (output reg Q, input C, CE, D, PRE); parameter [0:0] IS_D_INVERTED = 1'b0; parameter [0:0] IS_PRE_INVERTED = 1'b0; wire \$nextQ , \$currQ ; - \$__ABC_FDPE #( + FDPE #( .INIT(INIT), .IS_C_INVERTED(IS_C_INVERTED), .IS_D_INVERTED(IS_D_INVERTED), .IS_PRE_INVERTED(IS_PRE_INVERTED), - .CLK_POLARITY(!IS_C_INVERTED), - .EN_POLARITY(1'b1) ) _TECHMAP_REPLACE_ ( - .D(D), .Q(\$nextQ ), .\$pastQ (Q), .C(C), .CE(CE), .PRE(PRE) + .D(D), .Q(\$nextQ ), .\$currQ (Q), .C(C), .CE(CE), .PRE(PRE) ); \$__ABC_FF_ abc_dff (.D(\$nextQ ), .Q(\$currQ )); - \$__ABC_ASYNC abc_async (.A(\$currQ ), .S(PRE), .Y(Q)); + \$__ABC_ASYNC abc_async (.A(\$currQ ), .S(PRE ^ IS_PRE_INVERTED), .Y(Q)); endmodule module FDPE_1 (output reg Q, input C, CE, D, PRE); parameter [0:0] INIT = 1'b0; wire \$nextQ , \$currQ ; - \$__ABC_FDPE_1 #( - .INIT(INIT), - .CLK_POLARITY(1'b0), - .EN_POLARITY(1'b1) + FDPE_1 #( + .INIT(INIT) ) _TECHMAP_REPLACE_ ( - .D(D), .Q(\$nextQ ), .\$pastQ (Q), .C(C), .CE(CE), .PRE(PRE) + .D(D), .Q(\$nextQ ), .\$currQ (Q), .C(C), .CE(CE), .PRE(PRE) ); \$__ABC_FF_ abc_dff (.D(\$nextQ ), .Q(\$currQ )); \$__ABC_ASYNC abc_async (.A(\$currQ ), .S(PRE), .Y(Q)); endmodule +module FDSE (output reg Q, input C, CE, D, S); + 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_S_INVERTED = 1'b0; + wire \$nextQ ; + FDSE #( + .INIT(INIT), + .IS_C_INVERTED(IS_C_INVERTED), + .IS_D_INVERTED(IS_D_INVERTED), + .IS_S_INVERTED(IS_S_INVERTED) + ) _TECHMAP_REPLACE_ ( + .D(D), .Q(\$nextQ ), .\$currQ (Q), .C(C), .CE(CE), .S(S) + ); + \$__ABC_FF_ abc_dff (.D(\$nextQ ), .Q(Q)); +endmodule +module FDSE_1 (output reg Q, input C, CE, D, S); + parameter [0:0] INIT = 1'b0; + wire \$nextQ ; + FDSE_1 #( + .INIT(|0), + ) _TECHMAP_REPLACE_ ( + .D(D), .Q(\$nextQ ), .\$currQ (Q), .C(C), .CE(CE), .S(S) + ); + \$__ABC_FF_ abc_dff (.D(\$nextQ ), .Q(Q)); +endmodule + module RAM32X1D ( output DPO, SPO, input D, diff --git a/techlibs/xilinx/abc_model.v b/techlibs/xilinx/abc_model.v index d94ddb7e5..a2914464d 100644 --- a/techlibs/xilinx/abc_model.v +++ b/techlibs/xilinx/abc_model.v @@ -26,97 +26,9 @@ module \$__XILINX_MUXF78 (output O, input I0, I1, I2, I3, S0, S1); : (S0 ? I1 : I0); endmodule -module \$__ABC_FF_ (input C, D, output Q); +module \$__ABC_FF_ (input D, output Q); endmodule (* abc_box_id = 1000 *) module \$__ABC_ASYNC (input A, S, output Y); endmodule - -(* abc_box_id=1001, lib_whitebox, abc_flop *) -module \$__ABC_FDRE ((* abc_flop_q, abc_arrival=303 *) output Q, - (* abc_flop_clk *) input C, - (* abc_flop_en *) input CE, - (* abc_flop_d *) input D, - input R, \$pastQ ); - parameter [0:0] INIT = 1'b0; - parameter [0:0] IS_C_INVERTED = 1'b0; - parameter [0:0] IS_D_INVERTED = 1'b0; - parameter [0:0] IS_R_INVERTED = 1'b0; - parameter CLK_POLARITY = !IS_C_INVERTED; - parameter EN_POLARITY = 1'b1; - assign Q = (R ^ IS_R_INVERTED) ? 1'b0 : (CE ? (D ^ IS_D_INVERTED) : \$pastQ ); -endmodule - -(* abc_box_id=1002, lib_whitebox, abc_flop *) -module \$__ABC_FDRE_1 ((* abc_flop_q, abc_arrival=303 *) output Q, - (* abc_flop_clk *) input C, - (* abc_flop_en *) input CE, - (* abc_flop_d *) input D, - input R, \$pastQ ); - parameter [0:0] INIT = 1'b0; - parameter CLK_POLARITY = 1'b0; - parameter EN_POLARITY = 1'b1; - assign Q = R ? 1'b0 : (CE ? D : \$pastQ ); -endmodule - -(* abc_box_id=1003, lib_whitebox, abc_flop *) -module \$__ABC_FDCE ((* abc_flop_q, abc_arrival=303 *) output Q, - (* abc_flop_clk *) input C, - (* abc_flop_en *) input CE, - (* abc_flop_d *) input D, - input CLR, \$pastQ ); - parameter [0:0] INIT = 1'b0; - parameter [0:0] IS_C_INVERTED = 1'b0; - parameter [0:0] IS_D_INVERTED = 1'b0; - parameter [0:0] IS_CLR_INVERTED = 1'b0; - parameter CLK_POLARITY = !IS_C_INVERTED; - parameter EN_POLARITY = 1'b1; - assign Q = (CE && !(CLR ^ IS_CLR_INVERTED)) ? (D ^ IS_D_INVERTED) : \$pastQ ; -endmodule - -(* abc_box_id=1004, lib_whitebox, abc_flop *) -module \$__ABC_FDCE_1 ((* abc_flop_q, abc_arrival=303 *) output Q, - (* abc_flop_clk *) input C, - (* abc_flop_en *) input CE, - (* abc_flop_d *) input D, - input CLR, \$pastQ ); - parameter [0:0] INIT = 1'b0; - parameter CLK_POLARITY = 1'b0; - parameter EN_POLARITY = 1'b1; - assign Q = (CE && !CLR) ? D : \$pastQ ; -endmodule - -(* abc_box_id=1005, lib_whitebox, abc_flop *) -module \$__ABC_FDPE ((* abc_flop_q, abc_arrival=303 *) output Q, - (* abc_flop_clk *) input C, - (* abc_flop_en *) input CE, - (* abc_flop_d *) input D, - input PRE, \$pastQ ); - parameter [0:0] INIT = 1'b0; - parameter [0:0] IS_C_INVERTED = 1'b0; - parameter [0:0] IS_D_INVERTED = 1'b0; - parameter [0:0] IS_PRE_INVERTED = 1'b0; - parameter CLK_POLARITY = !IS_C_INVERTED; - parameter EN_POLARITY = 1'b1; - assign Q = (CE && !(PRE ^ IS_PRE_INVERTED)) ? (D ^ IS_D_INVERTED) : \$pastQ ; -endmodule - -(* abc_box_id=1006, lib_whitebox, abc_flop *) -module \$__ABC_FDPE_1 ((* abc_flop_q, abc_arrival=303 *) output Q, - (* abc_flop_clk *) input C, - (* abc_flop_en *) input CE, - (* abc_flop_d *) input D, - input PRE, \$pastQ ); - parameter [0:0] INIT = 1'b0; - parameter CLK_POLARITY = 1'b0; - parameter EN_POLARITY = 1'b1; - assign Q = (CE && !PRE) ? D : \$pastQ ; -endmodule - -(* abc_box_id=2000 *) -module \$__ABC_LUT6 (input A, input [5:0] S, output Y); -endmodule -(* abc_box_id=2001 *) -module \$__ABC_LUT7 (input A, input [6:0] S, output Y); -endmodule diff --git a/techlibs/xilinx/abc_unmap.v b/techlibs/xilinx/abc_unmap.v index c24571747..bf8253adb 100644 --- a/techlibs/xilinx/abc_unmap.v +++ b/techlibs/xilinx/abc_unmap.v @@ -24,124 +24,6 @@ module \$__ABC_ASYNC (input A, S, output Y); assign Y = A; endmodule -module \$__ABC_FDRE (output Q, - input C, - input CE, - input D, - input R, \$pastQ ); - parameter [0:0] INIT = 1'b0; - parameter [0:0] IS_C_INVERTED = 1'b0; - parameter [0:0] IS_D_INVERTED = 1'b0; - parameter [0:0] IS_R_INVERTED = 1'b0; - parameter CLK_POLARITY = !IS_C_INVERTED; - parameter EN_POLARITY = 1'b1; - - FDRE #( - .INIT(INIT), - .IS_C_INVERTED(IS_C_INVERTED), - .IS_D_INVERTED(IS_D_INVERTED), - .IS_R_INVERTED(IS_R_INVERTED), - ) _TECHMAP_REPLACE_ ( - .D(D), .Q(Q), .C(C), .CE(CE), .R(R) - ); -endmodule - -module \$__ABC_FDRE_1 (output Q, - input C, - input CE, - input D, - input R, \$pastQ ); - parameter [0:0] INIT = 1'b0; - parameter CLK_POLARITY = 1'b0; - parameter EN_POLARITY = 1'b1; - assign Q = R ? 1'b0 : (CE ? D : \$pastQ ); - - FDRE_1 #( - .INIT(INIT), - ) _TECHMAP_REPLACE_ ( - .D(D), .Q(Q), .C(C), .CE(CE), .R(R) - ); -endmodule - -module \$__ABC_FDCE (output Q, - input C, - input CE, - input D, - input CLR, \$pastQ ); - parameter [0:0] INIT = 1'b0; - parameter [0:0] IS_C_INVERTED = 1'b0; - parameter [0:0] IS_D_INVERTED = 1'b0; - parameter [0:0] IS_CLR_INVERTED = 1'b0; - parameter CLK_POLARITY = !IS_C_INVERTED; - parameter EN_POLARITY = 1'b1; - - FDCE #( - .INIT(INIT), - .IS_C_INVERTED(IS_C_INVERTED), - .IS_D_INVERTED(IS_D_INVERTED), - .IS_CLR_INVERTED(IS_CLR_INVERTED), - ) _TECHMAP_REPLACE_ ( - .D(D), .Q(Q), .C(C), .CE(CE), .CLR(CLR) - ); -endmodule - -module \$__ABC_FDCE_1 (output Q, - input C, - input CE, - input D, - input CLR, \$pastQ ); - parameter [0:0] INIT = 1'b0; - parameter CLK_POLARITY = 1'b0; - parameter EN_POLARITY = 1'b1; - - FDCE_1 #( - .INIT(INIT), - ) _TECHMAP_REPLACE_ ( - .D(D), .Q(Q), .C(C), .CE(CE), .CLR(CLR) - ); -endmodule - -module \$__ABC_FDPE (output Q, - input C, - input CE, - input D, - input PRE, \$pastQ ); - parameter [0:0] INIT = 1'b0; - parameter [0:0] IS_C_INVERTED = 1'b0; - parameter [0:0] IS_D_INVERTED = 1'b0; - parameter [0:0] IS_PRE_INVERTED = 1'b0; - parameter CLK_POLARITY = !IS_C_INVERTED; - parameter EN_POLARITY = 1'b1; - - FDPE #( - .INIT(INIT), - .IS_C_INVERTED(IS_C_INVERTED), - .IS_D_INVERTED(IS_D_INVERTED), - .IS_PRE_INVERTED(IS_PRE_INVERTED), - ) _TECHMAP_REPLACE_ ( - .D(D), .Q(Q), .C(C), .CE(CE), .PRE(PRE) - ); -endmodule - -module \$__ABC_FDPE_1 (output Q, - input C, - input CE, - input D, - input PRE, \$pastQ ); - parameter [0:0] INIT = 1'b0; - parameter CLK_POLARITY = 1'b0; - parameter EN_POLARITY = 1'b1; - - FDPE_1 #( - .INIT(INIT), - ) _TECHMAP_REPLACE_ ( - .D(D), .Q(Q), .C(C), .CE(CE), .PRE(PRE) - ); -endmodule - -module \$__ABC_LUT6 (input A, input [5:0] S, output Y); - assign Y = A; -endmodule -module \$__ABC_LUT7 (input A, input [6:0] S, output Y); - assign Y = A; +module \$__ABC_FF_ (input D, output Q); + assign Q = D; endmodule diff --git a/techlibs/xilinx/abc_xc7.box b/techlibs/xilinx/abc_xc7.box index aebb8b975..daaa4d16f 100644 --- a/techlibs/xilinx/abc_xc7.box +++ b/techlibs/xilinx/abc_xc7.box @@ -52,36 +52,46 @@ $__ABC_ASYNC 1000 0 2 1 # https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L237-L251 # https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L265-L277 -# Inputs: C CE D R \$pastQ +# Inputs: C CE D R \$currQ # Outputs: Q FDRE 1001 1 5 1 0 151 0 446 0 -# Inputs: C CE D R \$pastQ +# Inputs: C CE D R \$currQ # Outputs: Q FDRE_1 1002 1 5 1 0 151 0 446 0 -# Inputs: C CE CLR D \$pastQ +# Inputs: C CE CLR D \$currQ # Outputs: Q FDCE 1003 1 5 1 0 151 806 0 0 -# Inputs: C CE CLR D \$pastQ +# Inputs: C CE CLR D \$currQ # Outputs: Q FDCE_1 1004 1 5 1 0 151 806 0 0 -# Inputs: C CE D PRE \$pastQ +# Inputs: C CE D PRE \$currQ # Outputs: Q FDPE 1005 1 5 1 0 151 0 806 0 -# Inputs: C CE D PRE \$pastQ +# Inputs: C CE D PRE \$currQ # Outputs: Q FDPE_1 1006 1 5 1 0 151 0 806 0 +# Inputs: C CE D S \$currQ +# Outputs: Q +FDSE 1007 1 5 1 +0 151 0 446 0 + +# Inputs: C CE D S \$currQ +# Outputs: Q +FDSE_1 1008 1 5 1 +0 151 0 446 0 + # 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. diff --git a/techlibs/xilinx/cells_sim.v b/techlibs/xilinx/cells_sim.v index ef4340d10..ee9d48684 100644 --- a/techlibs/xilinx/cells_sim.v +++ b/techlibs/xilinx/cells_sim.v @@ -240,6 +240,7 @@ endmodule // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLL_L.sdf#L238-L250 +(* abc_box_id=1001, lib_whitebox, abc9_flop *) module FDRE ( (* abc_arrival=303 *) output reg Q, @@ -257,35 +258,72 @@ module FDRE ( parameter [0:0] IS_D_INVERTED = 1'b0; parameter [0:0] IS_R_INVERTED = 1'b0; initial Q <= INIT; + wire \$currQ ; + reg \$nextQ ; + always @* if (R == !IS_R_INVERTED) \$nextQ = 1'b0; else if (CE) \$nextQ = D ^ IS_D_INVERTED; else \$nextQ = \$currQ ; +`ifdef _ABC + // `abc9' requires that complex flops be split into a combinatorial + // box (this module) feeding a simple flop ($_ABC_FF_ in abc_map.v) + // In order to achieve clock-enable behaviour, the current value + // of the sequential output is required which Yosys will + // connect to the special `\$currQ' wire. + + // Special signal indicating clock domain + // (used to partition the module so that `abc9' only performs + // sequential synthesis (reachability analysis) correctly on + // one domain at a time) + wire [1:0] \$abc9_clock = {C, IS_C_INVERTED}; + // Special signal indicating control domain + // (which, combined with this spell type, encodes to `abc9' + // which flops may be merged together) + wire [3:0] \$abc9_control = {CE, IS_D_INVERTED, R, IS_R_INVERTED}; + always @* Q = \$nextQ ; +`else + assign \$currQ = Q; generate case (|IS_C_INVERTED) - 1'b0: always @(posedge C) if (R == !IS_R_INVERTED) Q <= 1'b0; else if (CE) Q <= D ^ IS_D_INVERTED; - 1'b1: always @(negedge C) if (R == !IS_R_INVERTED) Q <= 1'b0; else if (CE) Q <= D ^ IS_D_INVERTED; + 1'b0: always @(posedge C) Q <= \$nextQ ; + 1'b1: always @(negedge C) Q <= \$nextQ ; endcase endgenerate +`endif endmodule -module FDSE ( +(* abc_box_id=1002, lib_whitebox, abc9_flop *) +module FDRE_1 ( (* abc_arrival=303 *) output reg Q, (* clkbuf_sink *) - (* invertible_pin = "IS_C_INVERTED" *) input C, - input CE, - (* invertible_pin = "IS_D_INVERTED" *) - input D, - (* invertible_pin = "IS_S_INVERTED" *) - input S + input CE, D, R ); - 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; + parameter [0:0] INIT = 1'b0; initial Q <= INIT; - generate case (|IS_C_INVERTED) - 1'b0: always @(posedge C) if (S == !IS_S_INVERTED) Q <= 1'b1; else if (CE) Q <= D ^ IS_D_INVERTED; - 1'b1: always @(negedge C) if (S == !IS_S_INVERTED) Q <= 1'b1; else if (CE) Q <= D ^ IS_D_INVERTED; - endcase endgenerate + wire \$currQ ; + reg \$nextQ ; + always @* if (R) Q <= 1'b0; else if (CE) Q <= D; else \$nextQ = \$currQ ; +`ifdef _ABC + // `abc9' requires that complex flops be split into a combinatorial + // box (this module) feeding a simple flop ($_ABC_FF_ in abc_map.v) + // In order to achieve clock-enable behaviour, the current value + // of the sequential output is required which Yosys will + // connect to the special `\$currQ' wire. + + // Special signal indicating clock domain + // (used to partition the module so that `abc9' only performs + // sequential synthesis (reachability analysis) correctly on + // one domain at a time) + wire [1:0] \$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */}; + // Special signal indicating control domain + // (which, combined with this spell type, encodes to `abc9' + // which flops may be merged together) + wire [3:0] \$abc9_control = {CE, 1'b0 /* IS_D_INVERTED */, R, 1'b0 /* IS_R_INVERTED */}; + always @* Q = \$nextQ ; +`else + assign \$currQ = Q; + always @(negedge C) Q <= \$nextQ ; +`endif endmodule +(* abc_box_id=1003, lib_whitebox, abc9_flop *) module FDCE ( (* abc_arrival=303 *) output reg Q, @@ -303,14 +341,78 @@ module FDCE ( parameter [0:0] IS_D_INVERTED = 1'b0; parameter [0:0] IS_CLR_INVERTED = 1'b0; initial Q <= INIT; + wire \$currQ ; + reg \$nextQ ; + always @* if (CE) Q <= D ^ IS_D_INVERTED; else \$nextQ = \$currQ ; +`ifdef _ABC + // `abc9' requires that complex flops be split into a combinatorial + // box (this module) feeding a simple flop ($_ABC_FF_ in abc_map.v) + // In order to achieve clock-enable behaviour, the current value + // of the sequential output is required which Yosys will + // connect to the special `\$currQ' wire. + // Since this is an async flop, async behaviour is also dealt with + // using the $_ABC_ASYNC box by abc_map.v + + // Special signal indicating clock domain + // (used to partition the module so that `abc9' only performs + // sequential synthesis (reachability analysis) correctly on + // one domain at a time) + wire [1:0] \$abc9_clock = {C, IS_C_INVERTED}; + // Special signal indicating control domain + // (which, combined with this spell type, encodes to `abc9' + // which flops may be merged together) + wire [3:0] \$abc9_control = {CE, IS_D_INVERTED, CLR, IS_CLR_INVERTED}; + always @* Q = \$nextQ ; +`else + assign \$currQ = Q; generate case ({|IS_C_INVERTED, |IS_CLR_INVERTED}) - 2'b00: always @(posedge C, posedge CLR) if ( CLR) Q <= 1'b0; else if (CE) Q <= D ^ IS_D_INVERTED; - 2'b01: always @(posedge C, negedge CLR) if (!CLR) Q <= 1'b0; else if (CE) Q <= D ^ IS_D_INVERTED; - 2'b10: always @(negedge C, posedge CLR) if ( CLR) Q <= 1'b0; else if (CE) Q <= D ^ IS_D_INVERTED; - 2'b11: always @(negedge C, negedge CLR) if (!CLR) Q <= 1'b0; else if (CE) Q <= D ^ IS_D_INVERTED; + 2'b00: always @(posedge C, posedge CLR) if ( CLR) Q <= 1'b0; else Q <= \$nextQ ; + 2'b01: always @(posedge C, negedge CLR) if (!CLR) Q <= 1'b0; else Q <= \$nextQ ; + 2'b10: always @(negedge C, posedge CLR) if ( CLR) Q <= 1'b0; else Q <= \$nextQ ; + 2'b11: always @(negedge C, negedge CLR) if (!CLR) Q <= 1'b0; else Q <= \$nextQ ; endcase endgenerate +`endif endmodule +(* abc_box_id=1004, lib_whitebox, abc9_flop *) +module FDCE_1 ( + (* abc_arrival=303 *) + output reg Q, + (* clkbuf_sink *) + input C, + input CE, D, CLR +); + parameter [0:0] INIT = 1'b0; + initial Q <= INIT; + wire \$currQ ; + reg \$nextQ ; + always @* if (CE) Q <= D; else \$nextQ = \$currQ ; +`ifdef _ABC + // `abc9' requires that complex flops be split into a combinatorial + // box (this module) feeding a simple flop ($_ABC_FF_ in abc_map.v) + // In order to achieve clock-enable behaviour, the current value + // of the sequential output is required which Yosys will + // connect to the special `\$currQ' wire. + // Since this is an async flop, async behaviour is also dealt with + // using the $_ABC_ASYNC box by abc_map.v + + // Special signal indicating clock domain + // (used to partition the module so that `abc9' only performs + // sequential synthesis (reachability analysis) correctly on + // one domain at a time) + wire [1:0] \$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */}; + // Special signal indicating control domain + // (which, combined with this spell type, encodes to `abc9' + // which flops may be merged together) + wire [3:0] \$abc9_control = {CE, 1'b0 /* IS_D_INVERTED */, CLR, 1'b0 /* IS_CLR_INVERTED */}; + always @* Q = \$nextQ ; +`else + assign \$currQ = Q; + always @(negedge C, posedge CLR) if (CLR == !IS_CLR_INVERTED) Q <= 1'b0; else Q <= \$nextQ ; +`endif +endmodule + +(* abc_box_id=1005, lib_whitebox, abc9_flop *) module FDPE ( (* abc_arrival=303 *) output reg Q, @@ -328,60 +430,158 @@ module FDPE ( parameter [0:0] IS_D_INVERTED = 1'b0; parameter [0:0] IS_PRE_INVERTED = 1'b0; initial Q <= INIT; + wire \$currQ ; + reg \$nextQ ; + always @* if (CE) Q <= D ^ IS_D_INVERTED; else \$nextQ = \$currQ ; +`ifdef _ABC + // `abc9' requires that complex flops be split into a combinatorial + // box (this module) feeding a simple flop ($_ABC_FF_ in abc_map.v) + // In order to achieve clock-enable behaviour, the current value + // of the sequential output is required which Yosys will + // connect to the special `\$currQ' wire. + // Since this is an async flop, async behaviour is also dealt with + // using the $_ABC_ASYNC box by abc_map.v + + // Special signal indicating clock domain + // (used to partition the module so that `abc9' only performs + // sequential synthesis (reachability analysis) correctly on + // one domain at a time) + wire [1:0] \$abc9_clock = {C, IS_C_INVERTED}; + // Special signal indicating control domain + // (which, combined with this spell type, encodes to `abc9' + // which flops may be merged together) + wire [3:0] \$abc9_control = {CE, IS_D_INVERTED, PRE, IS_PRE_INVERTED}; + always @* Q = \$nextQ ; +`else + assign \$currQ = Q; generate case ({|IS_C_INVERTED, |IS_PRE_INVERTED}) - 2'b00: always @(posedge C, posedge PRE) if ( PRE) Q <= 1'b1; else if (CE) Q <= D ^ IS_D_INVERTED; - 2'b01: always @(posedge C, negedge PRE) if (!PRE) Q <= 1'b1; else if (CE) Q <= D ^ IS_D_INVERTED; - 2'b10: always @(negedge C, posedge PRE) if ( PRE) Q <= 1'b1; else if (CE) Q <= D ^ IS_D_INVERTED; - 2'b11: always @(negedge C, negedge PRE) if (!PRE) Q <= 1'b1; else if (CE) Q <= D ^ IS_D_INVERTED; + 2'b00: always @(posedge C, posedge PRE) if ( PRE) Q <= 1'b1; else Q <= \$nextQ ; + 2'b01: always @(posedge C, negedge PRE) if (!PRE) Q <= 1'b1; else Q <= \$nextQ ; + 2'b10: always @(negedge C, posedge PRE) if ( PRE) Q <= 1'b1; else Q <= \$nextQ ; + 2'b11: always @(negedge C, negedge PRE) if (!PRE) Q <= 1'b1; else Q <= \$nextQ ; endcase endgenerate +`endif endmodule -module FDRE_1 ( - (* abc_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 ( +(* abc_box_id=1006, lib_whitebox, abc9_flop *) +module FDPE_1 ( (* abc_arrival=303 *) output reg Q, (* clkbuf_sink *) input C, - input CE, D, S + input CE, D, PRE ); parameter [0:0] INIT = 1'b1; initial Q <= INIT; - always @(negedge C) if (S) Q <= 1'b1; else if(CE) Q <= D; + wire \$currQ ; + reg \$nextQ ; + always @* if (CE) Q <= D; else \$nextQ = \$currQ ; +`ifdef _ABC + // `abc9' requires that complex flops be split into a combinatorial + // box (this module) feeding a simple flop ($_ABC_FF_ in abc_map.v) + // In order to achieve clock-enable behaviour, the current value + // of the sequential output is required which Yosys will + // connect to the special `\$currQ' wire. + // Since this is an async flop, async behaviour is also dealt with + // using the $_ABC_ASYNC box by abc_map.v + + // Special signal indicating clock domain + // (used to partition the module so that `abc9' only performs + // sequential synthesis (reachability analysis) correctly on + // one domain at a time) + wire [1:0] \$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */}; + // Special signal indicating control domain + // (which, combined with this spell type, encodes to `abc9' + // which flops may be merged together) + wire [3:0] \$abc9_control = {CE, 1'b0 /* IS_D_INVERTED */, PRE, 1'b0 /* IS_PRE_INVERTED */}; + always @* Q = \$nextQ ; +`else + assign \$currQ = Q; + always @(negedge C, posedge PRE) if (PRE) Q <= 1'b1; else Q <= \$nextQ ; +`endif endmodule -module FDCE_1 ( +(* abc_box_id=1007, lib_whitebox, abc9_flop *) +module FDSE ( (* abc_arrival=303 *) output reg Q, (* clkbuf_sink *) + (* invertible_pin = "IS_C_INVERTED" *) input C, - input CE, D, CLR + input CE, + (* invertible_pin = "IS_D_INVERTED" *) + input D, + (* invertible_pin = "IS_S_INVERTED" *) + input S ); - parameter [0:0] INIT = 1'b0; + 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; initial Q <= INIT; - always @(negedge C, posedge CLR) if (CLR) Q <= 1'b0; else if (CE) Q <= D; + wire \$currQ ; + reg \$nextQ ; + always @* if (S == !IS_S_INVERTED) \$nextQ = 1'b1; else if (CE) \$nextQ = D ^ IS_D_INVERTED; else \$nextQ = \$currQ ; +`ifdef _ABC + // `abc9' requires that complex flops be split into a combinatorial + // box (this module) feeding a simple flop ($_ABC_FF_ in abc_map.v) + // In order to achieve clock-enable behaviour, the current value + // of the sequential output is required which Yosys will + // connect to the special `\$currQ' wire. + + // Special signal indicating clock domain + // (used to partition the module so that `abc9' only performs + // sequential synthesis (reachability analysis) correctly on + // one domain at a time) + wire [1:0] \$abc9_clock = {C, IS_C_INVERTED}; + // Special signal indicating control domain + // (which, combined with this spell type, encodes to `abc9' + // which flops may be merged together) + wire [3:0] \$abc9_control = {CE, IS_D_INVERTED, S, IS_S_INVERTED}; + always @* Q = \$nextQ ; +`else + assign \$currQ = Q; + generate case (|IS_C_INVERTED) + 1'b0: always @(posedge C) Q <= \$nextQ ; + 1'b1: always @(negedge C) Q <= \$nextQ ; + endcase endgenerate +`endif endmodule -module FDPE_1 ( +(* abc_box_id=1008, lib_whitebox, abc9_flop *) +module FDSE_1 ( (* abc_arrival=303 *) output reg Q, (* clkbuf_sink *) input C, - input CE, D, PRE + input CE, D, S ); parameter [0:0] INIT = 1'b1; initial Q <= INIT; - always @(negedge C, posedge PRE) if (PRE) Q <= 1'b1; else if (CE) Q <= D; + wire \$currQ ; + reg \$nextQ ; + always @* if (S) \$nextQ = 1'b1; else if (CE) \$nextQ = D; else \$nextQ = \$currQ ; +`ifdef _ABC + // `abc9' requires that complex flops be split into a combinatorial + // box (this module) feeding a simple flop ($_ABC_FF_ in abc_map.v) + // In order to achieve clock-enable behaviour, the current value + // of the sequential output is required which Yosys will + // connect to the special `\$currQ' wire. + + // Special signal indicating clock domain + // (used to partition the module so that `abc9' only performs + // sequential synthesis (reachability analysis) correctly on + // one domain at a time) + wire [1:0] \$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */}; + // Special signal indicating control domain + // (which, combined with this spell type, encodes to `abc9' + // which flops may be merged together) + wire [3:0] \$abc9_control = {CE, 1'b0 /* IS_D_INVERTED */, S, 1'b0 /* IS_S_INVERTED */}; + always @* Q = \$nextQ ; +`else + assign \$currQ = Q; + always @(negedge C) Q <= \$nextQ ; +`endif endmodule module RAM32X1D ( diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index 888b5ed7b..f5143ca82 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -276,9 +276,9 @@ struct SynthXilinxPass : public ScriptPass if (check_label("begin")) { if (vpr) - run("read_verilog -lib -D_EXPLICIT_CARRY +/xilinx/cells_sim.v"); + run("read_verilog -lib -D_ABC -D_EXPLICIT_CARRY +/xilinx/cells_sim.v"); else - run("read_verilog -lib +/xilinx/cells_sim.v"); + run("read_verilog -lib -D_ABC +/xilinx/cells_sim.v"); if (help_mode) run("read_verilog -lib +/xilinx/{family}_cells_xtra.v"); -- cgit v1.2.3 From 5a4011e8c9d2c7c94ccaa6ff80a1ca1290e1053b Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Sun, 29 Sep 2019 09:58:00 -0700 Subject: Fix "scc" call inside abc9 to consider all wires --- passes/techmap/abc9.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index a5d823139..ce27f7eea 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -75,7 +75,7 @@ inline std::string remap_name(RTLIL::IdString abc_name) void handle_loops(RTLIL::Design *design) { - Pass::call(design, "scc -set_attr abc_scc_id {}"); + Pass::call(design, "scc -set_attr abc_scc_id {} % w:*"); // For every unique SCC found, (arbitrarily) find the first // cell in the component, and select (and mark) all its output -- cgit v1.2.3 From 18ebb86edbade4a94833dead59d69fddd980f5bd Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Sun, 29 Sep 2019 11:25:34 -0700 Subject: FDCE_1 does not have IS_CLR_INVERTED --- techlibs/xilinx/cells_sim.v | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/techlibs/xilinx/cells_sim.v b/techlibs/xilinx/cells_sim.v index ee9d48684..cf39bd45b 100644 --- a/techlibs/xilinx/cells_sim.v +++ b/techlibs/xilinx/cells_sim.v @@ -408,7 +408,7 @@ module FDCE_1 ( always @* Q = \$nextQ ; `else assign \$currQ = Q; - always @(negedge C, posedge CLR) if (CLR == !IS_CLR_INVERTED) Q <= 1'b0; else Q <= \$nextQ ; + always @(negedge C, posedge CLR) if (CLR) Q <= 1'b0; else Q <= \$nextQ ; `endif endmodule -- cgit v1.2.3 From f6203e6bd65f7383f14a15e926fc4b8f5f9a3edf Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Sun, 29 Sep 2019 21:55:53 -0700 Subject: Missing endmodule --- techlibs/xilinx/abc_model.v | 1 + 1 file changed, 1 insertion(+) diff --git a/techlibs/xilinx/abc_model.v b/techlibs/xilinx/abc_model.v index b302e46f6..8255804c2 100644 --- a/techlibs/xilinx/abc_model.v +++ b/techlibs/xilinx/abc_model.v @@ -35,6 +35,7 @@ endmodule (* abc_box_id = 1000 *) module \$__ABC_ASYNC (input A, S, output Y); +endmodule // Box to emulate comb/seq behaviour of RAMD{32,64} and SRL{16,32} // Necessary since RAMD* and SRL* have both combinatorial (i.e. -- cgit v1.2.3 From bd8356799aaee629b747984fd01d3ef4d1182a27 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 30 Sep 2019 12:34:28 -0700 Subject: Use derived module --- backends/aiger/xaiger.cc | 27 +++++---------------------- 1 file changed, 5 insertions(+), 22 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 616aca074..6907ccecc 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -808,6 +808,11 @@ struct XAigerWriter int box_count = 0; for (auto cell : box_list) { RTLIL::Module* box_module = module->design->module(cell->type); + if (box_module->get_bool_attribute("\\abc9_flop")) { + auto derived_name = box_module->derive(module->design, cell->parameters); + box_module = module->design->module(derived_name); + } + int box_inputs = 0, box_outputs = 0; Cell *holes_cell = nullptr; if (box_module->get_bool_attribute("\\whitebox")) { @@ -858,28 +863,6 @@ struct XAigerWriter } } - if (box_module->get_bool_attribute("\\abc9_flop")) { - log_assert(holes_cell); - IdString port_name = "\\$currQ"; - Wire* w = box_module->wire(port_name); - SigSpec rhs = cell->getPort(port_name); - log_assert(GetSize(w) == GetSize(rhs)); - SigSpec port_wire; - Wire *holes_wire; - 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); - } - port_wire.append(holes_wire); - } - holes_cell->setPort(w->name, port_wire); - } - write_h_buffer(box_inputs); write_h_buffer(box_outputs); write_h_buffer(box_module->attributes.at("\\abc_box_id").as_int()); -- cgit v1.2.3 From a6994c5f167c530e0dc81afcac5836ae66447a92 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 30 Sep 2019 12:57:19 -0700 Subject: scc call on active module module only, plus cleanup --- backends/aiger/xaiger.cc | 20 ++++++++++++-------- passes/techmap/abc9.cc | 37 ++++++++++++++++--------------------- 2 files changed, 28 insertions(+), 29 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 6907ccecc..3ae57bd3a 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -915,30 +915,34 @@ struct XAigerWriter //holes_module->fixup_ports(); holes_module->check(); - holes_module->design->selection_stack.emplace_back(false); - RTLIL::Selection& sel = holes_module->design->selection_stack.back(); + Design *design = holes_module->design; + design->selection_stack.emplace_back(false); + RTLIL::Selection& sel = design->selection_stack.back(); + log_assert(design->selected_active_module == module->name.c_str()); + design->selected_active_module = holes_module->name.str(); sel.select(holes_module); // TODO: Should not need to opt_merge if we only instantiate // each box type once... - Pass::call(holes_module->design, "opt_merge -share_all"); + Pass::call(design, "opt_merge -share_all"); - Pass::call(holes_module->design, "flatten -wb"); + Pass::call(design, "flatten -wb"); // TODO: Should techmap/aigmap/check all lib_whitebox-es just once, // instead of per write_xaiger call - Pass::call(holes_module->design, "techmap"); - Pass::call(holes_module->design, "aigmap"); + Pass::call(design, "techmap"); + Pass::call(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(); + design->selection_stack.pop_back(); + design->selected_active_module = module->name.str(); // 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); + design->modules_.erase(holes_module->name); holes_design->add(holes_module); Pass::call(holes_design, "clean -purge"); diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 0276283a5..33f608d29 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -65,16 +65,15 @@ PRIVATE_NAMESPACE_BEGIN bool markgroups; int map_autoidx; -SigMap assign_map; -RTLIL::Module *module; inline std::string remap_name(RTLIL::IdString abc_name) { return stringf("$abc$%d$%s", map_autoidx, abc_name.c_str()+1); } -void handle_loops(RTLIL::Design *design) +void handle_loops(RTLIL::Design *design, RTLIL::Module *module) { + // FIXME: Do not run on all modules in design!?! Pass::call(design, "scc -set_attr abc_scc_id {} % w:*"); // For every unique SCC found, (arbitrarily) find the first @@ -240,14 +239,13 @@ struct abc_output_filter } }; -void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::string script_file, std::string exe_file, +void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string script_file, std::string exe_file, bool cleanup, vector lut_costs, bool /*dff_mode*/, std::string /*clk_str*/, bool /*keepff*/, std::string delay_target, std::string /*lutin_shared*/, bool fast_mode, bool show_tempdir, std::string box_file, std::string lut_file, std::string wire_delay, const dict &box_lookup ) { - module = current_module; map_autoidx = autoidx++; std::string tempdir_name = "/tmp/yosys-abc-XXXXXX"; @@ -335,7 +333,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri if (count_output) { - handle_loops(design); + handle_loops(design, module); Pass::call(design, "aigmap -select"); @@ -862,8 +860,6 @@ struct Abc9Pass : public Pass { log_header(design, "Executing ABC9 pass (technology mapping using ABC9).\n"); log_push(); - assign_map.clear(); - #ifdef ABCEXTERNAL std::string exe_file = ABCEXTERNAL; #else @@ -1068,21 +1064,21 @@ struct Abc9Pass : public Pass { } } - for (auto mod : design->selected_modules()) + for (auto module : design->selected_modules()) { - if (mod->attributes.count(ID(abc_box_id))) + if (module->attributes.count(ID(abc_box_id))) continue; - if (mod->processes.size() > 0) { - log("Skipping module %s as it contains processes.\n", log_id(mod)); + if (module->processes.size() > 0) { + log("Skipping module %s as it contains processes.\n", log_id(module)); continue; } - assign_map.set(mod); + SigMap assign_map(module); CellTypes ct(design); - std::vector all_cells = mod->selected_cells(); + std::vector all_cells = module->selected_cells(); std::set unassigned_cells(all_cells.begin(), all_cells.end()); std::set expand_queue, next_expand_queue; @@ -1154,7 +1150,7 @@ struct Abc9Pass : public Pass { SigSpec abc9_clock = derived_sigmap(abc9_clock_wire); abc9_clock.replace(pattern, with); for (const auto &c : abc9_clock.chunks()) - log_assert(!c.wire || c.wire->module == mod); + log_assert(!c.wire || c.wire->module == module); Wire *abc9_control_wire = derived_module->wire("\\$abc9_control"); if (abc9_control_wire == NULL) @@ -1162,7 +1158,7 @@ struct Abc9Pass : public Pass { SigSpec abc9_control = derived_sigmap(abc9_control_wire); abc9_control.replace(pattern, with); for (const auto &c : abc9_control.chunks()) - log_assert(!c.wire || c.wire->module == mod); + log_assert(!c.wire || c.wire->module == module); unassigned_cells.erase(cell); expand_queue.insert(cell); @@ -1252,19 +1248,18 @@ struct Abc9Pass : public Pass { log(" %d cells in clk=%s\n", GetSize(it.second), log_signal(it.first)); design->selection_stack.emplace_back(false); + design->selected_active_module = module->name.str(); for (auto &it : assigned_cells) { RTLIL::Selection& sel = design->selection_stack.back(); - sel.selected_members[mod->name] = std::move(it.second); - abc9_module(design, mod, script_file, exe_file, cleanup, lut_costs, false, "$", + sel.selected_members[module->name] = std::move(it.second); + abc9_module(design, module, script_file, exe_file, cleanup, lut_costs, false, "$", keepff, delay_target, lutin_shared, fast_mode, show_tempdir, box_file, lut_file, wire_delay, box_lookup); - assign_map.set(mod); } design->selection_stack.pop_back(); + design->selected_active_module.clear(); } - assign_map.clear(); - log_pop(); } } Abc9Pass; -- cgit v1.2.3 From 74678227c73d0ba1dfa391ba93bd2010ce3202c1 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 30 Sep 2019 13:21:07 -0700 Subject: Use a cell_cache to instantiate once rather than opt_merge call --- backends/aiger/xaiger.cc | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 3ae57bd3a..1aa2bc62e 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -804,20 +804,23 @@ struct XAigerWriter RTLIL::Module *holes_module = module->design->addModule("$__holes__"); log_assert(holes_module); + dict cell_cache; + int port_id = 1; int box_count = 0; for (auto cell : box_list) { RTLIL::Module* box_module = module->design->module(cell->type); - if (box_module->get_bool_attribute("\\abc9_flop")) { - auto derived_name = box_module->derive(module->design, cell->parameters); - box_module = module->design->module(derived_name); - } + log_assert(box_module); + IdString derived_name = box_module->derive(module->design, cell->parameters); + box_module = module->design->module(derived_name); int box_inputs = 0, box_outputs = 0; - Cell *holes_cell = nullptr; - if (box_module->get_bool_attribute("\\whitebox")) { + 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 @@ -827,7 +830,7 @@ struct XAigerWriter log_assert(w); RTLIL::Wire *holes_wire; RTLIL::SigSpec port_wire; - if (w->port_input) { + if (w->port_input) for (int i = 0; i < GetSize(w); i++) { box_inputs++; holes_wire = holes_module->wire(stringf("\\i%d", box_inputs)); @@ -840,9 +843,6 @@ struct XAigerWriter if (holes_cell) port_wire.append(holes_wire); } - if (!port_wire.empty()) - holes_cell->setPort(w->name, port_wire); - } if (w->port_output) { box_outputs += GetSize(w); for (int i = 0; i < GetSize(w); i++) { @@ -858,8 +858,12 @@ struct XAigerWriter else holes_module->connect(holes_wire, State::S0); } - if (!port_wire.empty()) + } + if (!port_wire.empty()) { + if (r.second) holes_cell->setPort(w->name, port_wire); + else + holes_module->connect(port_wire, holes_cell->getPort(w->name)); } } @@ -922,10 +926,6 @@ struct XAigerWriter design->selected_active_module = holes_module->name.str(); sel.select(holes_module); - // TODO: Should not need to opt_merge if we only instantiate - // each box type once... - Pass::call(design, "opt_merge -share_all"); - Pass::call(design, "flatten -wb"); // TODO: Should techmap/aigmap/check all lib_whitebox-es just once, -- cgit v1.2.3 From e0aa772663a95fb5417d9fbe64f27ac8c7395bf0 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 30 Sep 2019 15:19:02 -0700 Subject: Add comment --- passes/techmap/abc9.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 33f608d29..6e424d517 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -1117,6 +1117,7 @@ struct Abc9Pass : public Pass { auto derived_name = inst_module->derive(design, cell->parameters); auto derived_module = design->module(derived_name); log_assert(derived_module); + // FIXME: call once Pass::call_on_module(design, derived_module, "proc"); SigMap derived_sigmap(derived_module); -- cgit v1.2.3 From eecfdda6144856f399f0440d82595ca05c11e41b Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 30 Sep 2019 15:24:03 -0700 Subject: Cleanup --- backends/aiger/xaiger.cc | 103 ++--------------------------------------------- 1 file changed, 3 insertions(+), 100 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 1aa2bc62e..52273e9b9 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -81,7 +81,7 @@ struct XAigerWriter dict init_map; pool input_bits, output_bits; - dict not_map, /*ff_map,*/ alias_map; + dict not_map, alias_map; dict> and_map; vector> ci_bits; vector> co_bits; @@ -89,7 +89,7 @@ struct XAigerWriter dict arrival_times; vector> aig_gates; - vector aig_latchin, aig_latchinit, aig_outputs; + vector aig_outputs; int aig_m = 0, aig_i = 0, aig_l = 0, aig_o = 0, aig_a = 0; dict aig_map; @@ -99,9 +99,6 @@ struct XAigerWriter vector box_list; bool omode = false; - //dict init_inputs; - //int initstate_ff = 0; - int mkgate(int a0, int a1) { aig_m++, aig_a++; @@ -561,7 +558,6 @@ struct XAigerWriter log_warning("Treating a total of %d undriven bits in %s like $anyseq.\n", GetSize(undriven_bits), log_id(module)); } - init_map.sort(); if (holes_mode) { struct sort_by_port_id { bool operator()(const RTLIL::SigBit& a, const RTLIL::SigBit& b) const { @@ -577,7 +573,6 @@ struct XAigerWriter } not_map.sort(); - //ff_map.sort(); and_map.sort(); aig_map[State::S0] = 0; @@ -605,62 +600,6 @@ struct XAigerWriter ff_aig_map[bit] = 2*aig_m; } - //if (zinit_mode) - //{ - // for (auto it : ff_map) { - // if (init_map.count(it.first)) - // continue; - // aig_m++, aig_i++; - // init_inputs[it.first] = 2*aig_m; - // } - //} - - //for (auto it : ff_map) { - // aig_m++, aig_l++; - // aig_map[it.first] = 2*aig_m; - // ordered_latches[it.first] = aig_l-1; - // if (init_map.count(it.first) == 0) - // aig_latchinit.push_back(2); - // else - // aig_latchinit.push_back(init_map.at(it.first) ? 1 : 0); - //} - - //if (!init_inputs.empty()) { - // aig_m++, aig_l++; - // initstate_ff = 2*aig_m+1; - // aig_latchinit.push_back(0); - //} - - //if (zinit_mode) - //{ - // for (auto it : ff_map) - // { - // int l = ordered_latches[it.first]; - - // if (aig_latchinit.at(l) == 1) - // aig_map[it.first] ^= 1; - - // if (aig_latchinit.at(l) == 2) - // { - // int gated_ffout = mkgate(aig_map[it.first], initstate_ff^1); - // int gated_initin = mkgate(init_inputs[it.first], initstate_ff); - // aig_map[it.first] = mkgate(gated_ffout^1, gated_initin^1)^1; - // } - // } - //} - - //for (auto it : ff_map) { - // int a = bit2aig(it.second); - // int l = ordered_latches[it.first]; - // if (zinit_mode && aig_latchinit.at(l) == 1) - // aig_latchin.push_back(a ^ 1); - // else - // aig_latchin.push_back(a); - //} - - //if (!init_inputs.empty()) - // aig_latchin.push_back(1); - for (auto &c : co_bits) { RTLIL::SigBit bit = std::get<0>(c); std::get<4>(c) = ordered_outputs[bit] = aig_o++; @@ -697,8 +636,6 @@ struct XAigerWriter int aig_obcjf = aig_obcj; log_assert(aig_m == aig_i + aig_l + aig_a); - log_assert(aig_l == GetSize(aig_latchin)); - log_assert(aig_l == GetSize(aig_latchinit)); log_assert(aig_obcjf == GetSize(aig_outputs)); f << stringf("%s %d %d %d %d %d", ascii_mode ? "aag" : "aig", aig_m, aig_i, aig_l, aig_o, aig_a); @@ -709,15 +646,6 @@ struct XAigerWriter for (int i = 0; i < aig_i; i++) f << stringf("%d\n", 2*i+2); - //for (int i = 0; i < aig_l; i++) { - // if (zinit_mode || aig_latchinit.at(i) == 0) - // f << stringf("%d %d\n", 2*(aig_i+i)+2, aig_latchin.at(i)); - // else if (aig_latchinit.at(i) == 1) - // f << stringf("%d %d 1\n", 2*(aig_i+i)+2, aig_latchin.at(i)); - // else if (aig_latchinit.at(i) == 2) - // f << stringf("%d %d %d\n", 2*(aig_i+i)+2, aig_latchin.at(i), 2*(aig_i+i)+2); - //} - for (int i = 0; i < aig_obc; i++) f << stringf("%d\n", aig_outputs.at(i)); @@ -735,15 +663,6 @@ struct XAigerWriter } else { - //for (int i = 0; i < aig_l; i++) { - // if (zinit_mode || aig_latchinit.at(i) == 0) - // f << stringf("%d\n", aig_latchin.at(i)); - // else if (aig_latchinit.at(i) == 1) - // f << stringf("%d 1\n", aig_latchin.at(i)); - // else if (aig_latchinit.at(i) == 2) - // f << stringf("%d %d\n", aig_latchin.at(i), 2*(aig_i+i)+2); - //} - for (int i = 0; i < aig_obc; i++) f << stringf("%d\n", aig_outputs.at(i)); @@ -1008,7 +927,7 @@ struct XAigerWriter if (output_bits.count(b)) { int o = ordered_outputs.at(b); - int init = 2; + int init = zinit_mode ? 0 : 2; auto it = init_map.find(b); if (it != init_map.end()) init = it->second ? 1 : 0; @@ -1016,22 +935,6 @@ struct XAigerWriter continue; } - //if (init_inputs.count(sig[i])) { - // int a = init_inputs.at(sig[i]); - // log_assert((a & 1) == 0); - // init_lines[a] += stringf("init %d %d %s\n", (a >> 1)-1, i, log_id(wire)); - // continue; - //} - - //if (ordered_latches.count(sig[i])) { - // int l = ordered_latches.at(sig[i]); - // if (zinit_mode && (aig_latchinit.at(l) == 1)) - // latch_lines[l] += stringf("invlatch %d %d %s\n", l, i, log_id(wire)); - // else - // latch_lines[l] += stringf("latch %d %d %s\n", l, i, log_id(wire)); - // continue; - //} - if (verbose_map) { if (aig_map.count(sig[i]) == 0) continue; -- cgit v1.2.3 From 5e9ae90cbba4e9c2abfe5d6a1b90c2256aae1615 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 30 Sep 2019 15:39:24 -0700 Subject: Add explanation to abc_map.v --- techlibs/xilinx/abc_map.v | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/techlibs/xilinx/abc_map.v b/techlibs/xilinx/abc_map.v index cb252b828..6a0e18abe 100644 --- a/techlibs/xilinx/abc_map.v +++ b/techlibs/xilinx/abc_map.v @@ -18,8 +18,24 @@ * */ +// 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. +// +// 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. + // ============================================================================ +// The purpose of the following FD* rules are to wrap the flop (which, when +// called with the `_ABC' macro set captures contains only its combinatorial +// behaviour) with: +// (a) a special $__ABC_FF_ in front of the FD*'s output, indicating to abc9 +// the location of its basic D-Q flop +// (b) a special \$currQ connection that feeds back into the (combinatorial) +// FD* cell to facilitate clock-enable behaviour -- note that \$currQ +// isn't a real input port, it is one that is understood only by abc9 module FDRE (output reg Q, input C, CE, D, R); parameter [0:0] INIT = 1'b0; parameter [0:0] IS_C_INVERTED = 1'b0; -- cgit v1.2.3 From e529872b0170ba269db2d00c96108c86b260e864 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 30 Sep 2019 16:33:40 -0700 Subject: Remove need for $currQ port connection --- backends/aiger/xaiger.cc | 6 +- passes/techmap/techmap.cc | 8 +++ techlibs/xilinx/abc_map.v | 69 ++++++++++--------- techlibs/xilinx/cells_sim.v | 160 ++++++++++++++++++++++---------------------- 4 files changed, 129 insertions(+), 114 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 52273e9b9..65792421f 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -483,12 +483,12 @@ struct XAigerWriter if (box_module->get_bool_attribute("\\abc9_flop")) { IdString port_name = "\\$currQ"; - RTLIL::Wire* w = box_module->wire(port_name); - SigSpec rhs = cell->getPort(port_name); + Wire *w = box_module->wire(port_name); + SigSpec rhs = module->wire(stringf("%s.$currQ", cell->name.c_str())); log_assert(GetSize(w) == GetSize(rhs)); int offset = 0; - for (auto b : rhs.bits()) { + for (auto b : rhs) { SigBit I = sigmap(b); if (b == RTLIL::Sx) b = State::S0; diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index 08a1af2d5..c2dc9b959 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -256,6 +256,14 @@ struct TechmapWorker if (w->attributes.count(ID(src))) w->add_strpool_attribute(ID(src), extra_src_attrs); } + + + if (it.second->name.begins_with("\\_TECHMAP_REPLACE_")) { + IdString replace_name = stringf("%s%s", orig_cell_name.c_str(), it.second->name.c_str() + strlen("\\_TECHMAP_REPLACE_")); + Wire *replace_w = module->addWire(replace_name, it.second); + module->connect(replace_w, w); + } + design->select(module, w); } diff --git a/techlibs/xilinx/abc_map.v b/techlibs/xilinx/abc_map.v index 6a0e18abe..4eec77df9 100644 --- a/techlibs/xilinx/abc_map.v +++ b/techlibs/xilinx/abc_map.v @@ -33,34 +33,35 @@ // behaviour) with: // (a) a special $__ABC_FF_ in front of the FD*'s output, indicating to abc9 // the location of its basic D-Q flop -// (b) a special \$currQ connection that feeds back into the (combinatorial) -// FD* cell to facilitate clock-enable behaviour -- note that \$currQ -// isn't a real input port, it is one that is understood only by abc9 +// (b) a special TECHMAP_REPLACE_.$currQwire that will be used for feedback +// into the (combinatorial) FD* cell to facilitate clock-enable behaviour module FDRE (output reg Q, input C, CE, D, R); parameter [0:0] INIT = 1'b0; parameter [0:0] IS_C_INVERTED = 1'b0; parameter [0:0] IS_D_INVERTED = 1'b0; parameter [0:0] IS_R_INVERTED = 1'b0; - wire \$nextQ ; + wire $nextQ; FDRE #( .INIT(INIT), .IS_C_INVERTED(IS_C_INVERTED), .IS_D_INVERTED(IS_D_INVERTED), .IS_R_INVERTED(IS_R_INVERTED) ) _TECHMAP_REPLACE_ ( - .D(D), .Q(\$nextQ ), .\$currQ (Q), .C(C), .CE(CE), .R(R) + .D(D), .Q($nextQ), .C(C), .CE(CE), .R(R) ); - \$__ABC_FF_ abc_dff (.D(\$nextQ ), .Q(Q)); + wire _TECHMAP_REPLACE_.$currQ = Q; + \$__ABC_FF_ abc_dff (.D($nextQ), .Q(Q)); endmodule module FDRE_1 (output reg Q, input C, CE, D, R); parameter [0:0] INIT = 1'b0; - wire \$nextQ ; + wire $nextQ; FDRE_1 #( .INIT(|0), ) _TECHMAP_REPLACE_ ( - .D(D), .Q(\$nextQ ), .\$currQ (Q), .C(C), .CE(CE), .R(R) + .D(D), .Q($nextQ), .C(C), .CE(CE), .R(R) ); - \$__ABC_FF_ abc_dff (.D(\$nextQ ), .Q(Q)); + wire _TECHMAP_REPLACE_.$currQ = Q; + \$__ABC_FF_ abc_dff (.D($nextQ), .Q(Q)); endmodule module FDCE (output reg Q, input C, CE, D, CLR); @@ -68,28 +69,30 @@ module FDCE (output reg Q, input C, CE, D, CLR); parameter [0:0] IS_C_INVERTED = 1'b0; parameter [0:0] IS_D_INVERTED = 1'b0; parameter [0:0] IS_CLR_INVERTED = 1'b0; - wire \$nextQ , \$currQ ; + wire $currQ, $nextQ; FDCE #( .INIT(INIT), .IS_C_INVERTED(IS_C_INVERTED), .IS_D_INVERTED(IS_D_INVERTED), .IS_CLR_INVERTED(IS_CLR_INVERTED) ) _TECHMAP_REPLACE_ ( - .D(D), .Q(\$nextQ ), .\$currQ (Q), .C(C), .CE(CE), .CLR(CLR) + .D(D), .Q($nextQ), .C(C), .CE(CE), .CLR(CLR) ); - \$__ABC_FF_ abc_dff (.D(\$nextQ ), .Q(\$currQ )); - \$__ABC_ASYNC abc_async (.A(\$currQ ), .S(CLR ^ IS_CLR_INVERTED), .Y(Q)); + wire _TECHMAP_REPLACE_.$currQ = Q; + \$__ABC_FF_ abc_dff (.D($nextQ), .Q($currQ)); + \$__ABC_ASYNC abc_async (.A($currQ), .S(CLR ^ IS_CLR_INVERTED), .Y(Q)); endmodule module FDCE_1 (output reg Q, input C, CE, D, CLR); parameter [0:0] INIT = 1'b0; - wire \$nextQ , \$currQ ; + wire $nextQ, $currQ; FDCE_1 #( .INIT(INIT) ) _TECHMAP_REPLACE_ ( - .D(D), .Q(\$nextQ ), .\$currQ (Q), .C(C), .CE(CE), .CLR(CLR) + .D(D), .Q($nextQ), .C(C), .CE(CE), .CLR(CLR) ); - \$__ABC_FF_ abc_dff (.D(\$nextQ ), .Q(\$currQ )); - \$__ABC_ASYNC abc_async (.A(\$currQ ), .S(CLR), .Y(Q)); + wire _TECHMAP_REPLACE_.$currQ = Q; + \$__ABC_FF_ abc_dff (.D($nextQ), .Q($currQ)); + \$__ABC_ASYNC abc_async (.A($currQ), .S(CLR), .Y(Q)); endmodule module FDPE (output reg Q, input C, CE, D, PRE); @@ -97,28 +100,30 @@ module FDPE (output reg Q, input C, CE, D, PRE); parameter [0:0] IS_C_INVERTED = 1'b0; parameter [0:0] IS_D_INVERTED = 1'b0; parameter [0:0] IS_PRE_INVERTED = 1'b0; - wire \$nextQ , \$currQ ; + wire $nextQ, $currQ; FDPE #( .INIT(INIT), .IS_C_INVERTED(IS_C_INVERTED), .IS_D_INVERTED(IS_D_INVERTED), .IS_PRE_INVERTED(IS_PRE_INVERTED), ) _TECHMAP_REPLACE_ ( - .D(D), .Q(\$nextQ ), .\$currQ (Q), .C(C), .CE(CE), .PRE(PRE) + .D(D), .Q($nextQ), .C(C), .CE(CE), .PRE(PRE) ); - \$__ABC_FF_ abc_dff (.D(\$nextQ ), .Q(\$currQ )); - \$__ABC_ASYNC abc_async (.A(\$currQ ), .S(PRE ^ IS_PRE_INVERTED), .Y(Q)); + wire _TECHMAP_REPLACE_.$currQ = Q; + \$__ABC_FF_ abc_dff (.D($nextQ), .Q($currQ)); + \$__ABC_ASYNC abc_async (.A($currQ), .S(PRE ^ IS_PRE_INVERTED), .Y(Q)); endmodule module FDPE_1 (output reg Q, input C, CE, D, PRE); parameter [0:0] INIT = 1'b0; - wire \$nextQ , \$currQ ; + wire $nextQ, $currQ; FDPE_1 #( .INIT(INIT) ) _TECHMAP_REPLACE_ ( - .D(D), .Q(\$nextQ ), .\$currQ (Q), .C(C), .CE(CE), .PRE(PRE) + .D(D), .Q($nextQ), .C(C), .CE(CE), .PRE(PRE) ); - \$__ABC_FF_ abc_dff (.D(\$nextQ ), .Q(\$currQ )); - \$__ABC_ASYNC abc_async (.A(\$currQ ), .S(PRE), .Y(Q)); + wire _TECHMAP_REPLACE_.$currQ = Q; + \$__ABC_FF_ abc_dff (.D($nextQ), .Q($currQ)); + \$__ABC_ASYNC abc_async (.A($currQ), .S(PRE), .Y(Q)); endmodule module FDSE (output reg Q, input C, CE, D, S); @@ -126,26 +131,28 @@ module FDSE (output reg Q, input C, CE, D, S); 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 \$nextQ ; + wire $nextQ; FDSE #( .INIT(INIT), .IS_C_INVERTED(IS_C_INVERTED), .IS_D_INVERTED(IS_D_INVERTED), .IS_S_INVERTED(IS_S_INVERTED) ) _TECHMAP_REPLACE_ ( - .D(D), .Q(\$nextQ ), .\$currQ (Q), .C(C), .CE(CE), .S(S) + .D(D), .Q($nextQ), .C(C), .CE(CE), .S(S) ); - \$__ABC_FF_ abc_dff (.D(\$nextQ ), .Q(Q)); + wire _TECHMAP_REPLACE_.$currQ = Q; + \$__ABC_FF_ abc_dff (.D($nextQ), .Q(Q)); endmodule module FDSE_1 (output reg Q, input C, CE, D, S); parameter [0:0] INIT = 1'b0; - wire \$nextQ ; + wire $nextQ; FDSE_1 #( .INIT(|0), ) _TECHMAP_REPLACE_ ( - .D(D), .Q(\$nextQ ), .\$currQ (Q), .C(C), .CE(CE), .S(S) + .D(D), .Q($nextQ), .C(C), .CE(CE), .S(S) ); - \$__ABC_FF_ abc_dff (.D(\$nextQ ), .Q(Q)); + wire _TECHMAP_REPLACE_.$currQ = Q; + \$__ABC_FF_ abc_dff (.D($nextQ), .Q(Q)); endmodule module RAM32X1D ( diff --git a/techlibs/xilinx/cells_sim.v b/techlibs/xilinx/cells_sim.v index 3aa686e81..7ab28b0aa 100644 --- a/techlibs/xilinx/cells_sim.v +++ b/techlibs/xilinx/cells_sim.v @@ -258,31 +258,31 @@ module FDRE ( parameter [0:0] IS_D_INVERTED = 1'b0; parameter [0:0] IS_R_INVERTED = 1'b0; initial Q <= INIT; - wire \$currQ ; - reg \$nextQ ; - always @* if (R == !IS_R_INVERTED) \$nextQ = 1'b0; else if (CE) \$nextQ = D ^ IS_D_INVERTED; else \$nextQ = \$currQ ; + wire $currQ; + reg $nextQ; + always @* if (R == !IS_R_INVERTED) $nextQ = 1'b0; else if (CE) $nextQ = D ^ IS_D_INVERTED; else $nextQ = $currQ; `ifdef _ABC // `abc9' requires that complex flops be split into a combinatorial // box (this module) feeding a simple flop ($_ABC_FF_ in abc_map.v) // In order to achieve clock-enable behaviour, the current value // of the sequential output is required which Yosys will - // connect to the special `\$currQ' wire. + // connect to the special `$currQ' wire. // Special signal indicating clock domain // (used to partition the module so that `abc9' only performs // sequential synthesis (reachability analysis) correctly on // one domain at a time) - wire [1:0] \$abc9_clock = {C, IS_C_INVERTED}; + wire [1:0] $abc9_clock = {C, IS_C_INVERTED}; // Special signal indicating control domain // (which, combined with this spell type, encodes to `abc9' // which flops may be merged together) - wire [3:0] \$abc9_control = {CE, IS_D_INVERTED, R, IS_R_INVERTED}; - always @* Q = \$nextQ ; + wire [3:0] $abc9_control = {CE, IS_D_INVERTED, R, IS_R_INVERTED}; + always @* Q = $nextQ; `else - assign \$currQ = Q; + assign $currQ = Q; generate case (|IS_C_INVERTED) - 1'b0: always @(posedge C) Q <= \$nextQ ; - 1'b1: always @(negedge C) Q <= \$nextQ ; + 1'b0: always @(posedge C) Q <= $nextQ; + 1'b1: always @(negedge C) Q <= $nextQ; endcase endgenerate `endif endmodule @@ -297,29 +297,29 @@ module FDRE_1 ( ); parameter [0:0] INIT = 1'b0; initial Q <= INIT; - wire \$currQ ; - reg \$nextQ ; - always @* if (R) Q <= 1'b0; else if (CE) Q <= D; else \$nextQ = \$currQ ; + wire $currQ; + reg $nextQ; + always @* if (R) Q <= 1'b0; else if (CE) Q <= D; else $nextQ = $currQ; `ifdef _ABC // `abc9' requires that complex flops be split into a combinatorial // box (this module) feeding a simple flop ($_ABC_FF_ in abc_map.v) // In order to achieve clock-enable behaviour, the current value // of the sequential output is required which Yosys will - // connect to the special `\$currQ' wire. + // connect to the special `$currQ' wire. // Special signal indicating clock domain // (used to partition the module so that `abc9' only performs // sequential synthesis (reachability analysis) correctly on // one domain at a time) - wire [1:0] \$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */}; + wire [1:0] $abc9_clock = {C, 1'b1 /* IS_C_INVERTED */}; // Special signal indicating control domain // (which, combined with this spell type, encodes to `abc9' // which flops may be merged together) - wire [3:0] \$abc9_control = {CE, 1'b0 /* IS_D_INVERTED */, R, 1'b0 /* IS_R_INVERTED */}; - always @* Q = \$nextQ ; + wire [3:0] $abc9_control = {CE, 1'b0 /* IS_D_INVERTED */, R, 1'b0 /* IS_R_INVERTED */}; + always @* Q = $nextQ; `else - assign \$currQ = Q; - always @(negedge C) Q <= \$nextQ ; + assign $currQ = Q; + always @(negedge C) Q <= $nextQ; `endif endmodule @@ -341,15 +341,15 @@ module FDCE ( parameter [0:0] IS_D_INVERTED = 1'b0; parameter [0:0] IS_CLR_INVERTED = 1'b0; initial Q <= INIT; - wire \$currQ ; - reg \$nextQ ; - always @* if (CE) Q <= D ^ IS_D_INVERTED; else \$nextQ = \$currQ ; + wire $currQ; + reg $nextQ; + always @* if (CE) Q <= D ^ IS_D_INVERTED; else $nextQ = $currQ; `ifdef _ABC // `abc9' requires that complex flops be split into a combinatorial // box (this module) feeding a simple flop ($_ABC_FF_ in abc_map.v) // In order to achieve clock-enable behaviour, the current value // of the sequential output is required which Yosys will - // connect to the special `\$currQ' wire. + // connect to the special `$currQ' wire. // Since this is an async flop, async behaviour is also dealt with // using the $_ABC_ASYNC box by abc_map.v @@ -357,19 +357,19 @@ module FDCE ( // (used to partition the module so that `abc9' only performs // sequential synthesis (reachability analysis) correctly on // one domain at a time) - wire [1:0] \$abc9_clock = {C, IS_C_INVERTED}; + wire [1:0] $abc9_clock = {C, IS_C_INVERTED}; // Special signal indicating control domain // (which, combined with this spell type, encodes to `abc9' // which flops may be merged together) - wire [3:0] \$abc9_control = {CE, IS_D_INVERTED, CLR, IS_CLR_INVERTED}; - always @* Q = \$nextQ ; + wire [3:0] $abc9_control = {CE, IS_D_INVERTED, CLR, IS_CLR_INVERTED}; + always @* Q = $nextQ; `else - assign \$currQ = Q; + assign $currQ = Q; generate case ({|IS_C_INVERTED, |IS_CLR_INVERTED}) - 2'b00: always @(posedge C, posedge CLR) if ( CLR) Q <= 1'b0; else Q <= \$nextQ ; - 2'b01: always @(posedge C, negedge CLR) if (!CLR) Q <= 1'b0; else Q <= \$nextQ ; - 2'b10: always @(negedge C, posedge CLR) if ( CLR) Q <= 1'b0; else Q <= \$nextQ ; - 2'b11: always @(negedge C, negedge CLR) if (!CLR) Q <= 1'b0; else Q <= \$nextQ ; + 2'b00: always @(posedge C, posedge CLR) if ( CLR) Q <= 1'b0; else Q <= $nextQ; + 2'b01: always @(posedge C, negedge CLR) if (!CLR) Q <= 1'b0; else Q <= $nextQ; + 2'b10: always @(negedge C, posedge CLR) if ( CLR) Q <= 1'b0; else Q <= $nextQ; + 2'b11: always @(negedge C, negedge CLR) if (!CLR) Q <= 1'b0; else Q <= $nextQ; endcase endgenerate `endif endmodule @@ -384,15 +384,15 @@ module FDCE_1 ( ); parameter [0:0] INIT = 1'b0; initial Q <= INIT; - wire \$currQ ; - reg \$nextQ ; - always @* if (CE) Q <= D; else \$nextQ = \$currQ ; + wire $currQ; + reg $nextQ; + always @* if (CE) Q <= D; else $nextQ = $currQ; `ifdef _ABC // `abc9' requires that complex flops be split into a combinatorial // box (this module) feeding a simple flop ($_ABC_FF_ in abc_map.v) // In order to achieve clock-enable behaviour, the current value // of the sequential output is required which Yosys will - // connect to the special `\$currQ' wire. + // connect to the special `$currQ' wire. // Since this is an async flop, async behaviour is also dealt with // using the $_ABC_ASYNC box by abc_map.v @@ -400,15 +400,15 @@ module FDCE_1 ( // (used to partition the module so that `abc9' only performs // sequential synthesis (reachability analysis) correctly on // one domain at a time) - wire [1:0] \$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */}; + wire [1:0] $abc9_clock = {C, 1'b1 /* IS_C_INVERTED */}; // Special signal indicating control domain // (which, combined with this spell type, encodes to `abc9' // which flops may be merged together) - wire [3:0] \$abc9_control = {CE, 1'b0 /* IS_D_INVERTED */, CLR, 1'b0 /* IS_CLR_INVERTED */}; - always @* Q = \$nextQ ; + wire [3:0] $abc9_control = {CE, 1'b0 /* IS_D_INVERTED */, CLR, 1'b0 /* IS_CLR_INVERTED */}; + always @* Q = $nextQ; `else - assign \$currQ = Q; - always @(negedge C, posedge CLR) if (CLR) Q <= 1'b0; else Q <= \$nextQ ; + assign $currQ = Q; + always @(negedge C, posedge CLR) if (CLR) Q <= 1'b0; else Q <= $nextQ; `endif endmodule @@ -430,15 +430,15 @@ module FDPE ( parameter [0:0] IS_D_INVERTED = 1'b0; parameter [0:0] IS_PRE_INVERTED = 1'b0; initial Q <= INIT; - wire \$currQ ; - reg \$nextQ ; - always @* if (CE) Q <= D ^ IS_D_INVERTED; else \$nextQ = \$currQ ; + wire $currQ; + reg $nextQ; + always @* if (CE) Q <= D ^ IS_D_INVERTED; else $nextQ = $currQ; `ifdef _ABC // `abc9' requires that complex flops be split into a combinatorial // box (this module) feeding a simple flop ($_ABC_FF_ in abc_map.v) // In order to achieve clock-enable behaviour, the current value // of the sequential output is required which Yosys will - // connect to the special `\$currQ' wire. + // connect to the special `$currQ' wire. // Since this is an async flop, async behaviour is also dealt with // using the $_ABC_ASYNC box by abc_map.v @@ -446,19 +446,19 @@ module FDPE ( // (used to partition the module so that `abc9' only performs // sequential synthesis (reachability analysis) correctly on // one domain at a time) - wire [1:0] \$abc9_clock = {C, IS_C_INVERTED}; + wire [1:0] $abc9_clock = {C, IS_C_INVERTED}; // Special signal indicating control domain // (which, combined with this spell type, encodes to `abc9' // which flops may be merged together) - wire [3:0] \$abc9_control = {CE, IS_D_INVERTED, PRE, IS_PRE_INVERTED}; - always @* Q = \$nextQ ; + wire [3:0] $abc9_control = {CE, IS_D_INVERTED, PRE, IS_PRE_INVERTED}; + always @* Q = $nextQ; `else - assign \$currQ = Q; + assign $currQ = Q; generate case ({|IS_C_INVERTED, |IS_PRE_INVERTED}) - 2'b00: always @(posedge C, posedge PRE) if ( PRE) Q <= 1'b1; else Q <= \$nextQ ; - 2'b01: always @(posedge C, negedge PRE) if (!PRE) Q <= 1'b1; else Q <= \$nextQ ; - 2'b10: always @(negedge C, posedge PRE) if ( PRE) Q <= 1'b1; else Q <= \$nextQ ; - 2'b11: always @(negedge C, negedge PRE) if (!PRE) Q <= 1'b1; else Q <= \$nextQ ; + 2'b00: always @(posedge C, posedge PRE) if ( PRE) Q <= 1'b1; else Q <= $nextQ; + 2'b01: always @(posedge C, negedge PRE) if (!PRE) Q <= 1'b1; else Q <= $nextQ; + 2'b10: always @(negedge C, posedge PRE) if ( PRE) Q <= 1'b1; else Q <= $nextQ; + 2'b11: always @(negedge C, negedge PRE) if (!PRE) Q <= 1'b1; else Q <= $nextQ; endcase endgenerate `endif endmodule @@ -473,15 +473,15 @@ module FDPE_1 ( ); parameter [0:0] INIT = 1'b1; initial Q <= INIT; - wire \$currQ ; - reg \$nextQ ; - always @* if (CE) Q <= D; else \$nextQ = \$currQ ; + wire $currQ; + reg $nextQ; + always @* if (CE) Q <= D; else $nextQ = $currQ; `ifdef _ABC // `abc9' requires that complex flops be split into a combinatorial // box (this module) feeding a simple flop ($_ABC_FF_ in abc_map.v) // In order to achieve clock-enable behaviour, the current value // of the sequential output is required which Yosys will - // connect to the special `\$currQ' wire. + // connect to the special `$currQ' wire. // Since this is an async flop, async behaviour is also dealt with // using the $_ABC_ASYNC box by abc_map.v @@ -489,15 +489,15 @@ module FDPE_1 ( // (used to partition the module so that `abc9' only performs // sequential synthesis (reachability analysis) correctly on // one domain at a time) - wire [1:0] \$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */}; + wire [1:0] $abc9_clock = {C, 1'b1 /* IS_C_INVERTED */}; // Special signal indicating control domain // (which, combined with this spell type, encodes to `abc9' // which flops may be merged together) - wire [3:0] \$abc9_control = {CE, 1'b0 /* IS_D_INVERTED */, PRE, 1'b0 /* IS_PRE_INVERTED */}; - always @* Q = \$nextQ ; + wire [3:0] $abc9_control = {CE, 1'b0 /* IS_D_INVERTED */, PRE, 1'b0 /* IS_PRE_INVERTED */}; + always @* Q = $nextQ; `else - assign \$currQ = Q; - always @(negedge C, posedge PRE) if (PRE) Q <= 1'b1; else Q <= \$nextQ ; + assign $currQ = Q; + always @(negedge C, posedge PRE) if (PRE) Q <= 1'b1; else Q <= $nextQ; `endif endmodule @@ -519,31 +519,31 @@ module FDSE ( parameter [0:0] IS_D_INVERTED = 1'b0; parameter [0:0] IS_S_INVERTED = 1'b0; initial Q <= INIT; - wire \$currQ ; - reg \$nextQ ; - always @* if (S == !IS_S_INVERTED) \$nextQ = 1'b1; else if (CE) \$nextQ = D ^ IS_D_INVERTED; else \$nextQ = \$currQ ; + wire $currQ; + reg $nextQ; + always @* if (S == !IS_S_INVERTED) $nextQ = 1'b1; else if (CE) $nextQ = D ^ IS_D_INVERTED; else $nextQ = $currQ; `ifdef _ABC // `abc9' requires that complex flops be split into a combinatorial // box (this module) feeding a simple flop ($_ABC_FF_ in abc_map.v) // In order to achieve clock-enable behaviour, the current value // of the sequential output is required which Yosys will - // connect to the special `\$currQ' wire. + // connect to the special `$currQ' wire. // Special signal indicating clock domain // (used to partition the module so that `abc9' only performs // sequential synthesis (reachability analysis) correctly on // one domain at a time) - wire [1:0] \$abc9_clock = {C, IS_C_INVERTED}; + wire [1:0] $abc9_clock = {C, IS_C_INVERTED}; // Special signal indicating control domain // (which, combined with this spell type, encodes to `abc9' // which flops may be merged together) - wire [3:0] \$abc9_control = {CE, IS_D_INVERTED, S, IS_S_INVERTED}; - always @* Q = \$nextQ ; + wire [3:0] $abc9_control = {CE, IS_D_INVERTED, S, IS_S_INVERTED}; + always @* Q = $nextQ; `else - assign \$currQ = Q; + assign $currQ = Q; generate case (|IS_C_INVERTED) - 1'b0: always @(posedge C) Q <= \$nextQ ; - 1'b1: always @(negedge C) Q <= \$nextQ ; + 1'b0: always @(posedge C) Q <= $nextQ; + 1'b1: always @(negedge C) Q <= $nextQ; endcase endgenerate `endif endmodule @@ -558,29 +558,29 @@ module FDSE_1 ( ); parameter [0:0] INIT = 1'b1; initial Q <= INIT; - wire \$currQ ; - reg \$nextQ ; - always @* if (S) \$nextQ = 1'b1; else if (CE) \$nextQ = D; else \$nextQ = \$currQ ; + wire $currQ; + reg $nextQ; + always @* if (S) $nextQ = 1'b1; else if (CE) $nextQ = D; else $nextQ = $currQ; `ifdef _ABC // `abc9' requires that complex flops be split into a combinatorial // box (this module) feeding a simple flop ($_ABC_FF_ in abc_map.v) // In order to achieve clock-enable behaviour, the current value // of the sequential output is required which Yosys will - // connect to the special `\$currQ' wire. + // connect to the special `$currQ' wire. // Special signal indicating clock domain // (used to partition the module so that `abc9' only performs // sequential synthesis (reachability analysis) correctly on // one domain at a time) - wire [1:0] \$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */}; + wire [1:0] $abc9_clock = {C, 1'b1 /* IS_C_INVERTED */}; // Special signal indicating control domain // (which, combined with this spell type, encodes to `abc9' // which flops may be merged together) - wire [3:0] \$abc9_control = {CE, 1'b0 /* IS_D_INVERTED */, S, 1'b0 /* IS_S_INVERTED */}; - always @* Q = \$nextQ ; + wire [3:0] $abc9_control = {CE, 1'b0 /* IS_D_INVERTED */, S, 1'b0 /* IS_S_INVERTED */}; + always @* Q = $nextQ; `else - assign \$currQ = Q; - always @(negedge C) Q <= \$nextQ ; + assign $currQ = Q; + always @(negedge C) Q <= $nextQ; `endif endmodule -- cgit v1.2.3 From f9bb3352944275acc6e82eaf53aebf3c964f68c4 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 30 Sep 2019 16:36:42 -0700 Subject: Cleanup $currQ from aigerparse --- frontends/aiger/aigerparse.cc | 2 -- 1 file changed, 2 deletions(-) diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc index d40f33447..594bf60ce 100644 --- a/frontends/aiger/aigerparse.cc +++ b/frontends/aiger/aigerparse.cc @@ -817,8 +817,6 @@ void AigerReader::post_process() } if (is_flop) { - Wire* port = box_module->wire("\\$currQ"); - log_assert(port); log_assert(co_count < outputs.size()); Wire *wire = outputs[co_count++]; log_assert(wire); -- cgit v1.2.3 From 390b960c8c646018c1f6cddfec5fc2d528d42fa4 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 30 Sep 2019 16:37:29 -0700 Subject: Resolve FIXME on calling proc just once --- passes/techmap/abc9.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 6e424d517..ce057566c 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -1117,8 +1117,8 @@ struct Abc9Pass : public Pass { auto derived_name = inst_module->derive(design, cell->parameters); auto derived_module = design->module(derived_name); log_assert(derived_module); - // FIXME: call once - Pass::call_on_module(design, derived_module, "proc"); + if (derived_module->has_processes()) + Pass::call_on_module(design, derived_module, "proc"); SigMap derived_sigmap(derived_module); Wire *currQ = derived_module->wire("\\$currQ"); -- cgit v1.2.3 From 1b96d29174d7c56a14031bc117a7da5fa5192c81 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 30 Sep 2019 17:02:20 -0700 Subject: No need to punch ports at all --- backends/aiger/xaiger.cc | 24 ++++++++++++++++++++++++ passes/techmap/abc9.cc | 13 ------------- 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 65792421f..4bdd54772 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -481,6 +481,7 @@ struct XAigerWriter } } + // Connect $currQ as an input to the flop box if (box_module->get_bool_attribute("\\abc9_flop")) { IdString port_name = "\\$currQ"; Wire *w = box_module->wire(port_name); @@ -786,6 +787,29 @@ struct XAigerWriter } } + // For flops only, create an extra input for $currQ + if (box_module->get_bool_attribute("\\abc9_flop")) { + log_assert(holes_cell); + + Wire *w = box_module->wire("\\$currQ"); + Wire *holes_wire; + RTLIL::SigSpec port_wire; + 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); + } + port_wire.append(holes_wire); + } + w = holes_module->addWire(stringf("%s.$currQ", cell->name.c_str()), GetSize(w)); + w->set_bool_attribute("\\hierconn"); + holes_module->connect(w, port_wire); + } + write_h_buffer(box_inputs); write_h_buffer(box_outputs); write_h_buffer(box_module->attributes.at("\\abc_box_id").as_int()); diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index ce057566c..777ec6ac8 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -1121,19 +1121,6 @@ struct Abc9Pass : public Pass { Pass::call_on_module(design, derived_module, "proc"); SigMap derived_sigmap(derived_module); - Wire *currQ = derived_module->wire("\\$currQ"); - if (currQ == NULL) - log_error("'\\$currQ' is not a wire present in module '%s'.\n", log_id(cell->type)); - log_assert(!currQ->port_output); - if (!currQ->port_input) { - currQ->port_input = true; - derived_module->ports.push_back(currQ->name); - currQ->port_id = GetSize(derived_module->ports); -#ifndef NDEBUG - derived_module->check(); -#endif - } - SigSpec pattern; SigSpec with; for (auto &conn : cell->connections()) { -- cgit v1.2.3 From 03ebe43e3edce03d3dc24f80c05e16cdb7b76748 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 1 Oct 2019 13:05:56 -0700 Subject: Escape Verilog identifiers for legality outside of Yosys --- techlibs/xilinx/cells_sim.v | 96 ++++++++++++++++++++++----------------------- 1 file changed, 48 insertions(+), 48 deletions(-) diff --git a/techlibs/xilinx/cells_sim.v b/techlibs/xilinx/cells_sim.v index 7ab28b0aa..84139cd9c 100644 --- a/techlibs/xilinx/cells_sim.v +++ b/techlibs/xilinx/cells_sim.v @@ -258,9 +258,9 @@ module FDRE ( parameter [0:0] IS_D_INVERTED = 1'b0; parameter [0:0] IS_R_INVERTED = 1'b0; initial Q <= INIT; - wire $currQ; - reg $nextQ; - always @* if (R == !IS_R_INVERTED) $nextQ = 1'b0; else if (CE) $nextQ = D ^ IS_D_INVERTED; else $nextQ = $currQ; + wire \$currQ ; + reg \$nextQ ; + always @* if (R == !IS_R_INVERTED) $nextQ = 1'b0; else if (CE) $nextQ = D ^ IS_D_INVERTED; else $nextQ = \$currQ ; `ifdef _ABC // `abc9' requires that complex flops be split into a combinatorial // box (this module) feeding a simple flop ($_ABC_FF_ in abc_map.v) @@ -277,12 +277,12 @@ module FDRE ( // (which, combined with this spell type, encodes to `abc9' // which flops may be merged together) wire [3:0] $abc9_control = {CE, IS_D_INVERTED, R, IS_R_INVERTED}; - always @* Q = $nextQ; + always @* Q = \$nextQ ; `else assign $currQ = Q; generate case (|IS_C_INVERTED) - 1'b0: always @(posedge C) Q <= $nextQ; - 1'b1: always @(negedge C) Q <= $nextQ; + 1'b0: always @(posedge C) Q <= \$nextQ ; + 1'b1: always @(negedge C) Q <= \$nextQ ; endcase endgenerate `endif endmodule @@ -297,9 +297,9 @@ module FDRE_1 ( ); parameter [0:0] INIT = 1'b0; initial Q <= INIT; - wire $currQ; - reg $nextQ; - always @* if (R) Q <= 1'b0; else if (CE) Q <= D; else $nextQ = $currQ; + wire \$currQ ; + reg \$nextQ ; + always @* if (R) Q <= 1'b0; else if (CE) Q <= D; else $nextQ = \$currQ ; `ifdef _ABC // `abc9' requires that complex flops be split into a combinatorial // box (this module) feeding a simple flop ($_ABC_FF_ in abc_map.v) @@ -316,10 +316,10 @@ module FDRE_1 ( // (which, combined with this spell type, encodes to `abc9' // which flops may be merged together) wire [3:0] $abc9_control = {CE, 1'b0 /* IS_D_INVERTED */, R, 1'b0 /* IS_R_INVERTED */}; - always @* Q = $nextQ; + always @* Q = \$nextQ ; `else assign $currQ = Q; - always @(negedge C) Q <= $nextQ; + always @(negedge C) Q <= \$nextQ ; `endif endmodule @@ -341,9 +341,9 @@ module FDCE ( parameter [0:0] IS_D_INVERTED = 1'b0; parameter [0:0] IS_CLR_INVERTED = 1'b0; initial Q <= INIT; - wire $currQ; - reg $nextQ; - always @* if (CE) Q <= D ^ IS_D_INVERTED; else $nextQ = $currQ; + wire \$currQ ; + reg \$nextQ ; + always @* if (CE) Q <= D ^ IS_D_INVERTED; else $nextQ = \$currQ ; `ifdef _ABC // `abc9' requires that complex flops be split into a combinatorial // box (this module) feeding a simple flop ($_ABC_FF_ in abc_map.v) @@ -362,14 +362,14 @@ module FDCE ( // (which, combined with this spell type, encodes to `abc9' // which flops may be merged together) wire [3:0] $abc9_control = {CE, IS_D_INVERTED, CLR, IS_CLR_INVERTED}; - always @* Q = $nextQ; + always @* Q = \$nextQ ; `else assign $currQ = Q; generate case ({|IS_C_INVERTED, |IS_CLR_INVERTED}) - 2'b00: always @(posedge C, posedge CLR) if ( CLR) Q <= 1'b0; else Q <= $nextQ; - 2'b01: always @(posedge C, negedge CLR) if (!CLR) Q <= 1'b0; else Q <= $nextQ; - 2'b10: always @(negedge C, posedge CLR) if ( CLR) Q <= 1'b0; else Q <= $nextQ; - 2'b11: always @(negedge C, negedge CLR) if (!CLR) Q <= 1'b0; else Q <= $nextQ; + 2'b00: always @(posedge C, posedge CLR) if ( CLR) Q <= 1'b0; else Q <= \$nextQ ; + 2'b01: always @(posedge C, negedge CLR) if (!CLR) Q <= 1'b0; else Q <= \$nextQ ; + 2'b10: always @(negedge C, posedge CLR) if ( CLR) Q <= 1'b0; else Q <= \$nextQ ; + 2'b11: always @(negedge C, negedge CLR) if (!CLR) Q <= 1'b0; else Q <= \$nextQ ; endcase endgenerate `endif endmodule @@ -384,9 +384,9 @@ module FDCE_1 ( ); parameter [0:0] INIT = 1'b0; initial Q <= INIT; - wire $currQ; - reg $nextQ; - always @* if (CE) Q <= D; else $nextQ = $currQ; + wire \$currQ ; + reg \$nextQ ; + always @* if (CE) Q <= D; else $nextQ = \$currQ ; `ifdef _ABC // `abc9' requires that complex flops be split into a combinatorial // box (this module) feeding a simple flop ($_ABC_FF_ in abc_map.v) @@ -405,10 +405,10 @@ module FDCE_1 ( // (which, combined with this spell type, encodes to `abc9' // which flops may be merged together) wire [3:0] $abc9_control = {CE, 1'b0 /* IS_D_INVERTED */, CLR, 1'b0 /* IS_CLR_INVERTED */}; - always @* Q = $nextQ; + always @* Q = \$nextQ ; `else assign $currQ = Q; - always @(negedge C, posedge CLR) if (CLR) Q <= 1'b0; else Q <= $nextQ; + always @(negedge C, posedge CLR) if (CLR) Q <= 1'b0; else Q <= \$nextQ ; `endif endmodule @@ -430,9 +430,9 @@ module FDPE ( parameter [0:0] IS_D_INVERTED = 1'b0; parameter [0:0] IS_PRE_INVERTED = 1'b0; initial Q <= INIT; - wire $currQ; - reg $nextQ; - always @* if (CE) Q <= D ^ IS_D_INVERTED; else $nextQ = $currQ; + wire \$currQ ; + reg \$nextQ ; + always @* if (CE) Q <= D ^ IS_D_INVERTED; else $nextQ = \$currQ ; `ifdef _ABC // `abc9' requires that complex flops be split into a combinatorial // box (this module) feeding a simple flop ($_ABC_FF_ in abc_map.v) @@ -451,14 +451,14 @@ module FDPE ( // (which, combined with this spell type, encodes to `abc9' // which flops may be merged together) wire [3:0] $abc9_control = {CE, IS_D_INVERTED, PRE, IS_PRE_INVERTED}; - always @* Q = $nextQ; + always @* Q = \$nextQ ; `else assign $currQ = Q; generate case ({|IS_C_INVERTED, |IS_PRE_INVERTED}) - 2'b00: always @(posedge C, posedge PRE) if ( PRE) Q <= 1'b1; else Q <= $nextQ; - 2'b01: always @(posedge C, negedge PRE) if (!PRE) Q <= 1'b1; else Q <= $nextQ; - 2'b10: always @(negedge C, posedge PRE) if ( PRE) Q <= 1'b1; else Q <= $nextQ; - 2'b11: always @(negedge C, negedge PRE) if (!PRE) Q <= 1'b1; else Q <= $nextQ; + 2'b00: always @(posedge C, posedge PRE) if ( PRE) Q <= 1'b1; else Q <= \$nextQ ; + 2'b01: always @(posedge C, negedge PRE) if (!PRE) Q <= 1'b1; else Q <= \$nextQ ; + 2'b10: always @(negedge C, posedge PRE) if ( PRE) Q <= 1'b1; else Q <= \$nextQ ; + 2'b11: always @(negedge C, negedge PRE) if (!PRE) Q <= 1'b1; else Q <= \$nextQ ; endcase endgenerate `endif endmodule @@ -473,9 +473,9 @@ module FDPE_1 ( ); parameter [0:0] INIT = 1'b1; initial Q <= INIT; - wire $currQ; - reg $nextQ; - always @* if (CE) Q <= D; else $nextQ = $currQ; + wire \$currQ ; + reg \$nextQ ; + always @* if (CE) Q <= D; else $nextQ = \$currQ ; `ifdef _ABC // `abc9' requires that complex flops be split into a combinatorial // box (this module) feeding a simple flop ($_ABC_FF_ in abc_map.v) @@ -494,10 +494,10 @@ module FDPE_1 ( // (which, combined with this spell type, encodes to `abc9' // which flops may be merged together) wire [3:0] $abc9_control = {CE, 1'b0 /* IS_D_INVERTED */, PRE, 1'b0 /* IS_PRE_INVERTED */}; - always @* Q = $nextQ; + always @* Q = \$nextQ ; `else assign $currQ = Q; - always @(negedge C, posedge PRE) if (PRE) Q <= 1'b1; else Q <= $nextQ; + always @(negedge C, posedge PRE) if (PRE) Q <= 1'b1; else Q <= \$nextQ ; `endif endmodule @@ -519,9 +519,9 @@ module FDSE ( parameter [0:0] IS_D_INVERTED = 1'b0; parameter [0:0] IS_S_INVERTED = 1'b0; initial Q <= INIT; - wire $currQ; - reg $nextQ; - always @* if (S == !IS_S_INVERTED) $nextQ = 1'b1; else if (CE) $nextQ = D ^ IS_D_INVERTED; else $nextQ = $currQ; + wire \$currQ ; + reg \$nextQ ; + always @* if (S == !IS_S_INVERTED) $nextQ = 1'b1; else if (CE) $nextQ = D ^ IS_D_INVERTED; else $nextQ = \$currQ ; `ifdef _ABC // `abc9' requires that complex flops be split into a combinatorial // box (this module) feeding a simple flop ($_ABC_FF_ in abc_map.v) @@ -538,12 +538,12 @@ module FDSE ( // (which, combined with this spell type, encodes to `abc9' // which flops may be merged together) wire [3:0] $abc9_control = {CE, IS_D_INVERTED, S, IS_S_INVERTED}; - always @* Q = $nextQ; + always @* Q = \$nextQ ; `else assign $currQ = Q; generate case (|IS_C_INVERTED) - 1'b0: always @(posedge C) Q <= $nextQ; - 1'b1: always @(negedge C) Q <= $nextQ; + 1'b0: always @(posedge C) Q <= \$nextQ ; + 1'b1: always @(negedge C) Q <= \$nextQ ; endcase endgenerate `endif endmodule @@ -558,9 +558,9 @@ module FDSE_1 ( ); parameter [0:0] INIT = 1'b1; initial Q <= INIT; - wire $currQ; - reg $nextQ; - always @* if (S) $nextQ = 1'b1; else if (CE) $nextQ = D; else $nextQ = $currQ; + wire \$currQ ; + reg \$nextQ ; + always @* if (S) $nextQ = 1'b1; else if (CE) $nextQ = D; else $nextQ = \$currQ ; `ifdef _ABC // `abc9' requires that complex flops be split into a combinatorial // box (this module) feeding a simple flop ($_ABC_FF_ in abc_map.v) @@ -577,10 +577,10 @@ module FDSE_1 ( // (which, combined with this spell type, encodes to `abc9' // which flops may be merged together) wire [3:0] $abc9_control = {CE, 1'b0 /* IS_D_INVERTED */, S, 1'b0 /* IS_S_INVERTED */}; - always @* Q = $nextQ; + always @* Q = \$nextQ ; `else assign $currQ = Q; - always @(negedge C) Q <= $nextQ; + always @(negedge C) Q <= \$nextQ ; `endif endmodule -- cgit v1.2.3 From 5299884f049e73c395fdff090b345b15d54aab1e Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 1 Oct 2019 13:41:08 -0700 Subject: More fixes --- techlibs/xilinx/cells_sim.v | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/techlibs/xilinx/cells_sim.v b/techlibs/xilinx/cells_sim.v index 84139cd9c..04aa60f91 100644 --- a/techlibs/xilinx/cells_sim.v +++ b/techlibs/xilinx/cells_sim.v @@ -260,7 +260,7 @@ module FDRE ( initial Q <= INIT; wire \$currQ ; reg \$nextQ ; - always @* if (R == !IS_R_INVERTED) $nextQ = 1'b0; else if (CE) $nextQ = D ^ IS_D_INVERTED; else $nextQ = \$currQ ; + always @* if (R == !IS_R_INVERTED) \$nextQ = 1'b0; else if (CE) \$nextQ = D ^ IS_D_INVERTED; else \$nextQ = \$currQ ; `ifdef _ABC // `abc9' requires that complex flops be split into a combinatorial // box (this module) feeding a simple flop ($_ABC_FF_ in abc_map.v) @@ -279,7 +279,7 @@ module FDRE ( wire [3:0] $abc9_control = {CE, IS_D_INVERTED, R, IS_R_INVERTED}; always @* Q = \$nextQ ; `else - assign $currQ = Q; + assign \$currQ = Q; generate case (|IS_C_INVERTED) 1'b0: always @(posedge C) Q <= \$nextQ ; 1'b1: always @(negedge C) Q <= \$nextQ ; @@ -299,7 +299,7 @@ module FDRE_1 ( initial Q <= INIT; wire \$currQ ; reg \$nextQ ; - always @* if (R) Q <= 1'b0; else if (CE) Q <= D; else $nextQ = \$currQ ; + always @* if (R) Q <= 1'b0; else if (CE) Q <= D; else \$nextQ = \$currQ ; `ifdef _ABC // `abc9' requires that complex flops be split into a combinatorial // box (this module) feeding a simple flop ($_ABC_FF_ in abc_map.v) @@ -318,7 +318,7 @@ module FDRE_1 ( wire [3:0] $abc9_control = {CE, 1'b0 /* IS_D_INVERTED */, R, 1'b0 /* IS_R_INVERTED */}; always @* Q = \$nextQ ; `else - assign $currQ = Q; + assign \$currQ = Q; always @(negedge C) Q <= \$nextQ ; `endif endmodule @@ -343,7 +343,7 @@ module FDCE ( initial Q <= INIT; wire \$currQ ; reg \$nextQ ; - always @* if (CE) Q <= D ^ IS_D_INVERTED; else $nextQ = \$currQ ; + always @* if (CE) Q <= D ^ IS_D_INVERTED; else \$nextQ = \$currQ ; `ifdef _ABC // `abc9' requires that complex flops be split into a combinatorial // box (this module) feeding a simple flop ($_ABC_FF_ in abc_map.v) @@ -364,7 +364,7 @@ module FDCE ( wire [3:0] $abc9_control = {CE, IS_D_INVERTED, CLR, IS_CLR_INVERTED}; always @* Q = \$nextQ ; `else - assign $currQ = Q; + assign \$currQ = Q; generate case ({|IS_C_INVERTED, |IS_CLR_INVERTED}) 2'b00: always @(posedge C, posedge CLR) if ( CLR) Q <= 1'b0; else Q <= \$nextQ ; 2'b01: always @(posedge C, negedge CLR) if (!CLR) Q <= 1'b0; else Q <= \$nextQ ; @@ -386,7 +386,7 @@ module FDCE_1 ( initial Q <= INIT; wire \$currQ ; reg \$nextQ ; - always @* if (CE) Q <= D; else $nextQ = \$currQ ; + always @* if (CE) Q <= D; else \$nextQ = \$currQ ; `ifdef _ABC // `abc9' requires that complex flops be split into a combinatorial // box (this module) feeding a simple flop ($_ABC_FF_ in abc_map.v) @@ -407,7 +407,7 @@ module FDCE_1 ( wire [3:0] $abc9_control = {CE, 1'b0 /* IS_D_INVERTED */, CLR, 1'b0 /* IS_CLR_INVERTED */}; always @* Q = \$nextQ ; `else - assign $currQ = Q; + assign \$currQ = Q; always @(negedge C, posedge CLR) if (CLR) Q <= 1'b0; else Q <= \$nextQ ; `endif endmodule @@ -432,7 +432,7 @@ module FDPE ( initial Q <= INIT; wire \$currQ ; reg \$nextQ ; - always @* if (CE) Q <= D ^ IS_D_INVERTED; else $nextQ = \$currQ ; + always @* if (CE) Q <= D ^ IS_D_INVERTED; else \$nextQ = \$currQ ; `ifdef _ABC // `abc9' requires that complex flops be split into a combinatorial // box (this module) feeding a simple flop ($_ABC_FF_ in abc_map.v) @@ -453,7 +453,7 @@ module FDPE ( wire [3:0] $abc9_control = {CE, IS_D_INVERTED, PRE, IS_PRE_INVERTED}; always @* Q = \$nextQ ; `else - assign $currQ = Q; + assign \$currQ = Q; generate case ({|IS_C_INVERTED, |IS_PRE_INVERTED}) 2'b00: always @(posedge C, posedge PRE) if ( PRE) Q <= 1'b1; else Q <= \$nextQ ; 2'b01: always @(posedge C, negedge PRE) if (!PRE) Q <= 1'b1; else Q <= \$nextQ ; @@ -475,7 +475,7 @@ module FDPE_1 ( initial Q <= INIT; wire \$currQ ; reg \$nextQ ; - always @* if (CE) Q <= D; else $nextQ = \$currQ ; + always @* if (CE) Q <= D; else \$nextQ = \$currQ ; `ifdef _ABC // `abc9' requires that complex flops be split into a combinatorial // box (this module) feeding a simple flop ($_ABC_FF_ in abc_map.v) @@ -496,7 +496,7 @@ module FDPE_1 ( wire [3:0] $abc9_control = {CE, 1'b0 /* IS_D_INVERTED */, PRE, 1'b0 /* IS_PRE_INVERTED */}; always @* Q = \$nextQ ; `else - assign $currQ = Q; + assign \$currQ = Q; always @(negedge C, posedge PRE) if (PRE) Q <= 1'b1; else Q <= \$nextQ ; `endif endmodule @@ -521,7 +521,7 @@ module FDSE ( initial Q <= INIT; wire \$currQ ; reg \$nextQ ; - always @* if (S == !IS_S_INVERTED) $nextQ = 1'b1; else if (CE) $nextQ = D ^ IS_D_INVERTED; else $nextQ = \$currQ ; + always @* if (S == !IS_S_INVERTED) \$nextQ = 1'b1; else if (CE) \$nextQ = D ^ IS_D_INVERTED; else \$nextQ = \$currQ ; `ifdef _ABC // `abc9' requires that complex flops be split into a combinatorial // box (this module) feeding a simple flop ($_ABC_FF_ in abc_map.v) @@ -540,7 +540,7 @@ module FDSE ( wire [3:0] $abc9_control = {CE, IS_D_INVERTED, S, IS_S_INVERTED}; always @* Q = \$nextQ ; `else - assign $currQ = Q; + assign \$currQ = Q; generate case (|IS_C_INVERTED) 1'b0: always @(posedge C) Q <= \$nextQ ; 1'b1: always @(negedge C) Q <= \$nextQ ; @@ -560,7 +560,7 @@ module FDSE_1 ( initial Q <= INIT; wire \$currQ ; reg \$nextQ ; - always @* if (S) $nextQ = 1'b1; else if (CE) $nextQ = D; else $nextQ = \$currQ ; + always @* if (S) \$nextQ = 1'b1; else if (CE) \$nextQ = D; else \$nextQ = \$currQ ; `ifdef _ABC // `abc9' requires that complex flops be split into a combinatorial // box (this module) feeding a simple flop ($_ABC_FF_ in abc_map.v) @@ -579,7 +579,7 @@ module FDSE_1 ( wire [3:0] $abc9_control = {CE, 1'b0 /* IS_D_INVERTED */, S, 1'b0 /* IS_S_INVERTED */}; always @* Q = \$nextQ ; `else - assign $currQ = Q; + assign \$currQ = Q; always @(negedge C) Q <= \$nextQ ; `endif endmodule -- cgit v1.2.3 From 655f1b2ac559f73a7d781ae25afd1ab3b898afc0 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 3 Oct 2019 10:11:25 -0700 Subject: English --- techlibs/xilinx/abc_map.v | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/techlibs/xilinx/abc_map.v b/techlibs/xilinx/abc_map.v index 4eec77df9..db996fbc3 100644 --- a/techlibs/xilinx/abc_map.v +++ b/techlibs/xilinx/abc_map.v @@ -29,11 +29,11 @@ // ============================================================================ // The purpose of the following FD* rules are to wrap the flop (which, when -// called with the `_ABC' macro set captures contains only its combinatorial +// called with the `_ABC' macro set captures only its combinatorial // behaviour) with: // (a) a special $__ABC_FF_ in front of the FD*'s output, indicating to abc9 -// the location of its basic D-Q flop -// (b) a special TECHMAP_REPLACE_.$currQwire that will be used for feedback +// the connectivity of its basic D-Q flop +// (b) a special TECHMAP_REPLACE_.$currQ wire that will be used for feedback // into the (combinatorial) FD* cell to facilitate clock-enable behaviour module FDRE (output reg Q, input C, CE, D, R); parameter [0:0] INIT = 1'b0; -- cgit v1.2.3 From 7959e9d6b25d7afefded4b14e14ccf2b0b5af553 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 4 Oct 2019 17:21:14 -0700 Subject: Fix merge issues --- backends/aiger/xaiger.cc | 2 +- frontends/aiger/aigerparse.cc | 2 +- passes/techmap/abc9.cc | 4 ++-- passes/techmap/techmap.cc | 8 -------- techlibs/xilinx/abc9_map.v | 18 +++++++++--------- techlibs/xilinx/abc9_unmap.v | 1 + 6 files changed, 14 insertions(+), 21 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 09b5586fe..4547b9c09 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -254,7 +254,7 @@ struct XAigerWriter log_assert(!holes_mode); - if (cell->type == "$__ABC_FF_") + if (cell->type == "$__ABC9_FF_") { SigBit D = sigmap(cell->getPort("\\D").as_bit()); SigBit Q = sigmap(cell->getPort("\\Q").as_bit()); diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc index 77a49c34f..4b66af3ad 100644 --- a/frontends/aiger/aigerparse.cc +++ b/frontends/aiger/aigerparse.cc @@ -833,7 +833,7 @@ void AigerReader::post_process() log_assert(q->port_input); q->port_input = false; - auto ff = module->addCell(NEW_ID, "$__ABC_FF_"); + auto ff = module->addCell(NEW_ID, "$__ABC9_FF_"); ff->setPort("\\D", d); ff->setPort("\\Q", q); flop_count++; diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 87235f1a7..0dbe70a68 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -459,7 +459,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip dict abc9_box; vector boxes; for (auto cell : module->selected_cells()) { - if (cell->type.in(ID($_AND_), ID($_NOT_), ID($__ABC_FF_))) { + if (cell->type.in(ID($_AND_), ID($_NOT_), ID($__ABC9_FF_))) { module->remove(cell); continue; } @@ -533,7 +533,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip cell_stats[mapped_cell->type]++; RTLIL::Cell *existing_cell = nullptr; - if (mapped_cell->type.in(ID($lut), ID($__ABC_FF_))) { + 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")) { diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index a07a2f280..0c57733d4 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -256,14 +256,6 @@ struct TechmapWorker if (w->attributes.count(ID(src))) w->add_strpool_attribute(ID(src), extra_src_attrs); } - - - if (it.second->name.begins_with("\\_TECHMAP_REPLACE_")) { - IdString replace_name = stringf("%s%s", orig_cell_name.c_str(), it.second->name.c_str() + strlen("\\_TECHMAP_REPLACE_")); - Wire *replace_w = module->addWire(replace_name, it.second); - module->connect(replace_w, w); - } - design->select(module, w); if (it.second->name.begins_with("\\_TECHMAP_REPLACE_.")) { diff --git a/techlibs/xilinx/abc9_map.v b/techlibs/xilinx/abc9_map.v index 0b81be15f..05063f86d 100644 --- a/techlibs/xilinx/abc9_map.v +++ b/techlibs/xilinx/abc9_map.v @@ -31,7 +31,7 @@ // The purpose of the following FD* rules are to wrap the flop (which, when // called with the `_ABC' macro set captures only its combinatorial // behaviour) with: -// (a) a special $__ABC_FF_ in front of the FD*'s output, indicating to abc9 +// (a) a special $__ABC9_FF_ in front of the FD*'s output, indicating to abc9 // the connectivity of its basic D-Q flop // (b) a special TECHMAP_REPLACE_.$currQ wire that will be used for feedback // into the (combinatorial) FD* cell to facilitate clock-enable behaviour @@ -50,7 +50,7 @@ module FDRE (output reg Q, input C, CE, D, R); .D(D), .Q($nextQ), .C(C), .CE(CE), .R(R) ); wire _TECHMAP_REPLACE_.$currQ = Q; - \$__ABC_FF_ abc_dff (.D($nextQ), .Q(Q)); + \$__ABC9_FF_ abc_dff (.D($nextQ), .Q(Q)); endmodule module FDRE_1 (output reg Q, input C, CE, D, R); parameter [0:0] INIT = 1'b0; @@ -61,7 +61,7 @@ module FDRE_1 (output reg Q, input C, CE, D, R); .D(D), .Q($nextQ), .C(C), .CE(CE), .R(R) ); wire _TECHMAP_REPLACE_.$currQ = Q; - \$__ABC_FF_ abc_dff (.D($nextQ), .Q(Q)); + \$__ABC9_FF_ abc_dff (.D($nextQ), .Q(Q)); endmodule module FDCE (output reg Q, input C, CE, D, CLR); @@ -79,7 +79,7 @@ module FDCE (output reg Q, input C, CE, D, CLR); .D(D), .Q($nextQ), .C(C), .CE(CE), .CLR(CLR) ); wire _TECHMAP_REPLACE_.$currQ = Q; - \$__ABC_FF_ abc_dff (.D($nextQ), .Q($currQ)); + \$__ABC9_FF_ abc_dff (.D($nextQ), .Q($currQ)); \$__ABC_ASYNC abc_async (.A($currQ), .S(CLR ^ IS_CLR_INVERTED), .Y(Q)); endmodule module FDCE_1 (output reg Q, input C, CE, D, CLR); @@ -91,7 +91,7 @@ module FDCE_1 (output reg Q, input C, CE, D, CLR); .D(D), .Q($nextQ), .C(C), .CE(CE), .CLR(CLR) ); wire _TECHMAP_REPLACE_.$currQ = Q; - \$__ABC_FF_ abc_dff (.D($nextQ), .Q($currQ)); + \$__ABC9_FF_ abc_dff (.D($nextQ), .Q($currQ)); \$__ABC_ASYNC abc_async (.A($currQ), .S(CLR), .Y(Q)); endmodule @@ -110,7 +110,7 @@ module FDPE (output reg Q, input C, CE, D, PRE); .D(D), .Q($nextQ), .C(C), .CE(CE), .PRE(PRE) ); wire _TECHMAP_REPLACE_.$currQ = Q; - \$__ABC_FF_ abc_dff (.D($nextQ), .Q($currQ)); + \$__ABC9_FF_ abc_dff (.D($nextQ), .Q($currQ)); \$__ABC_ASYNC abc_async (.A($currQ), .S(PRE ^ IS_PRE_INVERTED), .Y(Q)); endmodule module FDPE_1 (output reg Q, input C, CE, D, PRE); @@ -122,7 +122,7 @@ module FDPE_1 (output reg Q, input C, CE, D, PRE); .D(D), .Q($nextQ), .C(C), .CE(CE), .PRE(PRE) ); wire _TECHMAP_REPLACE_.$currQ = Q; - \$__ABC_FF_ abc_dff (.D($nextQ), .Q($currQ)); + \$__ABC9_FF_ abc_dff (.D($nextQ), .Q($currQ)); \$__ABC_ASYNC abc_async (.A($currQ), .S(PRE), .Y(Q)); endmodule @@ -141,7 +141,7 @@ module FDSE (output reg Q, input C, CE, D, S); .D(D), .Q($nextQ), .C(C), .CE(CE), .S(S) ); wire _TECHMAP_REPLACE_.$currQ = Q; - \$__ABC_FF_ abc_dff (.D($nextQ), .Q(Q)); + \$__ABC9_FF_ abc_dff (.D($nextQ), .Q(Q)); endmodule module FDSE_1 (output reg Q, input C, CE, D, S); parameter [0:0] INIT = 1'b0; @@ -152,7 +152,7 @@ module FDSE_1 (output reg Q, input C, CE, D, S); .D(D), .Q($nextQ), .C(C), .CE(CE), .S(S) ); wire _TECHMAP_REPLACE_.$currQ = Q; - \$__ABC_FF_ abc_dff (.D($nextQ), .Q(Q)); + \$__ABC9_FF_ abc_dff (.D($nextQ), .Q(Q)); endmodule module RAM32X1D ( diff --git a/techlibs/xilinx/abc9_unmap.v b/techlibs/xilinx/abc9_unmap.v index f97b0bc66..21fe78d08 100644 --- a/techlibs/xilinx/abc9_unmap.v +++ b/techlibs/xilinx/abc9_unmap.v @@ -26,6 +26,7 @@ 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; -- cgit v1.2.3 From d4212d128b5985cf09f5e7f14bc06e7323e644ac Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 4 Oct 2019 17:27:05 -0700 Subject: Use read_args for read_verilog --- techlibs/xilinx/synth_xilinx.cc | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index 16b607aac..caeeb3266 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -283,10 +283,13 @@ 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_ABC -D_EXPLICIT_CARRY +/xilinx/cells_sim.v"); - else - run("read_verilog -lib -D_ABC +/xilinx/cells_sim.v"); + read_args += " -D_EXPLICIT_CARRY"; + if (abc9) + read_args += " -D_ABC9"; + read_args += " -lib +/xilinx/cells_sim.v"; + run("read_verilog" + read_args); if (help_mode) run("read_verilog -lib +/xilinx/{family}_cells_xtra.v"); -- cgit v1.2.3 From f0cadb0de801391083f6cc91d842e8137396b820 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 4 Oct 2019 17:52:19 -0700 Subject: Fix from merge --- passes/techmap/abc9.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 6c8527811..e9cdaf524 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -1251,7 +1251,7 @@ struct Abc9Pass : public Pass { abc9_module(design, module, script_file, exe_file, cleanup, lut_costs, false, "$", keepff, delay_target, lutin_shared, fast_mode, show_tempdir, box_file, lut_file, wire_delay, box_lookup, nomfs); - assign_map.set(mod); + assign_map.set(module); } design->selection_stack.pop_back(); design->selected_active_module.clear(); -- cgit v1.2.3 From a2ef93f03a1f75c25329c66d0e7d69da71e88e1f Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 4 Oct 2019 17:56:38 -0700 Subject: abc -> abc9 --- techlibs/xilinx/synth_xilinx.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index 6c598acf2..07f3d9a8a 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -481,13 +481,13 @@ struct SynthXilinxPass : public ScriptPass "will use timing for 'xc7' instead.\n", family.c_str()); run("techmap -map +/xilinx/abc9_map.v -max_iter 1"); run("read_verilog -icells -lib +/xilinx/abc9_model.v"); - std::string abc9_opts = " -box +/xilinx/abc_xc7.box"; + std::string abc9_opts = " -box +/xilinx/abc9_xc7.box"; abc9_opts += stringf(" -W %d", XC7_WIRE_DELAY); abc9_opts += " -nomfs"; if (nowidelut) - abc9_opts += " -lut +/xilinx/abc_xc7_nowide.lut"; + abc9_opts += " -lut +/xilinx/abc9_xc7_nowide.lut"; else - abc9_opts += " -lut +/xilinx/abc_xc7.lut"; + abc9_opts += " -lut +/xilinx/abc9_xc7.lut"; run("abc9" + abc9_opts); } else { -- cgit v1.2.3 From 3c6e5d82a62650a48027d35e6d92a7a88ad43a16 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Sat, 5 Oct 2019 09:06:13 -0700 Subject: Error if $currQ not found --- backends/aiger/xaiger.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 4547b9c09..3e3a8fdc6 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -485,7 +485,11 @@ struct XAigerWriter if (box_module->get_bool_attribute("\\abc9_flop")) { IdString port_name = "\\$currQ"; Wire *w = box_module->wire(port_name); + if (!w) + log_error("'$currQ' is not a wire present in module '%s'.\n", log_id(box_module)); SigSpec rhs = module->wire(stringf("%s.$currQ", cell->name.c_str())); + if (rhs.empty()) + log_error("'%s.$currQ' is not a wire present in module '%s'.\n", log_id(cell), log_id(module)); log_assert(GetSize(w) == GetSize(rhs)); int offset = 0; -- cgit v1.2.3 From 3879ca13983a6e3f7d4653b1d80dacd14fbe82df Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Sat, 5 Oct 2019 22:55:18 -0700 Subject: Do not require changes to cells_sim.v; try and work out comb model --- backends/aiger/xaiger.cc | 118 +++++++++++++---------- passes/techmap/abc9.cc | 36 ++----- techlibs/xilinx/abc9_map.v | 199 ++++++++++++++++++++++++++++++++++---- techlibs/xilinx/abc9_model.v | 5 +- techlibs/xilinx/abc9_xc7.box | 2 +- techlibs/xilinx/cells_sim.v | 224 ++++--------------------------------------- 6 files changed, 276 insertions(+), 308 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 3e3a8fdc6..cedf611f2 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -481,16 +481,11 @@ struct XAigerWriter } } - // Connect $currQ as an input to the flop box + // Connect .$currQ (inserted by abc9_map.v) as an input to the flop box if (box_module->get_bool_attribute("\\abc9_flop")) { - IdString port_name = "\\$currQ"; - Wire *w = box_module->wire(port_name); - if (!w) - log_error("'$currQ' is not a wire present in module '%s'.\n", log_id(box_module)); SigSpec rhs = module->wire(stringf("%s.$currQ", cell->name.c_str())); if (rhs.empty()) log_error("'%s.$currQ' is not a wire present in module '%s'.\n", log_id(cell), log_id(module)); - log_assert(GetSize(w) == GetSize(rhs)); int offset = 0; for (auto b : rhs) { @@ -503,7 +498,7 @@ struct XAigerWriter else alias_map[b] = I; } - co_bits.emplace_back(b, cell, port_name, offset++, 0); + co_bits.emplace_back(b, cell, "\\$currQ", offset++, 0); unused_bits.erase(b); } } @@ -737,6 +732,8 @@ struct XAigerWriter 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()) + Pass::call_on_module(module->design, box_module, "proc"); int box_inputs = 0, box_outputs = 0; auto r = cell_cache.insert(std::make_pair(derived_name, nullptr)); @@ -753,7 +750,7 @@ struct XAigerWriter RTLIL::Wire *w = box_module->wire(port_name); log_assert(w); RTLIL::Wire *holes_wire; - RTLIL::SigSpec port_wire; + RTLIL::SigSpec port_sig; if (w->port_input) for (int i = 0; i < GetSize(w); i++) { box_inputs++; @@ -765,7 +762,7 @@ struct XAigerWriter holes_module->ports.push_back(holes_wire->name); } if (holes_cell) - port_wire.append(holes_wire); + port_sig.append(holes_wire); } if (w->port_output) { box_outputs += GetSize(w); @@ -777,41 +774,36 @@ struct XAigerWriter holes_wire->port_output = true; holes_wire->port_id = port_id++; holes_module->ports.push_back(holes_wire->name); - if (holes_cell) - port_wire.append(holes_wire); + if (holes_cell) { + port_sig.append(holes_wire); + } else holes_module->connect(holes_wire, State::S0); } } - if (!port_wire.empty()) { + if (!port_sig.empty()) { if (r.second) - holes_cell->setPort(w->name, port_wire); + holes_cell->setPort(w->name, port_sig); else - holes_module->connect(port_wire, holes_cell->getPort(w->name)); + holes_module->connect(holes_cell->getPort(w->name), port_sig); } } - // For flops only, create an extra input for $currQ + // For flops only, create an extra 1-bit input that drives a new wire + // called ".$currQ" that is used below if (box_module->get_bool_attribute("\\abc9_flop")) { log_assert(holes_cell); - Wire *w = box_module->wire("\\$currQ"); - Wire *holes_wire; - RTLIL::SigSpec port_wire; - 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); - } - port_wire.append(holes_wire); + 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); } - w = holes_module->addWire(stringf("%s.$currQ", cell->name.c_str()), GetSize(w)); - w->set_bool_attribute("\\hierconn"); - holes_module->connect(w, port_wire); + Wire *w = holes_module->addWire(stringf("%s.$currQ", cell->name.c_str())); + holes_module->connect(w, holes_wire); } write_h_buffer(box_inputs); @@ -866,37 +858,67 @@ struct XAigerWriter //holes_module->fixup_ports(); holes_module->check(); - Design *design = holes_module->design; - design->selection_stack.emplace_back(false); - RTLIL::Selection& sel = design->selection_stack.back(); - log_assert(design->selected_active_module == module->name.c_str()); - design->selected_active_module = holes_module->name.str(); - sel.select(holes_module); - - Pass::call(design, "flatten -wb"); - // TODO: Should techmap/aigmap/check all lib_whitebox-es just once, // instead of per write_xaiger call - Pass::call(design, "techmap"); - Pass::call(design, "aigmap"); - for (auto cell : holes_module->cells()) - if (!cell->type.in("$_NOT_", "$_AND_")) + Pass::call_on_module(holes_module->design, holes_module, "flatten -wb; techmap; aigmap"); + + dict output_port; + SigMap holes_sigmap(holes_module); + for (auto port_name : holes_module->ports) { + Wire *port = holes_module->wire(port_name); + if (port->port_input) + continue; + output_port.insert(std::make_pair(holes_sigmap(port), port)); + } + + dict replace; + for (auto it = holes_module->cells_.begin(); it != holes_module->cells_.end(); ) { + auto cell = it->second; + if (cell->type.in("$_DFF_N_", "$_DFF_P_")) { + 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 = output_port.at(Q); + log_assert(port); + // Prepare to replace "assign = DFF.Q;" with "assign = DFF.D;" + // in order to extract the combinatorial control logic that feeds the box + // (i.e. clock enable, synchronous reset, etc.) + replace.insert(std::make_pair(SigSig(port,Q), SigSig(port,D))); + // Since `flatten` above would have created wires named ".Q", + // extract the pre-techmap cell name + auto pos = Q.wire->name.str().rfind("."); + log_assert(pos != std::string::npos); + IdString driver = Q.wire->name.substr(0, pos); + // And drive the signal that was previously driven by "DFF.Q" (typically + // used to implement clock-enable functionality) with the ".$currQ" + // wire (which itself is driven an input port) we inserted above + Wire *currQ = holes_module->wire(stringf("%s.$currQ", driver.c_str())); + log_assert(currQ); + holes_module->connect(Q, currQ); + continue; + } + else if (!cell->type.in("$_NOT_", "$_AND_")) log_error("Whitebox contents cannot be represented as AIG. Please verify whiteboxes are synthesisable.\n"); + ++it; + } - design->selection_stack.pop_back(); - design->selected_active_module = module->name.str(); + for (auto &conn : holes_module->connections_) { + auto it = replace.find(conn); + if (it != replace.end()) + conn = it->second; + } // Move into a new (temporary) design so that "clean" will only // operate (and run checks on) this one module RTLIL::Design *holes_design = new RTLIL::Design; - design->modules_.erase(holes_module->name); + module->design->modules_.erase(holes_module->name); holes_design->add(holes_module); Pass::call(holes_design, "clean -purge"); std::stringstream a_buffer; XAigerWriter writer(holes_module, false /*zinit_mode*/, true /* holes_mode */); writer.write_aiger(a_buffer, false /*ascii_mode*/); - delete holes_design; f << "a"; diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index e9cdaf524..2ceaacf87 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -1122,39 +1122,15 @@ struct Abc9Pass : public Pass { if (!inst_module || !inst_module->attributes.count("\\abc9_flop")) continue; - auto derived_name = inst_module->derive(design, cell->parameters); - auto derived_module = design->module(derived_name); - log_assert(derived_module); - if (derived_module->has_processes()) - Pass::call_on_module(design, derived_module, "proc"); - SigMap derived_sigmap(derived_module); - - SigSpec pattern; - SigSpec with; - for (auto &conn : cell->connections()) { - Wire *first = derived_module->wire(conn.first); - log_assert(first); - SigSpec second = assign_map(conn.second); - log_assert(GetSize(first) == GetSize(second)); - pattern.append(first); - with.append(second); - } - - Wire *abc9_clock_wire = derived_module->wire("\\$abc9_clock"); + Wire *abc9_clock_wire = module->wire(stringf("%s.$abc9_clock", cell->name.c_str())); if (abc9_clock_wire == NULL) - log_error("'\\$abc9_clock' is not a wire present in module '%s'.\n", log_id(cell->type)); - SigSpec abc9_clock = derived_sigmap(abc9_clock_wire); - abc9_clock.replace(pattern, with); - for (const auto &c : abc9_clock.chunks()) - log_assert(!c.wire || c.wire->module == module); + log_error("'%s$abc9_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); - Wire *abc9_control_wire = derived_module->wire("\\$abc9_control"); + Wire *abc9_control_wire = module->wire(stringf("%s.$abc9_control", cell->name.c_str())); if (abc9_control_wire == NULL) - log_error("'\\$abc9_control' is not a wire present in module '%s'.\n", log_id(cell->type)); - SigSpec abc9_control = derived_sigmap(abc9_control_wire); - abc9_control.replace(pattern, with); - for (const auto &c : abc9_control.chunks()) - log_assert(!c.wire || c.wire->module == module); + log_error("'%s$abc9_control' is not a wire present in module '%s'.\n", cell->name.c_str(), log_id(module)); + SigSpec abc9_control = assign_map(abc9_control_wire); unassigned_cells.erase(cell); expand_queue.insert(cell); diff --git a/techlibs/xilinx/abc9_map.v b/techlibs/xilinx/abc9_map.v index 05063f86d..ef7a1a09f 100644 --- a/techlibs/xilinx/abc9_map.v +++ b/techlibs/xilinx/abc9_map.v @@ -49,8 +49,57 @@ module FDRE (output reg Q, input C, CE, D, R); ) _TECHMAP_REPLACE_ ( .D(D), .Q($nextQ), .C(C), .CE(CE), .R(R) ); - wire _TECHMAP_REPLACE_.$currQ = Q; + // `abc9' requires that complex flops be split into a combinatorial box + // feeding a simple flop ($_ABC9_FF_). + // 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. > || |$_ABC_| + // CE -->>-----< logic >--->>-- $nextQ --| FF_ |--+-->> Q + // $currQ +-->>-----< > || +------+ | + // | || \/\/\/\/ || | + // | || || | + // | ++==================++ | + // | | + // +----------------------------------------------+ \$__ABC9_FF_ abc_dff (.D($nextQ), .Q(Q)); + + // Special signal indicating clock domain + // (used to partition the module so that `abc9' only performs + // sequential synthesis (reachability analysis) correctly on + // one domain at a time) + wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, IS_C_INVERTED}; + // Special signal indicating control domain + // (which, combined with this cell type, encodes to `abc9' + // which flops may be merged together) + wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, IS_D_INVERTED, R, IS_R_INVERTED}; + // Special signal indicating the current value of the flip-flop + // In order to achieve clock-enable behaviour, the current value + // of the sequential output is required which Yosys will + // connect to the special `$currQ' wire. + wire _TECHMAP_REPLACE_.$currQ = Q; endmodule module FDRE_1 (output reg Q, input C, CE, D, R); parameter [0:0] INIT = 1'b0; @@ -60,8 +109,22 @@ module FDRE_1 (output reg Q, input C, CE, D, R); ) _TECHMAP_REPLACE_ ( .D(D), .Q($nextQ), .C(C), .CE(CE), .R(R) ); - wire _TECHMAP_REPLACE_.$currQ = Q; \$__ABC9_FF_ abc_dff (.D($nextQ), .Q(Q)); + + // Special signal indicating clock domain + // (used to partition the module so that `abc9' only performs + // sequential synthesis (reachability analysis) correctly on + // one domain at a time) + wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */}; + // Special signal indicating control domain + // (which, combined with this spell type, encodes to `abc9' + // which flops may be merged together) + wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, 1'b0 /* IS_D_INVERTED */, R, 1'b0 /* IS_R_INVERTED */}; + // Special signal indicating the current value of the flip-flop + // In order to achieve clock-enable behaviour, the current value + // of the sequential output is required which Yosys will + // connect to the special `$currQ' wire. + wire _TECHMAP_REPLACE_.$currQ = Q; endmodule module FDCE (output reg Q, input C, CE, D, CLR); @@ -69,18 +132,38 @@ module FDCE (output reg Q, input C, CE, D, CLR); 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 $currQ, $nextQ; + wire $nextQ, $currQ; FDCE #( .INIT(INIT), .IS_C_INVERTED(IS_C_INVERTED), .IS_D_INVERTED(IS_D_INVERTED), .IS_CLR_INVERTED(IS_CLR_INVERTED) ) _TECHMAP_REPLACE_ ( - .D(D), .Q($nextQ), .C(C), .CE(CE), .CLR(CLR) + .D(D), .Q($nextQ), .C(C), .CE(CE), .CLR(IS_CLR_INVERTED) + // ^^^ Note that async + // control is disabled + // and captured by + // $__ABC9_ASYNC below ); - wire _TECHMAP_REPLACE_.$currQ = Q; \$__ABC9_FF_ abc_dff (.D($nextQ), .Q($currQ)); - \$__ABC_ASYNC abc_async (.A($currQ), .S(CLR ^ IS_CLR_INVERTED), .Y(Q)); + // Since this is an async flop, async behaviour is also dealt with + // using the $_ABC9_ASYNC box by abc9_map.v + \$__ABC9_ASYNC abc_async (.A($currQ), .S(CLR ^ IS_CLR_INVERTED), .Y(Q)); + + // Special signal indicating clock domain + // (used to partition the module so that `abc9' only performs + // sequential synthesis (reachability analysis) correctly on + // one domain at a time) + wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, IS_C_INVERTED}; + // Special signal indicating control domain + // (which, combined with this spell type, encodes to `abc9' + // which flops may be merged together) + wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, IS_D_INVERTED, CLR, IS_CLR_INVERTED}; + // Special signal indicating the current value of the flip-flop + // In order to achieve clock-enable behaviour, the current value + // of the sequential output is required which Yosys will + // connect to the special `$currQ' wire. + wire _TECHMAP_REPLACE_.$currQ = $currQ; endmodule module FDCE_1 (output reg Q, input C, CE, D, CLR); parameter [0:0] INIT = 1'b0; @@ -88,11 +171,29 @@ module FDCE_1 (output reg Q, input C, CE, D, CLR); FDCE_1 #( .INIT(INIT) ) _TECHMAP_REPLACE_ ( - .D(D), .Q($nextQ), .C(C), .CE(CE), .CLR(CLR) + .D(D), .Q($nextQ), .C(C), .CE(CE), .CLR(1'b0) + // ^^^ Note that async + // control is disabled + // and captured by + // $__ABC9_ASYNC below ); - wire _TECHMAP_REPLACE_.$currQ = Q; \$__ABC9_FF_ abc_dff (.D($nextQ), .Q($currQ)); - \$__ABC_ASYNC abc_async (.A($currQ), .S(CLR), .Y(Q)); + \$__ABC9_ASYNC abc_async (.A($currQ), .S(CLR), .Y(Q)); + + // Special signal indicating clock domain + // (used to partition the module so that `abc9' only performs + // sequential synthesis (reachability analysis) correctly on + // one domain at a time) + wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */}; + // Special signal indicating control domain + // (which, combined with this spell type, encodes to `abc9' + // which flops may be merged together) + wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, 1'b0 /* IS_D_INVERTED */, CLR, 1'b0 /* IS_CLR_INVERTED */}; + // Special signal indicating the current value of the flip-flop + // In order to achieve clock-enable behaviour, the current value + // of the sequential output is required which Yosys will + // connect to the special `$currQ' wire. + wire _TECHMAP_REPLACE_.$currQ = $currQ; endmodule module FDPE (output reg Q, input C, CE, D, PRE); @@ -107,11 +208,29 @@ module FDPE (output reg Q, input C, CE, D, PRE); .IS_D_INVERTED(IS_D_INVERTED), .IS_PRE_INVERTED(IS_PRE_INVERTED), ) _TECHMAP_REPLACE_ ( - .D(D), .Q($nextQ), .C(C), .CE(CE), .PRE(PRE) + .D(D), .Q($nextQ), .C(C), .CE(CE), .PRE(IS_PRE_INVERTED) + // ^^^ Note that async + // control is disabled + // and captured by + // $__ABC9_ASYNC below ); - wire _TECHMAP_REPLACE_.$currQ = Q; \$__ABC9_FF_ abc_dff (.D($nextQ), .Q($currQ)); - \$__ABC_ASYNC abc_async (.A($currQ), .S(PRE ^ IS_PRE_INVERTED), .Y(Q)); + \$__ABC9_ASYNC abc_async (.A($currQ), .S(PRE ^ IS_PRE_INVERTED), .Y(Q)); + + // Special signal indicating clock domain + // (used to partition the module so that `abc9' only performs + // sequential synthesis (reachability analysis) correctly on + // one domain at a time) + wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, IS_C_INVERTED}; + // Special signal indicating control domain + // (which, combined with this spell type, encodes to `abc9' + // which flops may be merged together) + wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, IS_D_INVERTED, PRE, IS_PRE_INVERTED}; + // Special signal indicating the current value of the flip-flop + // In order to achieve clock-enable behaviour, the current value + // of the sequential output is required which Yosys will + // connect to the special `$currQ' wire. + wire _TECHMAP_REPLACE_.$currQ = $currQ; endmodule module FDPE_1 (output reg Q, input C, CE, D, PRE); parameter [0:0] INIT = 1'b0; @@ -119,11 +238,29 @@ module FDPE_1 (output reg Q, input C, CE, D, PRE); FDPE_1 #( .INIT(INIT) ) _TECHMAP_REPLACE_ ( - .D(D), .Q($nextQ), .C(C), .CE(CE), .PRE(PRE) + .D(D), .Q($nextQ), .C(C), .CE(CE), .PRE(1'b0) + // ^^^ Note that async + // control is disabled + // and captured by + // $__ABC9_ASYNC below ); - wire _TECHMAP_REPLACE_.$currQ = Q; \$__ABC9_FF_ abc_dff (.D($nextQ), .Q($currQ)); - \$__ABC_ASYNC abc_async (.A($currQ), .S(PRE), .Y(Q)); + \$__ABC9_ASYNC abc_async (.A($currQ), .S(PRE), .Y(Q)); + + // Special signal indicating clock domain + // (used to partition the module so that `abc9' only performs + // sequential synthesis (reachability analysis) correctly on + // one domain at a time) + wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */}; + // Special signal indicating control domain + // (which, combined with this spell type, encodes to `abc9' + // which flops may be merged together) + wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, 1'b0 /* IS_D_INVERTED */, PRE, 1'b0 /* IS_PRE_INVERTED */}; + // Special signal indicating the current value of the flip-flop + // In order to achieve clock-enable behaviour, the current value + // of the sequential output is required which Yosys will + // connect to the special `$currQ' wire. + wire _TECHMAP_REPLACE_.$currQ = $currQ; endmodule module FDSE (output reg Q, input C, CE, D, S); @@ -140,8 +277,22 @@ module FDSE (output reg Q, input C, CE, D, S); ) _TECHMAP_REPLACE_ ( .D(D), .Q($nextQ), .C(C), .CE(CE), .S(S) ); - wire _TECHMAP_REPLACE_.$currQ = Q; \$__ABC9_FF_ abc_dff (.D($nextQ), .Q(Q)); + + // Special signal indicating clock domain + // (used to partition the module so that `abc9' only performs + // sequential synthesis (reachability analysis) correctly on + // one domain at a time) + wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, IS_C_INVERTED}; + // Special signal indicating control domain + // (which, combined with this spell type, encodes to `abc9' + // which flops may be merged together) + wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, IS_D_INVERTED, S, IS_S_INVERTED}; + // Special signal indicating the current value of the flip-flop + // In order to achieve clock-enable behaviour, the current value + // of the sequential output is required which Yosys will + // connect to the special `$currQ' wire. + wire _TECHMAP_REPLACE_.$currQ = Q; endmodule module FDSE_1 (output reg Q, input C, CE, D, S); parameter [0:0] INIT = 1'b0; @@ -151,8 +302,22 @@ module FDSE_1 (output reg Q, input C, CE, D, S); ) _TECHMAP_REPLACE_ ( .D(D), .Q($nextQ), .C(C), .CE(CE), .S(S) ); - wire _TECHMAP_REPLACE_.$currQ = Q; \$__ABC9_FF_ abc_dff (.D($nextQ), .Q(Q)); + + // Special signal indicating clock domain + // (used to partition the module so that `abc9' only performs + // sequential synthesis (reachability analysis) correctly on + // one domain at a time) + wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */}; + // Special signal indicating control domain + // (which, combined with this spell type, encodes to `abc9' + // which flops may be merged together) + wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, 1'b0 /* IS_D_INVERTED */, S, 1'b0 /* IS_S_INVERTED */}; + // Special signal indicating the current value of the flip-flop + // In order to achieve clock-enable behaviour, the current value + // of the sequential output is required which Yosys will + // connect to the special `$currQ' wire. + wire _TECHMAP_REPLACE_.$currQ = Q; endmodule module RAM32X1D ( diff --git a/techlibs/xilinx/abc9_model.v b/techlibs/xilinx/abc9_model.v index 74b5cf66a..c17d6744a 100644 --- a/techlibs/xilinx/abc9_model.v +++ b/techlibs/xilinx/abc9_model.v @@ -30,11 +30,8 @@ module \$__XILINX_MUXF78 (output O, input I0, I1, I2, I3, S0, S1); : (S0 ? I1 : I0); endmodule -module \$__ABC_FF_ (input D, output Q); -endmodule - (* abc_box_id = 1000 *) -module \$__ABC_ASYNC (input A, S, output Y); +module \$__ABC9_ASYNC (input A, S, output Y); endmodule // Box to emulate comb/seq behaviour of RAMD{32,64} and SRL{16,32} diff --git a/techlibs/xilinx/abc9_xc7.box b/techlibs/xilinx/abc9_xc7.box index 6814b101f..24b1898a4 100644 --- a/techlibs/xilinx/abc9_xc7.box +++ b/techlibs/xilinx/abc9_xc7.box @@ -44,7 +44,7 @@ CARRY4 4 1 10 8 # Box to emulate async behaviour of FD[CP]* # Inputs: A S # Outputs: Y -$__ABC_ASYNC 1000 0 2 1 +$__ABC9_ASYNC 1000 0 2 1 0 764 # The following FD*.{CE,R,CLR,PRE) are offset by 46ps to diff --git a/techlibs/xilinx/cells_sim.v b/techlibs/xilinx/cells_sim.v index 309ee500a..35d9aac96 100644 --- a/techlibs/xilinx/cells_sim.v +++ b/techlibs/xilinx/cells_sim.v @@ -258,33 +258,10 @@ module FDRE ( parameter [0:0] IS_D_INVERTED = 1'b0; parameter [0:0] IS_R_INVERTED = 1'b0; initial Q <= INIT; - wire \$currQ ; - reg \$nextQ ; - always @* if (R == !IS_R_INVERTED) \$nextQ = 1'b0; else if (CE) \$nextQ = D ^ IS_D_INVERTED; else \$nextQ = \$currQ ; -`ifdef _ABC9 - // `abc9' requires that complex flops be split into a combinatorial - // box (this module) feeding a simple flop ($_ABC9_FF_ in abc9_map.v) - // In order to achieve clock-enable behaviour, the current value - // of the sequential output is required which Yosys will - // connect to the special `$currQ' wire. - - // Special signal indicating clock domain - // (used to partition the module so that `abc9' only performs - // sequential synthesis (reachability analysis) correctly on - // one domain at a time) - wire [1:0] $abc9_clock = {C, IS_C_INVERTED}; - // Special signal indicating control domain - // (which, combined with this spell type, encodes to `abc9' - // which flops may be merged together) - wire [3:0] $abc9_control = {CE, IS_D_INVERTED, R, IS_R_INVERTED}; - always @* Q = \$nextQ ; -`else - assign \$currQ = Q; generate case (|IS_C_INVERTED) - 1'b0: always @(posedge C) Q <= \$nextQ ; - 1'b1: always @(negedge C) Q <= \$nextQ ; + 1'b0: always @(posedge C) if (R == !IS_R_INVERTED) Q <= 1'b0; else if (CE) Q <= D ^ IS_D_INVERTED; + 1'b1: always @(negedge C) if (R == !IS_R_INVERTED) Q <= 1'b0; else if (CE) Q <= D ^ IS_D_INVERTED; endcase endgenerate -`endif endmodule (* abc9_box_id=1002, lib_whitebox, abc9_flop *) @@ -297,30 +274,7 @@ module FDRE_1 ( ); parameter [0:0] INIT = 1'b0; initial Q <= INIT; - wire \$currQ ; - reg \$nextQ ; - always @* if (R) Q <= 1'b0; else if (CE) Q <= D; else \$nextQ = \$currQ ; -`ifdef _ABC9 - // `abc9' requires that complex flops be split into a combinatorial - // box (this module) feeding a simple flop ($_ABC9_FF_ in abc9_map.v) - // In order to achieve clock-enable behaviour, the current value - // of the sequential output is required which Yosys will - // connect to the special `$currQ' wire. - - // Special signal indicating clock domain - // (used to partition the module so that `abc9' only performs - // sequential synthesis (reachability analysis) correctly on - // one domain at a time) - wire [1:0] $abc9_clock = {C, 1'b1 /* IS_C_INVERTED */}; - // Special signal indicating control domain - // (which, combined with this spell type, encodes to `abc9' - // which flops may be merged together) - wire [3:0] $abc9_control = {CE, 1'b0 /* IS_D_INVERTED */, R, 1'b0 /* IS_R_INVERTED */}; - always @* Q = \$nextQ ; -`else - assign \$currQ = Q; - always @(negedge C) Q <= \$nextQ ; -`endif + always @(negedge C) if (R) Q <= 1'b0; else if (CE) Q <= D; endmodule (* abc9_box_id=1003, lib_whitebox, abc9_flop *) @@ -341,37 +295,12 @@ module FDCE ( parameter [0:0] IS_D_INVERTED = 1'b0; parameter [0:0] IS_CLR_INVERTED = 1'b0; initial Q <= INIT; - wire \$currQ ; - reg \$nextQ ; - always @* if (CE) Q <= D ^ IS_D_INVERTED; else \$nextQ = \$currQ ; -`ifdef _ABC9 - // `abc9' requires that complex flops be split into a combinatorial - // box (this module) feeding a simple flop ($_ABC9_FF_ in abc9_map.v) - // In order to achieve clock-enable behaviour, the current value - // of the sequential output is required which Yosys will - // connect to the special `$currQ' wire. - // Since this is an async flop, async behaviour is also dealt with - // using the $_ABC9_ASYNC box by abc9_map.v - - // Special signal indicating clock domain - // (used to partition the module so that `abc9' only performs - // sequential synthesis (reachability analysis) correctly on - // one domain at a time) - wire [1:0] $abc9_clock = {C, IS_C_INVERTED}; - // Special signal indicating control domain - // (which, combined with this spell type, encodes to `abc9' - // which flops may be merged together) - wire [3:0] $abc9_control = {CE, IS_D_INVERTED, CLR, IS_CLR_INVERTED}; - always @* Q = \$nextQ ; -`else - assign \$currQ = Q; generate case ({|IS_C_INVERTED, |IS_CLR_INVERTED}) - 2'b00: always @(posedge C, posedge CLR) if ( CLR) Q <= 1'b0; else Q <= \$nextQ ; - 2'b01: always @(posedge C, negedge CLR) if (!CLR) Q <= 1'b0; else Q <= \$nextQ ; - 2'b10: always @(negedge C, posedge CLR) if ( CLR) Q <= 1'b0; else Q <= \$nextQ ; - 2'b11: always @(negedge C, negedge CLR) if (!CLR) Q <= 1'b0; else Q <= \$nextQ ; + 2'b00: always @(posedge C, posedge CLR) if ( CLR) Q <= 1'b0; else if (CE) Q <= D ^ IS_D_INVERTED; + 2'b01: always @(posedge C, negedge CLR) if (!CLR) Q <= 1'b0; else if (CE) Q <= D ^ IS_D_INVERTED; + 2'b10: always @(negedge C, posedge CLR) if ( CLR) Q <= 1'b0; else if (CE) Q <= D ^ IS_D_INVERTED; + 2'b11: always @(negedge C, negedge CLR) if (!CLR) Q <= 1'b0; else if (CE) Q <= D ^ IS_D_INVERTED; endcase endgenerate -`endif endmodule (* abc9_box_id=1004, lib_whitebox, abc9_flop *) @@ -384,32 +313,7 @@ module FDCE_1 ( ); parameter [0:0] INIT = 1'b0; initial Q <= INIT; - wire \$currQ ; - reg \$nextQ ; - always @* if (CE) Q <= D; else \$nextQ = \$currQ ; -`ifdef _ABC9 - // `abc9' requires that complex flops be split into a combinatorial - // box (this module) feeding a simple flop ($_ABC9_FF_ in abc9_map.v) - // In order to achieve clock-enable behaviour, the current value - // of the sequential output is required which Yosys will - // connect to the special `$currQ' wire. - // Since this is an async flop, async behaviour is also dealt with - // using the $_ABC9_ASYNC box by abc9_map.v - - // Special signal indicating clock domain - // (used to partition the module so that `abc9' only performs - // sequential synthesis (reachability analysis) correctly on - // one domain at a time) - wire [1:0] $abc9_clock = {C, 1'b1 /* IS_C_INVERTED */}; - // Special signal indicating control domain - // (which, combined with this spell type, encodes to `abc9' - // which flops may be merged together) - wire [3:0] $abc9_control = {CE, 1'b0 /* IS_D_INVERTED */, CLR, 1'b0 /* IS_CLR_INVERTED */}; - always @* Q = \$nextQ ; -`else - assign \$currQ = Q; - always @(negedge C, posedge CLR) if (CLR) Q <= 1'b0; else Q <= \$nextQ ; -`endif + always @(negedge C, posedge CLR) if (CLR) Q <= 1'b0; else if (CE) Q <= D; endmodule (* abc9_box_id=1005, lib_whitebox, abc9_flop *) @@ -430,37 +334,12 @@ module FDPE ( parameter [0:0] IS_D_INVERTED = 1'b0; parameter [0:0] IS_PRE_INVERTED = 1'b0; initial Q <= INIT; - wire \$currQ ; - reg \$nextQ ; - always @* if (CE) Q <= D ^ IS_D_INVERTED; else \$nextQ = \$currQ ; -`ifdef _ABC9 - // `abc9' requires that complex flops be split into a combinatorial - // box (this module) feeding a simple flop ($_ABC9_FF_ in abc9_map.v) - // In order to achieve clock-enable behaviour, the current value - // of the sequential output is required which Yosys will - // connect to the special `$currQ' wire. - // Since this is an async flop, async behaviour is also dealt with - // using the $_ABC9_ASYNC box by abc9_map.v - - // Special signal indicating clock domain - // (used to partition the module so that `abc9' only performs - // sequential synthesis (reachability analysis) correctly on - // one domain at a time) - wire [1:0] $abc9_clock = {C, IS_C_INVERTED}; - // Special signal indicating control domain - // (which, combined with this spell type, encodes to `abc9' - // which flops may be merged together) - wire [3:0] $abc9_control = {CE, IS_D_INVERTED, PRE, IS_PRE_INVERTED}; - always @* Q = \$nextQ ; -`else - assign \$currQ = Q; generate case ({|IS_C_INVERTED, |IS_PRE_INVERTED}) - 2'b00: always @(posedge C, posedge PRE) if ( PRE) Q <= 1'b1; else Q <= \$nextQ ; - 2'b01: always @(posedge C, negedge PRE) if (!PRE) Q <= 1'b1; else Q <= \$nextQ ; - 2'b10: always @(negedge C, posedge PRE) if ( PRE) Q <= 1'b1; else Q <= \$nextQ ; - 2'b11: always @(negedge C, negedge PRE) if (!PRE) Q <= 1'b1; else Q <= \$nextQ ; + 2'b00: always @(posedge C, posedge PRE) if ( PRE) Q <= 1'b1; else Q <= Q ; + 2'b01: always @(posedge C, negedge PRE) if (!PRE) Q <= 1'b1; else Q <= Q ; + 2'b10: always @(negedge C, posedge PRE) if ( PRE) Q <= 1'b1; else Q <= Q ; + 2'b11: always @(negedge C, negedge PRE) if (!PRE) Q <= 1'b1; else Q <= Q ; endcase endgenerate -`endif endmodule (* abc9_box_id=1006, lib_whitebox, abc9_flop *) @@ -473,32 +352,7 @@ module FDPE_1 ( ); parameter [0:0] INIT = 1'b1; initial Q <= INIT; - wire \$currQ ; - reg \$nextQ ; - always @* if (CE) Q <= D; else \$nextQ = \$currQ ; -`ifdef _ABC9 - // `abc9' requires that complex flops be split into a combinatorial - // box (this module) feeding a simple flop ($_ABC9_FF_ in abc9_map.v) - // In order to achieve clock-enable behaviour, the current value - // of the sequential output is required which Yosys will - // connect to the special `$currQ' wire. - // Since this is an async flop, async behaviour is also dealt with - // using the $_ABC9_ASYNC box by abc9_map.v - - // Special signal indicating clock domain - // (used to partition the module so that `abc9' only performs - // sequential synthesis (reachability analysis) correctly on - // one domain at a time) - wire [1:0] $abc9_clock = {C, 1'b1 /* IS_C_INVERTED */}; - // Special signal indicating control domain - // (which, combined with this spell type, encodes to `abc9' - // which flops may be merged together) - wire [3:0] $abc9_control = {CE, 1'b0 /* IS_D_INVERTED */, PRE, 1'b0 /* IS_PRE_INVERTED */}; - always @* Q = \$nextQ ; -`else - assign \$currQ = Q; - always @(negedge C, posedge PRE) if (PRE) Q <= 1'b1; else Q <= \$nextQ ; -`endif + always @(negedge C, posedge PRE) if (PRE) Q <= 1'b1; else if (CE) Q <= D; endmodule (* abc9_box_id=1007, lib_whitebox, abc9_flop *) @@ -519,33 +373,10 @@ module FDSE ( parameter [0:0] IS_D_INVERTED = 1'b0; parameter [0:0] IS_S_INVERTED = 1'b0; initial Q <= INIT; - wire \$currQ ; - reg \$nextQ ; - always @* if (S == !IS_S_INVERTED) \$nextQ = 1'b1; else if (CE) \$nextQ = D ^ IS_D_INVERTED; else \$nextQ = \$currQ ; -`ifdef _ABC9 - // `abc9' requires that complex flops be split into a combinatorial - // box (this module) feeding a simple flop ($_ABC9_FF_ in abc9_map.v) - // In order to achieve clock-enable behaviour, the current value - // of the sequential output is required which Yosys will - // connect to the special `$currQ' wire. - - // Special signal indicating clock domain - // (used to partition the module so that `abc9' only performs - // sequential synthesis (reachability analysis) correctly on - // one domain at a time) - wire [1:0] $abc9_clock = {C, IS_C_INVERTED}; - // Special signal indicating control domain - // (which, combined with this spell type, encodes to `abc9' - // which flops may be merged together) - wire [3:0] $abc9_control = {CE, IS_D_INVERTED, S, IS_S_INVERTED}; - always @* Q = \$nextQ ; -`else - assign \$currQ = Q; generate case (|IS_C_INVERTED) - 1'b0: always @(posedge C) Q <= \$nextQ ; - 1'b1: always @(negedge C) Q <= \$nextQ ; + 1'b0: always @(posedge C) if (S == !IS_S_INVERTED) Q <= 1'b1; else if (CE) Q <= D ^ IS_D_INVERTED; + 1'b1: always @(negedge C) if (S == !IS_S_INVERTED) Q <= 1'b1; else if (CE) Q <= D ^ IS_D_INVERTED; endcase endgenerate -`endif endmodule (* abc9_box_id=1008, lib_whitebox, abc9_flop *) @@ -558,30 +389,7 @@ module FDSE_1 ( ); parameter [0:0] INIT = 1'b1; initial Q <= INIT; - wire \$currQ ; - reg \$nextQ ; - always @* if (S) \$nextQ = 1'b1; else if (CE) \$nextQ = D; else \$nextQ = \$currQ ; -`ifdef _ABC9 - // `abc9' requires that complex flops be split into a combinatorial - // box (this module) feeding a simple flop ($_ABC9_FF_ in abc9_map.v) - // In order to achieve clock-enable behaviour, the current value - // of the sequential output is required which Yosys will - // connect to the special `$currQ' wire. - - // Special signal indicating clock domain - // (used to partition the module so that `abc9' only performs - // sequential synthesis (reachability analysis) correctly on - // one domain at a time) - wire [1:0] $abc9_clock = {C, 1'b1 /* IS_C_INVERTED */}; - // Special signal indicating control domain - // (which, combined with this spell type, encodes to `abc9' - // which flops may be merged together) - wire [3:0] $abc9_control = {CE, 1'b0 /* IS_D_INVERTED */, S, 1'b0 /* IS_S_INVERTED */}; - always @* Q = \$nextQ ; -`else - assign \$currQ = Q; - always @(negedge C) Q <= \$nextQ ; -`endif + always @(negedge C) if (S) Q <= 1'b1; else if (CE) Q <= D; endmodule module LDCE ( -- cgit v1.2.3 From d9fba95177ce6d37966af6a89e15c09feceee3df Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 7 Oct 2019 11:49:06 -0700 Subject: Get rid of output_port lookup --- backends/aiger/xaiger.cc | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index cedf611f2..33d4cfe8e 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -768,15 +768,14 @@ struct XAigerWriter box_outputs += GetSize(w); for (int i = 0; i < GetSize(w); i++) { if (GetSize(w) == 1) - holes_wire = holes_module->addWire(stringf("%s.%s", cell->name.c_str(), w->name.c_str())); + holes_wire = holes_module->addWire(stringf("$abc%s.%s", cell->name.c_str(), log_id(w->name))); else - holes_wire = holes_module->addWire(stringf("%s.%s[%d]", cell->name.c_str(), w->name.c_str(), i)); + 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) { + if (holes_cell) port_sig.append(holes_wire); - } else holes_module->connect(holes_wire, State::S0); } @@ -862,15 +861,6 @@ struct XAigerWriter // instead of per write_xaiger call Pass::call_on_module(holes_module->design, holes_module, "flatten -wb; techmap; aigmap"); - dict output_port; - SigMap holes_sigmap(holes_module); - for (auto port_name : holes_module->ports) { - Wire *port = holes_module->wire(port_name); - if (port->port_input) - continue; - output_port.insert(std::make_pair(holes_sigmap(port), port)); - } - dict replace; for (auto it = holes_module->cells_.begin(); it != holes_module->cells_.end(); ) { auto cell = it->second; @@ -879,7 +869,11 @@ struct XAigerWriter 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 = output_port.at(Q); + Wire *port; + if (GetSize(Q.wire) == 1) + port = holes_module->wire(stringf("$abc%s", Q.wire->name.c_str())); + else + port = holes_module->wire(stringf("$abc%s[%d]", Q.wire->name.c_str(), Q.offset)); log_assert(port); // Prepare to replace "assign = DFF.Q;" with "assign = DFF.D;" // in order to extract the combinatorial control logic that feeds the box -- cgit v1.2.3 From e1554b56dd9c82b609c6565067160268cbc403f3 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 7 Oct 2019 11:56:17 -0700 Subject: Add comment on default flop init --- backends/aiger/xaiger.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 33d4cfe8e..ce67cac54 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -842,6 +842,7 @@ struct XAigerWriter continue; } } + // Default flop init is zero write_s_buffer(0); } f << "s"; -- cgit v1.2.3 From 1504ca2cd9211d9c4f31ecc262e347c842dc4fba Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 7 Oct 2019 11:58:49 -0700 Subject: Remove "write_xaiger -zinit" --- backends/aiger/xaiger.cc | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index ce67cac54..b1b7af513 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -76,7 +76,6 @@ void aiger_encode(std::ostream &f, int x) struct XAigerWriter { Module *module; - bool zinit_mode; SigMap sigmap; dict init_map; @@ -141,7 +140,7 @@ struct XAigerWriter return a; } - XAigerWriter(Module *module, bool zinit_mode, bool holes_mode=false) : module(module), zinit_mode(zinit_mode), sigmap(module) + XAigerWriter(Module *module, bool holes_mode=false) : module(module), sigmap(module) { pool undriven_bits; pool unused_bits; @@ -912,7 +911,7 @@ struct XAigerWriter Pass::call(holes_design, "clean -purge"); std::stringstream a_buffer; - XAigerWriter writer(holes_module, false /*zinit_mode*/, true /* holes_mode */); + XAigerWriter writer(holes_module, true /* holes_mode */); writer.write_aiger(a_buffer, false /*ascii_mode*/); delete holes_design; @@ -972,10 +971,10 @@ struct XAigerWriter if (output_bits.count(b)) { int o = ordered_outputs.at(b); - int init = zinit_mode ? 0 : 2; + int init = 0; auto it = init_map.find(b); - if (it != init_map.end()) - init = it->second ? 1 : 0; + if (it != init_map.end() && it->second) + init = 1; output_lines[o] += stringf("output %d %d %s %d\n", o - GetSize(co_bits), i, log_id(wire), init); continue; } @@ -1036,10 +1035,6 @@ struct XAigerBackend : public Backend { log(" -ascii\n"); log(" write ASCII version of AIGER format\n"); log("\n"); - log(" -zinit\n"); - log(" convert FFs to zero-initialized FFs, adding additional inputs for\n"); - log(" uninitialized FFs.\n"); - log("\n"); log(" -map \n"); log(" write an extra file with port and latch symbols\n"); log("\n"); @@ -1050,7 +1045,6 @@ struct XAigerBackend : public Backend { void execute(std::ostream *&f, std::string filename, std::vector args, RTLIL::Design *design) YS_OVERRIDE { bool ascii_mode = false; - bool zinit_mode = false; bool verbose_map = false; std::string map_filename; @@ -1063,10 +1057,6 @@ struct XAigerBackend : public Backend { ascii_mode = true; continue; } - if (args[argidx] == "-zinit") { - zinit_mode = true; - continue; - } if (map_filename.empty() && args[argidx] == "-map" && argidx+1 < args.size()) { map_filename = args[++argidx]; continue; @@ -1085,7 +1075,7 @@ struct XAigerBackend : public Backend { if (top_module == nullptr) log_error("Can't find top module in current design!\n"); - XAigerWriter writer(top_module, zinit_mode); + XAigerWriter writer(top_module); writer.write_aiger(*f, ascii_mode); if (!map_filename.empty()) { -- cgit v1.2.3 From 1dc22607c38486d9e1a2b56f749d1eca35d405d2 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 7 Oct 2019 12:21:52 -0700 Subject: Remove -D_ABC9 --- techlibs/xilinx/synth_xilinx.cc | 2 -- 1 file changed, 2 deletions(-) diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index 07f3d9a8a..a99aef7c7 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -286,8 +286,6 @@ struct SynthXilinxPass : public ScriptPass std::string read_args; if (vpr) read_args += " -D_EXPLICIT_CARRY"; - if (abc9) - read_args += " -D_ABC9"; read_args += " -lib +/xilinx/cells_sim.v"; run("read_verilog" + read_args); -- cgit v1.2.3 From bae3d8705d844912699b0ed502630040ce4efa85 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 7 Oct 2019 12:54:45 -0700 Subject: Update comments in abc9_map.v --- techlibs/xilinx/abc9_map.v | 188 ++++++++++++++------------------------------- 1 file changed, 57 insertions(+), 131 deletions(-) diff --git a/techlibs/xilinx/abc9_map.v b/techlibs/xilinx/abc9_map.v index ef7a1a09f..feaf979ad 100644 --- a/techlibs/xilinx/abc9_map.v +++ b/techlibs/xilinx/abc9_map.v @@ -28,12 +28,53 @@ // ============================================================================ -// The purpose of the following FD* rules are to wrap the flop (which, when -// called with the `_ABC' macro set captures only its combinatorial -// behaviour) with: +// `abc9' requires that complex flops be split into a combinatorial box +// feeding a simple flop ($_ABC9_FF_). +// 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. > || |$_ABC_| +// CE -->>-----< logic >--->>-- $nextQ --| FF_ |--+-->> Q +// $currQ +-->>-----< > || +------+ | +// | || \/\/\/\/ || | +// | || || | +// | ++==================++ | +// | | +// +----------------------------------------------+ +// +// 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) a special TECHMAP_REPLACE_.$currQ wire that will be used for feedback +// (b) a special _TECHMAP_REPLACE_.$abc9_clock wire to capture its clock +// domain (used when partitioning the module so that `abc9' only +// performs sequential synthesis (with reachability analysis) correctly on +// one domain at a time) +// (c) a special _TECHMAP_REPLACE_.$abc9_control that captures the control +// domain (which, combined with this cell type, encodes to `abc9' which +// flops may be merged together) +// (d) a special _TECHMAP_REPLACE_.$currQ wire that will be used for feedback // into the (combinatorial) FD* cell to facilitate clock-enable behaviour module FDRE (output reg Q, input C, CE, D, R); parameter [0:0] INIT = 1'b0; @@ -49,56 +90,11 @@ module FDRE (output reg Q, input C, CE, D, R); ) _TECHMAP_REPLACE_ ( .D(D), .Q($nextQ), .C(C), .CE(CE), .R(R) ); - // `abc9' requires that complex flops be split into a combinatorial box - // feeding a simple flop ($_ABC9_FF_). - // 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. > || |$_ABC_| - // CE -->>-----< logic >--->>-- $nextQ --| FF_ |--+-->> Q - // $currQ +-->>-----< > || +------+ | - // | || \/\/\/\/ || | - // | || || | - // | ++==================++ | - // | | - // +----------------------------------------------+ \$__ABC9_FF_ abc_dff (.D($nextQ), .Q(Q)); - // Special signal indicating clock domain - // (used to partition the module so that `abc9' only performs - // sequential synthesis (reachability analysis) correctly on - // one domain at a time) + // Special signals wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, IS_C_INVERTED}; - // Special signal indicating control domain - // (which, combined with this cell type, encodes to `abc9' - // which flops may be merged together) wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, IS_D_INVERTED, R, IS_R_INVERTED}; - // Special signal indicating the current value of the flip-flop - // In order to achieve clock-enable behaviour, the current value - // of the sequential output is required which Yosys will - // connect to the special `$currQ' wire. wire _TECHMAP_REPLACE_.$currQ = Q; endmodule module FDRE_1 (output reg Q, input C, CE, D, R); @@ -111,19 +107,9 @@ module FDRE_1 (output reg Q, input C, CE, D, R); ); \$__ABC9_FF_ abc_dff (.D($nextQ), .Q(Q)); - // Special signal indicating clock domain - // (used to partition the module so that `abc9' only performs - // sequential synthesis (reachability analysis) correctly on - // one domain at a time) + // Special signals wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */}; - // Special signal indicating control domain - // (which, combined with this spell type, encodes to `abc9' - // which flops may be merged together) wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, 1'b0 /* IS_D_INVERTED */, R, 1'b0 /* IS_R_INVERTED */}; - // Special signal indicating the current value of the flip-flop - // In order to achieve clock-enable behaviour, the current value - // of the sequential output is required which Yosys will - // connect to the special `$currQ' wire. wire _TECHMAP_REPLACE_.$currQ = Q; endmodule @@ -142,7 +128,7 @@ module FDCE (output reg Q, input C, CE, D, CLR); .D(D), .Q($nextQ), .C(C), .CE(CE), .CLR(IS_CLR_INVERTED) // ^^^ Note that async // control is disabled - // and captured by + // here but captured by // $__ABC9_ASYNC below ); \$__ABC9_FF_ abc_dff (.D($nextQ), .Q($currQ)); @@ -150,19 +136,9 @@ module FDCE (output reg Q, input C, CE, D, CLR); // using the $_ABC9_ASYNC box by abc9_map.v \$__ABC9_ASYNC abc_async (.A($currQ), .S(CLR ^ IS_CLR_INVERTED), .Y(Q)); - // Special signal indicating clock domain - // (used to partition the module so that `abc9' only performs - // sequential synthesis (reachability analysis) correctly on - // one domain at a time) + // Special signals wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, IS_C_INVERTED}; - // Special signal indicating control domain - // (which, combined with this spell type, encodes to `abc9' - // which flops may be merged together) wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, IS_D_INVERTED, CLR, IS_CLR_INVERTED}; - // Special signal indicating the current value of the flip-flop - // In order to achieve clock-enable behaviour, the current value - // of the sequential output is required which Yosys will - // connect to the special `$currQ' wire. wire _TECHMAP_REPLACE_.$currQ = $currQ; endmodule module FDCE_1 (output reg Q, input C, CE, D, CLR); @@ -174,25 +150,15 @@ module FDCE_1 (output reg Q, input C, CE, D, CLR); .D(D), .Q($nextQ), .C(C), .CE(CE), .CLR(1'b0) // ^^^ Note that async // control is disabled - // and captured by + // here but captured by // $__ABC9_ASYNC below ); \$__ABC9_FF_ abc_dff (.D($nextQ), .Q($currQ)); \$__ABC9_ASYNC abc_async (.A($currQ), .S(CLR), .Y(Q)); - // Special signal indicating clock domain - // (used to partition the module so that `abc9' only performs - // sequential synthesis (reachability analysis) correctly on - // one domain at a time) + // Special signals wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */}; - // Special signal indicating control domain - // (which, combined with this spell type, encodes to `abc9' - // which flops may be merged together) wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, 1'b0 /* IS_D_INVERTED */, CLR, 1'b0 /* IS_CLR_INVERTED */}; - // Special signal indicating the current value of the flip-flop - // In order to achieve clock-enable behaviour, the current value - // of the sequential output is required which Yosys will - // connect to the special `$currQ' wire. wire _TECHMAP_REPLACE_.$currQ = $currQ; endmodule @@ -211,25 +177,15 @@ module FDPE (output reg Q, input C, CE, D, PRE); .D(D), .Q($nextQ), .C(C), .CE(CE), .PRE(IS_PRE_INVERTED) // ^^^ Note that async // control is disabled - // and captured by + // here but captured by // $__ABC9_ASYNC below ); \$__ABC9_FF_ abc_dff (.D($nextQ), .Q($currQ)); \$__ABC9_ASYNC abc_async (.A($currQ), .S(PRE ^ IS_PRE_INVERTED), .Y(Q)); - // Special signal indicating clock domain - // (used to partition the module so that `abc9' only performs - // sequential synthesis (reachability analysis) correctly on - // one domain at a time) + // Special signals wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, IS_C_INVERTED}; - // Special signal indicating control domain - // (which, combined with this spell type, encodes to `abc9' - // which flops may be merged together) wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, IS_D_INVERTED, PRE, IS_PRE_INVERTED}; - // Special signal indicating the current value of the flip-flop - // In order to achieve clock-enable behaviour, the current value - // of the sequential output is required which Yosys will - // connect to the special `$currQ' wire. wire _TECHMAP_REPLACE_.$currQ = $currQ; endmodule module FDPE_1 (output reg Q, input C, CE, D, PRE); @@ -241,25 +197,15 @@ module FDPE_1 (output reg Q, input C, CE, D, PRE); .D(D), .Q($nextQ), .C(C), .CE(CE), .PRE(1'b0) // ^^^ Note that async // control is disabled - // and captured by + // here but captured by // $__ABC9_ASYNC below ); \$__ABC9_FF_ abc_dff (.D($nextQ), .Q($currQ)); \$__ABC9_ASYNC abc_async (.A($currQ), .S(PRE), .Y(Q)); - // Special signal indicating clock domain - // (used to partition the module so that `abc9' only performs - // sequential synthesis (reachability analysis) correctly on - // one domain at a time) + // Special signals wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */}; - // Special signal indicating control domain - // (which, combined with this spell type, encodes to `abc9' - // which flops may be merged together) wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, 1'b0 /* IS_D_INVERTED */, PRE, 1'b0 /* IS_PRE_INVERTED */}; - // Special signal indicating the current value of the flip-flop - // In order to achieve clock-enable behaviour, the current value - // of the sequential output is required which Yosys will - // connect to the special `$currQ' wire. wire _TECHMAP_REPLACE_.$currQ = $currQ; endmodule @@ -279,19 +225,9 @@ module FDSE (output reg Q, input C, CE, D, S); ); \$__ABC9_FF_ abc_dff (.D($nextQ), .Q(Q)); - // Special signal indicating clock domain - // (used to partition the module so that `abc9' only performs - // sequential synthesis (reachability analysis) correctly on - // one domain at a time) + // Special signals wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, IS_C_INVERTED}; - // Special signal indicating control domain - // (which, combined with this spell type, encodes to `abc9' - // which flops may be merged together) wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, IS_D_INVERTED, S, IS_S_INVERTED}; - // Special signal indicating the current value of the flip-flop - // In order to achieve clock-enable behaviour, the current value - // of the sequential output is required which Yosys will - // connect to the special `$currQ' wire. wire _TECHMAP_REPLACE_.$currQ = Q; endmodule module FDSE_1 (output reg Q, input C, CE, D, S); @@ -304,19 +240,9 @@ module FDSE_1 (output reg Q, input C, CE, D, S); ); \$__ABC9_FF_ abc_dff (.D($nextQ), .Q(Q)); - // Special signal indicating clock domain - // (used to partition the module so that `abc9' only performs - // sequential synthesis (reachability analysis) correctly on - // one domain at a time) + // Special signals wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */}; - // Special signal indicating control domain - // (which, combined with this spell type, encodes to `abc9' - // which flops may be merged together) wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, 1'b0 /* IS_D_INVERTED */, S, 1'b0 /* IS_S_INVERTED */}; - // Special signal indicating the current value of the flip-flop - // In order to achieve clock-enable behaviour, the current value - // of the sequential output is required which Yosys will - // connect to the special `$currQ' wire. wire _TECHMAP_REPLACE_.$currQ = Q; endmodule -- cgit v1.2.3 From 90a954bb9c856cc6934cb0db6e37e5f80ade5b9a Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 7 Oct 2019 13:09:13 -0700 Subject: Get rid of latch_* in write_xaiger --- backends/aiger/xaiger.cc | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index b1b7af513..4f6491311 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -93,7 +93,6 @@ struct XAigerWriter dict aig_map; dict ordered_outputs; - dict ordered_latches; vector box_list; bool omode = false; @@ -950,7 +949,6 @@ struct XAigerWriter dict input_lines; dict init_lines; dict output_lines; - dict latch_lines; dict wire_lines; for (auto wire : module->wires()) @@ -1011,10 +1009,6 @@ struct XAigerWriter if (omode && output_bits.empty()) f << "output " << output_lines.size() << " 0 $__dummy__\n"; - latch_lines.sort(); - for (auto &it : latch_lines) - f << it.second; - wire_lines.sort(); for (auto &it : wire_lines) f << it.second; @@ -1036,7 +1030,7 @@ struct XAigerBackend : public Backend { log(" write ASCII version of AIGER format\n"); log("\n"); log(" -map \n"); - log(" write an extra file with port and latch symbols\n"); + log(" write an extra file with port and box symbols\n"); log("\n"); log(" -vmap \n"); log(" like -map, but more verbose\n"); -- cgit v1.2.3 From 2cb2116b4c4d94c08be1fa087dca217eb6c0f7b9 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 7 Oct 2019 15:03:44 -0700 Subject: Use "abc9_period" attribute for delay target --- passes/techmap/abc9.cc | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 2ceaacf87..34cdd3c3e 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -852,8 +852,17 @@ 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 externally\n"); + log("if you want to use ABC to convert your design into another format.\n"); + log("\n"); + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("Delay targets can also be specified on a per clock basis by attaching a\n"); + log("'(* abc9_period = *)' attribute onto clock wires (specifically, onto wires\n"); + log("that appear inside any special '$abc9_clock' wires inserted by abc9_map.v). This\n"); + log("can be achieved by modifying the source directly, or through a `setattr`\n"); + log("invocation. Since such attributes cannot yet be propagated through a\n"); + log("hierarchical design (whether or not it has been uniquified) it is recommended\n"); + log("that the design be flattened when using this feature.\n"); log("\n"); log("[1] http://www.eecs.berkeley.edu/~alanmi/abc/\n"); log("\n"); @@ -1222,10 +1231,22 @@ struct Abc9Pass : public Pass { design->selection_stack.emplace_back(false); design->selected_active_module = module->name.str(); for (auto &it : assigned_cells) { + std::string target = delay_target; + if (target.empty()) { + for (auto b : assign_map(it.first)) + if (b.wire) { + auto jt = b.wire->attributes.find("\\abc9_period"); + if (jt != b.wire->attributes.end()) { + target = stringf("-D %d", jt->second.as_int()); + log("Target period = %s ps for clock domain %s\n", target.c_str(), log_signal(it.first)); + break; + } + } + } RTLIL::Selection& sel = design->selection_stack.back(); sel.selected_members[module->name] = std::move(it.second); abc9_module(design, module, script_file, exe_file, cleanup, lut_costs, false, "$", - keepff, delay_target, lutin_shared, fast_mode, show_tempdir, + keepff, target, lutin_shared, fast_mode, show_tempdir, box_file, lut_file, wire_delay, box_lookup, nomfs); assign_map.set(module); } -- cgit v1.2.3 From b2e34f932ac37e66435d413ab7a9f0074dc0343f Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 7 Oct 2019 15:31:43 -0700 Subject: Rename $currQ to $abc9_currQ --- backends/aiger/xaiger.cc | 16 ++++---- techlibs/xilinx/abc9_map.v | 92 +++++++++++++++++++++++----------------------- 2 files changed, 54 insertions(+), 54 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 4f6491311..03246a9b5 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -479,11 +479,11 @@ struct XAigerWriter } } - // Connect .$currQ (inserted by abc9_map.v) as an input to the flop box + // Connect .$abc9_currQ (inserted by abc9_map.v) as an input to the flop box if (box_module->get_bool_attribute("\\abc9_flop")) { - SigSpec rhs = module->wire(stringf("%s.$currQ", cell->name.c_str())); + SigSpec rhs = module->wire(stringf("%s.$abc9_currQ", cell->name.c_str())); if (rhs.empty()) - log_error("'%s.$currQ' is not a wire present in module '%s'.\n", log_id(cell), log_id(module)); + log_error("'%s.$abc9_currQ' is not a wire present in module '%s'.\n", log_id(cell), log_id(module)); int offset = 0; for (auto b : rhs) { @@ -496,7 +496,7 @@ struct XAigerWriter else alias_map[b] = I; } - co_bits.emplace_back(b, cell, "\\$currQ", offset++, 0); + co_bits.emplace_back(b, cell, "\\$abc9_currQ", offset++, 0); unused_bits.erase(b); } } @@ -787,7 +787,7 @@ struct XAigerWriter } // For flops only, create an extra 1-bit input that drives a new wire - // called ".$currQ" that is used below + // called ".$abc9_currQ" that is used below if (box_module->get_bool_attribute("\\abc9_flop")) { log_assert(holes_cell); @@ -799,7 +799,7 @@ struct XAigerWriter holes_wire->port_id = port_id++; holes_module->ports.push_back(holes_wire->name); } - Wire *w = holes_module->addWire(stringf("%s.$currQ", cell->name.c_str())); + Wire *w = holes_module->addWire(stringf("%s.$abc9_currQ", cell->name.c_str())); holes_module->connect(w, holes_wire); } @@ -884,9 +884,9 @@ struct XAigerWriter 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 ".$currQ" + // used to implement clock-enable functionality) with the ".$abc9_currQ" // wire (which itself is driven an input port) we inserted above - Wire *currQ = holes_module->wire(stringf("%s.$currQ", driver.c_str())); + Wire *currQ = holes_module->wire(stringf("%s.$abc9_currQ", driver.c_str())); log_assert(currQ); holes_module->connect(Q, currQ); continue; diff --git a/techlibs/xilinx/abc9_map.v b/techlibs/xilinx/abc9_map.v index feaf979ad..ee319a8e3 100644 --- a/techlibs/xilinx/abc9_map.v +++ b/techlibs/xilinx/abc9_map.v @@ -35,34 +35,34 @@ // 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 -// || +--< > +------+ | || -// || | \/\/\/\/ | || -// || | | || -// || +----------------------------+ || -// || || -// ++===================================++ +// ++===================================++ +// || Sim model || +// || /\/\/\/\ || +// D -->>-----< > +------+ || +// R -->>-----< Comb. > |$_DFF_| || +// CE -->>-----< logic >-----| [NP]_|---+---->>-- Q +// || +--< > +------+ | || +// || | \/\/\/\/ | || +// || | | || +// || +----------------------------+ || +// || || +// ++===================================++ // // is transformed into: // -// ++==================++ -// || Comb box || -// || || -// || /\/\/\/\ || -// D -->>-----< > || +------+ -// R -->>-----< Comb. > || |$_ABC_| -// CE -->>-----< logic >--->>-- $nextQ --| FF_ |--+-->> Q -// $currQ +-->>-----< > || +------+ | -// | || \/\/\/\/ || | -// | || || | -// | ++==================++ | -// | | -// +----------------------------------------------+ +// ++==================++ +// || Comb box || +// || || +// || /\/\/\/\ || +// D -->>-----< > || +------+ +// R -->>-----< Comb. > || |$_ABC_| +// CE -->>-----< logic >--->>-- $nextQ --| FF_ |--+-->> Q +// $abc9_currQ +-->>-----< > || +------+ | +// | || \/\/\/\/ || | +// | || || | +// | ++==================++ | +// | | +// +----------------------------------------------+ // // 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 @@ -74,7 +74,7 @@ // (c) a special _TECHMAP_REPLACE_.$abc9_control that captures the control // domain (which, combined with this cell type, encodes to `abc9' which // flops may be merged together) -// (d) a special _TECHMAP_REPLACE_.$currQ wire that will be used for feedback +// (d) a special _TECHMAP_REPLACE_.$abc9_currQ wire that will be used for feedback // into the (combinatorial) FD* cell to facilitate clock-enable behaviour module FDRE (output reg Q, input C, CE, D, R); parameter [0:0] INIT = 1'b0; @@ -95,7 +95,7 @@ module FDRE (output reg Q, input C, CE, D, R); // Special signals wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, IS_C_INVERTED}; wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, IS_D_INVERTED, R, IS_R_INVERTED}; - wire _TECHMAP_REPLACE_.$currQ = Q; + wire _TECHMAP_REPLACE_.$abc9_currQ = Q; endmodule module FDRE_1 (output reg Q, input C, CE, D, R); parameter [0:0] INIT = 1'b0; @@ -110,7 +110,7 @@ module FDRE_1 (output reg Q, input C, CE, D, R); // Special signals wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */}; wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, 1'b0 /* IS_D_INVERTED */, R, 1'b0 /* IS_R_INVERTED */}; - wire _TECHMAP_REPLACE_.$currQ = Q; + wire _TECHMAP_REPLACE_.$abc9_currQ = Q; endmodule module FDCE (output reg Q, input C, CE, D, CLR); @@ -118,7 +118,7 @@ module FDCE (output reg Q, input C, CE, D, CLR); parameter [0:0] IS_C_INVERTED = 1'b0; parameter [0:0] IS_D_INVERTED = 1'b0; parameter [0:0] IS_CLR_INVERTED = 1'b0; - wire $nextQ, $currQ; + wire $nextQ, $abc9_currQ; FDCE #( .INIT(INIT), .IS_C_INVERTED(IS_C_INVERTED), @@ -131,19 +131,19 @@ module FDCE (output reg Q, input C, CE, D, CLR); // here but captured by // $__ABC9_ASYNC below ); - \$__ABC9_FF_ abc_dff (.D($nextQ), .Q($currQ)); + \$__ABC9_FF_ abc_dff (.D($nextQ), .Q($abc9_currQ)); // Since this is an async flop, async behaviour is also dealt with // using the $_ABC9_ASYNC box by abc9_map.v - \$__ABC9_ASYNC abc_async (.A($currQ), .S(CLR ^ IS_CLR_INVERTED), .Y(Q)); + \$__ABC9_ASYNC abc_async (.A($abc9_currQ), .S(CLR ^ IS_CLR_INVERTED), .Y(Q)); // Special signals wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, IS_C_INVERTED}; wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, IS_D_INVERTED, CLR, IS_CLR_INVERTED}; - wire _TECHMAP_REPLACE_.$currQ = $currQ; + wire _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ; endmodule module FDCE_1 (output reg Q, input C, CE, D, CLR); parameter [0:0] INIT = 1'b0; - wire $nextQ, $currQ; + wire $nextQ, $abc9_currQ; FDCE_1 #( .INIT(INIT) ) _TECHMAP_REPLACE_ ( @@ -153,13 +153,13 @@ module FDCE_1 (output reg Q, input C, CE, D, CLR); // here but captured by // $__ABC9_ASYNC below ); - \$__ABC9_FF_ abc_dff (.D($nextQ), .Q($currQ)); - \$__ABC9_ASYNC abc_async (.A($currQ), .S(CLR), .Y(Q)); + \$__ABC9_FF_ abc_dff (.D($nextQ), .Q($abc9_currQ)); + \$__ABC9_ASYNC abc_async (.A($abc9_currQ), .S(CLR), .Y(Q)); // Special signals wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */}; wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, 1'b0 /* IS_D_INVERTED */, CLR, 1'b0 /* IS_CLR_INVERTED */}; - wire _TECHMAP_REPLACE_.$currQ = $currQ; + wire _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ; endmodule module FDPE (output reg Q, input C, CE, D, PRE); @@ -167,7 +167,7 @@ module FDPE (output reg Q, input C, CE, D, PRE); parameter [0:0] IS_C_INVERTED = 1'b0; parameter [0:0] IS_D_INVERTED = 1'b0; parameter [0:0] IS_PRE_INVERTED = 1'b0; - wire $nextQ, $currQ; + wire $nextQ, $abc9_currQ; FDPE #( .INIT(INIT), .IS_C_INVERTED(IS_C_INVERTED), @@ -180,17 +180,17 @@ module FDPE (output reg Q, input C, CE, D, PRE); // here but captured by // $__ABC9_ASYNC below ); - \$__ABC9_FF_ abc_dff (.D($nextQ), .Q($currQ)); - \$__ABC9_ASYNC abc_async (.A($currQ), .S(PRE ^ IS_PRE_INVERTED), .Y(Q)); + \$__ABC9_FF_ abc_dff (.D($nextQ), .Q($abc9_currQ)); + \$__ABC9_ASYNC abc_async (.A($abc9_currQ), .S(PRE ^ IS_PRE_INVERTED), .Y(Q)); // Special signals wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, IS_C_INVERTED}; wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, IS_D_INVERTED, PRE, IS_PRE_INVERTED}; - wire _TECHMAP_REPLACE_.$currQ = $currQ; + wire _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ; endmodule module FDPE_1 (output reg Q, input C, CE, D, PRE); parameter [0:0] INIT = 1'b0; - wire $nextQ, $currQ; + wire $nextQ, $abc9_currQ; FDPE_1 #( .INIT(INIT) ) _TECHMAP_REPLACE_ ( @@ -200,13 +200,13 @@ module FDPE_1 (output reg Q, input C, CE, D, PRE); // here but captured by // $__ABC9_ASYNC below ); - \$__ABC9_FF_ abc_dff (.D($nextQ), .Q($currQ)); - \$__ABC9_ASYNC abc_async (.A($currQ), .S(PRE), .Y(Q)); + \$__ABC9_FF_ abc_dff (.D($nextQ), .Q($abc9_currQ)); + \$__ABC9_ASYNC abc_async (.A($abc9_currQ), .S(PRE), .Y(Q)); // Special signals wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */}; wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, 1'b0 /* IS_D_INVERTED */, PRE, 1'b0 /* IS_PRE_INVERTED */}; - wire _TECHMAP_REPLACE_.$currQ = $currQ; + wire _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ; endmodule module FDSE (output reg Q, input C, CE, D, S); @@ -228,7 +228,7 @@ module FDSE (output reg Q, input C, CE, D, S); // Special signals wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, IS_C_INVERTED}; wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, IS_D_INVERTED, S, IS_S_INVERTED}; - wire _TECHMAP_REPLACE_.$currQ = Q; + wire _TECHMAP_REPLACE_.$abc9_currQ = Q; endmodule module FDSE_1 (output reg Q, input C, CE, D, S); parameter [0:0] INIT = 1'b0; @@ -243,7 +243,7 @@ module FDSE_1 (output reg Q, input C, CE, D, S); // Special signals wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */}; wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, 1'b0 /* IS_D_INVERTED */, S, 1'b0 /* IS_S_INVERTED */}; - wire _TECHMAP_REPLACE_.$currQ = Q; + wire _TECHMAP_REPLACE_.$abc9_currQ = Q; endmodule module RAM32X1D ( -- cgit v1.2.3 From 4f0818275fe44c451be59235616061be8ff5e382 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 7 Oct 2019 15:58:55 -0700 Subject: Cleanup --- techlibs/xilinx/abc9_map.v | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/techlibs/xilinx/abc9_map.v b/techlibs/xilinx/abc9_map.v index ee319a8e3..95546db37 100644 --- a/techlibs/xilinx/abc9_map.v +++ b/techlibs/xilinx/abc9_map.v @@ -25,11 +25,6 @@ // 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. - -// ============================================================================ - -// `abc9' requires that complex flops be split into a combinatorial box -// feeding a simple flop ($_ABC9_FF_). // 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. @@ -55,8 +50,8 @@ // || || // || /\/\/\/\ || // D -->>-----< > || +------+ -// R -->>-----< Comb. > || |$_ABC_| -// CE -->>-----< logic >--->>-- $nextQ --| FF_ |--+-->> Q +// R -->>-----< Comb. > || |$__ABC| +// CE -->>-----< logic >--->>-- $nextQ --| _FF_ |--+-->> Q // $abc9_currQ +-->>-----< > || +------+ | // | || \/\/\/\/ || | // | || || | -- cgit v1.2.3 From 344619079d42e541fee8dc370318d9927cd6fb95 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 19 Nov 2019 16:57:07 -0800 Subject: Do not drop async control signals in abc_map.v --- techlibs/xilinx/abc9_map.v | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/techlibs/xilinx/abc9_map.v b/techlibs/xilinx/abc9_map.v index 95546db37..fc224e832 100644 --- a/techlibs/xilinx/abc9_map.v +++ b/techlibs/xilinx/abc9_map.v @@ -120,10 +120,11 @@ module FDCE (output reg Q, input C, CE, D, CLR); .IS_D_INVERTED(IS_D_INVERTED), .IS_CLR_INVERTED(IS_CLR_INVERTED) ) _TECHMAP_REPLACE_ ( - .D(D), .Q($nextQ), .C(C), .CE(CE), .CLR(IS_CLR_INVERTED) + .D(D), .Q($nextQ), .C(C), .CE(CE), .CLR(CLR) // ^^^ Note that async - // control is disabled - // here but captured by + // control is not directly + // supported by abc9 but its + // behaviour is captured by // $__ABC9_ASYNC below ); \$__ABC9_FF_ abc_dff (.D($nextQ), .Q($abc9_currQ)); @@ -142,10 +143,11 @@ module FDCE_1 (output reg Q, input C, CE, D, CLR); FDCE_1 #( .INIT(INIT) ) _TECHMAP_REPLACE_ ( - .D(D), .Q($nextQ), .C(C), .CE(CE), .CLR(1'b0) + .D(D), .Q($nextQ), .C(C), .CE(CE), .CLR(CLR) // ^^^ Note that async - // control is disabled - // here but captured by + // control is not directly + // supported by abc9 but its + // behaviour is captured by // $__ABC9_ASYNC below ); \$__ABC9_FF_ abc_dff (.D($nextQ), .Q($abc9_currQ)); @@ -169,10 +171,11 @@ module FDPE (output reg Q, input C, CE, D, PRE); .IS_D_INVERTED(IS_D_INVERTED), .IS_PRE_INVERTED(IS_PRE_INVERTED), ) _TECHMAP_REPLACE_ ( - .D(D), .Q($nextQ), .C(C), .CE(CE), .PRE(IS_PRE_INVERTED) + .D(D), .Q($nextQ), .C(C), .CE(CE), .PRE(PRE) // ^^^ Note that async - // control is disabled - // here but captured by + // control is not directly + // supported by abc9 but its + // behaviour is captured by // $__ABC9_ASYNC below ); \$__ABC9_FF_ abc_dff (.D($nextQ), .Q($abc9_currQ)); @@ -189,10 +192,11 @@ module FDPE_1 (output reg Q, input C, CE, D, PRE); FDPE_1 #( .INIT(INIT) ) _TECHMAP_REPLACE_ ( - .D(D), .Q($nextQ), .C(C), .CE(CE), .PRE(1'b0) + .D(D), .Q($nextQ), .C(C), .CE(CE), .PRE(PRE) // ^^^ Note that async - // control is disabled - // here but captured by + // control is not directly + // supported by abc9 but its + // behaviour is captured by // $__ABC9_ASYNC below ); \$__ABC9_FF_ abc_dff (.D($nextQ), .Q($abc9_currQ)); -- cgit v1.2.3 From 929beda19c24e8e6cb6e87b0ceaa97ad2829abbe Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 19 Nov 2019 16:57:26 -0800 Subject: abc9 to support async flops $_DFF_[NP][NP][01]_ --- backends/aiger/xaiger.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 03246a9b5..5d125b653 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -863,7 +863,8 @@ struct XAigerWriter dict replace; for (auto it = holes_module->cells_.begin(); it != holes_module->cells_.end(); ) { auto cell = it->second; - if (cell->type.in("$_DFF_N_", "$_DFF_P_")) { + 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 -- cgit v1.2.3 From 90c5ca330c5e6c8eb45ad0b755b0049a34dc7534 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 19 Nov 2019 16:57:58 -0800 Subject: Add two tests --- tests/simple_abc9/abc9.v | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/simple_abc9/abc9.v b/tests/simple_abc9/abc9.v index 64b625efe..58596d701 100644 --- a/tests/simple_abc9/abc9.v +++ b/tests/simple_abc9/abc9.v @@ -267,3 +267,15 @@ module abc9_test026(output [3:0] o, p); assign o = { 1'b1, 1'bx }; assign p = { 1'b1, 1'bx, 1'b0 }; endmodule + +module abc9_test029(input clk, d, r, output reg q); +always @(posedge clk or posedge r) + if (r) q <= 1'b0; + else q <= d; +endmodule + +module abc9_test030(input clk, d, r, output reg q); +always @(negedge clk or posedge r) + if (r) q <= 1'b1; + else q <= d; +endmodule -- cgit v1.2.3 From 1cc106452fb25d082ca9491c24df97cc51d4b992 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 19 Nov 2019 17:05:14 -0800 Subject: Add a equiv test too --- tests/various/abc9.v | 7 +++++++ tests/various/abc9.ys | 16 ++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/tests/various/abc9.v b/tests/various/abc9.v index 30ebd4e26..e53dcdb21 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_test031(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..9e732bdc8 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_test031 +proc +async2sync +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 -- cgit v1.2.3 From df63d75ff35e1441360a4b28a12b32b3d00f1190 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 20 Nov 2019 11:26:59 -0800 Subject: Fix INIT values --- techlibs/xilinx/abc9_map.v | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/techlibs/xilinx/abc9_map.v b/techlibs/xilinx/abc9_map.v index 95546db37..d2c0abeb6 100644 --- a/techlibs/xilinx/abc9_map.v +++ b/techlibs/xilinx/abc9_map.v @@ -96,7 +96,7 @@ module FDRE_1 (output reg Q, input C, CE, D, R); parameter [0:0] INIT = 1'b0; wire $nextQ; FDRE_1 #( - .INIT(|0), + .INIT(INIT), ) _TECHMAP_REPLACE_ ( .D(D), .Q($nextQ), .C(C), .CE(CE), .R(R) ); @@ -205,7 +205,7 @@ module FDPE_1 (output reg Q, input C, CE, D, PRE); endmodule module FDSE (output reg Q, input C, CE, D, S); - parameter [0:0] INIT = 1'b0; + 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; @@ -226,10 +226,10 @@ module FDSE (output reg Q, input C, CE, D, S); wire _TECHMAP_REPLACE_.$abc9_currQ = Q; endmodule module FDSE_1 (output reg Q, input C, CE, D, S); - parameter [0:0] INIT = 1'b0; + parameter [0:0] INIT = 1'b1; wire $nextQ; FDSE_1 #( - .INIT(|0), + .INIT(INIT), ) _TECHMAP_REPLACE_ ( .D(D), .Q($nextQ), .C(C), .CE(CE), .S(S) ); -- cgit v1.2.3 From cd9e830b67fdffcae88dba095548995a30988fa4 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 20 Nov 2019 13:28:55 -0800 Subject: Add multi clock test --- tests/simple_abc9/abc9.v | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/simple_abc9/abc9.v b/tests/simple_abc9/abc9.v index 64b625efe..1844bac20 100644 --- a/tests/simple_abc9/abc9.v +++ b/tests/simple_abc9/abc9.v @@ -267,3 +267,8 @@ module abc9_test026(output [3:0] o, p); assign o = { 1'b1, 1'bx }; assign p = { 1'b1, 1'bx, 1'b0 }; endmodule + +module abc9_test029(input clk1, clk2, input d, output reg q1, q2); +always @(posedge clk1) q1 <= d; +always @(negedge clk2) q2 <= q1; +endmodule -- cgit v1.2.3 From af3055fe8354e0a082bd8415448fcbeb5ee435f6 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 20 Nov 2019 14:30:56 -0800 Subject: Add blackbox model for $__ABC9_FF_ so that clock partitioning works --- techlibs/xilinx/abc9_model.v | 3 +++ 1 file changed, 3 insertions(+) diff --git a/techlibs/xilinx/abc9_model.v b/techlibs/xilinx/abc9_model.v index c17d6744a..cc0e5ec41 100644 --- a/techlibs/xilinx/abc9_model.v +++ b/techlibs/xilinx/abc9_model.v @@ -30,6 +30,9 @@ module \$__XILINX_MUXF78 (output O, input I0, I1, I2, I3, S0, S1); : (S0 ? I1 : I0); endmodule +module \$__ABC9_FF_ (input D, output Q); +endmodule + (* abc_box_id = 1000 *) module \$__ABC9_ASYNC (input A, S, output Y); endmodule -- cgit v1.2.3 From 729c6b93e8eb863aa9436239efea5f5678673b4f Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 20 Nov 2019 14:32:01 -0800 Subject: endomain -> ctrldomain --- passes/techmap/abc9.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 34cdd3c3e..8d4ff4025 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -1108,8 +1108,8 @@ struct Abc9Pass : public Pass { std::map> cell_to_bit, cell_to_bit_up, cell_to_bit_down; std::map> bit_to_cell, bit_to_cell_up, bit_to_cell_down; - typedef std::pair endomain_t; - std::map mergeability_class; + typedef std::pair ctrldomain_t; + std::map mergeability_class; for (auto cell : all_cells) { for (auto &conn : cell->connections()) @@ -1149,7 +1149,7 @@ struct Abc9Pass : public Pass { assigned_cells[abc9_clock].insert(cell->name); assigned_cells_reverse[cell] = abc9_clock; - endomain_t key(cell->type, abc9_control); + ctrldomain_t key(cell->type, abc9_control); auto r = mergeability_class.emplace(key, mergeability_class.size() + 1); auto YS_ATTRIBUTE(unused) r2 = cell->attributes.insert(std::make_pair(ID(abc9_mergeability), r.first->second)); log_assert(r2.second); -- cgit v1.2.3 From a5767474830756319ce0fff53b81573701ec0cd2 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 20 Nov 2019 15:40:46 -0800 Subject: Consistent log message, ignore 's' extension --- frontends/aiger/aigerparse.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc index 4b66af3ad..9374f1ab3 100644 --- a/frontends/aiger/aigerparse.cc +++ b/frontends/aiger/aigerparse.cc @@ -432,7 +432,7 @@ void AigerReader::parse_xaiger(const dict &box_lookup) 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_debug("flopNum = %u\n", flopNum); log_assert(dataSize == (flopNum+1) * sizeof(uint32_t)); f.ignore(flopNum * sizeof(uint32_t)); } @@ -464,9 +464,10 @@ void AigerReader::parse_xaiger(const dict &box_lookup) boxes.emplace_back(cell); } } - else if (c == 'a' || c == 'i' || c == 'o') { + 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; -- cgit v1.2.3 From 911a152b39959137b26e68581a6cacbcabb4ab1d Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 21 Nov 2019 16:13:28 -0800 Subject: Add test --- tests/simple_abc9/abc9.v | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/simple_abc9/abc9.v b/tests/simple_abc9/abc9.v index 1844bac20..13c505eec 100644 --- a/tests/simple_abc9/abc9.v +++ b/tests/simple_abc9/abc9.v @@ -268,7 +268,12 @@ assign o = { 1'b1, 1'bx }; assign p = { 1'b1, 1'bx, 1'b0 }; endmodule -module abc9_test029(input clk1, clk2, input d, output reg q1, q2); +module abc9_test029(input clk1, clk2, d, output reg q1, q2); always @(posedge clk1) q1 <= d; always @(negedge clk2) q2 <= q1; endmodule + +module abc9_test030(input clk, d, output reg q1, q2); +always @(posedge clk) q1 <= d; +always @(posedge clk) q2 <= q1; +endmodule -- cgit v1.2.3 From c4ec42ac38bd5678d9f3018d3921a3f0f4239986 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 21 Nov 2019 16:17:03 -0800 Subject: When expanding upwards, do not capture $__ABC9_{FF,ASYNC}_ Since they should be captured downwards from the owning flop --- passes/techmap/abc9.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 8d4ff4025..4b6ec6e11 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -1165,7 +1165,7 @@ struct Abc9Pass : public Pass { for (auto bit : cell_to_bit_up[cell]) for (auto c : bit_to_cell_up[bit]) - if (unassigned_cells.count(c)) { + if (unassigned_cells.count(c) && !c->type.in("$__ABC9_FF_", "$__ABC9_ASYNC_")) { unassigned_cells.erase(c); next_expand_queue_up.insert(c); assigned_cells[key].insert(c->name); -- cgit v1.2.3 From 0ab1e496dc601f8e9d5efbcc5b2be7cf6b2d9673 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 21 Nov 2019 16:19:28 -0800 Subject: write_xaiger to not use module POs but only write outputs if driven --- backends/aiger/xaiger.cc | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 5d125b653..c69b0fa85 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -542,18 +542,30 @@ struct XAigerWriter } for (auto bit : unused_bits) - undriven_bits.erase(bit); - - if (!undriven_bits.empty() && !holes_mode) { - bool whole_module = module->design->selected_whole_module(module->name); - undriven_bits.sort(); - for (auto bit : undriven_bits) { - if (whole_module) - log_warning("Treating undriven bit %s.%s like $anyseq.\n", log_id(module), log_signal(bit)); - input_bits.insert(bit); + if (holes_mode) + undriven_bits.erase(bit); + else if (!undriven_bits.count(bit)) + output_bits.insert(bit); + + if (!holes_mode) { + for (auto port : module->ports) { + auto wire = module->wire(port); + if (!wire->port_output) + continue; + for (int i = 0; i < GetSize(wire); i++) { + SigBit wirebit(wire, i); + SigBit bit = sigmap(wirebit); + if (bit == State::Sx) + continue; + if (!undriven_bits.count(bit)) { + output_bits.insert(wirebit); + } + } } - if (whole_module) - log_warning("Treating a total of %d undriven bits in %s like $anyseq.\n", GetSize(undriven_bits), log_id(module)); + + if (!undriven_bits.empty()) + for (auto bit : undriven_bits) + input_bits.insert(bit); } if (holes_mode) { -- cgit v1.2.3 From 39fdcb892b1b65363fdf7c1bc6d9e2612c1c38e6 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 21 Nov 2019 16:27:34 -0800 Subject: async2sync -> clk2fflogic --- tests/various/abc9.ys | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/various/abc9.ys b/tests/various/abc9.ys index 9e732bdc8..f7a3f1fa0 100644 --- a/tests/various/abc9.ys +++ b/tests/various/abc9.ys @@ -26,7 +26,7 @@ select -assert-none t:$lut t:unknown %% t: %D design -load read hierarchy -top abc9_test031 proc -async2sync +clk2fflogic design -save gold abc9 -lut 4 -- cgit v1.2.3 From 6841e3b1c2b2bc3124810f3a8f96ed00a96e954c Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 21 Nov 2019 16:33:20 -0800 Subject: Another sloppy mistake! --- tests/various/abc9.v | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/various/abc9.v b/tests/various/abc9.v index 85828bf30..f0b3f6837 100644 --- a/tests/various/abc9.v +++ b/tests/various/abc9.v @@ -13,6 +13,6 @@ 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; + if (!r) q <= 1'b0; else q <= d; endmodule -- cgit v1.2.3 From c761fa49b73e9ad3680b05e89442adb6fb22b543 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 22 Nov 2019 12:37:57 -0800 Subject: Missing endmodule --- tests/simple_abc9/abc9.v | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/simple_abc9/abc9.v b/tests/simple_abc9/abc9.v index 596a52501..6bdd3bc32 100644 --- a/tests/simple_abc9/abc9.v +++ b/tests/simple_abc9/abc9.v @@ -288,3 +288,4 @@ endmodule module abc9_test033(input clk, d, output reg q1, q2); always @(posedge clk) q1 <= d; always @(posedge clk) q2 <= q1; +endmodule -- cgit v1.2.3 From 8ef241c6f4a976dca67760c43e820d4e812f2fc2 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 22 Nov 2019 13:24:28 -0800 Subject: Revert "write_xaiger to not use module POs but only write outputs if driven" This reverts commit 0ab1e496dc601f8e9d5efbcc5b2be7cf6b2d9673. --- backends/aiger/xaiger.cc | 34 +++++++++++----------------------- 1 file changed, 11 insertions(+), 23 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index c69b0fa85..5d125b653 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -542,30 +542,18 @@ struct XAigerWriter } for (auto bit : unused_bits) - if (holes_mode) - undriven_bits.erase(bit); - else if (!undriven_bits.count(bit)) - output_bits.insert(bit); - - if (!holes_mode) { - for (auto port : module->ports) { - auto wire = module->wire(port); - if (!wire->port_output) - continue; - for (int i = 0; i < GetSize(wire); i++) { - SigBit wirebit(wire, i); - SigBit bit = sigmap(wirebit); - if (bit == State::Sx) - continue; - if (!undriven_bits.count(bit)) { - output_bits.insert(wirebit); - } - } + undriven_bits.erase(bit); + + if (!undriven_bits.empty() && !holes_mode) { + bool whole_module = module->design->selected_whole_module(module->name); + undriven_bits.sort(); + for (auto bit : undriven_bits) { + if (whole_module) + log_warning("Treating undriven bit %s.%s like $anyseq.\n", log_id(module), log_signal(bit)); + input_bits.insert(bit); } - - if (!undriven_bits.empty()) - for (auto bit : undriven_bits) - input_bits.insert(bit); + if (whole_module) + log_warning("Treating a total of %d undriven bits in %s like $anyseq.\n", GetSize(undriven_bits), log_id(module)); } if (holes_mode) { -- cgit v1.2.3 From 856a3dc98dcebdfdd331a5394a4556c00b4fcb8c Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 22 Nov 2019 15:33:51 -0800 Subject: New 'clkpart' to {,un}partition design according to clock/enable --- passes/techmap/clkpart.cc | 268 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 268 insertions(+) create mode 100644 passes/techmap/clkpart.cc diff --git a/passes/techmap/clkpart.cc b/passes/techmap/clkpart.cc new file mode 100644 index 000000000..4fa729250 --- /dev/null +++ b/passes/techmap/clkpart.cc @@ -0,0 +1,268 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 Clifford Wolf + * 2019 Eddie Hung + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#include "kernel/register.h" +#include "kernel/sigtools.h" +#include "kernel/celltypes.h" +#include "kernel/rtlil.h" +#include "kernel/log.h" + +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + +struct ClkPartPass : public Pass { + ClkPartPass() : Pass("clkpart", "partition design according to clock domain") { } + void help() YS_OVERRIDE + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" clkpart [options] [selection]\n"); + log("\n"); + log("Partition the contents of selected modules according to the clock (and optionally\n"); + log("the enable) domains of its $_DFF* cells by extracting them into sub-modules,\n"); + log("using the `submod` command.\n"); + log("Sub-modules created by this command are marked with a 'clkpart' attribute.\n"); + log("\n"); + log(" -unpart\n"); + log(" undo this operation within the selected modules, by flattening those with\n"); + log(" a 'clkpart' attribute into those modules without this attribute.\n"); + log("\n"); + log(" -enable\n"); + log(" also consider enable domains.\n"); + log("\n"); + } + + bool unpart_mode, enable_mode; + + void clear_flags() YS_OVERRIDE + { + unpart_mode = false; + enable_mode = false; + } + void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE + { + log_header(design, "Executing CLKPART pass (TODO).\n"); + log_push(); + + clear_flags(); + + size_t argidx; + for (argidx = 1; argidx < args.size(); argidx++) + { + if (args[argidx] == "-unpart") { + unpart_mode = true; + continue; + } + if (args[argidx] == "-enable") { + enable_mode = true; + continue; + } + break; + } + extra_args(args, argidx, design); + + if (unpart_mode) + unpart(design); + else + part(design); + + log_pop(); + } + + void part(RTLIL::Design *design) + { + CellTypes ct(design); + SigMap assign_map; + + for (auto mod : design->selected_modules()) + { + if (mod->processes.size() > 0) { + log("Skipping module %s as it contains processes.\n", log_id(mod)); + continue; + } + + assign_map.set(mod); + + std::vector all_cells = mod->selected_cells(); + std::set unassigned_cells(all_cells.begin(), all_cells.end()); + + std::set expand_queue, next_expand_queue; + std::set expand_queue_up, next_expand_queue_up; + std::set expand_queue_down, next_expand_queue_down; + + typedef tuple clkdomain_t; + std::map> assigned_cells; + std::map assigned_cells_reverse; + + std::map> cell_to_bit, cell_to_bit_up, cell_to_bit_down; + std::map> bit_to_cell, bit_to_cell_up, bit_to_cell_down; + + for (auto cell : all_cells) + { + clkdomain_t key; + + for (auto &conn : cell->connections()) + for (auto bit : conn.second) { + bit = assign_map(bit); + if (bit.wire != nullptr) { + cell_to_bit[cell].insert(bit); + bit_to_cell[bit].insert(cell); + if (ct.cell_input(cell->type, conn.first)) { + cell_to_bit_up[cell].insert(bit); + bit_to_cell_down[bit].insert(cell); + } + if (ct.cell_output(cell->type, conn.first)) { + cell_to_bit_down[cell].insert(bit); + bit_to_cell_up[bit].insert(cell); + } + } + } + + if (cell->type.in(ID($_DFF_N_), ID($_DFF_P_))) + { + key = clkdomain_t(cell->type == ID($_DFF_P_), assign_map(cell->getPort(ID(C))), true, RTLIL::SigSpec()); + } + else + if (cell->type.in(ID($_DFFE_NN_), ID($_DFFE_NP_), ID($_DFFE_PN_), ID($_DFFE_PP_))) + { + bool this_clk_pol = cell->type.in(ID($_DFFE_PN_), ID($_DFFE_PP_)); + bool this_en_pol = !enable_mode || cell->type.in(ID($_DFFE_NP_), ID($_DFFE_PP_)); + key = clkdomain_t(this_clk_pol, assign_map(cell->getPort(ID(C))), this_en_pol, enable_mode ? assign_map(cell->getPort(ID(E)) : RTLIL::SigSpec())); + } + 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->name); + assigned_cells_reverse[cell] = key; + } + + while (!expand_queue_up.empty() || !expand_queue_down.empty()) + { + if (!expand_queue_up.empty()) + { + RTLIL::Cell *cell = *expand_queue_up.begin(); + clkdomain_t key = assigned_cells_reverse.at(cell); + expand_queue_up.erase(cell); + + for (auto bit : cell_to_bit_up[cell]) + for (auto c : bit_to_cell_up[bit]) + if (unassigned_cells.count(c)) { + unassigned_cells.erase(c); + next_expand_queue_up.insert(c); + assigned_cells[key].push_back(c->name); + 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->name); + 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->name); + 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->name); + 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) { + RTLIL::Selection sel(false); + sel.selected_members[mod->name] = pool(it.second.begin(), it.second.end()); + + RTLIL::IdString submod = stringf("%s.%s", mod->name.c_str(), NEW_ID.c_str()); + Pass::call_on_selection(design, sel, stringf("submod -name %s", submod.c_str())); + + design->module(submod)->set_bool_attribute(ID(clkpart)); + } + } + } + + void unpart(RTLIL::Design *design) + { + vector keeped; + for (auto mod : design->selected_modules()) { + if (mod->get_bool_attribute(ID(clkpart))) + continue; + if (mod->get_bool_attribute(ID(keep_hierarchy))) + continue; + keeped.push_back(mod); + mod->set_bool_attribute(ID(keep_hierarchy)); + } + + Pass::call(design, "flatten"); + + for (auto mod : keeped) + mod->set_bool_attribute(ID(keep_hierarchy), false); + + } +} ClkPartPass; + +PRIVATE_NAMESPACE_END -- cgit v1.2.3 From 450ad0e9ba031fbeef904746ca773e3b0e21af8f Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 22 Nov 2019 15:35:08 -0800 Subject: Add to CHANGELOG --- CHANGELOG | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG b/CHANGELOG index a49c27b05..d9d261fbc 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -53,6 +53,7 @@ Yosys 0.9 .. Yosys 0.9-dev - Added "check -mapped" - Added checking of SystemVerilog always block types (always_comb, always_latch and always_ff) + - Added "clkpart" pass Yosys 0.8 .. Yosys 0.9 ---------------------- -- cgit v1.2.3 From 3df191cec5d64c743f8fbb0294d9492c5598bc1b Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 22 Nov 2019 15:41:23 -0800 Subject: Entry in Makefile.inc --- passes/techmap/Makefile.inc | 1 + 1 file changed, 1 insertion(+) diff --git a/passes/techmap/Makefile.inc b/passes/techmap/Makefile.inc index cd357d72a..13992315e 100644 --- a/passes/techmap/Makefile.inc +++ b/passes/techmap/Makefile.inc @@ -41,6 +41,7 @@ OBJS += passes/techmap/zinit.o OBJS += passes/techmap/dff2dffs.o OBJS += passes/techmap/flowmap.o OBJS += passes/techmap/extractinv.o +OBJS += passes/techmap/clkpart.o endif GENFILES += passes/techmap/techmap.inc -- cgit v1.2.3 From 84153288bb7d92c31c1d8873b1257a296ca664ad Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 22 Nov 2019 15:41:34 -0800 Subject: Brackets --- passes/techmap/clkpart.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/techmap/clkpart.cc b/passes/techmap/clkpart.cc index 4fa729250..bf3b5bd30 100644 --- a/passes/techmap/clkpart.cc +++ b/passes/techmap/clkpart.cc @@ -144,7 +144,7 @@ struct ClkPartPass : public Pass { { bool this_clk_pol = cell->type.in(ID($_DFFE_PN_), ID($_DFFE_PP_)); bool this_en_pol = !enable_mode || cell->type.in(ID($_DFFE_NP_), ID($_DFFE_PP_)); - key = clkdomain_t(this_clk_pol, assign_map(cell->getPort(ID(C))), this_en_pol, enable_mode ? assign_map(cell->getPort(ID(E)) : RTLIL::SigSpec())); + key = clkdomain_t(this_clk_pol, assign_map(cell->getPort(ID(C))), this_en_pol, enable_mode ? assign_map(cell->getPort(ID(E))) : RTLIL::SigSpec()); } else continue; -- cgit v1.2.3 From 2ef2e2c040d9ff299f1bc6daca891a1236ed877e Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 22 Nov 2019 16:41:05 -0800 Subject: Add testcase --- tests/various/submod.ys | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 tests/various/submod.ys diff --git a/tests/various/submod.ys b/tests/various/submod.ys new file mode 100644 index 000000000..54455b580 --- /dev/null +++ b/tests/various/submod.ys @@ -0,0 +1,26 @@ +read_verilog < Date: Fri, 22 Nov 2019 16:46:26 -0800 Subject: sigmap(wire) should inherit port_output status of POs --- passes/hierarchy/submod.cc | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/passes/hierarchy/submod.cc b/passes/hierarchy/submod.cc index ec242aa1f..982558fb2 100644 --- a/passes/hierarchy/submod.cc +++ b/passes/hierarchy/submod.cc @@ -20,6 +20,7 @@ #include "kernel/register.h" #include "kernel/celltypes.h" #include "kernel/log.h" +#include "kernel/sigtools.h" #include #include #include @@ -32,6 +33,7 @@ struct SubmodWorker CellTypes ct; RTLIL::Design *design; RTLIL::Module *module; + pool outputs; bool copy_mode; std::string opt_name; @@ -125,7 +127,7 @@ struct SubmodWorker if (wire->port_input) flags.is_ext_driven = true; - if (wire->port_output) + if (wire->port_output || outputs.count(wire)) flags.is_ext_used = true; bool new_wire_port_input = false; @@ -219,6 +221,22 @@ struct SubmodWorker ct.setup_stdcells_mem(); ct.setup_design(design); + SigMap sigmap(module); + for (auto port : module->ports) { + auto wire = module->wire(port); + if (!wire->port_output) + continue; + auto sig = sigmap(wire); + for (auto c : sig.chunks()) { + if (!c.wire) + continue; + if (c.wire == wire) + continue; + outputs.insert(c.wire); + log_dump(c.wire->name); + } + } + if (opt_name.empty()) { for (auto &it : module->wires_) -- cgit v1.2.3 From 8779faf7891cf1fc394204b12ad1a0e403d22c6b Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 22 Nov 2019 16:50:09 -0800 Subject: Cleanup spacing --- tests/various/submod.ys | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/various/submod.ys b/tests/various/submod.ys index 54455b580..271a8edef 100644 --- a/tests/various/submod.ys +++ b/tests/various/submod.ys @@ -13,9 +13,9 @@ EOT hierarchy -top top proc design -save gold + submod flatten - design -stash gate design -import gold -as gold @@ -23,4 +23,3 @@ design -import gate -as gate miter -equiv -flatten -make_assert -make_outputs gold gate miter sat -verify -prove-asserts -show-ports miter - -- cgit v1.2.3 From 81548d1ef988d10007706c36df5885f8557de74a Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 22 Nov 2019 16:52:17 -0800 Subject: write_xaiger back to working with whole modules only --- backends/aiger/xaiger.cc | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 5d125b653..de2f7dd73 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -545,15 +545,12 @@ struct XAigerWriter undriven_bits.erase(bit); if (!undriven_bits.empty() && !holes_mode) { - bool whole_module = module->design->selected_whole_module(module->name); undriven_bits.sort(); for (auto bit : undriven_bits) { - if (whole_module) - log_warning("Treating undriven bit %s.%s like $anyseq.\n", log_id(module), log_signal(bit)); + log_warning("Treating undriven bit %s.%s like $anyseq.\n", log_id(module), log_signal(bit)); input_bits.insert(bit); } - if (whole_module) - log_warning("Treating a total of %d undriven bits in %s like $anyseq.\n", GetSize(undriven_bits), log_id(module)); + log_warning("Treating a total of %d undriven bits in %s like $anyseq.\n", GetSize(undriven_bits), log_id(module)); } if (holes_mode) { -- cgit v1.2.3 From 74ea4381362d4f402e7fc262b960e14122128303 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 22 Nov 2019 16:52:55 -0800 Subject: Add testcase for signal used as part input part output --- tests/simple_abc9/abc9.v | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/simple_abc9/abc9.v b/tests/simple_abc9/abc9.v index 6bdd3bc32..8314af211 100644 --- a/tests/simple_abc9/abc9.v +++ b/tests/simple_abc9/abc9.v @@ -289,3 +289,8 @@ module abc9_test033(input clk, d, output reg q1, q2); always @(posedge clk) q1 <= d; always @(posedge clk) q2 <= q1; endmodule + +module abc9_test034(input clk, d, output reg [1:0] q); +always @(posedge clk) q[0] <= d; +always @(negedge clk) q[1] <= q[0]; +endmodule -- cgit v1.2.3 From 00d76f6cc4ccbf15b188570f0bf0dbd143ce3782 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 22 Nov 2019 16:58:08 -0800 Subject: Replace TODO --- passes/techmap/clkpart.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/techmap/clkpart.cc b/passes/techmap/clkpart.cc index bf3b5bd30..d8d53536d 100644 --- a/passes/techmap/clkpart.cc +++ b/passes/techmap/clkpart.cc @@ -58,7 +58,7 @@ struct ClkPartPass : public Pass { } void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE { - log_header(design, "Executing CLKPART pass (TODO).\n"); + log_header(design, "Executing CLKPART pass (partition design according to clock domain).\n"); log_push(); clear_flags(); -- cgit v1.2.3 From 95af8f56e45e23dd29c9a3992f18eee2fa6ceeb1 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 22 Nov 2019 17:00:11 -0800 Subject: Only action if there is more than one clock domain --- passes/techmap/clkpart.cc | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/passes/techmap/clkpart.cc b/passes/techmap/clkpart.cc index d8d53536d..8f671c175 100644 --- a/passes/techmap/clkpart.cc +++ b/passes/techmap/clkpart.cc @@ -233,15 +233,16 @@ struct ClkPartPass : public Pass { std::get<0>(it.first) ? "" : "!", log_signal(std::get<1>(it.first)), std::get<2>(it.first) ? "" : "!", log_signal(std::get<3>(it.first))); - for (auto &it : assigned_cells) { - RTLIL::Selection sel(false); - sel.selected_members[mod->name] = pool(it.second.begin(), it.second.end()); + if (assigned_cells.size() > 1) + for (auto &it : assigned_cells) { + RTLIL::Selection sel(false); + sel.selected_members[mod->name] = pool(it.second.begin(), it.second.end()); - RTLIL::IdString submod = stringf("%s.%s", mod->name.c_str(), NEW_ID.c_str()); - Pass::call_on_selection(design, sel, stringf("submod -name %s", submod.c_str())); + RTLIL::IdString submod = stringf("%s.%s", mod->name.c_str(), NEW_ID.c_str()); + Pass::call_on_selection(design, sel, stringf("submod -name %s", submod.c_str())); - design->module(submod)->set_bool_attribute(ID(clkpart)); - } + design->module(submod)->set_bool_attribute(ID(clkpart)); + } } } -- cgit v1.2.3 From 573396851a03f08f80644924a560369d50659507 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 22 Nov 2019 17:03:30 -0800 Subject: Oops --- passes/hierarchy/submod.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/passes/hierarchy/submod.cc b/passes/hierarchy/submod.cc index 982558fb2..707bc26b3 100644 --- a/passes/hierarchy/submod.cc +++ b/passes/hierarchy/submod.cc @@ -233,7 +233,6 @@ struct SubmodWorker if (c.wire == wire) continue; outputs.insert(c.wire); - log_dump(c.wire->name); } } -- cgit v1.2.3 From 4fdcf8f7d73d0e577815ab50a3e0255f4bfd2154 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 22 Nov 2019 17:23:34 -0800 Subject: Add another test with constant driver --- tests/various/submod.ys | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/tests/various/submod.ys b/tests/various/submod.ys index 271a8edef..a9d3fe672 100644 --- a/tests/various/submod.ys +++ b/tests/various/submod.ys @@ -23,3 +23,31 @@ design -import gate -as gate miter -equiv -flatten -make_assert -make_outputs gold gate miter sat -verify -prove-asserts -show-ports miter + + +design -reset +read_verilog < Date: Fri, 22 Nov 2019 17:23:51 -0800 Subject: Constant driven signals are also an input to submodules --- passes/hierarchy/submod.cc | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/passes/hierarchy/submod.cc b/passes/hierarchy/submod.cc index 707bc26b3..a1fac9b79 100644 --- a/passes/hierarchy/submod.cc +++ b/passes/hierarchy/submod.cc @@ -33,7 +33,7 @@ struct SubmodWorker CellTypes ct; RTLIL::Design *design; RTLIL::Module *module; - pool outputs; + pool constants, outputs; bool copy_mode; std::string opt_name; @@ -125,7 +125,7 @@ struct SubmodWorker RTLIL::Wire *wire = it.first; wire_flags_t &flags = it.second; - if (wire->port_input) + if (wire->port_input || constants.count(wire)) flags.is_ext_driven = true; if (wire->port_output || outputs.count(wire)) flags.is_ext_used = true; @@ -235,6 +235,14 @@ struct SubmodWorker outputs.insert(c.wire); } } + for (auto wire : module->wires()) { + auto sig = sigmap(wire); + for (auto c : sig.chunks()) { + if (c.wire) + continue; + constants.insert(wire); + } + } if (opt_name.empty()) { -- cgit v1.2.3 From 900c806d4e48e861161661239de418613f50babb Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 22 Nov 2019 17:25:53 -0800 Subject: Move clkpart into passes/hierarchy --- passes/hierarchy/Makefile.inc | 1 + passes/hierarchy/clkpart.cc | 269 ++++++++++++++++++++++++++++++++++++++++++ passes/techmap/Makefile.inc | 1 - passes/techmap/clkpart.cc | 269 ------------------------------------------ 4 files changed, 270 insertions(+), 270 deletions(-) create mode 100644 passes/hierarchy/clkpart.cc delete mode 100644 passes/techmap/clkpart.cc diff --git a/passes/hierarchy/Makefile.inc b/passes/hierarchy/Makefile.inc index b3f139b72..ea809ec08 100644 --- a/passes/hierarchy/Makefile.inc +++ b/passes/hierarchy/Makefile.inc @@ -2,4 +2,5 @@ OBJS += passes/hierarchy/hierarchy.o OBJS += passes/hierarchy/uniquify.o OBJS += passes/hierarchy/submod.o +OBJS += passes/hierarchy/clkpart.o diff --git a/passes/hierarchy/clkpart.cc b/passes/hierarchy/clkpart.cc new file mode 100644 index 000000000..8f671c175 --- /dev/null +++ b/passes/hierarchy/clkpart.cc @@ -0,0 +1,269 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 Clifford Wolf + * 2019 Eddie Hung + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#include "kernel/register.h" +#include "kernel/sigtools.h" +#include "kernel/celltypes.h" +#include "kernel/rtlil.h" +#include "kernel/log.h" + +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + +struct ClkPartPass : public Pass { + ClkPartPass() : Pass("clkpart", "partition design according to clock domain") { } + void help() YS_OVERRIDE + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" clkpart [options] [selection]\n"); + log("\n"); + log("Partition the contents of selected modules according to the clock (and optionally\n"); + log("the enable) domains of its $_DFF* cells by extracting them into sub-modules,\n"); + log("using the `submod` command.\n"); + log("Sub-modules created by this command are marked with a 'clkpart' attribute.\n"); + log("\n"); + log(" -unpart\n"); + log(" undo this operation within the selected modules, by flattening those with\n"); + log(" a 'clkpart' attribute into those modules without this attribute.\n"); + log("\n"); + log(" -enable\n"); + log(" also consider enable domains.\n"); + log("\n"); + } + + bool unpart_mode, enable_mode; + + void clear_flags() YS_OVERRIDE + { + unpart_mode = false; + enable_mode = false; + } + void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE + { + log_header(design, "Executing CLKPART pass (partition design according to clock domain).\n"); + log_push(); + + clear_flags(); + + size_t argidx; + for (argidx = 1; argidx < args.size(); argidx++) + { + if (args[argidx] == "-unpart") { + unpart_mode = true; + continue; + } + if (args[argidx] == "-enable") { + enable_mode = true; + continue; + } + break; + } + extra_args(args, argidx, design); + + if (unpart_mode) + unpart(design); + else + part(design); + + log_pop(); + } + + void part(RTLIL::Design *design) + { + CellTypes ct(design); + SigMap assign_map; + + for (auto mod : design->selected_modules()) + { + if (mod->processes.size() > 0) { + log("Skipping module %s as it contains processes.\n", log_id(mod)); + continue; + } + + assign_map.set(mod); + + std::vector all_cells = mod->selected_cells(); + std::set unassigned_cells(all_cells.begin(), all_cells.end()); + + std::set expand_queue, next_expand_queue; + std::set expand_queue_up, next_expand_queue_up; + std::set expand_queue_down, next_expand_queue_down; + + typedef tuple clkdomain_t; + std::map> assigned_cells; + std::map assigned_cells_reverse; + + std::map> cell_to_bit, cell_to_bit_up, cell_to_bit_down; + std::map> bit_to_cell, bit_to_cell_up, bit_to_cell_down; + + for (auto cell : all_cells) + { + clkdomain_t key; + + for (auto &conn : cell->connections()) + for (auto bit : conn.second) { + bit = assign_map(bit); + if (bit.wire != nullptr) { + cell_to_bit[cell].insert(bit); + bit_to_cell[bit].insert(cell); + if (ct.cell_input(cell->type, conn.first)) { + cell_to_bit_up[cell].insert(bit); + bit_to_cell_down[bit].insert(cell); + } + if (ct.cell_output(cell->type, conn.first)) { + cell_to_bit_down[cell].insert(bit); + bit_to_cell_up[bit].insert(cell); + } + } + } + + if (cell->type.in(ID($_DFF_N_), ID($_DFF_P_))) + { + key = clkdomain_t(cell->type == ID($_DFF_P_), assign_map(cell->getPort(ID(C))), true, RTLIL::SigSpec()); + } + else + if (cell->type.in(ID($_DFFE_NN_), ID($_DFFE_NP_), ID($_DFFE_PN_), ID($_DFFE_PP_))) + { + bool this_clk_pol = cell->type.in(ID($_DFFE_PN_), ID($_DFFE_PP_)); + bool this_en_pol = !enable_mode || cell->type.in(ID($_DFFE_NP_), ID($_DFFE_PP_)); + key = clkdomain_t(this_clk_pol, assign_map(cell->getPort(ID(C))), this_en_pol, enable_mode ? assign_map(cell->getPort(ID(E))) : RTLIL::SigSpec()); + } + 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->name); + assigned_cells_reverse[cell] = key; + } + + while (!expand_queue_up.empty() || !expand_queue_down.empty()) + { + if (!expand_queue_up.empty()) + { + RTLIL::Cell *cell = *expand_queue_up.begin(); + clkdomain_t key = assigned_cells_reverse.at(cell); + expand_queue_up.erase(cell); + + for (auto bit : cell_to_bit_up[cell]) + for (auto c : bit_to_cell_up[bit]) + if (unassigned_cells.count(c)) { + unassigned_cells.erase(c); + next_expand_queue_up.insert(c); + assigned_cells[key].push_back(c->name); + 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->name); + 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->name); + 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->name); + 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))); + + if (assigned_cells.size() > 1) + for (auto &it : assigned_cells) { + RTLIL::Selection sel(false); + sel.selected_members[mod->name] = pool(it.second.begin(), it.second.end()); + + RTLIL::IdString submod = stringf("%s.%s", mod->name.c_str(), NEW_ID.c_str()); + Pass::call_on_selection(design, sel, stringf("submod -name %s", submod.c_str())); + + design->module(submod)->set_bool_attribute(ID(clkpart)); + } + } + } + + void unpart(RTLIL::Design *design) + { + vector keeped; + for (auto mod : design->selected_modules()) { + if (mod->get_bool_attribute(ID(clkpart))) + continue; + if (mod->get_bool_attribute(ID(keep_hierarchy))) + continue; + keeped.push_back(mod); + mod->set_bool_attribute(ID(keep_hierarchy)); + } + + Pass::call(design, "flatten"); + + for (auto mod : keeped) + mod->set_bool_attribute(ID(keep_hierarchy), false); + + } +} ClkPartPass; + +PRIVATE_NAMESPACE_END diff --git a/passes/techmap/Makefile.inc b/passes/techmap/Makefile.inc index 13992315e..cd357d72a 100644 --- a/passes/techmap/Makefile.inc +++ b/passes/techmap/Makefile.inc @@ -41,7 +41,6 @@ OBJS += passes/techmap/zinit.o OBJS += passes/techmap/dff2dffs.o OBJS += passes/techmap/flowmap.o OBJS += passes/techmap/extractinv.o -OBJS += passes/techmap/clkpart.o endif GENFILES += passes/techmap/techmap.inc diff --git a/passes/techmap/clkpart.cc b/passes/techmap/clkpart.cc deleted file mode 100644 index 8f671c175..000000000 --- a/passes/techmap/clkpart.cc +++ /dev/null @@ -1,269 +0,0 @@ -/* - * yosys -- Yosys Open SYnthesis Suite - * - * Copyright (C) 2012 Clifford Wolf - * 2019 Eddie Hung - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - */ - -#include "kernel/register.h" -#include "kernel/sigtools.h" -#include "kernel/celltypes.h" -#include "kernel/rtlil.h" -#include "kernel/log.h" - -USING_YOSYS_NAMESPACE -PRIVATE_NAMESPACE_BEGIN - -struct ClkPartPass : public Pass { - ClkPartPass() : Pass("clkpart", "partition design according to clock domain") { } - void help() YS_OVERRIDE - { - // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| - log("\n"); - log(" clkpart [options] [selection]\n"); - log("\n"); - log("Partition the contents of selected modules according to the clock (and optionally\n"); - log("the enable) domains of its $_DFF* cells by extracting them into sub-modules,\n"); - log("using the `submod` command.\n"); - log("Sub-modules created by this command are marked with a 'clkpart' attribute.\n"); - log("\n"); - log(" -unpart\n"); - log(" undo this operation within the selected modules, by flattening those with\n"); - log(" a 'clkpart' attribute into those modules without this attribute.\n"); - log("\n"); - log(" -enable\n"); - log(" also consider enable domains.\n"); - log("\n"); - } - - bool unpart_mode, enable_mode; - - void clear_flags() YS_OVERRIDE - { - unpart_mode = false; - enable_mode = false; - } - void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE - { - log_header(design, "Executing CLKPART pass (partition design according to clock domain).\n"); - log_push(); - - clear_flags(); - - size_t argidx; - for (argidx = 1; argidx < args.size(); argidx++) - { - if (args[argidx] == "-unpart") { - unpart_mode = true; - continue; - } - if (args[argidx] == "-enable") { - enable_mode = true; - continue; - } - break; - } - extra_args(args, argidx, design); - - if (unpart_mode) - unpart(design); - else - part(design); - - log_pop(); - } - - void part(RTLIL::Design *design) - { - CellTypes ct(design); - SigMap assign_map; - - for (auto mod : design->selected_modules()) - { - if (mod->processes.size() > 0) { - log("Skipping module %s as it contains processes.\n", log_id(mod)); - continue; - } - - assign_map.set(mod); - - std::vector all_cells = mod->selected_cells(); - std::set unassigned_cells(all_cells.begin(), all_cells.end()); - - std::set expand_queue, next_expand_queue; - std::set expand_queue_up, next_expand_queue_up; - std::set expand_queue_down, next_expand_queue_down; - - typedef tuple clkdomain_t; - std::map> assigned_cells; - std::map assigned_cells_reverse; - - std::map> cell_to_bit, cell_to_bit_up, cell_to_bit_down; - std::map> bit_to_cell, bit_to_cell_up, bit_to_cell_down; - - for (auto cell : all_cells) - { - clkdomain_t key; - - for (auto &conn : cell->connections()) - for (auto bit : conn.second) { - bit = assign_map(bit); - if (bit.wire != nullptr) { - cell_to_bit[cell].insert(bit); - bit_to_cell[bit].insert(cell); - if (ct.cell_input(cell->type, conn.first)) { - cell_to_bit_up[cell].insert(bit); - bit_to_cell_down[bit].insert(cell); - } - if (ct.cell_output(cell->type, conn.first)) { - cell_to_bit_down[cell].insert(bit); - bit_to_cell_up[bit].insert(cell); - } - } - } - - if (cell->type.in(ID($_DFF_N_), ID($_DFF_P_))) - { - key = clkdomain_t(cell->type == ID($_DFF_P_), assign_map(cell->getPort(ID(C))), true, RTLIL::SigSpec()); - } - else - if (cell->type.in(ID($_DFFE_NN_), ID($_DFFE_NP_), ID($_DFFE_PN_), ID($_DFFE_PP_))) - { - bool this_clk_pol = cell->type.in(ID($_DFFE_PN_), ID($_DFFE_PP_)); - bool this_en_pol = !enable_mode || cell->type.in(ID($_DFFE_NP_), ID($_DFFE_PP_)); - key = clkdomain_t(this_clk_pol, assign_map(cell->getPort(ID(C))), this_en_pol, enable_mode ? assign_map(cell->getPort(ID(E))) : RTLIL::SigSpec()); - } - 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->name); - assigned_cells_reverse[cell] = key; - } - - while (!expand_queue_up.empty() || !expand_queue_down.empty()) - { - if (!expand_queue_up.empty()) - { - RTLIL::Cell *cell = *expand_queue_up.begin(); - clkdomain_t key = assigned_cells_reverse.at(cell); - expand_queue_up.erase(cell); - - for (auto bit : cell_to_bit_up[cell]) - for (auto c : bit_to_cell_up[bit]) - if (unassigned_cells.count(c)) { - unassigned_cells.erase(c); - next_expand_queue_up.insert(c); - assigned_cells[key].push_back(c->name); - 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->name); - 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->name); - 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->name); - 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))); - - if (assigned_cells.size() > 1) - for (auto &it : assigned_cells) { - RTLIL::Selection sel(false); - sel.selected_members[mod->name] = pool(it.second.begin(), it.second.end()); - - RTLIL::IdString submod = stringf("%s.%s", mod->name.c_str(), NEW_ID.c_str()); - Pass::call_on_selection(design, sel, stringf("submod -name %s", submod.c_str())); - - design->module(submod)->set_bool_attribute(ID(clkpart)); - } - } - } - - void unpart(RTLIL::Design *design) - { - vector keeped; - for (auto mod : design->selected_modules()) { - if (mod->get_bool_attribute(ID(clkpart))) - continue; - if (mod->get_bool_attribute(ID(keep_hierarchy))) - continue; - keeped.push_back(mod); - mod->set_bool_attribute(ID(keep_hierarchy)); - } - - Pass::call(design, "flatten"); - - for (auto mod : keeped) - mod->set_bool_attribute(ID(keep_hierarchy), false); - - } -} ClkPartPass; - -PRIVATE_NAMESPACE_END -- cgit v1.2.3 From 08f85e64383c0248030873dcdcf388853d335eea Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 22 Nov 2019 20:53:48 -0800 Subject: Stray dump --- tests/various/submod.ys | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/various/submod.ys b/tests/various/submod.ys index a9d3fe672..451ced5e6 100644 --- a/tests/various/submod.ys +++ b/tests/various/submod.ys @@ -42,7 +42,6 @@ proc design -save gold submod -dump flatten design -stash gate -- cgit v1.2.3 From cba3073026711e7683c46ba091c56a5c5a041a45 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 22 Nov 2019 20:53:58 -0800 Subject: submod to bitty rather bussy, for bussy wires used as input and output --- passes/hierarchy/submod.cc | 87 +++++++++++++++++++++------------------------- 1 file changed, 39 insertions(+), 48 deletions(-) diff --git a/passes/hierarchy/submod.cc b/passes/hierarchy/submod.cc index a1fac9b79..212932e46 100644 --- a/passes/hierarchy/submod.cc +++ b/passes/hierarchy/submod.cc @@ -33,7 +33,8 @@ struct SubmodWorker CellTypes ct; RTLIL::Design *design; RTLIL::Module *module; - pool constants, outputs; + SigMap sigmap; + pool outputs; bool copy_mode; std::string opt_name; @@ -46,44 +47,44 @@ struct SubmodWorker std::map submodules; - struct wire_flags_t { + struct bit_flags_t { RTLIL::Wire *new_wire; bool is_int_driven, is_int_used, is_ext_driven, is_ext_used; - wire_flags_t() : new_wire(NULL), is_int_driven(false), is_int_used(false), is_ext_driven(false), is_ext_used(false) { } + bit_flags_t() : new_wire(NULL), is_int_driven(false), is_int_used(false), is_ext_driven(false), is_ext_used(false) { } }; - std::map wire_flags; + std::map bit_flags; bool flag_found_something; - void flag_wire(RTLIL::Wire *wire, bool create, bool set_int_driven, bool set_int_used, bool set_ext_driven, bool set_ext_used) + void flag_bit(RTLIL::SigBit bit, bool create, bool set_int_driven, bool set_int_used, bool set_ext_driven, bool set_ext_used) { - if (wire_flags.count(wire) == 0) { + if (bit_flags.count(bit) == 0) { if (!create) return; - wire_flags[wire] = wire_flags_t(); + bit_flags[bit] = bit_flags_t(); } if (set_int_driven) - wire_flags[wire].is_int_driven = true; + bit_flags[bit].is_int_driven = true; if (set_int_used) - wire_flags[wire].is_int_used = true; + bit_flags[bit].is_int_used = true; if (set_ext_driven) - wire_flags[wire].is_ext_driven = true; + bit_flags[bit].is_ext_driven = true; if (set_ext_used) - wire_flags[wire].is_ext_used = true; + bit_flags[bit].is_ext_used = true; flag_found_something = true; } void flag_signal(const RTLIL::SigSpec &sig, bool create, bool set_int_driven, bool set_int_used, bool set_ext_driven, bool set_ext_used) { - for (auto &c : sig.chunks()) - if (c.wire != NULL) - flag_wire(c.wire, create, set_int_driven, set_int_used, set_ext_driven, set_ext_used); + for (auto &b : sig) + if (b.wire != NULL) + flag_bit(b, create, set_int_driven, set_int_used, set_ext_driven, set_ext_used); } void handle_submodule(SubModule &submod) { log("Creating submodule %s (%s) of module %s.\n", submod.name.c_str(), submod.full_name.c_str(), module->name.c_str()); - wire_flags.clear(); + bit_flags.clear(); for (RTLIL::Cell *cell : submod.cells) { if (ct.cell_known(cell->type)) { for (auto &conn : cell->connections()) @@ -116,18 +117,19 @@ struct SubmodWorker int auto_name_counter = 1; std::set all_wire_names; - for (auto &it : wire_flags) { - all_wire_names.insert(it.first->name); + for (auto &it : bit_flags) { + all_wire_names.insert(it.first.wire->name); } - for (auto &it : wire_flags) + for (auto &it : bit_flags) { - RTLIL::Wire *wire = it.first; - wire_flags_t &flags = it.second; + const RTLIL::SigBit &bit = it.first; + RTLIL::Wire *wire = bit.wire; + bit_flags_t &flags = it.second; - if (wire->port_input || constants.count(wire)) + if (wire->port_input) flags.is_ext_driven = true; - if (wire->port_output || outputs.count(wire)) + if (outputs.count(bit)) flags.is_ext_used = true; bool new_wire_port_input = false; @@ -141,7 +143,11 @@ struct SubmodWorker if (flags.is_int_driven && flags.is_ext_driven) new_wire_port_input = true, new_wire_port_output = true; - std::string new_wire_name = wire->name.str(); + RTLIL::IdString new_wire_name; + if (GetSize(wire) == 1) + new_wire_name = wire->name; + else + new_wire_name = stringf("%s[%d]", wire->name.c_str(), bit.offset); if (new_wire_port_input || new_wire_port_output) { while (new_wire_name[0] == '$') { std::string next_wire_name = stringf("\\n%d", auto_name_counter++); @@ -152,10 +158,9 @@ struct SubmodWorker } } - RTLIL::Wire *new_wire = new_mod->addWire(new_wire_name, wire->width); + RTLIL::Wire *new_wire = new_mod->addWire(new_wire_name); new_wire->port_input = new_wire_port_input; new_wire->port_output = new_wire_port_output; - new_wire->start_offset = wire->start_offset; new_wire->attributes = wire->attributes; if (new_wire->port_input && new_wire->port_output) @@ -178,8 +183,8 @@ struct SubmodWorker for (auto &conn : new_cell->connections_) for (auto &bit : conn.second) if (bit.wire != NULL) { - log_assert(wire_flags.count(bit.wire) > 0); - bit.wire = wire_flags[bit.wire].new_wire; + log_assert(bit_flags.count(bit) > 0); + bit = bit_flags[bit].new_wire; } log(" cell %s (%s)\n", new_cell->name.c_str(), new_cell->type.c_str()); if (!copy_mode) @@ -189,18 +194,18 @@ struct SubmodWorker if (!copy_mode) { RTLIL::Cell *new_cell = module->addCell(submod.full_name, submod.full_name); - for (auto &it : wire_flags) + for (auto &it : bit_flags) { - RTLIL::Wire *old_wire = it.first; + RTLIL::SigBit old_bit = it.first; RTLIL::Wire *new_wire = it.second.new_wire; if (new_wire->port_id > 0) - new_cell->setPort(new_wire->name, RTLIL::SigSpec(old_wire)); + new_cell->setPort(new_wire->name, old_bit); } } } SubmodWorker(RTLIL::Design *design, RTLIL::Module *module, bool copy_mode = false, std::string opt_name = std::string()) : - design(design), module(module), copy_mode(copy_mode), opt_name(opt_name) + design(design), module(module), sigmap(module), copy_mode(copy_mode), opt_name(opt_name) { if (!design->selected_whole_module(module->name) && opt_name.empty()) return; @@ -221,27 +226,13 @@ struct SubmodWorker ct.setup_stdcells_mem(); ct.setup_design(design); - SigMap sigmap(module); for (auto port : module->ports) { auto wire = module->wire(port); if (!wire->port_output) continue; - auto sig = sigmap(wire); - for (auto c : sig.chunks()) { - if (!c.wire) - continue; - if (c.wire == wire) - continue; - outputs.insert(c.wire); - } - } - for (auto wire : module->wires()) { - auto sig = sigmap(wire); - for (auto c : sig.chunks()) { - if (c.wire) - continue; - constants.insert(wire); - } + for (auto b : sigmap(wire)) + if (b.wire) + outputs.insert(b); } if (opt_name.empty()) -- cgit v1.2.3 From 5cd3d3db0aaa8642dad53f8fb629e3109cef5825 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 22 Nov 2019 22:22:56 -0800 Subject: Remove redundant flatten --- tests/various/submod.ys | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/various/submod.ys b/tests/various/submod.ys index 451ced5e6..7c6f555ac 100644 --- a/tests/various/submod.ys +++ b/tests/various/submod.ys @@ -15,7 +15,6 @@ proc design -save gold submod -flatten design -stash gate design -import gold -as gold @@ -42,7 +41,6 @@ proc design -save gold submod -flatten design -stash gate design -import gold -as gold -- cgit v1.2.3 From 736b96b186cd1096fd6043797fdcae295580f289 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 22 Nov 2019 23:16:15 -0800 Subject: Call submod once, more meaningful submod names, ignore largest domain --- passes/hierarchy/clkpart.cc | 50 +++++++++++++++++++++++++++++---------------- 1 file changed, 32 insertions(+), 18 deletions(-) diff --git a/passes/hierarchy/clkpart.cc b/passes/hierarchy/clkpart.cc index 8f671c175..a9ef2aa6c 100644 --- a/passes/hierarchy/clkpart.cc +++ b/passes/hierarchy/clkpart.cc @@ -90,7 +90,9 @@ struct ClkPartPass : public Pass { { CellTypes ct(design); SigMap assign_map; + std::vector new_submods; + log_header(design, "Summary of detected clock domains:\n"); for (auto mod : design->selected_modules()) { if (mod->processes.size() > 0) { @@ -108,7 +110,7 @@ struct ClkPartPass : public Pass { std::set expand_queue_down, next_expand_queue_down; typedef tuple clkdomain_t; - std::map> assigned_cells; + std::map> assigned_cells; std::map assigned_cells_reverse; std::map> cell_to_bit, cell_to_bit_up, cell_to_bit_down; @@ -154,7 +156,7 @@ struct ClkPartPass : public Pass { expand_queue_up.insert(cell); expand_queue_down.insert(cell); - assigned_cells[key].push_back(cell->name); + assigned_cells[key].push_back(cell); assigned_cells_reverse[cell] = key; } @@ -171,7 +173,7 @@ struct ClkPartPass : public Pass { if (unassigned_cells.count(c)) { unassigned_cells.erase(c); next_expand_queue_up.insert(c); - assigned_cells[key].push_back(c->name); + assigned_cells[key].push_back(c); assigned_cells_reverse[c] = key; expand_queue.insert(c); } @@ -188,7 +190,7 @@ struct ClkPartPass : public Pass { if (unassigned_cells.count(c)) { unassigned_cells.erase(c); next_expand_queue_up.insert(c); - assigned_cells[key].push_back(c->name); + assigned_cells[key].push_back(c); assigned_cells_reverse[c] = key; expand_queue.insert(c); } @@ -211,7 +213,7 @@ struct ClkPartPass : public Pass { if (unassigned_cells.count(c)) { unassigned_cells.erase(c); next_expand_queue.insert(c); - assigned_cells[key].push_back(c->name); + assigned_cells[key].push_back(c); assigned_cells_reverse[c] = key; } bit_to_cell[bit].clear(); @@ -223,27 +225,39 @@ struct ClkPartPass : public Pass { clkdomain_t key(true, RTLIL::SigSpec(), true, RTLIL::SigSpec()); for (auto cell : unassigned_cells) { - assigned_cells[key].push_back(cell->name); + 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), + clkdomain_t largest_domain; + int largest_domain_size = 0; + log(" module %s\n", mod->name.c_str()); + 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))); + if (GetSize(it.second) > largest_domain_size) { + largest_domain = it.first; + largest_domain_size = GetSize(it.second); + } + } - if (assigned_cells.size() > 1) - for (auto &it : assigned_cells) { - RTLIL::Selection sel(false); - sel.selected_members[mod->name] = pool(it.second.begin(), it.second.end()); - - RTLIL::IdString submod = stringf("%s.%s", mod->name.c_str(), NEW_ID.c_str()); - Pass::call_on_selection(design, sel, stringf("submod -name %s", submod.c_str())); + for (auto &it : assigned_cells) { + if (it.first == largest_domain) + continue; - design->module(submod)->set_bool_attribute(ID(clkpart)); - } + std::string submod = stringf("\\%s%s.%s%s", + 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 c : it.second) + c->attributes[ID(submod)] = submod; + new_submods.push_back(stringf("%s_%s", mod->name.c_str(), submod.c_str())); + } } + + Pass::call(design, "submod"); + for (auto m : new_submods) + design->module(m)->set_bool_attribute(ID(clkpart)); } void unpart(RTLIL::Design *design) -- cgit v1.2.3 From 96941aacbb4e3be4901941b8c0ba4565f9919a22 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 22 Nov 2019 23:29:10 -0800 Subject: Do not use log_signal() for empty SigSpec to prevent "{ }" --- passes/hierarchy/clkpart.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/passes/hierarchy/clkpart.cc b/passes/hierarchy/clkpart.cc index a9ef2aa6c..7cd1f4b43 100644 --- a/passes/hierarchy/clkpart.cc +++ b/passes/hierarchy/clkpart.cc @@ -246,9 +246,11 @@ struct ClkPartPass : public Pass { if (it.first == largest_domain) continue; + auto clk = std::get<1>(it.first); + auto en = std::get<3>(it.first); std::string submod = stringf("\\%s%s.%s%s", - std::get<0>(it.first) ? "" : "!", log_signal(std::get<1>(it.first)), - std::get<2>(it.first) ? "" : "!", log_signal(std::get<3>(it.first))); + std::get<0>(it.first) ? "" : "!", clk.empty() ? "" : log_signal(clk), + std::get<2>(it.first) ? "" : "!", en.empty() ? "" : log_signal(en)); for (auto c : it.second) c->attributes[ID(submod)] = submod; new_submods.push_back(stringf("%s_%s", mod->name.c_str(), submod.c_str())); -- cgit v1.2.3 From 66ff0511a0e3eeae2989c2fa582c1e1c13dd75ad Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Sat, 23 Nov 2019 09:52:17 -0800 Subject: Add -set_attr option, -unpart to take attr name --- passes/hierarchy/clkpart.cc | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/passes/hierarchy/clkpart.cc b/passes/hierarchy/clkpart.cc index 7cd1f4b43..acdd9b4ae 100644 --- a/passes/hierarchy/clkpart.cc +++ b/passes/hierarchy/clkpart.cc @@ -28,7 +28,7 @@ USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN struct ClkPartPass : public Pass { - ClkPartPass() : Pass("clkpart", "partition design according to clock domain") { } + ClkPartPass() : Pass("clkpart", "partition design according to clock/enable domain") { } void help() YS_OVERRIDE { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| @@ -38,11 +38,14 @@ struct ClkPartPass : public Pass { log("Partition the contents of selected modules according to the clock (and optionally\n"); log("the enable) domains of its $_DFF* cells by extracting them into sub-modules,\n"); log("using the `submod` command.\n"); - log("Sub-modules created by this command are marked with a 'clkpart' attribute.\n"); log("\n"); - log(" -unpart\n"); - log(" undo this operation within the selected modules, by flattening those with\n"); - log(" a 'clkpart' attribute into those modules without this attribute.\n"); + log(" -set_attr \n"); + log(" set the specified attribute on all sub-modules created.\n"); + log("\n"); + log(" -unpart \n"); + log(" undo this operation within the selected modules, by flattening those\n"); + log(" attached with an attribute into those modules without this\n"); + log(" attribute.\n"); log("\n"); log(" -enable\n"); log(" also consider enable domains.\n"); @@ -50,15 +53,19 @@ struct ClkPartPass : public Pass { } bool unpart_mode, enable_mode; + IdString attr_name; + Const attr_value; void clear_flags() YS_OVERRIDE { unpart_mode = false; enable_mode = false; + attr_name = IdString(); + attr_value = Const(); } void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE { - log_header(design, "Executing CLKPART pass (partition design according to clock domain).\n"); + log_header(design, "Executing CLKPART pass (partition design according to clock/enable domain).\n"); log_push(); clear_flags(); @@ -66,8 +73,14 @@ struct ClkPartPass : public Pass { size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) { - if (args[argidx] == "-unpart") { + if (args[argidx] == "-set_attr" && argidx+2 < args.size()) { + attr_name = args[argidx++]; + attr_value = args[argidx++]; + continue; + } + if (args[argidx] == "-unpart" && argidx+1 < args.size()) { unpart_mode = true; + attr_name = args[argidx++]; continue; } if (args[argidx] == "-enable") { @@ -258,15 +271,17 @@ struct ClkPartPass : public Pass { } Pass::call(design, "submod"); - for (auto m : new_submods) - design->module(m)->set_bool_attribute(ID(clkpart)); + + if (!attr_name.empty()) + for (auto m : new_submods) + design->module(m)->attributes[attr_name] = attr_value; } void unpart(RTLIL::Design *design) { vector keeped; for (auto mod : design->selected_modules()) { - if (mod->get_bool_attribute(ID(clkpart))) + if (mod->get_bool_attribute(attr_name)) continue; if (mod->get_bool_attribute(ID(keep_hierarchy))) continue; -- cgit v1.2.3 From 165f5cb6cf3415bb56ddaef91079c558cd2f16d4 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Sat, 23 Nov 2019 10:01:09 -0800 Subject: More sane naming of submod --- passes/hierarchy/clkpart.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/passes/hierarchy/clkpart.cc b/passes/hierarchy/clkpart.cc index acdd9b4ae..4f4291e06 100644 --- a/passes/hierarchy/clkpart.cc +++ b/passes/hierarchy/clkpart.cc @@ -261,9 +261,9 @@ struct ClkPartPass : public Pass { auto clk = std::get<1>(it.first); auto en = std::get<3>(it.first); - std::string submod = stringf("\\%s%s.%s%s", + std::string submod = stringf("clk=%s%s%s%s%s", std::get<0>(it.first) ? "" : "!", clk.empty() ? "" : log_signal(clk), - std::get<2>(it.first) ? "" : "!", en.empty() ? "" : log_signal(en)); + std::get<2>(it.first) ? "" : "!", en.empty() ? ".en=" : "", en.empty() ? "" : log_signal(en)); for (auto c : it.second) c->attributes[ID(submod)] = submod; new_submods.push_back(stringf("%s_%s", mod->name.c_str(), submod.c_str())); -- cgit v1.2.3 From 907c8aeaef4a0a06beda9126b23aae3bfcd53b65 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Sat, 23 Nov 2019 10:16:56 -0800 Subject: Escape IdStrings --- passes/hierarchy/clkpart.cc | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/passes/hierarchy/clkpart.cc b/passes/hierarchy/clkpart.cc index 4f4291e06..7c3e52178 100644 --- a/passes/hierarchy/clkpart.cc +++ b/passes/hierarchy/clkpart.cc @@ -74,13 +74,12 @@ struct ClkPartPass : public Pass { for (argidx = 1; argidx < args.size(); argidx++) { if (args[argidx] == "-set_attr" && argidx+2 < args.size()) { - attr_name = args[argidx++]; + attr_name = RTLIL::escape_id(args[argidx++]); attr_value = args[argidx++]; continue; } if (args[argidx] == "-unpart" && argidx+1 < args.size()) { - unpart_mode = true; - attr_name = args[argidx++]; + attr_name = RTLIL::escape_id(args[argidx++]); continue; } if (args[argidx] == "-enable") { -- cgit v1.2.3 From 722eeacc095106a80bfda5326416a643af02738d Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Sat, 23 Nov 2019 10:17:31 -0800 Subject: Print ".en=" only if there is an enable signal --- passes/hierarchy/clkpart.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/hierarchy/clkpart.cc b/passes/hierarchy/clkpart.cc index 7c3e52178..d914bcec0 100644 --- a/passes/hierarchy/clkpart.cc +++ b/passes/hierarchy/clkpart.cc @@ -262,7 +262,7 @@ struct ClkPartPass : public Pass { auto en = std::get<3>(it.first); std::string submod = stringf("clk=%s%s%s%s%s", std::get<0>(it.first) ? "" : "!", clk.empty() ? "" : log_signal(clk), - std::get<2>(it.first) ? "" : "!", en.empty() ? ".en=" : "", en.empty() ? "" : log_signal(en)); + std::get<2>(it.first) ? "" : "!", en.empty() ? "" : ".en=", en.empty() ? "" : log_signal(en)); for (auto c : it.second) c->attributes[ID(submod)] = submod; new_submods.push_back(stringf("%s_%s", mod->name.c_str(), submod.c_str())); -- cgit v1.2.3 From eb11c06a69c3b50e39cf363926992b40a9c440c3 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Sat, 23 Nov 2019 10:18:22 -0800 Subject: For abc9, run clkpart before ff_map and after abc9 --- techlibs/xilinx/synth_xilinx.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index b5c203d1f..7105ba429 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -513,6 +513,7 @@ struct SynthXilinxPass : public ScriptPass if (check_label("map_ffs")) { if (abc9 || help_mode) { + run("clkpart -set_attr clkpart 1", "('-abc9' only)"); run("techmap -map " + ff_map_file, "('-abc9' only)"); } } @@ -537,6 +538,7 @@ struct SynthXilinxPass : public ScriptPass else abc9_opts += " -lut +/xilinx/abc9_xc7.lut"; run("abc9" + abc9_opts); + run("clkpart -unpart clkpart"); } else { if (nowidelut) -- cgit v1.2.3 From bf1167bc64eba873ceaf3e4a1988a216fb3909c3 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Sat, 23 Nov 2019 10:26:55 -0800 Subject: Conditioning abc9 on POs not accurate due to cells --- passes/techmap/abc9.cc | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 4b6ec6e11..c2ac4ef7f 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -322,19 +322,10 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip fprintf(f, "%s\n", abc9_script.c_str()); fclose(f); - 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; - } - } - + //bool count_output = false; log_push(); - if (count_output) + //if (count_output) { handle_loops(design, module); @@ -736,10 +727,10 @@ clone_lut: design->remove(mapped_mod); } - else - { - log("Don't call ABC as there is nothing to map.\n"); - } + //else + //{ + // log("Don't call ABC as there is nothing to map.\n"); + //} if (cleanup) { -- cgit v1.2.3 From 15aa3f460d1aa873108360df1cf2d5f22137946d Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Sat, 23 Nov 2019 10:28:46 -0800 Subject: More oopsies --- passes/hierarchy/clkpart.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/passes/hierarchy/clkpart.cc b/passes/hierarchy/clkpart.cc index d914bcec0..b79625540 100644 --- a/passes/hierarchy/clkpart.cc +++ b/passes/hierarchy/clkpart.cc @@ -74,12 +74,13 @@ struct ClkPartPass : public Pass { for (argidx = 1; argidx < args.size(); argidx++) { if (args[argidx] == "-set_attr" && argidx+2 < args.size()) { - attr_name = RTLIL::escape_id(args[argidx++]); + attr_name = RTLIL::escape_id(args[++argidx]); attr_value = args[argidx++]; continue; } if (args[argidx] == "-unpart" && argidx+1 < args.size()) { - attr_name = RTLIL::escape_id(args[argidx++]); + unpart_mode = true; + attr_name = RTLIL::escape_id(args[++argidx]); continue; } if (args[argidx] == "-enable") { -- cgit v1.2.3 From 63b7a48fbc250dd16847eed95d5ce79417cd7d2f Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 25 Nov 2019 12:04:11 -0800 Subject: clkpart to analyse async flops too --- passes/hierarchy/clkpart.cc | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/passes/hierarchy/clkpart.cc b/passes/hierarchy/clkpart.cc index b79625540..15a5328b9 100644 --- a/passes/hierarchy/clkpart.cc +++ b/passes/hierarchy/clkpart.cc @@ -161,6 +161,14 @@ struct ClkPartPass : public Pass { bool this_en_pol = !enable_mode || cell->type.in(ID($_DFFE_NP_), ID($_DFFE_PP_)); key = clkdomain_t(this_clk_pol, assign_map(cell->getPort(ID(C))), this_en_pol, enable_mode ? assign_map(cell->getPort(ID(E))) : RTLIL::SigSpec()); } + else + if (cell->type.in(ID($_DFF_NN0_), ID($_DFF_NN1_), ID($_DFF_NP0_), ID($_DFF_NP1_), + ID($_DFF_PN0_), ID($_DFF_PN1_), ID($_DFF_PP0_), ID($_DFF_PP1_))) + { + bool this_clk_pol = cell->type.in(ID($_DFF_PN0_), ID($_DFF_PN1_), ID($_DFF_PP0_), ID($_DFF_PP1_)); + log_assert(!enable_mode); // TODO + key = clkdomain_t(this_clk_pol, assign_map(cell->getPort(ID(C))), true, RTLIL::SigSpec()); + } else continue; -- cgit v1.2.3 From f50b6422b0b517dd0d9a07742f04477e2973c0f9 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 25 Nov 2019 12:35:38 -0800 Subject: abc9 to no longer to clock partitioning, operate on whole modules only --- passes/techmap/abc9.cc | 171 +++++++++---------------------------------------- 1 file changed, 32 insertions(+), 139 deletions(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index c2ac4ef7f..60fc06f6e 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -752,6 +752,10 @@ struct Abc9Pass : public Pass { 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("Selection must only contain fully selected modules. It is assumed that such\n"); + log("modules contain only cells belonging to the same clock domain, as produced by\n"); + log("the 'clkpart' command.\n"); + log("\n"); log(" -exe \n"); #ifdef ABCEXTERNAL log(" use the specified command instead of \"" ABCEXTERNAL "\" to execute ABC.\n"); @@ -1082,63 +1086,44 @@ struct Abc9Pass : public Pass { continue; } - SigMap assign_map(module); - - CellTypes ct(design); - - std::vector all_cells = module->selected_cells(); - std::set unassigned_cells(all_cells.begin(), all_cells.end()); - - std::set expand_queue, next_expand_queue; - std::set expand_queue_up, next_expand_queue_up; - std::set expand_queue_down, next_expand_queue_down; - - std::map> assigned_cells; - std::map assigned_cells_reverse; + if (!design->selected_whole_module(module)) { + log("Skipping module %s as it is partially selected.\n", log_id(module)); + continue; + } - std::map> cell_to_bit, cell_to_bit_up, cell_to_bit_down; - std::map> bit_to_cell, bit_to_cell_up, bit_to_cell_down; + SigMap sigmap(module); typedef std::pair ctrldomain_t; std::map mergeability_class; + pool clocks; + std::string target = delay_target; - for (auto cell : all_cells) { - for (auto &conn : cell->connections()) - for (auto bit : assign_map(conn.second)) - 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); - } - } - + for (auto cell : module->selected_cells()) { auto inst_module = design->module(cell->type); if (!inst_module || !inst_module->attributes.count("\\abc9_flop")) continue; - Wire *abc9_clock_wire = module->wire(stringf("%s.$abc9_clock", cell->name.c_str())); - if (abc9_clock_wire == NULL) - log_error("'%s$abc9_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); + if (delay_target.empty()) { + Wire *abc9_clock_wire = module->wire(stringf("%s.$abc9_clock", cell->name.c_str())); + if (abc9_clock_wire == NULL) + log_error("'%s$abc9_clock' is not a wire present in module '%s'.\n", cell->name.c_str(), log_id(module)); + SigBit abc9_clock = sigmap(abc9_clock_wire); + auto r = clocks.insert(abc9_clock.wire); + if (r.second) { + auto it = abc9_clock.wire->attributes.find("\\abc9_period"); + if (it != abc9_clock.wire->attributes.end()) { + int period = it->second.as_int(); + log("Identified target period = %d ps for clock %s\n", period, log_signal(abc9_clock)); + target = stringf("-D %d", period); + } + } + } + Wire *abc9_control_wire = module->wire(stringf("%s.$abc9_control", cell->name.c_str())); if (abc9_control_wire == NULL) log_error("'%s$abc9_control' is not a wire present in module '%s'.\n", cell->name.c_str(), log_id(module)); - SigSpec abc9_control = assign_map(abc9_control_wire); - - unassigned_cells.erase(cell); - expand_queue.insert(cell); - expand_queue_up.insert(cell); - expand_queue_down.insert(cell); - - assigned_cells[abc9_clock].insert(cell->name); - assigned_cells_reverse[cell] = abc9_clock; + SigSpec abc9_control = sigmap(abc9_control_wire); ctrldomain_t key(cell->type, abc9_control); auto r = mergeability_class.emplace(key, mergeability_class.size() + 1); @@ -1146,102 +1131,10 @@ struct Abc9Pass : public Pass { log_assert(r2.second); } - while (!expand_queue_up.empty() || !expand_queue_down.empty()) - { - if (!expand_queue_up.empty()) - { - RTLIL::Cell *cell = *expand_queue_up.begin(); - SigSpec 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) && !c->type.in("$__ABC9_FF_", "$__ABC9_ASYNC_")) { - unassigned_cells.erase(c); - next_expand_queue_up.insert(c); - assigned_cells[key].insert(c->name); - assigned_cells_reverse[c] = key; - expand_queue.insert(c); - } - } - - if (!expand_queue_down.empty()) - { - RTLIL::Cell *cell = *expand_queue_down.begin(); - SigSpec 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].insert(c->name); - 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(); - SigSpec 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].insert(c->name); - assigned_cells_reverse[c] = key; - } - bit_to_cell[bit].clear(); - } - - if (expand_queue.empty()) - expand_queue.swap(next_expand_queue); - } - - SigSpec key; - for (auto cell : unassigned_cells) { - assigned_cells[key].insert(cell->name); - 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\n", GetSize(it.second), log_signal(it.first)); - - design->selection_stack.emplace_back(false); design->selected_active_module = module->name.str(); - for (auto &it : assigned_cells) { - std::string target = delay_target; - if (target.empty()) { - for (auto b : assign_map(it.first)) - if (b.wire) { - auto jt = b.wire->attributes.find("\\abc9_period"); - if (jt != b.wire->attributes.end()) { - target = stringf("-D %d", jt->second.as_int()); - log("Target period = %s ps for clock domain %s\n", target.c_str(), log_signal(it.first)); - break; - } - } - } - RTLIL::Selection& sel = design->selection_stack.back(); - sel.selected_members[module->name] = std::move(it.second); - abc9_module(design, module, script_file, exe_file, cleanup, lut_costs, false, "$", - keepff, target, lutin_shared, fast_mode, show_tempdir, - box_file, lut_file, wire_delay, box_lookup, nomfs); - assign_map.set(module); - } - design->selection_stack.pop_back(); + abc9_module(design, module, script_file, exe_file, cleanup, lut_costs, false, "$", + keepff, target, lutin_shared, fast_mode, show_tempdir, + box_file, lut_file, wire_delay, box_lookup, nomfs); design->selected_active_module.clear(); } -- cgit v1.2.3 From 180cb3939546f68eca878a8427a043eb1169094c Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 25 Nov 2019 12:35:57 -0800 Subject: abc9 to contain time call --- passes/techmap/abc9.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 60fc06f6e..2409f3d91 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -30,7 +30,7 @@ "&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" +#define ABC_COMMAND_LUT "&st; &scorr; &sweep; &dc2; &st; &dch -f; &ps; &if {W} {D} -v; &mfs; &ps -l; time" #endif -- cgit v1.2.3 From 6a2eb5d8f9286b9574647c03e2bdc8b63fccbe4d Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 25 Nov 2019 12:36:13 -0800 Subject: Special abc9_clock wire to contain only clock signal --- techlibs/xilinx/abc9_map.v | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/techlibs/xilinx/abc9_map.v b/techlibs/xilinx/abc9_map.v index 9913b229f..29ddf7133 100644 --- a/techlibs/xilinx/abc9_map.v +++ b/techlibs/xilinx/abc9_map.v @@ -62,10 +62,8 @@ // 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) a special _TECHMAP_REPLACE_.$abc9_clock wire to capture its clock -// domain (used when partitioning the module so that `abc9' only -// performs sequential synthesis (with reachability analysis) correctly on -// one domain at a time) +// (b) a special _TECHMAP_REPLACE_.$abc9_clock wire to indicate its clock +// signal, used to extract the delay target // (c) a special _TECHMAP_REPLACE_.$abc9_control that captures the control // domain (which, combined with this cell type, encodes to `abc9' which // flops may be merged together) @@ -88,7 +86,7 @@ module FDRE (output reg Q, input C, CE, D, R); \$__ABC9_FF_ abc_dff (.D($nextQ), .Q(Q)); // Special signals - wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, IS_C_INVERTED}; + wire [0:0] _TECHMAP_REPLACE_.$abc9_clock = C; wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, IS_D_INVERTED, R, IS_R_INVERTED}; wire _TECHMAP_REPLACE_.$abc9_currQ = Q; endmodule @@ -103,7 +101,7 @@ module FDRE_1 (output reg Q, input C, CE, D, R); \$__ABC9_FF_ abc_dff (.D($nextQ), .Q(Q)); // Special signals - wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */}; + wire [0:0] _TECHMAP_REPLACE_.$abc9_clock = C; wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, 1'b0 /* IS_D_INVERTED */, R, 1'b0 /* IS_R_INVERTED */}; wire _TECHMAP_REPLACE_.$abc9_currQ = Q; endmodule @@ -133,7 +131,7 @@ module FDCE (output reg Q, input C, CE, D, CLR); \$__ABC9_ASYNC abc_async (.A($abc9_currQ), .S(CLR ^ IS_CLR_INVERTED), .Y(Q)); // Special signals - wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, IS_C_INVERTED}; + wire [0:0] _TECHMAP_REPLACE_.$abc9_clock = C; wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, IS_D_INVERTED, CLR, IS_CLR_INVERTED}; wire _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ; endmodule @@ -154,7 +152,7 @@ module FDCE_1 (output reg Q, input C, CE, D, CLR); \$__ABC9_ASYNC abc_async (.A($abc9_currQ), .S(CLR), .Y(Q)); // Special signals - wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */}; + wire [0:0] _TECHMAP_REPLACE_.$abc9_clock = C; wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, 1'b0 /* IS_D_INVERTED */, CLR, 1'b0 /* IS_CLR_INVERTED */}; wire _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ; endmodule @@ -182,7 +180,7 @@ module FDPE (output reg Q, input C, CE, D, PRE); \$__ABC9_ASYNC abc_async (.A($abc9_currQ), .S(PRE ^ IS_PRE_INVERTED), .Y(Q)); // Special signals - wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, IS_C_INVERTED}; + wire [0:0] _TECHMAP_REPLACE_.$abc9_clock = C; wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, IS_D_INVERTED, PRE, IS_PRE_INVERTED}; wire _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ; endmodule @@ -203,7 +201,7 @@ module FDPE_1 (output reg Q, input C, CE, D, PRE); \$__ABC9_ASYNC abc_async (.A($abc9_currQ), .S(PRE), .Y(Q)); // Special signals - wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */}; + wire [0:0] _TECHMAP_REPLACE_.$abc9_clock = C; wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, 1'b0 /* IS_D_INVERTED */, PRE, 1'b0 /* IS_PRE_INVERTED */}; wire _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ; endmodule @@ -225,7 +223,7 @@ module FDSE (output reg Q, input C, CE, D, S); \$__ABC9_FF_ abc_dff (.D($nextQ), .Q(Q)); // Special signals - wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, IS_C_INVERTED}; + wire [0:0] _TECHMAP_REPLACE_.$abc9_clock = C; wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, IS_D_INVERTED, S, IS_S_INVERTED}; wire _TECHMAP_REPLACE_.$abc9_currQ = Q; endmodule @@ -240,7 +238,7 @@ module FDSE_1 (output reg Q, input C, CE, D, S); \$__ABC9_FF_ abc_dff (.D($nextQ), .Q(Q)); // Special signals - wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */}; + wire [0:0] _TECHMAP_REPLACE_.$abc9_clock = C; wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, 1'b0 /* IS_D_INVERTED */, S, 1'b0 /* IS_S_INVERTED */}; wire _TECHMAP_REPLACE_.$abc9_currQ = Q; endmodule -- cgit v1.2.3 From 6831510f5b436ddf05b8a1cb30b52be67f865de0 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 25 Nov 2019 12:59:34 -0800 Subject: Fix debug --- passes/techmap/abc9.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 2409f3d91..193103747 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -347,10 +347,10 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip log_assert(!design->module(ID($__abc9__))); { AigerReader reader(design, ifs, ID($__abc9__), "" /* clk_name */, buffer.c_str() /* map_filename */, true /* wideports */); - reader.parse_xaiger(); + reader.parse_xaiger(box_lookup); } ifs.close(); - Pass::call(design, stringf("write_verilog -noexpr -norename")); + Pass::call_on_module(design, design->module(ID($__abc9__)), stringf("write_verilog -noexpr -norename -selected")); design->remove(design->module(ID($__abc9__))); #endif @@ -421,7 +421,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip ifs.close(); #if 0 - Pass::call(design, stringf("write_verilog -noexpr -norename")); + Pass::call_on_module(design, design->module(ID($__abc9__)), stringf("write_verilog -noexpr -norename -selected")); #endif log_header(design, "Re-integrating ABC9 results.\n"); -- cgit v1.2.3 From 67be62a957c565bfa03f084c8f110d65ca14196b Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 25 Nov 2019 12:04:11 -0800 Subject: clkpart to analyse async flops too --- passes/hierarchy/clkpart.cc | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/passes/hierarchy/clkpart.cc b/passes/hierarchy/clkpart.cc index b79625540..15a5328b9 100644 --- a/passes/hierarchy/clkpart.cc +++ b/passes/hierarchy/clkpart.cc @@ -161,6 +161,14 @@ struct ClkPartPass : public Pass { bool this_en_pol = !enable_mode || cell->type.in(ID($_DFFE_NP_), ID($_DFFE_PP_)); key = clkdomain_t(this_clk_pol, assign_map(cell->getPort(ID(C))), this_en_pol, enable_mode ? assign_map(cell->getPort(ID(E))) : RTLIL::SigSpec()); } + else + if (cell->type.in(ID($_DFF_NN0_), ID($_DFF_NN1_), ID($_DFF_NP0_), ID($_DFF_NP1_), + ID($_DFF_PN0_), ID($_DFF_PN1_), ID($_DFF_PP0_), ID($_DFF_PP1_))) + { + bool this_clk_pol = cell->type.in(ID($_DFF_PN0_), ID($_DFF_PN1_), ID($_DFF_PP0_), ID($_DFF_PP1_)); + log_assert(!enable_mode); // TODO + key = clkdomain_t(this_clk_pol, assign_map(cell->getPort(ID(C))), true, RTLIL::SigSpec()); + } else continue; -- cgit v1.2.3 From 7f0914a40896b566a8b1e139438bd585a9ae2b4b Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 25 Nov 2019 15:42:07 -0800 Subject: Do not sigmap keep bits inside write_xaiger --- backends/aiger/xaiger.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index de2f7dd73..763a14909 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -183,7 +183,7 @@ struct XAigerWriter } if (keep) - keep_bits.insert(bit); + keep_bits.insert(wirebit); if (wire->port_input || keep) { if (bit != wirebit) -- cgit v1.2.3 From da51492dbcc9f19a4808ef18e8ae1222bc55b118 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 25 Nov 2019 15:43:37 -0800 Subject: Fold loop --- backends/aiger/xaiger.cc | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 763a14909..37ef30522 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -189,6 +189,7 @@ struct XAigerWriter if (bit != wirebit) alias_map[bit] = wirebit; input_bits.insert(wirebit); + undriven_bits.erase(bit); } if (wire->port_output || keep) { @@ -196,6 +197,8 @@ struct XAigerWriter if (bit != wirebit) alias_map[wirebit] = bit; output_bits.insert(wirebit); + if (!wire->port_input) + unused_bits.erase(bit); } else log_debug("Skipping PO '%s' driven by 1'bx\n", log_signal(wirebit)); @@ -203,12 +206,6 @@ struct XAigerWriter } } - for (auto bit : input_bits) - undriven_bits.erase(sigmap(bit)); - for (auto bit : output_bits) - if (!bit.wire->port_input) - unused_bits.erase(bit); - // TODO: Speed up toposort -- ultimately we care about // box ordering, but not individual AIG cells dict> bit_drivers, bit_users; -- cgit v1.2.3 From dd317c92808a73e61e771a123fc4377d3fb78af2 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 25 Nov 2019 16:07:35 -0800 Subject: Add testcase where \init is copied --- tests/various/submod.ys | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/tests/various/submod.ys b/tests/various/submod.ys index 7c6f555ac..f50556d76 100644 --- a/tests/various/submod.ys +++ b/tests/various/submod.ys @@ -48,3 +48,21 @@ design -import gate -as gate miter -equiv -flatten -make_assert -make_outputs gold gate miter sat -verify -prove-asserts -show-ports miter + + +design -reset +read_verilog -icells < Date: Mon, 25 Nov 2019 16:07:47 -0800 Subject: Move \init from source wire to submod if output port --- passes/hierarchy/submod.cc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/passes/hierarchy/submod.cc b/passes/hierarchy/submod.cc index 212932e46..7952c2dd6 100644 --- a/passes/hierarchy/submod.cc +++ b/passes/hierarchy/submod.cc @@ -162,6 +162,13 @@ struct SubmodWorker new_wire->port_input = new_wire_port_input; new_wire->port_output = new_wire_port_output; new_wire->attributes = wire->attributes; + if (new_wire->port_output) { + auto it = wire->attributes.find(ID(init)); + if (it != wire->attributes.end()) { + new_wire->attributes[ID(init)] = it->second[bit.offset]; + it->second[bit.offset] = State::Sx; + } + } if (new_wire->port_input && new_wire->port_output) log(" signal %s: inout %s\n", wire->name.c_str(), new_wire->name.c_str()); -- cgit v1.2.3 From eb666b46777877bfd723b7dc7fb36e717b66bfdd Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 26 Nov 2019 11:12:58 -0800 Subject: Update docs with bullet points --- passes/hierarchy/submod.cc | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/passes/hierarchy/submod.cc b/passes/hierarchy/submod.cc index 7952c2dd6..ae80f09a8 100644 --- a/passes/hierarchy/submod.cc +++ b/passes/hierarchy/submod.cc @@ -296,7 +296,7 @@ struct SubmodPass : public Pass { { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); - log(" submod [-copy] [selection]\n"); + log(" submod [options] [selection]\n"); log("\n"); log("This pass identifies all cells with the 'submod' attribute and moves them to\n"); log("a newly created module. The value of the attribute is used as name for the\n"); @@ -308,16 +308,15 @@ struct SubmodPass : public Pass { log("This pass only operates on completely selected modules with no processes\n"); log("or memories.\n"); log("\n"); + log(" -copy\n"); + log(" by default the cells are 'moved' from the source module and the source\n"); + log(" module will use an instance of the new module after this command is\n"); + log(" finished. call with -copy to not modify the source module.\n"); log("\n"); - log(" submod -name [-copy] [selection]\n"); - log("\n"); - log("As above, but don't use the 'submod' attribute but instead use the selection.\n"); - log("Only objects from one module might be selected. The value of the -name option\n"); - log("is used as the value of the 'submod' attribute above.\n"); - log("\n"); - log("By default the cells are 'moved' from the source module and the source module\n"); - log("will use an instance of the new module after this command is finished. Call\n"); - log("with -copy to not modify the source module.\n"); + log(" -name \n"); + log(" don't use the 'submod' attribute but instead use the selection. only\n"); + log(" objects from one module might be selected. the value of the -name option\n"); + log(" is used as the value of the 'submod' attribute instead.\n"); log("\n"); } void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE -- cgit v1.2.3 From e8aa92ca35f63612133def8b823ef17f396f0c0c Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 26 Nov 2019 11:35:15 -0800 Subject: Add -hidden option to submod --- passes/hierarchy/submod.cc | 60 ++++++++++++++++++++++++++++++---------------- 1 file changed, 40 insertions(+), 20 deletions(-) diff --git a/passes/hierarchy/submod.cc b/passes/hierarchy/submod.cc index 212932e46..118a65301 100644 --- a/passes/hierarchy/submod.cc +++ b/passes/hierarchy/submod.cc @@ -37,6 +37,7 @@ struct SubmodWorker pool outputs; bool copy_mode; + bool hidden_mode; std::string opt_name; struct SubModule @@ -149,19 +150,29 @@ struct SubmodWorker else new_wire_name = stringf("%s[%d]", wire->name.c_str(), bit.offset); if (new_wire_port_input || new_wire_port_output) { - while (new_wire_name[0] == '$') { - std::string next_wire_name = stringf("\\n%d", auto_name_counter++); - if (all_wire_names.count(next_wire_name) == 0) { - all_wire_names.insert(next_wire_name); - new_wire_name = next_wire_name; - } - } + if (new_wire_name[0] == '$') + do { + std::string next_wire_name = stringf("%s\\n%d", hidden_mode ? "$submod" : ":", auto_name_counter++); + if (all_wire_names.count(next_wire_name) == 0) { + all_wire_names.insert(next_wire_name); + new_wire_name = next_wire_name; + } + } while (new_wire_name[0] == '$'); + else + new_wire_name = stringf("$submod%s\n", new_wire_name.c_str()); } RTLIL::Wire *new_wire = new_mod->addWire(new_wire_name); new_wire->port_input = new_wire_port_input; new_wire->port_output = new_wire_port_output; new_wire->attributes = wire->attributes; + if (new_wire->port_output) { + auto it = wire->attributes.find(ID(init)); + if (it != wire->attributes.end()) { + new_wire->attributes[ID(init)] = it->second[bit.offset]; + it->second[bit.offset] = State::Sx; + } + } if (new_wire->port_input && new_wire->port_output) log(" signal %s: inout %s\n", wire->name.c_str(), new_wire->name.c_str()); @@ -204,8 +215,8 @@ struct SubmodWorker } } - SubmodWorker(RTLIL::Design *design, RTLIL::Module *module, bool copy_mode = false, std::string opt_name = std::string()) : - design(design), module(module), sigmap(module), copy_mode(copy_mode), opt_name(opt_name) + SubmodWorker(RTLIL::Design *design, RTLIL::Module *module, bool copy_mode = false, bool hidden_mode = false, std::string opt_name = std::string()) : + design(design), module(module), sigmap(module), copy_mode(copy_mode), hidden_mode(hidden_mode), opt_name(opt_name) { if (!design->selected_whole_module(module->name) && opt_name.empty()) return; @@ -289,7 +300,7 @@ struct SubmodPass : public Pass { { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); - log(" submod [-copy] [selection]\n"); + log(" submod [options] [selection]\n"); log("\n"); log("This pass identifies all cells with the 'submod' attribute and moves them to\n"); log("a newly created module. The value of the attribute is used as name for the\n"); @@ -301,16 +312,20 @@ struct SubmodPass : public Pass { log("This pass only operates on completely selected modules with no processes\n"); log("or memories.\n"); log("\n"); + log(" -copy\n"); + log(" by default the cells are 'moved' from the source module and the source\n"); + log(" module will use an instance of the new module after this command is\n"); + log(" finished. call with -copy to not modify the source module.\n"); log("\n"); - log(" submod -name [-copy] [selection]\n"); + log(" -name \n"); + log(" don't use the 'submod' attribute but instead use the selection. only\n"); + log(" objects from one module might be selected. the value of the -name option\n"); + log(" is used as the value of the 'submod' attribute instead.\n"); log("\n"); - log("As above, but don't use the 'submod' attribute but instead use the selection.\n"); - log("Only objects from one module might be selected. The value of the -name option\n"); - log("is used as the value of the 'submod' attribute above.\n"); - log("\n"); - log("By default the cells are 'moved' from the source module and the source module\n"); - log("will use an instance of the new module after this command is finished. Call\n"); - log("with -copy to not modify the source module.\n"); + log(" -hidden\n"); + log(" instead of creating submodule ports with public names, create ports with\n"); + log(" private names so that a subsequent 'flatten; clean' call will restore the\n"); + log(" original module with original public names.\n"); log("\n"); } void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE @@ -320,6 +335,7 @@ struct SubmodPass : public Pass { std::string opt_name; bool copy_mode = false; + bool hidden_mode = false; size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) { @@ -331,6 +347,10 @@ struct SubmodPass : public Pass { copy_mode = true; continue; } + if (args[argidx] == "-hidden") { + hidden_mode = true; + continue; + } break; } extra_args(args, argidx, design); @@ -351,7 +371,7 @@ struct SubmodPass : public Pass { queued_modules.push_back(mod_it.first); for (auto &modname : queued_modules) if (design->modules_.count(modname) != 0) { - SubmodWorker worker(design, design->modules_[modname], copy_mode); + SubmodWorker worker(design, design->modules_[modname], copy_mode, hidden_mode); handled_modules.insert(modname); did_something = true; } @@ -374,7 +394,7 @@ struct SubmodPass : public Pass { else { Pass::call_on_module(design, module, "opt_clean"); log_header(design, "Continuing SUBMOD pass.\n"); - SubmodWorker worker(design, module, copy_mode, opt_name); + SubmodWorker worker(design, module, copy_mode, hidden_mode, opt_name); } } -- cgit v1.2.3 From 3027f015c2f4dc91650af0dba224585a1a9d0b9f Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 26 Nov 2019 11:35:32 -0800 Subject: clkpart to use 'submod -hidden' --- passes/hierarchy/clkpart.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/hierarchy/clkpart.cc b/passes/hierarchy/clkpart.cc index 15a5328b9..81983e226 100644 --- a/passes/hierarchy/clkpart.cc +++ b/passes/hierarchy/clkpart.cc @@ -278,7 +278,7 @@ struct ClkPartPass : public Pass { } } - Pass::call(design, "submod"); + Pass::call(design, "submod -hidden"); if (!attr_name.empty()) for (auto m : new_submods) -- cgit v1.2.3 From 09637dd3e454784cba695496fc94be313e4d8522 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 26 Nov 2019 11:57:26 -0800 Subject: Fix submod -hidden --- passes/hierarchy/submod.cc | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/passes/hierarchy/submod.cc b/passes/hierarchy/submod.cc index 118a65301..14974666e 100644 --- a/passes/hierarchy/submod.cc +++ b/passes/hierarchy/submod.cc @@ -151,15 +151,16 @@ struct SubmodWorker new_wire_name = stringf("%s[%d]", wire->name.c_str(), bit.offset); if (new_wire_port_input || new_wire_port_output) { if (new_wire_name[0] == '$') - do { - std::string next_wire_name = stringf("%s\\n%d", hidden_mode ? "$submod" : ":", auto_name_counter++); + while (1) { + std::string next_wire_name = stringf("%s\\n%d", hidden_mode ? "$submod" : "", auto_name_counter++); if (all_wire_names.count(next_wire_name) == 0) { all_wire_names.insert(next_wire_name); new_wire_name = next_wire_name; + break; } - } while (new_wire_name[0] == '$'); - else - new_wire_name = stringf("$submod%s\n", new_wire_name.c_str()); + } + else if (hidden_mode) + new_wire_name = stringf("$submod%s", new_wire_name.c_str()); } RTLIL::Wire *new_wire = new_mod->addWire(new_wire_name); -- cgit v1.2.3 From 739f5309062f6e60809a2ebe4eda4602cca6fc41 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 26 Nov 2019 14:51:39 -0800 Subject: Move 'clean' from map_luts to finalize --- techlibs/xilinx/synth_xilinx.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index 7105ba429..6e8ced0df 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -560,7 +560,6 @@ struct SynthXilinxPass : public ScriptPass else techmap_args += " -map " + ff_map_file; run("techmap " + techmap_args); - run("clean"); } if (check_label("finalize")) { @@ -575,6 +574,7 @@ struct SynthXilinxPass : public ScriptPass run("iopadmap -bits -outpad OBUF I:O -inpad IBUF O:I A:top", "(only if '-iopad' or '-ise' and not '-noiopad')"); if (help_mode || ise) run("extractinv -inv INV O:I", "(only if '-ise')"); + run("clean"); } if (check_label("check")) { -- cgit v1.2.3 From 99702efabae4005970bdbae4bbb34c39fdd4c46d Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 26 Nov 2019 19:03:02 -0800 Subject: xaiger: do not promote output wires --- backends/aiger/xaiger.cc | 5 ----- 1 file changed, 5 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 37ef30522..f17a4c775 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -155,11 +155,6 @@ struct XAigerWriter if (wire->port_input) sigmap.add(wire); - // promote output wires - for (auto wire : module->wires()) - if (wire->port_output) - sigmap.add(wire); - for (auto wire : module->wires()) { if (wire->attributes.count("\\init")) { -- cgit v1.2.3 From 435d33c37307563f193b8c798ad46ebb19cf4f07 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 26 Nov 2019 11:35:15 -0800 Subject: Add -hidden option to submod --- passes/hierarchy/submod.cc | 36 +++++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/passes/hierarchy/submod.cc b/passes/hierarchy/submod.cc index ae80f09a8..118a65301 100644 --- a/passes/hierarchy/submod.cc +++ b/passes/hierarchy/submod.cc @@ -37,6 +37,7 @@ struct SubmodWorker pool outputs; bool copy_mode; + bool hidden_mode; std::string opt_name; struct SubModule @@ -149,13 +150,16 @@ struct SubmodWorker else new_wire_name = stringf("%s[%d]", wire->name.c_str(), bit.offset); if (new_wire_port_input || new_wire_port_output) { - while (new_wire_name[0] == '$') { - std::string next_wire_name = stringf("\\n%d", auto_name_counter++); - if (all_wire_names.count(next_wire_name) == 0) { - all_wire_names.insert(next_wire_name); - new_wire_name = next_wire_name; - } - } + if (new_wire_name[0] == '$') + do { + std::string next_wire_name = stringf("%s\\n%d", hidden_mode ? "$submod" : ":", auto_name_counter++); + if (all_wire_names.count(next_wire_name) == 0) { + all_wire_names.insert(next_wire_name); + new_wire_name = next_wire_name; + } + } while (new_wire_name[0] == '$'); + else + new_wire_name = stringf("$submod%s\n", new_wire_name.c_str()); } RTLIL::Wire *new_wire = new_mod->addWire(new_wire_name); @@ -211,8 +215,8 @@ struct SubmodWorker } } - SubmodWorker(RTLIL::Design *design, RTLIL::Module *module, bool copy_mode = false, std::string opt_name = std::string()) : - design(design), module(module), sigmap(module), copy_mode(copy_mode), opt_name(opt_name) + SubmodWorker(RTLIL::Design *design, RTLIL::Module *module, bool copy_mode = false, bool hidden_mode = false, std::string opt_name = std::string()) : + design(design), module(module), sigmap(module), copy_mode(copy_mode), hidden_mode(hidden_mode), opt_name(opt_name) { if (!design->selected_whole_module(module->name) && opt_name.empty()) return; @@ -318,6 +322,11 @@ struct SubmodPass : public Pass { log(" objects from one module might be selected. the value of the -name option\n"); log(" is used as the value of the 'submod' attribute instead.\n"); log("\n"); + log(" -hidden\n"); + log(" instead of creating submodule ports with public names, create ports with\n"); + log(" private names so that a subsequent 'flatten; clean' call will restore the\n"); + log(" original module with original public names.\n"); + log("\n"); } void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE { @@ -326,6 +335,7 @@ struct SubmodPass : public Pass { std::string opt_name; bool copy_mode = false; + bool hidden_mode = false; size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) { @@ -337,6 +347,10 @@ struct SubmodPass : public Pass { copy_mode = true; continue; } + if (args[argidx] == "-hidden") { + hidden_mode = true; + continue; + } break; } extra_args(args, argidx, design); @@ -357,7 +371,7 @@ struct SubmodPass : public Pass { queued_modules.push_back(mod_it.first); for (auto &modname : queued_modules) if (design->modules_.count(modname) != 0) { - SubmodWorker worker(design, design->modules_[modname], copy_mode); + SubmodWorker worker(design, design->modules_[modname], copy_mode, hidden_mode); handled_modules.insert(modname); did_something = true; } @@ -380,7 +394,7 @@ struct SubmodPass : public Pass { else { Pass::call_on_module(design, module, "opt_clean"); log_header(design, "Continuing SUBMOD pass.\n"); - SubmodWorker worker(design, module, copy_mode, opt_name); + SubmodWorker worker(design, module, copy_mode, hidden_mode, opt_name); } } -- cgit v1.2.3 From 5e487b103c3c1ed9f1fcaca21821466628b7ff80 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 26 Nov 2019 11:57:26 -0800 Subject: Fix submod -hidden --- passes/hierarchy/submod.cc | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/passes/hierarchy/submod.cc b/passes/hierarchy/submod.cc index 118a65301..14974666e 100644 --- a/passes/hierarchy/submod.cc +++ b/passes/hierarchy/submod.cc @@ -151,15 +151,16 @@ struct SubmodWorker new_wire_name = stringf("%s[%d]", wire->name.c_str(), bit.offset); if (new_wire_port_input || new_wire_port_output) { if (new_wire_name[0] == '$') - do { - std::string next_wire_name = stringf("%s\\n%d", hidden_mode ? "$submod" : ":", auto_name_counter++); + while (1) { + std::string next_wire_name = stringf("%s\\n%d", hidden_mode ? "$submod" : "", auto_name_counter++); if (all_wire_names.count(next_wire_name) == 0) { all_wire_names.insert(next_wire_name); new_wire_name = next_wire_name; + break; } - } while (new_wire_name[0] == '$'); - else - new_wire_name = stringf("$submod%s\n", new_wire_name.c_str()); + } + else if (hidden_mode) + new_wire_name = stringf("$submod%s", new_wire_name.c_str()); } RTLIL::Wire *new_wire = new_mod->addWire(new_wire_name); -- cgit v1.2.3 From 6318e3ce6df2484c4cc17856608e2a6354cd643a Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 26 Nov 2019 23:38:49 -0800 Subject: Fix wire width --- tests/various/submod.ys | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/various/submod.ys b/tests/various/submod.ys index f50556d76..a0a3f2da5 100644 --- a/tests/various/submod.ys +++ b/tests/various/submod.ys @@ -1,8 +1,8 @@ read_verilog < Date: Tue, 26 Nov 2019 23:39:14 -0800 Subject: Promote output wires in sigmap so that can be detected --- passes/hierarchy/submod.cc | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/passes/hierarchy/submod.cc b/passes/hierarchy/submod.cc index 14974666e..f23dfb702 100644 --- a/passes/hierarchy/submod.cc +++ b/passes/hierarchy/submod.cc @@ -34,7 +34,6 @@ struct SubmodWorker RTLIL::Design *design; RTLIL::Module *module; SigMap sigmap; - pool outputs; bool copy_mode; bool hidden_mode; @@ -124,13 +123,13 @@ struct SubmodWorker for (auto &it : bit_flags) { - const RTLIL::SigBit &bit = it.first; + const RTLIL::SigBit &bit = sigmap(it.first); RTLIL::Wire *wire = bit.wire; bit_flags_t &flags = it.second; if (wire->port_input) flags.is_ext_driven = true; - if (outputs.count(bit)) + if (wire->port_output) flags.is_ext_used = true; bool new_wire_port_input = false; @@ -240,11 +239,8 @@ struct SubmodWorker for (auto port : module->ports) { auto wire = module->wire(port); - if (!wire->port_output) - continue; - for (auto b : sigmap(wire)) - if (b.wire) - outputs.insert(b); + if (wire->port_output) + sigmap.add(wire); } if (opt_name.empty()) -- cgit v1.2.3 From 8c813632b6c1557f5123ea0cece2738fad40b89b Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 27 Nov 2019 00:48:22 -0800 Subject: Revert "submod to bitty rather bussy, for bussy wires used as input and output" This reverts commit cba3073026711e7683c46ba091c56a5c5a041a45. --- passes/hierarchy/submod.cc | 111 +++++++++++++++++++++++++++++---------------- tests/various/submod.ys | 7 ++- 2 files changed, 76 insertions(+), 42 deletions(-) diff --git a/passes/hierarchy/submod.cc b/passes/hierarchy/submod.cc index f23dfb702..238e1f43f 100644 --- a/passes/hierarchy/submod.cc +++ b/passes/hierarchy/submod.cc @@ -34,6 +34,7 @@ struct SubmodWorker RTLIL::Design *design; RTLIL::Module *module; SigMap sigmap; + std::map replace_const; bool copy_mode; bool hidden_mode; @@ -47,44 +48,51 @@ struct SubmodWorker std::map submodules; - struct bit_flags_t { + struct wire_flags_t { RTLIL::Wire *new_wire; - bool is_int_driven, is_int_used, is_ext_driven, is_ext_used; - bit_flags_t() : new_wire(NULL), is_int_driven(false), is_int_used(false), is_ext_driven(false), is_ext_used(false) { } + RTLIL::Const is_int_driven; + bool is_int_used, is_ext_driven, is_ext_used; + wire_flags_t(RTLIL::Wire* wire) : new_wire(NULL), is_int_driven(State::S0, GetSize(wire)), is_int_used(false), is_ext_driven(false), is_ext_used(false) { } }; - std::map bit_flags; + std::map wire_flags; bool flag_found_something; - void flag_bit(RTLIL::SigBit bit, bool create, bool set_int_driven, bool set_int_used, bool set_ext_driven, bool set_ext_used) + void flag_wire(RTLIL::Wire *wire, bool create, bool /*set_int_driven*/, bool set_int_used, bool set_ext_driven, bool set_ext_used) { - if (bit_flags.count(bit) == 0) { + if (wire_flags.count(wire) == 0) { if (!create) return; - bit_flags[bit] = bit_flags_t(); + wire_flags.emplace(wire, wire_flags_t(wire)); } - if (set_int_driven) - bit_flags[bit].is_int_driven = true; + //if (set_int_driven) + // wire_flags[wire].is_int_driven = true; if (set_int_used) - bit_flags[bit].is_int_used = true; + wire_flags.at(wire).is_int_used = true; if (set_ext_driven) - bit_flags[bit].is_ext_driven = true; + wire_flags.at(wire).is_ext_driven = true; if (set_ext_used) - bit_flags[bit].is_ext_used = true; + wire_flags.at(wire).is_ext_used = true; flag_found_something = true; } void flag_signal(const RTLIL::SigSpec &sig, bool create, bool set_int_driven, bool set_int_used, bool set_ext_driven, bool set_ext_used) { - for (auto &b : sig) - if (b.wire != NULL) - flag_bit(b, create, set_int_driven, set_int_used, set_ext_driven, set_ext_used); + for (auto &c : sig.chunks()) + if (c.wire != NULL) { + flag_wire(c.wire, create, set_int_driven, set_int_used, set_ext_driven, set_ext_used); + if (set_int_driven) + for (int i = c.offset; i < c.offset+c.width; i++) { + wire_flags.at(c.wire).is_int_driven[i] = State::S1; + flag_found_something = true; + } + } } void handle_submodule(SubModule &submod) { log("Creating submodule %s (%s) of module %s.\n", submod.name.c_str(), submod.full_name.c_str(), module->name.c_str()); - bit_flags.clear(); + wire_flags.clear(); for (RTLIL::Cell *cell : submod.cells) { if (ct.cell_known(cell->type)) { for (auto &conn : cell->connections()) @@ -117,37 +125,40 @@ struct SubmodWorker int auto_name_counter = 1; std::set all_wire_names; - for (auto &it : bit_flags) { - all_wire_names.insert(it.first.wire->name); + for (auto &it : wire_flags) { + all_wire_names.insert(it.first->name); } - for (auto &it : bit_flags) + for (auto &it : wire_flags) { - const RTLIL::SigBit &bit = sigmap(it.first); - RTLIL::Wire *wire = bit.wire; - bit_flags_t &flags = it.second; + RTLIL::Wire *wire = it.first; + wire_flags_t &flags = it.second; if (wire->port_input) flags.is_ext_driven = true; if (wire->port_output) flags.is_ext_used = true; + else { + auto sig = sigmap(wire); + for (auto c : sig.chunks()) + if (c.wire->port_output) { + flags.is_ext_used = true; + break; + } + } bool new_wire_port_input = false; bool new_wire_port_output = false; - if (flags.is_int_driven && flags.is_ext_used) + if (!flags.is_int_driven.is_fully_zero() && flags.is_ext_used) new_wire_port_output = true; if (flags.is_ext_driven && flags.is_int_used) new_wire_port_input = true; - if (flags.is_int_driven && flags.is_ext_driven) + if (!flags.is_int_driven.is_fully_zero() && flags.is_ext_driven) new_wire_port_input = true, new_wire_port_output = true; - RTLIL::IdString new_wire_name; - if (GetSize(wire) == 1) - new_wire_name = wire->name; - else - new_wire_name = stringf("%s[%d]", wire->name.c_str(), bit.offset); + std::string new_wire_name = wire->name.str(); if (new_wire_port_input || new_wire_port_output) { if (new_wire_name[0] == '$') while (1) { @@ -162,15 +173,26 @@ struct SubmodWorker new_wire_name = stringf("$submod%s", new_wire_name.c_str()); } - RTLIL::Wire *new_wire = new_mod->addWire(new_wire_name); + RTLIL::Wire *new_wire = new_mod->addWire(new_wire_name, wire->width); new_wire->port_input = new_wire_port_input; new_wire->port_output = new_wire_port_output; + new_wire->start_offset = wire->start_offset; new_wire->attributes = wire->attributes; if (new_wire->port_output) { - auto it = wire->attributes.find(ID(init)); - if (it != wire->attributes.end()) { - new_wire->attributes[ID(init)] = it->second[bit.offset]; - it->second[bit.offset] = State::Sx; + new_wire->attributes.erase(ID(init)); + auto sig = sigmap(wire); + for (int i = 0; i < GetSize(sig); i++) { + if (flags.is_int_driven[i] == State::S0) + continue; + log_dump(i, flags.is_int_driven[i]); + if (!sig[i].wire) + continue; + auto it = sig[i].wire->attributes.find(ID(init)); + if (it != sig[i].wire->attributes.end()) { + auto jt = new_wire->attributes.insert(std::make_pair(ID(init), Const(State::Sx, GetSize(sig)))).first; + jt->second[i] = it->second[sig[i].offset]; + it->second[sig[i].offset] = State::Sx; + } } } @@ -194,8 +216,8 @@ struct SubmodWorker for (auto &conn : new_cell->connections_) for (auto &bit : conn.second) if (bit.wire != NULL) { - log_assert(bit_flags.count(bit) > 0); - bit = bit_flags[bit].new_wire; + log_assert(wire_flags.count(bit.wire) > 0); + bit.wire = wire_flags.at(bit.wire).new_wire; } log(" cell %s (%s)\n", new_cell->name.c_str(), new_cell->type.c_str()); if (!copy_mode) @@ -205,12 +227,16 @@ struct SubmodWorker if (!copy_mode) { RTLIL::Cell *new_cell = module->addCell(submod.full_name, submod.full_name); - for (auto &it : bit_flags) + for (auto &it : wire_flags) { - RTLIL::SigBit old_bit = it.first; + RTLIL::SigSpec old_sig = sigmap(it.first); RTLIL::Wire *new_wire = it.second.new_wire; - if (new_wire->port_id > 0) - new_cell->setPort(new_wire->name, old_bit); + if (new_wire->port_id > 0) { + // Prevents "ERROR: Mismatch in directionality ..." when flattening + if (new_wire->port_output) + old_sig.replace(replace_const); + new_cell->setPort(new_wire->name, old_sig); + } } } } @@ -242,6 +268,11 @@ struct SubmodWorker if (wire->port_output) sigmap.add(wire); } + auto wire = module->addWire(NEW_ID); + replace_const.emplace(State::S0, wire); + replace_const.emplace(State::S1, wire); + replace_const.emplace(State::Sx, wire); + replace_const.emplace(State::Sz, wire); if (opt_name.empty()) { diff --git a/tests/various/submod.ys b/tests/various/submod.ys index a0a3f2da5..552fd4e01 100644 --- a/tests/various/submod.ys +++ b/tests/various/submod.ys @@ -52,8 +52,10 @@ sat -verify -prove-asserts -show-ports miter design -reset read_verilog -icells < Date: Wed, 27 Nov 2019 00:50:25 -0800 Subject: Stray log_dump --- passes/hierarchy/submod.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/passes/hierarchy/submod.cc b/passes/hierarchy/submod.cc index 238e1f43f..349483778 100644 --- a/passes/hierarchy/submod.cc +++ b/passes/hierarchy/submod.cc @@ -184,7 +184,6 @@ struct SubmodWorker for (int i = 0; i < GetSize(sig); i++) { if (flags.is_int_driven[i] == State::S0) continue; - log_dump(i, flags.is_int_driven[i]); if (!sig[i].wire) continue; auto it = sig[i].wire->attributes.find(ID(init)); -- cgit v1.2.3 From cb05fe0f70039077bdc1c72f0e2121be6eb7835b Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 27 Nov 2019 00:51:39 -0800 Subject: Check for nullptr --- passes/hierarchy/submod.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/hierarchy/submod.cc b/passes/hierarchy/submod.cc index 349483778..7b5e110cb 100644 --- a/passes/hierarchy/submod.cc +++ b/passes/hierarchy/submod.cc @@ -141,7 +141,7 @@ struct SubmodWorker else { auto sig = sigmap(wire); for (auto c : sig.chunks()) - if (c.wire->port_output) { + if (c.wire && c.wire->port_output) { flags.is_ext_used = true; break; } -- cgit v1.2.3 From c7aa2c6b79243201d076b6e71a461865610c9e8b Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 27 Nov 2019 01:01:24 -0800 Subject: Cleanup --- passes/hierarchy/submod.cc | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/passes/hierarchy/submod.cc b/passes/hierarchy/submod.cc index 7b5e110cb..cf27d2358 100644 --- a/passes/hierarchy/submod.cc +++ b/passes/hierarchy/submod.cc @@ -57,15 +57,13 @@ struct SubmodWorker std::map wire_flags; bool flag_found_something; - void flag_wire(RTLIL::Wire *wire, bool create, bool /*set_int_driven*/, bool set_int_used, bool set_ext_driven, bool set_ext_used) + void flag_wire(RTLIL::Wire *wire, bool create, bool set_int_used, bool set_ext_driven, bool set_ext_used) { if (wire_flags.count(wire) == 0) { if (!create) return; - wire_flags.emplace(wire, wire_flags_t(wire)); + wire_flags.emplace(wire, wire); } - //if (set_int_driven) - // wire_flags[wire].is_int_driven = true; if (set_int_used) wire_flags.at(wire).is_int_used = true; if (set_ext_driven) @@ -79,7 +77,7 @@ struct SubmodWorker { for (auto &c : sig.chunks()) if (c.wire != NULL) { - flag_wire(c.wire, create, set_int_driven, set_int_used, set_ext_driven, set_ext_used); + flag_wire(c.wire, create, set_int_used, set_ext_driven, set_ext_used); if (set_int_driven) for (int i = c.offset; i < c.offset+c.width; i++) { wire_flags.at(c.wire).is_int_driven[i] = State::S1; -- cgit v1.2.3 From 1c0ee4f786a77d8557c9dd462abc54982b7b639d Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 27 Nov 2019 08:18:41 -0800 Subject: Do not replace constants with same wire --- passes/hierarchy/submod.cc | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/passes/hierarchy/submod.cc b/passes/hierarchy/submod.cc index cf27d2358..b21b0de01 100644 --- a/passes/hierarchy/submod.cc +++ b/passes/hierarchy/submod.cc @@ -34,7 +34,6 @@ struct SubmodWorker RTLIL::Design *design; RTLIL::Module *module; SigMap sigmap; - std::map replace_const; bool copy_mode; bool hidden_mode; @@ -231,7 +230,9 @@ struct SubmodWorker if (new_wire->port_id > 0) { // Prevents "ERROR: Mismatch in directionality ..." when flattening if (new_wire->port_output) - old_sig.replace(replace_const); + for (auto &b : old_sig) + if (!b.wire) + b = module->addWire(NEW_ID); new_cell->setPort(new_wire->name, old_sig); } } @@ -265,11 +266,6 @@ struct SubmodWorker if (wire->port_output) sigmap.add(wire); } - auto wire = module->addWire(NEW_ID); - replace_const.emplace(State::S0, wire); - replace_const.emplace(State::S1, wire); - replace_const.emplace(State::Sx, wire); - replace_const.emplace(State::Sz, wire); if (opt_name.empty()) { -- cgit v1.2.3 From df8dc6d1fb1f9fc47a8356b5f0bf572a1ea140d2 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 27 Nov 2019 09:10:34 -0800 Subject: ean call after abc{,9} --- techlibs/xilinx/synth_xilinx.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index 6e8ced0df..5bc55387b 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -538,6 +538,7 @@ struct SynthXilinxPass : public ScriptPass else abc9_opts += " -lut +/xilinx/abc9_xc7.lut"; run("abc9" + abc9_opts); + run("clean"); run("clkpart -unpart clkpart"); } else { @@ -545,8 +546,8 @@ struct SynthXilinxPass : public ScriptPass run("abc -luts 2:2,3,6:5" + string(retime ? " -dff" : "")); else run("abc -luts 2:2,3,6:5,10,20" + string(retime ? " -dff" : "")); + run("clean"); } - run("clean"); // This shregmap call infers fixed length shift registers after abc // has performed any necessary retiming -- cgit v1.2.3 From 3a5a65829cc593965304537ddcb4d6d1d3e3ca8b Mon Sep 17 00:00:00 2001 From: Diego H Date: Tue, 26 Nov 2019 17:14:41 -0600 Subject: Adjusting Vivado's BRAM min bits threshold for RAMB18E1 --- techlibs/xilinx/xc7_xcu_brams.txt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/techlibs/xilinx/xc7_xcu_brams.txt b/techlibs/xilinx/xc7_xcu_brams.txt index f1161114e..ee961fff8 100644 --- a/techlibs/xilinx/xc7_xcu_brams.txt +++ b/techlibs/xilinx/xc7_xcu_brams.txt @@ -81,7 +81,7 @@ match $__XILINX_RAMB36_SDP endmatch match $__XILINX_RAMB18_SDP - min bits 4096 + min bits 1024 min efficiency 5 shuffle_enable B make_transp @@ -97,9 +97,12 @@ match $__XILINX_RAMB36_TDP endmatch match $__XILINX_RAMB18_TDP - min bits 4096 + min bits 1024 min efficiency 5 shuffle_enable B make_transp endmatch +# [[CITE]] 7 Series FPGAs Memory Resources User Guide (UG473), +# v1.14 ed., p 29-30, July, 2019. + -- cgit v1.2.3 From 403214f44d8f447ce4e367e2d7e135bfaabcb88d Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 27 Nov 2019 12:35:25 -0800 Subject: Revert "Fold loop" This reverts commit da51492dbcc9f19a4808ef18e8ae1222bc55b118. --- backends/aiger/xaiger.cc | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index f17a4c775..8b809b2e2 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -184,7 +184,6 @@ struct XAigerWriter if (bit != wirebit) alias_map[bit] = wirebit; input_bits.insert(wirebit); - undriven_bits.erase(bit); } if (wire->port_output || keep) { @@ -192,8 +191,6 @@ struct XAigerWriter if (bit != wirebit) alias_map[wirebit] = bit; output_bits.insert(wirebit); - if (!wire->port_input) - unused_bits.erase(bit); } else log_debug("Skipping PO '%s' driven by 1'bx\n", log_signal(wirebit)); @@ -201,6 +198,12 @@ struct XAigerWriter } } + for (auto bit : input_bits) + undriven_bits.erase(sigmap(bit)); + for (auto bit : output_bits) + if (!bit.wire->port_input) + unused_bits.erase(bit); + // TODO: Speed up toposort -- ultimately we care about // box ordering, but not individual AIG cells dict> bit_drivers, bit_users; -- cgit v1.2.3 From 449b1d2c6f3f3dffcb0bd50f4d6398ceb928b114 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 27 Nov 2019 13:20:12 -0800 Subject: Add comment, use sigmap --- backends/aiger/xaiger.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 8b809b2e2..e05b6cc60 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -198,11 +198,11 @@ struct XAigerWriter } } + // Cannot fold into above due to use of sigmap for (auto bit : input_bits) undriven_bits.erase(sigmap(bit)); for (auto bit : output_bits) - if (!bit.wire->port_input) - unused_bits.erase(bit); + unused_bits.erase(sigmap(bit)); // TODO: Speed up toposort -- ultimately we care about // box ordering, but not individual AIG cells -- cgit v1.2.3 From ac5b5e97bcd56a539a02344584011dd985f13f06 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 27 Nov 2019 13:21:59 -0800 Subject: Fix multiple driver issue --- passes/hierarchy/submod.cc | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/passes/hierarchy/submod.cc b/passes/hierarchy/submod.cc index b21b0de01..839f8561c 100644 --- a/passes/hierarchy/submod.cc +++ b/passes/hierarchy/submod.cc @@ -228,11 +228,16 @@ struct SubmodWorker RTLIL::SigSpec old_sig = sigmap(it.first); RTLIL::Wire *new_wire = it.second.new_wire; if (new_wire->port_id > 0) { - // Prevents "ERROR: Mismatch in directionality ..." when flattening if (new_wire->port_output) - for (auto &b : old_sig) + for (int i = 0; i < GetSize(old_sig); i++) { + auto &b = old_sig[i]; + // Prevents "ERROR: Mismatch in directionality ..." when flattening if (!b.wire) b = module->addWire(NEW_ID); + // Prevents "Warning: multiple conflicting drivers ..." + else if (!it.second.is_int_driven[i]) + b = module->addWire(NEW_ID); + } new_cell->setPort(new_wire->name, old_sig); } } -- cgit v1.2.3 From ff1e35768224a7824ec9838ca84d27bbb4a14676 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 27 Nov 2019 13:22:26 -0800 Subject: Add multiple driver testcase --- tests/various/submod.ys | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/tests/various/submod.ys b/tests/various/submod.ys index 552fd4e01..9d7dabdd7 100644 --- a/tests/various/submod.ys +++ b/tests/various/submod.ys @@ -15,6 +15,7 @@ proc design -save gold submod +check -assert design -stash gate design -import gold -as gold @@ -41,6 +42,7 @@ proc design -save gold submod +check -assert top design -stash gate design -import gold -as gold @@ -50,6 +52,35 @@ miter -equiv -flatten -make_assert -make_outputs gold gate miter sat -verify -prove-asserts -show-ports miter +design -reset +read_verilog < Date: Wed, 27 Nov 2019 13:21:59 -0800 Subject: Fix multiple driver issue --- passes/hierarchy/submod.cc | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/passes/hierarchy/submod.cc b/passes/hierarchy/submod.cc index b21b0de01..839f8561c 100644 --- a/passes/hierarchy/submod.cc +++ b/passes/hierarchy/submod.cc @@ -228,11 +228,16 @@ struct SubmodWorker RTLIL::SigSpec old_sig = sigmap(it.first); RTLIL::Wire *new_wire = it.second.new_wire; if (new_wire->port_id > 0) { - // Prevents "ERROR: Mismatch in directionality ..." when flattening if (new_wire->port_output) - for (auto &b : old_sig) + for (int i = 0; i < GetSize(old_sig); i++) { + auto &b = old_sig[i]; + // Prevents "ERROR: Mismatch in directionality ..." when flattening if (!b.wire) b = module->addWire(NEW_ID); + // Prevents "Warning: multiple conflicting drivers ..." + else if (!it.second.is_int_driven[i]) + b = module->addWire(NEW_ID); + } new_cell->setPort(new_wire->name, old_sig); } } -- cgit v1.2.3 From b3a66dff7cac8ee98a9b26463e8858a38ea57f83 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 28 Nov 2019 12:57:36 -0800 Subject: Move \init signal for non-port signals as long as internally driven --- passes/hierarchy/submod.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/hierarchy/submod.cc b/passes/hierarchy/submod.cc index 839f8561c..211f96175 100644 --- a/passes/hierarchy/submod.cc +++ b/passes/hierarchy/submod.cc @@ -175,7 +175,7 @@ struct SubmodWorker new_wire->port_output = new_wire_port_output; new_wire->start_offset = wire->start_offset; new_wire->attributes = wire->attributes; - if (new_wire->port_output) { + if (!flags.is_int_driven.is_fully_zero()) { new_wire->attributes.erase(ID(init)); auto sig = sigmap(wire); for (int i = 0; i < GetSize(sig); i++) { -- cgit v1.2.3 From b1ab7c16c41f0a14b8b14a041367f2259b3c0e37 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 28 Nov 2019 12:59:43 -0800 Subject: clkpart -unpart into 'finalize' --- techlibs/xilinx/synth_xilinx.cc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index 5bc55387b..554c42d68 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -538,16 +538,14 @@ struct SynthXilinxPass : public ScriptPass else abc9_opts += " -lut +/xilinx/abc9_xc7.lut"; run("abc9" + abc9_opts); - run("clean"); - run("clkpart -unpart clkpart"); } else { if (nowidelut) run("abc -luts 2:2,3,6:5" + string(retime ? " -dff" : "")); else run("abc -luts 2:2,3,6:5,10,20" + string(retime ? " -dff" : "")); - run("clean"); } + run("clean"); // This shregmap call infers fixed length shift registers after abc // has performed any necessary retiming @@ -564,6 +562,9 @@ struct SynthXilinxPass : public ScriptPass } if (check_label("finalize")) { + if (help_mode || abc9) + run("clkpart -unpart clkpart", "(only if 'abc9')"); + bool do_iopad = iopad || (ise && !noiopad); if (help_mode || !noclkbuf) { if (help_mode || do_iopad) -- cgit v1.2.3 From 4ac1b92df33d1ef4bbed71216e2b39c4a0651e5b Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Sun, 1 Dec 2019 23:19:32 -0800 Subject: Use pool<> not std::set<> for determinism --- passes/hierarchy/clkpart.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/passes/hierarchy/clkpart.cc b/passes/hierarchy/clkpart.cc index 81983e226..2d295e915 100644 --- a/passes/hierarchy/clkpart.cc +++ b/passes/hierarchy/clkpart.cc @@ -116,11 +116,11 @@ struct ClkPartPass : public Pass { assign_map.set(mod); std::vector all_cells = mod->selected_cells(); - std::set unassigned_cells(all_cells.begin(), all_cells.end()); + pool unassigned_cells(all_cells.begin(), all_cells.end()); - std::set expand_queue, next_expand_queue; - std::set expand_queue_up, next_expand_queue_up; - std::set expand_queue_down, next_expand_queue_down; + pool expand_queue, next_expand_queue; + pool expand_queue_up, next_expand_queue_up; + pool expand_queue_down, next_expand_queue_down; typedef tuple clkdomain_t; std::map> assigned_cells; -- cgit v1.2.3 From 1d87488795e4f898e2fcf6a71259a3972dbe7819 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Sun, 1 Dec 2019 23:26:17 -0800 Subject: Use pool instead of std::set for determinism --- passes/hierarchy/submod.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/hierarchy/submod.cc b/passes/hierarchy/submod.cc index 211f96175..3b4f33a60 100644 --- a/passes/hierarchy/submod.cc +++ b/passes/hierarchy/submod.cc @@ -42,7 +42,7 @@ struct SubmodWorker struct SubModule { std::string name, full_name; - std::set cells; + pool cells; }; std::map submodules; -- cgit v1.2.3 From 6398b7c17c406a502d157d69011b9acb460848ea Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Sun, 1 Dec 2019 23:43:28 -0800 Subject: Cleanup --- passes/techmap/abc9.cc | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 193103747..5a9cbc245 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -1098,7 +1098,7 @@ struct Abc9Pass : public Pass { pool clocks; std::string target = delay_target; - for (auto cell : module->selected_cells()) { + for (auto cell : module->cells()) { auto inst_module = design->module(cell->type); if (!inst_module || !inst_module->attributes.count("\\abc9_flop")) continue; @@ -1119,7 +1119,6 @@ struct Abc9Pass : public Pass { } } - Wire *abc9_control_wire = module->wire(stringf("%s.$abc9_control", cell->name.c_str())); if (abc9_control_wire == NULL) log_error("'%s$abc9_control' is not a wire present in module '%s'.\n", cell->name.c_str(), log_id(module)); @@ -1127,7 +1126,7 @@ struct Abc9Pass : public Pass { ctrldomain_t key(cell->type, abc9_control); auto r = mergeability_class.emplace(key, mergeability_class.size() + 1); - auto YS_ATTRIBUTE(unused) r2 = cell->attributes.insert(std::make_pair(ID(abc9_mergeability), r.first->second)); + auto YS_ATTRIBUTE(unused) r2 = cell->attributes.insert(std::make_pair(ID(abc9_mergeability), r.first->second)); log_assert(r2.second); } -- cgit v1.2.3 From 19bfb4195818be12e6fb962de29ca32444498c22 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 2 Dec 2019 14:17:06 -0800 Subject: Add INIT value to abc9_control --- techlibs/xilinx/abc9_map.v | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/techlibs/xilinx/abc9_map.v b/techlibs/xilinx/abc9_map.v index 29ddf7133..b8defcb64 100644 --- a/techlibs/xilinx/abc9_map.v +++ b/techlibs/xilinx/abc9_map.v @@ -87,7 +87,7 @@ module FDRE (output reg Q, input C, CE, D, R); // Special signals wire [0:0] _TECHMAP_REPLACE_.$abc9_clock = C; - wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, IS_D_INVERTED, R, IS_R_INVERTED}; + wire [4:0] _TECHMAP_REPLACE_.$abc9_control = {INIT, CE, IS_D_INVERTED, R, IS_R_INVERTED}; wire _TECHMAP_REPLACE_.$abc9_currQ = Q; endmodule module FDRE_1 (output reg Q, input C, CE, D, R); @@ -102,7 +102,7 @@ module FDRE_1 (output reg Q, input C, CE, D, R); // Special signals wire [0:0] _TECHMAP_REPLACE_.$abc9_clock = C; - wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, 1'b0 /* IS_D_INVERTED */, R, 1'b0 /* IS_R_INVERTED */}; + wire [4:0] _TECHMAP_REPLACE_.$abc9_control = {INIT, CE, 1'b0 /* IS_D_INVERTED */, R, 1'b0 /* IS_R_INVERTED */}; wire _TECHMAP_REPLACE_.$abc9_currQ = Q; endmodule @@ -132,7 +132,7 @@ module FDCE (output reg Q, input C, CE, D, CLR); // Special signals wire [0:0] _TECHMAP_REPLACE_.$abc9_clock = C; - wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, IS_D_INVERTED, CLR, IS_CLR_INVERTED}; + wire [4:0] _TECHMAP_REPLACE_.$abc9_control = {INIT, CE, IS_D_INVERTED, CLR, IS_CLR_INVERTED}; wire _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ; endmodule module FDCE_1 (output reg Q, input C, CE, D, CLR); @@ -153,7 +153,7 @@ module FDCE_1 (output reg Q, input C, CE, D, CLR); // Special signals wire [0:0] _TECHMAP_REPLACE_.$abc9_clock = C; - wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, 1'b0 /* IS_D_INVERTED */, CLR, 1'b0 /* IS_CLR_INVERTED */}; + wire [4:0] _TECHMAP_REPLACE_.$abc9_control = {INIT, CE, 1'b0 /* IS_D_INVERTED */, CLR, 1'b0 /* IS_CLR_INVERTED */}; wire _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ; endmodule @@ -181,7 +181,7 @@ module FDPE (output reg Q, input C, CE, D, PRE); // Special signals wire [0:0] _TECHMAP_REPLACE_.$abc9_clock = C; - wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, IS_D_INVERTED, PRE, IS_PRE_INVERTED}; + wire [4:0] _TECHMAP_REPLACE_.$abc9_control = {INIT, CE, IS_D_INVERTED, PRE, IS_PRE_INVERTED}; wire _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ; endmodule module FDPE_1 (output reg Q, input C, CE, D, PRE); @@ -202,7 +202,7 @@ module FDPE_1 (output reg Q, input C, CE, D, PRE); // Special signals wire [0:0] _TECHMAP_REPLACE_.$abc9_clock = C; - wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, 1'b0 /* IS_D_INVERTED */, PRE, 1'b0 /* IS_PRE_INVERTED */}; + wire [4:0] _TECHMAP_REPLACE_.$abc9_control = {INIT, CE, 1'b0 /* IS_D_INVERTED */, PRE, 1'b0 /* IS_PRE_INVERTED */}; wire _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ; endmodule @@ -224,7 +224,7 @@ module FDSE (output reg Q, input C, CE, D, S); // Special signals wire [0:0] _TECHMAP_REPLACE_.$abc9_clock = C; - wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, IS_D_INVERTED, S, IS_S_INVERTED}; + wire [4:0] _TECHMAP_REPLACE_.$abc9_control = {INIT, CE, IS_D_INVERTED, S, IS_S_INVERTED}; wire _TECHMAP_REPLACE_.$abc9_currQ = Q; endmodule module FDSE_1 (output reg Q, input C, CE, D, S); @@ -239,7 +239,7 @@ module FDSE_1 (output reg Q, input C, CE, D, S); // Special signals wire [0:0] _TECHMAP_REPLACE_.$abc9_clock = C; - wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, 1'b0 /* IS_D_INVERTED */, S, 1'b0 /* IS_S_INVERTED */}; + wire [4:0] _TECHMAP_REPLACE_.$abc9_control = {INIT, CE, 1'b0 /* IS_D_INVERTED */, S, 1'b0 /* IS_S_INVERTED */}; wire _TECHMAP_REPLACE_.$abc9_currQ = Q; endmodule -- cgit v1.2.3 From 0add5965c7bb369bc9dd883c559bcd890d911c14 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 3 Dec 2019 14:27:45 -0800 Subject: techmap abc_unmap.v before xilinx_srl -fixed --- techlibs/xilinx/synth_xilinx.cc | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index 554c42d68..3fffd81f6 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -538,6 +538,7 @@ struct SynthXilinxPass : public ScriptPass else abc9_opts += " -lut +/xilinx/abc9_xc7.lut"; run("abc9" + abc9_opts); + run("techmap -map +/xilinx/abc9_unmap.v"); } else { if (nowidelut) @@ -553,12 +554,10 @@ 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, "(option without '-abc9')"); } if (check_label("finalize")) { -- cgit v1.2.3 From 51650494107d414a53b3e9793b90c193714dac94 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 3 Dec 2019 15:09:33 -0800 Subject: Update ABCREV for upstream bugfix --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 6e7681cf3..b088e97f1 100644 --- a/Makefile +++ b/Makefile @@ -128,7 +128,7 @@ bumpversion: # is just a symlink to your actual ABC working directory, as 'make mrproper' # will remove the 'abc' directory and you do not want to accidentally # delete your work on ABC.. -ABCREV = 623b5e8 +ABCREV = d527697 ABCPULL = 1 ABCURL ?= https://github.com/berkeley-abc/abc ABCMKARGS = CC="$(CXX)" CXX="$(CXX)" ABC_USE_LIBSTDCXX=1 -- cgit v1.2.3 From f98aa1c13fdba69a2ceedd1f3b6613816c60a637 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 3 Dec 2019 15:40:44 -0800 Subject: Revert "Add INIT value to abc9_control" This reverts commit 19bfb4195818be12e6fb962de29ca32444498c22. --- techlibs/xilinx/abc9_map.v | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/techlibs/xilinx/abc9_map.v b/techlibs/xilinx/abc9_map.v index b8defcb64..29ddf7133 100644 --- a/techlibs/xilinx/abc9_map.v +++ b/techlibs/xilinx/abc9_map.v @@ -87,7 +87,7 @@ module FDRE (output reg Q, input C, CE, D, R); // Special signals wire [0:0] _TECHMAP_REPLACE_.$abc9_clock = C; - wire [4:0] _TECHMAP_REPLACE_.$abc9_control = {INIT, CE, IS_D_INVERTED, R, IS_R_INVERTED}; + wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, IS_D_INVERTED, R, IS_R_INVERTED}; wire _TECHMAP_REPLACE_.$abc9_currQ = Q; endmodule module FDRE_1 (output reg Q, input C, CE, D, R); @@ -102,7 +102,7 @@ module FDRE_1 (output reg Q, input C, CE, D, R); // Special signals wire [0:0] _TECHMAP_REPLACE_.$abc9_clock = C; - wire [4:0] _TECHMAP_REPLACE_.$abc9_control = {INIT, CE, 1'b0 /* IS_D_INVERTED */, R, 1'b0 /* IS_R_INVERTED */}; + wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, 1'b0 /* IS_D_INVERTED */, R, 1'b0 /* IS_R_INVERTED */}; wire _TECHMAP_REPLACE_.$abc9_currQ = Q; endmodule @@ -132,7 +132,7 @@ module FDCE (output reg Q, input C, CE, D, CLR); // Special signals wire [0:0] _TECHMAP_REPLACE_.$abc9_clock = C; - wire [4:0] _TECHMAP_REPLACE_.$abc9_control = {INIT, CE, IS_D_INVERTED, CLR, IS_CLR_INVERTED}; + wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, IS_D_INVERTED, CLR, IS_CLR_INVERTED}; wire _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ; endmodule module FDCE_1 (output reg Q, input C, CE, D, CLR); @@ -153,7 +153,7 @@ module FDCE_1 (output reg Q, input C, CE, D, CLR); // Special signals wire [0:0] _TECHMAP_REPLACE_.$abc9_clock = C; - wire [4:0] _TECHMAP_REPLACE_.$abc9_control = {INIT, CE, 1'b0 /* IS_D_INVERTED */, CLR, 1'b0 /* IS_CLR_INVERTED */}; + wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, 1'b0 /* IS_D_INVERTED */, CLR, 1'b0 /* IS_CLR_INVERTED */}; wire _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ; endmodule @@ -181,7 +181,7 @@ module FDPE (output reg Q, input C, CE, D, PRE); // Special signals wire [0:0] _TECHMAP_REPLACE_.$abc9_clock = C; - wire [4:0] _TECHMAP_REPLACE_.$abc9_control = {INIT, CE, IS_D_INVERTED, PRE, IS_PRE_INVERTED}; + wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, IS_D_INVERTED, PRE, IS_PRE_INVERTED}; wire _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ; endmodule module FDPE_1 (output reg Q, input C, CE, D, PRE); @@ -202,7 +202,7 @@ module FDPE_1 (output reg Q, input C, CE, D, PRE); // Special signals wire [0:0] _TECHMAP_REPLACE_.$abc9_clock = C; - wire [4:0] _TECHMAP_REPLACE_.$abc9_control = {INIT, CE, 1'b0 /* IS_D_INVERTED */, PRE, 1'b0 /* IS_PRE_INVERTED */}; + wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, 1'b0 /* IS_D_INVERTED */, PRE, 1'b0 /* IS_PRE_INVERTED */}; wire _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ; endmodule @@ -224,7 +224,7 @@ module FDSE (output reg Q, input C, CE, D, S); // Special signals wire [0:0] _TECHMAP_REPLACE_.$abc9_clock = C; - wire [4:0] _TECHMAP_REPLACE_.$abc9_control = {INIT, CE, IS_D_INVERTED, S, IS_S_INVERTED}; + wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, IS_D_INVERTED, S, IS_S_INVERTED}; wire _TECHMAP_REPLACE_.$abc9_currQ = Q; endmodule module FDSE_1 (output reg Q, input C, CE, D, S); @@ -239,7 +239,7 @@ module FDSE_1 (output reg Q, input C, CE, D, S); // Special signals wire [0:0] _TECHMAP_REPLACE_.$abc9_clock = C; - wire [4:0] _TECHMAP_REPLACE_.$abc9_control = {INIT, CE, 1'b0 /* IS_D_INVERTED */, S, 1'b0 /* IS_S_INVERTED */}; + wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, 1'b0 /* IS_D_INVERTED */, S, 1'b0 /* IS_S_INVERTED */}; wire _TECHMAP_REPLACE_.$abc9_currQ = Q; endmodule -- cgit v1.2.3 From a181ff66d3094e5740b0c803e6fafa8e91bb11e5 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 3 Dec 2019 18:47:09 -0800 Subject: Add abc9_init wire, attach to abc9_flop cell --- passes/techmap/abc9.cc | 14 ++++++++++++-- techlibs/xilinx/abc9_map.v | 14 ++++++++++++-- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 5a9cbc245..5139cb80b 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -1106,7 +1106,7 @@ struct Abc9Pass : public Pass { if (delay_target.empty()) { Wire *abc9_clock_wire = module->wire(stringf("%s.$abc9_clock", cell->name.c_str())); if (abc9_clock_wire == NULL) - log_error("'%s$abc9_clock' is not a wire present in module '%s'.\n", cell->name.c_str(), log_id(module)); + log_error("'%s.$abc9_clock' is not a wire present in module '%s'.\n", cell->name.c_str(), log_id(module)); SigBit abc9_clock = sigmap(abc9_clock_wire); auto r = clocks.insert(abc9_clock.wire); if (r.second) { @@ -1121,13 +1121,23 @@ struct Abc9Pass : public Pass { Wire *abc9_control_wire = module->wire(stringf("%s.$abc9_control", cell->name.c_str())); if (abc9_control_wire == NULL) - log_error("'%s$abc9_control' is not a wire present in module '%s'.\n", cell->name.c_str(), log_id(module)); + log_error("'%s.$abc9_control' is not a wire present in module '%s'.\n", cell->name.c_str(), log_id(module)); SigSpec abc9_control = sigmap(abc9_control_wire); ctrldomain_t key(cell->type, abc9_control); auto r = mergeability_class.emplace(key, mergeability_class.size() + 1); auto YS_ATTRIBUTE(unused) r2 = cell->attributes.insert(std::make_pair(ID(abc9_mergeability), r.first->second)); log_assert(r2.second); + + Wire *abc9_init_wire = module->wire(stringf("%s.$abc9_init", cell->name.c_str())); + if (abc9_init_wire == NULL) + log_error("'%s.$abc9_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 = sigmap(abc9_init_wire); + if (!abc9_init.is_fully_const()) + log_error("'%s.$abc9_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); } design->selected_active_module = module->name.str(); diff --git a/techlibs/xilinx/abc9_map.v b/techlibs/xilinx/abc9_map.v index 29ddf7133..98a4457ae 100644 --- a/techlibs/xilinx/abc9_map.v +++ b/techlibs/xilinx/abc9_map.v @@ -64,10 +64,12 @@ // the connectivity of its basic D-Q flop // (b) a special _TECHMAP_REPLACE_.$abc9_clock wire to indicate its clock // signal, used to extract the delay target -// (c) a special _TECHMAP_REPLACE_.$abc9_control that captures the control +// (c) a special _TECHMAP_REPLACE_.$abc9_control wire that captures the control // domain (which, combined with this cell type, encodes to `abc9' which // flops may be merged together) -// (d) a special _TECHMAP_REPLACE_.$abc9_currQ wire that will be used for feedback +// (d) a special _TECHMAP_REPLACE_.$abc9_init wire to encode the flop's initial +// state +// (e) a special _TECHMAP_REPLACE_.$abc9_currQ wire that will be used for feedback // into the (combinatorial) FD* cell to facilitate clock-enable behaviour module FDRE (output reg Q, input C, CE, D, R); parameter [0:0] INIT = 1'b0; @@ -88,6 +90,7 @@ module FDRE (output reg Q, input C, CE, D, R); // Special signals wire [0:0] _TECHMAP_REPLACE_.$abc9_clock = C; wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, IS_D_INVERTED, R, IS_R_INVERTED}; + wire [0:0] _TECHMAP_REPLACE_.$abc9_init = INIT; wire _TECHMAP_REPLACE_.$abc9_currQ = Q; endmodule module FDRE_1 (output reg Q, input C, CE, D, R); @@ -103,6 +106,7 @@ module FDRE_1 (output reg Q, input C, CE, D, R); // Special signals wire [0:0] _TECHMAP_REPLACE_.$abc9_clock = C; wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, 1'b0 /* IS_D_INVERTED */, R, 1'b0 /* IS_R_INVERTED */}; + wire [0:0] _TECHMAP_REPLACE_.$abc9_init = INIT; wire _TECHMAP_REPLACE_.$abc9_currQ = Q; endmodule @@ -133,6 +137,7 @@ module FDCE (output reg Q, input C, CE, D, CLR); // Special signals wire [0:0] _TECHMAP_REPLACE_.$abc9_clock = C; wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, IS_D_INVERTED, CLR, IS_CLR_INVERTED}; + wire [0:0] _TECHMAP_REPLACE_.$abc9_init = INIT; wire _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ; endmodule module FDCE_1 (output reg Q, input C, CE, D, CLR); @@ -154,6 +159,7 @@ module FDCE_1 (output reg Q, input C, CE, D, CLR); // Special signals wire [0:0] _TECHMAP_REPLACE_.$abc9_clock = C; wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, 1'b0 /* IS_D_INVERTED */, CLR, 1'b0 /* IS_CLR_INVERTED */}; + wire [0:0] _TECHMAP_REPLACE_.$abc9_init = INIT; wire _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ; endmodule @@ -182,6 +188,7 @@ module FDPE (output reg Q, input C, CE, D, PRE); // Special signals wire [0:0] _TECHMAP_REPLACE_.$abc9_clock = C; wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, IS_D_INVERTED, PRE, IS_PRE_INVERTED}; + wire [0:0] _TECHMAP_REPLACE_.$abc9_init = INIT; wire _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ; endmodule module FDPE_1 (output reg Q, input C, CE, D, PRE); @@ -203,6 +210,7 @@ module FDPE_1 (output reg Q, input C, CE, D, PRE); // Special signals wire [0:0] _TECHMAP_REPLACE_.$abc9_clock = C; wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, 1'b0 /* IS_D_INVERTED */, PRE, 1'b0 /* IS_PRE_INVERTED */}; + wire [0:0] _TECHMAP_REPLACE_.$abc9_init = INIT; wire _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ; endmodule @@ -225,6 +233,7 @@ module FDSE (output reg Q, input C, CE, D, S); // Special signals wire [0:0] _TECHMAP_REPLACE_.$abc9_clock = C; wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, IS_D_INVERTED, S, IS_S_INVERTED}; + wire [0:0] _TECHMAP_REPLACE_.$abc9_init = INIT; wire _TECHMAP_REPLACE_.$abc9_currQ = Q; endmodule module FDSE_1 (output reg Q, input C, CE, D, S); @@ -240,6 +249,7 @@ module FDSE_1 (output reg Q, input C, CE, D, S); // Special signals wire [0:0] _TECHMAP_REPLACE_.$abc9_clock = C; wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, 1'b0 /* IS_D_INVERTED */, S, 1'b0 /* IS_S_INVERTED */}; + wire [0:0] _TECHMAP_REPLACE_.$abc9_init = INIT; wire _TECHMAP_REPLACE_.$abc9_currQ = Q; endmodule -- cgit v1.2.3 From df52bc80d80e384dddf50a01fa970d1aa36123f2 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 3 Dec 2019 18:47:44 -0800 Subject: write_xaiger to consume abc9_init attribute for abc9_flops --- backends/aiger/xaiger.cc | 62 ++++++++++++++++++++++-------------------------- 1 file changed, 28 insertions(+), 34 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index e05b6cc60..2943ed90d 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -78,13 +78,12 @@ struct XAigerWriter Module *module; SigMap sigmap; - dict init_map; pool input_bits, output_bits; dict not_map, alias_map; dict> and_map; vector> ci_bits; vector> co_bits; - dict ff_bits; + dict> ff_bits; dict arrival_times; vector> aig_gates; @@ -157,14 +156,6 @@ struct XAigerWriter for (auto wire : module->wires()) { - if (wire->attributes.count("\\init")) { - SigSpec initsig = sigmap(wire); - Const initval = wire->attributes.at("\\init"); - for (int i = 0; i < GetSize(wire) && i < GetSize(initval); i++) - if (initval[i] == State::S0 || initval[i] == State::S1) - init_map[initsig[i]] = initval[i] == State::S1; - } - bool keep = wire->attributes.count("\\keep"); for (int i = 0; i < GetSize(wire); i++) @@ -254,7 +245,7 @@ struct XAigerWriter unused_bits.erase(D); undriven_bits.erase(Q); alias_map[Q] = D; - auto r = ff_bits.insert(std::make_pair(D, 0)); + auto r = ff_bits.insert(std::make_pair(D, std::make_pair(0, State::Sx))); log_assert(r.second); continue; } @@ -368,11 +359,20 @@ struct XAigerWriter else d = cell->getPort(r.first->second.first); + auto &rhs = ff_bits.at(d); + auto it = cell->attributes.find(ID(abc9_mergeability)); log_assert(it != cell->attributes.end()); - ff_bits.at(d) = it->second.as_int(); + rhs.first = it->second.as_int(); + cell->attributes.erase(it); + + it = cell->attributes.find(ID(abc9_init)); + log_assert(it != cell->attributes.end()); + log_assert(GetSize(it->second) == 1); + rhs.second = it->second[0]; cell->attributes.erase(it); + auto arrival = r.first->second.second; if (arrival) arrival_times[d] = arrival; @@ -805,10 +805,23 @@ struct XAigerWriter auto write_r_buffer = std::bind(write_buffer, std::ref(r_buffer), std::placeholders::_1); log_debug("flopNum = %d\n", GetSize(ff_bits)); write_r_buffer(ff_bits.size()); + + 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) { - log_assert(i.second > 0); - write_r_buffer(i.second); const SigBit &bit = i.first; + int mergeability = i.second.first; + log_assert(mergeability > 0); + write_r_buffer(mergeability); + State init = i.second.second; + if (init == State::S1) + write_s_buffer(1); + else if (init == State::S0) + write_s_buffer(0); + else + write_s_buffer(0); write_i_buffer(arrival_times.at(bit, 0)); //write_o_buffer(0); } @@ -819,22 +832,6 @@ struct XAigerWriter f.write(reinterpret_cast(&buffer_size_be), sizeof(buffer_size_be)); f.write(buffer_str.data(), buffer_str.size()); - std::stringstream s_buffer; - auto write_s_buffer = std::bind(write_buffer, std::ref(s_buffer), std::placeholders::_1); - write_s_buffer(ff_bits.size()); - for (const auto &i : ff_bits) { - const SigBit &bit = i.first; - auto it = bit.wire->attributes.find("\\init"); - if (it != bit.wire->attributes.end()) { - auto init = it->second[bit.offset]; - if (init == RTLIL::S1) { - write_s_buffer(1); - continue; - } - } - // Default flop init is zero - write_s_buffer(0); - } f << "s"; buffer_str = s_buffer.str(); buffer_size_be = to_big_endian(buffer_str.size()); @@ -962,10 +959,7 @@ struct XAigerWriter if (output_bits.count(b)) { int o = ordered_outputs.at(b); - int init = 0; - auto it = init_map.find(b); - if (it != init_map.end() && it->second) - init = 1; + int init = 2; output_lines[o] += stringf("output %d %d %s %d\n", o - GetSize(co_bits), i, log_id(wire), init); continue; } -- cgit v1.2.3 From d66d06b91df4aade84107b59b2b1f32188a3995e Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 3 Dec 2019 19:21:42 -0800 Subject: Add assertion --- passes/techmap/abc9.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 5139cb80b..5b4100574 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -1107,6 +1107,7 @@ struct Abc9Pass : public Pass { Wire *abc9_clock_wire = module->wire(stringf("%s.$abc9_clock", cell->name.c_str())); if (abc9_clock_wire == NULL) log_error("'%s.$abc9_clock' is not a wire present in module '%s'.\n", cell->name.c_str(), log_id(module)); + log_assert(GetSize(abc9_clock_wire) == 1); SigBit abc9_clock = sigmap(abc9_clock_wire); auto r = clocks.insert(abc9_clock.wire); if (r.second) { -- cgit v1.2.3 From c6ee2fb4825de727cc18c222888c4c8832d6f26f Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 3 Dec 2019 19:21:47 -0800 Subject: Cleanup --- backends/aiger/xaiger.cc | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 2943ed90d..c6d24cf94 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -83,7 +83,7 @@ struct XAigerWriter dict> and_map; vector> ci_bits; vector> co_bits; - dict> ff_bits; + dict> ff_bits; dict arrival_times; vector> aig_gates; @@ -245,7 +245,7 @@ struct XAigerWriter unused_bits.erase(D); undriven_bits.erase(Q); alias_map[Q] = D; - auto r = ff_bits.insert(std::make_pair(D, std::make_pair(0, State::Sx))); + auto r = ff_bits.insert(std::make_pair(D, std::make_pair(0, 2))); log_assert(r.second); continue; } @@ -369,10 +369,16 @@ struct XAigerWriter it = cell->attributes.find(ID(abc9_init)); log_assert(it != cell->attributes.end()); log_assert(GetSize(it->second) == 1); - rhs.second = it->second[0]; + if (it->second[0] == State::S1) + rhs.second = 1; + else if (it->second[0] == State::S0) + rhs.second = 0; + else { + log_assert(it->second[0] == State::Sx); + rhs.second = 0; + } cell->attributes.erase(it); - auto arrival = r.first->second.second; if (arrival) arrival_times[d] = arrival; @@ -815,13 +821,8 @@ struct XAigerWriter int mergeability = i.second.first; log_assert(mergeability > 0); write_r_buffer(mergeability); - State init = i.second.second; - if (init == State::S1) - write_s_buffer(1); - else if (init == State::S0) - write_s_buffer(0); - else - write_s_buffer(0); + int init = i.second.second; + write_s_buffer(init); write_i_buffer(arrival_times.at(bit, 0)); //write_o_buffer(0); } -- cgit v1.2.3 From 31ef4cc7048b9da557ee78bb791c5bb7210e9fc5 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 4 Dec 2019 16:11:02 -0800 Subject: abc9_map.v to do `zinit' and make INIT = 1'b0 --- techlibs/xilinx/abc9_map.v | 182 ++++++++++++++++++++++++++++----------------- 1 file changed, 112 insertions(+), 70 deletions(-) diff --git a/techlibs/xilinx/abc9_map.v b/techlibs/xilinx/abc9_map.v index 98a4457ae..8939b46a0 100644 --- a/techlibs/xilinx/abc9_map.v +++ b/techlibs/xilinx/abc9_map.v @@ -71,43 +71,55 @@ // state // (e) a special _TECHMAP_REPLACE_.$abc9_currQ wire that will be used for feedback // into the (combinatorial) FD* cell to facilitate clock-enable behaviour +// In order to perform sequential synthesis, `abc9' also requires that +// the initial value of all flops be zero. module FDRE (output reg Q, input C, CE, D, R); parameter [0:0] INIT = 1'b0; parameter [0:0] IS_C_INVERTED = 1'b0; parameter [0:0] IS_D_INVERTED = 1'b0; parameter [0:0] IS_R_INVERTED = 1'b0; - wire $nextQ; + wire DD, QQ, $nextQ; + generate if (INIT == 1'b1) + assign DD = ~D, Q = ~QQ; + else + assign DD = D, Q = QQ; + endgenerate FDRE #( - .INIT(INIT), + .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($nextQ), .C(C), .CE(CE), .R(R) + .D(DD), .Q($nextQ), .C(C), .CE(CE), .R(R) ); - \$__ABC9_FF_ abc_dff (.D($nextQ), .Q(Q)); + \$__ABC9_FF_ abc_dff (.D($nextQ), .Q(QQ)); // Special signals wire [0:0] _TECHMAP_REPLACE_.$abc9_clock = C; wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, IS_D_INVERTED, R, IS_R_INVERTED}; - wire [0:0] _TECHMAP_REPLACE_.$abc9_init = INIT; - wire _TECHMAP_REPLACE_.$abc9_currQ = Q; + wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; + wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = QQ; endmodule module FDRE_1 (output reg Q, input C, CE, D, R); parameter [0:0] INIT = 1'b0; - wire $nextQ; + wire DD, QQ, $nextQ; + generate if (INIT == 1'b1) + assign DD = ~D, Q = ~QQ; + else + assign DD = D, Q = QQ; + endgenerate FDRE_1 #( - .INIT(INIT), + .INIT(1'b0), ) _TECHMAP_REPLACE_ ( - .D(D), .Q($nextQ), .C(C), .CE(CE), .R(R) + .D(DD), .Q($nextQ), .C(C), .CE(CE), .R(R) ); - \$__ABC9_FF_ abc_dff (.D($nextQ), .Q(Q)); + \$__ABC9_FF_ abc_dff (.D($nextQ), .Q(QQ)); // Special signals wire [0:0] _TECHMAP_REPLACE_.$abc9_clock = C; wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, 1'b0 /* IS_D_INVERTED */, R, 1'b0 /* IS_R_INVERTED */}; - wire [0:0] _TECHMAP_REPLACE_.$abc9_init = INIT; - wire _TECHMAP_REPLACE_.$abc9_currQ = Q; + wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; + wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = QQ; endmodule module FDCE (output reg Q, input C, CE, D, CLR); @@ -115,103 +127,123 @@ module FDCE (output reg Q, input C, CE, D, CLR); parameter [0:0] IS_C_INVERTED = 1'b0; parameter [0:0] IS_D_INVERTED = 1'b0; parameter [0:0] IS_CLR_INVERTED = 1'b0; - wire $nextQ, $abc9_currQ; + wire DD, QQ, $nextQ, $abc9_currQ; + generate if (INIT == 1'b1) + assign DD = ~D, Q = ~QQ; + else + assign DD = D, Q = QQ; + endgenerate FDCE #( - .INIT(INIT), + .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($nextQ), .C(C), .CE(CE), .CLR(CLR) - // ^^^ Note that async - // control is not directly - // supported by abc9 but its - // behaviour is captured by - // $__ABC9_ASYNC below + .D(DD), .Q($nextQ), .C(C), .CE(CE), .CLR(CLR) + // ^^^ Note that async + // control is not directly + // supported by abc9 but its + // behaviour is captured by + // $__ABC9_ASYNC below ); \$__ABC9_FF_ abc_dff (.D($nextQ), .Q($abc9_currQ)); // Since this is an async flop, async behaviour is also dealt with // using the $_ABC9_ASYNC box by abc9_map.v - \$__ABC9_ASYNC abc_async (.A($abc9_currQ), .S(CLR ^ IS_CLR_INVERTED), .Y(Q)); + \$__ABC9_ASYNC abc_async (.A($abc9_currQ), .S(CLR ^ IS_CLR_INVERTED), .Y(QQ)); // Special signals wire [0:0] _TECHMAP_REPLACE_.$abc9_clock = C; wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, IS_D_INVERTED, CLR, IS_CLR_INVERTED}; - wire [0:0] _TECHMAP_REPLACE_.$abc9_init = INIT; - wire _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ; + wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; + wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ; endmodule module FDCE_1 (output reg Q, input C, CE, D, CLR); parameter [0:0] INIT = 1'b0; - wire $nextQ, $abc9_currQ; + wire DD, QQ, $nextQ, $abc9_currQ; + generate if (INIT == 1'b1) + assign DD = ~D, Q = ~QQ; + else + assign DD = D, Q = QQ; + endgenerate FDCE_1 #( - .INIT(INIT) + .INIT(1'b0) ) _TECHMAP_REPLACE_ ( - .D(D), .Q($nextQ), .C(C), .CE(CE), .CLR(CLR) - // ^^^ Note that async - // control is not directly - // supported by abc9 but its - // behaviour is captured by - // $__ABC9_ASYNC below + .D(DD), .Q($nextQ), .C(C), .CE(CE), .CLR(CLR) + // ^^^ Note that async + // control is not directly + // supported by abc9 but its + // behaviour is captured by + // $__ABC9_ASYNC below ); \$__ABC9_FF_ abc_dff (.D($nextQ), .Q($abc9_currQ)); - \$__ABC9_ASYNC abc_async (.A($abc9_currQ), .S(CLR), .Y(Q)); + \$__ABC9_ASYNC abc_async (.A($abc9_currQ), .S(CLR), .Y(QQ)); // Special signals wire [0:0] _TECHMAP_REPLACE_.$abc9_clock = C; wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, 1'b0 /* IS_D_INVERTED */, CLR, 1'b0 /* IS_CLR_INVERTED */}; - wire [0:0] _TECHMAP_REPLACE_.$abc9_init = INIT; - wire _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ; + wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; + wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ; endmodule module FDPE (output reg Q, input C, CE, D, PRE); - parameter [0:0] INIT = 1'b0; + 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 $nextQ, $abc9_currQ; + wire DD, QQ, $nextQ, $abc9_currQ; + generate if (INIT == 1'b1) + assign DD = ~D, Q = ~QQ; + else + assign DD = D, Q = QQ; + endgenerate FDPE #( - .INIT(INIT), + .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($nextQ), .C(C), .CE(CE), .PRE(PRE) - // ^^^ Note that async - // control is not directly - // supported by abc9 but its - // behaviour is captured by - // $__ABC9_ASYNC below + .D(DD), .Q($nextQ), .C(C), .CE(CE), .PRE(PRE) + // ^^^ Note that async + // control is not directly + // supported by abc9 but its + // behaviour is captured by + // $__ABC9_ASYNC below ); \$__ABC9_FF_ abc_dff (.D($nextQ), .Q($abc9_currQ)); - \$__ABC9_ASYNC abc_async (.A($abc9_currQ), .S(PRE ^ IS_PRE_INVERTED), .Y(Q)); + \$__ABC9_ASYNC abc_async (.A($abc9_currQ), .S(PRE ^ IS_PRE_INVERTED), .Y(QQ)); // Special signals wire [0:0] _TECHMAP_REPLACE_.$abc9_clock = C; wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, IS_D_INVERTED, PRE, IS_PRE_INVERTED}; - wire [0:0] _TECHMAP_REPLACE_.$abc9_init = INIT; - wire _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ; + wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; + wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ; endmodule module FDPE_1 (output reg Q, input C, CE, D, PRE); - parameter [0:0] INIT = 1'b0; - wire $nextQ, $abc9_currQ; + parameter [0:0] INIT = 1'b1; + wire DD, QQ, $nextQ, $abc9_currQ; + generate if (INIT == 1'b1) + assign DD = ~D, Q = ~QQ; + else + assign DD = D, Q = QQ; + endgenerate FDPE_1 #( - .INIT(INIT) + .INIT(1'b0), ) _TECHMAP_REPLACE_ ( - .D(D), .Q($nextQ), .C(C), .CE(CE), .PRE(PRE) - // ^^^ Note that async - // control is not directly - // supported by abc9 but its - // behaviour is captured by - // $__ABC9_ASYNC below + .D(DD), .Q($nextQ), .C(C), .CE(CE), .PRE(PRE) + // ^^^ Note that async + // control is not directly + // supported by abc9 but its + // behaviour is captured by + // $__ABC9_ASYNC below ); \$__ABC9_FF_ abc_dff (.D($nextQ), .Q($abc9_currQ)); - \$__ABC9_ASYNC abc_async (.A($abc9_currQ), .S(PRE), .Y(Q)); + \$__ABC9_ASYNC abc_async (.A($abc9_currQ), .S(PRE), .Y(QQ)); // Special signals wire [0:0] _TECHMAP_REPLACE_.$abc9_clock = C; wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, 1'b0 /* IS_D_INVERTED */, PRE, 1'b0 /* IS_PRE_INVERTED */}; - wire [0:0] _TECHMAP_REPLACE_.$abc9_init = INIT; - wire _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ; + wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; + wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ; endmodule module FDSE (output reg Q, input C, CE, D, S); @@ -219,38 +251,48 @@ module FDSE (output reg Q, input C, CE, D, S); 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 $nextQ; + wire DD, QQ, $nextQ; + generate if (INIT == 1'b1) + assign DD = ~D, Q = ~QQ; + else + assign DD = D, Q = QQ; + endgenerate FDSE #( - .INIT(INIT), + .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($nextQ), .C(C), .CE(CE), .S(S) + .D(DD), .Q($nextQ), .C(C), .CE(CE), .S(S) ); - \$__ABC9_FF_ abc_dff (.D($nextQ), .Q(Q)); + \$__ABC9_FF_ abc_dff (.D($nextQ), .Q(QQ)); // Special signals wire [0:0] _TECHMAP_REPLACE_.$abc9_clock = C; wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, IS_D_INVERTED, S, IS_S_INVERTED}; - wire [0:0] _TECHMAP_REPLACE_.$abc9_init = INIT; - wire _TECHMAP_REPLACE_.$abc9_currQ = Q; + wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; + wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = QQ; endmodule module FDSE_1 (output reg Q, input C, CE, D, S); parameter [0:0] INIT = 1'b1; - wire $nextQ; + wire DD, QQ, $nextQ; + generate if (INIT == 1'b1) + assign DD = ~D, Q = ~QQ; + else + assign DD = D, Q = QQ; + endgenerate FDSE_1 #( - .INIT(INIT), + .INIT(1'b0), ) _TECHMAP_REPLACE_ ( - .D(D), .Q($nextQ), .C(C), .CE(CE), .S(S) + .D(DD), .Q($nextQ), .C(C), .CE(CE), .S(S) ); - \$__ABC9_FF_ abc_dff (.D($nextQ), .Q(Q)); + \$__ABC9_FF_ abc_dff (.D($nextQ), .Q(QQ)); // Special signals wire [0:0] _TECHMAP_REPLACE_.$abc9_clock = C; wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, 1'b0 /* IS_D_INVERTED */, S, 1'b0 /* IS_S_INVERTED */}; - wire [0:0] _TECHMAP_REPLACE_.$abc9_init = INIT; - wire _TECHMAP_REPLACE_.$abc9_currQ = Q; + wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; + wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = QQ; endmodule module RAM32X1D ( -- cgit v1.2.3 From b43986c5a1e9c41865139df9c0b5f9750c26762c Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 4 Dec 2019 16:34:34 -0800 Subject: output reg Q -> output Q to suppress warning --- techlibs/xilinx/abc9_map.v | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/techlibs/xilinx/abc9_map.v b/techlibs/xilinx/abc9_map.v index 8939b46a0..d84b9a8fa 100644 --- a/techlibs/xilinx/abc9_map.v +++ b/techlibs/xilinx/abc9_map.v @@ -73,7 +73,7 @@ // into the (combinatorial) FD* cell to facilitate clock-enable behaviour // In order to perform sequential synthesis, `abc9' also requires that // the initial value of all flops be zero. -module FDRE (output reg Q, input C, CE, D, R); +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; @@ -100,7 +100,7 @@ module FDRE (output reg Q, input C, CE, D, R); wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = QQ; endmodule -module FDRE_1 (output reg Q, input C, CE, D, R); +module FDRE_1 (output Q, input C, CE, D, R); parameter [0:0] INIT = 1'b0; wire DD, QQ, $nextQ; generate if (INIT == 1'b1) @@ -122,7 +122,7 @@ module FDRE_1 (output reg Q, input C, CE, D, R); wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = QQ; endmodule -module FDCE (output reg Q, input C, CE, D, CLR); +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; @@ -157,7 +157,7 @@ module FDCE (output reg Q, input C, CE, D, CLR); wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ; endmodule -module FDCE_1 (output reg Q, input C, CE, D, CLR); +module FDCE_1 (output Q, input C, CE, D, CLR); parameter [0:0] INIT = 1'b0; wire DD, QQ, $nextQ, $abc9_currQ; generate if (INIT == 1'b1) @@ -185,7 +185,7 @@ module FDCE_1 (output reg Q, input C, CE, D, CLR); wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ; endmodule -module FDPE (output reg Q, input C, CE, D, PRE); +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; @@ -218,7 +218,7 @@ module FDPE (output reg Q, input C, CE, D, PRE); wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ; endmodule -module FDPE_1 (output reg Q, input C, CE, D, PRE); +module FDPE_1 (output Q, input C, CE, D, PRE); parameter [0:0] INIT = 1'b1; wire DD, QQ, $nextQ, $abc9_currQ; generate if (INIT == 1'b1) @@ -246,7 +246,7 @@ module FDPE_1 (output reg Q, input C, CE, D, PRE); wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ; endmodule -module FDSE (output reg Q, input C, CE, D, S); +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; @@ -273,7 +273,7 @@ module FDSE (output reg Q, input C, CE, D, S); wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = QQ; endmodule -module FDSE_1 (output reg Q, input C, CE, D, S); +module FDSE_1 (output Q, input C, CE, D, S); parameter [0:0] INIT = 1'b1; wire DD, QQ, $nextQ; generate if (INIT == 1'b1) -- cgit v1.2.3 From c8a7bc5d3a0a69e942a1c9ce84c1dbf0c32e49e4 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 4 Dec 2019 16:37:56 -0800 Subject: Bump ABC to get "&verify -s" fix --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index b088e97f1..e484656c8 100644 --- a/Makefile +++ b/Makefile @@ -128,7 +128,7 @@ bumpversion: # is just a symlink to your actual ABC working directory, as 'make mrproper' # will remove the 'abc' directory and you do not want to accidentally # delete your work on ABC.. -ABCREV = d527697 +ABCREV = 451f2b0 ABCPULL = 1 ABCURL ?= https://github.com/berkeley-abc/abc ABCMKARGS = CC="$(CXX)" CXX="$(CXX)" ABC_USE_LIBSTDCXX=1 -- cgit v1.2.3 From 258a34e6f148928e80f13416b28d6bba6988c78a Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 4 Dec 2019 20:33:24 -0800 Subject: Oh deary me --- techlibs/xilinx/cells_sim.v | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/techlibs/xilinx/cells_sim.v b/techlibs/xilinx/cells_sim.v index d845b324f..2fda3b8fd 100644 --- a/techlibs/xilinx/cells_sim.v +++ b/techlibs/xilinx/cells_sim.v @@ -378,10 +378,10 @@ module FDPE ( parameter [0:0] IS_PRE_INVERTED = 1'b0; initial Q <= INIT; generate case ({|IS_C_INVERTED, |IS_PRE_INVERTED}) - 2'b00: always @(posedge C, posedge PRE) if ( PRE) Q <= 1'b1; else Q <= Q ; - 2'b01: always @(posedge C, negedge PRE) if (!PRE) Q <= 1'b1; else Q <= Q ; - 2'b10: always @(negedge C, posedge PRE) if ( PRE) Q <= 1'b1; else Q <= Q ; - 2'b11: always @(negedge C, negedge PRE) if (!PRE) Q <= 1'b1; else Q <= Q ; + 2'b00: always @(posedge C, posedge PRE) if ( PRE) Q <= 1'b1; else if (CE) Q <= D ^ IS_D_INVERTED; + 2'b01: always @(posedge C, negedge PRE) if (!PRE) Q <= 1'b1; else if (CE) Q <= D ^ IS_D_INVERTED; + 2'b10: always @(negedge C, posedge PRE) if ( PRE) Q <= 1'b1; else if (CE) Q <= D ^ IS_D_INVERTED; + 2'b11: always @(negedge C, negedge PRE) if (!PRE) Q <= 1'b1; else if (CE) Q <= D ^ IS_D_INVERTED; endcase endgenerate endmodule -- cgit v1.2.3 From 19bc429482418aa42861ca0f195d86bc9577e320 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 4 Dec 2019 21:36:41 -0800 Subject: abc9_map.v to transform INIT=1 to INIT=0 --- techlibs/xilinx/abc9_map.v | 319 ++++++++++++++++++++++++++---------------- tests/arch/xilinx/abc9_map.ys | 91 ++++++++++++ 2 files changed, 292 insertions(+), 118 deletions(-) create mode 100644 tests/arch/xilinx/abc9_map.ys diff --git a/techlibs/xilinx/abc9_map.v b/techlibs/xilinx/abc9_map.v index d84b9a8fa..3fa5f5a1c 100644 --- a/techlibs/xilinx/abc9_map.v +++ b/techlibs/xilinx/abc9_map.v @@ -71,27 +71,39 @@ // state // (e) a special _TECHMAP_REPLACE_.$abc9_currQ wire that will be used for feedback // into the (combinatorial) FD* cell to facilitate clock-enable behaviour +// // In order to perform sequential synthesis, `abc9' also requires that // the initial value of all flops be zero. + 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 DD, QQ, $nextQ; - generate if (INIT == 1'b1) - assign DD = ~D, Q = ~QQ; - else - assign DD = D, Q = QQ; + wire QQ, $nextQ; + 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($nextQ), .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($nextQ), .C(C), .CE(CE), .R(R) + ); + end endgenerate - 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(DD), .Q($nextQ), .C(C), .CE(CE), .R(R) - ); \$__ABC9_FF_ abc_dff (.D($nextQ), .Q(QQ)); // Special signals @@ -102,17 +114,24 @@ module FDRE (output Q, input C, CE, D, R); endmodule module FDRE_1 (output Q, input C, CE, D, R); parameter [0:0] INIT = 1'b0; - wire DD, QQ, $nextQ; - generate if (INIT == 1'b1) - assign DD = ~D, Q = ~QQ; - else - assign DD = D, Q = QQ; + wire QQ, $nextQ; + generate if (INIT == 1'b1) begin + assign Q = ~QQ; + FDSE_1 #( + .INIT(1'b0) + ) _TECHMAP_REPLACE_ ( + .D(~D), .Q($nextQ), .C(C), .CE(CE), .S(R) + ); + end + else begin + assign Q = QQ; + FDRE_1 #( + .INIT(1'b0) + ) _TECHMAP_REPLACE_ ( + .D(D), .Q($nextQ), .C(C), .CE(CE), .R(R) + ); + end endgenerate - FDRE_1 #( - .INIT(1'b0), - ) _TECHMAP_REPLACE_ ( - .D(DD), .Q($nextQ), .C(C), .CE(CE), .R(R) - ); \$__ABC9_FF_ abc_dff (.D($nextQ), .Q(QQ)); // Special signals @@ -127,25 +146,39 @@ module FDCE (output Q, input C, CE, D, CLR); 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 DD, QQ, $nextQ, $abc9_currQ; - generate if (INIT == 1'b1) - assign DD = ~D, Q = ~QQ; - else - assign DD = D, Q = QQ; - endgenerate - 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(DD), .Q($nextQ), .C(C), .CE(CE), .CLR(CLR) - // ^^^ Note that async - // control is not directly - // supported by abc9 but its - // behaviour is captured by - // $__ABC9_ASYNC below - ); + wire QQ, $nextQ, $abc9_currQ; + 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($nextQ), .C(C), .CE(CE), .PRE(CLR) + // ^^^ Note that async + // control is not directly + // supported by abc9 but its + // behaviour is captured by + // $__ABC9_ASYNC below + ); + 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($nextQ), .C(C), .CE(CE), .CLR(CLR) + // ^^^ Note that async + // control is not directly + // supported by abc9 but its + // behaviour is captured by + // $__ABC9_ASYNC below + ); + end endgenerate \$__ABC9_FF_ abc_dff (.D($nextQ), .Q($abc9_currQ)); // Since this is an async flop, async behaviour is also dealt with // using the $_ABC9_ASYNC box by abc9_map.v @@ -159,22 +192,32 @@ module FDCE (output Q, input C, CE, D, CLR); endmodule module FDCE_1 (output Q, input C, CE, D, CLR); parameter [0:0] INIT = 1'b0; - wire DD, QQ, $nextQ, $abc9_currQ; - generate if (INIT == 1'b1) - assign DD = ~D, Q = ~QQ; - else - assign DD = D, Q = QQ; - endgenerate - FDCE_1 #( - .INIT(1'b0) - ) _TECHMAP_REPLACE_ ( - .D(DD), .Q($nextQ), .C(C), .CE(CE), .CLR(CLR) - // ^^^ Note that async - // control is not directly - // supported by abc9 but its - // behaviour is captured by - // $__ABC9_ASYNC below - ); + generate if (INIT == 1'b1) begin + assign Q = ~QQ; + FDPE_1 #( + .INIT(1'b0) + ) _TECHMAP_REPLACE_ ( + .D(~D), .Q($nextQ), .C(C), .CE(CE), .PRE(CLR) + // ^^^ Note that async + // control is not directly + // supported by abc9 but its + // behaviour is captured by + // $__ABC9_ASYNC below + ); + end + else begin + assign Q = QQ; + FDCE_1 #( + .INIT(1'b0) + ) _TECHMAP_REPLACE_ ( + .D(D), .Q($nextQ), .C(C), .CE(CE), .CLR(CLR) + // ^^^ Note that async + // control is not directly + // supported by abc9 but its + // behaviour is captured by + // $__ABC9_ASYNC below + ); + end endgenerate \$__ABC9_FF_ abc_dff (.D($nextQ), .Q($abc9_currQ)); \$__ABC9_ASYNC abc_async (.A($abc9_currQ), .S(CLR), .Y(QQ)); @@ -190,25 +233,39 @@ module FDPE (output Q, input C, CE, D, PRE); 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 DD, QQ, $nextQ, $abc9_currQ; - generate if (INIT == 1'b1) - assign DD = ~D, Q = ~QQ; - else - assign DD = D, Q = QQ; - endgenerate - 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(DD), .Q($nextQ), .C(C), .CE(CE), .PRE(PRE) - // ^^^ Note that async - // control is not directly - // supported by abc9 but its - // behaviour is captured by - // $__ABC9_ASYNC below - ); + wire QQ, $nextQ, $abc9_currQ; + 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($nextQ), .C(C), .CE(CE), .CLR(PRE) + // ^^^ Note that async + // control is not directly + // supported by abc9 but its + // behaviour is captured by + // $__ABC9_ASYNC below + ); + 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($nextQ), .C(C), .CE(CE), .PRE(PRE) + // ^^^ Note that async + // control is not directly + // supported by abc9 but its + // behaviour is captured by + // $__ABC9_ASYNC below + ); + end endgenerate \$__ABC9_FF_ abc_dff (.D($nextQ), .Q($abc9_currQ)); \$__ABC9_ASYNC abc_async (.A($abc9_currQ), .S(PRE ^ IS_PRE_INVERTED), .Y(QQ)); @@ -220,22 +277,33 @@ module FDPE (output Q, input C, CE, D, PRE); endmodule module FDPE_1 (output Q, input C, CE, D, PRE); parameter [0:0] INIT = 1'b1; - wire DD, QQ, $nextQ, $abc9_currQ; - generate if (INIT == 1'b1) - assign DD = ~D, Q = ~QQ; - else - assign DD = D, Q = QQ; - endgenerate - FDPE_1 #( - .INIT(1'b0), - ) _TECHMAP_REPLACE_ ( - .D(DD), .Q($nextQ), .C(C), .CE(CE), .PRE(PRE) - // ^^^ Note that async - // control is not directly - // supported by abc9 but its - // behaviour is captured by - // $__ABC9_ASYNC below - ); + wire QQ, $nextQ, $abc9_currQ; + generate if (INIT == 1'b1) begin + assign Q = ~QQ; + FDCE_1 #( + .INIT(1'b0) + ) _TECHMAP_REPLACE_ ( + .D(~D), .Q($nextQ), .C(C), .CE(CE), .CLR(PRE) + // ^^^ Note that async + // control is not directly + // supported by abc9 but its + // behaviour is captured by + // $__ABC9_ASYNC below + ); + end + else begin + assign Q = QQ; + FDPE_1 #( + .INIT(1'b0) + ) _TECHMAP_REPLACE_ ( + .D(D), .Q($nextQ), .C(C), .CE(CE), .PRE(PRE) + // ^^^ Note that async + // control is not directly + // supported by abc9 but its + // behaviour is captured by + // $__ABC9_ASYNC below + ); + end endgenerate \$__ABC9_FF_ abc_dff (.D($nextQ), .Q($abc9_currQ)); \$__ABC9_ASYNC abc_async (.A($abc9_currQ), .S(PRE), .Y(QQ)); @@ -251,20 +319,29 @@ module FDSE (output Q, input C, CE, D, S); 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 DD, QQ, $nextQ; - generate if (INIT == 1'b1) - assign DD = ~D, Q = ~QQ; - else - assign DD = D, Q = QQ; - endgenerate - 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(DD), .Q($nextQ), .C(C), .CE(CE), .S(S) - ); + wire QQ, $nextQ; + 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($nextQ), .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($nextQ), .C(C), .CE(CE), .S(S) + ); + end endgenerate \$__ABC9_FF_ abc_dff (.D($nextQ), .Q(QQ)); // Special signals @@ -275,17 +352,23 @@ module FDSE (output Q, input C, CE, D, S); endmodule module FDSE_1 (output Q, input C, CE, D, S); parameter [0:0] INIT = 1'b1; - wire DD, QQ, $nextQ; - generate if (INIT == 1'b1) - assign DD = ~D, Q = ~QQ; - else - assign DD = D, Q = QQ; - endgenerate - FDSE_1 #( - .INIT(1'b0), - ) _TECHMAP_REPLACE_ ( - .D(DD), .Q($nextQ), .C(C), .CE(CE), .S(S) - ); + wire QQ, $nextQ; + generate if (INIT == 1'b1) begin + assign Q = ~QQ; + FDRE_1 #( + .INIT(1'b0) + ) _TECHMAP_REPLACE_ ( + .D(~D), .Q($nextQ), .C(C), .CE(CE), .R(S) + ); + end + else begin + assign Q = QQ; + FDSE_1 #( + .INIT(1'b0) + ) _TECHMAP_REPLACE_ ( + .D(D), .Q($nextQ), .C(C), .CE(CE), .S(S) + ); + end endgenerate \$__ABC9_FF_ abc_dff (.D($nextQ), .Q(QQ)); // Special signals diff --git a/tests/arch/xilinx/abc9_map.ys b/tests/arch/xilinx/abc9_map.ys new file mode 100644 index 000000000..6823589f1 --- /dev/null +++ b/tests/arch/xilinx/abc9_map.ys @@ -0,0 +1,91 @@ +read_verilog < Date: Wed, 4 Dec 2019 23:04:40 -0800 Subject: Missing wire declaration --- techlibs/xilinx/abc9_map.v | 1 + 1 file changed, 1 insertion(+) diff --git a/techlibs/xilinx/abc9_map.v b/techlibs/xilinx/abc9_map.v index 3fa5f5a1c..d2159f82d 100644 --- a/techlibs/xilinx/abc9_map.v +++ b/techlibs/xilinx/abc9_map.v @@ -192,6 +192,7 @@ module FDCE (output Q, input C, CE, D, CLR); endmodule module FDCE_1 (output Q, input C, CE, D, CLR); parameter [0:0] INIT = 1'b0; + wire QQ, $nextQ, $abc9_currQ; generate if (INIT == 1'b1) begin assign Q = ~QQ; FDPE_1 #( -- cgit v1.2.3 From 72a5674c03e6749263e61751616b05b3be80e7cc Mon Sep 17 00:00:00 2001 From: whitequark Date: Thu, 5 Dec 2019 09:39:34 +0000 Subject: manual: document $dffe, $dffsr, $_DFFE_*, $_DFFSR_* cells. --- manual/CHAPTER_CellLib.tex | 101 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 90 insertions(+), 11 deletions(-) diff --git a/manual/CHAPTER_CellLib.tex b/manual/CHAPTER_CellLib.tex index 0106059b6..6367a4b37 100644 --- a/manual/CHAPTER_CellLib.tex +++ b/manual/CHAPTER_CellLib.tex @@ -177,8 +177,8 @@ Verilog & Cell Type \\ \subsection{Registers} -D-Type Flip-Flops are represented by {\tt \$dff} cells. These cells have a clock port \B{CLK}, -an input port \B{D} and an output port \B{Q}. The following parameters are available for \$dff +D-type flip-flops are represented by {\tt \$dff} cells. These cells have a clock port \B{CLK}, +an input port \B{D} and an output port \B{Q}. The following parameters are available for {\tt \$dff} cells: \begin{itemize} @@ -190,13 +190,23 @@ Clock is active on the positive edge if this parameter has the value {\tt 1'b1} edge if this parameter is {\tt 1'b0}. \end{itemize} -D-Type Flip-Flops with asynchronous resets are represented by {\tt \$adff} cells. As the {\tt \$dff} +D-type flip-flops with enable are represented by {\tt \$dffe} cells. As the {\tt \$dff} +cells they have \B{CLK}, \B{D} and \B{Q} ports. In addition they also have a single-bit \B{EN} +input port for the enable pin and the following parameter: + +\begin{itemize} +\item \B{EN\_POLARITY} \\ +The enable input is active-high if this parameter has the value {\tt 1'b1} and active-low +if this parameter is {\tt 1'b0}. +\end{itemize} + +D-type flip-flops with asynchronous reset are represented by {\tt \$adff} cells. As the {\tt \$dff} cells they have \B{CLK}, \B{D} and \B{Q} ports. In addition they also have a single-bit \B{ARST} input port for the reset pin and the following additional two parameters: \begin{itemize} \item \B{ARST\_POLARITY} \\ -The asynchronous reset is high-active if this parameter has the value {\tt 1'b1} and low-active +The asynchronous reset is active-high if this parameter has the value {\tt 1'b1} and active-low if this parameter is {\tt 1'b0}. \item \B{ARST\_VALUE} \\ @@ -210,8 +220,27 @@ Usually these cells are generated by the {\tt proc} pass using the information in the designs RTLIL::Process objects. \end{sloppypar} +D-type flip-flops with asynchronous set and reset are represented by {\tt \$dffsr} cells. +As the {\tt \$dff} cells they have \B{CLK}, \B{D} and \B{Q} ports. In addition they also have +a single-bit \B{SET} input port for the set pin, a single-bit \B{CLR} input port for the reset pin, +and the following two parameters: + +\begin{itemize} +\item \B{SET\_POLARITY} \\ +The set input is active-high if this parameter has the value {\tt 1'b1} and active-low +if this parameter is {\tt 1'b0}. + +\item \B{CLR\_POLARITY} \\ +The reset input is active-high if this parameter has the value {\tt 1'b1} and active-low +if this parameter is {\tt 1'b0}. +\end{itemize} + +When both the set and reset inputs of a {\tt \$dffsr} cell are active, the reset input takes +precedence. + \begin{fixme} -Add information about {\tt \$sr} cells (set-reset flip-flops) and d-type latches. +Add information about {\tt \$sr} cells (set-reset flip-flops), {\tt \$dlatch} cells (d-type latches), +and {\tt \$dlatchsr} cells (d-type latches with set/reset). \end{fixme} \subsection{Memories} @@ -430,6 +459,30 @@ $ClkEdge$ & $RstLvl$ & $RstVal$ & Cell Type \\ \lstinline[language=Verilog];posedge; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];0; & {\tt \$\_DFF\_PP0\_} \\ \lstinline[language=Verilog];posedge; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];1; & {\tt \$\_DFF\_PP1\_} \\ \end{tabular} +% FIXME: the layout of this is broken and I have no idea how to fix it +\hfil +\begin{tabular}[t]{lll} +$ClkEdge$ & $EnLvl$ & Cell Type \\ +\hline +\lstinline[language=Verilog];negedge; & \lstinline[language=Verilog];0; & {\tt \$\_DFFE\_NN\_} \\ +\lstinline[language=Verilog];negedge; & \lstinline[language=Verilog];1; & {\tt \$\_DFFE\_NP\_} \\ +\lstinline[language=Verilog];posedge; & \lstinline[language=Verilog];0; & {\tt \$\_DFFE\_PN\_} \\ +\lstinline[language=Verilog];posedge; & \lstinline[language=Verilog];1; & {\tt \$\_DFFE\_PP\_} \\ +\end{tabular} +% FIXME: the layout of this is broken too +\hfil +\begin{tabular}[t]{llll} +$ClkEdge$ & $SetLvl$ & $RstLvl$ & Cell Type \\ +\hline +\lstinline[language=Verilog];negedge; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];0; & {\tt \$\_DFFSR\_NNN\_} \\ +\lstinline[language=Verilog];negedge; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];1; & {\tt \$\_DFFSR\_NNP\_} \\ +\lstinline[language=Verilog];negedge; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];0; & {\tt \$\_DFFSR\_NPN\_} \\ +\lstinline[language=Verilog];negedge; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];1; & {\tt \$\_DFFSR\_NPP\_} \\ +\lstinline[language=Verilog];posedge; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];0; & {\tt \$\_DFFSR\_PNN\_} \\ +\lstinline[language=Verilog];posedge; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];1; & {\tt \$\_DFFSR\_PNP\_} \\ +\lstinline[language=Verilog];posedge; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];0; & {\tt \$\_DFFSR\_PPN\_} \\ +\lstinline[language=Verilog];posedge; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];1; & {\tt \$\_DFFSR\_PPP\_} \\ +\end{tabular} \caption{Cell types for gate level logic networks} \label{tab:CellLib_gates} \end{table} @@ -438,11 +491,22 @@ Table~\ref{tab:CellLib_gates} lists all cell types used for gate level logic. Th {\tt \$\_NOT\_}, {\tt \$\_AND\_}, {\tt \$\_NAND\_}, {\tt \$\_ANDNOT\_}, {\tt \$\_OR\_}, {\tt \$\_NOR\_}, {\tt \$\_ORNOT\_}, {\tt \$\_XOR\_}, {\tt \$\_XNOR\_} and {\tt \$\_MUX\_} are used to model combinatorial logic. The cell type {\tt \$\_TBUF\_} is used to model tristate logic. + The cell types {\tt \$\_DFF\_N\_} and {\tt \$\_DFF\_P\_} represent d-type flip-flops. +The cell types {\tt \$\_DFFE\_NN\_}, {\tt \$\_DFFE\_NP\_}, {\tt \$\_DFFE\_PN\_} and {\tt \$\_DFFE\_PP\_} +implement d-type flip-flops with enable. The values in the table for these cell types relate to the +following Verilog code template. + +\begin{lstlisting}[mathescape,language=Verilog] + always @($ClkEdge$ C) + if (EN == $EnLvl$) + Q <= D; +\end{lstlisting} + The cell types {\tt \$\_DFF\_NN0\_}, {\tt \$\_DFF\_NN1\_}, {\tt \$\_DFF\_NP0\_}, {\tt \$\_DFF\_NP1\_}, {\tt \$\_DFF\_PN0\_}, {\tt \$\_DFF\_PN1\_}, {\tt \$\_DFF\_PP0\_} and {\tt \$\_DFF\_PP1\_} implement -d-type flip-flops with asynchronous resets. The values in the table for these cell types relate to the +d-type flip-flops with asynchronous reset. The values in the table for these cell types relate to the following Verilog code template, where \lstinline[mathescape,language=Verilog];$RstEdge$; is \lstinline[language=Verilog];posedge; if \lstinline[mathescape,language=Verilog];$RstLvl$; if \lstinline[language=Verilog];1;, and \lstinline[language=Verilog];negedge; otherwise. @@ -455,6 +519,25 @@ otherwise. Q <= D; \end{lstlisting} +The cell types {\tt \$\_DFFSR\_NNN\_}, {\tt \$\_DFFSR\_NNP\_}, {\tt \$\_DFFSR\_NPN\_}, {\tt \$\_DFFSR\_NPP\_}, +{\tt \$\_DFFSR\_PNN\_}, {\tt \$\_DFFSR\_PNP\_}, {\tt \$\_DFFSR\_PPN\_} and {\tt \$\_DFFSR\_PPP\_} implement +d-type flip-flops with asynchronous set and reset. The values in the table for these cell types relate to the +following Verilog code template, where \lstinline[mathescape,language=Verilog];$RstEdge$; is \lstinline[language=Verilog];posedge; +if \lstinline[mathescape,language=Verilog];$RstLvl$; if \lstinline[language=Verilog];1;, \lstinline[language=Verilog];negedge; +otherwise, and \lstinline[mathescape,language=Verilog];$SetEdge$; is \lstinline[language=Verilog];posedge; +if \lstinline[mathescape,language=Verilog];$SetLvl$; if \lstinline[language=Verilog];1;, \lstinline[language=Verilog];negedge; +otherwise. + +\begin{lstlisting}[mathescape,language=Verilog] + always @($ClkEdge$ C, $RstEdge$ R, $SetEdge$ S) + if (R == $RstLvl$) + Q <= 0; + else if (S == $SetLvl$) + Q <= 1; + else + Q <= D; +\end{lstlisting} + In most cases gate level logic networks are created from RTL networks using the {\tt techmap} pass. The flip-flop cells from the gate level logic network can be mapped to physical flip-flop cells from a Liberty file using the {\tt dfflibmap} pass. The combinatorial logic cells can be mapped to physical cells from a Liberty file via ABC \citeweblink{ABC} @@ -486,11 +569,7 @@ Add information about {\tt \$ff} and {\tt \$\_FF\_} cells. \end{fixme} \begin{fixme} -Add information about {\tt \$dffe}, {\tt \$dffsr}, {\tt \$dlatch}, and {\tt \$dlatchsr} cells. -\end{fixme} - -\begin{fixme} -Add information about {\tt \$\_DFFE\_??\_}, {\tt \$\_DFFSR\_???\_}, {\tt \$\_DLATCH\_?\_}, and {\tt \$\_DLATCHSR\_???\_} cells. +Add information about {\tt \$\_DLATCH\_?\_}, and {\tt \$\_DLATCHSR\_???\_} cells. \end{fixme} \begin{fixme} -- cgit v1.2.3 From 864bff14f11fc67bac40f77e5bf17c7fc61ad9f6 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 5 Dec 2019 11:11:53 -0800 Subject: Revert "Special abc9_clock wire to contain only clock signal" This reverts commit 6a2eb5d8f9286b9574647c03e2bdc8b63fccbe4d. --- techlibs/xilinx/abc9_map.v | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/techlibs/xilinx/abc9_map.v b/techlibs/xilinx/abc9_map.v index d2159f82d..4d76a5232 100644 --- a/techlibs/xilinx/abc9_map.v +++ b/techlibs/xilinx/abc9_map.v @@ -62,8 +62,10 @@ // 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) a special _TECHMAP_REPLACE_.$abc9_clock wire to indicate its clock -// signal, used to extract the delay target +// (b) a special _TECHMAP_REPLACE_.$abc9_clock wire to capture its clock +// domain (used when partitioning the module so that `abc9' only +// performs sequential synthesis (with reachability analysis) correctly on +// one domain at a time) and used to infert the delay target // (c) a special _TECHMAP_REPLACE_.$abc9_control wire that captures the control // domain (which, combined with this cell type, encodes to `abc9' which // flops may be merged together) @@ -107,7 +109,7 @@ module FDRE (output Q, input C, CE, D, R); \$__ABC9_FF_ abc_dff (.D($nextQ), .Q(QQ)); // Special signals - wire [0:0] _TECHMAP_REPLACE_.$abc9_clock = C; + wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, IS_C_INVERTED}; wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, IS_D_INVERTED, R, IS_R_INVERTED}; wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = QQ; @@ -135,7 +137,7 @@ module FDRE_1 (output Q, input C, CE, D, R); \$__ABC9_FF_ abc_dff (.D($nextQ), .Q(QQ)); // Special signals - wire [0:0] _TECHMAP_REPLACE_.$abc9_clock = C; + wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */}; wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, 1'b0 /* IS_D_INVERTED */, R, 1'b0 /* IS_R_INVERTED */}; wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = QQ; @@ -185,7 +187,7 @@ module FDCE (output Q, input C, CE, D, CLR); \$__ABC9_ASYNC abc_async (.A($abc9_currQ), .S(CLR ^ IS_CLR_INVERTED), .Y(QQ)); // Special signals - wire [0:0] _TECHMAP_REPLACE_.$abc9_clock = C; + wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, IS_C_INVERTED}; wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, IS_D_INVERTED, CLR, IS_CLR_INVERTED}; wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ; @@ -223,7 +225,7 @@ module FDCE_1 (output Q, input C, CE, D, CLR); \$__ABC9_ASYNC abc_async (.A($abc9_currQ), .S(CLR), .Y(QQ)); // Special signals - wire [0:0] _TECHMAP_REPLACE_.$abc9_clock = C; + wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */}; wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, 1'b0 /* IS_D_INVERTED */, CLR, 1'b0 /* IS_CLR_INVERTED */}; wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ; @@ -271,7 +273,7 @@ module FDPE (output Q, input C, CE, D, PRE); \$__ABC9_ASYNC abc_async (.A($abc9_currQ), .S(PRE ^ IS_PRE_INVERTED), .Y(QQ)); // Special signals - wire [0:0] _TECHMAP_REPLACE_.$abc9_clock = C; + wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, IS_C_INVERTED}; wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, IS_D_INVERTED, PRE, IS_PRE_INVERTED}; wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ; @@ -309,7 +311,7 @@ module FDPE_1 (output Q, input C, CE, D, PRE); \$__ABC9_ASYNC abc_async (.A($abc9_currQ), .S(PRE), .Y(QQ)); // Special signals - wire [0:0] _TECHMAP_REPLACE_.$abc9_clock = C; + wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */}; wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, 1'b0 /* IS_D_INVERTED */, PRE, 1'b0 /* IS_PRE_INVERTED */}; wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ; @@ -346,7 +348,7 @@ module FDSE (output Q, input C, CE, D, S); \$__ABC9_FF_ abc_dff (.D($nextQ), .Q(QQ)); // Special signals - wire [0:0] _TECHMAP_REPLACE_.$abc9_clock = C; + wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, IS_C_INVERTED}; wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, IS_D_INVERTED, S, IS_S_INVERTED}; wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = QQ; @@ -373,7 +375,7 @@ module FDSE_1 (output Q, input C, CE, D, S); \$__ABC9_FF_ abc_dff (.D($nextQ), .Q(QQ)); // Special signals - wire [0:0] _TECHMAP_REPLACE_.$abc9_clock = C; + wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */}; wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, 1'b0 /* IS_D_INVERTED */, S, 1'b0 /* IS_S_INVERTED */}; wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = QQ; -- cgit v1.2.3 From 02786b0aa0eb45a53b92b86b192d5ae5846366bd Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 5 Dec 2019 17:25:26 -0800 Subject: Remove clkpart --- passes/hierarchy/Makefile.inc | 1 - passes/hierarchy/clkpart.cc | 308 ---------------------------------------- techlibs/xilinx/synth_xilinx.cc | 4 - 3 files changed, 313 deletions(-) delete mode 100644 passes/hierarchy/clkpart.cc diff --git a/passes/hierarchy/Makefile.inc b/passes/hierarchy/Makefile.inc index ea809ec08..b3f139b72 100644 --- a/passes/hierarchy/Makefile.inc +++ b/passes/hierarchy/Makefile.inc @@ -2,5 +2,4 @@ OBJS += passes/hierarchy/hierarchy.o OBJS += passes/hierarchy/uniquify.o OBJS += passes/hierarchy/submod.o -OBJS += passes/hierarchy/clkpart.o diff --git a/passes/hierarchy/clkpart.cc b/passes/hierarchy/clkpart.cc deleted file mode 100644 index 2d295e915..000000000 --- a/passes/hierarchy/clkpart.cc +++ /dev/null @@ -1,308 +0,0 @@ -/* - * yosys -- Yosys Open SYnthesis Suite - * - * Copyright (C) 2012 Clifford Wolf - * 2019 Eddie Hung - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - */ - -#include "kernel/register.h" -#include "kernel/sigtools.h" -#include "kernel/celltypes.h" -#include "kernel/rtlil.h" -#include "kernel/log.h" - -USING_YOSYS_NAMESPACE -PRIVATE_NAMESPACE_BEGIN - -struct ClkPartPass : public Pass { - ClkPartPass() : Pass("clkpart", "partition design according to clock/enable domain") { } - void help() YS_OVERRIDE - { - // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| - log("\n"); - log(" clkpart [options] [selection]\n"); - log("\n"); - log("Partition the contents of selected modules according to the clock (and optionally\n"); - log("the enable) domains of its $_DFF* cells by extracting them into sub-modules,\n"); - log("using the `submod` command.\n"); - log("\n"); - log(" -set_attr \n"); - log(" set the specified attribute on all sub-modules created.\n"); - log("\n"); - log(" -unpart \n"); - log(" undo this operation within the selected modules, by flattening those\n"); - log(" attached with an attribute into those modules without this\n"); - log(" attribute.\n"); - log("\n"); - log(" -enable\n"); - log(" also consider enable domains.\n"); - log("\n"); - } - - bool unpart_mode, enable_mode; - IdString attr_name; - Const attr_value; - - void clear_flags() YS_OVERRIDE - { - unpart_mode = false; - enable_mode = false; - attr_name = IdString(); - attr_value = Const(); - } - void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE - { - log_header(design, "Executing CLKPART pass (partition design according to clock/enable domain).\n"); - log_push(); - - clear_flags(); - - size_t argidx; - for (argidx = 1; argidx < args.size(); argidx++) - { - if (args[argidx] == "-set_attr" && argidx+2 < args.size()) { - attr_name = RTLIL::escape_id(args[++argidx]); - attr_value = args[argidx++]; - continue; - } - if (args[argidx] == "-unpart" && argidx+1 < args.size()) { - unpart_mode = true; - attr_name = RTLIL::escape_id(args[++argidx]); - continue; - } - if (args[argidx] == "-enable") { - enable_mode = true; - continue; - } - break; - } - extra_args(args, argidx, design); - - if (unpart_mode) - unpart(design); - else - part(design); - - log_pop(); - } - - void part(RTLIL::Design *design) - { - CellTypes ct(design); - SigMap assign_map; - std::vector new_submods; - - log_header(design, "Summary of detected clock domains:\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; - } - - assign_map.set(mod); - - std::vector all_cells = mod->selected_cells(); - pool unassigned_cells(all_cells.begin(), all_cells.end()); - - pool expand_queue, next_expand_queue; - pool expand_queue_up, next_expand_queue_up; - pool expand_queue_down, next_expand_queue_down; - - typedef tuple clkdomain_t; - std::map> assigned_cells; - std::map assigned_cells_reverse; - - std::map> cell_to_bit, cell_to_bit_up, cell_to_bit_down; - std::map> bit_to_cell, bit_to_cell_up, bit_to_cell_down; - - for (auto cell : all_cells) - { - clkdomain_t key; - - for (auto &conn : cell->connections()) - for (auto bit : conn.second) { - bit = assign_map(bit); - if (bit.wire != nullptr) { - cell_to_bit[cell].insert(bit); - bit_to_cell[bit].insert(cell); - if (ct.cell_input(cell->type, conn.first)) { - cell_to_bit_up[cell].insert(bit); - bit_to_cell_down[bit].insert(cell); - } - if (ct.cell_output(cell->type, conn.first)) { - cell_to_bit_down[cell].insert(bit); - bit_to_cell_up[bit].insert(cell); - } - } - } - - if (cell->type.in(ID($_DFF_N_), ID($_DFF_P_))) - { - key = clkdomain_t(cell->type == ID($_DFF_P_), assign_map(cell->getPort(ID(C))), true, RTLIL::SigSpec()); - } - else - if (cell->type.in(ID($_DFFE_NN_), ID($_DFFE_NP_), ID($_DFFE_PN_), ID($_DFFE_PP_))) - { - bool this_clk_pol = cell->type.in(ID($_DFFE_PN_), ID($_DFFE_PP_)); - bool this_en_pol = !enable_mode || cell->type.in(ID($_DFFE_NP_), ID($_DFFE_PP_)); - key = clkdomain_t(this_clk_pol, assign_map(cell->getPort(ID(C))), this_en_pol, enable_mode ? assign_map(cell->getPort(ID(E))) : RTLIL::SigSpec()); - } - else - if (cell->type.in(ID($_DFF_NN0_), ID($_DFF_NN1_), ID($_DFF_NP0_), ID($_DFF_NP1_), - ID($_DFF_PN0_), ID($_DFF_PN1_), ID($_DFF_PP0_), ID($_DFF_PP1_))) - { - bool this_clk_pol = cell->type.in(ID($_DFF_PN0_), ID($_DFF_PN1_), ID($_DFF_PP0_), ID($_DFF_PP1_)); - log_assert(!enable_mode); // TODO - key = clkdomain_t(this_clk_pol, assign_map(cell->getPort(ID(C))), true, RTLIL::SigSpec()); - } - else - continue; - - unassigned_cells.erase(cell); - expand_queue.insert(cell); - expand_queue_up.insert(cell); - expand_queue_down.insert(cell); - - assigned_cells[key].push_back(cell); - assigned_cells_reverse[cell] = key; - } - - while (!expand_queue_up.empty() || !expand_queue_down.empty()) - { - if (!expand_queue_up.empty()) - { - RTLIL::Cell *cell = *expand_queue_up.begin(); - clkdomain_t key = assigned_cells_reverse.at(cell); - expand_queue_up.erase(cell); - - for (auto bit : cell_to_bit_up[cell]) - for (auto c : bit_to_cell_up[bit]) - if (unassigned_cells.count(c)) { - unassigned_cells.erase(c); - next_expand_queue_up.insert(c); - assigned_cells[key].push_back(c); - assigned_cells_reverse[c] = key; - expand_queue.insert(c); - } - } - - if (!expand_queue_down.empty()) - { - RTLIL::Cell *cell = *expand_queue_down.begin(); - clkdomain_t key = assigned_cells_reverse.at(cell); - expand_queue_down.erase(cell); - - for (auto bit : cell_to_bit_down[cell]) - for (auto c : bit_to_cell_down[bit]) - if (unassigned_cells.count(c)) { - unassigned_cells.erase(c); - next_expand_queue_up.insert(c); - assigned_cells[key].push_back(c); - assigned_cells_reverse[c] = key; - expand_queue.insert(c); - } - } - - if (expand_queue_up.empty() && expand_queue_down.empty()) { - expand_queue_up.swap(next_expand_queue_up); - expand_queue_down.swap(next_expand_queue_down); - } - } - - while (!expand_queue.empty()) - { - RTLIL::Cell *cell = *expand_queue.begin(); - clkdomain_t key = assigned_cells_reverse.at(cell); - expand_queue.erase(cell); - - for (auto bit : cell_to_bit.at(cell)) { - for (auto c : bit_to_cell[bit]) - if (unassigned_cells.count(c)) { - unassigned_cells.erase(c); - next_expand_queue.insert(c); - assigned_cells[key].push_back(c); - assigned_cells_reverse[c] = key; - } - bit_to_cell[bit].clear(); - } - - if (expand_queue.empty()) - expand_queue.swap(next_expand_queue); - } - - clkdomain_t key(true, RTLIL::SigSpec(), true, RTLIL::SigSpec()); - for (auto cell : unassigned_cells) { - assigned_cells[key].push_back(cell); - assigned_cells_reverse[cell] = key; - } - - clkdomain_t largest_domain; - int largest_domain_size = 0; - log(" module %s\n", mod->name.c_str()); - 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))); - if (GetSize(it.second) > largest_domain_size) { - largest_domain = it.first; - largest_domain_size = GetSize(it.second); - } - } - - for (auto &it : assigned_cells) { - if (it.first == largest_domain) - continue; - - auto clk = std::get<1>(it.first); - auto en = std::get<3>(it.first); - std::string submod = stringf("clk=%s%s%s%s%s", - std::get<0>(it.first) ? "" : "!", clk.empty() ? "" : log_signal(clk), - std::get<2>(it.first) ? "" : "!", en.empty() ? "" : ".en=", en.empty() ? "" : log_signal(en)); - for (auto c : it.second) - c->attributes[ID(submod)] = submod; - new_submods.push_back(stringf("%s_%s", mod->name.c_str(), submod.c_str())); - } - } - - Pass::call(design, "submod -hidden"); - - if (!attr_name.empty()) - for (auto m : new_submods) - design->module(m)->attributes[attr_name] = attr_value; - } - - void unpart(RTLIL::Design *design) - { - vector keeped; - for (auto mod : design->selected_modules()) { - if (mod->get_bool_attribute(attr_name)) - continue; - if (mod->get_bool_attribute(ID(keep_hierarchy))) - continue; - keeped.push_back(mod); - mod->set_bool_attribute(ID(keep_hierarchy)); - } - - Pass::call(design, "flatten"); - - for (auto mod : keeped) - mod->set_bool_attribute(ID(keep_hierarchy), false); - - } -} ClkPartPass; - -PRIVATE_NAMESPACE_END diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index 3fffd81f6..30be9832c 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -513,7 +513,6 @@ struct SynthXilinxPass : public ScriptPass if (check_label("map_ffs")) { if (abc9 || help_mode) { - run("clkpart -set_attr clkpart 1", "('-abc9' only)"); run("techmap -map " + ff_map_file, "('-abc9' only)"); } } @@ -561,9 +560,6 @@ struct SynthXilinxPass : public ScriptPass } if (check_label("finalize")) { - if (help_mode || abc9) - run("clkpart -unpart clkpart", "(only if 'abc9')"); - bool do_iopad = iopad || (ise && !noiopad); if (help_mode || !noclkbuf) { if (help_mode || do_iopad) -- cgit v1.2.3 From 01a3cc29ba8dbadea254a205809f583d4a860672 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 5 Dec 2019 17:26:22 -0800 Subject: abc9 to do clock partitioning again --- passes/techmap/abc9.cc | 181 +++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 144 insertions(+), 37 deletions(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 5b4100574..0237724f6 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -752,10 +752,6 @@ struct Abc9Pass : public Pass { 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("Selection must only contain fully selected modules. It is assumed that such\n"); - log("modules contain only cells belonging to the same clock domain, as produced by\n"); - log("the 'clkpart' command.\n"); - log("\n"); log(" -exe \n"); #ifdef ABCEXTERNAL log(" use the specified command instead of \"" ABCEXTERNAL "\" to execute ABC.\n"); @@ -1076,6 +1072,8 @@ struct Abc9Pass : public Pass { } } + SigMap assign_map; + CellTypes ct(design); for (auto module : design->selected_modules()) { if (module->attributes.count(ID(abc9_box_id))) @@ -1086,65 +1084,174 @@ struct Abc9Pass : public Pass { continue; } - if (!design->selected_whole_module(module)) { - log("Skipping module %s as it is partially selected.\n", log_id(module)); - continue; - } + assign_map.set(module); + + std::vector all_cells = module->selected_cells(); + std::set unassigned_cells(all_cells.begin(), all_cells.end()); + + std::set expand_queue, next_expand_queue; + std::set expand_queue_up, next_expand_queue_up; + std::set expand_queue_down, next_expand_queue_down; - SigMap sigmap(module); + std::map> assigned_cells; + std::map assigned_cells_reverse; + + std::map> cell_to_bit, cell_to_bit_up, cell_to_bit_down; + std::map> bit_to_cell, bit_to_cell_up, bit_to_cell_down; typedef std::pair ctrldomain_t; std::map mergeability_class; - pool clocks; - std::string target = delay_target; - for (auto cell : module->cells()) { + for (auto cell : all_cells) { + for (auto &conn : cell->connections()) + for (auto bit : assign_map(conn.second)) + 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); + } + } + auto inst_module = design->module(cell->type); if (!inst_module || !inst_module->attributes.count("\\abc9_flop")) continue; - if (delay_target.empty()) { - Wire *abc9_clock_wire = module->wire(stringf("%s.$abc9_clock", cell->name.c_str())); - if (abc9_clock_wire == NULL) - log_error("'%s.$abc9_clock' is not a wire present in module '%s'.\n", cell->name.c_str(), log_id(module)); - log_assert(GetSize(abc9_clock_wire) == 1); - SigBit abc9_clock = sigmap(abc9_clock_wire); - auto r = clocks.insert(abc9_clock.wire); - if (r.second) { - auto it = abc9_clock.wire->attributes.find("\\abc9_period"); - if (it != abc9_clock.wire->attributes.end()) { - int period = it->second.as_int(); - log("Identified target period = %d ps for clock %s\n", period, log_signal(abc9_clock)); - target = stringf("-D %d", period); - } - } - } + Wire *abc9_clock_wire = module->wire(stringf("%s.$abc9_clock", cell->name.c_str())); + if (abc9_clock_wire == NULL) + log_error("'%s$abc9_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); Wire *abc9_control_wire = module->wire(stringf("%s.$abc9_control", cell->name.c_str())); if (abc9_control_wire == NULL) - log_error("'%s.$abc9_control' is not a wire present in module '%s'.\n", cell->name.c_str(), log_id(module)); - SigSpec abc9_control = sigmap(abc9_control_wire); + log_error("'%s$abc9_control' is not a wire present in module '%s'.\n", cell->name.c_str(), log_id(module)); + SigSpec abc9_control = assign_map(abc9_control_wire); + + unassigned_cells.erase(cell); + expand_queue.insert(cell); + expand_queue_up.insert(cell); + expand_queue_down.insert(cell); + + assigned_cells[abc9_clock].insert(cell->name); + assigned_cells_reverse[cell] = abc9_clock; ctrldomain_t key(cell->type, abc9_control); auto r = mergeability_class.emplace(key, mergeability_class.size() + 1); - auto YS_ATTRIBUTE(unused) r2 = cell->attributes.insert(std::make_pair(ID(abc9_mergeability), r.first->second)); + auto YS_ATTRIBUTE(unused) r2 = cell->attributes.insert(std::make_pair(ID(abc9_mergeability), r.first->second)); log_assert(r2.second); Wire *abc9_init_wire = module->wire(stringf("%s.$abc9_init", cell->name.c_str())); if (abc9_init_wire == NULL) - log_error("'%s.$abc9_init' is not a wire present in module '%s'.\n", cell->name.c_str(), log_id(module)); + log_error("'%s.$abc9_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 = sigmap(abc9_init_wire); + SigSpec abc9_init = assign_map(abc9_init_wire); if (!abc9_init.is_fully_const()) - log_error("'%s.$abc9_init' is not a constant wire present in module '%s'.\n", cell->name.c_str(), log_id(module)); + log_error("'%s.$abc9_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); } + while (!expand_queue_up.empty() || !expand_queue_down.empty()) + { + if (!expand_queue_up.empty()) + { + RTLIL::Cell *cell = *expand_queue_up.begin(); + SigSpec 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) && !c->type.in("$__ABC9_FF_", "$__ABC9_ASYNC_")) { + unassigned_cells.erase(c); + next_expand_queue_up.insert(c); + assigned_cells[key].insert(c->name); + assigned_cells_reverse[c] = key; + expand_queue.insert(c); + } + } + + if (!expand_queue_down.empty()) + { + RTLIL::Cell *cell = *expand_queue_down.begin(); + SigSpec 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].insert(c->name); + 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(); + SigSpec 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].insert(c->name); + assigned_cells_reverse[c] = key; + } + bit_to_cell[bit].clear(); + } + + if (expand_queue.empty()) + expand_queue.swap(next_expand_queue); + } + + SigSpec key; + for (auto cell : unassigned_cells) { + assigned_cells[key].insert(cell->name); + 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\n", GetSize(it.second), log_signal(it.first)); + + design->selection_stack.emplace_back(false); design->selected_active_module = module->name.str(); - abc9_module(design, module, script_file, exe_file, cleanup, lut_costs, false, "$", - keepff, target, lutin_shared, fast_mode, show_tempdir, - box_file, lut_file, wire_delay, box_lookup, nomfs); + for (auto &it : assigned_cells) { + std::string target = delay_target; + if (target.empty()) { + for (auto b : assign_map(it.first)) + if (b.wire) { + auto jt = b.wire->attributes.find("\\abc9_period"); + if (jt != b.wire->attributes.end()) { + target = stringf("-D %d", jt->second.as_int()); + log("Target period = %s ps for clock domain %s\n", target.c_str(), log_signal(it.first)); + break; + } + } + } + RTLIL::Selection& sel = design->selection_stack.back(); + sel.selected_members[module->name] = std::move(it.second); + abc9_module(design, module, script_file, exe_file, cleanup, lut_costs, false, "$", + keepff, target, lutin_shared, fast_mode, show_tempdir, + box_file, lut_file, wire_delay, box_lookup, nomfs); + assign_map.set(module); + } + design->selection_stack.pop_back(); design->selected_active_module.clear(); } -- cgit v1.2.3 From a682a3cf9393787a21ef64c4f7273ceeccdbd357 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 5 Dec 2019 17:54:43 -0800 Subject: write_xaiger to support part-selected modules again --- backends/aiger/xaiger.cc | 48 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 37 insertions(+), 11 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index c6d24cf94..8b4cebe60 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -78,7 +78,7 @@ struct XAigerWriter Module *module; SigMap sigmap; - pool input_bits, output_bits; + pool input_bits, output_bits, external_bits; dict not_map, alias_map; dict> and_map; vector> ci_bits; @@ -154,6 +154,11 @@ struct XAigerWriter if (wire->port_input) sigmap.add(wire); + // promote output wires + for (auto wire : module->wires()) + if (wire->port_output) + sigmap.add(wire); + for (auto wire : module->wires()) { bool keep = wire->attributes.count("\\keep"); @@ -168,20 +173,29 @@ struct XAigerWriter unused_bits.insert(bit); } - if (keep) + if (keep) { keep_bits.insert(wirebit); + if (bit != wirebit) + alias_map[wirebit] = bit; + input_bits.insert(wirebit); + output_bits.insert(wirebit); + continue; + } - if (wire->port_input || keep) { + if (wire->port_input) { if (bit != wirebit) alias_map[bit] = wirebit; input_bits.insert(wirebit); } - if (wire->port_output || keep) { + if (wire->port_output) { if (bit != RTLIL::Sx) { if (bit != wirebit) alias_map[wirebit] = bit; - output_bits.insert(wirebit); + if (holes_mode) + output_bits.insert(wirebit); + else + external_bits.insert(wirebit); } else log_debug("Skipping PO '%s' driven by 1'bx\n", log_signal(wirebit)); @@ -293,7 +307,7 @@ struct XAigerWriter if (I != b) alias_map[b] = I; output_bits.insert(b); - unused_bits.erase(b); + unused_bits.erase(I); if (!cell_known) keep_bits.insert(b); @@ -329,6 +343,12 @@ struct XAigerWriter //log_warning("Unsupported cell type: %s (%s)\n", log_id(cell->type), log_id(cell)); } + for (auto cell : module->cells()) + if (!module->selected(cell)) + for (auto &conn : cell->connections()) + for (auto bit : sigmap(conn.second)) + external_bits.insert(bit); + if (abc9_box_seen) { dict> flop_q; for (auto cell : flop_boxes) { @@ -449,7 +469,7 @@ struct XAigerWriter alias_map[b] = I; } co_bits.emplace_back(b, cell, port_name, offset++, 0); - unused_bits.erase(b); + unused_bits.erase(I); } } if (w->port_output) { @@ -498,7 +518,7 @@ struct XAigerWriter alias_map[b] = I; } co_bits.emplace_back(b, cell, "\\$abc9_currQ", offset++, 0); - unused_bits.erase(b); + unused_bits.erase(I); } } @@ -542,16 +562,22 @@ struct XAigerWriter } } + for (auto bit : external_bits) + if (!undriven_bits.count(sigmap(bit))) { + output_bits.insert(bit); + unused_bits.erase(sigmap(bit)); + } + for (auto bit : unused_bits) undriven_bits.erase(bit); if (!undriven_bits.empty() && !holes_mode) { - undriven_bits.sort(); + //undriven_bits.sort(); for (auto bit : undriven_bits) { - log_warning("Treating undriven bit %s.%s like $anyseq.\n", log_id(module), log_signal(bit)); + //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)); + //log_warning("Treating a total of %d undriven bits in %s like $anyseq.\n", GetSize(undriven_bits), log_id(module)); } if (holes_mode) { -- cgit v1.2.3 From ec0acc9f85af0d21ea722375788b372cc416f173 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 5 Dec 2019 23:18:27 -0800 Subject: abc9 to use mergeability class to differentiate sync/async --- techlibs/xilinx/abc9_map.v | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/techlibs/xilinx/abc9_map.v b/techlibs/xilinx/abc9_map.v index 4d76a5232..d5d5a89f6 100644 --- a/techlibs/xilinx/abc9_map.v +++ b/techlibs/xilinx/abc9_map.v @@ -62,16 +62,18 @@ // 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) a special _TECHMAP_REPLACE_.$abc9_clock wire to capture its clock +// (b) an optional $__ABC9_ASYNC_ cell in front of $__ABC_FF_'s output to +// capture asynchronous behaviour +// (c) a special _TECHMAP_REPLACE_.$abc9_clock wire to capture its clock // domain (used when partitioning the module so that `abc9' only // performs sequential synthesis (with reachability analysis) correctly on // one domain at a time) and used to infert the delay target -// (c) a special _TECHMAP_REPLACE_.$abc9_control wire that captures the control +// (d) a special _TECHMAP_REPLACE_.$abc9_control wire that captures the control // domain (which, combined with this cell type, encodes to `abc9' which // flops may be merged together) -// (d) a special _TECHMAP_REPLACE_.$abc9_init wire to encode the flop's initial +// (e) a special _TECHMAP_REPLACE_.$abc9_init wire to encode the flop's initial // state -// (e) a special _TECHMAP_REPLACE_.$abc9_currQ wire that will be used for feedback +// (f) a special _TECHMAP_REPLACE_.$abc9_currQ wire that will be used for feedback // into the (combinatorial) FD* cell to facilitate clock-enable behaviour // // In order to perform sequential synthesis, `abc9' also requires that @@ -110,7 +112,7 @@ module FDRE (output Q, input C, CE, D, R); // Special signals wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, IS_C_INVERTED}; - wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, IS_D_INVERTED, R, IS_R_INVERTED}; + wire [0:0] _TECHMAP_REPLACE_.$abc9_control = {1'b0 /* async */}; wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = QQ; endmodule @@ -138,7 +140,7 @@ module FDRE_1 (output Q, input C, CE, D, R); // Special signals wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */}; - wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, 1'b0 /* IS_D_INVERTED */, R, 1'b0 /* IS_R_INVERTED */}; + wire [0:0] _TECHMAP_REPLACE_.$abc9_control = {1'b1 /* async */}; wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = QQ; endmodule @@ -188,7 +190,7 @@ module FDCE (output Q, input C, CE, D, CLR); // Special signals wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, IS_C_INVERTED}; - wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, IS_D_INVERTED, CLR, IS_CLR_INVERTED}; + wire [0:0] _TECHMAP_REPLACE_.$abc9_control = {1'b1 /* async */}; wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ; endmodule @@ -226,7 +228,7 @@ module FDCE_1 (output Q, input C, CE, D, CLR); // Special signals wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */}; - wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, 1'b0 /* IS_D_INVERTED */, CLR, 1'b0 /* IS_CLR_INVERTED */}; + wire [0:0] _TECHMAP_REPLACE_.$abc9_control = {1'b1 /* async */}; wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ; endmodule @@ -274,7 +276,7 @@ module FDPE (output Q, input C, CE, D, PRE); // Special signals wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, IS_C_INVERTED}; - wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, IS_D_INVERTED, PRE, IS_PRE_INVERTED}; + wire [0:0] _TECHMAP_REPLACE_.$abc9_control = {1'b1 /* async */}; wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ; endmodule @@ -312,7 +314,8 @@ module FDPE_1 (output Q, input C, CE, D, PRE); // Special signals wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */}; - wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, 1'b0 /* IS_D_INVERTED */, PRE, 1'b0 /* IS_PRE_INVERTED */}; + wire [0:0] _TECHMAP_REPLACE_.$abc9_control = {1'b1 /* async */}; +>>>>>>> d3b23690... abc9 to use mergeability class to differentiate sync/async wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ; endmodule @@ -349,7 +352,7 @@ module FDSE (output Q, input C, CE, D, S); // Special signals wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, IS_C_INVERTED}; - wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, IS_D_INVERTED, S, IS_S_INVERTED}; + wire [0:0] _TECHMAP_REPLACE_.$abc9_control = {1'b0 /* async */}; wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = QQ; endmodule @@ -376,7 +379,7 @@ module FDSE_1 (output Q, input C, CE, D, S); // Special signals wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */}; - wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, 1'b0 /* IS_D_INVERTED */, S, 1'b0 /* IS_S_INVERTED */}; + wire [0:0] _TECHMAP_REPLACE_.$abc9_control = {1'b0 /* async */}; wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = QQ; endmodule -- cgit v1.2.3 From 1f96de04c9da12e17df0a8bf27f83b4fe4af8595 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 6 Dec 2019 16:19:10 -0800 Subject: Fix writing non-whole modules, including inouts and keeps --- backends/aiger/xaiger.cc | 171 ++++++++++++++++++++++------------------------- 1 file changed, 81 insertions(+), 90 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 8b4cebe60..c080cca4d 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -142,7 +142,7 @@ struct XAigerWriter { pool undriven_bits; pool unused_bits; - pool keep_bits; + pool inout_bits; // promote public wires for (auto wire : module->wires()) @@ -154,60 +154,45 @@ struct XAigerWriter if (wire->port_input) sigmap.add(wire); - // promote output wires + // promote keep wires for (auto wire : module->wires()) - if (wire->port_output) + if (wire->get_bool_attribute(ID::keep)) sigmap.add(wire); for (auto wire : module->wires()) - { - bool keep = wire->attributes.count("\\keep"); - 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 (keep) { - keep_bits.insert(wirebit); - if (bit != wirebit) - alias_map[wirebit] = bit; - input_bits.insert(wirebit); - output_bits.insert(wirebit); + if (bit.wire == nullptr) { + if (wire->port_output) { + aig_map[wirebit] = (bit == State::S1) ? 1 : 0; + if (holes_mode) + output_bits.insert(wirebit); + //external_bits.insert(wirebit); + } continue; } - if (wire->port_input) { - if (bit != wirebit) - alias_map[bit] = wirebit; - input_bits.insert(wirebit); - } + undriven_bits.insert(bit); + unused_bits.insert(bit); + + if (wire->port_input) + input_bits.insert(bit); if (wire->port_output) { - if (bit != RTLIL::Sx) { - if (bit != wirebit) - alias_map[wirebit] = bit; - if (holes_mode) - output_bits.insert(wirebit); - else - external_bits.insert(wirebit); - } + if (bit != wirebit) + alias_map[wirebit] = bit; + if (holes_mode) + output_bits.insert(wirebit); else - log_debug("Skipping PO '%s' driven by 1'bx\n", log_signal(wirebit)); + external_bits.insert(wirebit); } - } - } - // Cannot fold into above due to use of sigmap - for (auto bit : input_bits) - undriven_bits.erase(sigmap(bit)); - for (auto bit : output_bits) - unused_bits.erase(sigmap(bit)); + if (wire->port_input && wire->port_output) + inout_bits.insert(bit); + } // TODO: Speed up toposort -- ultimately we care about // box ordering, but not individual AIG cells @@ -307,10 +292,9 @@ struct XAigerWriter if (I != b) alias_map[b] = I; output_bits.insert(b); - unused_bits.erase(I); if (!cell_known) - keep_bits.insert(b); + inout_bits.insert(b); } } } @@ -328,11 +312,10 @@ struct XAigerWriter 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); + input_bits.insert(b); if (arrival) arrival_times[b] = arrival; @@ -343,12 +326,6 @@ struct XAigerWriter //log_warning("Unsupported cell type: %s (%s)\n", log_id(cell->type), log_id(cell)); } - for (auto cell : module->cells()) - if (!module->selected(cell)) - for (auto &conn : cell->connections()) - for (auto bit : sigmap(conn.second)) - external_bits.insert(bit); - if (abc9_box_seen) { dict> flop_q; for (auto cell : flop_boxes) { @@ -494,8 +471,8 @@ struct XAigerWriter SigBit O = sigmap(b); if (O != b) alias_map[O] = b; - undriven_bits.erase(O); input_bits.erase(b); + undriven_bits.erase(O); } } } @@ -528,56 +505,70 @@ struct XAigerWriter // TODO: Free memory from toposort, bit_drivers, bit_users } - for (auto bit : input_bits) { - if (!output_bits.count(bit)) + if (!holes_mode) + for (auto cell : module->cells()) + if (!module->selected(cell)) + for (auto &conn : cell->connections()) + if (cell->input(conn.first)) + for (auto wirebit : conn.second) + if (sigmap(wirebit).wire) + external_bits.insert(wirebit); + + // For all bits consumed outside of the selected cells, + // but driven from a selected cell, then add it as + // a primary output + for (auto wirebit : external_bits) { + SigBit bit = sigmap(wirebit); + if (!bit.wire) continue; - 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; - } - else if (and_map.count(bit)) { - auto a = and_map.at(bit); - and_map[new_bit] = a; - } - else if (alias_map.count(bit)) { - auto a = alias_map.at(bit); - alias_map[new_bit] = a; - } - else - alias_map[new_bit] = bit; - output_bits.erase(bit); - output_bits.insert(new_bit); + if (!undriven_bits.count(bit)) { + if (bit != wirebit) + alias_map[wirebit] = bit; + output_bits.insert(wirebit); } } - for (auto bit : external_bits) - if (!undriven_bits.count(sigmap(bit))) { - output_bits.insert(bit); - unused_bits.erase(sigmap(bit)); - } - + for (auto bit : input_bits) + undriven_bits.erase(sigmap(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(); + // Make all undriven bits a primary input + if (!holes_mode) for (auto bit : undriven_bits) { - //log_warning("Treating undriven bit %s.%s like $anyseq.\n", log_id(module), log_signal(bit)); input_bits.insert(bit); + undriven_bits.erase(bit); + } + + // For inout ports, or keep-ed wires, then create a new wire with an + // $inout.out suffix, make it a PO driven by the existing inout, and + // inherit existing inout's drivers + for (auto bit : inout_bits) { + RTLIL::Wire *wire = bit.wire; + 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; + } + else if (and_map.count(bit)) { + auto a = and_map.at(bit); + and_map[new_bit] = a; + } + else if (alias_map.count(bit)) { + auto a = alias_map.at(bit); + alias_map[new_bit] = a; } - //log_warning("Treating a total of %d undriven bits in %s like $anyseq.\n", GetSize(undriven_bits), log_id(module)); + else + alias_map[new_bit] = bit; + output_bits.erase(bit); + output_bits.insert(new_bit); } if (holes_mode) { @@ -880,7 +871,7 @@ struct XAigerWriter 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_")) { + "$_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 -- cgit v1.2.3 From fce527f4f7764ae2e2d5f6a7e01da59075f79350 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 6 Dec 2019 16:20:18 -0800 Subject: Fix abc9 re-integration, remove abc9_control_wire, use cell->type as as part of clock domain for mergeability class --- passes/techmap/abc9.cc | 54 ++++++++++++++------------------------------------ 1 file changed, 15 insertions(+), 39 deletions(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 0237724f6..2d1ce318a 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -30,7 +30,7 @@ "&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; time" +#define ABC_COMMAND_LUT "&st; &scorr; &sweep; &dc2; &st; &dch -f; &ps; &if {W} {D} -v; &mfs; &ps -l" #endif @@ -429,26 +429,10 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip if (mapped_mod == NULL) log_error("ABC output file does not contain a module `$__abc9__'.\n"); - pool output_bits; for (auto &it : mapped_mod->wires_) { RTLIL::Wire *w = it.second; RTLIL::Wire *remap_wire = module->addWire(remap_name(w->name), GetSize(w)); if (markgroups) remap_wire->attributes[ID(abcgroup)] = map_autoidx; - if (w->port_output) { - RTLIL::Wire *wire = module->wire(w->name); - log_assert(wire); - for (int i = 0; i < GetSize(w); i++) - output_bits.insert({wire, i}); - } - } - - for (auto &it : module->connections_) { - auto &signal = it.first; - auto bits = signal.bits(); - for (auto &b : bits) - if (output_bits.count(b)) - b = module->addWire(NEW_ID); - signal = std::move(bits); } dict abc9_box; @@ -1093,15 +1077,13 @@ struct Abc9Pass : public Pass { std::set expand_queue_up, next_expand_queue_up; std::set expand_queue_down, next_expand_queue_down; - std::map> assigned_cells; - std::map assigned_cells_reverse; + typedef std::pair clkdomain_t; + std::map> assigned_cells; + std::map assigned_cells_reverse; std::map> cell_to_bit, cell_to_bit_up, cell_to_bit_down; std::map> bit_to_cell, bit_to_cell_up, bit_to_cell_down; - typedef std::pair ctrldomain_t; - std::map mergeability_class; - for (auto cell : all_cells) { for (auto &conn : cell->connections()) for (auto bit : assign_map(conn.second)) @@ -1127,22 +1109,16 @@ struct Abc9Pass : public Pass { log_error("'%s$abc9_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); - Wire *abc9_control_wire = module->wire(stringf("%s.$abc9_control", cell->name.c_str())); - if (abc9_control_wire == NULL) - log_error("'%s$abc9_control' is not a wire present in module '%s'.\n", cell->name.c_str(), log_id(module)); - SigSpec abc9_control = assign_map(abc9_control_wire); - unassigned_cells.erase(cell); expand_queue.insert(cell); expand_queue_up.insert(cell); expand_queue_down.insert(cell); - assigned_cells[abc9_clock].insert(cell->name); - assigned_cells_reverse[cell] = abc9_clock; + clkdomain_t key(abc9_clock, cell->type); + assigned_cells[key].insert(cell->name); + assigned_cells_reverse[cell] = key; - ctrldomain_t key(cell->type, abc9_control); - auto r = mergeability_class.emplace(key, mergeability_class.size() + 1); - auto YS_ATTRIBUTE(unused) r2 = cell->attributes.insert(std::make_pair(ID(abc9_mergeability), r.first->second)); + auto YS_ATTRIBUTE(unused) r2 = cell->attributes.insert(std::make_pair(ID(abc9_mergeability), 1)); log_assert(r2.second); Wire *abc9_init_wire = module->wire(stringf("%s.$abc9_init", cell->name.c_str())); @@ -1161,7 +1137,7 @@ struct Abc9Pass : public Pass { if (!expand_queue_up.empty()) { RTLIL::Cell *cell = *expand_queue_up.begin(); - SigSpec key = assigned_cells_reverse.at(cell); + auto key = assigned_cells_reverse.at(cell); expand_queue_up.erase(cell); for (auto bit : cell_to_bit_up[cell]) @@ -1178,7 +1154,7 @@ struct Abc9Pass : public Pass { if (!expand_queue_down.empty()) { RTLIL::Cell *cell = *expand_queue_down.begin(); - SigSpec key = assigned_cells_reverse.at(cell); + auto key = assigned_cells_reverse.at(cell); expand_queue_down.erase(cell); for (auto bit : cell_to_bit_down[cell]) @@ -1201,7 +1177,7 @@ struct Abc9Pass : public Pass { while (!expand_queue.empty()) { RTLIL::Cell *cell = *expand_queue.begin(); - SigSpec key = assigned_cells_reverse.at(cell); + auto key = assigned_cells_reverse.at(cell); expand_queue.erase(cell); for (auto bit : cell_to_bit.at(cell)) { @@ -1219,7 +1195,7 @@ struct Abc9Pass : public Pass { expand_queue.swap(next_expand_queue); } - SigSpec key; + clkdomain_t key; for (auto cell : unassigned_cells) { assigned_cells[key].insert(cell->name); assigned_cells_reverse[cell] = key; @@ -1227,19 +1203,19 @@ struct Abc9Pass : public Pass { log_header(design, "Summary of detected clock domains:\n"); for (auto &it : assigned_cells) - log(" %d cells in clk=%s\n", GetSize(it.second), log_signal(it.first)); + log(" %d cells in clk=%s cell=%s\n", GetSize(it.second), log_signal(it.first.first), log_id(it.first.second)); design->selection_stack.emplace_back(false); design->selected_active_module = module->name.str(); for (auto &it : assigned_cells) { std::string target = delay_target; if (target.empty()) { - for (auto b : assign_map(it.first)) + for (auto b : assign_map(it.first.first)) if (b.wire) { auto jt = b.wire->attributes.find("\\abc9_period"); if (jt != b.wire->attributes.end()) { target = stringf("-D %d", jt->second.as_int()); - log("Target period = %s ps for clock domain %s\n", target.c_str(), log_signal(it.first)); + log("Target period = %s ps for clock domain %s\n", target.c_str(), log_signal(it.first.first)); break; } } -- cgit v1.2.3 From 69d8c1386a239372a2ab8910bf12d5d70701b7fa Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 6 Dec 2019 16:21:06 -0800 Subject: Do not connect undriven POs to 1'bx --- frontends/aiger/aigerparse.cc | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc index 9374f1ab3..084107b35 100644 --- a/frontends/aiger/aigerparse.cc +++ b/frontends/aiger/aigerparse.cc @@ -1005,15 +1005,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); } } } -- cgit v1.2.3 From c767525441ebc6a21b29bf0c1208049cd38adc8e Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 6 Dec 2019 16:23:09 -0800 Subject: Remove creation of $abc9_control_wire --- techlibs/xilinx/abc9_map.v | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/techlibs/xilinx/abc9_map.v b/techlibs/xilinx/abc9_map.v index d5d5a89f6..49000ea25 100644 --- a/techlibs/xilinx/abc9_map.v +++ b/techlibs/xilinx/abc9_map.v @@ -65,15 +65,14 @@ // (b) an optional $__ABC9_ASYNC_ cell in front of $__ABC_FF_'s output to // capture asynchronous behaviour // (c) a special _TECHMAP_REPLACE_.$abc9_clock wire to capture its clock -// domain (used when partitioning the module so that `abc9' only +// domain and polarity (used when partitioning the module so that `abc9' only // performs sequential synthesis (with reachability analysis) correctly on -// one domain at a time) and used to infert the delay target -// (d) a special _TECHMAP_REPLACE_.$abc9_control wire that captures the control -// domain (which, combined with this cell type, encodes to `abc9' which -// flops may be merged together) -// (e) a special _TECHMAP_REPLACE_.$abc9_init wire to encode the flop's initial +// one domain at a time) and also used to infer the optional delay target +// from the (* abc9_clock_period = %d *) attribute attached to any wire +// within +// (d) a special _TECHMAP_REPLACE_.$abc9_init wire to encode the flop's initial // state -// (f) a special _TECHMAP_REPLACE_.$abc9_currQ wire that will be used for feedback +// (e) a special _TECHMAP_REPLACE_.$abc9_currQ wire that will be used for feedback // into the (combinatorial) FD* cell to facilitate clock-enable behaviour // // In order to perform sequential synthesis, `abc9' also requires that @@ -112,7 +111,6 @@ module FDRE (output Q, input C, CE, D, R); // Special signals wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, IS_C_INVERTED}; - wire [0:0] _TECHMAP_REPLACE_.$abc9_control = {1'b0 /* async */}; wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = QQ; endmodule @@ -140,7 +138,6 @@ module FDRE_1 (output Q, input C, CE, D, R); // Special signals wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */}; - wire [0:0] _TECHMAP_REPLACE_.$abc9_control = {1'b1 /* async */}; wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = QQ; endmodule @@ -190,7 +187,6 @@ module FDCE (output Q, input C, CE, D, CLR); // Special signals wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, IS_C_INVERTED}; - wire [0:0] _TECHMAP_REPLACE_.$abc9_control = {1'b1 /* async */}; wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ; endmodule @@ -228,7 +224,6 @@ module FDCE_1 (output Q, input C, CE, D, CLR); // Special signals wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */}; - wire [0:0] _TECHMAP_REPLACE_.$abc9_control = {1'b1 /* async */}; wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ; endmodule @@ -276,7 +271,6 @@ module FDPE (output Q, input C, CE, D, PRE); // Special signals wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, IS_C_INVERTED}; - wire [0:0] _TECHMAP_REPLACE_.$abc9_control = {1'b1 /* async */}; wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ; endmodule @@ -314,8 +308,6 @@ module FDPE_1 (output Q, input C, CE, D, PRE); // Special signals wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */}; - wire [0:0] _TECHMAP_REPLACE_.$abc9_control = {1'b1 /* async */}; ->>>>>>> d3b23690... abc9 to use mergeability class to differentiate sync/async wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ; endmodule @@ -352,7 +344,6 @@ module FDSE (output Q, input C, CE, D, S); // Special signals wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, IS_C_INVERTED}; - wire [0:0] _TECHMAP_REPLACE_.$abc9_control = {1'b0 /* async */}; wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = QQ; endmodule @@ -379,7 +370,6 @@ module FDSE_1 (output Q, input C, CE, D, S); // Special signals wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */}; - wire [0:0] _TECHMAP_REPLACE_.$abc9_control = {1'b0 /* async */}; wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = QQ; endmodule -- cgit v1.2.3 From ab667d3d47ceb07a41b571517b4effb0f4a4bf0b Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 6 Dec 2019 16:35:57 -0800 Subject: Call abc9 with "&write -n", and parse_xaiger() to cope --- frontends/aiger/aigerparse.cc | 177 ++++++++++++++++++++---------------------- passes/techmap/abc9.cc | 4 +- 2 files changed, 87 insertions(+), 94 deletions(-) diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc index 084107b35..8ff690464 100644 --- a/frontends/aiger/aigerparse.cc +++ b/frontends/aiger/aigerparse.cc @@ -376,105 +376,98 @@ void AigerReader::parse_xaiger(const dict &box_lookup) 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); + c = f.get(); + log_assert(c == '\n'); + // 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(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(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' || c == 's') { - uint32_t dataSize = parse_xaiger_literal(f); - f.ignore(dataSize); - log_debug("ignoring '%c'\n", c); - } - 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(); diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 2d1ce318a..6b8936958 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -30,7 +30,7 @@ "&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" +#define ABC_COMMAND_LUT "&st; &scorr; &sweep; &dc2; &st; &dch -f; &ps; &if {W} {D} -v; &mfs; &ps -l; &verify -s" #endif @@ -311,7 +311,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip 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 += 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++) -- cgit v1.2.3 From 98c9ea605b5cb2eb540ae5b804a18f8921f0bc46 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 6 Dec 2019 17:05:02 -0800 Subject: techmap/aigmap of whiteboxes to occur before abc9 instead of in write_xaiger --- techlibs/ecp5/synth_ecp5.cc | 5 +++++ techlibs/ice40/synth_ice40.cc | 5 +++++ techlibs/xilinx/synth_xilinx.cc | 5 +++++ 3 files changed, 15 insertions(+) diff --git a/techlibs/ecp5/synth_ecp5.cc b/techlibs/ecp5/synth_ecp5.cc index 4cbb56ea1..b099c25d3 100644 --- a/techlibs/ecp5/synth_ecp5.cc +++ b/techlibs/ecp5/synth_ecp5.cc @@ -312,6 +312,11 @@ struct SynthEcp5Pass : public ScriptPass run("techmap " + techmap_args); if (abc9) { + run("select -set abc9_boxes A:abc9_box_id A:whitebox=1"); + run("wbflip @abc9_boxes"); + run("techmap -autoproc @abc9_boxes"); + run("aigmap @abc9_boxes"); + run("wbflip @abc9_boxes"); run("read_verilog -icells -lib +/ecp5/abc9_model.v"); if (nowidelut) run("abc9 -lut +/ecp5/abc9_5g_nowide.lut -box +/ecp5/abc9_5g.box -W 200 -nomfs"); diff --git a/techlibs/ice40/synth_ice40.cc b/techlibs/ice40/synth_ice40.cc index 901194b06..2f0bdb130 100644 --- a/techlibs/ice40/synth_ice40.cc +++ b/techlibs/ice40/synth_ice40.cc @@ -350,6 +350,11 @@ struct SynthIce40Pass : public ScriptPass } if (!noabc) { if (abc == "abc9") { + run("select -set abc9_boxes A:abc9_box_id A:whitebox=1"); + run("wbflip @abc9_boxes"); + run("techmap -autoproc @abc9_boxes"); + run("aigmap @abc9_boxes"); + run("wbflip @abc9_boxes"); run("read_verilog -icells -lib +/ice40/abc9_model.v"); int wire_delay; if (device_opt == "lp") diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index 2c5686a35..8c30148c0 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -533,6 +533,11 @@ struct SynthXilinxPass : public ScriptPass 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"); + run("select -set abc9_boxes A:abc9_box_id A:whitebox=1"); + run("wbflip @abc9_boxes"); + run("techmap -autoproc @abc9_boxes"); + run("aigmap @abc9_boxes"); + run("wbflip @abc9_boxes"); 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); -- cgit v1.2.3 From f2ac36de4ae372cd4467580ca1b28757ea7c9ff7 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 6 Dec 2019 17:06:10 -0800 Subject: write_xaiger to inst each cell type once, do not call techmap/aigmap --- backends/aiger/xaiger.cc | 46 +++++++++++++++++++++++++--------------------- 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 627133314..7765c37bf 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -605,15 +605,25 @@ struct XAigerWriter RTLIL::Module *holes_module = module->design->addModule("$__holes__"); log_assert(holes_module); + dict cell_cache; + int port_id = 1; int box_count = 0; for (auto cell : box_list) { RTLIL::Module* 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; - Cell *holes_cell = nullptr; - if (box_module->get_bool_attribute("\\whitebox")) { + 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 @@ -622,8 +632,8 @@ struct XAigerWriter RTLIL::Wire *w = box_module->wire(port_name); log_assert(w); RTLIL::Wire *holes_wire; - RTLIL::SigSpec port_wire; - if (w->port_input) { + 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)); @@ -634,31 +644,33 @@ struct XAigerWriter holes_module->ports.push_back(holes_wire->name); } if (holes_cell) - port_wire.append(holes_wire); + port_sig.append(holes_wire); } - if (!port_wire.empty()) - holes_cell->setPort(w->name, port_wire); - } if (w->port_output) { box_outputs += GetSize(w); for (int i = 0; i < GetSize(w); i++) { if (GetSize(w) == 1) - holes_wire = holes_module->addWire(stringf("%s.%s", cell->name.c_str(), w->name.c_str())); + 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(), w->name.c_str(), i)); + 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_wire.append(holes_wire); + port_sig.append(holes_wire); else holes_module->connect(holes_wire, State::S0); } - if (!port_wire.empty()) - holes_cell->setPort(w->name, port_wire); + } + 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); } } + write_h_buffer(box_inputs); write_h_buffer(box_outputs); write_h_buffer(box_module->attributes.at("\\abc9_box_id").as_int()); @@ -685,16 +697,8 @@ struct XAigerWriter RTLIL::Selection& sel = holes_module->design->selection_stack.back(); sel.select(holes_module); - // TODO: Should not need to opt_merge if we only instantiate - // each box type once... - Pass::call(holes_module->design, "opt_merge -share_all"); - Pass::call(holes_module->design, "flatten -wb"); - // TODO: Should techmap/aigmap/check all lib_whitebox-es just once, - // instead of per write_xaiger call - Pass::call(holes_module->design, "techmap"); - Pass::call(holes_module->design, "aigmap"); for (auto cell : holes_module->cells()) if (!cell->type.in("$_NOT_", "$_AND_")) log_error("Whitebox contents cannot be represented as AIG. Please verify whiteboxes are synthesisable.\n"); -- cgit v1.2.3 From 91467938c477c5c668f5ea1a38fef59e2b19db5c Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 6 Dec 2019 17:08:19 -0800 Subject: Stray newline --- backends/aiger/xaiger.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 7765c37bf..8074fa835 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -670,7 +670,6 @@ struct XAigerWriter } } - write_h_buffer(box_inputs); write_h_buffer(box_outputs); write_h_buffer(box_module->attributes.at("\\abc9_box_id").as_int()); -- cgit v1.2.3 From 184c0e796a0e6870c025808b1902da5f3771b721 Mon Sep 17 00:00:00 2001 From: David Shah Date: Sat, 7 Dec 2019 13:04:36 +0000 Subject: ecp5: Add support for mapping PRLD FFs Signed-off-by: David Shah --- techlibs/ecp5/cells_map.v | 15 +++++++++++++++ techlibs/ecp5/synth_ecp5.cc | 17 +++++++++++++---- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/techlibs/ecp5/cells_map.v b/techlibs/ecp5/cells_map.v index 71ae9237b..10e89a3e0 100644 --- a/techlibs/ecp5/cells_map.v +++ b/techlibs/ecp5/cells_map.v @@ -47,6 +47,21 @@ module \$__DFFSE_NP1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), . module \$__DFFSE_PP0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule module \$__DFFSE_PP1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule +`ifdef ASYNC_PRLD +module \$_DLATCH_N_ (input E, input D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.LSR(!E), .DI(1'b0), .M(D), .Q(Q)); endmodule +module \$_DLATCH_P_ (input E, input D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.LSR(E), .DI(1'b0), .M(D), .Q(Q)); endmodule + +module \$_DFFSR_NNN_ (input C, S, R, D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("INV"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!S || !R), .DI(D), .M(R), .Q(Q)); endmodule +module \$_DFFSR_NNP_ (input C, S, R, D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("INV"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!S || R), .DI(D), .M(!R), .Q(Q)); endmodule +module \$_DFFSR_NPN_ (input C, S, R, D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("INV"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(S || !R), .DI(D), .M(R), .Q(Q)); endmodule +module \$_DFFSR_NPP_ (input C, S, R, D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("INV"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(S || R), .DI(D), .M(!R), .Q(Q)); endmodule + +module \$_DFFSR_PNN_ (input C, S, R, D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!S || !R), .DI(D), .M(R), .Q(Q)); endmodule +module \$_DFFSR_PNP_ (input C, S, R, D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!S || R), .DI(D), .M(!R), .Q(Q)); endmodule +module \$_DFFSR_PPN_ (input C, S, R, D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(S || !R), .DI(D), .M(R), .Q(Q)); endmodule +module \$_DFFSR_PPP_ (input C, S, R, D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(S || R), .DI(D), .M(!R), .Q(Q)); endmodule +`endif + `include "cells_ff.vh" `include "cells_io.vh" diff --git a/techlibs/ecp5/synth_ecp5.cc b/techlibs/ecp5/synth_ecp5.cc index 4cbb56ea1..b71bb2395 100644 --- a/techlibs/ecp5/synth_ecp5.cc +++ b/techlibs/ecp5/synth_ecp5.cc @@ -79,6 +79,9 @@ struct SynthEcp5Pass : public ScriptPass log(" -nowidelut\n"); log(" do not use PFU muxes to implement LUTs larger than LUT4s\n"); log("\n"); + log(" -asyncprld\n"); + log(" use async PRLD mode to implement DLATCH and DFFSR (EXPERIMENTAL)\n"); + log("\n"); log(" -abc2\n"); log(" run two passes of 'abc' for slightly improved logic density\n"); log("\n"); @@ -99,7 +102,7 @@ struct SynthEcp5Pass : public ScriptPass } string top_opt, blif_file, edif_file, json_file; - bool noccu2, nodffe, nobram, nolutram, nowidelut, flatten, retime, abc2, abc9, nodsp, vpr; + bool noccu2, nodffe, nobram, nolutram, nowidelut, asyncprld, flatten, retime, abc2, abc9, nodsp, vpr; void clear_flags() YS_OVERRIDE { @@ -112,6 +115,7 @@ struct SynthEcp5Pass : public ScriptPass nobram = false; nolutram = false; nowidelut = false; + asyncprld = false; flatten = true; retime = false; abc2 = false; @@ -176,6 +180,10 @@ struct SynthEcp5Pass : public ScriptPass nobram = true; continue; } + if (args[argidx] == "-asyncprld") { + asyncprld = true; + continue; + } if (args[argidx] == "-nolutram" || /*deprecated alias*/ args[argidx] == "-nodram") { nolutram = true; continue; @@ -292,7 +300,7 @@ struct SynthEcp5Pass : public ScriptPass run("opt_clean"); if (!nodffe) run("dff2dffe -direct-match $_DFF_* -direct-match $__DFFS_*"); - run("techmap -D NO_LUT -map +/ecp5/cells_map.v"); + run(stringf("techmap -D NO_LUT %s -map +/ecp5/cells_map.v", help_mode ? "[-D ASYNC_PRLD]" : (asyncprld ? "-D ASYNC_PRLD" : ""))); run("opt_expr -undriven -mux_undef"); run("simplemap"); run("ecp5_ffinit"); @@ -306,10 +314,11 @@ struct SynthEcp5Pass : public ScriptPass if (abc2 || help_mode) { run("abc", " (only if -abc2)"); } - std::string techmap_args = "-map +/ecp5/latches_map.v"; + std::string techmap_args = asyncprld ? "" : "-map +/ecp5/latches_map.v"; if (abc9) techmap_args += " -map +/ecp5/abc9_map.v -max_iter 1"; - run("techmap " + techmap_args); + if (!asyncprld || abc9) + run("techmap " + techmap_args); if (abc9) { run("read_verilog -icells -lib +/ecp5/abc9_model.v"); -- cgit v1.2.3 From 49c2e59b2a4fce770bdaa74177adff0ee995f90d Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 9 Dec 2019 15:44:19 -0800 Subject: Fix comment --- techlibs/xilinx/abc9_xc7.box | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/techlibs/xilinx/abc9_xc7.box b/techlibs/xilinx/abc9_xc7.box index 24b1898a4..4e632c0fa 100644 --- a/techlibs/xilinx/abc9_xc7.box +++ b/techlibs/xilinx/abc9_xc7.box @@ -107,7 +107,7 @@ $__ABC9_LUT6 2000 0 7 1 # SLICEM/A6LUT + F7BMUX # Box to emulate comb/seq behaviour of RAMD128 # Inputs: A S0 S1 S2 S3 S4 S5 S6 -# Outputs: DPO SPO +# Outputs: Y $__ABC9_LUT7 2001 0 8 1 0 1047 1036 877 812 643 532 478 -- cgit v1.2.3 From 993a77d19b3fb56ef2da3a6dfafa8a1488039d01 Mon Sep 17 00:00:00 2001 From: Gustavo Romero Date: Wed, 11 Dec 2019 08:09:48 -0300 Subject: manual: Fix text in Abstract section --- manual/manual.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manual/manual.tex b/manual/manual.tex index 67982cbc8..75f087eca 100644 --- a/manual/manual.tex +++ b/manual/manual.tex @@ -146,7 +146,7 @@ with the help of HDL synthesis tools. In special cases such as synthesis for coarse-grain cell libraries or when testing new synthesis algorithms it might be necessary to write a custom HDL -synthesis tool or add new features to an existing one. It this cases the +synthesis tool or add new features to an existing one. In these cases the availability of a Free and Open Source (FOSS) synthesis tool that can be used as basis for custom tools would be helpful. -- cgit v1.2.3 From e75ca29b19e230bc829a369c7de9cbadb629f5a7 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 11 Dec 2019 11:26:54 -0800 Subject: Add test: 'Warning: ignoring initial value on non-register: \o' --- tests/sat/initval.ys | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/sat/initval.ys b/tests/sat/initval.ys index 2079d2f34..337aa9343 100644 --- a/tests/sat/initval.ys +++ b/tests/sat/initval.ys @@ -2,3 +2,13 @@ read_verilog -sv initval.v proc;; sat -seq 10 -prove-asserts + +design -reset +read_verilog -icells < Date: Wed, 11 Dec 2019 11:27:10 -0800 Subject: Suppress warning message for init[i] = 1'bx --- passes/sat/sat.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/passes/sat/sat.cc b/passes/sat/sat.cc index 430bba1e8..436ac1b01 100644 --- a/passes/sat/sat.cc +++ b/passes/sat/sat.cc @@ -269,7 +269,8 @@ struct SatHelper for (int i = 0; i < lhs.size(); i++) { RTLIL::SigSpec bit = lhs.extract(i, 1); if (rhs[i] == State::Sx || !satgen.initial_state.check_all(bit)) { - removed_bits.append(bit); + if (rhs[i] != State::Sx) + removed_bits.append(bit); lhs.remove(i, 1); rhs.remove(i, 1); i--; -- cgit v1.2.3 From 151f7533e89d1a6db9c52b3c5d77adb2089db366 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 11 Dec 2019 16:26:19 -0800 Subject: Add testcase --- tests/various/bug1531.ys | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 tests/various/bug1531.ys diff --git a/tests/various/bug1531.ys b/tests/various/bug1531.ys new file mode 100644 index 000000000..542223030 --- /dev/null +++ b/tests/various/bug1531.ys @@ -0,0 +1,34 @@ +read_verilog < Date: Wed, 11 Dec 2019 16:26:26 -0800 Subject: Preserve size of $genval$-s in for loops --- frontends/ast/simplify.cc | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 44fd32cdc..8cbf5a6e2 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1198,6 +1198,15 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, varbuf = new AstNode(AST_LOCALPARAM, varbuf); varbuf->str = init_ast->children[0]->str; + auto resolved = current_scope.at(init_ast->children[0]->str); + if (resolved->range_valid) { + varbuf->range_left = resolved->range_left; + varbuf->range_right = resolved->range_right; + varbuf->range_swapped = resolved->range_swapped; + varbuf->range_valid = resolved->range_valid; + log_dump(varbuf->range_left, varbuf->range_right); + } + AstNode *backup_scope_varbuf = current_scope[varbuf->str]; current_scope[varbuf->str] = varbuf; @@ -2998,6 +3007,14 @@ void AstNode::expand_genblock(std::string index_var, std::string prefix, std::ma current_ast_mod->children.push_back(p); str = p->str; id2ast = p; + + auto resolved = current_scope.at(index_var); + if (resolved->range_valid) { + p->range_left = resolved->range_left; + p->range_right = resolved->range_right; + p->range_swapped = resolved->range_swapped; + p->range_valid = resolved->range_valid; + } } } -- cgit v1.2.3 From 1ac1697e15ff72e69f4dfbf6922f0871c81bdff2 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 11 Dec 2019 16:59:00 -0800 Subject: Stray log_dump --- frontends/ast/simplify.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 8cbf5a6e2..b94a8d710 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1204,7 +1204,6 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, varbuf->range_right = resolved->range_right; varbuf->range_swapped = resolved->range_swapped; varbuf->range_valid = resolved->range_valid; - log_dump(varbuf->range_left, varbuf->range_right); } AstNode *backup_scope_varbuf = current_scope[varbuf->str]; -- cgit v1.2.3 From 61a1f3f49b7bd0478b92c0933c487af5803c53f9 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 11 Dec 2019 23:48:09 -0800 Subject: Make testcase clearer with \o having its own init --- tests/sat/initval.ys | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/sat/initval.ys b/tests/sat/initval.ys index 337aa9343..6cb68a8d3 100644 --- a/tests/sat/initval.ys +++ b/tests/sat/initval.ys @@ -6,6 +6,8 @@ sat -seq 10 -prove-asserts design -reset read_verilog -icells < Date: Wed, 11 Dec 2019 23:52:05 -0800 Subject: Even more obvious testcase --- tests/sat/initval.ys | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/tests/sat/initval.ys b/tests/sat/initval.ys index 6cb68a8d3..1436724b0 100644 --- a/tests/sat/initval.ys +++ b/tests/sat/initval.ys @@ -5,12 +5,11 @@ sat -seq 10 -prove-asserts design -reset read_verilog -icells < Date: Thu, 12 Dec 2019 16:14:20 +0100 Subject: add a command to read/modify scratchpad contents --- passes/cmds/Makefile.inc | 1 + passes/cmds/scratchpad.cc | 86 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+) create mode 100644 passes/cmds/scratchpad.cc diff --git a/passes/cmds/Makefile.inc b/passes/cmds/Makefile.inc index c7edc30fb..07a5d3ddc 100644 --- a/passes/cmds/Makefile.inc +++ b/passes/cmds/Makefile.inc @@ -32,3 +32,4 @@ OBJS += passes/cmds/chtype.o OBJS += passes/cmds/blackbox.o OBJS += passes/cmds/ltp.o OBJS += passes/cmds/bugpoint.o +OBJS += passes/cmds/scratchpad.o diff --git a/passes/cmds/scratchpad.cc b/passes/cmds/scratchpad.cc new file mode 100644 index 000000000..7d53c8a4f --- /dev/null +++ b/passes/cmds/scratchpad.cc @@ -0,0 +1,86 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 Clifford Wolf + * + * 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/rtlil.h" +#include "kernel/log.h" + +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + +struct ScratchpadPass : public Pass { + ScratchpadPass() : Pass("scratchpad", "get/set values in the scratchpad") { } + void help() YS_OVERRIDE + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" scratchpad [ -get id | -set id val | -unset id | -copy id1 id2 ]\n"); + log("\n"); + log("This pass allows to read and modify values from the scratchpad of the current\n"); + log("design. Options:\n"); + log(" -get \n"); + log(" -set \n"); + log(" -unset \n"); + log(" -copy \n"); + log("The identifier may not contain whitespace. By convention, it is usually prefixed\n"); + log("by the name of the pass that uses it, e.g. 'opt.did_something'. If the value\n"); + log("contains whitespace, it must be enclosed in double quotes.\n"); + log("\n"); + } + + void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE + { + size_t argidx; + for (argidx = 1; argidx < args.size(); argidx++) + { + if (args[argidx] == "-get" && argidx+1 < args.size()) { + string identifier = args[++argidx]; + if (design->scratchpad.count(identifier)){ + log("%s\n", design->scratchpad_get_string(identifier).c_str()); + } else { + log("\"%s\" not set\n", identifier.c_str()); + } + continue; + } + if (args[argidx] == "-set" && argidx+2 < args.size()) { + string identifier = args[++argidx]; + string value = args[++argidx]; + if (value.front() == '\"' && value.back() == '\"') value = value.substr(1, value.size() - 2); + design->scratchpad_set_string(identifier, value); + continue; + } + if (args[argidx] == "-unset" && argidx+1 < args.size()) { + string identifier = args[++argidx]; + design->scratchpad_unset(identifier); + continue; + } + if (args[argidx] == "-copy" && argidx+2 < args.size()) { + string identifier_from = args[++argidx]; + string identifier_to = args[++argidx]; + if (design->scratchpad.count(identifier_from) == 0) log_error("\"%s\" not set\n", identifier_from.c_str()); + string value = design->scratchpad_get_string(identifier_from); + design->scratchpad_set_string(identifier_to, value); + continue; + } + log("Unrecognized argument: %s\n", args[argidx].c_str()); + break; + } + } +} ScratchpadPass; +PRIVATE_NAMESPACE_END -- cgit v1.2.3 From 23fcfd0adb51f800936b70999a5f95fe59ee7631 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 12 Dec 2019 07:34:07 -0800 Subject: Make SV2017 compliant courtesy of @wsnyder --- tests/simple/mem_arst.v | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/simple/mem_arst.v b/tests/simple/mem_arst.v index 9bd38fcb3..88d0553b9 100644 --- a/tests/simple/mem_arst.v +++ b/tests/simple/mem_arst.v @@ -7,11 +7,9 @@ module MyMem #( input Clk_i, input [AddrWidth-1:0] Addr_i, input [DataWidth-1:0] Data_i, - output [DataWidth-1:0] Data_o, + output reg [DataWidth-1:0] Data_o, input WR_i); - reg [DataWidth-1:0] Data_o; - localparam Size = 2**AddrWidth; (* mem2reg *) -- cgit v1.2.3 From 937ec1ee78e5470c148d8c39387c7a80711af8a7 Mon Sep 17 00:00:00 2001 From: Diego H Date: Thu, 12 Dec 2019 13:50:36 -0600 Subject: Updating RAMB36E1 thresholds. Adding test for both RAMB18E1/RAMB36E1 --- techlibs/xilinx/xc7_xcu_brams.txt | 4 ++-- tests/arch/common/memory_params.v | 45 ++++++++++++++++++++++++++++++++++++++ tests/arch/xilinx/memory_params.ys | 45 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 92 insertions(+), 2 deletions(-) create mode 100644 tests/arch/common/memory_params.v create mode 100644 tests/arch/xilinx/memory_params.ys diff --git a/techlibs/xilinx/xc7_xcu_brams.txt b/techlibs/xilinx/xc7_xcu_brams.txt index ee961fff8..87e659bbc 100644 --- a/techlibs/xilinx/xc7_xcu_brams.txt +++ b/techlibs/xilinx/xc7_xcu_brams.txt @@ -73,7 +73,7 @@ bram $__XILINX_RAMB18_TDP endbram match $__XILINX_RAMB36_SDP - min bits 4096 + min bits 1024 min efficiency 5 shuffle_enable B make_transp @@ -89,7 +89,7 @@ match $__XILINX_RAMB18_SDP endmatch match $__XILINX_RAMB36_TDP - min bits 4096 + min bits 1024 min efficiency 5 shuffle_enable B make_transp diff --git a/tests/arch/common/memory_params.v b/tests/arch/common/memory_params.v new file mode 100644 index 000000000..dbc6ca65c --- /dev/null +++ b/tests/arch/common/memory_params.v @@ -0,0 +1,45 @@ +`default_nettype none +module sync_ram_sp #(parameter DATA_WIDTH=8, ADDRESS_WIDTH=10) + (input wire write_enable, clk, + input wire [DATA_WIDTH-1:0] data_in, + input wire [ADDRESS_WIDTH-1:0] address_in, + output wire [DATA_WIDTH-1:0] data_out); + + localparam WORD = (DATA_WIDTH-1); + localparam DEPTH = (2**ADDRESS_WIDTH-1); + + reg [WORD:0] data_out_r; + reg [WORD:0] memory [0:DEPTH]; + + always @(posedge clk) begin + if (write_enable) + memory[address_in] <= data_in; + data_out_r <= memory[address_in]; + end + + assign data_out = data_out_r; +endmodule // sync_ram_sp + + +`default_nettype none +module sync_ram_sdp #(parameter DATA_WIDTH=8, ADDRESS_WIDTH=10) + (input wire clk, write_enable, + input wire [DATA_WIDTH-1:0] data_in, + input wire [ADDRESS_WIDTH-1:0] address_in_r, address_in_w, + output wire [DATA_WIDTH-1:0] data_out); + + localparam WORD = (DATA_WIDTH-1); + localparam DEPTH = (2**ADDRESS_WIDTH-1); + + reg [WORD:0] data_out_r; + reg [WORD:0] memory [0:DEPTH]; + + always @(posedge clk) begin + if (write_enable) + memory[address_in_w] <= data_in; + data_out_r <= memory[address_in_r]; + end + + assign data_out = data_out_r; +endmodule // sync_ram_sdp + diff --git a/tests/arch/xilinx/memory_params.ys b/tests/arch/xilinx/memory_params.ys new file mode 100644 index 000000000..f279a4a6e --- /dev/null +++ b/tests/arch/xilinx/memory_params.ys @@ -0,0 +1,45 @@ +# Memory bits <= 18K; Data width <= 36; Address width <= 14: -> RAMB18E1 +read_verilog ../common/memory_params.v +chparam -set ADDRESS_WIDTH 10 -set DATA_WIDTH 1 sync_ram_sdp +synth_xilinx -top sync_ram_sdp +cd sync_ram_sdp +select -assert-count 1 t:RAMB18E1 + +design -reset +read_verilog ../common/memory_params.v +chparam -set ADDRESS_WIDTH 8 -set DATA_WIDTH 18 sync_ram_sdp +synth_xilinx -top sync_ram_sdp +cd sync_ram_sdp +select -assert-count 1 t:RAMB18E1 + +design -reset +read_verilog ../common/memory_params.v +chparam -set ADDRESS_WIDTH 14 -set DATA_WIDTH 1 sync_ram_sdp +synth_xilinx -top sync_ram_sdp +cd sync_ram_sdp +select -assert-count 1 t:RAMB18E1 + +design -reset +read_verilog ../common/memory_params.v +chparam -set ADDRESS_WIDTH 9 -set DATA_WIDTH 36 sync_ram_sdp +synth_xilinx -top sync_ram_sdp +cd sync_ram_sdp +select -assert-count 1 t:RAMB18E1 + +# Anything memory bits < 1024 -> LUTRAM +design -reset +read_verilog ../common/memory_params.v +chparam -set ADDRESS_WIDTH 8 -set DATA_WIDTH 2 sync_ram_sdp +synth_xilinx -top sync_ram_sdp +cd sync_ram_sdp +select -assert-count 0 t:RAMB18E1 +select -assert-count 4 t:RAM128X1D + +# More than 18K bits and addr <= 36: -> RAMB36E1 +design -reset +read_verilog ../common/memory_params.v +chparam -set ADDRESS_WIDTH 15 -set DATA_WIDTH 1 sync_ram_sdp +synth_xilinx -top sync_ram_sdp +cd sync_ram_sdp +select -assert-count 1 t:RAMB36E1 + -- cgit v1.2.3 From 1187e91c2f2684cb204c555cb3d53b68c7381c40 Mon Sep 17 00:00:00 2001 From: "N. Engelhardt" Date: Thu, 12 Dec 2019 20:51:59 +0100 Subject: add test and make help message more verbose --- passes/cmds/scratchpad.cc | 7 ++++++- tests/various/scratchpad.sh | 14 ++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) create mode 100755 tests/various/scratchpad.sh diff --git a/passes/cmds/scratchpad.cc b/passes/cmds/scratchpad.cc index 7d53c8a4f..c11c41caf 100644 --- a/passes/cmds/scratchpad.cc +++ b/passes/cmds/scratchpad.cc @@ -2,6 +2,7 @@ * yosys -- Yosys Open SYnthesis Suite * * Copyright (C) 2012 Clifford Wolf + * 2019 Nina Engelhardt * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -30,14 +31,18 @@ struct ScratchpadPass : public Pass { { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); - log(" scratchpad [ -get id | -set id val | -unset id | -copy id1 id2 ]\n"); + log(" scratchpad [options]\n"); log("\n"); log("This pass allows to read and modify values from the scratchpad of the current\n"); log("design. Options:\n"); log(" -get \n"); + log(" print the value saved in the scratchpad under the given identifier\n"); log(" -set \n"); + log(" save the given value in the scratchpad under the given identifier\n"); log(" -unset \n"); + log(" remove the entry for the given identifier from the scratchpad\n"); log(" -copy \n"); + log(" copy the value of the first identifier to the second identifier\n"); log("The identifier may not contain whitespace. By convention, it is usually prefixed\n"); log("by the name of the pass that uses it, e.g. 'opt.did_something'. If the value\n"); log("contains whitespace, it must be enclosed in double quotes.\n"); diff --git a/tests/various/scratchpad.sh b/tests/various/scratchpad.sh new file mode 100755 index 000000000..4e92473f8 --- /dev/null +++ b/tests/various/scratchpad.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +trap 'echo "ERROR in scratchpad.sh" >&2; exit 1' ERR + +../../yosys -qp "scratchpad -set foo \"bar baz\"; \ +scratchpad -copy foo oof; scratchpad -unset foo; \ +tee -o scratchpad1.log scratchpad -get oof; \ +tee -o scratchpad2.log scratchpad -get foo" + +test "$(cat scratchpad1.log)" = "bar baz" +test "$(cat scratchpad2.log)" = "\"foo\" not set" + +rm scratchpad1.log +rm scratchpad2.log -- cgit v1.2.3 From e33f407655fa516cb2f6754103973eb156ca90cf Mon Sep 17 00:00:00 2001 From: Diego H Date: Thu, 12 Dec 2019 16:06:46 -0600 Subject: Adding a note (TODO) in the memory_params.ys check file --- tests/arch/xilinx/memory_params.ys | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/arch/xilinx/memory_params.ys b/tests/arch/xilinx/memory_params.ys index f279a4a6e..657629e0f 100644 --- a/tests/arch/xilinx/memory_params.ys +++ b/tests/arch/xilinx/memory_params.ys @@ -1,3 +1,5 @@ +## TODO: Not running equivalence checking because BRAM models does not exists +## currently. Checking instance counts instead. # Memory bits <= 18K; Data width <= 36; Address width <= 14: -> RAMB18E1 read_verilog ../common/memory_params.v chparam -set ADDRESS_WIDTH 10 -set DATA_WIDTH 1 sync_ram_sdp -- cgit v1.2.3 From abf99d4dae8a464910b81122f9720660c59a631e Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 12 Dec 2019 14:32:29 -0800 Subject: tribuf: set scratchpad boolean 'tribuf.added_something' --- passes/techmap/tribuf.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/passes/techmap/tribuf.cc b/passes/techmap/tribuf.cc index 41fdc8f3d..decf9a202 100644 --- a/passes/techmap/tribuf.cc +++ b/passes/techmap/tribuf.cc @@ -86,6 +86,7 @@ struct TribufWorker { cell->unsetPort(ID(S)); cell->type = tri_type; tribuf_cells[sigmap(cell->getPort(ID::Y))].push_back(cell); + module->design->scratchpad_set_bool("tribuf.added_something", true); continue; } @@ -95,6 +96,7 @@ struct TribufWorker { cell->unsetPort(ID(S)); cell->type = tri_type; tribuf_cells[sigmap(cell->getPort(ID::Y))].push_back(cell); + module->design->scratchpad_set_bool("tribuf.added_something", true); continue; } } @@ -130,8 +132,10 @@ struct TribufWorker { if (no_tribuf) module->connect(it.first, muxout); - else + else { module->addTribuf(NEW_ID, muxout, module->ReduceOr(NEW_ID, pmux_s), it.first); + module->design->scratchpad_set_bool("tribuf.added_something", true); + } } } } -- cgit v1.2.3 From 3bd623bb05c0be74b024f5635e754e794bd6316c Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 12 Dec 2019 14:33:33 -0800 Subject: synth_xilinx: error out if tristate without '-iopad' --- techlibs/xilinx/synth_xilinx.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index 2c5686a35..6dd769055 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -306,6 +306,10 @@ struct SynthXilinxPass : public ScriptPass run("proc"); if (flatten || help_mode) run("flatten", "(with '-flatten')"); + active_design->scratchpad_unset("tribuf.added_something"); + run("tribuf -logic"); + if (!do_iopad && active_design->scratchpad_get_bool("tribuf.added_something")) + log_error("Tristate buffers are unsupported without the '-iopad' option.\n"); run("tribuf -logic"); run("deminout"); run("opt_expr"); -- cgit v1.2.3 From 47ac1b01e673c1fc6f0010237c66d9b20957dcd0 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 12 Dec 2019 14:43:13 -0800 Subject: Add test --- tests/arch/xilinx/tribuf.sh | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 tests/arch/xilinx/tribuf.sh diff --git a/tests/arch/xilinx/tribuf.sh b/tests/arch/xilinx/tribuf.sh new file mode 100644 index 000000000..636aed12a --- /dev/null +++ b/tests/arch/xilinx/tribuf.sh @@ -0,0 +1,5 @@ +! ../../../yosys ../common/tribuf.v -qp "synth_xilinx" +../../../yosys ../common/tribuf.v -qp "synth_xilinx -iopad; \ +select -assert-count 2 t:IBUF; \ +select -assert-count 1 t:INV; \ +select -assert-count 1 t:OBUFT" -- cgit v1.2.3 From 3eed8835b5911c4c635e0cade0978987c09c7ab5 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 12 Dec 2019 14:56:15 -0800 Subject: abc9_map.v: fix Xilinx LUTRAM --- techlibs/xilinx/abc9_map.v | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/techlibs/xilinx/abc9_map.v b/techlibs/xilinx/abc9_map.v index 49000ea25..d04cdb5eb 100644 --- a/techlibs/xilinx/abc9_map.v +++ b/techlibs/xilinx/abc9_map.v @@ -393,8 +393,8 @@ module RAM32X1D ( .A0(A0), .A1(A1), .A2(A2), .A3(A3), .A4(A4), .DPRA0(DPRA0), .DPRA1(DPRA1), .DPRA2(DPRA2), .DPRA3(DPRA3), .DPRA4(DPRA4) ); - \$__ABC9_LUT6 dpo (.A(\$DPO ), .S({1'b0, A0, A1, A2, A3, A4}), .Y(DPO)); - \$__ABC9_LUT6 spo (.A(\$SPO ), .S({1'b0, A0, A1, A2, A3, A4}), .Y(SPO)); + \$__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 ( @@ -416,8 +416,8 @@ module RAM64X1D ( .A0(A0), .A1(A1), .A2(A2), .A3(A3), .A4(A4), .A5(A5), .DPRA0(DPRA0), .DPRA1(DPRA1), .DPRA2(DPRA2), .DPRA3(DPRA3), .DPRA4(DPRA4), .DPRA5(DPRA5) ); - \$__ABC9_LUT6 dpo (.A(\$DPO ), .S({A0, A1, A2, A3, A4, A5}), .Y(DPO)); - \$__ABC9_LUT6 spo (.A(\$SPO ), .S({A0, A1, A2, A3, A4, A5}), .Y(SPO)); + \$__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 ( @@ -438,8 +438,8 @@ module RAM128X1D ( .A(A), .DPRA(DPRA) ); - \$__ABC9_LUT7 dpo (.A(\$DPO ), .S(A), .Y(DPO)); \$__ABC9_LUT7 spo (.A(\$SPO ), .S(A), .Y(SPO)); + \$__ABC9_LUT7 dpo (.A(\$DPO ), .S(DPRA), .Y(DPO)); endmodule module SRL16E ( @@ -455,7 +455,7 @@ module SRL16E ( .Q(\$Q ), .A0(A0), .A1(A1), .A2(A2), .A3(A3), .CE(CE), .CLK(CLK), .D(D) ); - \$__ABC9_LUT6 q (.A(\$Q ), .S({1'b1, A0, A1, A2, A3, 1'b1}), .Y(Q)); + \$__ABC9_LUT6 q (.A(\$Q ), .S({1'b1, A3, A2, A1, A0, 1'b1}), .Y(Q)); endmodule module SRLC32E ( -- cgit v1.2.3 From fce6bad6ae22a3e14115202b05b50ae4a69b5a93 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 12 Dec 2019 15:02:46 -0800 Subject: Remove 'clkpart' entry in CHANGELOG --- CHANGELOG | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index d9d261fbc..a49c27b05 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -53,7 +53,6 @@ Yosys 0.9 .. Yosys 0.9-dev - Added "check -mapped" - Added checking of SystemVerilog always block types (always_comb, always_latch and always_ff) - - Added "clkpart" pass Yosys 0.8 .. Yosys 0.9 ---------------------- -- cgit v1.2.3 From 751a18d7e974123352e372c75bb17226e6fabec0 Mon Sep 17 00:00:00 2001 From: Diego H Date: Thu, 12 Dec 2019 17:32:58 -0600 Subject: Fixing citation in xc7_xcu_brams.txt file. Fixing RAMB36E1 test. --- techlibs/xilinx/xc7_xcu_brams.txt | 10 +++++----- tests/arch/xilinx/memory_params.ys | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/techlibs/xilinx/xc7_xcu_brams.txt b/techlibs/xilinx/xc7_xcu_brams.txt index 87e659bbc..b7c893ff7 100644 --- a/techlibs/xilinx/xc7_xcu_brams.txt +++ b/techlibs/xilinx/xc7_xcu_brams.txt @@ -1,4 +1,3 @@ - bram $__XILINX_RAMB36_SDP init 1 abits 9 @@ -72,6 +71,11 @@ bram $__XILINX_RAMB18_TDP clkpol 2 3 endbram +# The "min bits" value were taken from: +# [[CITE]] 7 Series FPGAs Memory Resources User Guide (UG473), +# v1.14 ed., p 29-30, July, 2019. +# https://www.xilinx.com/support/documentation/user_guides/ug473_7Series_Memory_Resources.pdf + match $__XILINX_RAMB36_SDP min bits 1024 min efficiency 5 @@ -102,7 +106,3 @@ match $__XILINX_RAMB18_TDP shuffle_enable B make_transp endmatch - -# [[CITE]] 7 Series FPGAs Memory Resources User Guide (UG473), -# v1.14 ed., p 29-30, July, 2019. - diff --git a/tests/arch/xilinx/memory_params.ys b/tests/arch/xilinx/memory_params.ys index 657629e0f..c1b0ca489 100644 --- a/tests/arch/xilinx/memory_params.ys +++ b/tests/arch/xilinx/memory_params.ys @@ -37,10 +37,10 @@ cd sync_ram_sdp select -assert-count 0 t:RAMB18E1 select -assert-count 4 t:RAM128X1D -# More than 18K bits and addr <= 36: -> RAMB36E1 +# More than 18K bits, data width <= 36 (TDP), and address width from 10 to 15b (non-cascaded) -> RAMB36E1 design -reset read_verilog ../common/memory_params.v -chparam -set ADDRESS_WIDTH 15 -set DATA_WIDTH 1 sync_ram_sdp +chparam -set ADDRESS_WIDTH 10 -set DATA_WIDTH 36 sync_ram_sdp synth_xilinx -top sync_ram_sdp cd sync_ram_sdp select -assert-count 1 t:RAMB36E1 -- cgit v1.2.3 From caab66111e2b5052bd26c8fd64b1324e7e4a4106 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 12 Dec 2019 17:44:37 -0800 Subject: Rename memory tests to lutram, add more xilinx tests --- tests/arch/anlogic/lutram.ys | 21 ++++++++++ tests/arch/anlogic/memory.ys | 21 ---------- tests/arch/common/lutram.v | 42 +++++++++++++++++++ tests/arch/common/memory.v | 21 ---------- tests/arch/ecp5/lutram.ys | 19 +++++++++ tests/arch/ecp5/memory.ys | 19 --------- tests/arch/efinix/lutram.ys | 18 ++++++++ tests/arch/efinix/memory.ys | 18 -------- tests/arch/gowin/lutram.ys | 18 ++++++++ tests/arch/gowin/memory.ys | 18 -------- tests/arch/ice40/lutram.ys | 15 +++++++ tests/arch/ice40/memory.ys | 15 ------- tests/arch/xilinx/lutram.ys | 99 ++++++++++++++++++++++++++++++++++++++++++++ tests/arch/xilinx/memory.ys | 17 -------- 14 files changed, 232 insertions(+), 129 deletions(-) create mode 100644 tests/arch/anlogic/lutram.ys delete mode 100644 tests/arch/anlogic/memory.ys create mode 100644 tests/arch/common/lutram.v delete mode 100644 tests/arch/common/memory.v create mode 100644 tests/arch/ecp5/lutram.ys delete mode 100644 tests/arch/ecp5/memory.ys create mode 100644 tests/arch/efinix/lutram.ys delete mode 100644 tests/arch/efinix/memory.ys create mode 100644 tests/arch/gowin/lutram.ys delete mode 100644 tests/arch/gowin/memory.ys create mode 100644 tests/arch/ice40/lutram.ys delete mode 100644 tests/arch/ice40/memory.ys create mode 100644 tests/arch/xilinx/lutram.ys delete mode 100644 tests/arch/xilinx/memory.ys diff --git a/tests/arch/anlogic/lutram.ys b/tests/arch/anlogic/lutram.ys new file mode 100644 index 000000000..9ebb75443 --- /dev/null +++ b/tests/arch/anlogic/lutram.ys @@ -0,0 +1,21 @@ +read_verilog ../common/lutram.v +hierarchy -top lutram_1w1r +proc +memory -nomap +equiv_opt -run :prove -map +/anlogic/cells_sim.v synth_anlogic +memory +opt -full + +miter -equiv -flatten -make_assert -make_outputs gold gate miter +#ERROR: Failed to import cell gate.mem.0.0.0 (type EG_LOGIC_DRAM16X4) to SAT database. +#sat -verify -prove-asserts -seq 3 -set-init-zero -show-inputs -show-outputs miter + +design -load postopt +cd lutram_1w1r + +select -assert-count 8 t:AL_MAP_LUT2 +select -assert-count 8 t:AL_MAP_LUT4 +select -assert-count 8 t:AL_MAP_LUT5 +select -assert-count 36 t:AL_MAP_SEQ +select -assert-count 8 t:EG_LOGIC_DRAM16X4 #Why not AL_LOGIC_BRAM? +select -assert-none t:AL_MAP_LUT2 t:AL_MAP_LUT4 t:AL_MAP_LUT5 t:AL_MAP_SEQ t:EG_LOGIC_DRAM16X4 %% t:* %D diff --git a/tests/arch/anlogic/memory.ys b/tests/arch/anlogic/memory.ys deleted file mode 100644 index 87b93c2fe..000000000 --- a/tests/arch/anlogic/memory.ys +++ /dev/null @@ -1,21 +0,0 @@ -read_verilog ../common/memory.v -hierarchy -top top -proc -memory -nomap -equiv_opt -run :prove -map +/anlogic/cells_sim.v synth_anlogic -memory -opt -full - -miter -equiv -flatten -make_assert -make_outputs gold gate miter -#ERROR: Failed to import cell gate.mem.0.0.0 (type EG_LOGIC_DRAM16X4) to SAT database. -#sat -verify -prove-asserts -seq 3 -set-init-zero -show-inputs -show-outputs miter - -design -load postopt -cd top - -select -assert-count 8 t:AL_MAP_LUT2 -select -assert-count 8 t:AL_MAP_LUT4 -select -assert-count 8 t:AL_MAP_LUT5 -select -assert-count 36 t:AL_MAP_SEQ -select -assert-count 8 t:EG_LOGIC_DRAM16X4 #Why not AL_LOGIC_BRAM? -select -assert-none t:AL_MAP_LUT2 t:AL_MAP_LUT4 t:AL_MAP_LUT5 t:AL_MAP_SEQ t:EG_LOGIC_DRAM16X4 %% t:* %D diff --git a/tests/arch/common/lutram.v b/tests/arch/common/lutram.v new file mode 100644 index 000000000..9534b7619 --- /dev/null +++ b/tests/arch/common/lutram.v @@ -0,0 +1,42 @@ +module lutram_1w1r +#(parameter D_WIDTH=8, A_WIDTH=6) +( + input [D_WIDTH-1:0] data_a, + input [A_WIDTH:1] addr_a, + input we_a, clk, + output reg [D_WIDTH-1:0] q_a +); + // Declare the RAM variable + reg [D_WIDTH-1:0] ram[(2**A_WIDTH)-1:0]; + + // Port A + always @ (posedge clk) + begin + if (we_a) + ram[addr_a] <= data_a; + q_a <= ram[addr_a]; + end +endmodule + + +module lutram_1w3r +#(parameter D_WIDTH=8, A_WIDTH=5) +( + input [D_WIDTH-1:0] data_a, data_b, data_c, + input [A_WIDTH:1] addr_a, addr_b, addr_c, + input we_a, clk, + output reg [D_WIDTH-1:0] q_a, q_b, q_c +); + // Declare the RAM variable + reg [D_WIDTH-1:0] ram[(2**A_WIDTH)-1:0]; + + // Port A + always @ (posedge clk) + begin + if (we_a) + ram[addr_a] <= data_a; + q_a <= ram[addr_a]; + q_b <= ram[addr_b]; + q_c <= ram[addr_c]; + end +endmodule diff --git a/tests/arch/common/memory.v b/tests/arch/common/memory.v deleted file mode 100644 index cb7753f7b..000000000 --- a/tests/arch/common/memory.v +++ /dev/null @@ -1,21 +0,0 @@ -module top -( - input [7:0] data_a, - input [6:1] addr_a, - input we_a, clk, - output reg [7:0] q_a -); - // Declare the RAM variable - reg [7:0] ram[63:0]; - - // Port A - always @ (posedge clk) - begin - if (we_a) - begin - ram[addr_a] <= data_a; - q_a <= data_a; - end - q_a <= ram[addr_a]; - end -endmodule diff --git a/tests/arch/ecp5/lutram.ys b/tests/arch/ecp5/lutram.ys new file mode 100644 index 000000000..e1ae7abd5 --- /dev/null +++ b/tests/arch/ecp5/lutram.ys @@ -0,0 +1,19 @@ +read_verilog ../common/lutram.v +hierarchy -top lutram_1w1r +proc +memory -nomap +equiv_opt -run :prove -map +/ecp5/cells_sim.v synth_ecp5 +memory +opt -full + +miter -equiv -flatten -make_assert -make_outputs gold gate miter +sat -verify -prove-asserts -seq 5 -set-init-zero -show-inputs -show-outputs miter + +design -load postopt +cd lutram_1w1r +select -assert-count 24 t:L6MUX21 +select -assert-count 71 t:LUT4 +select -assert-count 32 t:PFUMX +select -assert-count 8 t:TRELLIS_DPR16X4 +select -assert-count 35 t:TRELLIS_FF +select -assert-none t:L6MUX21 t:LUT4 t:PFUMX t:TRELLIS_DPR16X4 t:TRELLIS_FF %% t:* %D diff --git a/tests/arch/ecp5/memory.ys b/tests/arch/ecp5/memory.ys deleted file mode 100644 index c82b7b405..000000000 --- a/tests/arch/ecp5/memory.ys +++ /dev/null @@ -1,19 +0,0 @@ -read_verilog ../common/memory.v -hierarchy -top top -proc -memory -nomap -equiv_opt -run :prove -map +/ecp5/cells_sim.v synth_ecp5 -memory -opt -full - -miter -equiv -flatten -make_assert -make_outputs gold gate miter -sat -verify -prove-asserts -seq 5 -set-init-zero -show-inputs -show-outputs miter - -design -load postopt -cd top -select -assert-count 24 t:L6MUX21 -select -assert-count 71 t:LUT4 -select -assert-count 32 t:PFUMX -select -assert-count 8 t:TRELLIS_DPR16X4 -select -assert-count 35 t:TRELLIS_FF -select -assert-none t:L6MUX21 t:LUT4 t:PFUMX t:TRELLIS_DPR16X4 t:TRELLIS_FF %% t:* %D diff --git a/tests/arch/efinix/lutram.ys b/tests/arch/efinix/lutram.ys new file mode 100644 index 000000000..dcf647ce0 --- /dev/null +++ b/tests/arch/efinix/lutram.ys @@ -0,0 +1,18 @@ +read_verilog ../common/lutram.v +hierarchy -top lutram_1w1r +proc +memory -nomap +equiv_opt -run :prove -map +/efinix/cells_sim.v synth_efinix +memory +opt -full + +miter -equiv -flatten -make_assert -make_outputs gold gate miter +#ERROR: Called with -verify and proof did fail! +#sat -verify -prove-asserts -seq 5 -set-init-zero -show-inputs -show-outputs miter +sat -prove-asserts -seq 5 -set-init-zero -show-inputs -show-outputs miter + +design -load postopt +cd lutram_1w1r +select -assert-count 1 t:EFX_GBUFCE +select -assert-count 1 t:EFX_RAM_5K +select -assert-none t:EFX_GBUFCE t:EFX_RAM_5K %% t:* %D diff --git a/tests/arch/efinix/memory.ys b/tests/arch/efinix/memory.ys deleted file mode 100644 index 6f6acdcde..000000000 --- a/tests/arch/efinix/memory.ys +++ /dev/null @@ -1,18 +0,0 @@ -read_verilog ../common/memory.v -hierarchy -top top -proc -memory -nomap -equiv_opt -run :prove -map +/efinix/cells_sim.v synth_efinix -memory -opt -full - -miter -equiv -flatten -make_assert -make_outputs gold gate miter -#ERROR: Called with -verify and proof did fail! -#sat -verify -prove-asserts -seq 5 -set-init-zero -show-inputs -show-outputs miter -sat -prove-asserts -seq 5 -set-init-zero -show-inputs -show-outputs miter - -design -load postopt -cd top -select -assert-count 1 t:EFX_GBUFCE -select -assert-count 1 t:EFX_RAM_5K -select -assert-none t:EFX_GBUFCE t:EFX_RAM_5K %% t:* %D diff --git a/tests/arch/gowin/lutram.ys b/tests/arch/gowin/lutram.ys new file mode 100644 index 000000000..56f69e7c5 --- /dev/null +++ b/tests/arch/gowin/lutram.ys @@ -0,0 +1,18 @@ +read_verilog ../common/lutram.v +hierarchy -top lutram_1w1r +proc +memory -nomap +equiv_opt -run :prove -map +/gowin/cells_sim.v synth_gowin +memory +opt -full + +miter -equiv -flatten -make_assert -make_outputs gold gate miter +#ERROR: Called with -verify and proof did fail! +#sat -verify -prove-asserts -seq 5 -set-init-zero -show-inputs -show-outputs miter +sat -prove-asserts -seq 5 -set-init-zero -show-inputs -show-outputs miter + +design -load postopt +cd lutram_1w1r +select -assert-count 8 t:RAM16S4 +# other logic present that is not simple +#select -assert-none t:RAM16S4 %% t:* %D diff --git a/tests/arch/gowin/memory.ys b/tests/arch/gowin/memory.ys deleted file mode 100644 index 8f88cdd7c..000000000 --- a/tests/arch/gowin/memory.ys +++ /dev/null @@ -1,18 +0,0 @@ -read_verilog ../common/memory.v -hierarchy -top top -proc -memory -nomap -equiv_opt -run :prove -map +/gowin/cells_sim.v synth_gowin -memory -opt -full - -miter -equiv -flatten -make_assert -make_outputs gold gate miter -#ERROR: Called with -verify and proof did fail! -#sat -verify -prove-asserts -seq 5 -set-init-zero -show-inputs -show-outputs miter -sat -prove-asserts -seq 5 -set-init-zero -show-inputs -show-outputs miter - -design -load postopt -cd top -select -assert-count 8 t:RAM16S4 -# other logic present that is not simple -#select -assert-none t:RAM16S4 %% t:* %D diff --git a/tests/arch/ice40/lutram.ys b/tests/arch/ice40/lutram.ys new file mode 100644 index 000000000..1ba40f8ec --- /dev/null +++ b/tests/arch/ice40/lutram.ys @@ -0,0 +1,15 @@ +read_verilog ../common/lutram.v +hierarchy -top lutram_1w1r +proc +memory -nomap +equiv_opt -run :prove -map +/ice40/cells_sim.v synth_ice40 +memory +opt -full + +miter -equiv -flatten -make_assert -make_outputs gold gate miter +sat -verify -prove-asserts -seq 5 -set-init-zero -show-inputs -show-outputs miter + +design -load postopt +cd lutram_1w1r +select -assert-count 1 t:SB_RAM40_4K +select -assert-none t:SB_RAM40_4K %% t:* %D diff --git a/tests/arch/ice40/memory.ys b/tests/arch/ice40/memory.ys deleted file mode 100644 index c356e67fb..000000000 --- a/tests/arch/ice40/memory.ys +++ /dev/null @@ -1,15 +0,0 @@ -read_verilog ../common/memory.v -hierarchy -top top -proc -memory -nomap -equiv_opt -run :prove -map +/ice40/cells_sim.v synth_ice40 -memory -opt -full - -miter -equiv -flatten -make_assert -make_outputs gold gate miter -sat -verify -prove-asserts -seq 5 -set-init-zero -show-inputs -show-outputs miter - -design -load postopt -cd top -select -assert-count 1 t:SB_RAM40_4K -select -assert-none t:SB_RAM40_4K %% t:* %D diff --git a/tests/arch/xilinx/lutram.ys b/tests/arch/xilinx/lutram.ys new file mode 100644 index 000000000..9b2c30ba1 --- /dev/null +++ b/tests/arch/xilinx/lutram.ys @@ -0,0 +1,99 @@ +read_verilog ../common/lutram.v +hierarchy -top lutram_1w1r -chparam A_WIDTH 4 +proc +memory -nomap +equiv_opt -run :prove -map +/xilinx/cells_sim.v synth_xilinx +memory +opt -full + +miter -equiv -flatten -make_assert -make_outputs gold gate miter +sat -verify -prove-asserts -seq 3 -set-init-zero -show-inputs -show-outputs miter + +design -load postopt +cd lutram_1w1r +select -assert-count 1 t:BUFG +select -assert-count 8 t:FDRE +select -assert-count 8 t:RAM16X1D +select -assert-none t:BUFG t:FDRE t:RAM16X1D %% t:* %D + + +design -reset +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 +memory +opt -full + +miter -equiv -flatten -make_assert -make_outputs gold gate miter +sat -verify -prove-asserts -seq 3 -set-init-zero -show-inputs -show-outputs miter + +design -load postopt +cd lutram_1w1r +select -assert-count 1 t:BUFG +select -assert-count 8 t:FDRE +select -assert-count 8 t:RAM32X1D +select -assert-none t:BUFG t:FDRE t:RAM32X1D %% t:* %D + + +design -reset +read_verilog ../common/lutram.v +hierarchy -top lutram_1w1r +proc +memory -nomap +equiv_opt -run :prove -map +/xilinx/cells_sim.v synth_xilinx +memory +opt -full + +miter -equiv -flatten -make_assert -make_outputs gold gate miter +sat -verify -prove-asserts -seq 3 -set-init-zero -show-inputs -show-outputs miter + +design -load postopt +cd lutram_1w1r +select -assert-count 1 t:BUFG +select -assert-count 8 t:FDRE +select -assert-count 8 t:RAM64X1D +select -assert-none t:BUFG t:FDRE t:RAM64X1D %% t:* %D + + +design -reset +read_verilog ../common/lutram.v +hierarchy -top lutram_1w3r +proc +memory -nomap +synth_xilinx +equiv_opt -run :prove -map +/xilinx/cells_sim.v synth_xilinx +memory +opt -full + +miter -equiv -flatten -make_assert -make_outputs gold gate miter +sat -verify -prove-asserts -seq 3 -set-init-zero -show-inputs -show-outputs miter + +design -load postopt +cd lutram_1w3r +select -assert-count 1 t:BUFG +select -assert-count 24 t:FDRE +select -assert-count 4 t:RAM32M +select -assert-none t:BUFG t:FDRE t:RAM32M %% t:* %D + + +design -reset +read_verilog ../common/lutram.v +hierarchy -top lutram_1w3r -chparam A_WIDTH 6 +proc +memory -nomap +synth_xilinx +equiv_opt -run :prove -map +/xilinx/cells_sim.v synth_xilinx +memory +opt -full + +miter -equiv -flatten -make_assert -make_outputs gold gate miter +sat -verify -prove-asserts -seq 3 -set-init-zero -show-inputs -show-outputs miter + +design -load postopt +cd lutram_1w3r +select -assert-count 1 t:BUFG +select -assert-count 24 t:FDRE +select -assert-count 8 t:RAM64M +select -assert-none t:BUFG t:FDRE t:RAM64M %% t:* %D diff --git a/tests/arch/xilinx/memory.ys b/tests/arch/xilinx/memory.ys deleted file mode 100644 index da1ed0e49..000000000 --- a/tests/arch/xilinx/memory.ys +++ /dev/null @@ -1,17 +0,0 @@ -read_verilog ../common/memory.v -hierarchy -top top -proc -memory -nomap -equiv_opt -run :prove -map +/xilinx/cells_sim.v synth_xilinx -memory -opt -full - -miter -equiv -flatten -make_assert -make_outputs gold gate miter -sat -verify -prove-asserts -seq 5 -set-init-zero -show-inputs -show-outputs miter - -design -load postopt -cd top -select -assert-count 1 t:BUFG -select -assert-count 8 t:FDRE -select -assert-count 8 t:RAM64X1D -select -assert-none t:BUFG t:FDRE t:RAM64X1D %% t:* %D -- cgit v1.2.3 From 7a9d1be97d100c265530270810071e2e9e676b3e Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 12 Dec 2019 17:44:59 -0800 Subject: Add memory rules for RAM16X1D, RAM32M, RAM64M --- techlibs/xilinx/lutrams.txt | 64 ++++++++++++++++++++++++++ techlibs/xilinx/lutrams_map.v | 104 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 168 insertions(+) diff --git a/techlibs/xilinx/lutrams.txt b/techlibs/xilinx/lutrams.txt index 2613c206c..3e260b0d7 100644 --- a/techlibs/xilinx/lutrams.txt +++ b/techlibs/xilinx/lutrams.txt @@ -1,4 +1,17 @@ +bram $__XILINX_RAM16X1D + init 1 + abits 4 + dbits 1 + groups 2 + ports 1 1 + wrmode 0 1 + enable 0 1 + transp 0 0 + clocks 0 1 + clkpol 0 2 +endbram + bram $__XILINX_RAM32X1D init 1 abits 5 @@ -38,6 +51,41 @@ bram $__XILINX_RAM128X1D clkpol 0 2 endbram + +bram $__XILINX_RAM32M + init 1 + abits 5 + dbits 2 + groups 2 + ports 3 1 + wrmode 0 1 + enable 0 1 + transp 0 0 + clocks 0 1 + clkpol 0 2 +endbram + +bram $__XILINX_RAM64M + init 1 + abits 6 + dbits 1 + groups 2 + ports 3 1 + wrmode 0 1 + enable 0 1 + transp 0 0 + clocks 0 1 + clkpol 0 2 +endbram + + +match $__XILINX_RAM16X1D + min bits 2 + min wports 1 + make_outreg + or_next_if_better +endmatch + match $__XILINX_RAM32X1D min bits 3 min wports 1 @@ -56,5 +104,21 @@ match $__XILINX_RAM128X1D min bits 9 min wports 1 make_outreg + or_next_if_better +endmatch + + +match $__XILINX_RAM32M + min bits 5 + min rports 3 + min wports 1 + make_outreg + or_next_if_better endmatch +match $__XILINX_RAM64M + min bits 5 + min rports 3 + min wports 1 + make_outreg +endmatch diff --git a/techlibs/xilinx/lutrams_map.v b/techlibs/xilinx/lutrams_map.v index 77041ca86..985e53ff4 100644 --- a/techlibs/xilinx/lutrams_map.v +++ b/techlibs/xilinx/lutrams_map.v @@ -1,4 +1,36 @@ +module \$__XILINX_RAM16X1D (CLK1, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN); + parameter [15:0] INIT = 16'bx; + parameter CLKPOL2 = 1; + input CLK1; + + input [3:0] A1ADDR; + output A1DATA; + + input [3:0] B1ADDR; + input B1DATA; + input B1EN; + + RAM16X1D #( + .INIT(INIT), + .IS_WCLK_INVERTED(!CLKPOL2) + ) _TECHMAP_REPLACE_ ( + .DPRA0(A1ADDR[0]), + .DPRA1(A1ADDR[1]), + .DPRA2(A1ADDR[2]), + .DPRA3(A1ADDR[3]), + .DPO(A1DATA), + + .A0(B1ADDR[0]), + .A1(B1ADDR[1]), + .A2(B1ADDR[2]), + .A3(B1ADDR[3]), + .D(B1DATA), + .WCLK(CLK1), + .WE(B1EN) + ); +endmodule + module \$__XILINX_RAM32X1D (CLK1, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN); parameter [31:0] INIT = 32'bx; parameter CLKPOL2 = 1; @@ -95,3 +127,75 @@ module \$__XILINX_RAM128X1D (CLK1, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN); ); endmodule + +module \$__XILINX_RAM32M (CLK1, A1ADDR, A1DATA, A2ADDR, A2DATA, A3ADDR, A3DATA, B1ADDR, B1DATA, B1EN); + parameter [31:0] INIT = 32'bx; + parameter CLKPOL2 = 1; + input CLK1; + + input [4:0] A1ADDR, A2ADDR, A3ADDR; + output [1:0] A1DATA, A2DATA, A3DATA; + + input [4:0] B1ADDR; + input [1:0] B1DATA; + input B1EN; + + RAM32M #( + .INIT_A(INIT), + .INIT_B(INIT), + .INIT_C(INIT), + .INIT_D(INIT), + .IS_WCLK_INVERTED(!CLKPOL2) + ) _TECHMAP_REPLACE_ ( + .ADDRA(A1ADDR), + .ADDRB(A2ADDR), + .ADDRC(A3ADDR), + .DOA(A1DATA), + .DOB(A2DATA), + .DOC(A3DATA), + + .ADDRD(B1ADDR), + .DIA(B1DATA), + .DIB(B1DATA), + .DIC(B1DATA), + .DID(B1DATA), + .WCLK(CLK1), + .WE(B1EN) + ); +endmodule + +module \$__XILINX_RAM64M (CLK1, A1ADDR, A1DATA, A2ADDR, A2DATA, A3ADDR, A3DATA, B1ADDR, B1DATA, B1EN); + parameter [63:0] INIT = 32'bx; + parameter CLKPOL2 = 1; + input CLK1; + + input [5:0] A1ADDR, A2ADDR, A3ADDR; + output A1DATA, A2DATA, A3DATA; + + input [5:0] B1ADDR; + input B1DATA; + input B1EN; + + RAM64M #( + .INIT_A(INIT), + .INIT_B(INIT), + .INIT_C(INIT), + .INIT_D(INIT), + .IS_WCLK_INVERTED(!CLKPOL2) + ) _TECHMAP_REPLACE_ ( + .ADDRA(A1ADDR), + .ADDRB(A2ADDR), + .ADDRC(A3ADDR), + .DOA(A1DATA), + .DOB(A2DATA), + .DOC(A3DATA), + + .ADDRD(B1ADDR), + .DIA(B1DATA), + .DIB(B1DATA), + .DIC(B1DATA), + .DID(B1DATA), + .WCLK(CLK1), + .WE(B1EN) + ); +endmodule -- cgit v1.2.3 From 037d1a03df20b9c445790728bb80e1818d1edafa Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 12 Dec 2019 17:49:55 -0800 Subject: Add #1460 testcase --- tests/arch/xilinx/bug1460.ys | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 tests/arch/xilinx/bug1460.ys diff --git a/tests/arch/xilinx/bug1460.ys b/tests/arch/xilinx/bug1460.ys new file mode 100644 index 000000000..2018071cc --- /dev/null +++ b/tests/arch/xilinx/bug1460.ys @@ -0,0 +1,34 @@ +read_verilog < Date: Thu, 12 Dec 2019 18:52:03 -0800 Subject: Fix RAM64M model to have 6 bit address bus --- techlibs/xilinx/cells_sim.v | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/techlibs/xilinx/cells_sim.v b/techlibs/xilinx/cells_sim.v index 3ed0759db..56eb782c6 100644 --- a/techlibs/xilinx/cells_sim.v +++ b/techlibs/xilinx/cells_sim.v @@ -1185,10 +1185,10 @@ module RAM64M ( output DOB, output DOC, output DOD, - input [4:0] ADDRA, - input [4:0] ADDRB, - input [4:0] ADDRC, - input [4:0] ADDRD, + input [5:0] ADDRA, + input [5:0] ADDRB, + input [5:0] ADDRC, + input [5:0] ADDRD, input DIA, input DIB, input DIC, -- cgit v1.2.3 From 8925bf4b9639e1604eb3fd9a298d9f1138093a56 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 12 Dec 2019 18:52:28 -0800 Subject: Add RAM32X6SDP and RAM64X3SDP modes --- techlibs/xilinx/lutrams.txt | 40 ++++++++++++++++++++ techlibs/xilinx/lutrams_map.v | 88 +++++++++++++++++++++++++++++++++++++++---- 2 files changed, 120 insertions(+), 8 deletions(-) diff --git a/techlibs/xilinx/lutrams.txt b/techlibs/xilinx/lutrams.txt index 3e260b0d7..be764a63f 100644 --- a/techlibs/xilinx/lutrams.txt +++ b/techlibs/xilinx/lutrams.txt @@ -52,6 +52,32 @@ bram $__XILINX_RAM128X1D endbram +bram $__XILINX_RAM32X6SDP + init 1 + abits 5 + dbits 6 + groups 2 + ports 1 1 + wrmode 0 1 + enable 0 1 + transp 0 0 + clocks 0 1 + clkpol 0 2 +endbram + +bram $__XILINX_RAM64X3SDP + init 1 + abits 6 + dbits 3 + groups 2 + ports 1 1 + wrmode 0 1 + enable 0 1 + transp 0 0 + clocks 0 1 + clkpol 0 2 +endbram + bram $__XILINX_RAM32M init 1 abits 5 @@ -108,6 +134,20 @@ match $__XILINX_RAM128X1D endmatch +match $__XILINX_RAM32X6SDP + min bits 5 + min wports 1 + make_outreg + or_next_if_better +endmatch + +match $__XILINX_RAM64X3SDP + min bits 6 + min wports 1 + make_outreg + or_next_if_better +endmatch + match $__XILINX_RAM32M min bits 5 min rports 3 diff --git a/techlibs/xilinx/lutrams_map.v b/techlibs/xilinx/lutrams_map.v index 985e53ff4..d01508de5 100644 --- a/techlibs/xilinx/lutrams_map.v +++ b/techlibs/xilinx/lutrams_map.v @@ -128,8 +128,80 @@ module \$__XILINX_RAM128X1D (CLK1, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN); endmodule +module \$__XILINX_RAM32X6SDP (CLK1, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN); + parameter [32*6-1:0] INIT = {32*6{1'bx}}; + parameter CLKPOL2 = 1; + input CLK1; + + input [4:0] A1ADDR; + output [5:0] A1DATA; + + input [4:0] B1ADDR; + input [5:0] B1DATA; + input B1EN; + + RAM32M #( + .INIT_A({INIT[187:186], INIT[181:180], INIT[175:174], INIT[169:168], INIT[163:162], INIT[157:156], INIT[151:150], INIT[145:144], INIT[139:138], INIT[133:132], INIT[127:126], INIT[121:120], INIT[115:114], INIT[109:108], INIT[103:102], INIT[ 97: 96], INIT[ 91: 90], INIT[ 85: 84], INIT[ 79: 78], INIT[ 73: 72], INIT[ 67: 66], INIT[ 61: 60], INIT[ 55: 54], INIT[ 49: 48], INIT[ 43: 42], INIT[ 37: 36], INIT[ 31: 30], INIT[ 25: 24], INIT[ 19: 18], INIT[ 13: 12], INIT[ 7: 6], INIT[ 1: 0]}), + .INIT_B({INIT[189:188], INIT[183:182], INIT[177:176], INIT[171:170], INIT[165:164], INIT[159:158], INIT[153:152], INIT[147:146], INIT[141:140], INIT[135:134], INIT[129:128], INIT[123:122], INIT[117:116], INIT[111:110], INIT[105:104], INIT[ 99: 98], INIT[ 93: 92], INIT[ 87: 86], INIT[ 81: 80], INIT[ 75: 74], INIT[ 69: 68], INIT[ 63: 62], INIT[ 57: 56], INIT[ 51: 50], INIT[ 45: 44], INIT[ 39: 38], INIT[ 33: 32], INIT[ 27: 26], INIT[ 21: 20], INIT[ 15: 14], INIT[ 9: 8], INIT[ 3: 2]}), + .INIT_C({INIT[191:190], INIT[185:184], INIT[179:178], INIT[173:172], INIT[167:166], INIT[161:160], INIT[155:154], INIT[149:148], INIT[143:142], INIT[137:136], INIT[131:130], INIT[125:124], INIT[119:118], INIT[113:112], INIT[107:106], INIT[101:100], INIT[ 95: 94], INIT[ 89: 88], INIT[ 83: 82], INIT[ 77: 76], INIT[ 71: 70], INIT[ 65: 64], INIT[ 59: 58], INIT[ 53: 52], INIT[ 47: 46], INIT[ 41: 40], INIT[ 35: 34], INIT[ 29: 28], INIT[ 23: 22], INIT[ 17: 16], INIT[ 11: 10], INIT[ 5: 4]}), + .INIT_D(64'bx), + .IS_WCLK_INVERTED(!CLKPOL2) + ) _TECHMAP_REPLACE_ ( + .ADDRA(A1ADDR), + .ADDRB(A1ADDR), + .ADDRC(A1ADDR), + .DOA(A1DATA[1:0]), + .DOB(A1DATA[3:2]), + .DOC(A1DATA[5:4]), + + .ADDRD(B1ADDR), + .DIA(B1DATA[1:0]), + .DIB(B1DATA[3:2]), + .DIC(B1DATA[5:4]), + .DID(), + .WCLK(CLK1), + .WE(B1EN) + ); +endmodule + +module \$__XILINX_RAM64X3SDP (CLK1, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN); + parameter [64*3-1:0] INIT = {64*3{1'bx}}; + parameter CLKPOL2 = 1; + input CLK1; + + input [5:0] A1ADDR; + output [2:0] A1DATA; + + input [5:0] B1ADDR; + input [2:0] B1DATA; + input B1EN; + + RAM64M #( + .INIT_A({INIT[189], INIT[186], INIT[183], INIT[180], INIT[177], INIT[174], INIT[171], INIT[168], INIT[165], INIT[162], INIT[159], INIT[156], INIT[153], INIT[150], INIT[147], INIT[144], INIT[141], INIT[138], INIT[135], INIT[132], INIT[129], INIT[126], INIT[123], INIT[120], INIT[117], INIT[114], INIT[111], INIT[108], INIT[105], INIT[102], INIT[ 99], INIT[ 96], INIT[ 93], INIT[ 90], INIT[ 87], INIT[ 84], INIT[ 81], INIT[ 78], INIT[ 75], INIT[ 72], INIT[ 69], INIT[ 66], INIT[ 63], INIT[ 60], INIT[ 57], INIT[ 54], INIT[ 51], INIT[ 48], INIT[ 45], INIT[ 42], INIT[ 39], INIT[ 36], INIT[ 33], INIT[ 30], INIT[ 27], INIT[ 24], INIT[ 21], INIT[ 18], INIT[ 15], INIT[ 12], INIT[ 9], INIT[ 6], INIT[ 3], INIT[ 0]}), + .INIT_B({INIT[190], INIT[187], INIT[184], INIT[181], INIT[178], INIT[175], INIT[172], INIT[169], INIT[166], INIT[163], INIT[160], INIT[157], INIT[154], INIT[151], INIT[148], INIT[145], INIT[142], INIT[139], INIT[136], INIT[133], INIT[130], INIT[127], INIT[124], INIT[121], INIT[118], INIT[115], INIT[112], INIT[109], INIT[106], INIT[103], INIT[100], INIT[ 97], INIT[ 94], INIT[ 91], INIT[ 88], INIT[ 85], INIT[ 82], INIT[ 79], INIT[ 76], INIT[ 73], INIT[ 70], INIT[ 67], INIT[ 64], INIT[ 61], INIT[ 58], INIT[ 55], INIT[ 52], INIT[ 49], INIT[ 46], INIT[ 43], INIT[ 40], INIT[ 37], INIT[ 34], INIT[ 31], INIT[ 28], INIT[ 25], INIT[ 22], INIT[ 19], INIT[ 16], INIT[ 13], INIT[ 10], INIT[ 7], INIT[ 4], INIT[ 1]}), + .INIT_C({INIT[191], INIT[188], INIT[185], INIT[182], INIT[179], INIT[176], INIT[173], INIT[170], INIT[167], INIT[164], INIT[161], INIT[158], INIT[155], INIT[152], INIT[149], INIT[146], INIT[143], INIT[140], INIT[137], INIT[134], INIT[131], INIT[128], INIT[125], INIT[122], INIT[119], INIT[116], INIT[113], INIT[110], INIT[107], INIT[104], INIT[101], INIT[ 98], INIT[ 95], INIT[ 92], INIT[ 89], INIT[ 86], INIT[ 83], INIT[ 80], INIT[ 77], INIT[ 74], INIT[ 71], INIT[ 68], INIT[ 65], INIT[ 62], INIT[ 59], INIT[ 56], INIT[ 53], INIT[ 50], INIT[ 47], INIT[ 44], INIT[ 41], INIT[ 38], INIT[ 35], INIT[ 32], INIT[ 29], INIT[ 26], INIT[ 23], INIT[ 20], INIT[ 17], INIT[ 14], INIT[ 11], INIT[ 8], INIT[ 5], INIT[ 2]}), + .INIT_D(64'bx), + .IS_WCLK_INVERTED(!CLKPOL2) + ) _TECHMAP_REPLACE_ ( + .ADDRA(A1ADDR), + .ADDRB(A1ADDR), + .ADDRC(A1ADDR), + .DOA(A1DATA[0]), + .DOB(A1DATA[1]), + .DOC(A1DATA[2]), + + .ADDRD(B1ADDR), + .DIA(B1DATA[0]), + .DIB(B1DATA[1]), + .DIC(B1DATA[2]), + .DID(), + .WCLK(CLK1), + .WE(B1EN) + ); +endmodule + module \$__XILINX_RAM32M (CLK1, A1ADDR, A1DATA, A2ADDR, A2DATA, A3ADDR, A3DATA, B1ADDR, B1DATA, B1EN); - parameter [31:0] INIT = 32'bx; + parameter [63:0] INIT = 64'bx; parameter CLKPOL2 = 1; input CLK1; @@ -150,9 +222,9 @@ module \$__XILINX_RAM32M (CLK1, A1ADDR, A1DATA, A2ADDR, A2DATA, A3ADDR, A3DATA, .ADDRA(A1ADDR), .ADDRB(A2ADDR), .ADDRC(A3ADDR), - .DOA(A1DATA), - .DOB(A2DATA), - .DOC(A3DATA), + .DOA(A1DATA), + .DOB(A2DATA), + .DOC(A3DATA), .ADDRD(B1ADDR), .DIA(B1DATA), @@ -165,7 +237,7 @@ module \$__XILINX_RAM32M (CLK1, A1ADDR, A1DATA, A2ADDR, A2DATA, A3ADDR, A3DATA, endmodule module \$__XILINX_RAM64M (CLK1, A1ADDR, A1DATA, A2ADDR, A2DATA, A3ADDR, A3DATA, B1ADDR, B1DATA, B1EN); - parameter [63:0] INIT = 32'bx; + parameter [63:0] INIT = 64'bx; parameter CLKPOL2 = 1; input CLK1; @@ -186,9 +258,9 @@ module \$__XILINX_RAM64M (CLK1, A1ADDR, A1DATA, A2ADDR, A2DATA, A3ADDR, A3DATA, .ADDRA(A1ADDR), .ADDRB(A2ADDR), .ADDRC(A3ADDR), - .DOA(A1DATA), - .DOB(A2DATA), - .DOC(A3DATA), + .DOA(A1DATA), + .DOB(A2DATA), + .DOC(A3DATA), .ADDRD(B1ADDR), .DIA(B1DATA), -- cgit v1.2.3 From 01116f0f0a0ace0c676271904222932dd433aae1 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 12 Dec 2019 18:52:48 -0800 Subject: Add tests for these new models --- tests/arch/xilinx/lutram.ys | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/tests/arch/xilinx/lutram.ys b/tests/arch/xilinx/lutram.ys index 9b2c30ba1..36367eff1 100644 --- a/tests/arch/xilinx/lutram.ys +++ b/tests/arch/xilinx/lutram.ys @@ -97,3 +97,43 @@ select -assert-count 1 t:BUFG select -assert-count 24 t:FDRE select -assert-count 8 t:RAM64M select -assert-none t:BUFG t:FDRE t:RAM64M %% t:* %D + + +design -reset +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 +memory +opt -full + +miter -equiv -flatten -make_assert -make_outputs gold gate miter +sat -verify -prove-asserts -seq 3 -set-init-zero -show-inputs -show-outputs miter + +design -load postopt +cd lutram_1w1r +select -assert-count 1 t:BUFG +select -assert-count 6 t:FDRE +select -assert-count 1 t:RAM32M +select -assert-none t:BUFG t:FDRE t:RAM32M %% t:* %D + + +design -reset +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 +memory +opt -full + +miter -equiv -flatten -make_assert -make_outputs gold gate miter +sat -verify -prove-asserts -seq 3 -set-init-zero -show-inputs -show-outputs miter + +design -load postopt +cd lutram_1w1r +select -assert-count 1 t:BUFG +select -assert-count 6 t:FDRE +select -assert-count 2 t:RAM64M +select -assert-none t:BUFG t:FDRE t:RAM64M %% t:* %D -- cgit v1.2.3 From d0ee4cd88f1f966c194fdc60e47ef67944882afb Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 12 Dec 2019 19:00:26 -0800 Subject: Remove extraneous synth_xilinx call --- tests/arch/xilinx/lutram.ys | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/arch/xilinx/lutram.ys b/tests/arch/xilinx/lutram.ys index 36367eff1..a2ede75a5 100644 --- a/tests/arch/xilinx/lutram.ys +++ b/tests/arch/xilinx/lutram.ys @@ -62,7 +62,6 @@ read_verilog ../common/lutram.v hierarchy -top lutram_1w3r proc memory -nomap -synth_xilinx equiv_opt -run :prove -map +/xilinx/cells_sim.v synth_xilinx memory opt -full @@ -83,7 +82,6 @@ read_verilog ../common/lutram.v hierarchy -top lutram_1w3r -chparam A_WIDTH 6 proc memory -nomap -synth_xilinx equiv_opt -run :prove -map +/xilinx/cells_sim.v synth_xilinx memory opt -full -- cgit v1.2.3 From ce3615b3670b942ae281db425b290023b1395b69 Mon Sep 17 00:00:00 2001 From: "N. Engelhardt" Date: Fri, 13 Dec 2019 10:28:34 +0100 Subject: add periods and newlines to help message --- passes/cmds/scratchpad.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/passes/cmds/scratchpad.cc b/passes/cmds/scratchpad.cc index c11c41caf..6bf14a6bd 100644 --- a/passes/cmds/scratchpad.cc +++ b/passes/cmds/scratchpad.cc @@ -34,15 +34,15 @@ struct ScratchpadPass : public Pass { log(" scratchpad [options]\n"); log("\n"); log("This pass allows to read and modify values from the scratchpad of the current\n"); - log("design. Options:\n"); + log("design. Options:\n\n"); log(" -get \n"); - log(" print the value saved in the scratchpad under the given identifier\n"); + log(" print the value saved in the scratchpad under the given identifier.\n\n"); log(" -set \n"); - log(" save the given value in the scratchpad under the given identifier\n"); + log(" save the given value in the scratchpad under the given identifier.\n\n"); log(" -unset \n"); - log(" remove the entry for the given identifier from the scratchpad\n"); + log(" remove the entry for the given identifier from the scratchpad.\n\n"); log(" -copy \n"); - log(" copy the value of the first identifier to the second identifier\n"); + log(" copy the value of the first identifier to the second identifier.\n\n"); log("The identifier may not contain whitespace. By convention, it is usually prefixed\n"); log("by the name of the pass that uses it, e.g. 'opt.did_something'. If the value\n"); log("contains whitespace, it must be enclosed in double quotes.\n"); -- cgit v1.2.3 From 91f427d7195caea16e116df7051bacd0da6212a6 Mon Sep 17 00:00:00 2001 From: "N. Engelhardt" Date: Fri, 13 Dec 2019 12:54:52 +0100 Subject: check scratchpad variables for custom abc scripts --- passes/techmap/abc.cc | 2 ++ passes/techmap/abc9.cc | 2 ++ 2 files changed, 4 insertions(+) diff --git a/passes/techmap/abc.cc b/passes/techmap/abc.cc index b29480e26..9b156a2af 100644 --- a/passes/techmap/abc.cc +++ b/passes/techmap/abc.cc @@ -732,6 +732,8 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin abc_script += script_file[i]; } else abc_script += stringf("source %s", script_file.c_str()); + } else if (design->scratchpad.count("abc.script")) { + abc_script += design->scratchpad_get_string("abc.script"); } else if (!lut_costs.empty()) { bool all_luts_cost_same = true; for (int this_cost : lut_costs) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 8276c3c16..7fd235d6e 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -332,6 +332,8 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri abc9_script += script_file[i]; } else abc9_script += stringf("source %s", script_file.c_str()); + } else if (design->scratchpad.count("abc9.script")) { + abc9_script += design->scratchpad_get_string("abc9.script"); } else if (!lut_costs.empty() || !lut_file.empty()) { //bool all_luts_cost_same = true; //for (int this_cost : lut_costs) -- cgit v1.2.3 From e9dc2759c414bdc8ab663fd5c8350b40b099b456 Mon Sep 17 00:00:00 2001 From: Rodrigo Alejandro Melo Date: Fri, 13 Dec 2019 10:17:05 -0300 Subject: Fixed some missing "verilog_" in documentation --- frontends/verilog/preproc.cc | 2 +- frontends/verilog/verilog_lexer.l | 2 +- manual/CHAPTER_Verilog.tex | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/frontends/verilog/preproc.cc b/frontends/verilog/preproc.cc index 7e107dc26..161253a99 100644 --- a/frontends/verilog/preproc.cc +++ b/frontends/verilog/preproc.cc @@ -28,7 +28,7 @@ * * Ad-hoc implementation of a Verilog preprocessor. The directives `define, * `include, `ifdef, `ifndef, `else and `endif are handled here. All other - * directives are handled by the lexer (see lexer.l). + * directives are handled by the lexer (see verilog_lexer.l). * */ diff --git a/frontends/verilog/verilog_lexer.l b/frontends/verilog/verilog_lexer.l index c8984c2c4..ca23df3e8 100644 --- a/frontends/verilog/verilog_lexer.l +++ b/frontends/verilog/verilog_lexer.l @@ -28,7 +28,7 @@ * * A simple lexer for Verilog code. Non-preprocessor compiler directives are * handled here. The preprocessor stuff is handled in preproc.cc. Everything - * else is left to the bison parser (see parser.y). + * else is left to the bison parser (see verilog_parser.y). * */ diff --git a/manual/CHAPTER_Verilog.tex b/manual/CHAPTER_Verilog.tex index e9ca6114e..d4cc55647 100644 --- a/manual/CHAPTER_Verilog.tex +++ b/manual/CHAPTER_Verilog.tex @@ -93,7 +93,7 @@ frontends/verilog/preproc.cc} in the Yosys source tree. \begin{sloppypar} The Verilog Lexer is written using the lexer generator {\it flex} \citeweblink{flex}. Its source code -can be found in {\tt frontends/verilog/lexer.l} in the Yosys source tree. +can be found in {\tt frontends/verilog/verilog\_lexer.l} in the Yosys source tree. The lexer does little more than identifying all keywords and literals recognised by the Yosys Verilog frontend. \end{sloppypar} @@ -115,7 +115,7 @@ whenever possible.) \subsection{The Verilog Parser} The Verilog Parser is written using the parser generator {\it bison} \citeweblink{bison}. Its source code -can be found in {\tt frontends/verilog/parser.y} in the Yosys source tree. +can be found in {\tt frontends/verilog/verilog\_parser.y} in the Yosys source tree. It generates an AST using the \lstinline[language=C++]{AST::AstNode} data structure defined in {\tt frontends/ast/ast.h}. An \lstinline[language=C++]{AST::AstNode} object has -- cgit v1.2.3 From 1c9634558747bf5b92a309b6af013a54034c35d3 Mon Sep 17 00:00:00 2001 From: Diego H Date: Fri, 13 Dec 2019 09:33:18 -0600 Subject: Renaming BRAM memory tests for the sake of uniformity --- tests/arch/common/blockram_params.v | 45 ++++++++++++++++++++++++++++++++++ tests/arch/common/memory_params.v | 45 ---------------------------------- tests/arch/xilinx/blockram_params.ys | 47 ++++++++++++++++++++++++++++++++++++ tests/arch/xilinx/memory_params.ys | 47 ------------------------------------ 4 files changed, 92 insertions(+), 92 deletions(-) create mode 100644 tests/arch/common/blockram_params.v delete mode 100644 tests/arch/common/memory_params.v create mode 100644 tests/arch/xilinx/blockram_params.ys delete mode 100644 tests/arch/xilinx/memory_params.ys diff --git a/tests/arch/common/blockram_params.v b/tests/arch/common/blockram_params.v new file mode 100644 index 000000000..dbc6ca65c --- /dev/null +++ b/tests/arch/common/blockram_params.v @@ -0,0 +1,45 @@ +`default_nettype none +module sync_ram_sp #(parameter DATA_WIDTH=8, ADDRESS_WIDTH=10) + (input wire write_enable, clk, + input wire [DATA_WIDTH-1:0] data_in, + input wire [ADDRESS_WIDTH-1:0] address_in, + output wire [DATA_WIDTH-1:0] data_out); + + localparam WORD = (DATA_WIDTH-1); + localparam DEPTH = (2**ADDRESS_WIDTH-1); + + reg [WORD:0] data_out_r; + reg [WORD:0] memory [0:DEPTH]; + + always @(posedge clk) begin + if (write_enable) + memory[address_in] <= data_in; + data_out_r <= memory[address_in]; + end + + assign data_out = data_out_r; +endmodule // sync_ram_sp + + +`default_nettype none +module sync_ram_sdp #(parameter DATA_WIDTH=8, ADDRESS_WIDTH=10) + (input wire clk, write_enable, + input wire [DATA_WIDTH-1:0] data_in, + input wire [ADDRESS_WIDTH-1:0] address_in_r, address_in_w, + output wire [DATA_WIDTH-1:0] data_out); + + localparam WORD = (DATA_WIDTH-1); + localparam DEPTH = (2**ADDRESS_WIDTH-1); + + reg [WORD:0] data_out_r; + reg [WORD:0] memory [0:DEPTH]; + + always @(posedge clk) begin + if (write_enable) + memory[address_in_w] <= data_in; + data_out_r <= memory[address_in_r]; + end + + assign data_out = data_out_r; +endmodule // sync_ram_sdp + diff --git a/tests/arch/common/memory_params.v b/tests/arch/common/memory_params.v deleted file mode 100644 index dbc6ca65c..000000000 --- a/tests/arch/common/memory_params.v +++ /dev/null @@ -1,45 +0,0 @@ -`default_nettype none -module sync_ram_sp #(parameter DATA_WIDTH=8, ADDRESS_WIDTH=10) - (input wire write_enable, clk, - input wire [DATA_WIDTH-1:0] data_in, - input wire [ADDRESS_WIDTH-1:0] address_in, - output wire [DATA_WIDTH-1:0] data_out); - - localparam WORD = (DATA_WIDTH-1); - localparam DEPTH = (2**ADDRESS_WIDTH-1); - - reg [WORD:0] data_out_r; - reg [WORD:0] memory [0:DEPTH]; - - always @(posedge clk) begin - if (write_enable) - memory[address_in] <= data_in; - data_out_r <= memory[address_in]; - end - - assign data_out = data_out_r; -endmodule // sync_ram_sp - - -`default_nettype none -module sync_ram_sdp #(parameter DATA_WIDTH=8, ADDRESS_WIDTH=10) - (input wire clk, write_enable, - input wire [DATA_WIDTH-1:0] data_in, - input wire [ADDRESS_WIDTH-1:0] address_in_r, address_in_w, - output wire [DATA_WIDTH-1:0] data_out); - - localparam WORD = (DATA_WIDTH-1); - localparam DEPTH = (2**ADDRESS_WIDTH-1); - - reg [WORD:0] data_out_r; - reg [WORD:0] memory [0:DEPTH]; - - always @(posedge clk) begin - if (write_enable) - memory[address_in_w] <= data_in; - data_out_r <= memory[address_in_r]; - end - - assign data_out = data_out_r; -endmodule // sync_ram_sdp - diff --git a/tests/arch/xilinx/blockram_params.ys b/tests/arch/xilinx/blockram_params.ys new file mode 100644 index 000000000..27a94834e --- /dev/null +++ b/tests/arch/xilinx/blockram_params.ys @@ -0,0 +1,47 @@ +## TODO: Not running equivalence checking because BRAM models does not exists +## currently. Checking instance counts instead. +# Memory bits <= 18K; Data width <= 36; Address width <= 14: -> RAMB18E1 +read_verilog ../common/blockram_params.v +chparam -set ADDRESS_WIDTH 10 -set DATA_WIDTH 1 sync_ram_sdp +synth_xilinx -top sync_ram_sdp +cd sync_ram_sdp +select -assert-count 1 t:RAMB18E1 + +design -reset +read_verilog ../common/blockram_params.v +chparam -set ADDRESS_WIDTH 8 -set DATA_WIDTH 18 sync_ram_sdp +synth_xilinx -top sync_ram_sdp +cd sync_ram_sdp +select -assert-count 1 t:RAMB18E1 + +design -reset +read_verilog ../common/blockram_params.v +chparam -set ADDRESS_WIDTH 14 -set DATA_WIDTH 1 sync_ram_sdp +synth_xilinx -top sync_ram_sdp +cd sync_ram_sdp +select -assert-count 1 t:RAMB18E1 + +design -reset +read_verilog ../common/blockram_params.v +chparam -set ADDRESS_WIDTH 9 -set DATA_WIDTH 36 sync_ram_sdp +synth_xilinx -top sync_ram_sdp +cd sync_ram_sdp +select -assert-count 1 t:RAMB18E1 + +# Anything memory bits < 1024 -> LUTRAM +design -reset +read_verilog ../common/blockram_params.v +chparam -set ADDRESS_WIDTH 8 -set DATA_WIDTH 2 sync_ram_sdp +synth_xilinx -top sync_ram_sdp +cd sync_ram_sdp +select -assert-count 0 t:RAMB18E1 +select -assert-count 4 t:RAM128X1D + +# More than 18K bits, data width <= 36 (TDP), and address width from 10 to 15b (non-cascaded) -> RAMB36E1 +design -reset +read_verilog ../common/blockram_params.v +chparam -set ADDRESS_WIDTH 10 -set DATA_WIDTH 36 sync_ram_sdp +synth_xilinx -top sync_ram_sdp +cd sync_ram_sdp +select -assert-count 1 t:RAMB36E1 + diff --git a/tests/arch/xilinx/memory_params.ys b/tests/arch/xilinx/memory_params.ys deleted file mode 100644 index c1b0ca489..000000000 --- a/tests/arch/xilinx/memory_params.ys +++ /dev/null @@ -1,47 +0,0 @@ -## TODO: Not running equivalence checking because BRAM models does not exists -## currently. Checking instance counts instead. -# Memory bits <= 18K; Data width <= 36; Address width <= 14: -> RAMB18E1 -read_verilog ../common/memory_params.v -chparam -set ADDRESS_WIDTH 10 -set DATA_WIDTH 1 sync_ram_sdp -synth_xilinx -top sync_ram_sdp -cd sync_ram_sdp -select -assert-count 1 t:RAMB18E1 - -design -reset -read_verilog ../common/memory_params.v -chparam -set ADDRESS_WIDTH 8 -set DATA_WIDTH 18 sync_ram_sdp -synth_xilinx -top sync_ram_sdp -cd sync_ram_sdp -select -assert-count 1 t:RAMB18E1 - -design -reset -read_verilog ../common/memory_params.v -chparam -set ADDRESS_WIDTH 14 -set DATA_WIDTH 1 sync_ram_sdp -synth_xilinx -top sync_ram_sdp -cd sync_ram_sdp -select -assert-count 1 t:RAMB18E1 - -design -reset -read_verilog ../common/memory_params.v -chparam -set ADDRESS_WIDTH 9 -set DATA_WIDTH 36 sync_ram_sdp -synth_xilinx -top sync_ram_sdp -cd sync_ram_sdp -select -assert-count 1 t:RAMB18E1 - -# Anything memory bits < 1024 -> LUTRAM -design -reset -read_verilog ../common/memory_params.v -chparam -set ADDRESS_WIDTH 8 -set DATA_WIDTH 2 sync_ram_sdp -synth_xilinx -top sync_ram_sdp -cd sync_ram_sdp -select -assert-count 0 t:RAMB18E1 -select -assert-count 4 t:RAM128X1D - -# More than 18K bits, data width <= 36 (TDP), and address width from 10 to 15b (non-cascaded) -> RAMB36E1 -design -reset -read_verilog ../common/memory_params.v -chparam -set ADDRESS_WIDTH 10 -set DATA_WIDTH 36 sync_ram_sdp -synth_xilinx -top sync_ram_sdp -cd sync_ram_sdp -select -assert-count 1 t:RAMB36E1 - -- cgit v1.2.3 From dd7d2d8db615f7d54d9bbee257fad9fb11bdc9f8 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 13 Dec 2019 08:51:05 -0800 Subject: Duplicate tribuf call, credit to @mwkmwkmwk --- techlibs/xilinx/synth_xilinx.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index 6dd769055..640659ad6 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -310,7 +310,6 @@ struct SynthXilinxPass : public ScriptPass run("tribuf -logic"); if (!do_iopad && active_design->scratchpad_get_bool("tribuf.added_something")) log_error("Tristate buffers are unsupported without the '-iopad' option.\n"); - run("tribuf -logic"); run("deminout"); run("opt_expr"); run("opt_clean"); -- cgit v1.2.3 From d6514fc2e13976b15be396f413b046deb6f0c9fa Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 13 Dec 2019 08:54:19 -0800 Subject: RAM64M8 to also have [5:0] for address --- techlibs/xilinx/cells_sim.v | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/techlibs/xilinx/cells_sim.v b/techlibs/xilinx/cells_sim.v index 56eb782c6..f9ce496ff 100644 --- a/techlibs/xilinx/cells_sim.v +++ b/techlibs/xilinx/cells_sim.v @@ -1230,14 +1230,14 @@ module RAM64M8 ( output DOF, output DOG, output DOH, - input [4:0] ADDRA, - input [4:0] ADDRB, - input [4:0] ADDRC, - input [4:0] ADDRD, - input [4:0] ADDRE, - input [4:0] ADDRF, - input [4:0] ADDRG, - input [4:0] ADDRH, + input [5:0] ADDRA, + input [5:0] ADDRB, + input [5:0] ADDRC, + input [5:0] ADDRD, + input [5:0] ADDRE, + input [5:0] ADDRF, + input [5:0] ADDRG, + input [5:0] ADDRH, input DIA, input DIB, input DIC, -- cgit v1.2.3 From c3262d60752bb20ff5cd54bc4ee6f56e2b772b05 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 13 Dec 2019 08:59:17 -0800 Subject: Disable RAM16X1D match rule; carry-over from LUT4 arches --- techlibs/xilinx/lutrams.txt | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/techlibs/xilinx/lutrams.txt b/techlibs/xilinx/lutrams.txt index be764a63f..ae629bce8 100644 --- a/techlibs/xilinx/lutrams.txt +++ b/techlibs/xilinx/lutrams.txt @@ -105,12 +105,15 @@ bram $__XILINX_RAM64M endbram -match $__XILINX_RAM16X1D - min bits 2 - min wports 1 - make_outreg - or_next_if_better -endmatch +# Disabled for now, pending support for LUT4 arches +# since on LUT6 arches this occupies same area as +# a RAM32X1D +#match $__XILINX_RAM16X1D +# min bits 2 +# min wports 1 +# make_outreg +# or_next_if_better +#endmatch match $__XILINX_RAM32X1D min bits 3 -- cgit v1.2.3 From a5764a12365073768edb822e893aa9c0a957e585 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 13 Dec 2019 10:28:13 -0800 Subject: Disable RAM16X1D test --- tests/arch/xilinx/lutram.ys | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/tests/arch/xilinx/lutram.ys b/tests/arch/xilinx/lutram.ys index a2ede75a5..6c9d1eae1 100644 --- a/tests/arch/xilinx/lutram.ys +++ b/tests/arch/xilinx/lutram.ys @@ -1,20 +1,20 @@ -read_verilog ../common/lutram.v -hierarchy -top lutram_1w1r -chparam A_WIDTH 4 -proc -memory -nomap -equiv_opt -run :prove -map +/xilinx/cells_sim.v synth_xilinx -memory -opt -full - -miter -equiv -flatten -make_assert -make_outputs gold gate miter -sat -verify -prove-asserts -seq 3 -set-init-zero -show-inputs -show-outputs miter - -design -load postopt -cd lutram_1w1r -select -assert-count 1 t:BUFG -select -assert-count 8 t:FDRE -select -assert-count 8 t:RAM16X1D -select -assert-none t:BUFG t:FDRE t:RAM16X1D %% t:* %D +#read_verilog ../common/lutram.v +#hierarchy -top lutram_1w1r -chparam A_WIDTH 4 +#proc +#memory -nomap +#equiv_opt -run :prove -map +/xilinx/cells_sim.v synth_xilinx +#memory +#opt -full +# +#miter -equiv -flatten -make_assert -make_outputs gold gate miter +#sat -verify -prove-asserts -seq 3 -set-init-zero -show-inputs -show-outputs miter +# +#design -load postopt +#cd lutram_1w1r +#select -assert-count 1 t:BUFG +#select -assert-count 8 t:FDRE +#select -assert-count 8 t:RAM16X1D +#select -assert-none t:BUFG t:FDRE t:RAM16X1D %% t:* %D design -reset -- cgit v1.2.3 From 266993408a2b926ffefcf536feb92b36b11e398e Mon Sep 17 00:00:00 2001 From: Diego H Date: Fri, 13 Dec 2019 15:43:24 -0600 Subject: Refactoring memory attribute matching based on IEEE 1364.1 and Tool specific --- passes/memory/memory_bram.cc | 77 +++++++++++++++++++++++++++++++++++++++ techlibs/xilinx/xc7_xcu_brams.txt | 19 ++++++++++ 2 files changed, 96 insertions(+) diff --git a/passes/memory/memory_bram.cc b/passes/memory/memory_bram.cc index aa8f94149..35cd0647a 100644 --- a/passes/memory/memory_bram.cc +++ b/passes/memory/memory_bram.cc @@ -327,6 +327,20 @@ struct rules_t continue; } + if (GetSize(tokens) >= 2 && tokens[0] == "attribute") { + for (int idx=1; idx<= GetSize(tokens)-1; idx++) { + size_t val = tokens[idx].find_first_of("!="); + if (val != std::string::npos) { + if (val == 0) { + data.attr_unmatch[RTLIL::escape_id(tokens[idx].substr(val+1))]; + } + else { + data.attr_match[RTLIL::escape_id(tokens[idx].substr(0, val))] = tokens[idx].substr(val+1); + } + } + } + continue; + } syntax_error(); } } @@ -813,6 +827,27 @@ grow_read_ports:; return false; } + if (!match.attr_match.empty()) { + for (auto iter: match.attr_match) { + auto it = cell->attributes.find(iter.first); + + if (iter.second.empty()) { + log(" Rule for bram type %s is rejected: requirement 'attribute %s=\"%s\"' not met.\n", + log_id(match.name), iter.first.c_str(), iter.second.decode_string().c_str()); + return false; + } + + if (it != cell->attributes.end()) { + if (it->second == iter.second) + continue; + log(" Rule for bram type %s is rejected: requirement 'attribute %s=\"%s\"' not met.\n", + log_id(match.name), iter.first.c_str(), iter.second.decode_string().c_str()); + return false; + } + continue; + } + } + if (mode == 1) return true; } @@ -997,6 +1032,7 @@ void handle_cell(Cell *cell, const rules_t &rules) log("Processing %s.%s:\n", log_id(cell->module), log_id(cell)); bool cell_init = !SigSpec(cell->getParam("\\INIT")).is_fully_undef(); + int access = 0; dict match_properties; match_properties["words"] = cell->getParam("\\SIZE").as_int(); @@ -1100,6 +1136,42 @@ void handle_cell(Cell *cell, const rules_t &rules) goto next_match_rule; } + for (auto iter: match.attr_unmatch) { + auto it = cell->attributes.find(iter.first); + + if (it != cell->attributes.end()) { + log(" Rule for bram type %s is rejected: requirement 'attribute %s' is met.\n", + log_id(match.name), iter.first.c_str()); + goto next_match_rule; + } + continue; + } + + if (!match.attr_match.empty()) { + for (auto iter: match.attr_match) { + int len=std::tuple_size::value; + auto it = cell->attributes.find(iter.first); + + if (iter.second.empty()) { + log(" Rule for bram type %s is rejected: requirement 'attribute %s=\"%s\"' not met.\n", + log_id(match.name), iter.first.c_str(), iter.second.decode_string().c_str()); + continue; + } + + if (it != cell->attributes.end()) { + if (it->second == iter.second) + continue; + log(" Rule for bram type %s is rejected: requirement 'attribute %s=\"%s\"' not met.\n", + log_id(match.name), iter.first.c_str(), iter.second.decode_string().c_str()); + } + access ++; + if (access == len) { + access = 0; + goto next_match_rule; + } + } + } + log(" Rule #%d for bram type %s (variant %d) accepted.\n", i+1, log_id(bram.name), bram.variant); if (or_next_if_better || !best_rule_cache.empty()) @@ -1225,6 +1297,11 @@ struct MemoryBramPass : public Pass { log(" dcells ....... number of cells in 'data-direction'\n"); log(" cells ........ total number of cells (acells*dcells*dups)\n"); log("\n"); + log("A match containing the condition 'attribute' followed by a name and optional\n"); + log("value requires that the memory contains the given attribute name and value\n"); + log("(if specified) or that the attribute is not present (prepending a '!')\n"); + log("or the value is empty (if value is not specified\n)."); + log("\n"); log("The interface for the created bram instances is derived from the bram\n"); log("description. Use 'techmap' to convert the created bram instances into\n"); log("instances of the actual bram cells of your target architecture.\n"); diff --git a/techlibs/xilinx/xc7_xcu_brams.txt b/techlibs/xilinx/xc7_xcu_brams.txt index b7c893ff7..a52dd9352 100644 --- a/techlibs/xilinx/xc7_xcu_brams.txt +++ b/techlibs/xilinx/xc7_xcu_brams.txt @@ -81,6 +81,7 @@ match $__XILINX_RAMB36_SDP min efficiency 5 shuffle_enable B make_transp + attribute !ram_style !logic_block or_next_if_better endmatch @@ -89,6 +90,14 @@ match $__XILINX_RAMB18_SDP min efficiency 5 shuffle_enable B make_transp + attribute !ram_style !logic_block + or_next_if_better +endmatch + +match $__XILINX_RAMB18_SDP + shuffle_enable B + make_transp + attribute ram_block=1 ram_style=block or_next_if_better endmatch @@ -97,6 +106,7 @@ match $__XILINX_RAMB36_TDP min efficiency 5 shuffle_enable B make_transp + attribute !ram_style !logic_block or_next_if_better endmatch @@ -105,4 +115,13 @@ match $__XILINX_RAMB18_TDP min efficiency 5 shuffle_enable B make_transp + attribute !ram_style !logic_block + or_next_if_better +endmatch + +match $__XILINX_RAMB18_TDP + min efficiency 5 + shuffle_enable B + make_transp + attribute ram_block=1 ram_style=block endmatch -- cgit v1.2.3 From c0339bbbf16cee8121417f69305c7601122ff70c Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 13 Dec 2019 16:21:09 -0800 Subject: Name inputs/outputs of aiger 'i%d' and 'o%d' --- frontends/aiger/aigerparse.cc | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc index 8ff690464..65a9e30ae 100644 --- a/frontends/aiger/aigerparse.cc +++ b/frontends/aiger/aigerparse.cc @@ -610,11 +610,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); } @@ -664,23 +665,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 -- cgit v1.2.3 From e709fd3da1c7e3ae36ee43a997fbd413909c764e Mon Sep 17 00:00:00 2001 From: Alyssa Milburn Date: Sun, 15 Dec 2019 20:40:38 +0100 Subject: Fix opt_expr.eqneq.cmpzero debug print --- passes/opt/opt_expr.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/opt/opt_expr.cc b/passes/opt/opt_expr.cc index 6cf66fb95..4a2f170b8 100644 --- a/passes/opt/opt_expr.cc +++ b/passes/opt/opt_expr.cc @@ -978,7 +978,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons { cover_list("opt.opt_expr.eqneq.cmpzero", "$eq", "$ne", cell->type.str()); log_debug("Replacing %s cell `%s' in module `%s' with %s.\n", log_id(cell->type), log_id(cell), - log_id(module), "$eq" ? "$logic_not" : "$reduce_bool"); + log_id(module), cell->type == ID($eq) ? "$logic_not" : "$reduce_bool"); cell->type = cell->type == ID($eq) ? ID($logic_not) : ID($reduce_bool); if (assign_map(cell->getPort(ID::A)).is_fully_zero()) { cell->setPort(ID::A, cell->getPort(ID::B)); -- cgit v1.2.3 From b35559fc335181d7c8f8046fa17bf05550c21ba7 Mon Sep 17 00:00:00 2001 From: Diego H Date: Sun, 15 Dec 2019 23:33:09 -0600 Subject: Merging attribute rules into a single match block; Adding tests --- passes/memory/memory_bram.cc | 148 +- techlibs/xilinx/xc7_xcu_brams.txt | 30 +- .../common/memory_attributes/attributes_test.v | 88 + .../common/memory_attributes/attributes_test.ys | 47 + tests/arch/common/memory_attributes/log | 3238 ++++++++++++++++++++ 5 files changed, 3465 insertions(+), 86 deletions(-) create mode 100644 tests/arch/common/memory_attributes/attributes_test.v create mode 100644 tests/arch/common/memory_attributes/attributes_test.ys create mode 100644 tests/arch/common/memory_attributes/log diff --git a/passes/memory/memory_bram.cc b/passes/memory/memory_bram.cc index 35cd0647a..10b48e321 100644 --- a/passes/memory/memory_bram.cc +++ b/passes/memory/memory_bram.cc @@ -134,6 +134,9 @@ struct rules_t dict min_limits, max_limits; bool or_next_if_better, make_transp, make_outreg; char shuffle_enable; + dict>> attr_match; + pair attr_val; + dict attr_unmatch; }; dict> brams; @@ -328,19 +331,31 @@ struct rules_t } if (GetSize(tokens) >= 2 && tokens[0] == "attribute") { - for (int idx=1; idx<= GetSize(tokens)-1; idx++) { - size_t val = tokens[idx].find_first_of("!="); - if (val != std::string::npos) { - if (val == 0) { - data.attr_unmatch[RTLIL::escape_id(tokens[idx].substr(val+1))]; - } - else { - data.attr_match[RTLIL::escape_id(tokens[idx].substr(0, val))] = tokens[idx].substr(val+1); + if (GetSize(tokens) <=2) { + size_t notval = tokens[1].find("!"); + size_t val = tokens[1].find("="); + + if (notval != std::string::npos) { + if (val != std::string::npos) + data.attr_unmatch[RTLIL::escape_id(tokens[1].substr(1, val-1))] = tokens[1].substr(val+1); + else + data.attr_unmatch[RTLIL::escape_id(tokens[1].substr(notval+1))] = RTLIL::Const('1'); + } + continue; + } + + else if (GetSize(tokens) > 2) { + for (int idx=1; idx<= GetSize(tokens)-1; idx++) { + size_t val = tokens[idx].find("="); + if (val != std::string::npos) { + data.attr_val = make_pair(RTLIL::escape_id(tokens[idx].substr(0, val)), tokens[idx].substr(val+1)); + data.attr_match[RTLIL::escape_id(tokens[0])].push_back(data.attr_val); } } + continue; } - continue; } + syntax_error(); } } @@ -738,7 +753,7 @@ grow_read_ports:; if (match.make_transp && wr_ports <= 1) { pi.make_transp = true; if (pi.clocks != 0) { - if (wr_ports == 1 && wr_clkdom != clkdom) { + if (wr_ports == 1 && wr_clkdom != clkdom) { log(" Bram port %c%d.%d cannot have soft transparency logic added as read and write clock domains differ.\n", pi.group + 'A', pi.index + 1, pi.dupidx + 1); goto skip_bram_rport; } @@ -806,6 +821,27 @@ grow_read_ports:; log(" Updated properties: dups=%d waste=%d efficiency=%d\n", match_properties["dups"], match_properties["waste"], match_properties["efficiency"]); + for (auto& iter: match.attr_match) { + for (auto& iter: iter.second) { + auto it = cell->attributes.find(iter.first); + + if (iter.second.empty()) { + log(" Rule for bram type %s is rejected: requirement 'attribute %s=\"%s\"' not met.\n", + log_id(match.name), log_id(iter.first), iter.second.decode_string().c_str()); + return false; + } + + if (it != cell->attributes.end()) { + if (it->second == iter.second) + continue; + log(" Rule for bram type %s is rejected: requirement 'attribute %s=\"%s\"' not met.\n", + log_id(match.name), log_id(iter.first), iter.second.decode_string().c_str()); + return false; + } + return true; + } + } + for (auto it : match.min_limits) { if (!match_properties.count(it.first)) log_error("Unknown property '%s' in match rule for bram type %s.\n", @@ -827,27 +863,6 @@ grow_read_ports:; return false; } - if (!match.attr_match.empty()) { - for (auto iter: match.attr_match) { - auto it = cell->attributes.find(iter.first); - - if (iter.second.empty()) { - log(" Rule for bram type %s is rejected: requirement 'attribute %s=\"%s\"' not met.\n", - log_id(match.name), iter.first.c_str(), iter.second.decode_string().c_str()); - return false; - } - - if (it != cell->attributes.end()) { - if (it->second == iter.second) - continue; - log(" Rule for bram type %s is rejected: requirement 'attribute %s=\"%s\"' not met.\n", - log_id(match.name), iter.first.c_str(), iter.second.decode_string().c_str()); - return false; - } - continue; - } - } - if (mode == 1) return true; } @@ -1032,7 +1047,6 @@ void handle_cell(Cell *cell, const rules_t &rules) log("Processing %s.%s:\n", log_id(cell->module), log_id(cell)); bool cell_init = !SigSpec(cell->getParam("\\INIT")).is_fully_undef(); - int access = 0; dict match_properties; match_properties["words"] = cell->getParam("\\SIZE").as_int(); @@ -1110,6 +1124,39 @@ void handle_cell(Cell *cell, const rules_t &rules) goto next_match_rule; } + for (auto& iter: match.attr_match) { + for (auto& iter: iter.second) { + auto it = cell->attributes.find(iter.first); + + if (it != cell->attributes.end()) { + if (!it->second.empty()) { + if (it->second.decode_string().length() == 1) + it->second = it->second.as_string().back(); + if (!it->second.decode_string().compare(iter.second.decode_string())) + goto attribute_matched; + else + log(" Rule for bram type %s is rejected: requirement 'attribute %s=\"%s\"' not met.\n", + log_id(match.name), log_id(iter.first), iter.second.decode_string().c_str()); + } + } + } + } + + for (auto& iter: match.attr_unmatch) { + auto it = cell->attributes.find(iter.first); + + if (it != cell->attributes.end()) { + if (!it->second.empty()) { + if (it->second.decode_string().length() == 1) + it->second = it->second.as_string().back(); + if (!it->second.decode_string().compare(iter.second.decode_string())) + goto next_match_rule; + log(" Rule for bram type %s is rejected: requirement 'attribute %s=\"%s\"' not met.\n", + log_id(match.name), log_id(iter.first), iter.second.decode_string().c_str()); + } + } + } + for (auto it : match.min_limits) { if (it.first == "waste" || it.first == "dups" || it.first == "acells" || it.first == "dcells" || it.first == "cells") continue; @@ -1136,42 +1183,7 @@ void handle_cell(Cell *cell, const rules_t &rules) goto next_match_rule; } - for (auto iter: match.attr_unmatch) { - auto it = cell->attributes.find(iter.first); - - if (it != cell->attributes.end()) { - log(" Rule for bram type %s is rejected: requirement 'attribute %s' is met.\n", - log_id(match.name), iter.first.c_str()); - goto next_match_rule; - } - continue; - } - - if (!match.attr_match.empty()) { - for (auto iter: match.attr_match) { - int len=std::tuple_size::value; - auto it = cell->attributes.find(iter.first); - - if (iter.second.empty()) { - log(" Rule for bram type %s is rejected: requirement 'attribute %s=\"%s\"' not met.\n", - log_id(match.name), iter.first.c_str(), iter.second.decode_string().c_str()); - continue; - } - - if (it != cell->attributes.end()) { - if (it->second == iter.second) - continue; - log(" Rule for bram type %s is rejected: requirement 'attribute %s=\"%s\"' not met.\n", - log_id(match.name), iter.first.c_str(), iter.second.decode_string().c_str()); - } - access ++; - if (access == len) { - access = 0; - goto next_match_rule; - } - } - } - + attribute_matched: log(" Rule #%d for bram type %s (variant %d) accepted.\n", i+1, log_id(bram.name), bram.variant); if (or_next_if_better || !best_rule_cache.empty()) diff --git a/techlibs/xilinx/xc7_xcu_brams.txt b/techlibs/xilinx/xc7_xcu_brams.txt index a52dd9352..2d94ac4a8 100644 --- a/techlibs/xilinx/xc7_xcu_brams.txt +++ b/techlibs/xilinx/xc7_xcu_brams.txt @@ -77,51 +77,45 @@ endbram # https://www.xilinx.com/support/documentation/user_guides/ug473_7Series_Memory_Resources.pdf match $__XILINX_RAMB36_SDP + attribute ram_style=block ram_block=1 + attribute !ram_style=distributed + attribute !logic_block min bits 1024 min efficiency 5 shuffle_enable B make_transp - attribute !ram_style !logic_block or_next_if_better endmatch match $__XILINX_RAMB18_SDP + attribute ram_style=block ram_block=1 + attribute !ram_style=distributed + attribute !logic_block min bits 1024 min efficiency 5 shuffle_enable B make_transp - attribute !ram_style !logic_block - or_next_if_better -endmatch - -match $__XILINX_RAMB18_SDP - shuffle_enable B - make_transp - attribute ram_block=1 ram_style=block or_next_if_better endmatch match $__XILINX_RAMB36_TDP + attribute ram_style=block ram_block=1 + attribute !ram_style=distributed + attribute !logic_block min bits 1024 min efficiency 5 shuffle_enable B make_transp - attribute !ram_style !logic_block or_next_if_better endmatch match $__XILINX_RAMB18_TDP + attribute ram_style=block ram_block=1 + attribute !ram_style=distributed + attribute !logic_block min bits 1024 min efficiency 5 shuffle_enable B make_transp - attribute !ram_style !logic_block - or_next_if_better endmatch -match $__XILINX_RAMB18_TDP - min efficiency 5 - shuffle_enable B - make_transp - attribute ram_block=1 ram_style=block -endmatch diff --git a/tests/arch/common/memory_attributes/attributes_test.v b/tests/arch/common/memory_attributes/attributes_test.v new file mode 100644 index 000000000..275800dd0 --- /dev/null +++ b/tests/arch/common/memory_attributes/attributes_test.v @@ -0,0 +1,88 @@ +`default_nettype none +module block_ram #(parameter DATA_WIDTH=4, ADDRESS_WIDTH=10) + (input wire write_enable, clk, + input wire [DATA_WIDTH-1:0] data_in, + input wire [ADDRESS_WIDTH-1:0] address_in, + output wire [DATA_WIDTH-1:0] data_out); + + localparam WORD = (DATA_WIDTH-1); + localparam DEPTH = (2**ADDRESS_WIDTH-1); + + reg [WORD:0] data_out_r; + reg [WORD:0] memory [0:DEPTH]; + + always @(posedge clk) begin + if (write_enable) + memory[address_in] <= data_in; + data_out_r <= memory[address_in]; + end + + assign data_out = data_out_r; +endmodule // block_ram + +`default_nettype none +module distributed_ram #(parameter DATA_WIDTH=8, ADDRESS_WIDTH=4) + (input wire write_enable, clk, + input wire [DATA_WIDTH-1:0] data_in, + input wire [ADDRESS_WIDTH-1:0] address_in, + output wire [DATA_WIDTH-1:0] data_out); + + localparam WORD = (DATA_WIDTH-1); + localparam DEPTH = (2**ADDRESS_WIDTH-1); + + reg [WORD:0] data_out_r; + reg [WORD:0] memory [0:DEPTH]; + + always @(posedge clk) begin + if (write_enable) + memory[address_in] <= data_in; + data_out_r <= memory[address_in]; + end + + assign data_out = data_out_r; +endmodule // distributed_ram + +`default_nettype none +module distributed_ram_manual #(parameter DATA_WIDTH=8, ADDRESS_WIDTH=4) + (input wire write_enable, clk, + input wire [DATA_WIDTH-1:0] data_in, + input wire [ADDRESS_WIDTH-1:0] address_in, + output wire [DATA_WIDTH-1:0] data_out); + + localparam WORD = (DATA_WIDTH-1); + localparam DEPTH = (2**ADDRESS_WIDTH-1); + + reg [WORD:0] data_out_r; + (* ram_style = "block" *) reg [WORD:0] memory [0:DEPTH]; + + always @(posedge clk) begin + if (write_enable) + memory[address_in] <= data_in; + data_out_r <= memory[address_in]; + end + + assign data_out = data_out_r; +endmodule // distributed_ram + +`default_nettype none +module distributed_ram_manual_syn #(parameter DATA_WIDTH=8, ADDRESS_WIDTH=4) + (input wire write_enable, clk, + input wire [DATA_WIDTH-1:0] data_in, + input wire [ADDRESS_WIDTH-1:0] address_in, + output wire [DATA_WIDTH-1:0] data_out); + + localparam WORD = (DATA_WIDTH-1); + localparam DEPTH = (2**ADDRESS_WIDTH-1); + + reg [WORD:0] data_out_r; + (* synthesis, ram_block *) reg [WORD:0] memory [0:DEPTH]; + + always @(posedge clk) begin + if (write_enable) + memory[address_in] <= data_in; + data_out_r <= memory[address_in]; + end + + assign data_out = data_out_r; +endmodule // distributed_ram + diff --git a/tests/arch/common/memory_attributes/attributes_test.ys b/tests/arch/common/memory_attributes/attributes_test.ys new file mode 100644 index 000000000..4e06a35e7 --- /dev/null +++ b/tests/arch/common/memory_attributes/attributes_test.ys @@ -0,0 +1,47 @@ +# Check that blockram memory without parameters is not modified +read_verilog attributes_test.v +hierarchy -top block_ram +synth_xilinx -top block_ram +cd block_ram # Constrain all select calls below inside the top module +select -assert-count 1 t:RAMB18E1 + +# Check that distributed memory without parameters is not modified +design -reset +read_verilog attributes_test.v +hierarchy -top distributed_ram +synth_xilinx -top distributed_ram +cd distributed_ram # Constrain all select calls below inside the top module +select -assert-count 8 t:RAM32X1D + +# Set ram_style distributed to blockram memory; will be implemented as distributed +design -reset +read_verilog attributes_test.v +prep +setattr -mod -set ram_style "distributed" block_ram +synth_xilinx -top block_ram +cd block_ram # Constrain all select calls below inside the top module +select -assert-count 32 t:RAM128X1D + +# Set synthesis, logic_block to blockram memory; will be implemented as distributed +design -reset +read_verilog attributes_test.v +prep +setattr -mod -set logic_block 1 block_ram +synth_xilinx -top block_ram +cd block_ram # Constrain all select calls below inside the top module +select -assert-count 0 t:RAMB18E1 +select -assert-count 32 t:RAM128X1D + +# Set ram_style block to a distributed memory; will be implemented as blockram +design -reset +read_verilog attributes_test.v +synth_xilinx -top distributed_ram_manual +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 attributes_test.v +synth_xilinx -top distributed_ram_manual_syn +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/common/memory_attributes/log b/tests/arch/common/memory_attributes/log new file mode 100644 index 000000000..5d526e661 --- /dev/null +++ b/tests/arch/common/memory_attributes/log @@ -0,0 +1,3238 @@ + + /----------------------------------------------------------------------------\ + | | + | yosys -- Yosys Open SYnthesis Suite | + | | + | Copyright (C) 2012 - 2019 Clifford Wolf | + | | + | 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. | + | | + \----------------------------------------------------------------------------/ + + Yosys 0.9+932 (git sha1 26699340, clang 6.0.0-1ubuntu2 -fPIC -Os) + + +-- Executing script file `attributes_test.ys' -- + +1. Executing Verilog-2005 frontend: attributes_test.v +Parsing Verilog input from `attributes_test.v' to AST representation. +Generating RTLIL representation for module `\block_ram'. +Generating RTLIL representation for module `\distributed_ram'. +Generating RTLIL representation for module `\distributed_ram_manual'. +Generating RTLIL representation for module `\distributed_ram_manual_syn'. +Successfully finished Verilog frontend. + +2. Executing HIERARCHY pass (managing design hierarchy). + +2.1. Analyzing design hierarchy.. +Top module: \block_ram + +2.2. Analyzing design hierarchy.. +Top module: \block_ram +Removing unused module `\distributed_ram_manual_syn'. +Removing unused module `\distributed_ram_manual'. +Removing unused module `\distributed_ram'. +Removed 3 unused modules. + +3. Executing SYNTH_XILINX pass. + +3.1. Executing Verilog-2005 frontend: /opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/cells_sim.v +Parsing Verilog input from `/opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/cells_sim.v' to AST representation. +Generating RTLIL representation for module `\VCC'. +Generating RTLIL representation for module `\GND'. +Generating RTLIL representation for module `\IBUF'. +Generating RTLIL representation for module `\IBUFG'. +Generating RTLIL representation for module `\OBUF'. +Generating RTLIL representation for module `\IOBUF'. +Generating RTLIL representation for module `\OBUFT'. +Generating RTLIL representation for module `\BUFG'. +Generating RTLIL representation for module `\BUFGCTRL'. +Generating RTLIL representation for module `\BUFHCE'. +Generating RTLIL representation for module `\INV'. +Generating RTLIL representation for module `\LUT1'. +Generating RTLIL representation for module `\LUT2'. +Generating RTLIL representation for module `\LUT3'. +Generating RTLIL representation for module `\LUT4'. +Generating RTLIL representation for module `\LUT5'. +Generating RTLIL representation for module `\LUT6'. +Generating RTLIL representation for module `\LUT6_2'. +Generating RTLIL representation for module `\MUXCY'. +Generating RTLIL representation for module `\MUXF7'. +Generating RTLIL representation for module `\MUXF8'. +Generating RTLIL representation for module `\XORCY'. +Generating RTLIL representation for module `\CARRY4'. +Generating RTLIL representation for module `\FDRE'. +Generating RTLIL representation for module `\FDSE'. +Generating RTLIL representation for module `\FDCE'. +Generating RTLIL representation for module `\FDPE'. +Generating RTLIL representation for module `\FDRE_1'. +Generating RTLIL representation for module `\FDSE_1'. +Generating RTLIL representation for module `\FDCE_1'. +Generating RTLIL representation for module `\FDPE_1'. +Generating RTLIL representation for module `\LDCE'. +Generating RTLIL representation for module `\LDPE'. +Generating RTLIL representation for module `\RAM16X1S'. +Generating RTLIL representation for module `\RAM16X1S_1'. +Generating RTLIL representation for module `\RAM32X1S'. +Generating RTLIL representation for module `\RAM32X1S_1'. +Generating RTLIL representation for module `\RAM64X1S'. +Generating RTLIL representation for module `\RAM64X1S_1'. +Generating RTLIL representation for module `\RAM128X1S'. +Generating RTLIL representation for module `\RAM128X1S_1'. +Generating RTLIL representation for module `\RAM256X1S'. +Generating RTLIL representation for module `\RAM512X1S'. +Generating RTLIL representation for module `\RAM16X2S'. +Generating RTLIL representation for module `\RAM32X2S'. +Generating RTLIL representation for module `\RAM64X2S'. +Generating RTLIL representation for module `\RAM16X4S'. +Generating RTLIL representation for module `\RAM32X4S'. +Generating RTLIL representation for module `\RAM16X8S'. +Generating RTLIL representation for module `\RAM32X8S'. +Generating RTLIL representation for module `\RAM16X1D'. +Generating RTLIL representation for module `\RAM16X1D_1'. +Generating RTLIL representation for module `\RAM32X1D'. +Generating RTLIL representation for module `\RAM32X1D_1'. +Generating RTLIL representation for module `\RAM64X1D'. +Generating RTLIL representation for module `\RAM64X1D_1'. +Generating RTLIL representation for module `\RAM128X1D'. +Generating RTLIL representation for module `\RAM256X1D'. +Generating RTLIL representation for module `\RAM32M'. +Generating RTLIL representation for module `\RAM32M16'. +Generating RTLIL representation for module `\RAM64M'. +Generating RTLIL representation for module `\RAM64M8'. +Generating RTLIL representation for module `\ROM16X1'. +Generating RTLIL representation for module `\ROM32X1'. +Generating RTLIL representation for module `\ROM64X1'. +Generating RTLIL representation for module `\ROM128X1'. +Generating RTLIL representation for module `\ROM256X1'. +Generating RTLIL representation for module `\SRL16E'. +Generating RTLIL representation for module `\SRLC16E'. +Generating RTLIL representation for module `\SRLC32E'. +Generating RTLIL representation for module `\MULT18X18'. +Generating RTLIL representation for module `\MULT18X18S'. +Generating RTLIL representation for module `\MULT18X18SIO'. +Generating RTLIL representation for module `\DSP48A'. +Generating RTLIL representation for module `\DSP48A1'. +Generating RTLIL representation for module `\DSP48E1'. +Successfully finished Verilog frontend. + +3.2. Executing Verilog-2005 frontend: /opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/cells_xtra.v +Parsing Verilog input from `/opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/cells_xtra.v' to AST representation. +Generating RTLIL representation for module `\FDCPE'. +Generating RTLIL representation for module `\FDRSE'. +Generating RTLIL representation for module `\LDCPE'. +Generating RTLIL representation for module `\AND2B1L'. +Generating RTLIL representation for module `\OR2L'. +Generating RTLIL representation for module `\MUXF5'. +Generating RTLIL representation for module `\MUXF6'. +Generating RTLIL representation for module `\MUXF9'. +Generating RTLIL representation for module `\CARRY8'. +Generating RTLIL representation for module `\ORCY'. +Generating RTLIL representation for module `\MULT_AND'. +Generating RTLIL representation for module `\SRL16'. +Generating RTLIL representation for module `\SRLC16'. +Generating RTLIL representation for module `\CFGLUT5'. +Generating RTLIL representation for module `\RAMB16_S1'. +Generating RTLIL representation for module `\RAMB16_S2'. +Generating RTLIL representation for module `\RAMB16_S4'. +Generating RTLIL representation for module `\RAMB16_S9'. +Generating RTLIL representation for module `\RAMB16_S18'. +Generating RTLIL representation for module `\RAMB16_S36'. +Generating RTLIL representation for module `\RAMB16_S1_S1'. +Generating RTLIL representation for module `\RAMB16_S1_S2'. +Generating RTLIL representation for module `\RAMB16_S1_S4'. +Generating RTLIL representation for module `\RAMB16_S1_S9'. +Generating RTLIL representation for module `\RAMB16_S1_S18'. +Generating RTLIL representation for module `\RAMB16_S1_S36'. +Generating RTLIL representation for module `\RAMB16_S2_S2'. +Generating RTLIL representation for module `\RAMB16_S2_S4'. +Generating RTLIL representation for module `\RAMB16_S2_S9'. +Generating RTLIL representation for module `\RAMB16_S2_S18'. +Generating RTLIL representation for module `\RAMB16_S2_S36'. +Generating RTLIL representation for module `\RAMB16_S4_S4'. +Generating RTLIL representation for module `\RAMB16_S4_S9'. +Generating RTLIL representation for module `\RAMB16_S4_S18'. +Generating RTLIL representation for module `\RAMB16_S4_S36'. +Generating RTLIL representation for module `\RAMB16_S9_S9'. +Generating RTLIL representation for module `\RAMB16_S9_S18'. +Generating RTLIL representation for module `\RAMB16_S9_S36'. +Generating RTLIL representation for module `\RAMB16_S18_S18'. +Generating RTLIL representation for module `\RAMB16_S18_S36'. +Generating RTLIL representation for module `\RAMB16_S36_S36'. +Generating RTLIL representation for module `\RAMB16BWE_S18'. +Generating RTLIL representation for module `\RAMB16BWE_S36'. +Generating RTLIL representation for module `\RAMB16BWE_S18_S9'. +Generating RTLIL representation for module `\RAMB16BWE_S18_S18'. +Generating RTLIL representation for module `\RAMB16BWE_S36_S9'. +Generating RTLIL representation for module `\RAMB16BWE_S36_S18'. +Generating RTLIL representation for module `\RAMB16BWE_S36_S36'. +Generating RTLIL representation for module `\RAMB16BWER'. +Generating RTLIL representation for module `\RAMB8BWER'. +Generating RTLIL representation for module `\FIFO16'. +Generating RTLIL representation for module `\RAMB16'. +Generating RTLIL representation for module `\RAMB32_S64_ECC'. +Generating RTLIL representation for module `\FIFO18'. +Generating RTLIL representation for module `\FIFO18_36'. +Generating RTLIL representation for module `\FIFO36'. +Generating RTLIL representation for module `\FIFO36_72'. +Generating RTLIL representation for module `\RAMB18'. +Generating RTLIL representation for module `\RAMB36'. +Generating RTLIL representation for module `\RAMB18SDP'. +Generating RTLIL representation for module `\RAMB36SDP'. +Generating RTLIL representation for module `\FIFO18E1'. +Generating RTLIL representation for module `\FIFO36E1'. +Generating RTLIL representation for module `\RAMB18E1'. +Generating RTLIL representation for module `\RAMB36E1'. +Generating RTLIL representation for module `\FIFO18E2'. +Generating RTLIL representation for module `\FIFO36E2'. +Generating RTLIL representation for module `\RAMB18E2'. +Generating RTLIL representation for module `\RAMB36E2'. +Generating RTLIL representation for module `\URAM288'. +Generating RTLIL representation for module `\URAM288_BASE'. +Generating RTLIL representation for module `\DSP48'. +Generating RTLIL representation for module `\DSP48E'. +Generating RTLIL representation for module `\DSP48E2'. +Generating RTLIL representation for module `\IFDDRCPE'. +Generating RTLIL representation for module `\IFDDRRSE'. +Generating RTLIL representation for module `\OFDDRCPE'. +Generating RTLIL representation for module `\OFDDRRSE'. +Generating RTLIL representation for module `\OFDDRTCPE'. +Generating RTLIL representation for module `\OFDDRTRSE'. +Generating RTLIL representation for module `\IDDR2'. +Generating RTLIL representation for module `\ODDR2'. +Generating RTLIL representation for module `\IDDR'. +Generating RTLIL representation for module `\IDDR_2CLK'. +Generating RTLIL representation for module `\ODDR'. +Generating RTLIL representation for module `\IDELAYCTRL'. +Generating RTLIL representation for module `\IDELAY'. +Generating RTLIL representation for module `\ISERDES'. +Generating RTLIL representation for module `\OSERDES'. +Generating RTLIL representation for module `\IODELAY'. +Generating RTLIL representation for module `\ISERDES_NODELAY'. +Generating RTLIL representation for module `\IODELAYE1'. +Generating RTLIL representation for module `\ISERDESE1'. +Generating RTLIL representation for module `\OSERDESE1'. +Generating RTLIL representation for module `\IDELAYE2'. +Generating RTLIL representation for module `\ODELAYE2'. +Generating RTLIL representation for module `\ISERDESE2'. +Generating RTLIL representation for module `\OSERDESE2'. +Generating RTLIL representation for module `\PHASER_IN'. +Generating RTLIL representation for module `\PHASER_IN_PHY'. +Generating RTLIL representation for module `\PHASER_OUT'. +Generating RTLIL representation for module `\PHASER_OUT_PHY'. +Generating RTLIL representation for module `\PHASER_REF'. +Generating RTLIL representation for module `\PHY_CONTROL'. +Generating RTLIL representation for module `\IDDRE1'. +Generating RTLIL representation for module `\ODDRE1'. +Generating RTLIL representation for module `\IDELAYE3'. +Generating RTLIL representation for module `\ODELAYE3'. +Generating RTLIL representation for module `\ISERDESE3'. +Generating RTLIL representation for module `\OSERDESE3'. +Generating RTLIL representation for module `\BITSLICE_CONTROL'. +Generating RTLIL representation for module `\RIU_OR'. +Generating RTLIL representation for module `\RX_BITSLICE'. +Generating RTLIL representation for module `\RXTX_BITSLICE'. +Generating RTLIL representation for module `\TX_BITSLICE'. +Generating RTLIL representation for module `\TX_BITSLICE_TRI'. +Generating RTLIL representation for module `\IODELAY2'. +Generating RTLIL representation for module `\IODRP2'. +Generating RTLIL representation for module `\IODRP2_MCB'. +Generating RTLIL representation for module `\ISERDES2'. +Generating RTLIL representation for module `\OSERDES2'. +Generating RTLIL representation for module `\IBUF_DLY_ADJ'. +Generating RTLIL representation for module `\IBUF_IBUFDISABLE'. +Generating RTLIL representation for module `\IBUF_INTERMDISABLE'. +Generating RTLIL representation for module `\IBUF_ANALOG'. +Generating RTLIL representation for module `\IBUFE3'. +Generating RTLIL representation for module `\IBUFDS'. +Generating RTLIL representation for module `\IBUFDS_DLY_ADJ'. +Generating RTLIL representation for module `\IBUFDS_IBUFDISABLE'. +Generating RTLIL representation for module `\IBUFDS_INTERMDISABLE'. +Generating RTLIL representation for module `\IBUFDS_DIFF_OUT'. +Generating RTLIL representation for module `\IBUFDS_DIFF_OUT_IBUFDISABLE'. +Generating RTLIL representation for module `\IBUFDS_DIFF_OUT_INTERMDISABLE'. +Generating RTLIL representation for module `\IBUFDSE3'. +Generating RTLIL representation for module `\IBUFDS_DPHY'. +Generating RTLIL representation for module `\IBUFGDS'. +Generating RTLIL representation for module `\IBUFGDS_DIFF_OUT'. +Generating RTLIL representation for module `\IOBUF_DCIEN'. +Generating RTLIL representation for module `\IOBUF_INTERMDISABLE'. +Generating RTLIL representation for module `\IOBUFE3'. +Generating RTLIL representation for module `\IOBUFDS'. +Generating RTLIL representation for module `\IOBUFDS_DCIEN'. +Generating RTLIL representation for module `\IOBUFDS_INTERMDISABLE'. +Generating RTLIL representation for module `\IOBUFDS_DIFF_OUT'. +Generating RTLIL representation for module `\IOBUFDS_DIFF_OUT_DCIEN'. +Generating RTLIL representation for module `\IOBUFDS_DIFF_OUT_INTERMDISABLE'. +Generating RTLIL representation for module `\IOBUFDSE3'. +Generating RTLIL representation for module `\OBUFDS'. +Generating RTLIL representation for module `\OBUFDS_DPHY'. +Generating RTLIL representation for module `\OBUFTDS'. +Generating RTLIL representation for module `\KEEPER'. +Generating RTLIL representation for module `\PULLDOWN'. +Generating RTLIL representation for module `\PULLUP'. +Generating RTLIL representation for module `\DCIRESET'. +Generating RTLIL representation for module `\HPIO_VREF'. +Generating RTLIL representation for module `\BUFGCE'. +Generating RTLIL representation for module `\BUFGCE_1'. +Generating RTLIL representation for module `\BUFGMUX'. +Generating RTLIL representation for module `\BUFGMUX_1'. +Generating RTLIL representation for module `\BUFGMUX_CTRL'. +Generating RTLIL representation for module `\BUFGMUX_VIRTEX4'. +Generating RTLIL representation for module `\BUFG_GT'. +Generating RTLIL representation for module `\BUFG_GT_SYNC'. +Generating RTLIL representation for module `\BUFG_PS'. +Generating RTLIL representation for module `\BUFGCE_DIV'. +Generating RTLIL representation for module `\BUFH'. +Generating RTLIL representation for module `\BUFIO2'. +Generating RTLIL representation for module `\BUFIO2_2CLK'. +Generating RTLIL representation for module `\BUFIO2FB'. +Generating RTLIL representation for module `\BUFPLL'. +Generating RTLIL representation for module `\BUFPLL_MCB'. +Generating RTLIL representation for module `\BUFIO'. +Generating RTLIL representation for module `\BUFIODQS'. +Generating RTLIL representation for module `\BUFR'. +Generating RTLIL representation for module `\BUFMR'. +Generating RTLIL representation for module `\BUFMRCE'. +Generating RTLIL representation for module `\DCM'. +Generating RTLIL representation for module `\DCM_SP'. +Generating RTLIL representation for module `\DCM_CLKGEN'. +Generating RTLIL representation for module `\DCM_ADV'. +Generating RTLIL representation for module `\DCM_BASE'. +Generating RTLIL representation for module `\DCM_PS'. +Generating RTLIL representation for module `\PMCD'. +Generating RTLIL representation for module `\PLL_ADV'. +Generating RTLIL representation for module `\PLL_BASE'. +Generating RTLIL representation for module `\MMCM_ADV'. +Generating RTLIL representation for module `\MMCM_BASE'. +Generating RTLIL representation for module `\MMCME2_ADV'. +Generating RTLIL representation for module `\MMCME2_BASE'. +Generating RTLIL representation for module `\PLLE2_ADV'. +Generating RTLIL representation for module `\PLLE2_BASE'. +Generating RTLIL representation for module `\MMCME3_ADV'. +Generating RTLIL representation for module `\MMCME3_BASE'. +Generating RTLIL representation for module `\PLLE3_ADV'. +Generating RTLIL representation for module `\PLLE3_BASE'. +Generating RTLIL representation for module `\MMCME4_ADV'. +Generating RTLIL representation for module `\MMCME4_BASE'. +Generating RTLIL representation for module `\PLLE4_ADV'. +Generating RTLIL representation for module `\PLLE4_BASE'. +Generating RTLIL representation for module `\BUFT'. +Generating RTLIL representation for module `\IN_FIFO'. +Generating RTLIL representation for module `\OUT_FIFO'. +Generating RTLIL representation for module `\HARD_SYNC'. +Generating RTLIL representation for module `\STARTUP_SPARTAN3'. +Generating RTLIL representation for module `\STARTUP_SPARTAN3E'. +Generating RTLIL representation for module `\STARTUP_SPARTAN3A'. +Generating RTLIL representation for module `\STARTUP_SPARTAN6'. +Generating RTLIL representation for module `\STARTUP_VIRTEX4'. +Generating RTLIL representation for module `\STARTUP_VIRTEX5'. +Generating RTLIL representation for module `\STARTUP_VIRTEX6'. +Generating RTLIL representation for module `\STARTUPE2'. +Generating RTLIL representation for module `\STARTUPE3'. +Generating RTLIL representation for module `\CAPTURE_SPARTAN3'. +Generating RTLIL representation for module `\CAPTURE_SPARTAN3A'. +Generating RTLIL representation for module `\CAPTURE_VIRTEX4'. +Generating RTLIL representation for module `\CAPTURE_VIRTEX5'. +Generating RTLIL representation for module `\CAPTURE_VIRTEX6'. +Generating RTLIL representation for module `\CAPTUREE2'. +Generating RTLIL representation for module `\ICAP_SPARTAN3A'. +Generating RTLIL representation for module `\ICAP_SPARTAN6'. +Generating RTLIL representation for module `\ICAP_VIRTEX4'. +Generating RTLIL representation for module `\ICAP_VIRTEX5'. +Generating RTLIL representation for module `\ICAP_VIRTEX6'. +Generating RTLIL representation for module `\ICAPE2'. +Generating RTLIL representation for module `\ICAPE3'. +Generating RTLIL representation for module `\BSCAN_SPARTAN3'. +Generating RTLIL representation for module `\BSCAN_SPARTAN3A'. +Generating RTLIL representation for module `\BSCAN_SPARTAN6'. +Generating RTLIL representation for module `\BSCAN_VIRTEX4'. +Generating RTLIL representation for module `\BSCAN_VIRTEX5'. +Generating RTLIL representation for module `\BSCAN_VIRTEX6'. +Generating RTLIL representation for module `\BSCANE2'. +Generating RTLIL representation for module `\DNA_PORT'. +Generating RTLIL representation for module `\DNA_PORTE2'. +Generating RTLIL representation for module `\FRAME_ECC_VIRTEX4'. +Generating RTLIL representation for module `\FRAME_ECC_VIRTEX5'. +Generating RTLIL representation for module `\FRAME_ECC_VIRTEX6'. +Generating RTLIL representation for module `\FRAME_ECCE2'. +Generating RTLIL representation for module `\FRAME_ECCE3'. +Generating RTLIL representation for module `\USR_ACCESS_VIRTEX4'. +Generating RTLIL representation for module `\USR_ACCESS_VIRTEX5'. +Generating RTLIL representation for module `\USR_ACCESS_VIRTEX6'. +Generating RTLIL representation for module `\USR_ACCESSE2'. +Generating RTLIL representation for module `\POST_CRC_INTERNAL'. +Generating RTLIL representation for module `\SUSPEND_SYNC'. +Generating RTLIL representation for module `\KEY_CLEAR'. +Generating RTLIL representation for module `\MASTER_JTAG'. +Generating RTLIL representation for module `\SPI_ACCESS'. +Generating RTLIL representation for module `\EFUSE_USR'. +Generating RTLIL representation for module `\SYSMON'. +Generating RTLIL representation for module `\XADC'. +Generating RTLIL representation for module `\SYSMONE1'. +Generating RTLIL representation for module `\SYSMONE4'. +Generating RTLIL representation for module `\GTPA1_DUAL'. +Generating RTLIL representation for module `\GT11_CUSTOM'. +Generating RTLIL representation for module `\GT11_DUAL'. +Generating RTLIL representation for module `\GT11CLK'. +Generating RTLIL representation for module `\GT11CLK_MGT'. +Generating RTLIL representation for module `\GTP_DUAL'. +Generating RTLIL representation for module `\GTX_DUAL'. +Generating RTLIL representation for module `\CRC32'. +Generating RTLIL representation for module `\CRC64'. +Generating RTLIL representation for module `\GTHE1_QUAD'. +Generating RTLIL representation for module `\GTXE1'. +Generating RTLIL representation for module `\IBUFDS_GTXE1'. +Generating RTLIL representation for module `\IBUFDS_GTHE1'. +Generating RTLIL representation for module `\GTHE2_CHANNEL'. +Generating RTLIL representation for module `\GTHE2_COMMON'. +Generating RTLIL representation for module `\GTPE2_CHANNEL'. +Generating RTLIL representation for module `\GTPE2_COMMON'. +Generating RTLIL representation for module `\GTXE2_CHANNEL'. +Generating RTLIL representation for module `\GTXE2_COMMON'. +Generating RTLIL representation for module `\IBUFDS_GTE2'. +Generating RTLIL representation for module `\GTHE3_CHANNEL'. +Generating RTLIL representation for module `\GTHE3_COMMON'. +Generating RTLIL representation for module `\GTHE4_CHANNEL'. +Generating RTLIL representation for module `\GTHE4_COMMON'. +Generating RTLIL representation for module `\GTYE3_CHANNEL'. +Generating RTLIL representation for module `\GTYE3_COMMON'. +Generating RTLIL representation for module `\GTYE4_CHANNEL'. +Generating RTLIL representation for module `\GTYE4_COMMON'. +Generating RTLIL representation for module `\IBUFDS_GTE3'. +Generating RTLIL representation for module `\IBUFDS_GTE4'. +Generating RTLIL representation for module `\OBUFDS_GTE3'. +Generating RTLIL representation for module `\OBUFDS_GTE3_ADV'. +Generating RTLIL representation for module `\OBUFDS_GTE4'. +Generating RTLIL representation for module `\OBUFDS_GTE4_ADV'. +Generating RTLIL representation for module `\PCIE_A1'. +Generating RTLIL representation for module `\PCIE_EP'. +Generating RTLIL representation for module `\PCIE_2_0'. +Generating RTLIL representation for module `\PCIE_2_1'. +Generating RTLIL representation for module `\PCIE_3_0'. +Generating RTLIL representation for module `\PCIE_3_1'. +Generating RTLIL representation for module `\PCIE40E4'. +Generating RTLIL representation for module `\EMAC'. +Generating RTLIL representation for module `\TEMAC'. +Generating RTLIL representation for module `\TEMAC_SINGLE'. +Generating RTLIL representation for module `\CMAC'. +Generating RTLIL representation for module `\CMACE4'. +Generating RTLIL representation for module `\PPC405_ADV'. +Generating RTLIL representation for module `\PPC440'. +Generating RTLIL representation for module `\MCB'. +Generating RTLIL representation for module `\PS7'. +Generating RTLIL representation for module `\PS8'. +Generating RTLIL representation for module `\ILKN'. +Generating RTLIL representation for module `\ILKNE4'. +Successfully finished Verilog frontend. + +3.3. Executing HIERARCHY pass (managing design hierarchy). + +3.3.1. Analyzing design hierarchy.. +Top module: \block_ram + +3.3.2. Analyzing design hierarchy.. +Top module: \block_ram +Removed 0 unused modules. + +3.4. Executing PROC pass (convert processes to netlists). + +3.4.1. Executing PROC_CLEAN pass (remove empty switches from decision trees). +Cleaned up 0 empty switches. + +3.4.2. Executing PROC_RMDEAD pass (remove dead branches from decision trees). +Removed a total of 0 dead cases. + +3.4.3. Executing PROC_PRUNE pass (remove redundant assignments in processes). +Removed 0 redundant assignments. +Promoted 1 assignment to connection. + +3.4.4. Executing PROC_INIT pass (extract init attributes). + +3.4.5. Executing PROC_ARST pass (detect async resets in processes). + +3.4.6. Executing PROC_MUX pass (convert decision trees to multiplexers). +Creating decoders for process `\block_ram.$proc$attributes_test.v:14$2'. + 1/3: $0$memwr$\memory$attributes_test.v:16$1_EN[3:0]$5 + 2/3: $0$memwr$\memory$attributes_test.v:16$1_DATA[3:0]$4 + 3/3: $0$memwr$\memory$attributes_test.v:16$1_ADDR[9:0]$3 + +3.4.7. Executing PROC_DLATCH pass (convert process syncs to latches). + +3.4.8. Executing PROC_DFF pass (convert process syncs to FFs). +Creating register for signal `\block_ram.\data_out_r' using process `\block_ram.$proc$attributes_test.v:14$2'. + created $dff cell `$procdff$48' with positive edge clock. +Creating register for signal `\block_ram.$memwr$\memory$attributes_test.v:16$1_ADDR' using process `\block_ram.$proc$attributes_test.v:14$2'. + created $dff cell `$procdff$49' with positive edge clock. +Creating register for signal `\block_ram.$memwr$\memory$attributes_test.v:16$1_DATA' using process `\block_ram.$proc$attributes_test.v:14$2'. + created $dff cell `$procdff$50' with positive edge clock. +Creating register for signal `\block_ram.$memwr$\memory$attributes_test.v:16$1_EN' using process `\block_ram.$proc$attributes_test.v:14$2'. + created $dff cell `$procdff$51' with positive edge clock. + +3.4.9. Executing PROC_CLEAN pass (remove empty switches from decision trees). +Found and cleaned up 1 empty switch in `\block_ram.$proc$attributes_test.v:14$2'. +Removing empty process `block_ram.$proc$attributes_test.v:14$2'. +Cleaned up 1 empty switch. + +3.5. Executing TRIBUF pass. + +3.6. Executing DEMINOUT pass (demote inout ports to input or output). + +3.7. Executing OPT_EXPR pass (perform const folding). +Optimizing module block_ram. + +3.8. Executing OPT_CLEAN pass (remove unused cells and wires). +Finding unused cells or wires in module \block_ram.. +Removed 0 unused cells and 7 unused wires. + + +3.9. Executing CHECK pass (checking for obvious problems). +checking module block_ram.. +found and reported 0 problems. + +3.10. Executing OPT pass (performing simple optimizations). + +3.10.1. Executing OPT_EXPR pass (perform const folding). +Optimizing module block_ram. + +3.10.2. Executing OPT_MERGE pass (detect identical cells). +Finding identical cells in module `\block_ram'. +Removed a total of 0 cells. + +3.10.3. Executing OPT_MUXTREE pass (detect dead branches in mux trees). +Running muxtree optimizer on module \block_ram.. + Creating internal representation of mux trees. + Evaluating internal representation of mux trees. + Analyzing evaluation results. +Removed 0 multiplexer ports. + + +3.10.4. Executing OPT_REDUCE pass (consolidate $*mux and $reduce_* inputs). + Optimizing cells in module \block_ram. + Consolidated identical input bits for $mux cell $procmux$42: + Old ports: A=4'0000, B=4'1111, Y=$0$memwr$\memory$attributes_test.v:16$1_EN[3:0]$5 + New ports: A=1'0, B=1'1, Y=$0$memwr$\memory$attributes_test.v:16$1_EN[3:0]$5 [0] + New connections: $0$memwr$\memory$attributes_test.v:16$1_EN[3:0]$5 [3:1] = { $0$memwr$\memory$attributes_test.v:16$1_EN[3:0]$5 [0] $0$memwr$\memory$attributes_test.v:16$1_EN[3:0]$5 [0] $0$memwr$\memory$attributes_test.v:16$1_EN[3:0]$5 [0] } + Optimizing cells in module \block_ram. +Performed a total of 1 changes. + +3.10.5. Executing OPT_MERGE pass (detect identical cells). +Finding identical cells in module `\block_ram'. +Removed a total of 0 cells. + +3.10.6. Executing OPT_RMDFF pass (remove dff with constant values). + +3.10.7. Executing OPT_CLEAN pass (remove unused cells and wires). +Finding unused cells or wires in module \block_ram.. + +3.10.8. Executing OPT_EXPR pass (perform const folding). +Optimizing module block_ram. + +3.10.9. Rerunning OPT passes. (Maybe there is more to do..) + +3.10.10. Executing OPT_MUXTREE pass (detect dead branches in mux trees). +Running muxtree optimizer on module \block_ram.. + Creating internal representation of mux trees. + Evaluating internal representation of mux trees. + Analyzing evaluation results. +Removed 0 multiplexer ports. + + +3.10.11. Executing OPT_REDUCE pass (consolidate $*mux and $reduce_* inputs). + Optimizing cells in module \block_ram. +Performed a total of 0 changes. + +3.10.12. Executing OPT_MERGE pass (detect identical cells). +Finding identical cells in module `\block_ram'. +Removed a total of 0 cells. + +3.10.13. Executing OPT_RMDFF pass (remove dff with constant values). + +3.10.14. Executing OPT_CLEAN pass (remove unused cells and wires). +Finding unused cells or wires in module \block_ram.. + +3.10.15. Executing OPT_EXPR pass (perform const folding). +Optimizing module block_ram. + +3.10.16. Finished OPT passes. (There is nothing left to do.) + +3.11. Executing WREDUCE pass (reducing word size of cells). +Removed cell block_ram.$procmux$44 ($mux). +Removed cell block_ram.$procmux$46 ($mux). +Removed top 3 bits (of 4) from FF cell block_ram.$procdff$51 ($dff). + +3.12. Executing PEEPOPT pass (run peephole optimizers). + +3.13. Executing OPT_CLEAN pass (remove unused cells and wires). +Finding unused cells or wires in module \block_ram.. +Removed 0 unused cells and 2 unused wires. + + +3.14. Executing PMUX2SHIFTX pass. + +3.15. Executing TECHMAP pass (map to technology primitives). + +3.15.1. Executing Verilog-2005 frontend: /opt/eda/fpga/FOSS/memattr/yosys_release/share/cmp2lut.v +Parsing Verilog input from `/opt/eda/fpga/FOSS/memattr/yosys_release/share/cmp2lut.v' to AST representation. +Generating RTLIL representation for module `\_90_lut_cmp_'. +Successfully finished Verilog frontend. + +3.15.2. Continuing TECHMAP pass. +No more expansions possible. + +3.16. Executing MEMORY_DFF pass (merging $dff cells to $memrd and $memwr). +Checking cell `$memwr$\memory$attributes_test.v:16$7' in module `\block_ram': merged $dff to cell. +Checking cell `$memrd$\memory$attributes_test.v:17$6' in module `\block_ram': merged data $dff to cell. + +3.17. Executing TECHMAP pass (map to technology primitives). + +3.17.1. Executing Verilog-2005 frontend: /opt/eda/fpga/FOSS/memattr/yosys_release/share/mul2dsp.v +Parsing Verilog input from `/opt/eda/fpga/FOSS/memattr/yosys_release/share/mul2dsp.v' to AST representation. +Generating RTLIL representation for module `\_80_mul'. +Generating RTLIL representation for module `\_90_soft_mul'. +Successfully finished Verilog frontend. + +3.17.2. Executing Verilog-2005 frontend: /opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/xc7_dsp_map.v +Parsing Verilog input from `/opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/xc7_dsp_map.v' to AST representation. +Generating RTLIL representation for module `\$__MUL25X18'. +Successfully finished Verilog frontend. + +3.17.3. Continuing TECHMAP pass. +No more expansions possible. + +3.18. Executing OPT_EXPR pass (perform const folding). + +3.19. Executing WREDUCE pass (reducing word size of cells). + +3.20. Executing XILINX_DSP pass (pack resources into DSPs). + +3.21. Executing ALUMACC pass (create $alu and $macc cells). +Extracting $alu and $macc cells in module block_ram: + created 0 $alu and 0 $macc cells. + +3.22. Executing SHARE pass (SAT-based resource sharing). + +3.23. Executing OPT pass (performing simple optimizations). + +3.23.1. Executing OPT_EXPR pass (perform const folding). +Optimizing module block_ram. + +3.23.2. Executing OPT_MERGE pass (detect identical cells). +Finding identical cells in module `\block_ram'. +Removed a total of 0 cells. + +3.23.3. Executing OPT_MUXTREE pass (detect dead branches in mux trees). +Running muxtree optimizer on module \block_ram.. + Creating internal representation of mux trees. + Evaluating internal representation of mux trees. + Analyzing evaluation results. +Removed 0 multiplexer ports. + + +3.23.4. Executing OPT_REDUCE pass (consolidate $*mux and $reduce_* inputs). + Optimizing cells in module \block_ram. +Performed a total of 0 changes. + +3.23.5. Executing OPT_MERGE pass (detect identical cells). +Finding identical cells in module `\block_ram'. +Removed a total of 0 cells. + +3.23.6. Executing OPT_RMDFF pass (remove dff with constant values). + +3.23.7. Executing OPT_CLEAN pass (remove unused cells and wires). +Finding unused cells or wires in module \block_ram.. +Removed 4 unused cells and 5 unused wires. + + +3.23.8. Executing OPT_EXPR pass (perform const folding). +Optimizing module block_ram. + +3.23.9. Rerunning OPT passes. (Maybe there is more to do..) + +3.23.10. Executing OPT_MUXTREE pass (detect dead branches in mux trees). +Running muxtree optimizer on module \block_ram.. + Creating internal representation of mux trees. + Evaluating internal representation of mux trees. + Analyzing evaluation results. +Removed 0 multiplexer ports. + + +3.23.11. Executing OPT_REDUCE pass (consolidate $*mux and $reduce_* inputs). + Optimizing cells in module \block_ram. +Performed a total of 0 changes. + +3.23.12. Executing OPT_MERGE pass (detect identical cells). +Finding identical cells in module `\block_ram'. +Removed a total of 0 cells. + +3.23.13. Executing OPT_RMDFF pass (remove dff with constant values). + +3.23.14. Executing OPT_CLEAN pass (remove unused cells and wires). +Finding unused cells or wires in module \block_ram.. + +3.23.15. Executing OPT_EXPR pass (perform const folding). +Optimizing module block_ram. + +3.23.16. Finished OPT passes. (There is nothing left to do.) + +3.24. Executing FSM pass (extract and optimize FSM). + +3.24.1. Executing FSM_DETECT pass (finding FSMs in design). + +3.24.2. Executing FSM_EXTRACT pass (extracting FSM from design). + +3.24.3. Executing FSM_OPT pass (simple optimizations of FSMs). + +3.24.4. Executing OPT_CLEAN pass (remove unused cells and wires). +Finding unused cells or wires in module \block_ram.. + +3.24.5. Executing FSM_OPT pass (simple optimizations of FSMs). + +3.24.6. Executing FSM_RECODE pass (re-assigning FSM state encoding). + +3.24.7. Executing FSM_INFO pass (dumping all available information on FSM cells). + +3.24.8. Executing FSM_MAP pass (mapping FSMs to basic logic). + +3.25. Executing OPT pass (performing simple optimizations). + +3.25.1. Executing OPT_EXPR pass (perform const folding). +Optimizing module block_ram. + +3.25.2. Executing OPT_MERGE pass (detect identical cells). +Finding identical cells in module `\block_ram'. +Removed a total of 0 cells. + +3.25.3. Executing OPT_RMDFF pass (remove dff with constant values). + +3.25.4. Executing OPT_CLEAN pass (remove unused cells and wires). +Finding unused cells or wires in module \block_ram.. + +3.25.5. Finished fast OPT passes. + +3.26. Executing MEMORY pass. + +3.26.1. Executing OPT_MEM pass (optimize memories). +Performed a total of 0 transformations. + +3.26.2. Executing MEMORY_DFF pass (merging $dff cells to $memrd and $memwr). + +3.26.3. Executing OPT_CLEAN pass (remove unused cells and wires). +Finding unused cells or wires in module \block_ram.. + +3.26.4. Executing MEMORY_SHARE pass (consolidating $memrd/$memwr cells). + +3.26.5. Executing OPT_CLEAN pass (remove unused cells and wires). +Finding unused cells or wires in module \block_ram.. + +3.26.6. Executing MEMORY_COLLECT pass (generating $mem cells). +Collecting $memrd, $memwr and $meminit for memory `\memory' in module `\block_ram': + $memwr$\memory$attributes_test.v:16$7 ($memwr) + $memrd$\memory$attributes_test.v:17$6 ($memrd) + +3.27. Executing OPT_CLEAN pass (remove unused cells and wires). +Finding unused cells or wires in module \block_ram.. + +3.28. Executing MEMORY_BRAM pass (mapping $mem cells to block memories). +Processing block_ram.memory: + Properties: ports=2 bits=4096 rports=1 wports=1 dbits=4 abits=10 words=1024 + Checking rule #1 for bram type $__XILINX_RAMB36_SDP (variant 1): + Bram geometry: abits=9 dbits=72 wports=0 rports=0 + Estimated number of duplicates for more read ports: dups=1 + Metrics for $__XILINX_RAMB36_SDP: awaste=0 dwaste=68 bwaste=34816 waste=34816 efficiency=5 + Rule #1 for bram type $__XILINX_RAMB36_SDP (variant 1) accepted. + Mapping to bram type $__XILINX_RAMB36_SDP (variant 1): + Shuffle bit order to accommodate enable buckets of size 9.. + Results of bit order shuffling: 0 1 2 3 -1 -1 -1 -1 -1 + Write port #0 is in clock domain \clk. + Mapped to bram port B1. + Read port #0 is in clock domain \clk. + Mapped to bram port A1.1. + Updated properties: dups=1 waste=34816 efficiency=5 + Storing for later selection. + Checking rule #2 for bram type $__XILINX_RAMB18_SDP (variant 1): + Bram geometry: abits=9 dbits=36 wports=0 rports=0 + Estimated number of duplicates for more read ports: dups=1 + Metrics for $__XILINX_RAMB18_SDP: awaste=0 dwaste=32 bwaste=16384 waste=16384 efficiency=11 + Rule #2 for bram type $__XILINX_RAMB18_SDP (variant 1) accepted. + Mapping to bram type $__XILINX_RAMB18_SDP (variant 1): + Shuffle bit order to accommodate enable buckets of size 9.. + Results of bit order shuffling: 0 1 2 3 -1 -1 -1 -1 -1 + Write port #0 is in clock domain \clk. + Mapped to bram port B1. + Read port #0 is in clock domain \clk. + Mapped to bram port A1.1. + Updated properties: dups=1 waste=16384 efficiency=11 + Storing for later selection. + Checking rule #3 for bram type $__XILINX_RAMB36_TDP (variant 1): + Bram geometry: abits=10 dbits=36 wports=0 rports=0 + Estimated number of duplicates for more read ports: dups=1 + Metrics for $__XILINX_RAMB36_TDP: awaste=0 dwaste=32 bwaste=32768 waste=32768 efficiency=11 + Rule #3 for bram type $__XILINX_RAMB36_TDP (variant 1) accepted. + Mapping to bram type $__XILINX_RAMB36_TDP (variant 1): + Shuffle bit order to accommodate enable buckets of size 9.. + Results of bit order shuffling: 0 1 2 3 -1 -1 -1 -1 -1 + Write port #0 is in clock domain \clk. + Mapped to bram port B1. + Read port #0 is in clock domain \clk. + Mapped to bram port A1.1. + Updated properties: dups=1 waste=32768 efficiency=11 + Storing for later selection. + Checking rule #3 for bram type $__XILINX_RAMB36_TDP (variant 2): + Bram geometry: abits=11 dbits=18 wports=0 rports=0 + Estimated number of duplicates for more read ports: dups=1 + Metrics for $__XILINX_RAMB36_TDP: awaste=1024 dwaste=14 bwaste=32768 waste=32768 efficiency=11 + Rule #3 for bram type $__XILINX_RAMB36_TDP (variant 2) accepted. + Mapping to bram type $__XILINX_RAMB36_TDP (variant 2): + Shuffle bit order to accommodate enable buckets of size 9.. + Results of bit order shuffling: 0 1 2 3 -1 -1 -1 -1 -1 + Write port #0 is in clock domain \clk. + Mapped to bram port B1. + Read port #0 is in clock domain \clk. + Mapped to bram port A1.1. + Updated properties: dups=1 waste=32768 efficiency=11 + Storing for later selection. + Checking rule #3 for bram type $__XILINX_RAMB36_TDP (variant 3): + Bram geometry: abits=12 dbits=9 wports=0 rports=0 + Estimated number of duplicates for more read ports: dups=1 + Metrics for $__XILINX_RAMB36_TDP: awaste=3072 dwaste=5 bwaste=32768 waste=32768 efficiency=11 + Rule #3 for bram type $__XILINX_RAMB36_TDP (variant 3) accepted. + Mapping to bram type $__XILINX_RAMB36_TDP (variant 3): + Shuffle bit order to accommodate enable buckets of size 9.. + Results of bit order shuffling: 0 1 2 3 -1 -1 -1 -1 -1 + Write port #0 is in clock domain \clk. + Mapped to bram port B1. + Read port #0 is in clock domain \clk. + Mapped to bram port A1.1. + Updated properties: dups=1 waste=32768 efficiency=11 + Storing for later selection. + Checking rule #3 for bram type $__XILINX_RAMB36_TDP (variant 4): + Bram geometry: abits=13 dbits=4 wports=0 rports=0 + Estimated number of duplicates for more read ports: dups=1 + Metrics for $__XILINX_RAMB36_TDP: awaste=7168 dwaste=0 bwaste=28672 waste=28672 efficiency=12 + Rule #3 for bram type $__XILINX_RAMB36_TDP (variant 4) accepted. + Mapping to bram type $__XILINX_RAMB36_TDP (variant 4): + Shuffle bit order to accommodate enable buckets of size 4.. + Results of bit order shuffling: 0 1 2 3 + Write port #0 is in clock domain \clk. + Mapped to bram port B1. + Read port #0 is in clock domain \clk. + Mapped to bram port A1.1. + Updated properties: dups=1 waste=28672 efficiency=12 + Storing for later selection. + Checking rule #3 for bram type $__XILINX_RAMB36_TDP (variant 5): + Bram geometry: abits=14 dbits=2 wports=0 rports=0 + Estimated number of duplicates for more read ports: dups=1 + Metrics for $__XILINX_RAMB36_TDP: awaste=15360 dwaste=0 bwaste=30720 waste=30720 efficiency=6 + Rule #3 for bram type $__XILINX_RAMB36_TDP (variant 5) accepted. + Mapping to bram type $__XILINX_RAMB36_TDP (variant 5): + Shuffle bit order to accommodate enable buckets of size 2.. + Results of bit order shuffling: 0 1 2 3 + Write port #0 is in clock domain \clk. + Mapped to bram port B1. + Read port #0 is in clock domain \clk. + Mapped to bram port A1.1. + Updated properties: dups=1 waste=30720 efficiency=6 + Storing for later selection. + Checking rule #3 for bram type $__XILINX_RAMB36_TDP (variant 6): + Bram geometry: abits=15 dbits=1 wports=0 rports=0 + Estimated number of duplicates for more read ports: dups=1 + Metrics for $__XILINX_RAMB36_TDP: awaste=31744 dwaste=0 bwaste=31744 waste=31744 efficiency=3 + Rule #3 for bram type $__XILINX_RAMB36_TDP (variant 6) rejected: requirement 'min efficiency 5' not met. + Checking rule #4 for bram type $__XILINX_RAMB18_TDP (variant 1): + Bram geometry: abits=10 dbits=18 wports=0 rports=0 + Estimated number of duplicates for more read ports: dups=1 + Metrics for $__XILINX_RAMB18_TDP: awaste=0 dwaste=14 bwaste=14336 waste=14336 efficiency=22 + Rule #4 for bram type $__XILINX_RAMB18_TDP (variant 1) accepted. + Mapping to bram type $__XILINX_RAMB18_TDP (variant 1): + Shuffle bit order to accommodate enable buckets of size 9.. + Results of bit order shuffling: 0 1 2 3 -1 -1 -1 -1 -1 + Write port #0 is in clock domain \clk. + Mapped to bram port B1. + Read port #0 is in clock domain \clk. + Mapped to bram port A1.1. + Updated properties: dups=1 waste=14336 efficiency=22 + Storing for later selection. + Checking rule #4 for bram type $__XILINX_RAMB18_TDP (variant 2): + Bram geometry: abits=11 dbits=9 wports=0 rports=0 + Estimated number of duplicates for more read ports: dups=1 + Metrics for $__XILINX_RAMB18_TDP: awaste=1024 dwaste=5 bwaste=14336 waste=14336 efficiency=22 + Rule #4 for bram type $__XILINX_RAMB18_TDP (variant 2) accepted. + Mapping to bram type $__XILINX_RAMB18_TDP (variant 2): + Shuffle bit order to accommodate enable buckets of size 9.. + Results of bit order shuffling: 0 1 2 3 -1 -1 -1 -1 -1 + Write port #0 is in clock domain \clk. + Mapped to bram port B1. + Read port #0 is in clock domain \clk. + Mapped to bram port A1.1. + Updated properties: dups=1 waste=14336 efficiency=22 + Storing for later selection. + Checking rule #4 for bram type $__XILINX_RAMB18_TDP (variant 3): + Bram geometry: abits=12 dbits=4 wports=0 rports=0 + Estimated number of duplicates for more read ports: dups=1 + Metrics for $__XILINX_RAMB18_TDP: awaste=3072 dwaste=0 bwaste=12288 waste=12288 efficiency=25 + Rule #4 for bram type $__XILINX_RAMB18_TDP (variant 3) accepted. + Mapping to bram type $__XILINX_RAMB18_TDP (variant 3): + Shuffle bit order to accommodate enable buckets of size 4.. + Results of bit order shuffling: 0 1 2 3 + Write port #0 is in clock domain \clk. + Mapped to bram port B1. + Read port #0 is in clock domain \clk. + Mapped to bram port A1.1. + Updated properties: dups=1 waste=12288 efficiency=25 + Storing for later selection. + Checking rule #4 for bram type $__XILINX_RAMB18_TDP (variant 4): + Bram geometry: abits=13 dbits=2 wports=0 rports=0 + Estimated number of duplicates for more read ports: dups=1 + Metrics for $__XILINX_RAMB18_TDP: awaste=7168 dwaste=0 bwaste=14336 waste=14336 efficiency=12 + Rule #4 for bram type $__XILINX_RAMB18_TDP (variant 4) accepted. + Mapping to bram type $__XILINX_RAMB18_TDP (variant 4): + Shuffle bit order to accommodate enable buckets of size 2.. + Results of bit order shuffling: 0 1 2 3 + Write port #0 is in clock domain \clk. + Mapped to bram port B1. + Read port #0 is in clock domain \clk. + Mapped to bram port A1.1. + Updated properties: dups=1 waste=14336 efficiency=12 + Storing for later selection. + Checking rule #4 for bram type $__XILINX_RAMB18_TDP (variant 5): + Bram geometry: abits=14 dbits=1 wports=0 rports=0 + Estimated number of duplicates for more read ports: dups=1 + Metrics for $__XILINX_RAMB18_TDP: awaste=15360 dwaste=0 bwaste=15360 waste=15360 efficiency=6 + Rule #4 for bram type $__XILINX_RAMB18_TDP (variant 5) accepted. + Mapping to bram type $__XILINX_RAMB18_TDP (variant 5): + Write port #0 is in clock domain \clk. + Mapped to bram port B1. + Read port #0 is in clock domain \clk. + Mapped to bram port A1.1. + Updated properties: dups=1 waste=15360 efficiency=6 + Storing for later selection. + Selecting best of 12 rules: + Efficiency for rule 4.5: efficiency=6, cells=4, acells=1 + Efficiency for rule 4.4: efficiency=12, cells=2, acells=1 + Efficiency for rule 4.3: efficiency=25, cells=1, acells=1 + Efficiency for rule 4.2: efficiency=22, cells=1, acells=1 + Efficiency for rule 4.1: efficiency=22, cells=1, acells=1 + Efficiency for rule 3.5: efficiency=6, cells=2, acells=1 + Efficiency for rule 3.4: efficiency=12, cells=1, acells=1 + Efficiency for rule 3.3: efficiency=11, cells=1, acells=1 + Efficiency for rule 3.2: efficiency=11, cells=1, acells=1 + Efficiency for rule 3.1: efficiency=11, cells=1, acells=1 + Efficiency for rule 2.1: efficiency=11, cells=2, acells=2 + Efficiency for rule 1.1: efficiency=5, cells=2, acells=2 + Selected rule 4.3 with efficiency 25. + Mapping to bram type $__XILINX_RAMB18_TDP (variant 3): + Shuffle bit order to accommodate enable buckets of size 4.. + Results of bit order shuffling: 0 1 2 3 + Write port #0 is in clock domain \clk. + Mapped to bram port B1. + Read port #0 is in clock domain \clk. + Mapped to bram port A1.1. + Creating $__XILINX_RAMB18_TDP cell at grid position <0 0 0>: memory.0.0.0 + +3.29. Executing TECHMAP pass (map to technology primitives). + +3.29.1. Executing Verilog-2005 frontend: /opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/xc7_brams_map.v +Parsing Verilog input from `/opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/xc7_brams_map.v' to AST representation. +Generating RTLIL representation for module `\$__XILINX_RAMB36_SDP'. +Generating RTLIL representation for module `\$__XILINX_RAMB18_SDP'. +Generating RTLIL representation for module `\$__XILINX_RAMB36_TDP'. +Generating RTLIL representation for module `\$__XILINX_RAMB18_TDP'. +Successfully finished Verilog frontend. + +3.29.2. Continuing TECHMAP pass. +Using template $paramod\$__XILINX_RAMB18_TDP\CFG_ABITS=12\CFG_DBITS=4\CFG_ENABLE_B=1\CLKPOL2=1\CLKPOL3=1 for cells of type $__XILINX_RAMB18_TDP. +No more expansions possible. + + +3.30. Executing MEMORY_BRAM pass (mapping $mem cells to block memories). + +3.31. Executing TECHMAP pass (map to technology primitives). + +3.31.1. Executing Verilog-2005 frontend: /opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/lutrams_map.v +Parsing Verilog input from `/opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/lutrams_map.v' to AST representation. +Generating RTLIL representation for module `\$__XILINX_RAM32X1D'. +Generating RTLIL representation for module `\$__XILINX_RAM64X1D'. +Generating RTLIL representation for module `\$__XILINX_RAM128X1D'. +Successfully finished Verilog frontend. + +3.31.2. Continuing TECHMAP pass. +No more expansions possible. + +3.32. Executing OPT pass (performing simple optimizations). + +3.32.1. Executing OPT_EXPR pass (perform const folding). +Optimizing module block_ram. + + +3.32.2. Executing OPT_MERGE pass (detect identical cells). +Finding identical cells in module `\block_ram'. +Removed a total of 0 cells. + +3.32.3. Executing OPT_RMDFF pass (remove dff with constant values). + +3.32.4. Executing OPT_CLEAN pass (remove unused cells and wires). +Finding unused cells or wires in module \block_ram.. +Removed 0 unused cells and 17 unused wires. + + +3.32.5. Finished fast OPT passes. + +3.33. Executing MEMORY_MAP pass (converting $mem cells to logic and flip-flops). + +3.34. Executing DFFSR2DFF pass (mapping DFFSR cells to simpler FFs). + +3.35. Executing DFF2DFFE pass (transform $dff to $dffe where applicable). +Transforming FF to FF+Enable cells in module block_ram: + +3.36. Executing OPT pass (performing simple optimizations). + +3.36.1. Executing OPT_EXPR pass (perform const folding). +Optimizing module block_ram. + +3.36.2. Executing OPT_MERGE pass (detect identical cells). +Finding identical cells in module `\block_ram'. +Removed a total of 0 cells. + +3.36.3. Executing OPT_MUXTREE pass (detect dead branches in mux trees). +Running muxtree optimizer on module \block_ram.. + Creating internal representation of mux trees. + No muxes found in this module. +Removed 0 multiplexer ports. + +3.36.4. Executing OPT_REDUCE pass (consolidate $*mux and $reduce_* inputs). + Optimizing cells in module \block_ram. +Performed a total of 0 changes. + +3.36.5. Executing OPT_MERGE pass (detect identical cells). +Finding identical cells in module `\block_ram'. +Removed a total of 0 cells. + +3.36.6. Executing OPT_SHARE pass. + +3.36.7. Executing OPT_RMDFF pass (remove dff with constant values). + +3.36.8. Executing OPT_CLEAN pass (remove unused cells and wires). +Finding unused cells or wires in module \block_ram.. + +3.36.9. Executing OPT_EXPR pass (perform const folding). +Optimizing module block_ram. + +3.36.10. Finished OPT passes. (There is nothing left to do.) + +3.37. Executing XILINX_SRL pass (Xilinx shift register extraction). + +3.38. Executing TECHMAP pass (map to technology primitives). + +3.38.1. Executing Verilog-2005 frontend: /opt/eda/fpga/FOSS/memattr/yosys_release/share/techmap.v +Parsing Verilog input from `/opt/eda/fpga/FOSS/memattr/yosys_release/share/techmap.v' to AST representation. +Generating RTLIL representation for module `\_90_simplemap_bool_ops'. +Generating RTLIL representation for module `\_90_simplemap_reduce_ops'. +Generating RTLIL representation for module `\_90_simplemap_logic_ops'. +Generating RTLIL representation for module `\_90_simplemap_compare_ops'. +Generating RTLIL representation for module `\_90_simplemap_various'. +Generating RTLIL representation for module `\_90_simplemap_registers'. +Generating RTLIL representation for module `\_90_shift_ops_shr_shl_sshl_sshr'. +Generating RTLIL representation for module `\_90_shift_shiftx'. +Generating RTLIL representation for module `\_90_fa'. +Generating RTLIL representation for module `\_90_lcu'. +Generating RTLIL representation for module `\_90_alu'. +Generating RTLIL representation for module `\_90_macc'. +Generating RTLIL representation for module `\_90_alumacc'. +Generating RTLIL representation for module `\$__div_mod_u'. +Generating RTLIL representation for module `\$__div_mod'. +Generating RTLIL representation for module `\_90_div'. +Generating RTLIL representation for module `\_90_mod'. +Generating RTLIL representation for module `\_90_pow'. +Generating RTLIL representation for module `\_90_pmux'. +Generating RTLIL representation for module `\_90_lut'. +Successfully finished Verilog frontend. + +3.38.2. Executing Verilog-2005 frontend: /opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/arith_map.v +Parsing Verilog input from `/opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/arith_map.v' to AST representation. +Generating RTLIL representation for module `\_80_xilinx_lcu'. +Generating RTLIL representation for module `\_80_xilinx_alu'. +Successfully finished Verilog frontend. + +3.38.3. Continuing TECHMAP pass. +No more expansions possible. + +3.39. Executing OPT pass (performing simple optimizations). + +3.39.1. Executing OPT_EXPR pass (perform const folding). +Optimizing module block_ram. + +3.39.2. Executing OPT_MERGE pass (detect identical cells). +Finding identical cells in module `\block_ram'. +Removed a total of 0 cells. + +3.39.3. Executing OPT_RMDFF pass (remove dff with constant values). + +3.39.4. Executing OPT_CLEAN pass (remove unused cells and wires). +Finding unused cells or wires in module \block_ram.. + +3.39.5. Finished fast OPT passes. + +3.40. Executing TECHMAP pass (map to technology primitives). + +3.40.1. Executing Verilog-2005 frontend: /opt/eda/fpga/FOSS/memattr/yosys_release/share/techmap.v +Parsing Verilog input from `/opt/eda/fpga/FOSS/memattr/yosys_release/share/techmap.v' to AST representation. +Generating RTLIL representation for module `\_90_simplemap_bool_ops'. +Generating RTLIL representation for module `\_90_simplemap_reduce_ops'. +Generating RTLIL representation for module `\_90_simplemap_logic_ops'. +Generating RTLIL representation for module `\_90_simplemap_compare_ops'. +Generating RTLIL representation for module `\_90_simplemap_various'. +Generating RTLIL representation for module `\_90_simplemap_registers'. +Generating RTLIL representation for module `\_90_shift_ops_shr_shl_sshl_sshr'. +Generating RTLIL representation for module `\_90_shift_shiftx'. +Generating RTLIL representation for module `\_90_fa'. +Generating RTLIL representation for module `\_90_lcu'. +Generating RTLIL representation for module `\_90_alu'. +Generating RTLIL representation for module `\_90_macc'. +Generating RTLIL representation for module `\_90_alumacc'. +Generating RTLIL representation for module `\$__div_mod_u'. +Generating RTLIL representation for module `\$__div_mod'. +Generating RTLIL representation for module `\_90_div'. +Generating RTLIL representation for module `\_90_mod'. +Generating RTLIL representation for module `\_90_pow'. +Generating RTLIL representation for module `\_90_pmux'. +Generating RTLIL representation for module `\_90_lut'. +Successfully finished Verilog frontend. + +3.40.2. Executing Verilog-2005 frontend: /opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/cells_map.v +Parsing Verilog input from `/opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/cells_map.v' to AST representation. +Generating RTLIL representation for module `\_90_dff_nn0_to_np0'. +Generating RTLIL representation for module `\_90_dff_pn0_to_pp0'. +Generating RTLIL representation for module `\_90_dff_nn1_to_np1'. +Generating RTLIL representation for module `\_90_dff_pn1_to_pp1'. +Generating RTLIL representation for module `\$__SHREG_'. +Generating RTLIL representation for module `\$__XILINX_SHREG_'. +Generating RTLIL representation for module `\$__XILINX_MUXF78'. +Generating RTLIL representation for module `\$__XILINX_TINOUTPAD'. +Generating RTLIL representation for module `\$__XILINX_TOUTPAD'. +Successfully finished Verilog frontend. + +3.40.3. Continuing TECHMAP pass. +No more expansions possible. + +3.41. Executing OPT_EXPR pass (perform const folding). +Optimizing module block_ram. + +3.42. Executing ABC pass (technology mapping using ABC). + +3.42.1. Extracting gate netlist of module `\block_ram' to `/input.blif'.. +Extracted 0 gates and 0 wires to a netlist network with 0 inputs and 0 outputs. +Don't call ABC as there is nothing to map. +Removing temp directory. + +3.43. Executing XILINX_SRL pass (Xilinx shift register extraction). + +3.44. Executing TECHMAP pass (map to technology primitives). + +3.44.1. Executing Verilog-2005 frontend: /opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/lut_map.v +Parsing Verilog input from `/opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/lut_map.v' to AST representation. +Generating RTLIL representation for module `\$lut'. +Successfully finished Verilog frontend. + +3.44.2. Executing Verilog-2005 frontend: /opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/cells_map.v +Parsing Verilog input from `/opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/cells_map.v' to AST representation. +Generating RTLIL representation for module `\_90_dff_nn0_to_np0'. +Generating RTLIL representation for module `\_90_dff_pn0_to_pp0'. +Generating RTLIL representation for module `\_90_dff_nn1_to_np1'. +Generating RTLIL representation for module `\_90_dff_pn1_to_pp1'. +Generating RTLIL representation for module `\$__SHREG_'. +Generating RTLIL representation for module `\$__XILINX_SHREG_'. +Generating RTLIL representation for module `\$__XILINX_MUXF78'. +Generating RTLIL representation for module `\$__XILINX_TINOUTPAD'. +Generating RTLIL representation for module `\$__XILINX_TOUTPAD'. +Successfully finished Verilog frontend. + +3.44.3. Executing Verilog-2005 frontend: /opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/xc7_ff_map.v +Parsing Verilog input from `/opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/xc7_ff_map.v' to AST representation. +Generating RTLIL representation for module `\$_DFF_N_'. +Generating RTLIL representation for module `\$_DFF_P_'. +Generating RTLIL representation for module `\$_DFFE_NP_'. +Generating RTLIL representation for module `\$_DFFE_PP_'. +Generating RTLIL representation for module `\$_DFF_NN0_'. +Generating RTLIL representation for module `\$_DFF_NP0_'. +Generating RTLIL representation for module `\$_DFF_PN0_'. +Generating RTLIL representation for module `\$_DFF_PP0_'. +Generating RTLIL representation for module `\$_DFF_NN1_'. +Generating RTLIL representation for module `\$_DFF_NP1_'. +Generating RTLIL representation for module `\$_DFF_PN1_'. +Generating RTLIL representation for module `\$_DFF_PP1_'. +Generating RTLIL representation for module `\$_DLATCH_N_'. +Generating RTLIL representation for module `\$_DLATCH_P_'. +Successfully finished Verilog frontend. + +3.44.4. Continuing TECHMAP pass. +No more expansions possible. + +3.45. Executing CLKBUFMAP pass (inserting global clock buffers). +Inserting BUFG on block_ram.clk[0]. + +3.46. Executing HIERARCHY pass (managing design hierarchy). + +3.46.1. Analyzing design hierarchy.. +Top module: \block_ram + +3.46.2. Analyzing design hierarchy.. +Top module: \block_ram +Removed 0 unused modules. + +3.47. Printing statistics. + +=== block_ram === + + Number of wires: 12 + Number of wire bits: 62 + Number of public wires: 6 + Number of public wire bits: 24 + Number of memories: 0 + Number of memory bits: 0 + Number of processes: 0 + Number of cells: 2 + BUFG 1 + RAMB18E1 1 + + Estimated number of LCs: 0 + +3.48. Executing CHECK pass (checking for obvious problems). +checking module block_ram.. +found and reported 0 problems. + +4. Executing Verilog-2005 frontend: attributes_test.v +Parsing Verilog input from `attributes_test.v' to AST representation. +Generating RTLIL representation for module `\block_ram'. +Generating RTLIL representation for module `\distributed_ram'. +Generating RTLIL representation for module `\distributed_ram_manual'. +Generating RTLIL representation for module `\distributed_ram_manual_syn'. +Successfully finished Verilog frontend. + +5. Executing HIERARCHY pass (managing design hierarchy). + +5.1. Analyzing design hierarchy.. +Top module: \distributed_ram + +5.2. Analyzing design hierarchy.. +Top module: \distributed_ram +Removing unused module `\distributed_ram_manual_syn'. +Removing unused module `\distributed_ram_manual'. +Removing unused module `\block_ram'. +Removed 3 unused modules. + +6. Executing SYNTH_XILINX pass. + +6.1. Executing Verilog-2005 frontend: /opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/cells_sim.v +Parsing Verilog input from `/opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/cells_sim.v' to AST representation. +Generating RTLIL representation for module `\VCC'. +Generating RTLIL representation for module `\GND'. +Generating RTLIL representation for module `\IBUF'. +Generating RTLIL representation for module `\IBUFG'. +Generating RTLIL representation for module `\OBUF'. +Generating RTLIL representation for module `\IOBUF'. +Generating RTLIL representation for module `\OBUFT'. +Generating RTLIL representation for module `\BUFG'. +Generating RTLIL representation for module `\BUFGCTRL'. +Generating RTLIL representation for module `\BUFHCE'. +Generating RTLIL representation for module `\INV'. +Generating RTLIL representation for module `\LUT1'. +Generating RTLIL representation for module `\LUT2'. +Generating RTLIL representation for module `\LUT3'. +Generating RTLIL representation for module `\LUT4'. +Generating RTLIL representation for module `\LUT5'. +Generating RTLIL representation for module `\LUT6'. +Generating RTLIL representation for module `\LUT6_2'. +Generating RTLIL representation for module `\MUXCY'. +Generating RTLIL representation for module `\MUXF7'. +Generating RTLIL representation for module `\MUXF8'. +Generating RTLIL representation for module `\XORCY'. +Generating RTLIL representation for module `\CARRY4'. +Generating RTLIL representation for module `\FDRE'. +Generating RTLIL representation for module `\FDSE'. +Generating RTLIL representation for module `\FDCE'. +Generating RTLIL representation for module `\FDPE'. +Generating RTLIL representation for module `\FDRE_1'. +Generating RTLIL representation for module `\FDSE_1'. +Generating RTLIL representation for module `\FDCE_1'. +Generating RTLIL representation for module `\FDPE_1'. +Generating RTLIL representation for module `\LDCE'. +Generating RTLIL representation for module `\LDPE'. +Generating RTLIL representation for module `\RAM16X1S'. +Generating RTLIL representation for module `\RAM16X1S_1'. +Generating RTLIL representation for module `\RAM32X1S'. +Generating RTLIL representation for module `\RAM32X1S_1'. +Generating RTLIL representation for module `\RAM64X1S'. +Generating RTLIL representation for module `\RAM64X1S_1'. +Generating RTLIL representation for module `\RAM128X1S'. +Generating RTLIL representation for module `\RAM128X1S_1'. +Generating RTLIL representation for module `\RAM256X1S'. +Generating RTLIL representation for module `\RAM512X1S'. +Generating RTLIL representation for module `\RAM16X2S'. +Generating RTLIL representation for module `\RAM32X2S'. +Generating RTLIL representation for module `\RAM64X2S'. +Generating RTLIL representation for module `\RAM16X4S'. +Generating RTLIL representation for module `\RAM32X4S'. +Generating RTLIL representation for module `\RAM16X8S'. +Generating RTLIL representation for module `\RAM32X8S'. +Generating RTLIL representation for module `\RAM16X1D'. +Generating RTLIL representation for module `\RAM16X1D_1'. +Generating RTLIL representation for module `\RAM32X1D'. +Generating RTLIL representation for module `\RAM32X1D_1'. +Generating RTLIL representation for module `\RAM64X1D'. +Generating RTLIL representation for module `\RAM64X1D_1'. +Generating RTLIL representation for module `\RAM128X1D'. +Generating RTLIL representation for module `\RAM256X1D'. +Generating RTLIL representation for module `\RAM32M'. +Generating RTLIL representation for module `\RAM32M16'. +Generating RTLIL representation for module `\RAM64M'. +Generating RTLIL representation for module `\RAM64M8'. +Generating RTLIL representation for module `\ROM16X1'. +Generating RTLIL representation for module `\ROM32X1'. +Generating RTLIL representation for module `\ROM64X1'. +Generating RTLIL representation for module `\ROM128X1'. +Generating RTLIL representation for module `\ROM256X1'. +Generating RTLIL representation for module `\SRL16E'. +Generating RTLIL representation for module `\SRLC16E'. +Generating RTLIL representation for module `\SRLC32E'. +Generating RTLIL representation for module `\MULT18X18'. +Generating RTLIL representation for module `\MULT18X18S'. +Generating RTLIL representation for module `\MULT18X18SIO'. +Generating RTLIL representation for module `\DSP48A'. +Generating RTLIL representation for module `\DSP48A1'. +Generating RTLIL representation for module `\DSP48E1'. +Successfully finished Verilog frontend. + +6.2. Executing Verilog-2005 frontend: /opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/cells_xtra.v +Parsing Verilog input from `/opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/cells_xtra.v' to AST representation. +Generating RTLIL representation for module `\FDCPE'. +Generating RTLIL representation for module `\FDRSE'. +Generating RTLIL representation for module `\LDCPE'. +Generating RTLIL representation for module `\AND2B1L'. +Generating RTLIL representation for module `\OR2L'. +Generating RTLIL representation for module `\MUXF5'. +Generating RTLIL representation for module `\MUXF6'. +Generating RTLIL representation for module `\MUXF9'. +Generating RTLIL representation for module `\CARRY8'. +Generating RTLIL representation for module `\ORCY'. +Generating RTLIL representation for module `\MULT_AND'. +Generating RTLIL representation for module `\SRL16'. +Generating RTLIL representation for module `\SRLC16'. +Generating RTLIL representation for module `\CFGLUT5'. +Generating RTLIL representation for module `\RAMB16_S1'. +Generating RTLIL representation for module `\RAMB16_S2'. +Generating RTLIL representation for module `\RAMB16_S4'. +Generating RTLIL representation for module `\RAMB16_S9'. +Generating RTLIL representation for module `\RAMB16_S18'. +Generating RTLIL representation for module `\RAMB16_S36'. +Generating RTLIL representation for module `\RAMB16_S1_S1'. +Generating RTLIL representation for module `\RAMB16_S1_S2'. +Generating RTLIL representation for module `\RAMB16_S1_S4'. +Generating RTLIL representation for module `\RAMB16_S1_S9'. +Generating RTLIL representation for module `\RAMB16_S1_S18'. +Generating RTLIL representation for module `\RAMB16_S1_S36'. +Generating RTLIL representation for module `\RAMB16_S2_S2'. +Generating RTLIL representation for module `\RAMB16_S2_S4'. +Generating RTLIL representation for module `\RAMB16_S2_S9'. +Generating RTLIL representation for module `\RAMB16_S2_S18'. +Generating RTLIL representation for module `\RAMB16_S2_S36'. +Generating RTLIL representation for module `\RAMB16_S4_S4'. +Generating RTLIL representation for module `\RAMB16_S4_S9'. +Generating RTLIL representation for module `\RAMB16_S4_S18'. +Generating RTLIL representation for module `\RAMB16_S4_S36'. +Generating RTLIL representation for module `\RAMB16_S9_S9'. +Generating RTLIL representation for module `\RAMB16_S9_S18'. +Generating RTLIL representation for module `\RAMB16_S9_S36'. +Generating RTLIL representation for module `\RAMB16_S18_S18'. +Generating RTLIL representation for module `\RAMB16_S18_S36'. +Generating RTLIL representation for module `\RAMB16_S36_S36'. +Generating RTLIL representation for module `\RAMB16BWE_S18'. +Generating RTLIL representation for module `\RAMB16BWE_S36'. +Generating RTLIL representation for module `\RAMB16BWE_S18_S9'. +Generating RTLIL representation for module `\RAMB16BWE_S18_S18'. +Generating RTLIL representation for module `\RAMB16BWE_S36_S9'. +Generating RTLIL representation for module `\RAMB16BWE_S36_S18'. +Generating RTLIL representation for module `\RAMB16BWE_S36_S36'. +Generating RTLIL representation for module `\RAMB16BWER'. +Generating RTLIL representation for module `\RAMB8BWER'. +Generating RTLIL representation for module `\FIFO16'. +Generating RTLIL representation for module `\RAMB16'. +Generating RTLIL representation for module `\RAMB32_S64_ECC'. +Generating RTLIL representation for module `\FIFO18'. +Generating RTLIL representation for module `\FIFO18_36'. +Generating RTLIL representation for module `\FIFO36'. +Generating RTLIL representation for module `\FIFO36_72'. +Generating RTLIL representation for module `\RAMB18'. +Generating RTLIL representation for module `\RAMB36'. +Generating RTLIL representation for module `\RAMB18SDP'. +Generating RTLIL representation for module `\RAMB36SDP'. +Generating RTLIL representation for module `\FIFO18E1'. +Generating RTLIL representation for module `\FIFO36E1'. +Generating RTLIL representation for module `\RAMB18E1'. +Generating RTLIL representation for module `\RAMB36E1'. +Generating RTLIL representation for module `\FIFO18E2'. +Generating RTLIL representation for module `\FIFO36E2'. +Generating RTLIL representation for module `\RAMB18E2'. +Generating RTLIL representation for module `\RAMB36E2'. +Generating RTLIL representation for module `\URAM288'. +Generating RTLIL representation for module `\URAM288_BASE'. +Generating RTLIL representation for module `\DSP48'. +Generating RTLIL representation for module `\DSP48E'. +Generating RTLIL representation for module `\DSP48E2'. +Generating RTLIL representation for module `\IFDDRCPE'. +Generating RTLIL representation for module `\IFDDRRSE'. +Generating RTLIL representation for module `\OFDDRCPE'. +Generating RTLIL representation for module `\OFDDRRSE'. +Generating RTLIL representation for module `\OFDDRTCPE'. +Generating RTLIL representation for module `\OFDDRTRSE'. +Generating RTLIL representation for module `\IDDR2'. +Generating RTLIL representation for module `\ODDR2'. +Generating RTLIL representation for module `\IDDR'. +Generating RTLIL representation for module `\IDDR_2CLK'. +Generating RTLIL representation for module `\ODDR'. +Generating RTLIL representation for module `\IDELAYCTRL'. +Generating RTLIL representation for module `\IDELAY'. +Generating RTLIL representation for module `\ISERDES'. +Generating RTLIL representation for module `\OSERDES'. +Generating RTLIL representation for module `\IODELAY'. +Generating RTLIL representation for module `\ISERDES_NODELAY'. +Generating RTLIL representation for module `\IODELAYE1'. +Generating RTLIL representation for module `\ISERDESE1'. +Generating RTLIL representation for module `\OSERDESE1'. +Generating RTLIL representation for module `\IDELAYE2'. +Generating RTLIL representation for module `\ODELAYE2'. +Generating RTLIL representation for module `\ISERDESE2'. +Generating RTLIL representation for module `\OSERDESE2'. +Generating RTLIL representation for module `\PHASER_IN'. +Generating RTLIL representation for module `\PHASER_IN_PHY'. +Generating RTLIL representation for module `\PHASER_OUT'. +Generating RTLIL representation for module `\PHASER_OUT_PHY'. +Generating RTLIL representation for module `\PHASER_REF'. +Generating RTLIL representation for module `\PHY_CONTROL'. +Generating RTLIL representation for module `\IDDRE1'. +Generating RTLIL representation for module `\ODDRE1'. +Generating RTLIL representation for module `\IDELAYE3'. +Generating RTLIL representation for module `\ODELAYE3'. +Generating RTLIL representation for module `\ISERDESE3'. +Generating RTLIL representation for module `\OSERDESE3'. +Generating RTLIL representation for module `\BITSLICE_CONTROL'. +Generating RTLIL representation for module `\RIU_OR'. +Generating RTLIL representation for module `\RX_BITSLICE'. +Generating RTLIL representation for module `\RXTX_BITSLICE'. +Generating RTLIL representation for module `\TX_BITSLICE'. +Generating RTLIL representation for module `\TX_BITSLICE_TRI'. +Generating RTLIL representation for module `\IODELAY2'. +Generating RTLIL representation for module `\IODRP2'. +Generating RTLIL representation for module `\IODRP2_MCB'. +Generating RTLIL representation for module `\ISERDES2'. +Generating RTLIL representation for module `\OSERDES2'. +Generating RTLIL representation for module `\IBUF_DLY_ADJ'. +Generating RTLIL representation for module `\IBUF_IBUFDISABLE'. +Generating RTLIL representation for module `\IBUF_INTERMDISABLE'. +Generating RTLIL representation for module `\IBUF_ANALOG'. +Generating RTLIL representation for module `\IBUFE3'. +Generating RTLIL representation for module `\IBUFDS'. +Generating RTLIL representation for module `\IBUFDS_DLY_ADJ'. +Generating RTLIL representation for module `\IBUFDS_IBUFDISABLE'. +Generating RTLIL representation for module `\IBUFDS_INTERMDISABLE'. +Generating RTLIL representation for module `\IBUFDS_DIFF_OUT'. +Generating RTLIL representation for module `\IBUFDS_DIFF_OUT_IBUFDISABLE'. +Generating RTLIL representation for module `\IBUFDS_DIFF_OUT_INTERMDISABLE'. +Generating RTLIL representation for module `\IBUFDSE3'. +Generating RTLIL representation for module `\IBUFDS_DPHY'. +Generating RTLIL representation for module `\IBUFGDS'. +Generating RTLIL representation for module `\IBUFGDS_DIFF_OUT'. +Generating RTLIL representation for module `\IOBUF_DCIEN'. +Generating RTLIL representation for module `\IOBUF_INTERMDISABLE'. +Generating RTLIL representation for module `\IOBUFE3'. +Generating RTLIL representation for module `\IOBUFDS'. +Generating RTLIL representation for module `\IOBUFDS_DCIEN'. +Generating RTLIL representation for module `\IOBUFDS_INTERMDISABLE'. +Generating RTLIL representation for module `\IOBUFDS_DIFF_OUT'. +Generating RTLIL representation for module `\IOBUFDS_DIFF_OUT_DCIEN'. +Generating RTLIL representation for module `\IOBUFDS_DIFF_OUT_INTERMDISABLE'. +Generating RTLIL representation for module `\IOBUFDSE3'. +Generating RTLIL representation for module `\OBUFDS'. +Generating RTLIL representation for module `\OBUFDS_DPHY'. +Generating RTLIL representation for module `\OBUFTDS'. +Generating RTLIL representation for module `\KEEPER'. +Generating RTLIL representation for module `\PULLDOWN'. +Generating RTLIL representation for module `\PULLUP'. +Generating RTLIL representation for module `\DCIRESET'. +Generating RTLIL representation for module `\HPIO_VREF'. +Generating RTLIL representation for module `\BUFGCE'. +Generating RTLIL representation for module `\BUFGCE_1'. +Generating RTLIL representation for module `\BUFGMUX'. +Generating RTLIL representation for module `\BUFGMUX_1'. +Generating RTLIL representation for module `\BUFGMUX_CTRL'. +Generating RTLIL representation for module `\BUFGMUX_VIRTEX4'. +Generating RTLIL representation for module `\BUFG_GT'. +Generating RTLIL representation for module `\BUFG_GT_SYNC'. +Generating RTLIL representation for module `\BUFG_PS'. +Generating RTLIL representation for module `\BUFGCE_DIV'. +Generating RTLIL representation for module `\BUFH'. +Generating RTLIL representation for module `\BUFIO2'. +Generating RTLIL representation for module `\BUFIO2_2CLK'. +Generating RTLIL representation for module `\BUFIO2FB'. +Generating RTLIL representation for module `\BUFPLL'. +Generating RTLIL representation for module `\BUFPLL_MCB'. +Generating RTLIL representation for module `\BUFIO'. +Generating RTLIL representation for module `\BUFIODQS'. +Generating RTLIL representation for module `\BUFR'. +Generating RTLIL representation for module `\BUFMR'. +Generating RTLIL representation for module `\BUFMRCE'. +Generating RTLIL representation for module `\DCM'. +Generating RTLIL representation for module `\DCM_SP'. +Generating RTLIL representation for module `\DCM_CLKGEN'. +Generating RTLIL representation for module `\DCM_ADV'. +Generating RTLIL representation for module `\DCM_BASE'. +Generating RTLIL representation for module `\DCM_PS'. +Generating RTLIL representation for module `\PMCD'. +Generating RTLIL representation for module `\PLL_ADV'. +Generating RTLIL representation for module `\PLL_BASE'. +Generating RTLIL representation for module `\MMCM_ADV'. +Generating RTLIL representation for module `\MMCM_BASE'. +Generating RTLIL representation for module `\MMCME2_ADV'. +Generating RTLIL representation for module `\MMCME2_BASE'. +Generating RTLIL representation for module `\PLLE2_ADV'. +Generating RTLIL representation for module `\PLLE2_BASE'. +Generating RTLIL representation for module `\MMCME3_ADV'. +Generating RTLIL representation for module `\MMCME3_BASE'. +Generating RTLIL representation for module `\PLLE3_ADV'. +Generating RTLIL representation for module `\PLLE3_BASE'. +Generating RTLIL representation for module `\MMCME4_ADV'. +Generating RTLIL representation for module `\MMCME4_BASE'. +Generating RTLIL representation for module `\PLLE4_ADV'. +Generating RTLIL representation for module `\PLLE4_BASE'. +Generating RTLIL representation for module `\BUFT'. +Generating RTLIL representation for module `\IN_FIFO'. +Generating RTLIL representation for module `\OUT_FIFO'. +Generating RTLIL representation for module `\HARD_SYNC'. +Generating RTLIL representation for module `\STARTUP_SPARTAN3'. +Generating RTLIL representation for module `\STARTUP_SPARTAN3E'. +Generating RTLIL representation for module `\STARTUP_SPARTAN3A'. +Generating RTLIL representation for module `\STARTUP_SPARTAN6'. +Generating RTLIL representation for module `\STARTUP_VIRTEX4'. +Generating RTLIL representation for module `\STARTUP_VIRTEX5'. +Generating RTLIL representation for module `\STARTUP_VIRTEX6'. +Generating RTLIL representation for module `\STARTUPE2'. +Generating RTLIL representation for module `\STARTUPE3'. +Generating RTLIL representation for module `\CAPTURE_SPARTAN3'. +Generating RTLIL representation for module `\CAPTURE_SPARTAN3A'. +Generating RTLIL representation for module `\CAPTURE_VIRTEX4'. +Generating RTLIL representation for module `\CAPTURE_VIRTEX5'. +Generating RTLIL representation for module `\CAPTURE_VIRTEX6'. +Generating RTLIL representation for module `\CAPTUREE2'. +Generating RTLIL representation for module `\ICAP_SPARTAN3A'. +Generating RTLIL representation for module `\ICAP_SPARTAN6'. +Generating RTLIL representation for module `\ICAP_VIRTEX4'. +Generating RTLIL representation for module `\ICAP_VIRTEX5'. +Generating RTLIL representation for module `\ICAP_VIRTEX6'. +Generating RTLIL representation for module `\ICAPE2'. +Generating RTLIL representation for module `\ICAPE3'. +Generating RTLIL representation for module `\BSCAN_SPARTAN3'. +Generating RTLIL representation for module `\BSCAN_SPARTAN3A'. +Generating RTLIL representation for module `\BSCAN_SPARTAN6'. +Generating RTLIL representation for module `\BSCAN_VIRTEX4'. +Generating RTLIL representation for module `\BSCAN_VIRTEX5'. +Generating RTLIL representation for module `\BSCAN_VIRTEX6'. +Generating RTLIL representation for module `\BSCANE2'. +Generating RTLIL representation for module `\DNA_PORT'. +Generating RTLIL representation for module `\DNA_PORTE2'. +Generating RTLIL representation for module `\FRAME_ECC_VIRTEX4'. +Generating RTLIL representation for module `\FRAME_ECC_VIRTEX5'. +Generating RTLIL representation for module `\FRAME_ECC_VIRTEX6'. +Generating RTLIL representation for module `\FRAME_ECCE2'. +Generating RTLIL representation for module `\FRAME_ECCE3'. +Generating RTLIL representation for module `\USR_ACCESS_VIRTEX4'. +Generating RTLIL representation for module `\USR_ACCESS_VIRTEX5'. +Generating RTLIL representation for module `\USR_ACCESS_VIRTEX6'. +Generating RTLIL representation for module `\USR_ACCESSE2'. +Generating RTLIL representation for module `\POST_CRC_INTERNAL'. +Generating RTLIL representation for module `\SUSPEND_SYNC'. +Generating RTLIL representation for module `\KEY_CLEAR'. +Generating RTLIL representation for module `\MASTER_JTAG'. +Generating RTLIL representation for module `\SPI_ACCESS'. +Generating RTLIL representation for module `\EFUSE_USR'. +Generating RTLIL representation for module `\SYSMON'. +Generating RTLIL representation for module `\XADC'. +Generating RTLIL representation for module `\SYSMONE1'. +Generating RTLIL representation for module `\SYSMONE4'. +Generating RTLIL representation for module `\GTPA1_DUAL'. +Generating RTLIL representation for module `\GT11_CUSTOM'. +Generating RTLIL representation for module `\GT11_DUAL'. +Generating RTLIL representation for module `\GT11CLK'. +Generating RTLIL representation for module `\GT11CLK_MGT'. +Generating RTLIL representation for module `\GTP_DUAL'. +Generating RTLIL representation for module `\GTX_DUAL'. +Generating RTLIL representation for module `\CRC32'. +Generating RTLIL representation for module `\CRC64'. +Generating RTLIL representation for module `\GTHE1_QUAD'. +Generating RTLIL representation for module `\GTXE1'. +Generating RTLIL representation for module `\IBUFDS_GTXE1'. +Generating RTLIL representation for module `\IBUFDS_GTHE1'. +Generating RTLIL representation for module `\GTHE2_CHANNEL'. +Generating RTLIL representation for module `\GTHE2_COMMON'. +Generating RTLIL representation for module `\GTPE2_CHANNEL'. +Generating RTLIL representation for module `\GTPE2_COMMON'. +Generating RTLIL representation for module `\GTXE2_CHANNEL'. +Generating RTLIL representation for module `\GTXE2_COMMON'. +Generating RTLIL representation for module `\IBUFDS_GTE2'. +Generating RTLIL representation for module `\GTHE3_CHANNEL'. +Generating RTLIL representation for module `\GTHE3_COMMON'. +Generating RTLIL representation for module `\GTHE4_CHANNEL'. +Generating RTLIL representation for module `\GTHE4_COMMON'. +Generating RTLIL representation for module `\GTYE3_CHANNEL'. +Generating RTLIL representation for module `\GTYE3_COMMON'. +Generating RTLIL representation for module `\GTYE4_CHANNEL'. +Generating RTLIL representation for module `\GTYE4_COMMON'. +Generating RTLIL representation for module `\IBUFDS_GTE3'. +Generating RTLIL representation for module `\IBUFDS_GTE4'. +Generating RTLIL representation for module `\OBUFDS_GTE3'. +Generating RTLIL representation for module `\OBUFDS_GTE3_ADV'. +Generating RTLIL representation for module `\OBUFDS_GTE4'. +Generating RTLIL representation for module `\OBUFDS_GTE4_ADV'. +Generating RTLIL representation for module `\PCIE_A1'. +Generating RTLIL representation for module `\PCIE_EP'. +Generating RTLIL representation for module `\PCIE_2_0'. +Generating RTLIL representation for module `\PCIE_2_1'. +Generating RTLIL representation for module `\PCIE_3_0'. +Generating RTLIL representation for module `\PCIE_3_1'. +Generating RTLIL representation for module `\PCIE40E4'. +Generating RTLIL representation for module `\EMAC'. +Generating RTLIL representation for module `\TEMAC'. +Generating RTLIL representation for module `\TEMAC_SINGLE'. +Generating RTLIL representation for module `\CMAC'. +Generating RTLIL representation for module `\CMACE4'. +Generating RTLIL representation for module `\PPC405_ADV'. +Generating RTLIL representation for module `\PPC440'. +Generating RTLIL representation for module `\MCB'. +Generating RTLIL representation for module `\PS7'. +Generating RTLIL representation for module `\PS8'. +Generating RTLIL representation for module `\ILKN'. +Generating RTLIL representation for module `\ILKNE4'. +Successfully finished Verilog frontend. + +6.3. Executing HIERARCHY pass (managing design hierarchy). + +6.3.1. Analyzing design hierarchy.. +Top module: \distributed_ram + +6.3.2. Analyzing design hierarchy.. +Top module: \distributed_ram +Removed 0 unused modules. + +6.4. Executing PROC pass (convert processes to netlists). + +6.4.1. Executing PROC_CLEAN pass (remove empty switches from decision trees). +Cleaned up 0 empty switches. + +6.4.2. Executing PROC_RMDEAD pass (remove dead branches from decision trees). +Removed a total of 0 dead cases. + +6.4.3. Executing PROC_PRUNE pass (remove redundant assignments in processes). +Removed 0 redundant assignments. +Promoted 1 assignment to connection. + +6.4.4. Executing PROC_INIT pass (extract init attributes). + +6.4.5. Executing PROC_ARST pass (detect async resets in processes). + +6.4.6. Executing PROC_MUX pass (convert decision trees to multiplexers). +Creating decoders for process `\distributed_ram.$proc$attributes_test.v:36$188'. + 1/3: $0$memwr$\memory$attributes_test.v:38$187_EN[7:0]$191 + 2/3: $0$memwr$\memory$attributes_test.v:38$187_DATA[7:0]$190 + 3/3: $0$memwr$\memory$attributes_test.v:38$187_ADDR[3:0]$189 + +6.4.7. Executing PROC_DLATCH pass (convert process syncs to latches). + +6.4.8. Executing PROC_DFF pass (convert process syncs to FFs). +Creating register for signal `\distributed_ram.\data_out_r' using process `\distributed_ram.$proc$attributes_test.v:36$188'. + created $dff cell `$procdff$227' with positive edge clock. +Creating register for signal `\distributed_ram.$memwr$\memory$attributes_test.v:38$187_ADDR' using process `\distributed_ram.$proc$attributes_test.v:36$188'. + created $dff cell `$procdff$228' with positive edge clock. +Creating register for signal `\distributed_ram.$memwr$\memory$attributes_test.v:38$187_DATA' using process `\distributed_ram.$proc$attributes_test.v:36$188'. + created $dff cell `$procdff$229' with positive edge clock. +Creating register for signal `\distributed_ram.$memwr$\memory$attributes_test.v:38$187_EN' using process `\distributed_ram.$proc$attributes_test.v:36$188'. + created $dff cell `$procdff$230' with positive edge clock. + +6.4.9. Executing PROC_CLEAN pass (remove empty switches from decision trees). +Found and cleaned up 1 empty switch in `\distributed_ram.$proc$attributes_test.v:36$188'. +Removing empty process `distributed_ram.$proc$attributes_test.v:36$188'. +Cleaned up 1 empty switch. + +6.5. Executing TRIBUF pass. + +6.6. Executing DEMINOUT pass (demote inout ports to input or output). + +6.7. Executing OPT_EXPR pass (perform const folding). +Optimizing module distributed_ram. + +6.8. Executing OPT_CLEAN pass (remove unused cells and wires). +Finding unused cells or wires in module \distributed_ram.. +Removed 0 unused cells and 7 unused wires. + + +6.9. Executing CHECK pass (checking for obvious problems). +checking module distributed_ram.. +found and reported 0 problems. + +6.10. Executing OPT pass (performing simple optimizations). + +6.10.1. Executing OPT_EXPR pass (perform const folding). +Optimizing module distributed_ram. + +6.10.2. Executing OPT_MERGE pass (detect identical cells). +Finding identical cells in module `\distributed_ram'. +Removed a total of 0 cells. + +6.10.3. Executing OPT_MUXTREE pass (detect dead branches in mux trees). +Running muxtree optimizer on module \distributed_ram.. + Creating internal representation of mux trees. + Evaluating internal representation of mux trees. + Analyzing evaluation results. +Removed 0 multiplexer ports. + + +6.10.4. Executing OPT_REDUCE pass (consolidate $*mux and $reduce_* inputs). + Optimizing cells in module \distributed_ram. + Consolidated identical input bits for $mux cell $procmux$221: + Old ports: A=8'00000000, B=8'11111111, Y=$0$memwr$\memory$attributes_test.v:38$187_EN[7:0]$191 + New ports: A=1'0, B=1'1, Y=$0$memwr$\memory$attributes_test.v:38$187_EN[7:0]$191 [0] + New connections: $0$memwr$\memory$attributes_test.v:38$187_EN[7:0]$191 [7:1] = { $0$memwr$\memory$attributes_test.v:38$187_EN[7:0]$191 [0] $0$memwr$\memory$attributes_test.v:38$187_EN[7:0]$191 [0] $0$memwr$\memory$attributes_test.v:38$187_EN[7:0]$191 [0] $0$memwr$\memory$attributes_test.v:38$187_EN[7:0]$191 [0] $0$memwr$\memory$attributes_test.v:38$187_EN[7:0]$191 [0] $0$memwr$\memory$attributes_test.v:38$187_EN[7:0]$191 [0] $0$memwr$\memory$attributes_test.v:38$187_EN[7:0]$191 [0] } + Optimizing cells in module \distributed_ram. +Performed a total of 1 changes. + +6.10.5. Executing OPT_MERGE pass (detect identical cells). +Finding identical cells in module `\distributed_ram'. +Removed a total of 0 cells. + +6.10.6. Executing OPT_RMDFF pass (remove dff with constant values). + +6.10.7. Executing OPT_CLEAN pass (remove unused cells and wires). +Finding unused cells or wires in module \distributed_ram.. + +6.10.8. Executing OPT_EXPR pass (perform const folding). +Optimizing module distributed_ram. + +6.10.9. Rerunning OPT passes. (Maybe there is more to do..) + +6.10.10. Executing OPT_MUXTREE pass (detect dead branches in mux trees). +Running muxtree optimizer on module \distributed_ram.. + Creating internal representation of mux trees. + Evaluating internal representation of mux trees. + Analyzing evaluation results. +Removed 0 multiplexer ports. + + +6.10.11. Executing OPT_REDUCE pass (consolidate $*mux and $reduce_* inputs). + Optimizing cells in module \distributed_ram. +Performed a total of 0 changes. + +6.10.12. Executing OPT_MERGE pass (detect identical cells). +Finding identical cells in module `\distributed_ram'. +Removed a total of 0 cells. + +6.10.13. Executing OPT_RMDFF pass (remove dff with constant values). + +6.10.14. Executing OPT_CLEAN pass (remove unused cells and wires). +Finding unused cells or wires in module \distributed_ram.. + +6.10.15. Executing OPT_EXPR pass (perform const folding). +Optimizing module distributed_ram. + +6.10.16. Finished OPT passes. (There is nothing left to do.) + +6.11. Executing WREDUCE pass (reducing word size of cells). +Removed cell distributed_ram.$procmux$223 ($mux). +Removed cell distributed_ram.$procmux$225 ($mux). +Removed top 7 bits (of 8) from FF cell distributed_ram.$procdff$230 ($dff). + +6.12. Executing PEEPOPT pass (run peephole optimizers). + +6.13. Executing OPT_CLEAN pass (remove unused cells and wires). +Finding unused cells or wires in module \distributed_ram.. +Removed 0 unused cells and 2 unused wires. + + +6.14. Executing PMUX2SHIFTX pass. + +6.15. Executing TECHMAP pass (map to technology primitives). + +6.15.1. Executing Verilog-2005 frontend: /opt/eda/fpga/FOSS/memattr/yosys_release/share/cmp2lut.v +Parsing Verilog input from `/opt/eda/fpga/FOSS/memattr/yosys_release/share/cmp2lut.v' to AST representation. +Generating RTLIL representation for module `\_90_lut_cmp_'. +Successfully finished Verilog frontend. + +6.15.2. Continuing TECHMAP pass. +No more expansions possible. + +6.16. Executing MEMORY_DFF pass (merging $dff cells to $memrd and $memwr). +Checking cell `$memwr$\memory$attributes_test.v:38$193' in module `\distributed_ram': merged $dff to cell. +Checking cell `$memrd$\memory$attributes_test.v:39$192' in module `\distributed_ram': merged data $dff to cell. + +6.17. Executing TECHMAP pass (map to technology primitives). + +6.17.1. Executing Verilog-2005 frontend: /opt/eda/fpga/FOSS/memattr/yosys_release/share/mul2dsp.v +Parsing Verilog input from `/opt/eda/fpga/FOSS/memattr/yosys_release/share/mul2dsp.v' to AST representation. +Generating RTLIL representation for module `\_80_mul'. +Generating RTLIL representation for module `\_90_soft_mul'. +Successfully finished Verilog frontend. + +6.17.2. Executing Verilog-2005 frontend: /opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/xc7_dsp_map.v +Parsing Verilog input from `/opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/xc7_dsp_map.v' to AST representation. +Generating RTLIL representation for module `\$__MUL25X18'. +Successfully finished Verilog frontend. + +6.17.3. Continuing TECHMAP pass. +No more expansions possible. + +6.18. Executing OPT_EXPR pass (perform const folding). + +6.19. Executing WREDUCE pass (reducing word size of cells). + +6.20. Executing XILINX_DSP pass (pack resources into DSPs). + +6.21. Executing ALUMACC pass (create $alu and $macc cells). +Extracting $alu and $macc cells in module distributed_ram: + created 0 $alu and 0 $macc cells. + +6.22. Executing SHARE pass (SAT-based resource sharing). + +6.23. Executing OPT pass (performing simple optimizations). + +6.23.1. Executing OPT_EXPR pass (perform const folding). +Optimizing module distributed_ram. + +6.23.2. Executing OPT_MERGE pass (detect identical cells). +Finding identical cells in module `\distributed_ram'. +Removed a total of 0 cells. + +6.23.3. Executing OPT_MUXTREE pass (detect dead branches in mux trees). +Running muxtree optimizer on module \distributed_ram.. + Creating internal representation of mux trees. + Evaluating internal representation of mux trees. + Analyzing evaluation results. +Removed 0 multiplexer ports. + + +6.23.4. Executing OPT_REDUCE pass (consolidate $*mux and $reduce_* inputs). + Optimizing cells in module \distributed_ram. +Performed a total of 0 changes. + +6.23.5. Executing OPT_MERGE pass (detect identical cells). +Finding identical cells in module `\distributed_ram'. +Removed a total of 0 cells. + +6.23.6. Executing OPT_RMDFF pass (remove dff with constant values). + +6.23.7. Executing OPT_CLEAN pass (remove unused cells and wires). +Finding unused cells or wires in module \distributed_ram.. +Removed 4 unused cells and 5 unused wires. + + +6.23.8. Executing OPT_EXPR pass (perform const folding). +Optimizing module distributed_ram. + +6.23.9. Rerunning OPT passes. (Maybe there is more to do..) + +6.23.10. Executing OPT_MUXTREE pass (detect dead branches in mux trees). +Running muxtree optimizer on module \distributed_ram.. + Creating internal representation of mux trees. + Evaluating internal representation of mux trees. + Analyzing evaluation results. +Removed 0 multiplexer ports. + + +6.23.11. Executing OPT_REDUCE pass (consolidate $*mux and $reduce_* inputs). + Optimizing cells in module \distributed_ram. +Performed a total of 0 changes. + +6.23.12. Executing OPT_MERGE pass (detect identical cells). +Finding identical cells in module `\distributed_ram'. +Removed a total of 0 cells. + +6.23.13. Executing OPT_RMDFF pass (remove dff with constant values). + +6.23.14. Executing OPT_CLEAN pass (remove unused cells and wires). +Finding unused cells or wires in module \distributed_ram.. + +6.23.15. Executing OPT_EXPR pass (perform const folding). +Optimizing module distributed_ram. + +6.23.16. Finished OPT passes. (There is nothing left to do.) + +6.24. Executing FSM pass (extract and optimize FSM). + +6.24.1. Executing FSM_DETECT pass (finding FSMs in design). + +6.24.2. Executing FSM_EXTRACT pass (extracting FSM from design). + +6.24.3. Executing FSM_OPT pass (simple optimizations of FSMs). + +6.24.4. Executing OPT_CLEAN pass (remove unused cells and wires). +Finding unused cells or wires in module \distributed_ram.. + +6.24.5. Executing FSM_OPT pass (simple optimizations of FSMs). + +6.24.6. Executing FSM_RECODE pass (re-assigning FSM state encoding). + +6.24.7. Executing FSM_INFO pass (dumping all available information on FSM cells). + +6.24.8. Executing FSM_MAP pass (mapping FSMs to basic logic). + +6.25. Executing OPT pass (performing simple optimizations). + +6.25.1. Executing OPT_EXPR pass (perform const folding). +Optimizing module distributed_ram. + +6.25.2. Executing OPT_MERGE pass (detect identical cells). +Finding identical cells in module `\distributed_ram'. +Removed a total of 0 cells. + +6.25.3. Executing OPT_RMDFF pass (remove dff with constant values). + +6.25.4. Executing OPT_CLEAN pass (remove unused cells and wires). +Finding unused cells or wires in module \distributed_ram.. + +6.25.5. Finished fast OPT passes. + +6.26. Executing MEMORY pass. + +6.26.1. Executing OPT_MEM pass (optimize memories). +Performed a total of 0 transformations. + +6.26.2. Executing MEMORY_DFF pass (merging $dff cells to $memrd and $memwr). + +6.26.3. Executing OPT_CLEAN pass (remove unused cells and wires). +Finding unused cells or wires in module \distributed_ram.. + +6.26.4. Executing MEMORY_SHARE pass (consolidating $memrd/$memwr cells). + +6.26.5. Executing OPT_CLEAN pass (remove unused cells and wires). +Finding unused cells or wires in module \distributed_ram.. + +6.26.6. Executing MEMORY_COLLECT pass (generating $mem cells). +Collecting $memrd, $memwr and $meminit for memory `\memory' in module `\distributed_ram': + $memwr$\memory$attributes_test.v:38$193 ($memwr) + $memrd$\memory$attributes_test.v:39$192 ($memrd) + +6.27. Executing OPT_CLEAN pass (remove unused cells and wires). +Finding unused cells or wires in module \distributed_ram.. + +6.28. Executing MEMORY_BRAM pass (mapping $mem cells to block memories). +Processing distributed_ram.memory: + Properties: ports=2 bits=128 rports=1 wports=1 dbits=8 abits=4 words=16 + Checking rule #1 for bram type $__XILINX_RAMB36_SDP (variant 1): + Bram geometry: abits=9 dbits=72 wports=0 rports=0 + Estimated number of duplicates for more read ports: dups=1 + Metrics for $__XILINX_RAMB36_SDP: awaste=496 dwaste=64 bwaste=36736 waste=36736 efficiency=0 + Rule #1 for bram type $__XILINX_RAMB36_SDP (variant 1) rejected: requirement 'min efficiency 5' not met. + Checking rule #2 for bram type $__XILINX_RAMB18_SDP (variant 1): + Bram geometry: abits=9 dbits=36 wports=0 rports=0 + Estimated number of duplicates for more read ports: dups=1 + Metrics for $__XILINX_RAMB18_SDP: awaste=496 dwaste=28 bwaste=18304 waste=18304 efficiency=0 + Rule #2 for bram type $__XILINX_RAMB18_SDP (variant 1) rejected: requirement 'min efficiency 5' not met. + Checking rule #3 for bram type $__XILINX_RAMB36_TDP (variant 1): + Bram geometry: abits=10 dbits=36 wports=0 rports=0 + Estimated number of duplicates for more read ports: dups=1 + Metrics for $__XILINX_RAMB36_TDP: awaste=1008 dwaste=28 bwaste=36736 waste=36736 efficiency=0 + Rule #3 for bram type $__XILINX_RAMB36_TDP (variant 1) rejected: requirement 'min efficiency 5' not met. + Checking rule #3 for bram type $__XILINX_RAMB36_TDP (variant 2): + Bram geometry: abits=11 dbits=18 wports=0 rports=0 + Estimated number of duplicates for more read ports: dups=1 + Metrics for $__XILINX_RAMB36_TDP: awaste=2032 dwaste=10 bwaste=36736 waste=36736 efficiency=0 + Rule #3 for bram type $__XILINX_RAMB36_TDP (variant 2) rejected: requirement 'min efficiency 5' not met. + Checking rule #3 for bram type $__XILINX_RAMB36_TDP (variant 3): + Bram geometry: abits=12 dbits=9 wports=0 rports=0 + Estimated number of duplicates for more read ports: dups=1 + Metrics for $__XILINX_RAMB36_TDP: awaste=4080 dwaste=1 bwaste=36736 waste=36736 efficiency=0 + Rule #3 for bram type $__XILINX_RAMB36_TDP (variant 3) rejected: requirement 'min efficiency 5' not met. + Checking rule #3 for bram type $__XILINX_RAMB36_TDP (variant 4): + Bram geometry: abits=13 dbits=4 wports=0 rports=0 + Estimated number of duplicates for more read ports: dups=1 + Metrics for $__XILINX_RAMB36_TDP: awaste=8176 dwaste=0 bwaste=32704 waste=32704 efficiency=0 + Rule #3 for bram type $__XILINX_RAMB36_TDP (variant 4) rejected: requirement 'min efficiency 5' not met. + Checking rule #3 for bram type $__XILINX_RAMB36_TDP (variant 5): + Bram geometry: abits=14 dbits=2 wports=0 rports=0 + Estimated number of duplicates for more read ports: dups=1 + Metrics for $__XILINX_RAMB36_TDP: awaste=16368 dwaste=0 bwaste=32736 waste=32736 efficiency=0 + Rule #3 for bram type $__XILINX_RAMB36_TDP (variant 5) rejected: requirement 'min efficiency 5' not met. + Checking rule #3 for bram type $__XILINX_RAMB36_TDP (variant 6): + Bram geometry: abits=15 dbits=1 wports=0 rports=0 + Estimated number of duplicates for more read ports: dups=1 + Metrics for $__XILINX_RAMB36_TDP: awaste=32752 dwaste=0 bwaste=32752 waste=32752 efficiency=0 + Rule #3 for bram type $__XILINX_RAMB36_TDP (variant 6) rejected: requirement 'min efficiency 5' not met. + Checking rule #4 for bram type $__XILINX_RAMB18_TDP (variant 1): + Bram geometry: abits=10 dbits=18 wports=0 rports=0 + Estimated number of duplicates for more read ports: dups=1 + Metrics for $__XILINX_RAMB18_TDP: awaste=1008 dwaste=10 bwaste=18304 waste=18304 efficiency=0 + Rule #4 for bram type $__XILINX_RAMB18_TDP (variant 1) rejected: requirement 'min efficiency 5' not met. + Checking rule #4 for bram type $__XILINX_RAMB18_TDP (variant 2): + Bram geometry: abits=11 dbits=9 wports=0 rports=0 + Estimated number of duplicates for more read ports: dups=1 + Metrics for $__XILINX_RAMB18_TDP: awaste=2032 dwaste=1 bwaste=18304 waste=18304 efficiency=0 + Rule #4 for bram type $__XILINX_RAMB18_TDP (variant 2) rejected: requirement 'min efficiency 5' not met. + Checking rule #4 for bram type $__XILINX_RAMB18_TDP (variant 3): + Bram geometry: abits=12 dbits=4 wports=0 rports=0 + Estimated number of duplicates for more read ports: dups=1 + Metrics for $__XILINX_RAMB18_TDP: awaste=4080 dwaste=0 bwaste=16320 waste=16320 efficiency=0 + Rule #4 for bram type $__XILINX_RAMB18_TDP (variant 3) rejected: requirement 'min efficiency 5' not met. + Checking rule #4 for bram type $__XILINX_RAMB18_TDP (variant 4): + Bram geometry: abits=13 dbits=2 wports=0 rports=0 + Estimated number of duplicates for more read ports: dups=1 + Metrics for $__XILINX_RAMB18_TDP: awaste=8176 dwaste=0 bwaste=16352 waste=16352 efficiency=0 + Rule #4 for bram type $__XILINX_RAMB18_TDP (variant 4) rejected: requirement 'min efficiency 5' not met. + Checking rule #4 for bram type $__XILINX_RAMB18_TDP (variant 5): + Bram geometry: abits=14 dbits=1 wports=0 rports=0 + Estimated number of duplicates for more read ports: dups=1 + Metrics for $__XILINX_RAMB18_TDP: awaste=16368 dwaste=0 bwaste=16368 waste=16368 efficiency=0 + Rule #4 for bram type $__XILINX_RAMB18_TDP (variant 5) rejected: requirement 'min efficiency 5' not met. + No acceptable bram resources found. + +6.29. Executing TECHMAP pass (map to technology primitives). + +6.29.1. Executing Verilog-2005 frontend: /opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/xc7_brams_map.v +Parsing Verilog input from `/opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/xc7_brams_map.v' to AST representation. +Generating RTLIL representation for module `\$__XILINX_RAMB36_SDP'. +Generating RTLIL representation for module `\$__XILINX_RAMB18_SDP'. +Generating RTLIL representation for module `\$__XILINX_RAMB36_TDP'. +Generating RTLIL representation for module `\$__XILINX_RAMB18_TDP'. +Successfully finished Verilog frontend. + +6.29.2. Continuing TECHMAP pass. +No more expansions possible. + +6.30. Executing MEMORY_BRAM pass (mapping $mem cells to block memories). +Processing distributed_ram.memory: + Properties: ports=2 bits=128 rports=1 wports=1 dbits=8 abits=4 words=16 + Checking rule #1 for bram type $__XILINX_RAM32X1D (variant 1): + Bram geometry: abits=5 dbits=1 wports=0 rports=0 + Estimated number of duplicates for more read ports: dups=1 + Metrics for $__XILINX_RAM32X1D: awaste=16 dwaste=0 bwaste=16 waste=16 efficiency=50 + Rule #1 for bram type $__XILINX_RAM32X1D (variant 1) accepted. + Mapping to bram type $__XILINX_RAM32X1D (variant 1): + Write port #0 is in clock domain \clk. + Mapped to bram port B1. + Read port #0 is in clock domain \clk. + Mapped to bram port A1.1. + Updated properties: dups=1 waste=16 efficiency=50 + Storing for later selection. + Checking rule #2 for bram type $__XILINX_RAM64X1D (variant 1): + Bram geometry: abits=6 dbits=1 wports=0 rports=0 + Estimated number of duplicates for more read ports: dups=1 + Metrics for $__XILINX_RAM64X1D: awaste=48 dwaste=0 bwaste=48 waste=48 efficiency=25 + Rule #2 for bram type $__XILINX_RAM64X1D (variant 1) accepted. + Mapping to bram type $__XILINX_RAM64X1D (variant 1): + Write port #0 is in clock domain \clk. + Mapped to bram port B1. + Read port #0 is in clock domain \clk. + Mapped to bram port A1.1. + Updated properties: dups=1 waste=48 efficiency=25 + Storing for later selection. + Checking rule #3 for bram type $__XILINX_RAM128X1D (variant 1): + Bram geometry: abits=7 dbits=1 wports=0 rports=0 + Estimated number of duplicates for more read ports: dups=1 + Metrics for $__XILINX_RAM128X1D: awaste=112 dwaste=0 bwaste=112 waste=112 efficiency=12 + Rule #3 for bram type $__XILINX_RAM128X1D (variant 1) accepted. + Mapping to bram type $__XILINX_RAM128X1D (variant 1): + Write port #0 is in clock domain \clk. + Mapped to bram port B1. + Read port #0 is in clock domain \clk. + Mapped to bram port A1.1. + Updated properties: dups=1 waste=112 efficiency=12 + Storing for later selection. + Selecting best of 3 rules: + Efficiency for rule 3.1: efficiency=12, cells=8, acells=1 + Efficiency for rule 2.1: efficiency=25, cells=8, acells=1 + Efficiency for rule 1.1: efficiency=50, cells=8, acells=1 + Selected rule 1.1 with efficiency 50. + Mapping to bram type $__XILINX_RAM32X1D (variant 1): + Write port #0 is in clock domain \clk. + Mapped to bram port B1. + Read port #0 is in clock domain \clk. + Mapped to bram port A1.1. + Creating $__XILINX_RAM32X1D cell at grid position <0 0 0>: memory.0.0.0 + Creating $__XILINX_RAM32X1D cell at grid position <1 0 0>: memory.1.0.0 + Creating $__XILINX_RAM32X1D cell at grid position <2 0 0>: memory.2.0.0 + Creating $__XILINX_RAM32X1D cell at grid position <3 0 0>: memory.3.0.0 + Creating $__XILINX_RAM32X1D cell at grid position <4 0 0>: memory.4.0.0 + Creating $__XILINX_RAM32X1D cell at grid position <5 0 0>: memory.5.0.0 + Creating $__XILINX_RAM32X1D cell at grid position <6 0 0>: memory.6.0.0 + Creating $__XILINX_RAM32X1D cell at grid position <7 0 0>: memory.7.0.0 + +6.31. Executing TECHMAP pass (map to technology primitives). + +6.31.1. Executing Verilog-2005 frontend: /opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/lutrams_map.v +Parsing Verilog input from `/opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/lutrams_map.v' to AST representation. +Generating RTLIL representation for module `\$__XILINX_RAM32X1D'. +Generating RTLIL representation for module `\$__XILINX_RAM64X1D'. +Generating RTLIL representation for module `\$__XILINX_RAM128X1D'. +Successfully finished Verilog frontend. + +6.31.2. Continuing TECHMAP pass. +Using template $paramod\$__XILINX_RAM32X1D\CLKPOL2=1 for cells of type $__XILINX_RAM32X1D. +No more expansions possible. + + +6.32. Executing OPT pass (performing simple optimizations). + +6.32.1. Executing OPT_EXPR pass (perform const folding). +Optimizing module distributed_ram. + + +6.32.2. Executing OPT_MERGE pass (detect identical cells). +Finding identical cells in module `\distributed_ram'. +Removed a total of 0 cells. + +6.32.3. Executing OPT_RMDFF pass (remove dff with constant values). + +6.32.4. Executing OPT_CLEAN pass (remove unused cells and wires). +Finding unused cells or wires in module \distributed_ram.. +Removed 0 unused cells and 65 unused wires. + + +6.32.5. Finished fast OPT passes. + +6.33. Executing MEMORY_MAP pass (converting $mem cells to logic and flip-flops). + +6.34. Executing DFFSR2DFF pass (mapping DFFSR cells to simpler FFs). + +6.35. Executing DFF2DFFE pass (transform $dff to $dffe where applicable). +Transforming FF to FF+Enable cells in module distributed_ram: + +6.36. Executing OPT pass (performing simple optimizations). + +6.36.1. Executing OPT_EXPR pass (perform const folding). +Optimizing module distributed_ram. + +6.36.2. Executing OPT_MERGE pass (detect identical cells). +Finding identical cells in module `\distributed_ram'. +Removed a total of 0 cells. + +6.36.3. Executing OPT_MUXTREE pass (detect dead branches in mux trees). +Running muxtree optimizer on module \distributed_ram.. + Creating internal representation of mux trees. + No muxes found in this module. +Removed 0 multiplexer ports. + +6.36.4. Executing OPT_REDUCE pass (consolidate $*mux and $reduce_* inputs). + Optimizing cells in module \distributed_ram. +Performed a total of 0 changes. + +6.36.5. Executing OPT_MERGE pass (detect identical cells). +Finding identical cells in module `\distributed_ram'. +Removed a total of 0 cells. + +6.36.6. Executing OPT_SHARE pass. + +6.36.7. Executing OPT_RMDFF pass (remove dff with constant values). + +6.36.8. Executing OPT_CLEAN pass (remove unused cells and wires). +Finding unused cells or wires in module \distributed_ram.. + +6.36.9. Executing OPT_EXPR pass (perform const folding). +Optimizing module distributed_ram. + +6.36.10. Finished OPT passes. (There is nothing left to do.) + +6.37. Executing XILINX_SRL pass (Xilinx shift register extraction). + +6.38. Executing TECHMAP pass (map to technology primitives). + +6.38.1. Executing Verilog-2005 frontend: /opt/eda/fpga/FOSS/memattr/yosys_release/share/techmap.v +Parsing Verilog input from `/opt/eda/fpga/FOSS/memattr/yosys_release/share/techmap.v' to AST representation. +Generating RTLIL representation for module `\_90_simplemap_bool_ops'. +Generating RTLIL representation for module `\_90_simplemap_reduce_ops'. +Generating RTLIL representation for module `\_90_simplemap_logic_ops'. +Generating RTLIL representation for module `\_90_simplemap_compare_ops'. +Generating RTLIL representation for module `\_90_simplemap_various'. +Generating RTLIL representation for module `\_90_simplemap_registers'. +Generating RTLIL representation for module `\_90_shift_ops_shr_shl_sshl_sshr'. +Generating RTLIL representation for module `\_90_shift_shiftx'. +Generating RTLIL representation for module `\_90_fa'. +Generating RTLIL representation for module `\_90_lcu'. +Generating RTLIL representation for module `\_90_alu'. +Generating RTLIL representation for module `\_90_macc'. +Generating RTLIL representation for module `\_90_alumacc'. +Generating RTLIL representation for module `\$__div_mod_u'. +Generating RTLIL representation for module `\$__div_mod'. +Generating RTLIL representation for module `\_90_div'. +Generating RTLIL representation for module `\_90_mod'. +Generating RTLIL representation for module `\_90_pow'. +Generating RTLIL representation for module `\_90_pmux'. +Generating RTLIL representation for module `\_90_lut'. +Successfully finished Verilog frontend. + +6.38.2. Executing Verilog-2005 frontend: /opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/arith_map.v +Parsing Verilog input from `/opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/arith_map.v' to AST representation. +Generating RTLIL representation for module `\_80_xilinx_lcu'. +Generating RTLIL representation for module `\_80_xilinx_alu'. +Successfully finished Verilog frontend. + +6.38.3. Continuing TECHMAP pass. +Using extmapper simplemap for cells of type $dff. +No more expansions possible. + + +6.39. Executing OPT pass (performing simple optimizations). + +6.39.1. Executing OPT_EXPR pass (perform const folding). +Optimizing module distributed_ram. + +6.39.2. Executing OPT_MERGE pass (detect identical cells). +Finding identical cells in module `\distributed_ram'. +Removed a total of 0 cells. + +6.39.3. Executing OPT_RMDFF pass (remove dff with constant values). + +6.39.4. Executing OPT_CLEAN pass (remove unused cells and wires). +Finding unused cells or wires in module \distributed_ram.. + +6.39.5. Finished fast OPT passes. + +6.40. Executing TECHMAP pass (map to technology primitives). + +6.40.1. Executing Verilog-2005 frontend: /opt/eda/fpga/FOSS/memattr/yosys_release/share/techmap.v +Parsing Verilog input from `/opt/eda/fpga/FOSS/memattr/yosys_release/share/techmap.v' to AST representation. +Generating RTLIL representation for module `\_90_simplemap_bool_ops'. +Generating RTLIL representation for module `\_90_simplemap_reduce_ops'. +Generating RTLIL representation for module `\_90_simplemap_logic_ops'. +Generating RTLIL representation for module `\_90_simplemap_compare_ops'. +Generating RTLIL representation for module `\_90_simplemap_various'. +Generating RTLIL representation for module `\_90_simplemap_registers'. +Generating RTLIL representation for module `\_90_shift_ops_shr_shl_sshl_sshr'. +Generating RTLIL representation for module `\_90_shift_shiftx'. +Generating RTLIL representation for module `\_90_fa'. +Generating RTLIL representation for module `\_90_lcu'. +Generating RTLIL representation for module `\_90_alu'. +Generating RTLIL representation for module `\_90_macc'. +Generating RTLIL representation for module `\_90_alumacc'. +Generating RTLIL representation for module `\$__div_mod_u'. +Generating RTLIL representation for module `\$__div_mod'. +Generating RTLIL representation for module `\_90_div'. +Generating RTLIL representation for module `\_90_mod'. +Generating RTLIL representation for module `\_90_pow'. +Generating RTLIL representation for module `\_90_pmux'. +Generating RTLIL representation for module `\_90_lut'. +Successfully finished Verilog frontend. + +6.40.2. Executing Verilog-2005 frontend: /opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/cells_map.v +Parsing Verilog input from `/opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/cells_map.v' to AST representation. +Generating RTLIL representation for module `\_90_dff_nn0_to_np0'. +Generating RTLIL representation for module `\_90_dff_pn0_to_pp0'. +Generating RTLIL representation for module `\_90_dff_nn1_to_np1'. +Generating RTLIL representation for module `\_90_dff_pn1_to_pp1'. +Generating RTLIL representation for module `\$__SHREG_'. +Generating RTLIL representation for module `\$__XILINX_SHREG_'. +Generating RTLIL representation for module `\$__XILINX_MUXF78'. +Generating RTLIL representation for module `\$__XILINX_TINOUTPAD'. +Generating RTLIL representation for module `\$__XILINX_TOUTPAD'. +Successfully finished Verilog frontend. + +6.40.3. Continuing TECHMAP pass. +No more expansions possible. + +6.41. Executing OPT_EXPR pass (perform const folding). +Optimizing module distributed_ram. + +6.42. Executing ABC pass (technology mapping using ABC). + +6.42.1. Extracting gate netlist of module `\distributed_ram' to `/input.blif'.. +Extracted 0 gates and 0 wires to a netlist network with 0 inputs and 0 outputs. +Don't call ABC as there is nothing to map. +Removing temp directory. + +6.43. Executing XILINX_SRL pass (Xilinx shift register extraction). + +6.44. Executing TECHMAP pass (map to technology primitives). + +6.44.1. Executing Verilog-2005 frontend: /opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/lut_map.v +Parsing Verilog input from `/opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/lut_map.v' to AST representation. +Generating RTLIL representation for module `\$lut'. +Successfully finished Verilog frontend. + +6.44.2. Executing Verilog-2005 frontend: /opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/cells_map.v +Parsing Verilog input from `/opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/cells_map.v' to AST representation. +Generating RTLIL representation for module `\_90_dff_nn0_to_np0'. +Generating RTLIL representation for module `\_90_dff_pn0_to_pp0'. +Generating RTLIL representation for module `\_90_dff_nn1_to_np1'. +Generating RTLIL representation for module `\_90_dff_pn1_to_pp1'. +Generating RTLIL representation for module `\$__SHREG_'. +Generating RTLIL representation for module `\$__XILINX_SHREG_'. +Generating RTLIL representation for module `\$__XILINX_MUXF78'. +Generating RTLIL representation for module `\$__XILINX_TINOUTPAD'. +Generating RTLIL representation for module `\$__XILINX_TOUTPAD'. +Successfully finished Verilog frontend. + +6.44.3. Executing Verilog-2005 frontend: /opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/xc7_ff_map.v +Parsing Verilog input from `/opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/xc7_ff_map.v' to AST representation. +Generating RTLIL representation for module `\$_DFF_N_'. +Generating RTLIL representation for module `\$_DFF_P_'. +Generating RTLIL representation for module `\$_DFFE_NP_'. +Generating RTLIL representation for module `\$_DFFE_PP_'. +Generating RTLIL representation for module `\$_DFF_NN0_'. +Generating RTLIL representation for module `\$_DFF_NP0_'. +Generating RTLIL representation for module `\$_DFF_PN0_'. +Generating RTLIL representation for module `\$_DFF_PP0_'. +Generating RTLIL representation for module `\$_DFF_NN1_'. +Generating RTLIL representation for module `\$_DFF_NP1_'. +Generating RTLIL representation for module `\$_DFF_PN1_'. +Generating RTLIL representation for module `\$_DFF_PP1_'. +Generating RTLIL representation for module `\$_DLATCH_N_'. +Generating RTLIL representation for module `\$_DLATCH_P_'. +Successfully finished Verilog frontend. + +6.44.4. Continuing TECHMAP pass. +Using template $paramod\$_DFF_P_\_TECHMAP_WIREINIT_Q_=1'x for cells of type $_DFF_P_. +No more expansions possible. + +Removed 0 unused cells and 32 unused wires. + +6.45. Executing CLKBUFMAP pass (inserting global clock buffers). +Inserting BUFG on distributed_ram.clk[0]. + +6.46. Executing HIERARCHY pass (managing design hierarchy). + +6.46.1. Analyzing design hierarchy.. +Top module: \distributed_ram + +6.46.2. Analyzing design hierarchy.. +Top module: \distributed_ram +Removed 0 unused modules. + +6.47. Printing statistics. + +=== distributed_ram === + + Number of wires: 16 + Number of wire bits: 40 + Number of public wires: 6 + Number of public wire bits: 30 + Number of memories: 0 + Number of memory bits: 0 + Number of processes: 0 + Number of cells: 17 + BUFG 1 + FDRE 8 + RAM32X1D 8 + + Estimated number of LCs: 0 + +6.48. Executing CHECK pass (checking for obvious problems). +checking module distributed_ram.. +found and reported 0 problems. + +7. Executing Verilog-2005 frontend: attributes_test.v +Parsing Verilog input from `attributes_test.v' to AST representation. +Generating RTLIL representation for module `\block_ram'. +Generating RTLIL representation for module `\distributed_ram'. +Generating RTLIL representation for module `\distributed_ram_manual'. +Generating RTLIL representation for module `\distributed_ram_manual_syn'. +Successfully finished Verilog frontend. + +8. Executing PREP pass. + +8.1. Executing HIERARCHY pass (managing design hierarchy). + +8.2. Executing PROC pass (convert processes to netlists). + +8.2.1. Executing PROC_CLEAN pass (remove empty switches from decision trees). +Cleaned up 0 empty switches. + +8.2.2. Executing PROC_RMDEAD pass (remove dead branches from decision trees). +Removed a total of 0 dead cases. + +8.2.3. Executing PROC_PRUNE pass (remove redundant assignments in processes). +Removed 0 redundant assignments. +Promoted 4 assignments to connections. + +8.2.4. Executing PROC_INIT pass (extract init attributes). + +8.2.5. Executing PROC_ARST pass (detect async resets in processes). + +8.2.6. Executing PROC_MUX pass (convert decision trees to multiplexers). +Creating decoders for process `\distributed_ram_manual_syn.$proc$attributes_test.v:80$441'. + 1/3: $0$memwr$\memory$attributes_test.v:82$440_EN[7:0]$443 + 2/3: $0$memwr$\memory$attributes_test.v:82$440_DATA[7:0]$444 + 3/3: $0$memwr$\memory$attributes_test.v:82$440_ADDR[3:0]$442 +Creating decoders for process `\distributed_ram_manual.$proc$attributes_test.v:58$434'. + 1/3: $0$memwr$\memory$attributes_test.v:60$433_EN[7:0]$435 + 2/3: $0$memwr$\memory$attributes_test.v:60$433_DATA[7:0]$437 + 3/3: $0$memwr$\memory$attributes_test.v:60$433_ADDR[3:0]$436 +Creating decoders for process `\distributed_ram.$proc$attributes_test.v:36$427'. + 1/3: $0$memwr$\memory$attributes_test.v:38$426_EN[7:0]$430 + 2/3: $0$memwr$\memory$attributes_test.v:38$426_DATA[7:0]$429 + 3/3: $0$memwr$\memory$attributes_test.v:38$426_ADDR[3:0]$428 +Creating decoders for process `\block_ram.$proc$attributes_test.v:14$420'. + 1/3: $0$memwr$\memory$attributes_test.v:16$419_EN[3:0]$423 + 2/3: $0$memwr$\memory$attributes_test.v:16$419_DATA[3:0]$422 + 3/3: $0$memwr$\memory$attributes_test.v:16$419_ADDR[9:0]$421 + +8.2.7. Executing PROC_DLATCH pass (convert process syncs to latches). + +8.2.8. Executing PROC_DFF pass (convert process syncs to FFs). +Creating register for signal `\distributed_ram_manual_syn.$memwr$\memory$attributes_test.v:82$440_ADDR' using process `\distributed_ram_manual_syn.$proc$attributes_test.v:80$441'. + created $dff cell `$procdff$471' with positive edge clock. +Creating register for signal `\distributed_ram_manual_syn.\data_out_r' using process `\distributed_ram_manual_syn.$proc$attributes_test.v:80$441'. + created $dff cell `$procdff$472' with positive edge clock. +Creating register for signal `\distributed_ram_manual_syn.$memwr$\memory$attributes_test.v:82$440_EN' using process `\distributed_ram_manual_syn.$proc$attributes_test.v:80$441'. + created $dff cell `$procdff$473' with positive edge clock. +Creating register for signal `\distributed_ram_manual_syn.$memwr$\memory$attributes_test.v:82$440_DATA' using process `\distributed_ram_manual_syn.$proc$attributes_test.v:80$441'. + created $dff cell `$procdff$474' with positive edge clock. +Creating register for signal `\distributed_ram_manual.$memwr$\memory$attributes_test.v:60$433_EN' using process `\distributed_ram_manual.$proc$attributes_test.v:58$434'. + created $dff cell `$procdff$475' with positive edge clock. +Creating register for signal `\distributed_ram_manual.$memwr$\memory$attributes_test.v:60$433_ADDR' using process `\distributed_ram_manual.$proc$attributes_test.v:58$434'. + created $dff cell `$procdff$476' with positive edge clock. +Creating register for signal `\distributed_ram_manual.$memwr$\memory$attributes_test.v:60$433_DATA' using process `\distributed_ram_manual.$proc$attributes_test.v:58$434'. + created $dff cell `$procdff$477' with positive edge clock. +Creating register for signal `\distributed_ram_manual.\data_out_r' using process `\distributed_ram_manual.$proc$attributes_test.v:58$434'. + created $dff cell `$procdff$478' with positive edge clock. +Creating register for signal `\distributed_ram.$memwr$\memory$attributes_test.v:38$426_ADDR' using process `\distributed_ram.$proc$attributes_test.v:36$427'. + created $dff cell `$procdff$479' with positive edge clock. +Creating register for signal `\distributed_ram.\data_out_r' using process `\distributed_ram.$proc$attributes_test.v:36$427'. + created $dff cell `$procdff$480' with positive edge clock. +Creating register for signal `\distributed_ram.$memwr$\memory$attributes_test.v:38$426_DATA' using process `\distributed_ram.$proc$attributes_test.v:36$427'. + created $dff cell `$procdff$481' with positive edge clock. +Creating register for signal `\distributed_ram.$memwr$\memory$attributes_test.v:38$426_EN' using process `\distributed_ram.$proc$attributes_test.v:36$427'. + created $dff cell `$procdff$482' with positive edge clock. +Creating register for signal `\block_ram.$memwr$\memory$attributes_test.v:16$419_ADDR' using process `\block_ram.$proc$attributes_test.v:14$420'. + created $dff cell `$procdff$483' with positive edge clock. +Creating register for signal `\block_ram.\data_out_r' using process `\block_ram.$proc$attributes_test.v:14$420'. + created $dff cell `$procdff$484' with positive edge clock. +Creating register for signal `\block_ram.$memwr$\memory$attributes_test.v:16$419_DATA' using process `\block_ram.$proc$attributes_test.v:14$420'. + created $dff cell `$procdff$485' with positive edge clock. +Creating register for signal `\block_ram.$memwr$\memory$attributes_test.v:16$419_EN' using process `\block_ram.$proc$attributes_test.v:14$420'. + created $dff cell `$procdff$486' with positive edge clock. + +8.2.9. Executing PROC_CLEAN pass (remove empty switches from decision trees). +Found and cleaned up 1 empty switch in `\distributed_ram_manual_syn.$proc$attributes_test.v:80$441'. +Removing empty process `distributed_ram_manual_syn.$proc$attributes_test.v:80$441'. +Found and cleaned up 1 empty switch in `\distributed_ram_manual.$proc$attributes_test.v:58$434'. +Removing empty process `distributed_ram_manual.$proc$attributes_test.v:58$434'. +Found and cleaned up 1 empty switch in `\distributed_ram.$proc$attributes_test.v:36$427'. +Removing empty process `distributed_ram.$proc$attributes_test.v:36$427'. +Found and cleaned up 1 empty switch in `\block_ram.$proc$attributes_test.v:14$420'. +Removing empty process `block_ram.$proc$attributes_test.v:14$420'. +Cleaned up 4 empty switches. + +8.3. Executing OPT_EXPR pass (perform const folding). +Optimizing module distributed_ram_manual_syn. +Optimizing module distributed_ram_manual. +Optimizing module distributed_ram. +Optimizing module block_ram. + +8.4. Executing OPT_CLEAN pass (remove unused cells and wires). +Finding unused cells or wires in module \distributed_ram_manual_syn.. +Finding unused cells or wires in module \distributed_ram_manual.. +Finding unused cells or wires in module \distributed_ram.. +Finding unused cells or wires in module \block_ram.. +Removed 0 unused cells and 28 unused wires. + + +8.5. Executing CHECK pass (checking for obvious problems). +checking module block_ram.. +checking module distributed_ram.. +checking module distributed_ram_manual.. +checking module distributed_ram_manual_syn.. +found and reported 0 problems. + +8.6. Executing OPT pass (performing simple optimizations). + +8.6.1. Executing OPT_EXPR pass (perform const folding). +Optimizing module block_ram. +Optimizing module distributed_ram. +Optimizing module distributed_ram_manual. +Optimizing module distributed_ram_manual_syn. + +8.6.2. Executing OPT_MERGE pass (detect identical cells). +Finding identical cells in module `\block_ram'. +Finding identical cells in module `\distributed_ram'. +Finding identical cells in module `\distributed_ram_manual'. +Finding identical cells in module `\distributed_ram_manual_syn'. +Removed a total of 0 cells. + +8.6.3. Executing OPT_MUXTREE pass (detect dead branches in mux trees). +Running muxtree optimizer on module \block_ram.. + Creating internal representation of mux trees. + Evaluating internal representation of mux trees. + Analyzing evaluation results. +Running muxtree optimizer on module \distributed_ram.. + Creating internal representation of mux trees. + Evaluating internal representation of mux trees. + Analyzing evaluation results. +Running muxtree optimizer on module \distributed_ram_manual.. + Creating internal representation of mux trees. + Evaluating internal representation of mux trees. + Analyzing evaluation results. +Running muxtree optimizer on module \distributed_ram_manual_syn.. + Creating internal representation of mux trees. + Evaluating internal representation of mux trees. + Analyzing evaluation results. +Removed 0 multiplexer ports. + + +8.6.4. Executing OPT_REDUCE pass (consolidate $*mux and $reduce_* inputs). + Optimizing cells in module \block_ram. + Consolidated identical input bits for $mux cell $procmux$465: + Old ports: A=4'0000, B=4'1111, Y=$0$memwr$\memory$attributes_test.v:16$419_EN[3:0]$423 + New ports: A=1'0, B=1'1, Y=$0$memwr$\memory$attributes_test.v:16$419_EN[3:0]$423 [0] + New connections: $0$memwr$\memory$attributes_test.v:16$419_EN[3:0]$423 [3:1] = { $0$memwr$\memory$attributes_test.v:16$419_EN[3:0]$423 [0] $0$memwr$\memory$attributes_test.v:16$419_EN[3:0]$423 [0] $0$memwr$\memory$attributes_test.v:16$419_EN[3:0]$423 [0] } + Optimizing cells in module \block_ram. + Optimizing cells in module \distributed_ram. + Consolidated identical input bits for $mux cell $procmux$459: + Old ports: A=8'00000000, B=8'11111111, Y=$0$memwr$\memory$attributes_test.v:38$426_EN[7:0]$430 + New ports: A=1'0, B=1'1, Y=$0$memwr$\memory$attributes_test.v:38$426_EN[7:0]$430 [0] + New connections: $0$memwr$\memory$attributes_test.v:38$426_EN[7:0]$430 [7:1] = { $0$memwr$\memory$attributes_test.v:38$426_EN[7:0]$430 [0] $0$memwr$\memory$attributes_test.v:38$426_EN[7:0]$430 [0] $0$memwr$\memory$attributes_test.v:38$426_EN[7:0]$430 [0] $0$memwr$\memory$attributes_test.v:38$426_EN[7:0]$430 [0] $0$memwr$\memory$attributes_test.v:38$426_EN[7:0]$430 [0] $0$memwr$\memory$attributes_test.v:38$426_EN[7:0]$430 [0] $0$memwr$\memory$attributes_test.v:38$426_EN[7:0]$430 [0] } + Optimizing cells in module \distributed_ram. + Optimizing cells in module \distributed_ram_manual. + Consolidated identical input bits for $mux cell $procmux$453: + Old ports: A=8'00000000, B=8'11111111, Y=$0$memwr$\memory$attributes_test.v:60$433_EN[7:0]$435 + New ports: A=1'0, B=1'1, Y=$0$memwr$\memory$attributes_test.v:60$433_EN[7:0]$435 [0] + New connections: $0$memwr$\memory$attributes_test.v:60$433_EN[7:0]$435 [7:1] = { $0$memwr$\memory$attributes_test.v:60$433_EN[7:0]$435 [0] $0$memwr$\memory$attributes_test.v:60$433_EN[7:0]$435 [0] $0$memwr$\memory$attributes_test.v:60$433_EN[7:0]$435 [0] $0$memwr$\memory$attributes_test.v:60$433_EN[7:0]$435 [0] $0$memwr$\memory$attributes_test.v:60$433_EN[7:0]$435 [0] $0$memwr$\memory$attributes_test.v:60$433_EN[7:0]$435 [0] $0$memwr$\memory$attributes_test.v:60$433_EN[7:0]$435 [0] } + Optimizing cells in module \distributed_ram_manual. + Optimizing cells in module \distributed_ram_manual_syn. + Consolidated identical input bits for $mux cell $procmux$447: + Old ports: A=8'00000000, B=8'11111111, Y=$0$memwr$\memory$attributes_test.v:82$440_EN[7:0]$443 + New ports: A=1'0, B=1'1, Y=$0$memwr$\memory$attributes_test.v:82$440_EN[7:0]$443 [0] + New connections: $0$memwr$\memory$attributes_test.v:82$440_EN[7:0]$443 [7:1] = { $0$memwr$\memory$attributes_test.v:82$440_EN[7:0]$443 [0] $0$memwr$\memory$attributes_test.v:82$440_EN[7:0]$443 [0] $0$memwr$\memory$attributes_test.v:82$440_EN[7:0]$443 [0] $0$memwr$\memory$attributes_test.v:82$440_EN[7:0]$443 [0] $0$memwr$\memory$attributes_test.v:82$440_EN[7:0]$443 [0] $0$memwr$\memory$attributes_test.v:82$440_EN[7:0]$443 [0] $0$memwr$\memory$attributes_test.v:82$440_EN[7:0]$443 [0] } + Optimizing cells in module \distributed_ram_manual_syn. +Performed a total of 4 changes. + +8.6.5. Executing OPT_MERGE pass (detect identical cells). +Finding identical cells in module `\block_ram'. +Finding identical cells in module `\distributed_ram'. +Finding identical cells in module `\distributed_ram_manual'. +Finding identical cells in module `\distributed_ram_manual_syn'. +Removed a total of 0 cells. + +8.6.6. Executing OPT_RMDFF pass (remove dff with constant values). + +8.6.7. Executing OPT_CLEAN pass (remove unused cells and wires). +Finding unused cells or wires in module \block_ram.. +Finding unused cells or wires in module \distributed_ram.. +Finding unused cells or wires in module \distributed_ram_manual.. +Finding unused cells or wires in module \distributed_ram_manual_syn.. + +8.6.8. Executing OPT_EXPR pass (perform const folding). +Optimizing module block_ram. +Optimizing module distributed_ram. +Optimizing module distributed_ram_manual. +Optimizing module distributed_ram_manual_syn. + +8.6.9. Rerunning OPT passes. (Maybe there is more to do..) + +8.6.10. Executing OPT_MUXTREE pass (detect dead branches in mux trees). +Running muxtree optimizer on module \block_ram.. + Creating internal representation of mux trees. + Evaluating internal representation of mux trees. + Analyzing evaluation results. +Running muxtree optimizer on module \distributed_ram.. + Creating internal representation of mux trees. + Evaluating internal representation of mux trees. + Analyzing evaluation results. +Running muxtree optimizer on module \distributed_ram_manual.. + Creating internal representation of mux trees. + Evaluating internal representation of mux trees. + Analyzing evaluation results. +Running muxtree optimizer on module \distributed_ram_manual_syn.. + Creating internal representation of mux trees. + Evaluating internal representation of mux trees. + Analyzing evaluation results. +Removed 0 multiplexer ports. + + +8.6.11. Executing OPT_REDUCE pass (consolidate $*mux and $reduce_* inputs). + Optimizing cells in module \block_ram. + Optimizing cells in module \distributed_ram. + Optimizing cells in module \distributed_ram_manual. + Optimizing cells in module \distributed_ram_manual_syn. +Performed a total of 0 changes. + +8.6.12. Executing OPT_MERGE pass (detect identical cells). +Finding identical cells in module `\block_ram'. +Finding identical cells in module `\distributed_ram'. +Finding identical cells in module `\distributed_ram_manual'. +Finding identical cells in module `\distributed_ram_manual_syn'. +Removed a total of 0 cells. + +8.6.13. Executing OPT_RMDFF pass (remove dff with constant values). + +8.6.14. Executing OPT_CLEAN pass (remove unused cells and wires). +Finding unused cells or wires in module \block_ram.. +Finding unused cells or wires in module \distributed_ram.. +Finding unused cells or wires in module \distributed_ram_manual.. +Finding unused cells or wires in module \distributed_ram_manual_syn.. + +8.6.15. Executing OPT_EXPR pass (perform const folding). +Optimizing module block_ram. +Optimizing module distributed_ram. +Optimizing module distributed_ram_manual. +Optimizing module distributed_ram_manual_syn. + +8.6.16. Finished OPT passes. (There is nothing left to do.) + +8.7. Executing WREDUCE pass (reducing word size of cells). +Removed top 3 bits (of 4) from FF cell block_ram.$procdff$486 ($dff). +Removed top 7 bits (of 8) from FF cell distributed_ram.$procdff$482 ($dff). +Removed top 7 bits (of 8) from FF cell distributed_ram_manual.$procdff$475 ($dff). +Removed top 7 bits (of 8) from FF cell distributed_ram_manual_syn.$procdff$473 ($dff). + +8.8. Executing MEMORY_DFF pass (merging $dff cells to $memrd and $memwr). +Checking cell `$memwr$\memory$attributes_test.v:16$425' in module `\block_ram': merged $dff to cell. +Checking cell `$memwr$\memory$attributes_test.v:38$432' in module `\distributed_ram': merged $dff to cell. +Checking cell `$memwr$\memory$attributes_test.v:60$439' in module `\distributed_ram_manual': merged $dff to cell. +Checking cell `$memwr$\memory$attributes_test.v:82$446' in module `\distributed_ram_manual_syn': merged $dff to cell. + +8.9. Executing OPT_CLEAN pass (remove unused cells and wires). +Finding unused cells or wires in module \block_ram.. +Finding unused cells or wires in module \distributed_ram.. +Finding unused cells or wires in module \distributed_ram_manual.. +Finding unused cells or wires in module \distributed_ram_manual_syn.. +Removed 12 unused cells and 12 unused wires. + + +8.10. Executing MEMORY_COLLECT pass (generating $mem cells). +Collecting $memrd, $memwr and $meminit for memory `\memory' in module `\block_ram': + $memwr$\memory$attributes_test.v:16$425 ($memwr) + $memrd$\memory$attributes_test.v:17$424 ($memrd) +Collecting $memrd, $memwr and $meminit for memory `\memory' in module `\distributed_ram': + $memwr$\memory$attributes_test.v:38$432 ($memwr) + $memrd$\memory$attributes_test.v:39$431 ($memrd) +Collecting $memrd, $memwr and $meminit for memory `\memory' in module `\distributed_ram_manual': + $memwr$\memory$attributes_test.v:60$439 ($memwr) + $memrd$\memory$attributes_test.v:61$438 ($memrd) +Collecting $memrd, $memwr and $meminit for memory `\memory' in module `\distributed_ram_manual_syn': + $memwr$\memory$attributes_test.v:82$446 ($memwr) + $memrd$\memory$attributes_test.v:83$445 ($memrd) + +8.11. Executing OPT pass (performing simple optimizations). + +8.11.1. Executing OPT_EXPR pass (perform const folding). +Optimizing module block_ram. +Optimizing module distributed_ram. +Optimizing module distributed_ram_manual. +Optimizing module distributed_ram_manual_syn. + +8.11.2. Executing OPT_MERGE pass (detect identical cells). +Finding identical cells in module `\block_ram'. +Finding identical cells in module `\distributed_ram'. +Finding identical cells in module `\distributed_ram_manual'. +Finding identical cells in module `\distributed_ram_manual_syn'. +Removed a total of 0 cells. + +8.11.3. Executing OPT_RMDFF pass (remove dff with constant values). + +8.11.4. Executing OPT_CLEAN pass (remove unused cells and wires). +Finding unused cells or wires in module \block_ram.. +Finding unused cells or wires in module \distributed_ram.. +Finding unused cells or wires in module \distributed_ram_manual.. +Finding unused cells or wires in module \distributed_ram_manual_syn.. + +8.11.5. Finished fast OPT passes. + +8.12. Printing statistics. + +=== block_ram === + + Number of wires: 10 + Number of wire bits: 46 + Number of public wires: 6 + Number of public wire bits: 24 + Number of memories: 0 + Number of memory bits: 0 + Number of processes: 0 + Number of cells: 5 + $dff 1 + $mem 1 + $mux 3 + +=== distributed_ram === + + Number of wires: 10 + Number of wire bits: 58 + Number of public wires: 6 + Number of public wire bits: 30 + Number of memories: 0 + Number of memory bits: 0 + Number of processes: 0 + Number of cells: 5 + $dff 1 + $mem 1 + $mux 3 + +=== distributed_ram_manual === + + Number of wires: 10 + Number of wire bits: 58 + Number of public wires: 6 + Number of public wire bits: 30 + Number of memories: 0 + Number of memory bits: 0 + Number of processes: 0 + Number of cells: 5 + $dff 1 + $mem 1 + $mux 3 + +=== distributed_ram_manual_syn === + + Number of wires: 10 + Number of wire bits: 58 + Number of public wires: 6 + Number of public wire bits: 30 + Number of memories: 0 + Number of memory bits: 0 + Number of processes: 0 + Number of cells: 5 + $dff 1 + $mem 1 + $mux 3 + +8.13. Executing CHECK pass (checking for obvious problems). +checking module block_ram.. +checking module distributed_ram.. +checking module distributed_ram_manual.. +checking module distributed_ram_manual_syn.. +found and reported 0 problems. + +9. Executing SYNTH_XILINX pass. + +9.1. Executing Verilog-2005 frontend: /opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/cells_sim.v +Parsing Verilog input from `/opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/cells_sim.v' to AST representation. +Generating RTLIL representation for module `\VCC'. +Generating RTLIL representation for module `\GND'. +Generating RTLIL representation for module `\IBUF'. +Generating RTLIL representation for module `\IBUFG'. +Generating RTLIL representation for module `\OBUF'. +Generating RTLIL representation for module `\IOBUF'. +Generating RTLIL representation for module `\OBUFT'. +Generating RTLIL representation for module `\BUFG'. +Generating RTLIL representation for module `\BUFGCTRL'. +Generating RTLIL representation for module `\BUFHCE'. +Generating RTLIL representation for module `\INV'. +Generating RTLIL representation for module `\LUT1'. +Generating RTLIL representation for module `\LUT2'. +Generating RTLIL representation for module `\LUT3'. +Generating RTLIL representation for module `\LUT4'. +Generating RTLIL representation for module `\LUT5'. +Generating RTLIL representation for module `\LUT6'. +Generating RTLIL representation for module `\LUT6_2'. +Generating RTLIL representation for module `\MUXCY'. +Generating RTLIL representation for module `\MUXF7'. +Generating RTLIL representation for module `\MUXF8'. +Generating RTLIL representation for module `\XORCY'. +Generating RTLIL representation for module `\CARRY4'. +Generating RTLIL representation for module `\FDRE'. +Generating RTLIL representation for module `\FDSE'. +Generating RTLIL representation for module `\FDCE'. +Generating RTLIL representation for module `\FDPE'. +Generating RTLIL representation for module `\FDRE_1'. +Generating RTLIL representation for module `\FDSE_1'. +Generating RTLIL representation for module `\FDCE_1'. +Generating RTLIL representation for module `\FDPE_1'. +Generating RTLIL representation for module `\LDCE'. +Generating RTLIL representation for module `\LDPE'. +Generating RTLIL representation for module `\RAM16X1S'. +Generating RTLIL representation for module `\RAM16X1S_1'. +Generating RTLIL representation for module `\RAM32X1S'. +Generating RTLIL representation for module `\RAM32X1S_1'. +Generating RTLIL representation for module `\RAM64X1S'. +Generating RTLIL representation for module `\RAM64X1S_1'. +Generating RTLIL representation for module `\RAM128X1S'. +Generating RTLIL representation for module `\RAM128X1S_1'. +Generating RTLIL representation for module `\RAM256X1S'. +Generating RTLIL representation for module `\RAM512X1S'. +Generating RTLIL representation for module `\RAM16X2S'. +Generating RTLIL representation for module `\RAM32X2S'. +Generating RTLIL representation for module `\RAM64X2S'. +Generating RTLIL representation for module `\RAM16X4S'. +Generating RTLIL representation for module `\RAM32X4S'. +Generating RTLIL representation for module `\RAM16X8S'. +Generating RTLIL representation for module `\RAM32X8S'. +Generating RTLIL representation for module `\RAM16X1D'. +Generating RTLIL representation for module `\RAM16X1D_1'. +Generating RTLIL representation for module `\RAM32X1D'. +Generating RTLIL representation for module `\RAM32X1D_1'. +Generating RTLIL representation for module `\RAM64X1D'. +Generating RTLIL representation for module `\RAM64X1D_1'. +Generating RTLIL representation for module `\RAM128X1D'. +Generating RTLIL representation for module `\RAM256X1D'. +Generating RTLIL representation for module `\RAM32M'. +Generating RTLIL representation for module `\RAM32M16'. +Generating RTLIL representation for module `\RAM64M'. +Generating RTLIL representation for module `\RAM64M8'. +Generating RTLIL representation for module `\ROM16X1'. +Generating RTLIL representation for module `\ROM32X1'. +Generating RTLIL representation for module `\ROM64X1'. +Generating RTLIL representation for module `\ROM128X1'. +Generating RTLIL representation for module `\ROM256X1'. +Generating RTLIL representation for module `\SRL16E'. +Generating RTLIL representation for module `\SRLC16E'. +Generating RTLIL representation for module `\SRLC32E'. +Generating RTLIL representation for module `\MULT18X18'. +Generating RTLIL representation for module `\MULT18X18S'. +Generating RTLIL representation for module `\MULT18X18SIO'. +Generating RTLIL representation for module `\DSP48A'. +Generating RTLIL representation for module `\DSP48A1'. +Generating RTLIL representation for module `\DSP48E1'. +Successfully finished Verilog frontend. + +9.2. Executing Verilog-2005 frontend: /opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/cells_xtra.v +Parsing Verilog input from `/opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/cells_xtra.v' to AST representation. +Generating RTLIL representation for module `\FDCPE'. +Generating RTLIL representation for module `\FDRSE'. +Generating RTLIL representation for module `\LDCPE'. +Generating RTLIL representation for module `\AND2B1L'. +Generating RTLIL representation for module `\OR2L'. +Generating RTLIL representation for module `\MUXF5'. +Generating RTLIL representation for module `\MUXF6'. +Generating RTLIL representation for module `\MUXF9'. +Generating RTLIL representation for module `\CARRY8'. +Generating RTLIL representation for module `\ORCY'. +Generating RTLIL representation for module `\MULT_AND'. +Generating RTLIL representation for module `\SRL16'. +Generating RTLIL representation for module `\SRLC16'. +Generating RTLIL representation for module `\CFGLUT5'. +Generating RTLIL representation for module `\RAMB16_S1'. +Generating RTLIL representation for module `\RAMB16_S2'. +Generating RTLIL representation for module `\RAMB16_S4'. +Generating RTLIL representation for module `\RAMB16_S9'. +Generating RTLIL representation for module `\RAMB16_S18'. +Generating RTLIL representation for module `\RAMB16_S36'. +Generating RTLIL representation for module `\RAMB16_S1_S1'. +Generating RTLIL representation for module `\RAMB16_S1_S2'. +Generating RTLIL representation for module `\RAMB16_S1_S4'. +Generating RTLIL representation for module `\RAMB16_S1_S9'. +Generating RTLIL representation for module `\RAMB16_S1_S18'. +Generating RTLIL representation for module `\RAMB16_S1_S36'. +Generating RTLIL representation for module `\RAMB16_S2_S2'. +Generating RTLIL representation for module `\RAMB16_S2_S4'. +Generating RTLIL representation for module `\RAMB16_S2_S9'. +Generating RTLIL representation for module `\RAMB16_S2_S18'. +Generating RTLIL representation for module `\RAMB16_S2_S36'. +Generating RTLIL representation for module `\RAMB16_S4_S4'. +Generating RTLIL representation for module `\RAMB16_S4_S9'. +Generating RTLIL representation for module `\RAMB16_S4_S18'. +Generating RTLIL representation for module `\RAMB16_S4_S36'. +Generating RTLIL representation for module `\RAMB16_S9_S9'. +Generating RTLIL representation for module `\RAMB16_S9_S18'. +Generating RTLIL representation for module `\RAMB16_S9_S36'. +Generating RTLIL representation for module `\RAMB16_S18_S18'. +Generating RTLIL representation for module `\RAMB16_S18_S36'. +Generating RTLIL representation for module `\RAMB16_S36_S36'. +Generating RTLIL representation for module `\RAMB16BWE_S18'. +Generating RTLIL representation for module `\RAMB16BWE_S36'. +Generating RTLIL representation for module `\RAMB16BWE_S18_S9'. +Generating RTLIL representation for module `\RAMB16BWE_S18_S18'. +Generating RTLIL representation for module `\RAMB16BWE_S36_S9'. +Generating RTLIL representation for module `\RAMB16BWE_S36_S18'. +Generating RTLIL representation for module `\RAMB16BWE_S36_S36'. +Generating RTLIL representation for module `\RAMB16BWER'. +Generating RTLIL representation for module `\RAMB8BWER'. +Generating RTLIL representation for module `\FIFO16'. +Generating RTLIL representation for module `\RAMB16'. +Generating RTLIL representation for module `\RAMB32_S64_ECC'. +Generating RTLIL representation for module `\FIFO18'. +Generating RTLIL representation for module `\FIFO18_36'. +Generating RTLIL representation for module `\FIFO36'. +Generating RTLIL representation for module `\FIFO36_72'. +Generating RTLIL representation for module `\RAMB18'. +Generating RTLIL representation for module `\RAMB36'. +Generating RTLIL representation for module `\RAMB18SDP'. +Generating RTLIL representation for module `\RAMB36SDP'. +Generating RTLIL representation for module `\FIFO18E1'. +Generating RTLIL representation for module `\FIFO36E1'. +Generating RTLIL representation for module `\RAMB18E1'. +Generating RTLIL representation for module `\RAMB36E1'. +Generating RTLIL representation for module `\FIFO18E2'. +Generating RTLIL representation for module `\FIFO36E2'. +Generating RTLIL representation for module `\RAMB18E2'. +Generating RTLIL representation for module `\RAMB36E2'. +Generating RTLIL representation for module `\URAM288'. +Generating RTLIL representation for module `\URAM288_BASE'. +Generating RTLIL representation for module `\DSP48'. +Generating RTLIL representation for module `\DSP48E'. +Generating RTLIL representation for module `\DSP48E2'. +Generating RTLIL representation for module `\IFDDRCPE'. +Generating RTLIL representation for module `\IFDDRRSE'. +Generating RTLIL representation for module `\OFDDRCPE'. +Generating RTLIL representation for module `\OFDDRRSE'. +Generating RTLIL representation for module `\OFDDRTCPE'. +Generating RTLIL representation for module `\OFDDRTRSE'. +Generating RTLIL representation for module `\IDDR2'. +Generating RTLIL representation for module `\ODDR2'. +Generating RTLIL representation for module `\IDDR'. +Generating RTLIL representation for module `\IDDR_2CLK'. +Generating RTLIL representation for module `\ODDR'. +Generating RTLIL representation for module `\IDELAYCTRL'. +Generating RTLIL representation for module `\IDELAY'. +Generating RTLIL representation for module `\ISERDES'. +Generating RTLIL representation for module `\OSERDES'. +Generating RTLIL representation for module `\IODELAY'. +Generating RTLIL representation for module `\ISERDES_NODELAY'. +Generating RTLIL representation for module `\IODELAYE1'. +Generating RTLIL representation for module `\ISERDESE1'. +Generating RTLIL representation for module `\OSERDESE1'. +Generating RTLIL representation for module `\IDELAYE2'. +Generating RTLIL representation for module `\ODELAYE2'. +Generating RTLIL representation for module `\ISERDESE2'. +Generating RTLIL representation for module `\OSERDESE2'. +Generating RTLIL representation for module `\PHASER_IN'. +Generating RTLIL representation for module `\PHASER_IN_PHY'. +Generating RTLIL representation for module `\PHASER_OUT'. +Generating RTLIL representation for module `\PHASER_OUT_PHY'. +Generating RTLIL representation for module `\PHASER_REF'. +Generating RTLIL representation for module `\PHY_CONTROL'. +Generating RTLIL representation for module `\IDDRE1'. +Generating RTLIL representation for module `\ODDRE1'. +Generating RTLIL representation for module `\IDELAYE3'. +Generating RTLIL representation for module `\ODELAYE3'. +Generating RTLIL representation for module `\ISERDESE3'. +Generating RTLIL representation for module `\OSERDESE3'. +Generating RTLIL representation for module `\BITSLICE_CONTROL'. +Generating RTLIL representation for module `\RIU_OR'. +Generating RTLIL representation for module `\RX_BITSLICE'. +Generating RTLIL representation for module `\RXTX_BITSLICE'. +Generating RTLIL representation for module `\TX_BITSLICE'. +Generating RTLIL representation for module `\TX_BITSLICE_TRI'. +Generating RTLIL representation for module `\IODELAY2'. +Generating RTLIL representation for module `\IODRP2'. +Generating RTLIL representation for module `\IODRP2_MCB'. +Generating RTLIL representation for module `\ISERDES2'. +Generating RTLIL representation for module `\OSERDES2'. +Generating RTLIL representation for module `\IBUF_DLY_ADJ'. +Generating RTLIL representation for module `\IBUF_IBUFDISABLE'. +Generating RTLIL representation for module `\IBUF_INTERMDISABLE'. +Generating RTLIL representation for module `\IBUF_ANALOG'. +Generating RTLIL representation for module `\IBUFE3'. +Generating RTLIL representation for module `\IBUFDS'. +Generating RTLIL representation for module `\IBUFDS_DLY_ADJ'. +Generating RTLIL representation for module `\IBUFDS_IBUFDISABLE'. +Generating RTLIL representation for module `\IBUFDS_INTERMDISABLE'. +Generating RTLIL representation for module `\IBUFDS_DIFF_OUT'. +Generating RTLIL representation for module `\IBUFDS_DIFF_OUT_IBUFDISABLE'. +Generating RTLIL representation for module `\IBUFDS_DIFF_OUT_INTERMDISABLE'. +Generating RTLIL representation for module `\IBUFDSE3'. +Generating RTLIL representation for module `\IBUFDS_DPHY'. +Generating RTLIL representation for module `\IBUFGDS'. +Generating RTLIL representation for module `\IBUFGDS_DIFF_OUT'. +Generating RTLIL representation for module `\IOBUF_DCIEN'. +Generating RTLIL representation for module `\IOBUF_INTERMDISABLE'. +Generating RTLIL representation for module `\IOBUFE3'. +Generating RTLIL representation for module `\IOBUFDS'. +Generating RTLIL representation for module `\IOBUFDS_DCIEN'. +Generating RTLIL representation for module `\IOBUFDS_INTERMDISABLE'. +Generating RTLIL representation for module `\IOBUFDS_DIFF_OUT'. +Generating RTLIL representation for module `\IOBUFDS_DIFF_OUT_DCIEN'. +Generating RTLIL representation for module `\IOBUFDS_DIFF_OUT_INTERMDISABLE'. +Generating RTLIL representation for module `\IOBUFDSE3'. +Generating RTLIL representation for module `\OBUFDS'. +Generating RTLIL representation for module `\OBUFDS_DPHY'. +Generating RTLIL representation for module `\OBUFTDS'. +Generating RTLIL representation for module `\KEEPER'. +Generating RTLIL representation for module `\PULLDOWN'. +Generating RTLIL representation for module `\PULLUP'. +Generating RTLIL representation for module `\DCIRESET'. +Generating RTLIL representation for module `\HPIO_VREF'. +Generating RTLIL representation for module `\BUFGCE'. +Generating RTLIL representation for module `\BUFGCE_1'. +Generating RTLIL representation for module `\BUFGMUX'. +Generating RTLIL representation for module `\BUFGMUX_1'. +Generating RTLIL representation for module `\BUFGMUX_CTRL'. +Generating RTLIL representation for module `\BUFGMUX_VIRTEX4'. +Generating RTLIL representation for module `\BUFG_GT'. +Generating RTLIL representation for module `\BUFG_GT_SYNC'. +Generating RTLIL representation for module `\BUFG_PS'. +Generating RTLIL representation for module `\BUFGCE_DIV'. +Generating RTLIL representation for module `\BUFH'. +Generating RTLIL representation for module `\BUFIO2'. +Generating RTLIL representation for module `\BUFIO2_2CLK'. +Generating RTLIL representation for module `\BUFIO2FB'. +Generating RTLIL representation for module `\BUFPLL'. +Generating RTLIL representation for module `\BUFPLL_MCB'. +Generating RTLIL representation for module `\BUFIO'. +Generating RTLIL representation for module `\BUFIODQS'. +Generating RTLIL representation for module `\BUFR'. +Generating RTLIL representation for module `\BUFMR'. +Generating RTLIL representation for module `\BUFMRCE'. +Generating RTLIL representation for module `\DCM'. +Generating RTLIL representation for module `\DCM_SP'. +Generating RTLIL representation for module `\DCM_CLKGEN'. +Generating RTLIL representation for module `\DCM_ADV'. +Generating RTLIL representation for module `\DCM_BASE'. +Generating RTLIL representation for module `\DCM_PS'. +Generating RTLIL representation for module `\PMCD'. +Generating RTLIL representation for module `\PLL_ADV'. +Generating RTLIL representation for module `\PLL_BASE'. +Generating RTLIL representation for module `\MMCM_ADV'. +Generating RTLIL representation for module `\MMCM_BASE'. +Generating RTLIL representation for module `\MMCME2_ADV'. +Generating RTLIL representation for module `\MMCME2_BASE'. +Generating RTLIL representation for module `\PLLE2_ADV'. +Generating RTLIL representation for module `\PLLE2_BASE'. +Generating RTLIL representation for module `\MMCME3_ADV'. +Generating RTLIL representation for module `\MMCME3_BASE'. +Generating RTLIL representation for module `\PLLE3_ADV'. +Generating RTLIL representation for module `\PLLE3_BASE'. +Generating RTLIL representation for module `\MMCME4_ADV'. +Generating RTLIL representation for module `\MMCME4_BASE'. +Generating RTLIL representation for module `\PLLE4_ADV'. +Generating RTLIL representation for module `\PLLE4_BASE'. +Generating RTLIL representation for module `\BUFT'. +Generating RTLIL representation for module `\IN_FIFO'. +Generating RTLIL representation for module `\OUT_FIFO'. +Generating RTLIL representation for module `\HARD_SYNC'. +Generating RTLIL representation for module `\STARTUP_SPARTAN3'. +Generating RTLIL representation for module `\STARTUP_SPARTAN3E'. +Generating RTLIL representation for module `\STARTUP_SPARTAN3A'. +Generating RTLIL representation for module `\STARTUP_SPARTAN6'. +Generating RTLIL representation for module `\STARTUP_VIRTEX4'. +Generating RTLIL representation for module `\STARTUP_VIRTEX5'. +Generating RTLIL representation for module `\STARTUP_VIRTEX6'. +Generating RTLIL representation for module `\STARTUPE2'. +Generating RTLIL representation for module `\STARTUPE3'. +Generating RTLIL representation for module `\CAPTURE_SPARTAN3'. +Generating RTLIL representation for module `\CAPTURE_SPARTAN3A'. +Generating RTLIL representation for module `\CAPTURE_VIRTEX4'. +Generating RTLIL representation for module `\CAPTURE_VIRTEX5'. +Generating RTLIL representation for module `\CAPTURE_VIRTEX6'. +Generating RTLIL representation for module `\CAPTUREE2'. +Generating RTLIL representation for module `\ICAP_SPARTAN3A'. +Generating RTLIL representation for module `\ICAP_SPARTAN6'. +Generating RTLIL representation for module `\ICAP_VIRTEX4'. +Generating RTLIL representation for module `\ICAP_VIRTEX5'. +Generating RTLIL representation for module `\ICAP_VIRTEX6'. +Generating RTLIL representation for module `\ICAPE2'. +Generating RTLIL representation for module `\ICAPE3'. +Generating RTLIL representation for module `\BSCAN_SPARTAN3'. +Generating RTLIL representation for module `\BSCAN_SPARTAN3A'. +Generating RTLIL representation for module `\BSCAN_SPARTAN6'. +Generating RTLIL representation for module `\BSCAN_VIRTEX4'. +Generating RTLIL representation for module `\BSCAN_VIRTEX5'. +Generating RTLIL representation for module `\BSCAN_VIRTEX6'. +Generating RTLIL representation for module `\BSCANE2'. +Generating RTLIL representation for module `\DNA_PORT'. +Generating RTLIL representation for module `\DNA_PORTE2'. +Generating RTLIL representation for module `\FRAME_ECC_VIRTEX4'. +Generating RTLIL representation for module `\FRAME_ECC_VIRTEX5'. +Generating RTLIL representation for module `\FRAME_ECC_VIRTEX6'. +Generating RTLIL representation for module `\FRAME_ECCE2'. +Generating RTLIL representation for module `\FRAME_ECCE3'. +Generating RTLIL representation for module `\USR_ACCESS_VIRTEX4'. +Generating RTLIL representation for module `\USR_ACCESS_VIRTEX5'. +Generating RTLIL representation for module `\USR_ACCESS_VIRTEX6'. +Generating RTLIL representation for module `\USR_ACCESSE2'. +Generating RTLIL representation for module `\POST_CRC_INTERNAL'. +Generating RTLIL representation for module `\SUSPEND_SYNC'. +Generating RTLIL representation for module `\KEY_CLEAR'. +Generating RTLIL representation for module `\MASTER_JTAG'. +Generating RTLIL representation for module `\SPI_ACCESS'. +Generating RTLIL representation for module `\EFUSE_USR'. +Generating RTLIL representation for module `\SYSMON'. +Generating RTLIL representation for module `\XADC'. +Generating RTLIL representation for module `\SYSMONE1'. +Generating RTLIL representation for module `\SYSMONE4'. +Generating RTLIL representation for module `\GTPA1_DUAL'. +Generating RTLIL representation for module `\GT11_CUSTOM'. +Generating RTLIL representation for module `\GT11_DUAL'. +Generating RTLIL representation for module `\GT11CLK'. +Generating RTLIL representation for module `\GT11CLK_MGT'. +Generating RTLIL representation for module `\GTP_DUAL'. +Generating RTLIL representation for module `\GTX_DUAL'. +Generating RTLIL representation for module `\CRC32'. +Generating RTLIL representation for module `\CRC64'. +Generating RTLIL representation for module `\GTHE1_QUAD'. +Generating RTLIL representation for module `\GTXE1'. +Generating RTLIL representation for module `\IBUFDS_GTXE1'. +Generating RTLIL representation for module `\IBUFDS_GTHE1'. +Generating RTLIL representation for module `\GTHE2_CHANNEL'. +Generating RTLIL representation for module `\GTHE2_COMMON'. +Generating RTLIL representation for module `\GTPE2_CHANNEL'. +Generating RTLIL representation for module `\GTPE2_COMMON'. +Generating RTLIL representation for module `\GTXE2_CHANNEL'. +Generating RTLIL representation for module `\GTXE2_COMMON'. +Generating RTLIL representation for module `\IBUFDS_GTE2'. +Generating RTLIL representation for module `\GTHE3_CHANNEL'. +Generating RTLIL representation for module `\GTHE3_COMMON'. +Generating RTLIL representation for module `\GTHE4_CHANNEL'. +Generating RTLIL representation for module `\GTHE4_COMMON'. +Generating RTLIL representation for module `\GTYE3_CHANNEL'. +Generating RTLIL representation for module `\GTYE3_COMMON'. +Generating RTLIL representation for module `\GTYE4_CHANNEL'. +Generating RTLIL representation for module `\GTYE4_COMMON'. +Generating RTLIL representation for module `\IBUFDS_GTE3'. +Generating RTLIL representation for module `\IBUFDS_GTE4'. +Generating RTLIL representation for module `\OBUFDS_GTE3'. +Generating RTLIL representation for module `\OBUFDS_GTE3_ADV'. +Generating RTLIL representation for module `\OBUFDS_GTE4'. +Generating RTLIL representation for module `\OBUFDS_GTE4_ADV'. +Generating RTLIL representation for module `\PCIE_A1'. +Generating RTLIL representation for module `\PCIE_EP'. +Generating RTLIL representation for module `\PCIE_2_0'. +Generating RTLIL representation for module `\PCIE_2_1'. +Generating RTLIL representation for module `\PCIE_3_0'. +Generating RTLIL representation for module `\PCIE_3_1'. +Generating RTLIL representation for module `\PCIE40E4'. +Generating RTLIL representation for module `\EMAC'. +Generating RTLIL representation for module `\TEMAC'. +Generating RTLIL representation for module `\TEMAC_SINGLE'. +Generating RTLIL representation for module `\CMAC'. +Generating RTLIL representation for module `\CMACE4'. +Generating RTLIL representation for module `\PPC405_ADV'. +Generating RTLIL representation for module `\PPC440'. +Generating RTLIL representation for module `\MCB'. +Generating RTLIL representation for module `\PS7'. +Generating RTLIL representation for module `\PS8'. +Generating RTLIL representation for module `\ILKN'. +Generating RTLIL representation for module `\ILKNE4'. +Successfully finished Verilog frontend. + +9.3. Executing HIERARCHY pass (managing design hierarchy). + +9.3.1. Analyzing design hierarchy.. +Top module: \block_ram + +9.3.2. Analyzing design hierarchy.. +Top module: \block_ram +Removing unused module `\distributed_ram'. +Removing unused module `\distributed_ram_manual'. +Removing unused module `\distributed_ram_manual_syn'. +Removed 3 unused modules. + +9.4. Executing PROC pass (convert processes to netlists). + +9.4.1. Executing PROC_CLEAN pass (remove empty switches from decision trees). +Cleaned up 0 empty switches. + +9.4.2. Executing PROC_RMDEAD pass (remove dead branches from decision trees). +Removed a total of 0 dead cases. + +9.4.3. Executing PROC_PRUNE pass (remove redundant assignments in processes). +Removed 0 redundant assignments. +Promoted 0 assignments to connections. + +9.4.4. Executing PROC_INIT pass (extract init attributes). + +9.4.5. Executing PROC_ARST pass (detect async resets in processes). + +9.4.6. Executing PROC_MUX pass (convert decision trees to multiplexers). + +9.4.7. Executing PROC_DLATCH pass (convert process syncs to latches). + +9.4.8. Executing PROC_DFF pass (convert process syncs to FFs). + +9.4.9. Executing PROC_CLEAN pass (remove empty switches from decision trees). +Cleaned up 0 empty switches. + +9.5. Executing TRIBUF pass. + +9.6. Executing DEMINOUT pass (demote inout ports to input or output). + +9.7. Executing OPT_EXPR pass (perform const folding). +Optimizing module block_ram. + +9.8. Executing OPT_CLEAN pass (remove unused cells and wires). +Finding unused cells or wires in module \block_ram.. + +9.9. Executing CHECK pass (checking for obvious problems). +checking module block_ram.. +found and reported 0 problems. + +9.10. Executing OPT pass (performing simple optimizations). + +9.10.1. Executing OPT_EXPR pass (perform const folding). +Optimizing module block_ram. + +9.10.2. Executing OPT_MERGE pass (detect identical cells). +Finding identical cells in module `\block_ram'. +Removed a total of 0 cells. + +9.10.3. Executing OPT_MUXTREE pass (detect dead branches in mux trees). +Running muxtree optimizer on module \block_ram.. + Creating internal representation of mux trees. + Evaluating internal representation of mux trees. + Analyzing evaluation results. +Removed 0 multiplexer ports. + + +9.10.4. Executing OPT_REDUCE pass (consolidate $*mux and $reduce_* inputs). + Optimizing cells in module \block_ram. +Performed a total of 0 changes. + +9.10.5. Executing OPT_MERGE pass (detect identical cells). +Finding identical cells in module `\block_ram'. +Removed a total of 0 cells. + +9.10.6. Executing OPT_RMDFF pass (remove dff with constant values). + +9.10.7. Executing OPT_CLEAN pass (remove unused cells and wires). +Finding unused cells or wires in module \block_ram.. + +9.10.8. Executing OPT_EXPR pass (perform const folding). +Optimizing module block_ram. + +9.10.9. Finished OPT passes. (There is nothing left to do.) + +9.11. Executing WREDUCE pass (reducing word size of cells). +Removed cell block_ram.$procmux$469 ($mux). +Removed cell block_ram.$procmux$467 ($mux). + +9.12. Executing PEEPOPT pass (run peephole optimizers). + +9.13. Executing OPT_CLEAN pass (remove unused cells and wires). +Finding unused cells or wires in module \block_ram.. +Removed 0 unused cells and 2 unused wires. + + +9.14. Executing PMUX2SHIFTX pass. + +9.15. Executing TECHMAP pass (map to technology primitives). + +9.15.1. Executing Verilog-2005 frontend: /opt/eda/fpga/FOSS/memattr/yosys_release/share/cmp2lut.v +Parsing Verilog input from `/opt/eda/fpga/FOSS/memattr/yosys_release/share/cmp2lut.v' to AST representation. +Generating RTLIL representation for module `\_90_lut_cmp_'. +Successfully finished Verilog frontend. + +9.15.2. Continuing TECHMAP pass. +No more expansions possible. + +9.16. Executing MEMORY_DFF pass (merging $dff cells to $memrd and $memwr). + +9.17. Executing TECHMAP pass (map to technology primitives). + +9.17.1. Executing Verilog-2005 frontend: /opt/eda/fpga/FOSS/memattr/yosys_release/share/mul2dsp.v +Parsing Verilog input from `/opt/eda/fpga/FOSS/memattr/yosys_release/share/mul2dsp.v' to AST representation. +Generating RTLIL representation for module `\_80_mul'. +Generating RTLIL representation for module `\_90_soft_mul'. +Successfully finished Verilog frontend. + +9.17.2. Executing Verilog-2005 frontend: /opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/xc7_dsp_map.v +Parsing Verilog input from `/opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/xc7_dsp_map.v' to AST representation. +Generating RTLIL representation for module `\$__MUL25X18'. +Successfully finished Verilog frontend. + +9.17.3. Continuing TECHMAP pass. +No more expansions possible. + +9.18. Executing OPT_EXPR pass (perform const folding). + +9.19. Executing WREDUCE pass (reducing word size of cells). + +9.20. Executing XILINX_DSP pass (pack resources into DSPs). + +9.21. Executing ALUMACC pass (create $alu and $macc cells). +Extracting $alu and $macc cells in module block_ram: + created 0 $alu and 0 $macc cells. + +9.22. Executing SHARE pass (SAT-based resource sharing). -- cgit v1.2.3 From f3f59910eb06bf74a2a4b8157797a327dd097451 Mon Sep 17 00:00:00 2001 From: Diego H Date: Sun, 15 Dec 2019 23:51:58 -0600 Subject: Removing fixed attribute value to !ramstyle rules --- techlibs/xilinx/xc7_xcu_brams.txt | 8 +- tests/arch/common/memory_attributes/log | 3238 ------------------------------- 2 files changed, 4 insertions(+), 3242 deletions(-) delete mode 100644 tests/arch/common/memory_attributes/log diff --git a/techlibs/xilinx/xc7_xcu_brams.txt b/techlibs/xilinx/xc7_xcu_brams.txt index 2d94ac4a8..1374a0a36 100644 --- a/techlibs/xilinx/xc7_xcu_brams.txt +++ b/techlibs/xilinx/xc7_xcu_brams.txt @@ -78,7 +78,7 @@ endbram match $__XILINX_RAMB36_SDP attribute ram_style=block ram_block=1 - attribute !ram_style=distributed + attribute !ram_style attribute !logic_block min bits 1024 min efficiency 5 @@ -89,7 +89,7 @@ endmatch match $__XILINX_RAMB18_SDP attribute ram_style=block ram_block=1 - attribute !ram_style=distributed + attribute !ram_style attribute !logic_block min bits 1024 min efficiency 5 @@ -100,7 +100,7 @@ endmatch match $__XILINX_RAMB36_TDP attribute ram_style=block ram_block=1 - attribute !ram_style=distributed + attribute !ram_style attribute !logic_block min bits 1024 min efficiency 5 @@ -111,7 +111,7 @@ endmatch match $__XILINX_RAMB18_TDP attribute ram_style=block ram_block=1 - attribute !ram_style=distributed + attribute !ram_style attribute !logic_block min bits 1024 min efficiency 5 diff --git a/tests/arch/common/memory_attributes/log b/tests/arch/common/memory_attributes/log deleted file mode 100644 index 5d526e661..000000000 --- a/tests/arch/common/memory_attributes/log +++ /dev/null @@ -1,3238 +0,0 @@ - - /----------------------------------------------------------------------------\ - | | - | yosys -- Yosys Open SYnthesis Suite | - | | - | Copyright (C) 2012 - 2019 Clifford Wolf | - | | - | 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. | - | | - \----------------------------------------------------------------------------/ - - Yosys 0.9+932 (git sha1 26699340, clang 6.0.0-1ubuntu2 -fPIC -Os) - - --- Executing script file `attributes_test.ys' -- - -1. Executing Verilog-2005 frontend: attributes_test.v -Parsing Verilog input from `attributes_test.v' to AST representation. -Generating RTLIL representation for module `\block_ram'. -Generating RTLIL representation for module `\distributed_ram'. -Generating RTLIL representation for module `\distributed_ram_manual'. -Generating RTLIL representation for module `\distributed_ram_manual_syn'. -Successfully finished Verilog frontend. - -2. Executing HIERARCHY pass (managing design hierarchy). - -2.1. Analyzing design hierarchy.. -Top module: \block_ram - -2.2. Analyzing design hierarchy.. -Top module: \block_ram -Removing unused module `\distributed_ram_manual_syn'. -Removing unused module `\distributed_ram_manual'. -Removing unused module `\distributed_ram'. -Removed 3 unused modules. - -3. Executing SYNTH_XILINX pass. - -3.1. Executing Verilog-2005 frontend: /opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/cells_sim.v -Parsing Verilog input from `/opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/cells_sim.v' to AST representation. -Generating RTLIL representation for module `\VCC'. -Generating RTLIL representation for module `\GND'. -Generating RTLIL representation for module `\IBUF'. -Generating RTLIL representation for module `\IBUFG'. -Generating RTLIL representation for module `\OBUF'. -Generating RTLIL representation for module `\IOBUF'. -Generating RTLIL representation for module `\OBUFT'. -Generating RTLIL representation for module `\BUFG'. -Generating RTLIL representation for module `\BUFGCTRL'. -Generating RTLIL representation for module `\BUFHCE'. -Generating RTLIL representation for module `\INV'. -Generating RTLIL representation for module `\LUT1'. -Generating RTLIL representation for module `\LUT2'. -Generating RTLIL representation for module `\LUT3'. -Generating RTLIL representation for module `\LUT4'. -Generating RTLIL representation for module `\LUT5'. -Generating RTLIL representation for module `\LUT6'. -Generating RTLIL representation for module `\LUT6_2'. -Generating RTLIL representation for module `\MUXCY'. -Generating RTLIL representation for module `\MUXF7'. -Generating RTLIL representation for module `\MUXF8'. -Generating RTLIL representation for module `\XORCY'. -Generating RTLIL representation for module `\CARRY4'. -Generating RTLIL representation for module `\FDRE'. -Generating RTLIL representation for module `\FDSE'. -Generating RTLIL representation for module `\FDCE'. -Generating RTLIL representation for module `\FDPE'. -Generating RTLIL representation for module `\FDRE_1'. -Generating RTLIL representation for module `\FDSE_1'. -Generating RTLIL representation for module `\FDCE_1'. -Generating RTLIL representation for module `\FDPE_1'. -Generating RTLIL representation for module `\LDCE'. -Generating RTLIL representation for module `\LDPE'. -Generating RTLIL representation for module `\RAM16X1S'. -Generating RTLIL representation for module `\RAM16X1S_1'. -Generating RTLIL representation for module `\RAM32X1S'. -Generating RTLIL representation for module `\RAM32X1S_1'. -Generating RTLIL representation for module `\RAM64X1S'. -Generating RTLIL representation for module `\RAM64X1S_1'. -Generating RTLIL representation for module `\RAM128X1S'. -Generating RTLIL representation for module `\RAM128X1S_1'. -Generating RTLIL representation for module `\RAM256X1S'. -Generating RTLIL representation for module `\RAM512X1S'. -Generating RTLIL representation for module `\RAM16X2S'. -Generating RTLIL representation for module `\RAM32X2S'. -Generating RTLIL representation for module `\RAM64X2S'. -Generating RTLIL representation for module `\RAM16X4S'. -Generating RTLIL representation for module `\RAM32X4S'. -Generating RTLIL representation for module `\RAM16X8S'. -Generating RTLIL representation for module `\RAM32X8S'. -Generating RTLIL representation for module `\RAM16X1D'. -Generating RTLIL representation for module `\RAM16X1D_1'. -Generating RTLIL representation for module `\RAM32X1D'. -Generating RTLIL representation for module `\RAM32X1D_1'. -Generating RTLIL representation for module `\RAM64X1D'. -Generating RTLIL representation for module `\RAM64X1D_1'. -Generating RTLIL representation for module `\RAM128X1D'. -Generating RTLIL representation for module `\RAM256X1D'. -Generating RTLIL representation for module `\RAM32M'. -Generating RTLIL representation for module `\RAM32M16'. -Generating RTLIL representation for module `\RAM64M'. -Generating RTLIL representation for module `\RAM64M8'. -Generating RTLIL representation for module `\ROM16X1'. -Generating RTLIL representation for module `\ROM32X1'. -Generating RTLIL representation for module `\ROM64X1'. -Generating RTLIL representation for module `\ROM128X1'. -Generating RTLIL representation for module `\ROM256X1'. -Generating RTLIL representation for module `\SRL16E'. -Generating RTLIL representation for module `\SRLC16E'. -Generating RTLIL representation for module `\SRLC32E'. -Generating RTLIL representation for module `\MULT18X18'. -Generating RTLIL representation for module `\MULT18X18S'. -Generating RTLIL representation for module `\MULT18X18SIO'. -Generating RTLIL representation for module `\DSP48A'. -Generating RTLIL representation for module `\DSP48A1'. -Generating RTLIL representation for module `\DSP48E1'. -Successfully finished Verilog frontend. - -3.2. Executing Verilog-2005 frontend: /opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/cells_xtra.v -Parsing Verilog input from `/opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/cells_xtra.v' to AST representation. -Generating RTLIL representation for module `\FDCPE'. -Generating RTLIL representation for module `\FDRSE'. -Generating RTLIL representation for module `\LDCPE'. -Generating RTLIL representation for module `\AND2B1L'. -Generating RTLIL representation for module `\OR2L'. -Generating RTLIL representation for module `\MUXF5'. -Generating RTLIL representation for module `\MUXF6'. -Generating RTLIL representation for module `\MUXF9'. -Generating RTLIL representation for module `\CARRY8'. -Generating RTLIL representation for module `\ORCY'. -Generating RTLIL representation for module `\MULT_AND'. -Generating RTLIL representation for module `\SRL16'. -Generating RTLIL representation for module `\SRLC16'. -Generating RTLIL representation for module `\CFGLUT5'. -Generating RTLIL representation for module `\RAMB16_S1'. -Generating RTLIL representation for module `\RAMB16_S2'. -Generating RTLIL representation for module `\RAMB16_S4'. -Generating RTLIL representation for module `\RAMB16_S9'. -Generating RTLIL representation for module `\RAMB16_S18'. -Generating RTLIL representation for module `\RAMB16_S36'. -Generating RTLIL representation for module `\RAMB16_S1_S1'. -Generating RTLIL representation for module `\RAMB16_S1_S2'. -Generating RTLIL representation for module `\RAMB16_S1_S4'. -Generating RTLIL representation for module `\RAMB16_S1_S9'. -Generating RTLIL representation for module `\RAMB16_S1_S18'. -Generating RTLIL representation for module `\RAMB16_S1_S36'. -Generating RTLIL representation for module `\RAMB16_S2_S2'. -Generating RTLIL representation for module `\RAMB16_S2_S4'. -Generating RTLIL representation for module `\RAMB16_S2_S9'. -Generating RTLIL representation for module `\RAMB16_S2_S18'. -Generating RTLIL representation for module `\RAMB16_S2_S36'. -Generating RTLIL representation for module `\RAMB16_S4_S4'. -Generating RTLIL representation for module `\RAMB16_S4_S9'. -Generating RTLIL representation for module `\RAMB16_S4_S18'. -Generating RTLIL representation for module `\RAMB16_S4_S36'. -Generating RTLIL representation for module `\RAMB16_S9_S9'. -Generating RTLIL representation for module `\RAMB16_S9_S18'. -Generating RTLIL representation for module `\RAMB16_S9_S36'. -Generating RTLIL representation for module `\RAMB16_S18_S18'. -Generating RTLIL representation for module `\RAMB16_S18_S36'. -Generating RTLIL representation for module `\RAMB16_S36_S36'. -Generating RTLIL representation for module `\RAMB16BWE_S18'. -Generating RTLIL representation for module `\RAMB16BWE_S36'. -Generating RTLIL representation for module `\RAMB16BWE_S18_S9'. -Generating RTLIL representation for module `\RAMB16BWE_S18_S18'. -Generating RTLIL representation for module `\RAMB16BWE_S36_S9'. -Generating RTLIL representation for module `\RAMB16BWE_S36_S18'. -Generating RTLIL representation for module `\RAMB16BWE_S36_S36'. -Generating RTLIL representation for module `\RAMB16BWER'. -Generating RTLIL representation for module `\RAMB8BWER'. -Generating RTLIL representation for module `\FIFO16'. -Generating RTLIL representation for module `\RAMB16'. -Generating RTLIL representation for module `\RAMB32_S64_ECC'. -Generating RTLIL representation for module `\FIFO18'. -Generating RTLIL representation for module `\FIFO18_36'. -Generating RTLIL representation for module `\FIFO36'. -Generating RTLIL representation for module `\FIFO36_72'. -Generating RTLIL representation for module `\RAMB18'. -Generating RTLIL representation for module `\RAMB36'. -Generating RTLIL representation for module `\RAMB18SDP'. -Generating RTLIL representation for module `\RAMB36SDP'. -Generating RTLIL representation for module `\FIFO18E1'. -Generating RTLIL representation for module `\FIFO36E1'. -Generating RTLIL representation for module `\RAMB18E1'. -Generating RTLIL representation for module `\RAMB36E1'. -Generating RTLIL representation for module `\FIFO18E2'. -Generating RTLIL representation for module `\FIFO36E2'. -Generating RTLIL representation for module `\RAMB18E2'. -Generating RTLIL representation for module `\RAMB36E2'. -Generating RTLIL representation for module `\URAM288'. -Generating RTLIL representation for module `\URAM288_BASE'. -Generating RTLIL representation for module `\DSP48'. -Generating RTLIL representation for module `\DSP48E'. -Generating RTLIL representation for module `\DSP48E2'. -Generating RTLIL representation for module `\IFDDRCPE'. -Generating RTLIL representation for module `\IFDDRRSE'. -Generating RTLIL representation for module `\OFDDRCPE'. -Generating RTLIL representation for module `\OFDDRRSE'. -Generating RTLIL representation for module `\OFDDRTCPE'. -Generating RTLIL representation for module `\OFDDRTRSE'. -Generating RTLIL representation for module `\IDDR2'. -Generating RTLIL representation for module `\ODDR2'. -Generating RTLIL representation for module `\IDDR'. -Generating RTLIL representation for module `\IDDR_2CLK'. -Generating RTLIL representation for module `\ODDR'. -Generating RTLIL representation for module `\IDELAYCTRL'. -Generating RTLIL representation for module `\IDELAY'. -Generating RTLIL representation for module `\ISERDES'. -Generating RTLIL representation for module `\OSERDES'. -Generating RTLIL representation for module `\IODELAY'. -Generating RTLIL representation for module `\ISERDES_NODELAY'. -Generating RTLIL representation for module `\IODELAYE1'. -Generating RTLIL representation for module `\ISERDESE1'. -Generating RTLIL representation for module `\OSERDESE1'. -Generating RTLIL representation for module `\IDELAYE2'. -Generating RTLIL representation for module `\ODELAYE2'. -Generating RTLIL representation for module `\ISERDESE2'. -Generating RTLIL representation for module `\OSERDESE2'. -Generating RTLIL representation for module `\PHASER_IN'. -Generating RTLIL representation for module `\PHASER_IN_PHY'. -Generating RTLIL representation for module `\PHASER_OUT'. -Generating RTLIL representation for module `\PHASER_OUT_PHY'. -Generating RTLIL representation for module `\PHASER_REF'. -Generating RTLIL representation for module `\PHY_CONTROL'. -Generating RTLIL representation for module `\IDDRE1'. -Generating RTLIL representation for module `\ODDRE1'. -Generating RTLIL representation for module `\IDELAYE3'. -Generating RTLIL representation for module `\ODELAYE3'. -Generating RTLIL representation for module `\ISERDESE3'. -Generating RTLIL representation for module `\OSERDESE3'. -Generating RTLIL representation for module `\BITSLICE_CONTROL'. -Generating RTLIL representation for module `\RIU_OR'. -Generating RTLIL representation for module `\RX_BITSLICE'. -Generating RTLIL representation for module `\RXTX_BITSLICE'. -Generating RTLIL representation for module `\TX_BITSLICE'. -Generating RTLIL representation for module `\TX_BITSLICE_TRI'. -Generating RTLIL representation for module `\IODELAY2'. -Generating RTLIL representation for module `\IODRP2'. -Generating RTLIL representation for module `\IODRP2_MCB'. -Generating RTLIL representation for module `\ISERDES2'. -Generating RTLIL representation for module `\OSERDES2'. -Generating RTLIL representation for module `\IBUF_DLY_ADJ'. -Generating RTLIL representation for module `\IBUF_IBUFDISABLE'. -Generating RTLIL representation for module `\IBUF_INTERMDISABLE'. -Generating RTLIL representation for module `\IBUF_ANALOG'. -Generating RTLIL representation for module `\IBUFE3'. -Generating RTLIL representation for module `\IBUFDS'. -Generating RTLIL representation for module `\IBUFDS_DLY_ADJ'. -Generating RTLIL representation for module `\IBUFDS_IBUFDISABLE'. -Generating RTLIL representation for module `\IBUFDS_INTERMDISABLE'. -Generating RTLIL representation for module `\IBUFDS_DIFF_OUT'. -Generating RTLIL representation for module `\IBUFDS_DIFF_OUT_IBUFDISABLE'. -Generating RTLIL representation for module `\IBUFDS_DIFF_OUT_INTERMDISABLE'. -Generating RTLIL representation for module `\IBUFDSE3'. -Generating RTLIL representation for module `\IBUFDS_DPHY'. -Generating RTLIL representation for module `\IBUFGDS'. -Generating RTLIL representation for module `\IBUFGDS_DIFF_OUT'. -Generating RTLIL representation for module `\IOBUF_DCIEN'. -Generating RTLIL representation for module `\IOBUF_INTERMDISABLE'. -Generating RTLIL representation for module `\IOBUFE3'. -Generating RTLIL representation for module `\IOBUFDS'. -Generating RTLIL representation for module `\IOBUFDS_DCIEN'. -Generating RTLIL representation for module `\IOBUFDS_INTERMDISABLE'. -Generating RTLIL representation for module `\IOBUFDS_DIFF_OUT'. -Generating RTLIL representation for module `\IOBUFDS_DIFF_OUT_DCIEN'. -Generating RTLIL representation for module `\IOBUFDS_DIFF_OUT_INTERMDISABLE'. -Generating RTLIL representation for module `\IOBUFDSE3'. -Generating RTLIL representation for module `\OBUFDS'. -Generating RTLIL representation for module `\OBUFDS_DPHY'. -Generating RTLIL representation for module `\OBUFTDS'. -Generating RTLIL representation for module `\KEEPER'. -Generating RTLIL representation for module `\PULLDOWN'. -Generating RTLIL representation for module `\PULLUP'. -Generating RTLIL representation for module `\DCIRESET'. -Generating RTLIL representation for module `\HPIO_VREF'. -Generating RTLIL representation for module `\BUFGCE'. -Generating RTLIL representation for module `\BUFGCE_1'. -Generating RTLIL representation for module `\BUFGMUX'. -Generating RTLIL representation for module `\BUFGMUX_1'. -Generating RTLIL representation for module `\BUFGMUX_CTRL'. -Generating RTLIL representation for module `\BUFGMUX_VIRTEX4'. -Generating RTLIL representation for module `\BUFG_GT'. -Generating RTLIL representation for module `\BUFG_GT_SYNC'. -Generating RTLIL representation for module `\BUFG_PS'. -Generating RTLIL representation for module `\BUFGCE_DIV'. -Generating RTLIL representation for module `\BUFH'. -Generating RTLIL representation for module `\BUFIO2'. -Generating RTLIL representation for module `\BUFIO2_2CLK'. -Generating RTLIL representation for module `\BUFIO2FB'. -Generating RTLIL representation for module `\BUFPLL'. -Generating RTLIL representation for module `\BUFPLL_MCB'. -Generating RTLIL representation for module `\BUFIO'. -Generating RTLIL representation for module `\BUFIODQS'. -Generating RTLIL representation for module `\BUFR'. -Generating RTLIL representation for module `\BUFMR'. -Generating RTLIL representation for module `\BUFMRCE'. -Generating RTLIL representation for module `\DCM'. -Generating RTLIL representation for module `\DCM_SP'. -Generating RTLIL representation for module `\DCM_CLKGEN'. -Generating RTLIL representation for module `\DCM_ADV'. -Generating RTLIL representation for module `\DCM_BASE'. -Generating RTLIL representation for module `\DCM_PS'. -Generating RTLIL representation for module `\PMCD'. -Generating RTLIL representation for module `\PLL_ADV'. -Generating RTLIL representation for module `\PLL_BASE'. -Generating RTLIL representation for module `\MMCM_ADV'. -Generating RTLIL representation for module `\MMCM_BASE'. -Generating RTLIL representation for module `\MMCME2_ADV'. -Generating RTLIL representation for module `\MMCME2_BASE'. -Generating RTLIL representation for module `\PLLE2_ADV'. -Generating RTLIL representation for module `\PLLE2_BASE'. -Generating RTLIL representation for module `\MMCME3_ADV'. -Generating RTLIL representation for module `\MMCME3_BASE'. -Generating RTLIL representation for module `\PLLE3_ADV'. -Generating RTLIL representation for module `\PLLE3_BASE'. -Generating RTLIL representation for module `\MMCME4_ADV'. -Generating RTLIL representation for module `\MMCME4_BASE'. -Generating RTLIL representation for module `\PLLE4_ADV'. -Generating RTLIL representation for module `\PLLE4_BASE'. -Generating RTLIL representation for module `\BUFT'. -Generating RTLIL representation for module `\IN_FIFO'. -Generating RTLIL representation for module `\OUT_FIFO'. -Generating RTLIL representation for module `\HARD_SYNC'. -Generating RTLIL representation for module `\STARTUP_SPARTAN3'. -Generating RTLIL representation for module `\STARTUP_SPARTAN3E'. -Generating RTLIL representation for module `\STARTUP_SPARTAN3A'. -Generating RTLIL representation for module `\STARTUP_SPARTAN6'. -Generating RTLIL representation for module `\STARTUP_VIRTEX4'. -Generating RTLIL representation for module `\STARTUP_VIRTEX5'. -Generating RTLIL representation for module `\STARTUP_VIRTEX6'. -Generating RTLIL representation for module `\STARTUPE2'. -Generating RTLIL representation for module `\STARTUPE3'. -Generating RTLIL representation for module `\CAPTURE_SPARTAN3'. -Generating RTLIL representation for module `\CAPTURE_SPARTAN3A'. -Generating RTLIL representation for module `\CAPTURE_VIRTEX4'. -Generating RTLIL representation for module `\CAPTURE_VIRTEX5'. -Generating RTLIL representation for module `\CAPTURE_VIRTEX6'. -Generating RTLIL representation for module `\CAPTUREE2'. -Generating RTLIL representation for module `\ICAP_SPARTAN3A'. -Generating RTLIL representation for module `\ICAP_SPARTAN6'. -Generating RTLIL representation for module `\ICAP_VIRTEX4'. -Generating RTLIL representation for module `\ICAP_VIRTEX5'. -Generating RTLIL representation for module `\ICAP_VIRTEX6'. -Generating RTLIL representation for module `\ICAPE2'. -Generating RTLIL representation for module `\ICAPE3'. -Generating RTLIL representation for module `\BSCAN_SPARTAN3'. -Generating RTLIL representation for module `\BSCAN_SPARTAN3A'. -Generating RTLIL representation for module `\BSCAN_SPARTAN6'. -Generating RTLIL representation for module `\BSCAN_VIRTEX4'. -Generating RTLIL representation for module `\BSCAN_VIRTEX5'. -Generating RTLIL representation for module `\BSCAN_VIRTEX6'. -Generating RTLIL representation for module `\BSCANE2'. -Generating RTLIL representation for module `\DNA_PORT'. -Generating RTLIL representation for module `\DNA_PORTE2'. -Generating RTLIL representation for module `\FRAME_ECC_VIRTEX4'. -Generating RTLIL representation for module `\FRAME_ECC_VIRTEX5'. -Generating RTLIL representation for module `\FRAME_ECC_VIRTEX6'. -Generating RTLIL representation for module `\FRAME_ECCE2'. -Generating RTLIL representation for module `\FRAME_ECCE3'. -Generating RTLIL representation for module `\USR_ACCESS_VIRTEX4'. -Generating RTLIL representation for module `\USR_ACCESS_VIRTEX5'. -Generating RTLIL representation for module `\USR_ACCESS_VIRTEX6'. -Generating RTLIL representation for module `\USR_ACCESSE2'. -Generating RTLIL representation for module `\POST_CRC_INTERNAL'. -Generating RTLIL representation for module `\SUSPEND_SYNC'. -Generating RTLIL representation for module `\KEY_CLEAR'. -Generating RTLIL representation for module `\MASTER_JTAG'. -Generating RTLIL representation for module `\SPI_ACCESS'. -Generating RTLIL representation for module `\EFUSE_USR'. -Generating RTLIL representation for module `\SYSMON'. -Generating RTLIL representation for module `\XADC'. -Generating RTLIL representation for module `\SYSMONE1'. -Generating RTLIL representation for module `\SYSMONE4'. -Generating RTLIL representation for module `\GTPA1_DUAL'. -Generating RTLIL representation for module `\GT11_CUSTOM'. -Generating RTLIL representation for module `\GT11_DUAL'. -Generating RTLIL representation for module `\GT11CLK'. -Generating RTLIL representation for module `\GT11CLK_MGT'. -Generating RTLIL representation for module `\GTP_DUAL'. -Generating RTLIL representation for module `\GTX_DUAL'. -Generating RTLIL representation for module `\CRC32'. -Generating RTLIL representation for module `\CRC64'. -Generating RTLIL representation for module `\GTHE1_QUAD'. -Generating RTLIL representation for module `\GTXE1'. -Generating RTLIL representation for module `\IBUFDS_GTXE1'. -Generating RTLIL representation for module `\IBUFDS_GTHE1'. -Generating RTLIL representation for module `\GTHE2_CHANNEL'. -Generating RTLIL representation for module `\GTHE2_COMMON'. -Generating RTLIL representation for module `\GTPE2_CHANNEL'. -Generating RTLIL representation for module `\GTPE2_COMMON'. -Generating RTLIL representation for module `\GTXE2_CHANNEL'. -Generating RTLIL representation for module `\GTXE2_COMMON'. -Generating RTLIL representation for module `\IBUFDS_GTE2'. -Generating RTLIL representation for module `\GTHE3_CHANNEL'. -Generating RTLIL representation for module `\GTHE3_COMMON'. -Generating RTLIL representation for module `\GTHE4_CHANNEL'. -Generating RTLIL representation for module `\GTHE4_COMMON'. -Generating RTLIL representation for module `\GTYE3_CHANNEL'. -Generating RTLIL representation for module `\GTYE3_COMMON'. -Generating RTLIL representation for module `\GTYE4_CHANNEL'. -Generating RTLIL representation for module `\GTYE4_COMMON'. -Generating RTLIL representation for module `\IBUFDS_GTE3'. -Generating RTLIL representation for module `\IBUFDS_GTE4'. -Generating RTLIL representation for module `\OBUFDS_GTE3'. -Generating RTLIL representation for module `\OBUFDS_GTE3_ADV'. -Generating RTLIL representation for module `\OBUFDS_GTE4'. -Generating RTLIL representation for module `\OBUFDS_GTE4_ADV'. -Generating RTLIL representation for module `\PCIE_A1'. -Generating RTLIL representation for module `\PCIE_EP'. -Generating RTLIL representation for module `\PCIE_2_0'. -Generating RTLIL representation for module `\PCIE_2_1'. -Generating RTLIL representation for module `\PCIE_3_0'. -Generating RTLIL representation for module `\PCIE_3_1'. -Generating RTLIL representation for module `\PCIE40E4'. -Generating RTLIL representation for module `\EMAC'. -Generating RTLIL representation for module `\TEMAC'. -Generating RTLIL representation for module `\TEMAC_SINGLE'. -Generating RTLIL representation for module `\CMAC'. -Generating RTLIL representation for module `\CMACE4'. -Generating RTLIL representation for module `\PPC405_ADV'. -Generating RTLIL representation for module `\PPC440'. -Generating RTLIL representation for module `\MCB'. -Generating RTLIL representation for module `\PS7'. -Generating RTLIL representation for module `\PS8'. -Generating RTLIL representation for module `\ILKN'. -Generating RTLIL representation for module `\ILKNE4'. -Successfully finished Verilog frontend. - -3.3. Executing HIERARCHY pass (managing design hierarchy). - -3.3.1. Analyzing design hierarchy.. -Top module: \block_ram - -3.3.2. Analyzing design hierarchy.. -Top module: \block_ram -Removed 0 unused modules. - -3.4. Executing PROC pass (convert processes to netlists). - -3.4.1. Executing PROC_CLEAN pass (remove empty switches from decision trees). -Cleaned up 0 empty switches. - -3.4.2. Executing PROC_RMDEAD pass (remove dead branches from decision trees). -Removed a total of 0 dead cases. - -3.4.3. Executing PROC_PRUNE pass (remove redundant assignments in processes). -Removed 0 redundant assignments. -Promoted 1 assignment to connection. - -3.4.4. Executing PROC_INIT pass (extract init attributes). - -3.4.5. Executing PROC_ARST pass (detect async resets in processes). - -3.4.6. Executing PROC_MUX pass (convert decision trees to multiplexers). -Creating decoders for process `\block_ram.$proc$attributes_test.v:14$2'. - 1/3: $0$memwr$\memory$attributes_test.v:16$1_EN[3:0]$5 - 2/3: $0$memwr$\memory$attributes_test.v:16$1_DATA[3:0]$4 - 3/3: $0$memwr$\memory$attributes_test.v:16$1_ADDR[9:0]$3 - -3.4.7. Executing PROC_DLATCH pass (convert process syncs to latches). - -3.4.8. Executing PROC_DFF pass (convert process syncs to FFs). -Creating register for signal `\block_ram.\data_out_r' using process `\block_ram.$proc$attributes_test.v:14$2'. - created $dff cell `$procdff$48' with positive edge clock. -Creating register for signal `\block_ram.$memwr$\memory$attributes_test.v:16$1_ADDR' using process `\block_ram.$proc$attributes_test.v:14$2'. - created $dff cell `$procdff$49' with positive edge clock. -Creating register for signal `\block_ram.$memwr$\memory$attributes_test.v:16$1_DATA' using process `\block_ram.$proc$attributes_test.v:14$2'. - created $dff cell `$procdff$50' with positive edge clock. -Creating register for signal `\block_ram.$memwr$\memory$attributes_test.v:16$1_EN' using process `\block_ram.$proc$attributes_test.v:14$2'. - created $dff cell `$procdff$51' with positive edge clock. - -3.4.9. Executing PROC_CLEAN pass (remove empty switches from decision trees). -Found and cleaned up 1 empty switch in `\block_ram.$proc$attributes_test.v:14$2'. -Removing empty process `block_ram.$proc$attributes_test.v:14$2'. -Cleaned up 1 empty switch. - -3.5. Executing TRIBUF pass. - -3.6. Executing DEMINOUT pass (demote inout ports to input or output). - -3.7. Executing OPT_EXPR pass (perform const folding). -Optimizing module block_ram. - -3.8. Executing OPT_CLEAN pass (remove unused cells and wires). -Finding unused cells or wires in module \block_ram.. -Removed 0 unused cells and 7 unused wires. - - -3.9. Executing CHECK pass (checking for obvious problems). -checking module block_ram.. -found and reported 0 problems. - -3.10. Executing OPT pass (performing simple optimizations). - -3.10.1. Executing OPT_EXPR pass (perform const folding). -Optimizing module block_ram. - -3.10.2. Executing OPT_MERGE pass (detect identical cells). -Finding identical cells in module `\block_ram'. -Removed a total of 0 cells. - -3.10.3. Executing OPT_MUXTREE pass (detect dead branches in mux trees). -Running muxtree optimizer on module \block_ram.. - Creating internal representation of mux trees. - Evaluating internal representation of mux trees. - Analyzing evaluation results. -Removed 0 multiplexer ports. - - -3.10.4. Executing OPT_REDUCE pass (consolidate $*mux and $reduce_* inputs). - Optimizing cells in module \block_ram. - Consolidated identical input bits for $mux cell $procmux$42: - Old ports: A=4'0000, B=4'1111, Y=$0$memwr$\memory$attributes_test.v:16$1_EN[3:0]$5 - New ports: A=1'0, B=1'1, Y=$0$memwr$\memory$attributes_test.v:16$1_EN[3:0]$5 [0] - New connections: $0$memwr$\memory$attributes_test.v:16$1_EN[3:0]$5 [3:1] = { $0$memwr$\memory$attributes_test.v:16$1_EN[3:0]$5 [0] $0$memwr$\memory$attributes_test.v:16$1_EN[3:0]$5 [0] $0$memwr$\memory$attributes_test.v:16$1_EN[3:0]$5 [0] } - Optimizing cells in module \block_ram. -Performed a total of 1 changes. - -3.10.5. Executing OPT_MERGE pass (detect identical cells). -Finding identical cells in module `\block_ram'. -Removed a total of 0 cells. - -3.10.6. Executing OPT_RMDFF pass (remove dff with constant values). - -3.10.7. Executing OPT_CLEAN pass (remove unused cells and wires). -Finding unused cells or wires in module \block_ram.. - -3.10.8. Executing OPT_EXPR pass (perform const folding). -Optimizing module block_ram. - -3.10.9. Rerunning OPT passes. (Maybe there is more to do..) - -3.10.10. Executing OPT_MUXTREE pass (detect dead branches in mux trees). -Running muxtree optimizer on module \block_ram.. - Creating internal representation of mux trees. - Evaluating internal representation of mux trees. - Analyzing evaluation results. -Removed 0 multiplexer ports. - - -3.10.11. Executing OPT_REDUCE pass (consolidate $*mux and $reduce_* inputs). - Optimizing cells in module \block_ram. -Performed a total of 0 changes. - -3.10.12. Executing OPT_MERGE pass (detect identical cells). -Finding identical cells in module `\block_ram'. -Removed a total of 0 cells. - -3.10.13. Executing OPT_RMDFF pass (remove dff with constant values). - -3.10.14. Executing OPT_CLEAN pass (remove unused cells and wires). -Finding unused cells or wires in module \block_ram.. - -3.10.15. Executing OPT_EXPR pass (perform const folding). -Optimizing module block_ram. - -3.10.16. Finished OPT passes. (There is nothing left to do.) - -3.11. Executing WREDUCE pass (reducing word size of cells). -Removed cell block_ram.$procmux$44 ($mux). -Removed cell block_ram.$procmux$46 ($mux). -Removed top 3 bits (of 4) from FF cell block_ram.$procdff$51 ($dff). - -3.12. Executing PEEPOPT pass (run peephole optimizers). - -3.13. Executing OPT_CLEAN pass (remove unused cells and wires). -Finding unused cells or wires in module \block_ram.. -Removed 0 unused cells and 2 unused wires. - - -3.14. Executing PMUX2SHIFTX pass. - -3.15. Executing TECHMAP pass (map to technology primitives). - -3.15.1. Executing Verilog-2005 frontend: /opt/eda/fpga/FOSS/memattr/yosys_release/share/cmp2lut.v -Parsing Verilog input from `/opt/eda/fpga/FOSS/memattr/yosys_release/share/cmp2lut.v' to AST representation. -Generating RTLIL representation for module `\_90_lut_cmp_'. -Successfully finished Verilog frontend. - -3.15.2. Continuing TECHMAP pass. -No more expansions possible. - -3.16. Executing MEMORY_DFF pass (merging $dff cells to $memrd and $memwr). -Checking cell `$memwr$\memory$attributes_test.v:16$7' in module `\block_ram': merged $dff to cell. -Checking cell `$memrd$\memory$attributes_test.v:17$6' in module `\block_ram': merged data $dff to cell. - -3.17. Executing TECHMAP pass (map to technology primitives). - -3.17.1. Executing Verilog-2005 frontend: /opt/eda/fpga/FOSS/memattr/yosys_release/share/mul2dsp.v -Parsing Verilog input from `/opt/eda/fpga/FOSS/memattr/yosys_release/share/mul2dsp.v' to AST representation. -Generating RTLIL representation for module `\_80_mul'. -Generating RTLIL representation for module `\_90_soft_mul'. -Successfully finished Verilog frontend. - -3.17.2. Executing Verilog-2005 frontend: /opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/xc7_dsp_map.v -Parsing Verilog input from `/opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/xc7_dsp_map.v' to AST representation. -Generating RTLIL representation for module `\$__MUL25X18'. -Successfully finished Verilog frontend. - -3.17.3. Continuing TECHMAP pass. -No more expansions possible. - -3.18. Executing OPT_EXPR pass (perform const folding). - -3.19. Executing WREDUCE pass (reducing word size of cells). - -3.20. Executing XILINX_DSP pass (pack resources into DSPs). - -3.21. Executing ALUMACC pass (create $alu and $macc cells). -Extracting $alu and $macc cells in module block_ram: - created 0 $alu and 0 $macc cells. - -3.22. Executing SHARE pass (SAT-based resource sharing). - -3.23. Executing OPT pass (performing simple optimizations). - -3.23.1. Executing OPT_EXPR pass (perform const folding). -Optimizing module block_ram. - -3.23.2. Executing OPT_MERGE pass (detect identical cells). -Finding identical cells in module `\block_ram'. -Removed a total of 0 cells. - -3.23.3. Executing OPT_MUXTREE pass (detect dead branches in mux trees). -Running muxtree optimizer on module \block_ram.. - Creating internal representation of mux trees. - Evaluating internal representation of mux trees. - Analyzing evaluation results. -Removed 0 multiplexer ports. - - -3.23.4. Executing OPT_REDUCE pass (consolidate $*mux and $reduce_* inputs). - Optimizing cells in module \block_ram. -Performed a total of 0 changes. - -3.23.5. Executing OPT_MERGE pass (detect identical cells). -Finding identical cells in module `\block_ram'. -Removed a total of 0 cells. - -3.23.6. Executing OPT_RMDFF pass (remove dff with constant values). - -3.23.7. Executing OPT_CLEAN pass (remove unused cells and wires). -Finding unused cells or wires in module \block_ram.. -Removed 4 unused cells and 5 unused wires. - - -3.23.8. Executing OPT_EXPR pass (perform const folding). -Optimizing module block_ram. - -3.23.9. Rerunning OPT passes. (Maybe there is more to do..) - -3.23.10. Executing OPT_MUXTREE pass (detect dead branches in mux trees). -Running muxtree optimizer on module \block_ram.. - Creating internal representation of mux trees. - Evaluating internal representation of mux trees. - Analyzing evaluation results. -Removed 0 multiplexer ports. - - -3.23.11. Executing OPT_REDUCE pass (consolidate $*mux and $reduce_* inputs). - Optimizing cells in module \block_ram. -Performed a total of 0 changes. - -3.23.12. Executing OPT_MERGE pass (detect identical cells). -Finding identical cells in module `\block_ram'. -Removed a total of 0 cells. - -3.23.13. Executing OPT_RMDFF pass (remove dff with constant values). - -3.23.14. Executing OPT_CLEAN pass (remove unused cells and wires). -Finding unused cells or wires in module \block_ram.. - -3.23.15. Executing OPT_EXPR pass (perform const folding). -Optimizing module block_ram. - -3.23.16. Finished OPT passes. (There is nothing left to do.) - -3.24. Executing FSM pass (extract and optimize FSM). - -3.24.1. Executing FSM_DETECT pass (finding FSMs in design). - -3.24.2. Executing FSM_EXTRACT pass (extracting FSM from design). - -3.24.3. Executing FSM_OPT pass (simple optimizations of FSMs). - -3.24.4. Executing OPT_CLEAN pass (remove unused cells and wires). -Finding unused cells or wires in module \block_ram.. - -3.24.5. Executing FSM_OPT pass (simple optimizations of FSMs). - -3.24.6. Executing FSM_RECODE pass (re-assigning FSM state encoding). - -3.24.7. Executing FSM_INFO pass (dumping all available information on FSM cells). - -3.24.8. Executing FSM_MAP pass (mapping FSMs to basic logic). - -3.25. Executing OPT pass (performing simple optimizations). - -3.25.1. Executing OPT_EXPR pass (perform const folding). -Optimizing module block_ram. - -3.25.2. Executing OPT_MERGE pass (detect identical cells). -Finding identical cells in module `\block_ram'. -Removed a total of 0 cells. - -3.25.3. Executing OPT_RMDFF pass (remove dff with constant values). - -3.25.4. Executing OPT_CLEAN pass (remove unused cells and wires). -Finding unused cells or wires in module \block_ram.. - -3.25.5. Finished fast OPT passes. - -3.26. Executing MEMORY pass. - -3.26.1. Executing OPT_MEM pass (optimize memories). -Performed a total of 0 transformations. - -3.26.2. Executing MEMORY_DFF pass (merging $dff cells to $memrd and $memwr). - -3.26.3. Executing OPT_CLEAN pass (remove unused cells and wires). -Finding unused cells or wires in module \block_ram.. - -3.26.4. Executing MEMORY_SHARE pass (consolidating $memrd/$memwr cells). - -3.26.5. Executing OPT_CLEAN pass (remove unused cells and wires). -Finding unused cells or wires in module \block_ram.. - -3.26.6. Executing MEMORY_COLLECT pass (generating $mem cells). -Collecting $memrd, $memwr and $meminit for memory `\memory' in module `\block_ram': - $memwr$\memory$attributes_test.v:16$7 ($memwr) - $memrd$\memory$attributes_test.v:17$6 ($memrd) - -3.27. Executing OPT_CLEAN pass (remove unused cells and wires). -Finding unused cells or wires in module \block_ram.. - -3.28. Executing MEMORY_BRAM pass (mapping $mem cells to block memories). -Processing block_ram.memory: - Properties: ports=2 bits=4096 rports=1 wports=1 dbits=4 abits=10 words=1024 - Checking rule #1 for bram type $__XILINX_RAMB36_SDP (variant 1): - Bram geometry: abits=9 dbits=72 wports=0 rports=0 - Estimated number of duplicates for more read ports: dups=1 - Metrics for $__XILINX_RAMB36_SDP: awaste=0 dwaste=68 bwaste=34816 waste=34816 efficiency=5 - Rule #1 for bram type $__XILINX_RAMB36_SDP (variant 1) accepted. - Mapping to bram type $__XILINX_RAMB36_SDP (variant 1): - Shuffle bit order to accommodate enable buckets of size 9.. - Results of bit order shuffling: 0 1 2 3 -1 -1 -1 -1 -1 - Write port #0 is in clock domain \clk. - Mapped to bram port B1. - Read port #0 is in clock domain \clk. - Mapped to bram port A1.1. - Updated properties: dups=1 waste=34816 efficiency=5 - Storing for later selection. - Checking rule #2 for bram type $__XILINX_RAMB18_SDP (variant 1): - Bram geometry: abits=9 dbits=36 wports=0 rports=0 - Estimated number of duplicates for more read ports: dups=1 - Metrics for $__XILINX_RAMB18_SDP: awaste=0 dwaste=32 bwaste=16384 waste=16384 efficiency=11 - Rule #2 for bram type $__XILINX_RAMB18_SDP (variant 1) accepted. - Mapping to bram type $__XILINX_RAMB18_SDP (variant 1): - Shuffle bit order to accommodate enable buckets of size 9.. - Results of bit order shuffling: 0 1 2 3 -1 -1 -1 -1 -1 - Write port #0 is in clock domain \clk. - Mapped to bram port B1. - Read port #0 is in clock domain \clk. - Mapped to bram port A1.1. - Updated properties: dups=1 waste=16384 efficiency=11 - Storing for later selection. - Checking rule #3 for bram type $__XILINX_RAMB36_TDP (variant 1): - Bram geometry: abits=10 dbits=36 wports=0 rports=0 - Estimated number of duplicates for more read ports: dups=1 - Metrics for $__XILINX_RAMB36_TDP: awaste=0 dwaste=32 bwaste=32768 waste=32768 efficiency=11 - Rule #3 for bram type $__XILINX_RAMB36_TDP (variant 1) accepted. - Mapping to bram type $__XILINX_RAMB36_TDP (variant 1): - Shuffle bit order to accommodate enable buckets of size 9.. - Results of bit order shuffling: 0 1 2 3 -1 -1 -1 -1 -1 - Write port #0 is in clock domain \clk. - Mapped to bram port B1. - Read port #0 is in clock domain \clk. - Mapped to bram port A1.1. - Updated properties: dups=1 waste=32768 efficiency=11 - Storing for later selection. - Checking rule #3 for bram type $__XILINX_RAMB36_TDP (variant 2): - Bram geometry: abits=11 dbits=18 wports=0 rports=0 - Estimated number of duplicates for more read ports: dups=1 - Metrics for $__XILINX_RAMB36_TDP: awaste=1024 dwaste=14 bwaste=32768 waste=32768 efficiency=11 - Rule #3 for bram type $__XILINX_RAMB36_TDP (variant 2) accepted. - Mapping to bram type $__XILINX_RAMB36_TDP (variant 2): - Shuffle bit order to accommodate enable buckets of size 9.. - Results of bit order shuffling: 0 1 2 3 -1 -1 -1 -1 -1 - Write port #0 is in clock domain \clk. - Mapped to bram port B1. - Read port #0 is in clock domain \clk. - Mapped to bram port A1.1. - Updated properties: dups=1 waste=32768 efficiency=11 - Storing for later selection. - Checking rule #3 for bram type $__XILINX_RAMB36_TDP (variant 3): - Bram geometry: abits=12 dbits=9 wports=0 rports=0 - Estimated number of duplicates for more read ports: dups=1 - Metrics for $__XILINX_RAMB36_TDP: awaste=3072 dwaste=5 bwaste=32768 waste=32768 efficiency=11 - Rule #3 for bram type $__XILINX_RAMB36_TDP (variant 3) accepted. - Mapping to bram type $__XILINX_RAMB36_TDP (variant 3): - Shuffle bit order to accommodate enable buckets of size 9.. - Results of bit order shuffling: 0 1 2 3 -1 -1 -1 -1 -1 - Write port #0 is in clock domain \clk. - Mapped to bram port B1. - Read port #0 is in clock domain \clk. - Mapped to bram port A1.1. - Updated properties: dups=1 waste=32768 efficiency=11 - Storing for later selection. - Checking rule #3 for bram type $__XILINX_RAMB36_TDP (variant 4): - Bram geometry: abits=13 dbits=4 wports=0 rports=0 - Estimated number of duplicates for more read ports: dups=1 - Metrics for $__XILINX_RAMB36_TDP: awaste=7168 dwaste=0 bwaste=28672 waste=28672 efficiency=12 - Rule #3 for bram type $__XILINX_RAMB36_TDP (variant 4) accepted. - Mapping to bram type $__XILINX_RAMB36_TDP (variant 4): - Shuffle bit order to accommodate enable buckets of size 4.. - Results of bit order shuffling: 0 1 2 3 - Write port #0 is in clock domain \clk. - Mapped to bram port B1. - Read port #0 is in clock domain \clk. - Mapped to bram port A1.1. - Updated properties: dups=1 waste=28672 efficiency=12 - Storing for later selection. - Checking rule #3 for bram type $__XILINX_RAMB36_TDP (variant 5): - Bram geometry: abits=14 dbits=2 wports=0 rports=0 - Estimated number of duplicates for more read ports: dups=1 - Metrics for $__XILINX_RAMB36_TDP: awaste=15360 dwaste=0 bwaste=30720 waste=30720 efficiency=6 - Rule #3 for bram type $__XILINX_RAMB36_TDP (variant 5) accepted. - Mapping to bram type $__XILINX_RAMB36_TDP (variant 5): - Shuffle bit order to accommodate enable buckets of size 2.. - Results of bit order shuffling: 0 1 2 3 - Write port #0 is in clock domain \clk. - Mapped to bram port B1. - Read port #0 is in clock domain \clk. - Mapped to bram port A1.1. - Updated properties: dups=1 waste=30720 efficiency=6 - Storing for later selection. - Checking rule #3 for bram type $__XILINX_RAMB36_TDP (variant 6): - Bram geometry: abits=15 dbits=1 wports=0 rports=0 - Estimated number of duplicates for more read ports: dups=1 - Metrics for $__XILINX_RAMB36_TDP: awaste=31744 dwaste=0 bwaste=31744 waste=31744 efficiency=3 - Rule #3 for bram type $__XILINX_RAMB36_TDP (variant 6) rejected: requirement 'min efficiency 5' not met. - Checking rule #4 for bram type $__XILINX_RAMB18_TDP (variant 1): - Bram geometry: abits=10 dbits=18 wports=0 rports=0 - Estimated number of duplicates for more read ports: dups=1 - Metrics for $__XILINX_RAMB18_TDP: awaste=0 dwaste=14 bwaste=14336 waste=14336 efficiency=22 - Rule #4 for bram type $__XILINX_RAMB18_TDP (variant 1) accepted. - Mapping to bram type $__XILINX_RAMB18_TDP (variant 1): - Shuffle bit order to accommodate enable buckets of size 9.. - Results of bit order shuffling: 0 1 2 3 -1 -1 -1 -1 -1 - Write port #0 is in clock domain \clk. - Mapped to bram port B1. - Read port #0 is in clock domain \clk. - Mapped to bram port A1.1. - Updated properties: dups=1 waste=14336 efficiency=22 - Storing for later selection. - Checking rule #4 for bram type $__XILINX_RAMB18_TDP (variant 2): - Bram geometry: abits=11 dbits=9 wports=0 rports=0 - Estimated number of duplicates for more read ports: dups=1 - Metrics for $__XILINX_RAMB18_TDP: awaste=1024 dwaste=5 bwaste=14336 waste=14336 efficiency=22 - Rule #4 for bram type $__XILINX_RAMB18_TDP (variant 2) accepted. - Mapping to bram type $__XILINX_RAMB18_TDP (variant 2): - Shuffle bit order to accommodate enable buckets of size 9.. - Results of bit order shuffling: 0 1 2 3 -1 -1 -1 -1 -1 - Write port #0 is in clock domain \clk. - Mapped to bram port B1. - Read port #0 is in clock domain \clk. - Mapped to bram port A1.1. - Updated properties: dups=1 waste=14336 efficiency=22 - Storing for later selection. - Checking rule #4 for bram type $__XILINX_RAMB18_TDP (variant 3): - Bram geometry: abits=12 dbits=4 wports=0 rports=0 - Estimated number of duplicates for more read ports: dups=1 - Metrics for $__XILINX_RAMB18_TDP: awaste=3072 dwaste=0 bwaste=12288 waste=12288 efficiency=25 - Rule #4 for bram type $__XILINX_RAMB18_TDP (variant 3) accepted. - Mapping to bram type $__XILINX_RAMB18_TDP (variant 3): - Shuffle bit order to accommodate enable buckets of size 4.. - Results of bit order shuffling: 0 1 2 3 - Write port #0 is in clock domain \clk. - Mapped to bram port B1. - Read port #0 is in clock domain \clk. - Mapped to bram port A1.1. - Updated properties: dups=1 waste=12288 efficiency=25 - Storing for later selection. - Checking rule #4 for bram type $__XILINX_RAMB18_TDP (variant 4): - Bram geometry: abits=13 dbits=2 wports=0 rports=0 - Estimated number of duplicates for more read ports: dups=1 - Metrics for $__XILINX_RAMB18_TDP: awaste=7168 dwaste=0 bwaste=14336 waste=14336 efficiency=12 - Rule #4 for bram type $__XILINX_RAMB18_TDP (variant 4) accepted. - Mapping to bram type $__XILINX_RAMB18_TDP (variant 4): - Shuffle bit order to accommodate enable buckets of size 2.. - Results of bit order shuffling: 0 1 2 3 - Write port #0 is in clock domain \clk. - Mapped to bram port B1. - Read port #0 is in clock domain \clk. - Mapped to bram port A1.1. - Updated properties: dups=1 waste=14336 efficiency=12 - Storing for later selection. - Checking rule #4 for bram type $__XILINX_RAMB18_TDP (variant 5): - Bram geometry: abits=14 dbits=1 wports=0 rports=0 - Estimated number of duplicates for more read ports: dups=1 - Metrics for $__XILINX_RAMB18_TDP: awaste=15360 dwaste=0 bwaste=15360 waste=15360 efficiency=6 - Rule #4 for bram type $__XILINX_RAMB18_TDP (variant 5) accepted. - Mapping to bram type $__XILINX_RAMB18_TDP (variant 5): - Write port #0 is in clock domain \clk. - Mapped to bram port B1. - Read port #0 is in clock domain \clk. - Mapped to bram port A1.1. - Updated properties: dups=1 waste=15360 efficiency=6 - Storing for later selection. - Selecting best of 12 rules: - Efficiency for rule 4.5: efficiency=6, cells=4, acells=1 - Efficiency for rule 4.4: efficiency=12, cells=2, acells=1 - Efficiency for rule 4.3: efficiency=25, cells=1, acells=1 - Efficiency for rule 4.2: efficiency=22, cells=1, acells=1 - Efficiency for rule 4.1: efficiency=22, cells=1, acells=1 - Efficiency for rule 3.5: efficiency=6, cells=2, acells=1 - Efficiency for rule 3.4: efficiency=12, cells=1, acells=1 - Efficiency for rule 3.3: efficiency=11, cells=1, acells=1 - Efficiency for rule 3.2: efficiency=11, cells=1, acells=1 - Efficiency for rule 3.1: efficiency=11, cells=1, acells=1 - Efficiency for rule 2.1: efficiency=11, cells=2, acells=2 - Efficiency for rule 1.1: efficiency=5, cells=2, acells=2 - Selected rule 4.3 with efficiency 25. - Mapping to bram type $__XILINX_RAMB18_TDP (variant 3): - Shuffle bit order to accommodate enable buckets of size 4.. - Results of bit order shuffling: 0 1 2 3 - Write port #0 is in clock domain \clk. - Mapped to bram port B1. - Read port #0 is in clock domain \clk. - Mapped to bram port A1.1. - Creating $__XILINX_RAMB18_TDP cell at grid position <0 0 0>: memory.0.0.0 - -3.29. Executing TECHMAP pass (map to technology primitives). - -3.29.1. Executing Verilog-2005 frontend: /opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/xc7_brams_map.v -Parsing Verilog input from `/opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/xc7_brams_map.v' to AST representation. -Generating RTLIL representation for module `\$__XILINX_RAMB36_SDP'. -Generating RTLIL representation for module `\$__XILINX_RAMB18_SDP'. -Generating RTLIL representation for module `\$__XILINX_RAMB36_TDP'. -Generating RTLIL representation for module `\$__XILINX_RAMB18_TDP'. -Successfully finished Verilog frontend. - -3.29.2. Continuing TECHMAP pass. -Using template $paramod\$__XILINX_RAMB18_TDP\CFG_ABITS=12\CFG_DBITS=4\CFG_ENABLE_B=1\CLKPOL2=1\CLKPOL3=1 for cells of type $__XILINX_RAMB18_TDP. -No more expansions possible. - - -3.30. Executing MEMORY_BRAM pass (mapping $mem cells to block memories). - -3.31. Executing TECHMAP pass (map to technology primitives). - -3.31.1. Executing Verilog-2005 frontend: /opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/lutrams_map.v -Parsing Verilog input from `/opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/lutrams_map.v' to AST representation. -Generating RTLIL representation for module `\$__XILINX_RAM32X1D'. -Generating RTLIL representation for module `\$__XILINX_RAM64X1D'. -Generating RTLIL representation for module `\$__XILINX_RAM128X1D'. -Successfully finished Verilog frontend. - -3.31.2. Continuing TECHMAP pass. -No more expansions possible. - -3.32. Executing OPT pass (performing simple optimizations). - -3.32.1. Executing OPT_EXPR pass (perform const folding). -Optimizing module block_ram. - - -3.32.2. Executing OPT_MERGE pass (detect identical cells). -Finding identical cells in module `\block_ram'. -Removed a total of 0 cells. - -3.32.3. Executing OPT_RMDFF pass (remove dff with constant values). - -3.32.4. Executing OPT_CLEAN pass (remove unused cells and wires). -Finding unused cells or wires in module \block_ram.. -Removed 0 unused cells and 17 unused wires. - - -3.32.5. Finished fast OPT passes. - -3.33. Executing MEMORY_MAP pass (converting $mem cells to logic and flip-flops). - -3.34. Executing DFFSR2DFF pass (mapping DFFSR cells to simpler FFs). - -3.35. Executing DFF2DFFE pass (transform $dff to $dffe where applicable). -Transforming FF to FF+Enable cells in module block_ram: - -3.36. Executing OPT pass (performing simple optimizations). - -3.36.1. Executing OPT_EXPR pass (perform const folding). -Optimizing module block_ram. - -3.36.2. Executing OPT_MERGE pass (detect identical cells). -Finding identical cells in module `\block_ram'. -Removed a total of 0 cells. - -3.36.3. Executing OPT_MUXTREE pass (detect dead branches in mux trees). -Running muxtree optimizer on module \block_ram.. - Creating internal representation of mux trees. - No muxes found in this module. -Removed 0 multiplexer ports. - -3.36.4. Executing OPT_REDUCE pass (consolidate $*mux and $reduce_* inputs). - Optimizing cells in module \block_ram. -Performed a total of 0 changes. - -3.36.5. Executing OPT_MERGE pass (detect identical cells). -Finding identical cells in module `\block_ram'. -Removed a total of 0 cells. - -3.36.6. Executing OPT_SHARE pass. - -3.36.7. Executing OPT_RMDFF pass (remove dff with constant values). - -3.36.8. Executing OPT_CLEAN pass (remove unused cells and wires). -Finding unused cells or wires in module \block_ram.. - -3.36.9. Executing OPT_EXPR pass (perform const folding). -Optimizing module block_ram. - -3.36.10. Finished OPT passes. (There is nothing left to do.) - -3.37. Executing XILINX_SRL pass (Xilinx shift register extraction). - -3.38. Executing TECHMAP pass (map to technology primitives). - -3.38.1. Executing Verilog-2005 frontend: /opt/eda/fpga/FOSS/memattr/yosys_release/share/techmap.v -Parsing Verilog input from `/opt/eda/fpga/FOSS/memattr/yosys_release/share/techmap.v' to AST representation. -Generating RTLIL representation for module `\_90_simplemap_bool_ops'. -Generating RTLIL representation for module `\_90_simplemap_reduce_ops'. -Generating RTLIL representation for module `\_90_simplemap_logic_ops'. -Generating RTLIL representation for module `\_90_simplemap_compare_ops'. -Generating RTLIL representation for module `\_90_simplemap_various'. -Generating RTLIL representation for module `\_90_simplemap_registers'. -Generating RTLIL representation for module `\_90_shift_ops_shr_shl_sshl_sshr'. -Generating RTLIL representation for module `\_90_shift_shiftx'. -Generating RTLIL representation for module `\_90_fa'. -Generating RTLIL representation for module `\_90_lcu'. -Generating RTLIL representation for module `\_90_alu'. -Generating RTLIL representation for module `\_90_macc'. -Generating RTLIL representation for module `\_90_alumacc'. -Generating RTLIL representation for module `\$__div_mod_u'. -Generating RTLIL representation for module `\$__div_mod'. -Generating RTLIL representation for module `\_90_div'. -Generating RTLIL representation for module `\_90_mod'. -Generating RTLIL representation for module `\_90_pow'. -Generating RTLIL representation for module `\_90_pmux'. -Generating RTLIL representation for module `\_90_lut'. -Successfully finished Verilog frontend. - -3.38.2. Executing Verilog-2005 frontend: /opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/arith_map.v -Parsing Verilog input from `/opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/arith_map.v' to AST representation. -Generating RTLIL representation for module `\_80_xilinx_lcu'. -Generating RTLIL representation for module `\_80_xilinx_alu'. -Successfully finished Verilog frontend. - -3.38.3. Continuing TECHMAP pass. -No more expansions possible. - -3.39. Executing OPT pass (performing simple optimizations). - -3.39.1. Executing OPT_EXPR pass (perform const folding). -Optimizing module block_ram. - -3.39.2. Executing OPT_MERGE pass (detect identical cells). -Finding identical cells in module `\block_ram'. -Removed a total of 0 cells. - -3.39.3. Executing OPT_RMDFF pass (remove dff with constant values). - -3.39.4. Executing OPT_CLEAN pass (remove unused cells and wires). -Finding unused cells or wires in module \block_ram.. - -3.39.5. Finished fast OPT passes. - -3.40. Executing TECHMAP pass (map to technology primitives). - -3.40.1. Executing Verilog-2005 frontend: /opt/eda/fpga/FOSS/memattr/yosys_release/share/techmap.v -Parsing Verilog input from `/opt/eda/fpga/FOSS/memattr/yosys_release/share/techmap.v' to AST representation. -Generating RTLIL representation for module `\_90_simplemap_bool_ops'. -Generating RTLIL representation for module `\_90_simplemap_reduce_ops'. -Generating RTLIL representation for module `\_90_simplemap_logic_ops'. -Generating RTLIL representation for module `\_90_simplemap_compare_ops'. -Generating RTLIL representation for module `\_90_simplemap_various'. -Generating RTLIL representation for module `\_90_simplemap_registers'. -Generating RTLIL representation for module `\_90_shift_ops_shr_shl_sshl_sshr'. -Generating RTLIL representation for module `\_90_shift_shiftx'. -Generating RTLIL representation for module `\_90_fa'. -Generating RTLIL representation for module `\_90_lcu'. -Generating RTLIL representation for module `\_90_alu'. -Generating RTLIL representation for module `\_90_macc'. -Generating RTLIL representation for module `\_90_alumacc'. -Generating RTLIL representation for module `\$__div_mod_u'. -Generating RTLIL representation for module `\$__div_mod'. -Generating RTLIL representation for module `\_90_div'. -Generating RTLIL representation for module `\_90_mod'. -Generating RTLIL representation for module `\_90_pow'. -Generating RTLIL representation for module `\_90_pmux'. -Generating RTLIL representation for module `\_90_lut'. -Successfully finished Verilog frontend. - -3.40.2. Executing Verilog-2005 frontend: /opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/cells_map.v -Parsing Verilog input from `/opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/cells_map.v' to AST representation. -Generating RTLIL representation for module `\_90_dff_nn0_to_np0'. -Generating RTLIL representation for module `\_90_dff_pn0_to_pp0'. -Generating RTLIL representation for module `\_90_dff_nn1_to_np1'. -Generating RTLIL representation for module `\_90_dff_pn1_to_pp1'. -Generating RTLIL representation for module `\$__SHREG_'. -Generating RTLIL representation for module `\$__XILINX_SHREG_'. -Generating RTLIL representation for module `\$__XILINX_MUXF78'. -Generating RTLIL representation for module `\$__XILINX_TINOUTPAD'. -Generating RTLIL representation for module `\$__XILINX_TOUTPAD'. -Successfully finished Verilog frontend. - -3.40.3. Continuing TECHMAP pass. -No more expansions possible. - -3.41. Executing OPT_EXPR pass (perform const folding). -Optimizing module block_ram. - -3.42. Executing ABC pass (technology mapping using ABC). - -3.42.1. Extracting gate netlist of module `\block_ram' to `/input.blif'.. -Extracted 0 gates and 0 wires to a netlist network with 0 inputs and 0 outputs. -Don't call ABC as there is nothing to map. -Removing temp directory. - -3.43. Executing XILINX_SRL pass (Xilinx shift register extraction). - -3.44. Executing TECHMAP pass (map to technology primitives). - -3.44.1. Executing Verilog-2005 frontend: /opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/lut_map.v -Parsing Verilog input from `/opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/lut_map.v' to AST representation. -Generating RTLIL representation for module `\$lut'. -Successfully finished Verilog frontend. - -3.44.2. Executing Verilog-2005 frontend: /opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/cells_map.v -Parsing Verilog input from `/opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/cells_map.v' to AST representation. -Generating RTLIL representation for module `\_90_dff_nn0_to_np0'. -Generating RTLIL representation for module `\_90_dff_pn0_to_pp0'. -Generating RTLIL representation for module `\_90_dff_nn1_to_np1'. -Generating RTLIL representation for module `\_90_dff_pn1_to_pp1'. -Generating RTLIL representation for module `\$__SHREG_'. -Generating RTLIL representation for module `\$__XILINX_SHREG_'. -Generating RTLIL representation for module `\$__XILINX_MUXF78'. -Generating RTLIL representation for module `\$__XILINX_TINOUTPAD'. -Generating RTLIL representation for module `\$__XILINX_TOUTPAD'. -Successfully finished Verilog frontend. - -3.44.3. Executing Verilog-2005 frontend: /opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/xc7_ff_map.v -Parsing Verilog input from `/opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/xc7_ff_map.v' to AST representation. -Generating RTLIL representation for module `\$_DFF_N_'. -Generating RTLIL representation for module `\$_DFF_P_'. -Generating RTLIL representation for module `\$_DFFE_NP_'. -Generating RTLIL representation for module `\$_DFFE_PP_'. -Generating RTLIL representation for module `\$_DFF_NN0_'. -Generating RTLIL representation for module `\$_DFF_NP0_'. -Generating RTLIL representation for module `\$_DFF_PN0_'. -Generating RTLIL representation for module `\$_DFF_PP0_'. -Generating RTLIL representation for module `\$_DFF_NN1_'. -Generating RTLIL representation for module `\$_DFF_NP1_'. -Generating RTLIL representation for module `\$_DFF_PN1_'. -Generating RTLIL representation for module `\$_DFF_PP1_'. -Generating RTLIL representation for module `\$_DLATCH_N_'. -Generating RTLIL representation for module `\$_DLATCH_P_'. -Successfully finished Verilog frontend. - -3.44.4. Continuing TECHMAP pass. -No more expansions possible. - -3.45. Executing CLKBUFMAP pass (inserting global clock buffers). -Inserting BUFG on block_ram.clk[0]. - -3.46. Executing HIERARCHY pass (managing design hierarchy). - -3.46.1. Analyzing design hierarchy.. -Top module: \block_ram - -3.46.2. Analyzing design hierarchy.. -Top module: \block_ram -Removed 0 unused modules. - -3.47. Printing statistics. - -=== block_ram === - - Number of wires: 12 - Number of wire bits: 62 - Number of public wires: 6 - Number of public wire bits: 24 - Number of memories: 0 - Number of memory bits: 0 - Number of processes: 0 - Number of cells: 2 - BUFG 1 - RAMB18E1 1 - - Estimated number of LCs: 0 - -3.48. Executing CHECK pass (checking for obvious problems). -checking module block_ram.. -found and reported 0 problems. - -4. Executing Verilog-2005 frontend: attributes_test.v -Parsing Verilog input from `attributes_test.v' to AST representation. -Generating RTLIL representation for module `\block_ram'. -Generating RTLIL representation for module `\distributed_ram'. -Generating RTLIL representation for module `\distributed_ram_manual'. -Generating RTLIL representation for module `\distributed_ram_manual_syn'. -Successfully finished Verilog frontend. - -5. Executing HIERARCHY pass (managing design hierarchy). - -5.1. Analyzing design hierarchy.. -Top module: \distributed_ram - -5.2. Analyzing design hierarchy.. -Top module: \distributed_ram -Removing unused module `\distributed_ram_manual_syn'. -Removing unused module `\distributed_ram_manual'. -Removing unused module `\block_ram'. -Removed 3 unused modules. - -6. Executing SYNTH_XILINX pass. - -6.1. Executing Verilog-2005 frontend: /opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/cells_sim.v -Parsing Verilog input from `/opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/cells_sim.v' to AST representation. -Generating RTLIL representation for module `\VCC'. -Generating RTLIL representation for module `\GND'. -Generating RTLIL representation for module `\IBUF'. -Generating RTLIL representation for module `\IBUFG'. -Generating RTLIL representation for module `\OBUF'. -Generating RTLIL representation for module `\IOBUF'. -Generating RTLIL representation for module `\OBUFT'. -Generating RTLIL representation for module `\BUFG'. -Generating RTLIL representation for module `\BUFGCTRL'. -Generating RTLIL representation for module `\BUFHCE'. -Generating RTLIL representation for module `\INV'. -Generating RTLIL representation for module `\LUT1'. -Generating RTLIL representation for module `\LUT2'. -Generating RTLIL representation for module `\LUT3'. -Generating RTLIL representation for module `\LUT4'. -Generating RTLIL representation for module `\LUT5'. -Generating RTLIL representation for module `\LUT6'. -Generating RTLIL representation for module `\LUT6_2'. -Generating RTLIL representation for module `\MUXCY'. -Generating RTLIL representation for module `\MUXF7'. -Generating RTLIL representation for module `\MUXF8'. -Generating RTLIL representation for module `\XORCY'. -Generating RTLIL representation for module `\CARRY4'. -Generating RTLIL representation for module `\FDRE'. -Generating RTLIL representation for module `\FDSE'. -Generating RTLIL representation for module `\FDCE'. -Generating RTLIL representation for module `\FDPE'. -Generating RTLIL representation for module `\FDRE_1'. -Generating RTLIL representation for module `\FDSE_1'. -Generating RTLIL representation for module `\FDCE_1'. -Generating RTLIL representation for module `\FDPE_1'. -Generating RTLIL representation for module `\LDCE'. -Generating RTLIL representation for module `\LDPE'. -Generating RTLIL representation for module `\RAM16X1S'. -Generating RTLIL representation for module `\RAM16X1S_1'. -Generating RTLIL representation for module `\RAM32X1S'. -Generating RTLIL representation for module `\RAM32X1S_1'. -Generating RTLIL representation for module `\RAM64X1S'. -Generating RTLIL representation for module `\RAM64X1S_1'. -Generating RTLIL representation for module `\RAM128X1S'. -Generating RTLIL representation for module `\RAM128X1S_1'. -Generating RTLIL representation for module `\RAM256X1S'. -Generating RTLIL representation for module `\RAM512X1S'. -Generating RTLIL representation for module `\RAM16X2S'. -Generating RTLIL representation for module `\RAM32X2S'. -Generating RTLIL representation for module `\RAM64X2S'. -Generating RTLIL representation for module `\RAM16X4S'. -Generating RTLIL representation for module `\RAM32X4S'. -Generating RTLIL representation for module `\RAM16X8S'. -Generating RTLIL representation for module `\RAM32X8S'. -Generating RTLIL representation for module `\RAM16X1D'. -Generating RTLIL representation for module `\RAM16X1D_1'. -Generating RTLIL representation for module `\RAM32X1D'. -Generating RTLIL representation for module `\RAM32X1D_1'. -Generating RTLIL representation for module `\RAM64X1D'. -Generating RTLIL representation for module `\RAM64X1D_1'. -Generating RTLIL representation for module `\RAM128X1D'. -Generating RTLIL representation for module `\RAM256X1D'. -Generating RTLIL representation for module `\RAM32M'. -Generating RTLIL representation for module `\RAM32M16'. -Generating RTLIL representation for module `\RAM64M'. -Generating RTLIL representation for module `\RAM64M8'. -Generating RTLIL representation for module `\ROM16X1'. -Generating RTLIL representation for module `\ROM32X1'. -Generating RTLIL representation for module `\ROM64X1'. -Generating RTLIL representation for module `\ROM128X1'. -Generating RTLIL representation for module `\ROM256X1'. -Generating RTLIL representation for module `\SRL16E'. -Generating RTLIL representation for module `\SRLC16E'. -Generating RTLIL representation for module `\SRLC32E'. -Generating RTLIL representation for module `\MULT18X18'. -Generating RTLIL representation for module `\MULT18X18S'. -Generating RTLIL representation for module `\MULT18X18SIO'. -Generating RTLIL representation for module `\DSP48A'. -Generating RTLIL representation for module `\DSP48A1'. -Generating RTLIL representation for module `\DSP48E1'. -Successfully finished Verilog frontend. - -6.2. Executing Verilog-2005 frontend: /opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/cells_xtra.v -Parsing Verilog input from `/opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/cells_xtra.v' to AST representation. -Generating RTLIL representation for module `\FDCPE'. -Generating RTLIL representation for module `\FDRSE'. -Generating RTLIL representation for module `\LDCPE'. -Generating RTLIL representation for module `\AND2B1L'. -Generating RTLIL representation for module `\OR2L'. -Generating RTLIL representation for module `\MUXF5'. -Generating RTLIL representation for module `\MUXF6'. -Generating RTLIL representation for module `\MUXF9'. -Generating RTLIL representation for module `\CARRY8'. -Generating RTLIL representation for module `\ORCY'. -Generating RTLIL representation for module `\MULT_AND'. -Generating RTLIL representation for module `\SRL16'. -Generating RTLIL representation for module `\SRLC16'. -Generating RTLIL representation for module `\CFGLUT5'. -Generating RTLIL representation for module `\RAMB16_S1'. -Generating RTLIL representation for module `\RAMB16_S2'. -Generating RTLIL representation for module `\RAMB16_S4'. -Generating RTLIL representation for module `\RAMB16_S9'. -Generating RTLIL representation for module `\RAMB16_S18'. -Generating RTLIL representation for module `\RAMB16_S36'. -Generating RTLIL representation for module `\RAMB16_S1_S1'. -Generating RTLIL representation for module `\RAMB16_S1_S2'. -Generating RTLIL representation for module `\RAMB16_S1_S4'. -Generating RTLIL representation for module `\RAMB16_S1_S9'. -Generating RTLIL representation for module `\RAMB16_S1_S18'. -Generating RTLIL representation for module `\RAMB16_S1_S36'. -Generating RTLIL representation for module `\RAMB16_S2_S2'. -Generating RTLIL representation for module `\RAMB16_S2_S4'. -Generating RTLIL representation for module `\RAMB16_S2_S9'. -Generating RTLIL representation for module `\RAMB16_S2_S18'. -Generating RTLIL representation for module `\RAMB16_S2_S36'. -Generating RTLIL representation for module `\RAMB16_S4_S4'. -Generating RTLIL representation for module `\RAMB16_S4_S9'. -Generating RTLIL representation for module `\RAMB16_S4_S18'. -Generating RTLIL representation for module `\RAMB16_S4_S36'. -Generating RTLIL representation for module `\RAMB16_S9_S9'. -Generating RTLIL representation for module `\RAMB16_S9_S18'. -Generating RTLIL representation for module `\RAMB16_S9_S36'. -Generating RTLIL representation for module `\RAMB16_S18_S18'. -Generating RTLIL representation for module `\RAMB16_S18_S36'. -Generating RTLIL representation for module `\RAMB16_S36_S36'. -Generating RTLIL representation for module `\RAMB16BWE_S18'. -Generating RTLIL representation for module `\RAMB16BWE_S36'. -Generating RTLIL representation for module `\RAMB16BWE_S18_S9'. -Generating RTLIL representation for module `\RAMB16BWE_S18_S18'. -Generating RTLIL representation for module `\RAMB16BWE_S36_S9'. -Generating RTLIL representation for module `\RAMB16BWE_S36_S18'. -Generating RTLIL representation for module `\RAMB16BWE_S36_S36'. -Generating RTLIL representation for module `\RAMB16BWER'. -Generating RTLIL representation for module `\RAMB8BWER'. -Generating RTLIL representation for module `\FIFO16'. -Generating RTLIL representation for module `\RAMB16'. -Generating RTLIL representation for module `\RAMB32_S64_ECC'. -Generating RTLIL representation for module `\FIFO18'. -Generating RTLIL representation for module `\FIFO18_36'. -Generating RTLIL representation for module `\FIFO36'. -Generating RTLIL representation for module `\FIFO36_72'. -Generating RTLIL representation for module `\RAMB18'. -Generating RTLIL representation for module `\RAMB36'. -Generating RTLIL representation for module `\RAMB18SDP'. -Generating RTLIL representation for module `\RAMB36SDP'. -Generating RTLIL representation for module `\FIFO18E1'. -Generating RTLIL representation for module `\FIFO36E1'. -Generating RTLIL representation for module `\RAMB18E1'. -Generating RTLIL representation for module `\RAMB36E1'. -Generating RTLIL representation for module `\FIFO18E2'. -Generating RTLIL representation for module `\FIFO36E2'. -Generating RTLIL representation for module `\RAMB18E2'. -Generating RTLIL representation for module `\RAMB36E2'. -Generating RTLIL representation for module `\URAM288'. -Generating RTLIL representation for module `\URAM288_BASE'. -Generating RTLIL representation for module `\DSP48'. -Generating RTLIL representation for module `\DSP48E'. -Generating RTLIL representation for module `\DSP48E2'. -Generating RTLIL representation for module `\IFDDRCPE'. -Generating RTLIL representation for module `\IFDDRRSE'. -Generating RTLIL representation for module `\OFDDRCPE'. -Generating RTLIL representation for module `\OFDDRRSE'. -Generating RTLIL representation for module `\OFDDRTCPE'. -Generating RTLIL representation for module `\OFDDRTRSE'. -Generating RTLIL representation for module `\IDDR2'. -Generating RTLIL representation for module `\ODDR2'. -Generating RTLIL representation for module `\IDDR'. -Generating RTLIL representation for module `\IDDR_2CLK'. -Generating RTLIL representation for module `\ODDR'. -Generating RTLIL representation for module `\IDELAYCTRL'. -Generating RTLIL representation for module `\IDELAY'. -Generating RTLIL representation for module `\ISERDES'. -Generating RTLIL representation for module `\OSERDES'. -Generating RTLIL representation for module `\IODELAY'. -Generating RTLIL representation for module `\ISERDES_NODELAY'. -Generating RTLIL representation for module `\IODELAYE1'. -Generating RTLIL representation for module `\ISERDESE1'. -Generating RTLIL representation for module `\OSERDESE1'. -Generating RTLIL representation for module `\IDELAYE2'. -Generating RTLIL representation for module `\ODELAYE2'. -Generating RTLIL representation for module `\ISERDESE2'. -Generating RTLIL representation for module `\OSERDESE2'. -Generating RTLIL representation for module `\PHASER_IN'. -Generating RTLIL representation for module `\PHASER_IN_PHY'. -Generating RTLIL representation for module `\PHASER_OUT'. -Generating RTLIL representation for module `\PHASER_OUT_PHY'. -Generating RTLIL representation for module `\PHASER_REF'. -Generating RTLIL representation for module `\PHY_CONTROL'. -Generating RTLIL representation for module `\IDDRE1'. -Generating RTLIL representation for module `\ODDRE1'. -Generating RTLIL representation for module `\IDELAYE3'. -Generating RTLIL representation for module `\ODELAYE3'. -Generating RTLIL representation for module `\ISERDESE3'. -Generating RTLIL representation for module `\OSERDESE3'. -Generating RTLIL representation for module `\BITSLICE_CONTROL'. -Generating RTLIL representation for module `\RIU_OR'. -Generating RTLIL representation for module `\RX_BITSLICE'. -Generating RTLIL representation for module `\RXTX_BITSLICE'. -Generating RTLIL representation for module `\TX_BITSLICE'. -Generating RTLIL representation for module `\TX_BITSLICE_TRI'. -Generating RTLIL representation for module `\IODELAY2'. -Generating RTLIL representation for module `\IODRP2'. -Generating RTLIL representation for module `\IODRP2_MCB'. -Generating RTLIL representation for module `\ISERDES2'. -Generating RTLIL representation for module `\OSERDES2'. -Generating RTLIL representation for module `\IBUF_DLY_ADJ'. -Generating RTLIL representation for module `\IBUF_IBUFDISABLE'. -Generating RTLIL representation for module `\IBUF_INTERMDISABLE'. -Generating RTLIL representation for module `\IBUF_ANALOG'. -Generating RTLIL representation for module `\IBUFE3'. -Generating RTLIL representation for module `\IBUFDS'. -Generating RTLIL representation for module `\IBUFDS_DLY_ADJ'. -Generating RTLIL representation for module `\IBUFDS_IBUFDISABLE'. -Generating RTLIL representation for module `\IBUFDS_INTERMDISABLE'. -Generating RTLIL representation for module `\IBUFDS_DIFF_OUT'. -Generating RTLIL representation for module `\IBUFDS_DIFF_OUT_IBUFDISABLE'. -Generating RTLIL representation for module `\IBUFDS_DIFF_OUT_INTERMDISABLE'. -Generating RTLIL representation for module `\IBUFDSE3'. -Generating RTLIL representation for module `\IBUFDS_DPHY'. -Generating RTLIL representation for module `\IBUFGDS'. -Generating RTLIL representation for module `\IBUFGDS_DIFF_OUT'. -Generating RTLIL representation for module `\IOBUF_DCIEN'. -Generating RTLIL representation for module `\IOBUF_INTERMDISABLE'. -Generating RTLIL representation for module `\IOBUFE3'. -Generating RTLIL representation for module `\IOBUFDS'. -Generating RTLIL representation for module `\IOBUFDS_DCIEN'. -Generating RTLIL representation for module `\IOBUFDS_INTERMDISABLE'. -Generating RTLIL representation for module `\IOBUFDS_DIFF_OUT'. -Generating RTLIL representation for module `\IOBUFDS_DIFF_OUT_DCIEN'. -Generating RTLIL representation for module `\IOBUFDS_DIFF_OUT_INTERMDISABLE'. -Generating RTLIL representation for module `\IOBUFDSE3'. -Generating RTLIL representation for module `\OBUFDS'. -Generating RTLIL representation for module `\OBUFDS_DPHY'. -Generating RTLIL representation for module `\OBUFTDS'. -Generating RTLIL representation for module `\KEEPER'. -Generating RTLIL representation for module `\PULLDOWN'. -Generating RTLIL representation for module `\PULLUP'. -Generating RTLIL representation for module `\DCIRESET'. -Generating RTLIL representation for module `\HPIO_VREF'. -Generating RTLIL representation for module `\BUFGCE'. -Generating RTLIL representation for module `\BUFGCE_1'. -Generating RTLIL representation for module `\BUFGMUX'. -Generating RTLIL representation for module `\BUFGMUX_1'. -Generating RTLIL representation for module `\BUFGMUX_CTRL'. -Generating RTLIL representation for module `\BUFGMUX_VIRTEX4'. -Generating RTLIL representation for module `\BUFG_GT'. -Generating RTLIL representation for module `\BUFG_GT_SYNC'. -Generating RTLIL representation for module `\BUFG_PS'. -Generating RTLIL representation for module `\BUFGCE_DIV'. -Generating RTLIL representation for module `\BUFH'. -Generating RTLIL representation for module `\BUFIO2'. -Generating RTLIL representation for module `\BUFIO2_2CLK'. -Generating RTLIL representation for module `\BUFIO2FB'. -Generating RTLIL representation for module `\BUFPLL'. -Generating RTLIL representation for module `\BUFPLL_MCB'. -Generating RTLIL representation for module `\BUFIO'. -Generating RTLIL representation for module `\BUFIODQS'. -Generating RTLIL representation for module `\BUFR'. -Generating RTLIL representation for module `\BUFMR'. -Generating RTLIL representation for module `\BUFMRCE'. -Generating RTLIL representation for module `\DCM'. -Generating RTLIL representation for module `\DCM_SP'. -Generating RTLIL representation for module `\DCM_CLKGEN'. -Generating RTLIL representation for module `\DCM_ADV'. -Generating RTLIL representation for module `\DCM_BASE'. -Generating RTLIL representation for module `\DCM_PS'. -Generating RTLIL representation for module `\PMCD'. -Generating RTLIL representation for module `\PLL_ADV'. -Generating RTLIL representation for module `\PLL_BASE'. -Generating RTLIL representation for module `\MMCM_ADV'. -Generating RTLIL representation for module `\MMCM_BASE'. -Generating RTLIL representation for module `\MMCME2_ADV'. -Generating RTLIL representation for module `\MMCME2_BASE'. -Generating RTLIL representation for module `\PLLE2_ADV'. -Generating RTLIL representation for module `\PLLE2_BASE'. -Generating RTLIL representation for module `\MMCME3_ADV'. -Generating RTLIL representation for module `\MMCME3_BASE'. -Generating RTLIL representation for module `\PLLE3_ADV'. -Generating RTLIL representation for module `\PLLE3_BASE'. -Generating RTLIL representation for module `\MMCME4_ADV'. -Generating RTLIL representation for module `\MMCME4_BASE'. -Generating RTLIL representation for module `\PLLE4_ADV'. -Generating RTLIL representation for module `\PLLE4_BASE'. -Generating RTLIL representation for module `\BUFT'. -Generating RTLIL representation for module `\IN_FIFO'. -Generating RTLIL representation for module `\OUT_FIFO'. -Generating RTLIL representation for module `\HARD_SYNC'. -Generating RTLIL representation for module `\STARTUP_SPARTAN3'. -Generating RTLIL representation for module `\STARTUP_SPARTAN3E'. -Generating RTLIL representation for module `\STARTUP_SPARTAN3A'. -Generating RTLIL representation for module `\STARTUP_SPARTAN6'. -Generating RTLIL representation for module `\STARTUP_VIRTEX4'. -Generating RTLIL representation for module `\STARTUP_VIRTEX5'. -Generating RTLIL representation for module `\STARTUP_VIRTEX6'. -Generating RTLIL representation for module `\STARTUPE2'. -Generating RTLIL representation for module `\STARTUPE3'. -Generating RTLIL representation for module `\CAPTURE_SPARTAN3'. -Generating RTLIL representation for module `\CAPTURE_SPARTAN3A'. -Generating RTLIL representation for module `\CAPTURE_VIRTEX4'. -Generating RTLIL representation for module `\CAPTURE_VIRTEX5'. -Generating RTLIL representation for module `\CAPTURE_VIRTEX6'. -Generating RTLIL representation for module `\CAPTUREE2'. -Generating RTLIL representation for module `\ICAP_SPARTAN3A'. -Generating RTLIL representation for module `\ICAP_SPARTAN6'. -Generating RTLIL representation for module `\ICAP_VIRTEX4'. -Generating RTLIL representation for module `\ICAP_VIRTEX5'. -Generating RTLIL representation for module `\ICAP_VIRTEX6'. -Generating RTLIL representation for module `\ICAPE2'. -Generating RTLIL representation for module `\ICAPE3'. -Generating RTLIL representation for module `\BSCAN_SPARTAN3'. -Generating RTLIL representation for module `\BSCAN_SPARTAN3A'. -Generating RTLIL representation for module `\BSCAN_SPARTAN6'. -Generating RTLIL representation for module `\BSCAN_VIRTEX4'. -Generating RTLIL representation for module `\BSCAN_VIRTEX5'. -Generating RTLIL representation for module `\BSCAN_VIRTEX6'. -Generating RTLIL representation for module `\BSCANE2'. -Generating RTLIL representation for module `\DNA_PORT'. -Generating RTLIL representation for module `\DNA_PORTE2'. -Generating RTLIL representation for module `\FRAME_ECC_VIRTEX4'. -Generating RTLIL representation for module `\FRAME_ECC_VIRTEX5'. -Generating RTLIL representation for module `\FRAME_ECC_VIRTEX6'. -Generating RTLIL representation for module `\FRAME_ECCE2'. -Generating RTLIL representation for module `\FRAME_ECCE3'. -Generating RTLIL representation for module `\USR_ACCESS_VIRTEX4'. -Generating RTLIL representation for module `\USR_ACCESS_VIRTEX5'. -Generating RTLIL representation for module `\USR_ACCESS_VIRTEX6'. -Generating RTLIL representation for module `\USR_ACCESSE2'. -Generating RTLIL representation for module `\POST_CRC_INTERNAL'. -Generating RTLIL representation for module `\SUSPEND_SYNC'. -Generating RTLIL representation for module `\KEY_CLEAR'. -Generating RTLIL representation for module `\MASTER_JTAG'. -Generating RTLIL representation for module `\SPI_ACCESS'. -Generating RTLIL representation for module `\EFUSE_USR'. -Generating RTLIL representation for module `\SYSMON'. -Generating RTLIL representation for module `\XADC'. -Generating RTLIL representation for module `\SYSMONE1'. -Generating RTLIL representation for module `\SYSMONE4'. -Generating RTLIL representation for module `\GTPA1_DUAL'. -Generating RTLIL representation for module `\GT11_CUSTOM'. -Generating RTLIL representation for module `\GT11_DUAL'. -Generating RTLIL representation for module `\GT11CLK'. -Generating RTLIL representation for module `\GT11CLK_MGT'. -Generating RTLIL representation for module `\GTP_DUAL'. -Generating RTLIL representation for module `\GTX_DUAL'. -Generating RTLIL representation for module `\CRC32'. -Generating RTLIL representation for module `\CRC64'. -Generating RTLIL representation for module `\GTHE1_QUAD'. -Generating RTLIL representation for module `\GTXE1'. -Generating RTLIL representation for module `\IBUFDS_GTXE1'. -Generating RTLIL representation for module `\IBUFDS_GTHE1'. -Generating RTLIL representation for module `\GTHE2_CHANNEL'. -Generating RTLIL representation for module `\GTHE2_COMMON'. -Generating RTLIL representation for module `\GTPE2_CHANNEL'. -Generating RTLIL representation for module `\GTPE2_COMMON'. -Generating RTLIL representation for module `\GTXE2_CHANNEL'. -Generating RTLIL representation for module `\GTXE2_COMMON'. -Generating RTLIL representation for module `\IBUFDS_GTE2'. -Generating RTLIL representation for module `\GTHE3_CHANNEL'. -Generating RTLIL representation for module `\GTHE3_COMMON'. -Generating RTLIL representation for module `\GTHE4_CHANNEL'. -Generating RTLIL representation for module `\GTHE4_COMMON'. -Generating RTLIL representation for module `\GTYE3_CHANNEL'. -Generating RTLIL representation for module `\GTYE3_COMMON'. -Generating RTLIL representation for module `\GTYE4_CHANNEL'. -Generating RTLIL representation for module `\GTYE4_COMMON'. -Generating RTLIL representation for module `\IBUFDS_GTE3'. -Generating RTLIL representation for module `\IBUFDS_GTE4'. -Generating RTLIL representation for module `\OBUFDS_GTE3'. -Generating RTLIL representation for module `\OBUFDS_GTE3_ADV'. -Generating RTLIL representation for module `\OBUFDS_GTE4'. -Generating RTLIL representation for module `\OBUFDS_GTE4_ADV'. -Generating RTLIL representation for module `\PCIE_A1'. -Generating RTLIL representation for module `\PCIE_EP'. -Generating RTLIL representation for module `\PCIE_2_0'. -Generating RTLIL representation for module `\PCIE_2_1'. -Generating RTLIL representation for module `\PCIE_3_0'. -Generating RTLIL representation for module `\PCIE_3_1'. -Generating RTLIL representation for module `\PCIE40E4'. -Generating RTLIL representation for module `\EMAC'. -Generating RTLIL representation for module `\TEMAC'. -Generating RTLIL representation for module `\TEMAC_SINGLE'. -Generating RTLIL representation for module `\CMAC'. -Generating RTLIL representation for module `\CMACE4'. -Generating RTLIL representation for module `\PPC405_ADV'. -Generating RTLIL representation for module `\PPC440'. -Generating RTLIL representation for module `\MCB'. -Generating RTLIL representation for module `\PS7'. -Generating RTLIL representation for module `\PS8'. -Generating RTLIL representation for module `\ILKN'. -Generating RTLIL representation for module `\ILKNE4'. -Successfully finished Verilog frontend. - -6.3. Executing HIERARCHY pass (managing design hierarchy). - -6.3.1. Analyzing design hierarchy.. -Top module: \distributed_ram - -6.3.2. Analyzing design hierarchy.. -Top module: \distributed_ram -Removed 0 unused modules. - -6.4. Executing PROC pass (convert processes to netlists). - -6.4.1. Executing PROC_CLEAN pass (remove empty switches from decision trees). -Cleaned up 0 empty switches. - -6.4.2. Executing PROC_RMDEAD pass (remove dead branches from decision trees). -Removed a total of 0 dead cases. - -6.4.3. Executing PROC_PRUNE pass (remove redundant assignments in processes). -Removed 0 redundant assignments. -Promoted 1 assignment to connection. - -6.4.4. Executing PROC_INIT pass (extract init attributes). - -6.4.5. Executing PROC_ARST pass (detect async resets in processes). - -6.4.6. Executing PROC_MUX pass (convert decision trees to multiplexers). -Creating decoders for process `\distributed_ram.$proc$attributes_test.v:36$188'. - 1/3: $0$memwr$\memory$attributes_test.v:38$187_EN[7:0]$191 - 2/3: $0$memwr$\memory$attributes_test.v:38$187_DATA[7:0]$190 - 3/3: $0$memwr$\memory$attributes_test.v:38$187_ADDR[3:0]$189 - -6.4.7. Executing PROC_DLATCH pass (convert process syncs to latches). - -6.4.8. Executing PROC_DFF pass (convert process syncs to FFs). -Creating register for signal `\distributed_ram.\data_out_r' using process `\distributed_ram.$proc$attributes_test.v:36$188'. - created $dff cell `$procdff$227' with positive edge clock. -Creating register for signal `\distributed_ram.$memwr$\memory$attributes_test.v:38$187_ADDR' using process `\distributed_ram.$proc$attributes_test.v:36$188'. - created $dff cell `$procdff$228' with positive edge clock. -Creating register for signal `\distributed_ram.$memwr$\memory$attributes_test.v:38$187_DATA' using process `\distributed_ram.$proc$attributes_test.v:36$188'. - created $dff cell `$procdff$229' with positive edge clock. -Creating register for signal `\distributed_ram.$memwr$\memory$attributes_test.v:38$187_EN' using process `\distributed_ram.$proc$attributes_test.v:36$188'. - created $dff cell `$procdff$230' with positive edge clock. - -6.4.9. Executing PROC_CLEAN pass (remove empty switches from decision trees). -Found and cleaned up 1 empty switch in `\distributed_ram.$proc$attributes_test.v:36$188'. -Removing empty process `distributed_ram.$proc$attributes_test.v:36$188'. -Cleaned up 1 empty switch. - -6.5. Executing TRIBUF pass. - -6.6. Executing DEMINOUT pass (demote inout ports to input or output). - -6.7. Executing OPT_EXPR pass (perform const folding). -Optimizing module distributed_ram. - -6.8. Executing OPT_CLEAN pass (remove unused cells and wires). -Finding unused cells or wires in module \distributed_ram.. -Removed 0 unused cells and 7 unused wires. - - -6.9. Executing CHECK pass (checking for obvious problems). -checking module distributed_ram.. -found and reported 0 problems. - -6.10. Executing OPT pass (performing simple optimizations). - -6.10.1. Executing OPT_EXPR pass (perform const folding). -Optimizing module distributed_ram. - -6.10.2. Executing OPT_MERGE pass (detect identical cells). -Finding identical cells in module `\distributed_ram'. -Removed a total of 0 cells. - -6.10.3. Executing OPT_MUXTREE pass (detect dead branches in mux trees). -Running muxtree optimizer on module \distributed_ram.. - Creating internal representation of mux trees. - Evaluating internal representation of mux trees. - Analyzing evaluation results. -Removed 0 multiplexer ports. - - -6.10.4. Executing OPT_REDUCE pass (consolidate $*mux and $reduce_* inputs). - Optimizing cells in module \distributed_ram. - Consolidated identical input bits for $mux cell $procmux$221: - Old ports: A=8'00000000, B=8'11111111, Y=$0$memwr$\memory$attributes_test.v:38$187_EN[7:0]$191 - New ports: A=1'0, B=1'1, Y=$0$memwr$\memory$attributes_test.v:38$187_EN[7:0]$191 [0] - New connections: $0$memwr$\memory$attributes_test.v:38$187_EN[7:0]$191 [7:1] = { $0$memwr$\memory$attributes_test.v:38$187_EN[7:0]$191 [0] $0$memwr$\memory$attributes_test.v:38$187_EN[7:0]$191 [0] $0$memwr$\memory$attributes_test.v:38$187_EN[7:0]$191 [0] $0$memwr$\memory$attributes_test.v:38$187_EN[7:0]$191 [0] $0$memwr$\memory$attributes_test.v:38$187_EN[7:0]$191 [0] $0$memwr$\memory$attributes_test.v:38$187_EN[7:0]$191 [0] $0$memwr$\memory$attributes_test.v:38$187_EN[7:0]$191 [0] } - Optimizing cells in module \distributed_ram. -Performed a total of 1 changes. - -6.10.5. Executing OPT_MERGE pass (detect identical cells). -Finding identical cells in module `\distributed_ram'. -Removed a total of 0 cells. - -6.10.6. Executing OPT_RMDFF pass (remove dff with constant values). - -6.10.7. Executing OPT_CLEAN pass (remove unused cells and wires). -Finding unused cells or wires in module \distributed_ram.. - -6.10.8. Executing OPT_EXPR pass (perform const folding). -Optimizing module distributed_ram. - -6.10.9. Rerunning OPT passes. (Maybe there is more to do..) - -6.10.10. Executing OPT_MUXTREE pass (detect dead branches in mux trees). -Running muxtree optimizer on module \distributed_ram.. - Creating internal representation of mux trees. - Evaluating internal representation of mux trees. - Analyzing evaluation results. -Removed 0 multiplexer ports. - - -6.10.11. Executing OPT_REDUCE pass (consolidate $*mux and $reduce_* inputs). - Optimizing cells in module \distributed_ram. -Performed a total of 0 changes. - -6.10.12. Executing OPT_MERGE pass (detect identical cells). -Finding identical cells in module `\distributed_ram'. -Removed a total of 0 cells. - -6.10.13. Executing OPT_RMDFF pass (remove dff with constant values). - -6.10.14. Executing OPT_CLEAN pass (remove unused cells and wires). -Finding unused cells or wires in module \distributed_ram.. - -6.10.15. Executing OPT_EXPR pass (perform const folding). -Optimizing module distributed_ram. - -6.10.16. Finished OPT passes. (There is nothing left to do.) - -6.11. Executing WREDUCE pass (reducing word size of cells). -Removed cell distributed_ram.$procmux$223 ($mux). -Removed cell distributed_ram.$procmux$225 ($mux). -Removed top 7 bits (of 8) from FF cell distributed_ram.$procdff$230 ($dff). - -6.12. Executing PEEPOPT pass (run peephole optimizers). - -6.13. Executing OPT_CLEAN pass (remove unused cells and wires). -Finding unused cells or wires in module \distributed_ram.. -Removed 0 unused cells and 2 unused wires. - - -6.14. Executing PMUX2SHIFTX pass. - -6.15. Executing TECHMAP pass (map to technology primitives). - -6.15.1. Executing Verilog-2005 frontend: /opt/eda/fpga/FOSS/memattr/yosys_release/share/cmp2lut.v -Parsing Verilog input from `/opt/eda/fpga/FOSS/memattr/yosys_release/share/cmp2lut.v' to AST representation. -Generating RTLIL representation for module `\_90_lut_cmp_'. -Successfully finished Verilog frontend. - -6.15.2. Continuing TECHMAP pass. -No more expansions possible. - -6.16. Executing MEMORY_DFF pass (merging $dff cells to $memrd and $memwr). -Checking cell `$memwr$\memory$attributes_test.v:38$193' in module `\distributed_ram': merged $dff to cell. -Checking cell `$memrd$\memory$attributes_test.v:39$192' in module `\distributed_ram': merged data $dff to cell. - -6.17. Executing TECHMAP pass (map to technology primitives). - -6.17.1. Executing Verilog-2005 frontend: /opt/eda/fpga/FOSS/memattr/yosys_release/share/mul2dsp.v -Parsing Verilog input from `/opt/eda/fpga/FOSS/memattr/yosys_release/share/mul2dsp.v' to AST representation. -Generating RTLIL representation for module `\_80_mul'. -Generating RTLIL representation for module `\_90_soft_mul'. -Successfully finished Verilog frontend. - -6.17.2. Executing Verilog-2005 frontend: /opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/xc7_dsp_map.v -Parsing Verilog input from `/opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/xc7_dsp_map.v' to AST representation. -Generating RTLIL representation for module `\$__MUL25X18'. -Successfully finished Verilog frontend. - -6.17.3. Continuing TECHMAP pass. -No more expansions possible. - -6.18. Executing OPT_EXPR pass (perform const folding). - -6.19. Executing WREDUCE pass (reducing word size of cells). - -6.20. Executing XILINX_DSP pass (pack resources into DSPs). - -6.21. Executing ALUMACC pass (create $alu and $macc cells). -Extracting $alu and $macc cells in module distributed_ram: - created 0 $alu and 0 $macc cells. - -6.22. Executing SHARE pass (SAT-based resource sharing). - -6.23. Executing OPT pass (performing simple optimizations). - -6.23.1. Executing OPT_EXPR pass (perform const folding). -Optimizing module distributed_ram. - -6.23.2. Executing OPT_MERGE pass (detect identical cells). -Finding identical cells in module `\distributed_ram'. -Removed a total of 0 cells. - -6.23.3. Executing OPT_MUXTREE pass (detect dead branches in mux trees). -Running muxtree optimizer on module \distributed_ram.. - Creating internal representation of mux trees. - Evaluating internal representation of mux trees. - Analyzing evaluation results. -Removed 0 multiplexer ports. - - -6.23.4. Executing OPT_REDUCE pass (consolidate $*mux and $reduce_* inputs). - Optimizing cells in module \distributed_ram. -Performed a total of 0 changes. - -6.23.5. Executing OPT_MERGE pass (detect identical cells). -Finding identical cells in module `\distributed_ram'. -Removed a total of 0 cells. - -6.23.6. Executing OPT_RMDFF pass (remove dff with constant values). - -6.23.7. Executing OPT_CLEAN pass (remove unused cells and wires). -Finding unused cells or wires in module \distributed_ram.. -Removed 4 unused cells and 5 unused wires. - - -6.23.8. Executing OPT_EXPR pass (perform const folding). -Optimizing module distributed_ram. - -6.23.9. Rerunning OPT passes. (Maybe there is more to do..) - -6.23.10. Executing OPT_MUXTREE pass (detect dead branches in mux trees). -Running muxtree optimizer on module \distributed_ram.. - Creating internal representation of mux trees. - Evaluating internal representation of mux trees. - Analyzing evaluation results. -Removed 0 multiplexer ports. - - -6.23.11. Executing OPT_REDUCE pass (consolidate $*mux and $reduce_* inputs). - Optimizing cells in module \distributed_ram. -Performed a total of 0 changes. - -6.23.12. Executing OPT_MERGE pass (detect identical cells). -Finding identical cells in module `\distributed_ram'. -Removed a total of 0 cells. - -6.23.13. Executing OPT_RMDFF pass (remove dff with constant values). - -6.23.14. Executing OPT_CLEAN pass (remove unused cells and wires). -Finding unused cells or wires in module \distributed_ram.. - -6.23.15. Executing OPT_EXPR pass (perform const folding). -Optimizing module distributed_ram. - -6.23.16. Finished OPT passes. (There is nothing left to do.) - -6.24. Executing FSM pass (extract and optimize FSM). - -6.24.1. Executing FSM_DETECT pass (finding FSMs in design). - -6.24.2. Executing FSM_EXTRACT pass (extracting FSM from design). - -6.24.3. Executing FSM_OPT pass (simple optimizations of FSMs). - -6.24.4. Executing OPT_CLEAN pass (remove unused cells and wires). -Finding unused cells or wires in module \distributed_ram.. - -6.24.5. Executing FSM_OPT pass (simple optimizations of FSMs). - -6.24.6. Executing FSM_RECODE pass (re-assigning FSM state encoding). - -6.24.7. Executing FSM_INFO pass (dumping all available information on FSM cells). - -6.24.8. Executing FSM_MAP pass (mapping FSMs to basic logic). - -6.25. Executing OPT pass (performing simple optimizations). - -6.25.1. Executing OPT_EXPR pass (perform const folding). -Optimizing module distributed_ram. - -6.25.2. Executing OPT_MERGE pass (detect identical cells). -Finding identical cells in module `\distributed_ram'. -Removed a total of 0 cells. - -6.25.3. Executing OPT_RMDFF pass (remove dff with constant values). - -6.25.4. Executing OPT_CLEAN pass (remove unused cells and wires). -Finding unused cells or wires in module \distributed_ram.. - -6.25.5. Finished fast OPT passes. - -6.26. Executing MEMORY pass. - -6.26.1. Executing OPT_MEM pass (optimize memories). -Performed a total of 0 transformations. - -6.26.2. Executing MEMORY_DFF pass (merging $dff cells to $memrd and $memwr). - -6.26.3. Executing OPT_CLEAN pass (remove unused cells and wires). -Finding unused cells or wires in module \distributed_ram.. - -6.26.4. Executing MEMORY_SHARE pass (consolidating $memrd/$memwr cells). - -6.26.5. Executing OPT_CLEAN pass (remove unused cells and wires). -Finding unused cells or wires in module \distributed_ram.. - -6.26.6. Executing MEMORY_COLLECT pass (generating $mem cells). -Collecting $memrd, $memwr and $meminit for memory `\memory' in module `\distributed_ram': - $memwr$\memory$attributes_test.v:38$193 ($memwr) - $memrd$\memory$attributes_test.v:39$192 ($memrd) - -6.27. Executing OPT_CLEAN pass (remove unused cells and wires). -Finding unused cells or wires in module \distributed_ram.. - -6.28. Executing MEMORY_BRAM pass (mapping $mem cells to block memories). -Processing distributed_ram.memory: - Properties: ports=2 bits=128 rports=1 wports=1 dbits=8 abits=4 words=16 - Checking rule #1 for bram type $__XILINX_RAMB36_SDP (variant 1): - Bram geometry: abits=9 dbits=72 wports=0 rports=0 - Estimated number of duplicates for more read ports: dups=1 - Metrics for $__XILINX_RAMB36_SDP: awaste=496 dwaste=64 bwaste=36736 waste=36736 efficiency=0 - Rule #1 for bram type $__XILINX_RAMB36_SDP (variant 1) rejected: requirement 'min efficiency 5' not met. - Checking rule #2 for bram type $__XILINX_RAMB18_SDP (variant 1): - Bram geometry: abits=9 dbits=36 wports=0 rports=0 - Estimated number of duplicates for more read ports: dups=1 - Metrics for $__XILINX_RAMB18_SDP: awaste=496 dwaste=28 bwaste=18304 waste=18304 efficiency=0 - Rule #2 for bram type $__XILINX_RAMB18_SDP (variant 1) rejected: requirement 'min efficiency 5' not met. - Checking rule #3 for bram type $__XILINX_RAMB36_TDP (variant 1): - Bram geometry: abits=10 dbits=36 wports=0 rports=0 - Estimated number of duplicates for more read ports: dups=1 - Metrics for $__XILINX_RAMB36_TDP: awaste=1008 dwaste=28 bwaste=36736 waste=36736 efficiency=0 - Rule #3 for bram type $__XILINX_RAMB36_TDP (variant 1) rejected: requirement 'min efficiency 5' not met. - Checking rule #3 for bram type $__XILINX_RAMB36_TDP (variant 2): - Bram geometry: abits=11 dbits=18 wports=0 rports=0 - Estimated number of duplicates for more read ports: dups=1 - Metrics for $__XILINX_RAMB36_TDP: awaste=2032 dwaste=10 bwaste=36736 waste=36736 efficiency=0 - Rule #3 for bram type $__XILINX_RAMB36_TDP (variant 2) rejected: requirement 'min efficiency 5' not met. - Checking rule #3 for bram type $__XILINX_RAMB36_TDP (variant 3): - Bram geometry: abits=12 dbits=9 wports=0 rports=0 - Estimated number of duplicates for more read ports: dups=1 - Metrics for $__XILINX_RAMB36_TDP: awaste=4080 dwaste=1 bwaste=36736 waste=36736 efficiency=0 - Rule #3 for bram type $__XILINX_RAMB36_TDP (variant 3) rejected: requirement 'min efficiency 5' not met. - Checking rule #3 for bram type $__XILINX_RAMB36_TDP (variant 4): - Bram geometry: abits=13 dbits=4 wports=0 rports=0 - Estimated number of duplicates for more read ports: dups=1 - Metrics for $__XILINX_RAMB36_TDP: awaste=8176 dwaste=0 bwaste=32704 waste=32704 efficiency=0 - Rule #3 for bram type $__XILINX_RAMB36_TDP (variant 4) rejected: requirement 'min efficiency 5' not met. - Checking rule #3 for bram type $__XILINX_RAMB36_TDP (variant 5): - Bram geometry: abits=14 dbits=2 wports=0 rports=0 - Estimated number of duplicates for more read ports: dups=1 - Metrics for $__XILINX_RAMB36_TDP: awaste=16368 dwaste=0 bwaste=32736 waste=32736 efficiency=0 - Rule #3 for bram type $__XILINX_RAMB36_TDP (variant 5) rejected: requirement 'min efficiency 5' not met. - Checking rule #3 for bram type $__XILINX_RAMB36_TDP (variant 6): - Bram geometry: abits=15 dbits=1 wports=0 rports=0 - Estimated number of duplicates for more read ports: dups=1 - Metrics for $__XILINX_RAMB36_TDP: awaste=32752 dwaste=0 bwaste=32752 waste=32752 efficiency=0 - Rule #3 for bram type $__XILINX_RAMB36_TDP (variant 6) rejected: requirement 'min efficiency 5' not met. - Checking rule #4 for bram type $__XILINX_RAMB18_TDP (variant 1): - Bram geometry: abits=10 dbits=18 wports=0 rports=0 - Estimated number of duplicates for more read ports: dups=1 - Metrics for $__XILINX_RAMB18_TDP: awaste=1008 dwaste=10 bwaste=18304 waste=18304 efficiency=0 - Rule #4 for bram type $__XILINX_RAMB18_TDP (variant 1) rejected: requirement 'min efficiency 5' not met. - Checking rule #4 for bram type $__XILINX_RAMB18_TDP (variant 2): - Bram geometry: abits=11 dbits=9 wports=0 rports=0 - Estimated number of duplicates for more read ports: dups=1 - Metrics for $__XILINX_RAMB18_TDP: awaste=2032 dwaste=1 bwaste=18304 waste=18304 efficiency=0 - Rule #4 for bram type $__XILINX_RAMB18_TDP (variant 2) rejected: requirement 'min efficiency 5' not met. - Checking rule #4 for bram type $__XILINX_RAMB18_TDP (variant 3): - Bram geometry: abits=12 dbits=4 wports=0 rports=0 - Estimated number of duplicates for more read ports: dups=1 - Metrics for $__XILINX_RAMB18_TDP: awaste=4080 dwaste=0 bwaste=16320 waste=16320 efficiency=0 - Rule #4 for bram type $__XILINX_RAMB18_TDP (variant 3) rejected: requirement 'min efficiency 5' not met. - Checking rule #4 for bram type $__XILINX_RAMB18_TDP (variant 4): - Bram geometry: abits=13 dbits=2 wports=0 rports=0 - Estimated number of duplicates for more read ports: dups=1 - Metrics for $__XILINX_RAMB18_TDP: awaste=8176 dwaste=0 bwaste=16352 waste=16352 efficiency=0 - Rule #4 for bram type $__XILINX_RAMB18_TDP (variant 4) rejected: requirement 'min efficiency 5' not met. - Checking rule #4 for bram type $__XILINX_RAMB18_TDP (variant 5): - Bram geometry: abits=14 dbits=1 wports=0 rports=0 - Estimated number of duplicates for more read ports: dups=1 - Metrics for $__XILINX_RAMB18_TDP: awaste=16368 dwaste=0 bwaste=16368 waste=16368 efficiency=0 - Rule #4 for bram type $__XILINX_RAMB18_TDP (variant 5) rejected: requirement 'min efficiency 5' not met. - No acceptable bram resources found. - -6.29. Executing TECHMAP pass (map to technology primitives). - -6.29.1. Executing Verilog-2005 frontend: /opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/xc7_brams_map.v -Parsing Verilog input from `/opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/xc7_brams_map.v' to AST representation. -Generating RTLIL representation for module `\$__XILINX_RAMB36_SDP'. -Generating RTLIL representation for module `\$__XILINX_RAMB18_SDP'. -Generating RTLIL representation for module `\$__XILINX_RAMB36_TDP'. -Generating RTLIL representation for module `\$__XILINX_RAMB18_TDP'. -Successfully finished Verilog frontend. - -6.29.2. Continuing TECHMAP pass. -No more expansions possible. - -6.30. Executing MEMORY_BRAM pass (mapping $mem cells to block memories). -Processing distributed_ram.memory: - Properties: ports=2 bits=128 rports=1 wports=1 dbits=8 abits=4 words=16 - Checking rule #1 for bram type $__XILINX_RAM32X1D (variant 1): - Bram geometry: abits=5 dbits=1 wports=0 rports=0 - Estimated number of duplicates for more read ports: dups=1 - Metrics for $__XILINX_RAM32X1D: awaste=16 dwaste=0 bwaste=16 waste=16 efficiency=50 - Rule #1 for bram type $__XILINX_RAM32X1D (variant 1) accepted. - Mapping to bram type $__XILINX_RAM32X1D (variant 1): - Write port #0 is in clock domain \clk. - Mapped to bram port B1. - Read port #0 is in clock domain \clk. - Mapped to bram port A1.1. - Updated properties: dups=1 waste=16 efficiency=50 - Storing for later selection. - Checking rule #2 for bram type $__XILINX_RAM64X1D (variant 1): - Bram geometry: abits=6 dbits=1 wports=0 rports=0 - Estimated number of duplicates for more read ports: dups=1 - Metrics for $__XILINX_RAM64X1D: awaste=48 dwaste=0 bwaste=48 waste=48 efficiency=25 - Rule #2 for bram type $__XILINX_RAM64X1D (variant 1) accepted. - Mapping to bram type $__XILINX_RAM64X1D (variant 1): - Write port #0 is in clock domain \clk. - Mapped to bram port B1. - Read port #0 is in clock domain \clk. - Mapped to bram port A1.1. - Updated properties: dups=1 waste=48 efficiency=25 - Storing for later selection. - Checking rule #3 for bram type $__XILINX_RAM128X1D (variant 1): - Bram geometry: abits=7 dbits=1 wports=0 rports=0 - Estimated number of duplicates for more read ports: dups=1 - Metrics for $__XILINX_RAM128X1D: awaste=112 dwaste=0 bwaste=112 waste=112 efficiency=12 - Rule #3 for bram type $__XILINX_RAM128X1D (variant 1) accepted. - Mapping to bram type $__XILINX_RAM128X1D (variant 1): - Write port #0 is in clock domain \clk. - Mapped to bram port B1. - Read port #0 is in clock domain \clk. - Mapped to bram port A1.1. - Updated properties: dups=1 waste=112 efficiency=12 - Storing for later selection. - Selecting best of 3 rules: - Efficiency for rule 3.1: efficiency=12, cells=8, acells=1 - Efficiency for rule 2.1: efficiency=25, cells=8, acells=1 - Efficiency for rule 1.1: efficiency=50, cells=8, acells=1 - Selected rule 1.1 with efficiency 50. - Mapping to bram type $__XILINX_RAM32X1D (variant 1): - Write port #0 is in clock domain \clk. - Mapped to bram port B1. - Read port #0 is in clock domain \clk. - Mapped to bram port A1.1. - Creating $__XILINX_RAM32X1D cell at grid position <0 0 0>: memory.0.0.0 - Creating $__XILINX_RAM32X1D cell at grid position <1 0 0>: memory.1.0.0 - Creating $__XILINX_RAM32X1D cell at grid position <2 0 0>: memory.2.0.0 - Creating $__XILINX_RAM32X1D cell at grid position <3 0 0>: memory.3.0.0 - Creating $__XILINX_RAM32X1D cell at grid position <4 0 0>: memory.4.0.0 - Creating $__XILINX_RAM32X1D cell at grid position <5 0 0>: memory.5.0.0 - Creating $__XILINX_RAM32X1D cell at grid position <6 0 0>: memory.6.0.0 - Creating $__XILINX_RAM32X1D cell at grid position <7 0 0>: memory.7.0.0 - -6.31. Executing TECHMAP pass (map to technology primitives). - -6.31.1. Executing Verilog-2005 frontend: /opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/lutrams_map.v -Parsing Verilog input from `/opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/lutrams_map.v' to AST representation. -Generating RTLIL representation for module `\$__XILINX_RAM32X1D'. -Generating RTLIL representation for module `\$__XILINX_RAM64X1D'. -Generating RTLIL representation for module `\$__XILINX_RAM128X1D'. -Successfully finished Verilog frontend. - -6.31.2. Continuing TECHMAP pass. -Using template $paramod\$__XILINX_RAM32X1D\CLKPOL2=1 for cells of type $__XILINX_RAM32X1D. -No more expansions possible. - - -6.32. Executing OPT pass (performing simple optimizations). - -6.32.1. Executing OPT_EXPR pass (perform const folding). -Optimizing module distributed_ram. - - -6.32.2. Executing OPT_MERGE pass (detect identical cells). -Finding identical cells in module `\distributed_ram'. -Removed a total of 0 cells. - -6.32.3. Executing OPT_RMDFF pass (remove dff with constant values). - -6.32.4. Executing OPT_CLEAN pass (remove unused cells and wires). -Finding unused cells or wires in module \distributed_ram.. -Removed 0 unused cells and 65 unused wires. - - -6.32.5. Finished fast OPT passes. - -6.33. Executing MEMORY_MAP pass (converting $mem cells to logic and flip-flops). - -6.34. Executing DFFSR2DFF pass (mapping DFFSR cells to simpler FFs). - -6.35. Executing DFF2DFFE pass (transform $dff to $dffe where applicable). -Transforming FF to FF+Enable cells in module distributed_ram: - -6.36. Executing OPT pass (performing simple optimizations). - -6.36.1. Executing OPT_EXPR pass (perform const folding). -Optimizing module distributed_ram. - -6.36.2. Executing OPT_MERGE pass (detect identical cells). -Finding identical cells in module `\distributed_ram'. -Removed a total of 0 cells. - -6.36.3. Executing OPT_MUXTREE pass (detect dead branches in mux trees). -Running muxtree optimizer on module \distributed_ram.. - Creating internal representation of mux trees. - No muxes found in this module. -Removed 0 multiplexer ports. - -6.36.4. Executing OPT_REDUCE pass (consolidate $*mux and $reduce_* inputs). - Optimizing cells in module \distributed_ram. -Performed a total of 0 changes. - -6.36.5. Executing OPT_MERGE pass (detect identical cells). -Finding identical cells in module `\distributed_ram'. -Removed a total of 0 cells. - -6.36.6. Executing OPT_SHARE pass. - -6.36.7. Executing OPT_RMDFF pass (remove dff with constant values). - -6.36.8. Executing OPT_CLEAN pass (remove unused cells and wires). -Finding unused cells or wires in module \distributed_ram.. - -6.36.9. Executing OPT_EXPR pass (perform const folding). -Optimizing module distributed_ram. - -6.36.10. Finished OPT passes. (There is nothing left to do.) - -6.37. Executing XILINX_SRL pass (Xilinx shift register extraction). - -6.38. Executing TECHMAP pass (map to technology primitives). - -6.38.1. Executing Verilog-2005 frontend: /opt/eda/fpga/FOSS/memattr/yosys_release/share/techmap.v -Parsing Verilog input from `/opt/eda/fpga/FOSS/memattr/yosys_release/share/techmap.v' to AST representation. -Generating RTLIL representation for module `\_90_simplemap_bool_ops'. -Generating RTLIL representation for module `\_90_simplemap_reduce_ops'. -Generating RTLIL representation for module `\_90_simplemap_logic_ops'. -Generating RTLIL representation for module `\_90_simplemap_compare_ops'. -Generating RTLIL representation for module `\_90_simplemap_various'. -Generating RTLIL representation for module `\_90_simplemap_registers'. -Generating RTLIL representation for module `\_90_shift_ops_shr_shl_sshl_sshr'. -Generating RTLIL representation for module `\_90_shift_shiftx'. -Generating RTLIL representation for module `\_90_fa'. -Generating RTLIL representation for module `\_90_lcu'. -Generating RTLIL representation for module `\_90_alu'. -Generating RTLIL representation for module `\_90_macc'. -Generating RTLIL representation for module `\_90_alumacc'. -Generating RTLIL representation for module `\$__div_mod_u'. -Generating RTLIL representation for module `\$__div_mod'. -Generating RTLIL representation for module `\_90_div'. -Generating RTLIL representation for module `\_90_mod'. -Generating RTLIL representation for module `\_90_pow'. -Generating RTLIL representation for module `\_90_pmux'. -Generating RTLIL representation for module `\_90_lut'. -Successfully finished Verilog frontend. - -6.38.2. Executing Verilog-2005 frontend: /opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/arith_map.v -Parsing Verilog input from `/opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/arith_map.v' to AST representation. -Generating RTLIL representation for module `\_80_xilinx_lcu'. -Generating RTLIL representation for module `\_80_xilinx_alu'. -Successfully finished Verilog frontend. - -6.38.3. Continuing TECHMAP pass. -Using extmapper simplemap for cells of type $dff. -No more expansions possible. - - -6.39. Executing OPT pass (performing simple optimizations). - -6.39.1. Executing OPT_EXPR pass (perform const folding). -Optimizing module distributed_ram. - -6.39.2. Executing OPT_MERGE pass (detect identical cells). -Finding identical cells in module `\distributed_ram'. -Removed a total of 0 cells. - -6.39.3. Executing OPT_RMDFF pass (remove dff with constant values). - -6.39.4. Executing OPT_CLEAN pass (remove unused cells and wires). -Finding unused cells or wires in module \distributed_ram.. - -6.39.5. Finished fast OPT passes. - -6.40. Executing TECHMAP pass (map to technology primitives). - -6.40.1. Executing Verilog-2005 frontend: /opt/eda/fpga/FOSS/memattr/yosys_release/share/techmap.v -Parsing Verilog input from `/opt/eda/fpga/FOSS/memattr/yosys_release/share/techmap.v' to AST representation. -Generating RTLIL representation for module `\_90_simplemap_bool_ops'. -Generating RTLIL representation for module `\_90_simplemap_reduce_ops'. -Generating RTLIL representation for module `\_90_simplemap_logic_ops'. -Generating RTLIL representation for module `\_90_simplemap_compare_ops'. -Generating RTLIL representation for module `\_90_simplemap_various'. -Generating RTLIL representation for module `\_90_simplemap_registers'. -Generating RTLIL representation for module `\_90_shift_ops_shr_shl_sshl_sshr'. -Generating RTLIL representation for module `\_90_shift_shiftx'. -Generating RTLIL representation for module `\_90_fa'. -Generating RTLIL representation for module `\_90_lcu'. -Generating RTLIL representation for module `\_90_alu'. -Generating RTLIL representation for module `\_90_macc'. -Generating RTLIL representation for module `\_90_alumacc'. -Generating RTLIL representation for module `\$__div_mod_u'. -Generating RTLIL representation for module `\$__div_mod'. -Generating RTLIL representation for module `\_90_div'. -Generating RTLIL representation for module `\_90_mod'. -Generating RTLIL representation for module `\_90_pow'. -Generating RTLIL representation for module `\_90_pmux'. -Generating RTLIL representation for module `\_90_lut'. -Successfully finished Verilog frontend. - -6.40.2. Executing Verilog-2005 frontend: /opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/cells_map.v -Parsing Verilog input from `/opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/cells_map.v' to AST representation. -Generating RTLIL representation for module `\_90_dff_nn0_to_np0'. -Generating RTLIL representation for module `\_90_dff_pn0_to_pp0'. -Generating RTLIL representation for module `\_90_dff_nn1_to_np1'. -Generating RTLIL representation for module `\_90_dff_pn1_to_pp1'. -Generating RTLIL representation for module `\$__SHREG_'. -Generating RTLIL representation for module `\$__XILINX_SHREG_'. -Generating RTLIL representation for module `\$__XILINX_MUXF78'. -Generating RTLIL representation for module `\$__XILINX_TINOUTPAD'. -Generating RTLIL representation for module `\$__XILINX_TOUTPAD'. -Successfully finished Verilog frontend. - -6.40.3. Continuing TECHMAP pass. -No more expansions possible. - -6.41. Executing OPT_EXPR pass (perform const folding). -Optimizing module distributed_ram. - -6.42. Executing ABC pass (technology mapping using ABC). - -6.42.1. Extracting gate netlist of module `\distributed_ram' to `/input.blif'.. -Extracted 0 gates and 0 wires to a netlist network with 0 inputs and 0 outputs. -Don't call ABC as there is nothing to map. -Removing temp directory. - -6.43. Executing XILINX_SRL pass (Xilinx shift register extraction). - -6.44. Executing TECHMAP pass (map to technology primitives). - -6.44.1. Executing Verilog-2005 frontend: /opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/lut_map.v -Parsing Verilog input from `/opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/lut_map.v' to AST representation. -Generating RTLIL representation for module `\$lut'. -Successfully finished Verilog frontend. - -6.44.2. Executing Verilog-2005 frontend: /opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/cells_map.v -Parsing Verilog input from `/opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/cells_map.v' to AST representation. -Generating RTLIL representation for module `\_90_dff_nn0_to_np0'. -Generating RTLIL representation for module `\_90_dff_pn0_to_pp0'. -Generating RTLIL representation for module `\_90_dff_nn1_to_np1'. -Generating RTLIL representation for module `\_90_dff_pn1_to_pp1'. -Generating RTLIL representation for module `\$__SHREG_'. -Generating RTLIL representation for module `\$__XILINX_SHREG_'. -Generating RTLIL representation for module `\$__XILINX_MUXF78'. -Generating RTLIL representation for module `\$__XILINX_TINOUTPAD'. -Generating RTLIL representation for module `\$__XILINX_TOUTPAD'. -Successfully finished Verilog frontend. - -6.44.3. Executing Verilog-2005 frontend: /opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/xc7_ff_map.v -Parsing Verilog input from `/opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/xc7_ff_map.v' to AST representation. -Generating RTLIL representation for module `\$_DFF_N_'. -Generating RTLIL representation for module `\$_DFF_P_'. -Generating RTLIL representation for module `\$_DFFE_NP_'. -Generating RTLIL representation for module `\$_DFFE_PP_'. -Generating RTLIL representation for module `\$_DFF_NN0_'. -Generating RTLIL representation for module `\$_DFF_NP0_'. -Generating RTLIL representation for module `\$_DFF_PN0_'. -Generating RTLIL representation for module `\$_DFF_PP0_'. -Generating RTLIL representation for module `\$_DFF_NN1_'. -Generating RTLIL representation for module `\$_DFF_NP1_'. -Generating RTLIL representation for module `\$_DFF_PN1_'. -Generating RTLIL representation for module `\$_DFF_PP1_'. -Generating RTLIL representation for module `\$_DLATCH_N_'. -Generating RTLIL representation for module `\$_DLATCH_P_'. -Successfully finished Verilog frontend. - -6.44.4. Continuing TECHMAP pass. -Using template $paramod\$_DFF_P_\_TECHMAP_WIREINIT_Q_=1'x for cells of type $_DFF_P_. -No more expansions possible. - -Removed 0 unused cells and 32 unused wires. - -6.45. Executing CLKBUFMAP pass (inserting global clock buffers). -Inserting BUFG on distributed_ram.clk[0]. - -6.46. Executing HIERARCHY pass (managing design hierarchy). - -6.46.1. Analyzing design hierarchy.. -Top module: \distributed_ram - -6.46.2. Analyzing design hierarchy.. -Top module: \distributed_ram -Removed 0 unused modules. - -6.47. Printing statistics. - -=== distributed_ram === - - Number of wires: 16 - Number of wire bits: 40 - Number of public wires: 6 - Number of public wire bits: 30 - Number of memories: 0 - Number of memory bits: 0 - Number of processes: 0 - Number of cells: 17 - BUFG 1 - FDRE 8 - RAM32X1D 8 - - Estimated number of LCs: 0 - -6.48. Executing CHECK pass (checking for obvious problems). -checking module distributed_ram.. -found and reported 0 problems. - -7. Executing Verilog-2005 frontend: attributes_test.v -Parsing Verilog input from `attributes_test.v' to AST representation. -Generating RTLIL representation for module `\block_ram'. -Generating RTLIL representation for module `\distributed_ram'. -Generating RTLIL representation for module `\distributed_ram_manual'. -Generating RTLIL representation for module `\distributed_ram_manual_syn'. -Successfully finished Verilog frontend. - -8. Executing PREP pass. - -8.1. Executing HIERARCHY pass (managing design hierarchy). - -8.2. Executing PROC pass (convert processes to netlists). - -8.2.1. Executing PROC_CLEAN pass (remove empty switches from decision trees). -Cleaned up 0 empty switches. - -8.2.2. Executing PROC_RMDEAD pass (remove dead branches from decision trees). -Removed a total of 0 dead cases. - -8.2.3. Executing PROC_PRUNE pass (remove redundant assignments in processes). -Removed 0 redundant assignments. -Promoted 4 assignments to connections. - -8.2.4. Executing PROC_INIT pass (extract init attributes). - -8.2.5. Executing PROC_ARST pass (detect async resets in processes). - -8.2.6. Executing PROC_MUX pass (convert decision trees to multiplexers). -Creating decoders for process `\distributed_ram_manual_syn.$proc$attributes_test.v:80$441'. - 1/3: $0$memwr$\memory$attributes_test.v:82$440_EN[7:0]$443 - 2/3: $0$memwr$\memory$attributes_test.v:82$440_DATA[7:0]$444 - 3/3: $0$memwr$\memory$attributes_test.v:82$440_ADDR[3:0]$442 -Creating decoders for process `\distributed_ram_manual.$proc$attributes_test.v:58$434'. - 1/3: $0$memwr$\memory$attributes_test.v:60$433_EN[7:0]$435 - 2/3: $0$memwr$\memory$attributes_test.v:60$433_DATA[7:0]$437 - 3/3: $0$memwr$\memory$attributes_test.v:60$433_ADDR[3:0]$436 -Creating decoders for process `\distributed_ram.$proc$attributes_test.v:36$427'. - 1/3: $0$memwr$\memory$attributes_test.v:38$426_EN[7:0]$430 - 2/3: $0$memwr$\memory$attributes_test.v:38$426_DATA[7:0]$429 - 3/3: $0$memwr$\memory$attributes_test.v:38$426_ADDR[3:0]$428 -Creating decoders for process `\block_ram.$proc$attributes_test.v:14$420'. - 1/3: $0$memwr$\memory$attributes_test.v:16$419_EN[3:0]$423 - 2/3: $0$memwr$\memory$attributes_test.v:16$419_DATA[3:0]$422 - 3/3: $0$memwr$\memory$attributes_test.v:16$419_ADDR[9:0]$421 - -8.2.7. Executing PROC_DLATCH pass (convert process syncs to latches). - -8.2.8. Executing PROC_DFF pass (convert process syncs to FFs). -Creating register for signal `\distributed_ram_manual_syn.$memwr$\memory$attributes_test.v:82$440_ADDR' using process `\distributed_ram_manual_syn.$proc$attributes_test.v:80$441'. - created $dff cell `$procdff$471' with positive edge clock. -Creating register for signal `\distributed_ram_manual_syn.\data_out_r' using process `\distributed_ram_manual_syn.$proc$attributes_test.v:80$441'. - created $dff cell `$procdff$472' with positive edge clock. -Creating register for signal `\distributed_ram_manual_syn.$memwr$\memory$attributes_test.v:82$440_EN' using process `\distributed_ram_manual_syn.$proc$attributes_test.v:80$441'. - created $dff cell `$procdff$473' with positive edge clock. -Creating register for signal `\distributed_ram_manual_syn.$memwr$\memory$attributes_test.v:82$440_DATA' using process `\distributed_ram_manual_syn.$proc$attributes_test.v:80$441'. - created $dff cell `$procdff$474' with positive edge clock. -Creating register for signal `\distributed_ram_manual.$memwr$\memory$attributes_test.v:60$433_EN' using process `\distributed_ram_manual.$proc$attributes_test.v:58$434'. - created $dff cell `$procdff$475' with positive edge clock. -Creating register for signal `\distributed_ram_manual.$memwr$\memory$attributes_test.v:60$433_ADDR' using process `\distributed_ram_manual.$proc$attributes_test.v:58$434'. - created $dff cell `$procdff$476' with positive edge clock. -Creating register for signal `\distributed_ram_manual.$memwr$\memory$attributes_test.v:60$433_DATA' using process `\distributed_ram_manual.$proc$attributes_test.v:58$434'. - created $dff cell `$procdff$477' with positive edge clock. -Creating register for signal `\distributed_ram_manual.\data_out_r' using process `\distributed_ram_manual.$proc$attributes_test.v:58$434'. - created $dff cell `$procdff$478' with positive edge clock. -Creating register for signal `\distributed_ram.$memwr$\memory$attributes_test.v:38$426_ADDR' using process `\distributed_ram.$proc$attributes_test.v:36$427'. - created $dff cell `$procdff$479' with positive edge clock. -Creating register for signal `\distributed_ram.\data_out_r' using process `\distributed_ram.$proc$attributes_test.v:36$427'. - created $dff cell `$procdff$480' with positive edge clock. -Creating register for signal `\distributed_ram.$memwr$\memory$attributes_test.v:38$426_DATA' using process `\distributed_ram.$proc$attributes_test.v:36$427'. - created $dff cell `$procdff$481' with positive edge clock. -Creating register for signal `\distributed_ram.$memwr$\memory$attributes_test.v:38$426_EN' using process `\distributed_ram.$proc$attributes_test.v:36$427'. - created $dff cell `$procdff$482' with positive edge clock. -Creating register for signal `\block_ram.$memwr$\memory$attributes_test.v:16$419_ADDR' using process `\block_ram.$proc$attributes_test.v:14$420'. - created $dff cell `$procdff$483' with positive edge clock. -Creating register for signal `\block_ram.\data_out_r' using process `\block_ram.$proc$attributes_test.v:14$420'. - created $dff cell `$procdff$484' with positive edge clock. -Creating register for signal `\block_ram.$memwr$\memory$attributes_test.v:16$419_DATA' using process `\block_ram.$proc$attributes_test.v:14$420'. - created $dff cell `$procdff$485' with positive edge clock. -Creating register for signal `\block_ram.$memwr$\memory$attributes_test.v:16$419_EN' using process `\block_ram.$proc$attributes_test.v:14$420'. - created $dff cell `$procdff$486' with positive edge clock. - -8.2.9. Executing PROC_CLEAN pass (remove empty switches from decision trees). -Found and cleaned up 1 empty switch in `\distributed_ram_manual_syn.$proc$attributes_test.v:80$441'. -Removing empty process `distributed_ram_manual_syn.$proc$attributes_test.v:80$441'. -Found and cleaned up 1 empty switch in `\distributed_ram_manual.$proc$attributes_test.v:58$434'. -Removing empty process `distributed_ram_manual.$proc$attributes_test.v:58$434'. -Found and cleaned up 1 empty switch in `\distributed_ram.$proc$attributes_test.v:36$427'. -Removing empty process `distributed_ram.$proc$attributes_test.v:36$427'. -Found and cleaned up 1 empty switch in `\block_ram.$proc$attributes_test.v:14$420'. -Removing empty process `block_ram.$proc$attributes_test.v:14$420'. -Cleaned up 4 empty switches. - -8.3. Executing OPT_EXPR pass (perform const folding). -Optimizing module distributed_ram_manual_syn. -Optimizing module distributed_ram_manual. -Optimizing module distributed_ram. -Optimizing module block_ram. - -8.4. Executing OPT_CLEAN pass (remove unused cells and wires). -Finding unused cells or wires in module \distributed_ram_manual_syn.. -Finding unused cells or wires in module \distributed_ram_manual.. -Finding unused cells or wires in module \distributed_ram.. -Finding unused cells or wires in module \block_ram.. -Removed 0 unused cells and 28 unused wires. - - -8.5. Executing CHECK pass (checking for obvious problems). -checking module block_ram.. -checking module distributed_ram.. -checking module distributed_ram_manual.. -checking module distributed_ram_manual_syn.. -found and reported 0 problems. - -8.6. Executing OPT pass (performing simple optimizations). - -8.6.1. Executing OPT_EXPR pass (perform const folding). -Optimizing module block_ram. -Optimizing module distributed_ram. -Optimizing module distributed_ram_manual. -Optimizing module distributed_ram_manual_syn. - -8.6.2. Executing OPT_MERGE pass (detect identical cells). -Finding identical cells in module `\block_ram'. -Finding identical cells in module `\distributed_ram'. -Finding identical cells in module `\distributed_ram_manual'. -Finding identical cells in module `\distributed_ram_manual_syn'. -Removed a total of 0 cells. - -8.6.3. Executing OPT_MUXTREE pass (detect dead branches in mux trees). -Running muxtree optimizer on module \block_ram.. - Creating internal representation of mux trees. - Evaluating internal representation of mux trees. - Analyzing evaluation results. -Running muxtree optimizer on module \distributed_ram.. - Creating internal representation of mux trees. - Evaluating internal representation of mux trees. - Analyzing evaluation results. -Running muxtree optimizer on module \distributed_ram_manual.. - Creating internal representation of mux trees. - Evaluating internal representation of mux trees. - Analyzing evaluation results. -Running muxtree optimizer on module \distributed_ram_manual_syn.. - Creating internal representation of mux trees. - Evaluating internal representation of mux trees. - Analyzing evaluation results. -Removed 0 multiplexer ports. - - -8.6.4. Executing OPT_REDUCE pass (consolidate $*mux and $reduce_* inputs). - Optimizing cells in module \block_ram. - Consolidated identical input bits for $mux cell $procmux$465: - Old ports: A=4'0000, B=4'1111, Y=$0$memwr$\memory$attributes_test.v:16$419_EN[3:0]$423 - New ports: A=1'0, B=1'1, Y=$0$memwr$\memory$attributes_test.v:16$419_EN[3:0]$423 [0] - New connections: $0$memwr$\memory$attributes_test.v:16$419_EN[3:0]$423 [3:1] = { $0$memwr$\memory$attributes_test.v:16$419_EN[3:0]$423 [0] $0$memwr$\memory$attributes_test.v:16$419_EN[3:0]$423 [0] $0$memwr$\memory$attributes_test.v:16$419_EN[3:0]$423 [0] } - Optimizing cells in module \block_ram. - Optimizing cells in module \distributed_ram. - Consolidated identical input bits for $mux cell $procmux$459: - Old ports: A=8'00000000, B=8'11111111, Y=$0$memwr$\memory$attributes_test.v:38$426_EN[7:0]$430 - New ports: A=1'0, B=1'1, Y=$0$memwr$\memory$attributes_test.v:38$426_EN[7:0]$430 [0] - New connections: $0$memwr$\memory$attributes_test.v:38$426_EN[7:0]$430 [7:1] = { $0$memwr$\memory$attributes_test.v:38$426_EN[7:0]$430 [0] $0$memwr$\memory$attributes_test.v:38$426_EN[7:0]$430 [0] $0$memwr$\memory$attributes_test.v:38$426_EN[7:0]$430 [0] $0$memwr$\memory$attributes_test.v:38$426_EN[7:0]$430 [0] $0$memwr$\memory$attributes_test.v:38$426_EN[7:0]$430 [0] $0$memwr$\memory$attributes_test.v:38$426_EN[7:0]$430 [0] $0$memwr$\memory$attributes_test.v:38$426_EN[7:0]$430 [0] } - Optimizing cells in module \distributed_ram. - Optimizing cells in module \distributed_ram_manual. - Consolidated identical input bits for $mux cell $procmux$453: - Old ports: A=8'00000000, B=8'11111111, Y=$0$memwr$\memory$attributes_test.v:60$433_EN[7:0]$435 - New ports: A=1'0, B=1'1, Y=$0$memwr$\memory$attributes_test.v:60$433_EN[7:0]$435 [0] - New connections: $0$memwr$\memory$attributes_test.v:60$433_EN[7:0]$435 [7:1] = { $0$memwr$\memory$attributes_test.v:60$433_EN[7:0]$435 [0] $0$memwr$\memory$attributes_test.v:60$433_EN[7:0]$435 [0] $0$memwr$\memory$attributes_test.v:60$433_EN[7:0]$435 [0] $0$memwr$\memory$attributes_test.v:60$433_EN[7:0]$435 [0] $0$memwr$\memory$attributes_test.v:60$433_EN[7:0]$435 [0] $0$memwr$\memory$attributes_test.v:60$433_EN[7:0]$435 [0] $0$memwr$\memory$attributes_test.v:60$433_EN[7:0]$435 [0] } - Optimizing cells in module \distributed_ram_manual. - Optimizing cells in module \distributed_ram_manual_syn. - Consolidated identical input bits for $mux cell $procmux$447: - Old ports: A=8'00000000, B=8'11111111, Y=$0$memwr$\memory$attributes_test.v:82$440_EN[7:0]$443 - New ports: A=1'0, B=1'1, Y=$0$memwr$\memory$attributes_test.v:82$440_EN[7:0]$443 [0] - New connections: $0$memwr$\memory$attributes_test.v:82$440_EN[7:0]$443 [7:1] = { $0$memwr$\memory$attributes_test.v:82$440_EN[7:0]$443 [0] $0$memwr$\memory$attributes_test.v:82$440_EN[7:0]$443 [0] $0$memwr$\memory$attributes_test.v:82$440_EN[7:0]$443 [0] $0$memwr$\memory$attributes_test.v:82$440_EN[7:0]$443 [0] $0$memwr$\memory$attributes_test.v:82$440_EN[7:0]$443 [0] $0$memwr$\memory$attributes_test.v:82$440_EN[7:0]$443 [0] $0$memwr$\memory$attributes_test.v:82$440_EN[7:0]$443 [0] } - Optimizing cells in module \distributed_ram_manual_syn. -Performed a total of 4 changes. - -8.6.5. Executing OPT_MERGE pass (detect identical cells). -Finding identical cells in module `\block_ram'. -Finding identical cells in module `\distributed_ram'. -Finding identical cells in module `\distributed_ram_manual'. -Finding identical cells in module `\distributed_ram_manual_syn'. -Removed a total of 0 cells. - -8.6.6. Executing OPT_RMDFF pass (remove dff with constant values). - -8.6.7. Executing OPT_CLEAN pass (remove unused cells and wires). -Finding unused cells or wires in module \block_ram.. -Finding unused cells or wires in module \distributed_ram.. -Finding unused cells or wires in module \distributed_ram_manual.. -Finding unused cells or wires in module \distributed_ram_manual_syn.. - -8.6.8. Executing OPT_EXPR pass (perform const folding). -Optimizing module block_ram. -Optimizing module distributed_ram. -Optimizing module distributed_ram_manual. -Optimizing module distributed_ram_manual_syn. - -8.6.9. Rerunning OPT passes. (Maybe there is more to do..) - -8.6.10. Executing OPT_MUXTREE pass (detect dead branches in mux trees). -Running muxtree optimizer on module \block_ram.. - Creating internal representation of mux trees. - Evaluating internal representation of mux trees. - Analyzing evaluation results. -Running muxtree optimizer on module \distributed_ram.. - Creating internal representation of mux trees. - Evaluating internal representation of mux trees. - Analyzing evaluation results. -Running muxtree optimizer on module \distributed_ram_manual.. - Creating internal representation of mux trees. - Evaluating internal representation of mux trees. - Analyzing evaluation results. -Running muxtree optimizer on module \distributed_ram_manual_syn.. - Creating internal representation of mux trees. - Evaluating internal representation of mux trees. - Analyzing evaluation results. -Removed 0 multiplexer ports. - - -8.6.11. Executing OPT_REDUCE pass (consolidate $*mux and $reduce_* inputs). - Optimizing cells in module \block_ram. - Optimizing cells in module \distributed_ram. - Optimizing cells in module \distributed_ram_manual. - Optimizing cells in module \distributed_ram_manual_syn. -Performed a total of 0 changes. - -8.6.12. Executing OPT_MERGE pass (detect identical cells). -Finding identical cells in module `\block_ram'. -Finding identical cells in module `\distributed_ram'. -Finding identical cells in module `\distributed_ram_manual'. -Finding identical cells in module `\distributed_ram_manual_syn'. -Removed a total of 0 cells. - -8.6.13. Executing OPT_RMDFF pass (remove dff with constant values). - -8.6.14. Executing OPT_CLEAN pass (remove unused cells and wires). -Finding unused cells or wires in module \block_ram.. -Finding unused cells or wires in module \distributed_ram.. -Finding unused cells or wires in module \distributed_ram_manual.. -Finding unused cells or wires in module \distributed_ram_manual_syn.. - -8.6.15. Executing OPT_EXPR pass (perform const folding). -Optimizing module block_ram. -Optimizing module distributed_ram. -Optimizing module distributed_ram_manual. -Optimizing module distributed_ram_manual_syn. - -8.6.16. Finished OPT passes. (There is nothing left to do.) - -8.7. Executing WREDUCE pass (reducing word size of cells). -Removed top 3 bits (of 4) from FF cell block_ram.$procdff$486 ($dff). -Removed top 7 bits (of 8) from FF cell distributed_ram.$procdff$482 ($dff). -Removed top 7 bits (of 8) from FF cell distributed_ram_manual.$procdff$475 ($dff). -Removed top 7 bits (of 8) from FF cell distributed_ram_manual_syn.$procdff$473 ($dff). - -8.8. Executing MEMORY_DFF pass (merging $dff cells to $memrd and $memwr). -Checking cell `$memwr$\memory$attributes_test.v:16$425' in module `\block_ram': merged $dff to cell. -Checking cell `$memwr$\memory$attributes_test.v:38$432' in module `\distributed_ram': merged $dff to cell. -Checking cell `$memwr$\memory$attributes_test.v:60$439' in module `\distributed_ram_manual': merged $dff to cell. -Checking cell `$memwr$\memory$attributes_test.v:82$446' in module `\distributed_ram_manual_syn': merged $dff to cell. - -8.9. Executing OPT_CLEAN pass (remove unused cells and wires). -Finding unused cells or wires in module \block_ram.. -Finding unused cells or wires in module \distributed_ram.. -Finding unused cells or wires in module \distributed_ram_manual.. -Finding unused cells or wires in module \distributed_ram_manual_syn.. -Removed 12 unused cells and 12 unused wires. - - -8.10. Executing MEMORY_COLLECT pass (generating $mem cells). -Collecting $memrd, $memwr and $meminit for memory `\memory' in module `\block_ram': - $memwr$\memory$attributes_test.v:16$425 ($memwr) - $memrd$\memory$attributes_test.v:17$424 ($memrd) -Collecting $memrd, $memwr and $meminit for memory `\memory' in module `\distributed_ram': - $memwr$\memory$attributes_test.v:38$432 ($memwr) - $memrd$\memory$attributes_test.v:39$431 ($memrd) -Collecting $memrd, $memwr and $meminit for memory `\memory' in module `\distributed_ram_manual': - $memwr$\memory$attributes_test.v:60$439 ($memwr) - $memrd$\memory$attributes_test.v:61$438 ($memrd) -Collecting $memrd, $memwr and $meminit for memory `\memory' in module `\distributed_ram_manual_syn': - $memwr$\memory$attributes_test.v:82$446 ($memwr) - $memrd$\memory$attributes_test.v:83$445 ($memrd) - -8.11. Executing OPT pass (performing simple optimizations). - -8.11.1. Executing OPT_EXPR pass (perform const folding). -Optimizing module block_ram. -Optimizing module distributed_ram. -Optimizing module distributed_ram_manual. -Optimizing module distributed_ram_manual_syn. - -8.11.2. Executing OPT_MERGE pass (detect identical cells). -Finding identical cells in module `\block_ram'. -Finding identical cells in module `\distributed_ram'. -Finding identical cells in module `\distributed_ram_manual'. -Finding identical cells in module `\distributed_ram_manual_syn'. -Removed a total of 0 cells. - -8.11.3. Executing OPT_RMDFF pass (remove dff with constant values). - -8.11.4. Executing OPT_CLEAN pass (remove unused cells and wires). -Finding unused cells or wires in module \block_ram.. -Finding unused cells or wires in module \distributed_ram.. -Finding unused cells or wires in module \distributed_ram_manual.. -Finding unused cells or wires in module \distributed_ram_manual_syn.. - -8.11.5. Finished fast OPT passes. - -8.12. Printing statistics. - -=== block_ram === - - Number of wires: 10 - Number of wire bits: 46 - Number of public wires: 6 - Number of public wire bits: 24 - Number of memories: 0 - Number of memory bits: 0 - Number of processes: 0 - Number of cells: 5 - $dff 1 - $mem 1 - $mux 3 - -=== distributed_ram === - - Number of wires: 10 - Number of wire bits: 58 - Number of public wires: 6 - Number of public wire bits: 30 - Number of memories: 0 - Number of memory bits: 0 - Number of processes: 0 - Number of cells: 5 - $dff 1 - $mem 1 - $mux 3 - -=== distributed_ram_manual === - - Number of wires: 10 - Number of wire bits: 58 - Number of public wires: 6 - Number of public wire bits: 30 - Number of memories: 0 - Number of memory bits: 0 - Number of processes: 0 - Number of cells: 5 - $dff 1 - $mem 1 - $mux 3 - -=== distributed_ram_manual_syn === - - Number of wires: 10 - Number of wire bits: 58 - Number of public wires: 6 - Number of public wire bits: 30 - Number of memories: 0 - Number of memory bits: 0 - Number of processes: 0 - Number of cells: 5 - $dff 1 - $mem 1 - $mux 3 - -8.13. Executing CHECK pass (checking for obvious problems). -checking module block_ram.. -checking module distributed_ram.. -checking module distributed_ram_manual.. -checking module distributed_ram_manual_syn.. -found and reported 0 problems. - -9. Executing SYNTH_XILINX pass. - -9.1. Executing Verilog-2005 frontend: /opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/cells_sim.v -Parsing Verilog input from `/opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/cells_sim.v' to AST representation. -Generating RTLIL representation for module `\VCC'. -Generating RTLIL representation for module `\GND'. -Generating RTLIL representation for module `\IBUF'. -Generating RTLIL representation for module `\IBUFG'. -Generating RTLIL representation for module `\OBUF'. -Generating RTLIL representation for module `\IOBUF'. -Generating RTLIL representation for module `\OBUFT'. -Generating RTLIL representation for module `\BUFG'. -Generating RTLIL representation for module `\BUFGCTRL'. -Generating RTLIL representation for module `\BUFHCE'. -Generating RTLIL representation for module `\INV'. -Generating RTLIL representation for module `\LUT1'. -Generating RTLIL representation for module `\LUT2'. -Generating RTLIL representation for module `\LUT3'. -Generating RTLIL representation for module `\LUT4'. -Generating RTLIL representation for module `\LUT5'. -Generating RTLIL representation for module `\LUT6'. -Generating RTLIL representation for module `\LUT6_2'. -Generating RTLIL representation for module `\MUXCY'. -Generating RTLIL representation for module `\MUXF7'. -Generating RTLIL representation for module `\MUXF8'. -Generating RTLIL representation for module `\XORCY'. -Generating RTLIL representation for module `\CARRY4'. -Generating RTLIL representation for module `\FDRE'. -Generating RTLIL representation for module `\FDSE'. -Generating RTLIL representation for module `\FDCE'. -Generating RTLIL representation for module `\FDPE'. -Generating RTLIL representation for module `\FDRE_1'. -Generating RTLIL representation for module `\FDSE_1'. -Generating RTLIL representation for module `\FDCE_1'. -Generating RTLIL representation for module `\FDPE_1'. -Generating RTLIL representation for module `\LDCE'. -Generating RTLIL representation for module `\LDPE'. -Generating RTLIL representation for module `\RAM16X1S'. -Generating RTLIL representation for module `\RAM16X1S_1'. -Generating RTLIL representation for module `\RAM32X1S'. -Generating RTLIL representation for module `\RAM32X1S_1'. -Generating RTLIL representation for module `\RAM64X1S'. -Generating RTLIL representation for module `\RAM64X1S_1'. -Generating RTLIL representation for module `\RAM128X1S'. -Generating RTLIL representation for module `\RAM128X1S_1'. -Generating RTLIL representation for module `\RAM256X1S'. -Generating RTLIL representation for module `\RAM512X1S'. -Generating RTLIL representation for module `\RAM16X2S'. -Generating RTLIL representation for module `\RAM32X2S'. -Generating RTLIL representation for module `\RAM64X2S'. -Generating RTLIL representation for module `\RAM16X4S'. -Generating RTLIL representation for module `\RAM32X4S'. -Generating RTLIL representation for module `\RAM16X8S'. -Generating RTLIL representation for module `\RAM32X8S'. -Generating RTLIL representation for module `\RAM16X1D'. -Generating RTLIL representation for module `\RAM16X1D_1'. -Generating RTLIL representation for module `\RAM32X1D'. -Generating RTLIL representation for module `\RAM32X1D_1'. -Generating RTLIL representation for module `\RAM64X1D'. -Generating RTLIL representation for module `\RAM64X1D_1'. -Generating RTLIL representation for module `\RAM128X1D'. -Generating RTLIL representation for module `\RAM256X1D'. -Generating RTLIL representation for module `\RAM32M'. -Generating RTLIL representation for module `\RAM32M16'. -Generating RTLIL representation for module `\RAM64M'. -Generating RTLIL representation for module `\RAM64M8'. -Generating RTLIL representation for module `\ROM16X1'. -Generating RTLIL representation for module `\ROM32X1'. -Generating RTLIL representation for module `\ROM64X1'. -Generating RTLIL representation for module `\ROM128X1'. -Generating RTLIL representation for module `\ROM256X1'. -Generating RTLIL representation for module `\SRL16E'. -Generating RTLIL representation for module `\SRLC16E'. -Generating RTLIL representation for module `\SRLC32E'. -Generating RTLIL representation for module `\MULT18X18'. -Generating RTLIL representation for module `\MULT18X18S'. -Generating RTLIL representation for module `\MULT18X18SIO'. -Generating RTLIL representation for module `\DSP48A'. -Generating RTLIL representation for module `\DSP48A1'. -Generating RTLIL representation for module `\DSP48E1'. -Successfully finished Verilog frontend. - -9.2. Executing Verilog-2005 frontend: /opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/cells_xtra.v -Parsing Verilog input from `/opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/cells_xtra.v' to AST representation. -Generating RTLIL representation for module `\FDCPE'. -Generating RTLIL representation for module `\FDRSE'. -Generating RTLIL representation for module `\LDCPE'. -Generating RTLIL representation for module `\AND2B1L'. -Generating RTLIL representation for module `\OR2L'. -Generating RTLIL representation for module `\MUXF5'. -Generating RTLIL representation for module `\MUXF6'. -Generating RTLIL representation for module `\MUXF9'. -Generating RTLIL representation for module `\CARRY8'. -Generating RTLIL representation for module `\ORCY'. -Generating RTLIL representation for module `\MULT_AND'. -Generating RTLIL representation for module `\SRL16'. -Generating RTLIL representation for module `\SRLC16'. -Generating RTLIL representation for module `\CFGLUT5'. -Generating RTLIL representation for module `\RAMB16_S1'. -Generating RTLIL representation for module `\RAMB16_S2'. -Generating RTLIL representation for module `\RAMB16_S4'. -Generating RTLIL representation for module `\RAMB16_S9'. -Generating RTLIL representation for module `\RAMB16_S18'. -Generating RTLIL representation for module `\RAMB16_S36'. -Generating RTLIL representation for module `\RAMB16_S1_S1'. -Generating RTLIL representation for module `\RAMB16_S1_S2'. -Generating RTLIL representation for module `\RAMB16_S1_S4'. -Generating RTLIL representation for module `\RAMB16_S1_S9'. -Generating RTLIL representation for module `\RAMB16_S1_S18'. -Generating RTLIL representation for module `\RAMB16_S1_S36'. -Generating RTLIL representation for module `\RAMB16_S2_S2'. -Generating RTLIL representation for module `\RAMB16_S2_S4'. -Generating RTLIL representation for module `\RAMB16_S2_S9'. -Generating RTLIL representation for module `\RAMB16_S2_S18'. -Generating RTLIL representation for module `\RAMB16_S2_S36'. -Generating RTLIL representation for module `\RAMB16_S4_S4'. -Generating RTLIL representation for module `\RAMB16_S4_S9'. -Generating RTLIL representation for module `\RAMB16_S4_S18'. -Generating RTLIL representation for module `\RAMB16_S4_S36'. -Generating RTLIL representation for module `\RAMB16_S9_S9'. -Generating RTLIL representation for module `\RAMB16_S9_S18'. -Generating RTLIL representation for module `\RAMB16_S9_S36'. -Generating RTLIL representation for module `\RAMB16_S18_S18'. -Generating RTLIL representation for module `\RAMB16_S18_S36'. -Generating RTLIL representation for module `\RAMB16_S36_S36'. -Generating RTLIL representation for module `\RAMB16BWE_S18'. -Generating RTLIL representation for module `\RAMB16BWE_S36'. -Generating RTLIL representation for module `\RAMB16BWE_S18_S9'. -Generating RTLIL representation for module `\RAMB16BWE_S18_S18'. -Generating RTLIL representation for module `\RAMB16BWE_S36_S9'. -Generating RTLIL representation for module `\RAMB16BWE_S36_S18'. -Generating RTLIL representation for module `\RAMB16BWE_S36_S36'. -Generating RTLIL representation for module `\RAMB16BWER'. -Generating RTLIL representation for module `\RAMB8BWER'. -Generating RTLIL representation for module `\FIFO16'. -Generating RTLIL representation for module `\RAMB16'. -Generating RTLIL representation for module `\RAMB32_S64_ECC'. -Generating RTLIL representation for module `\FIFO18'. -Generating RTLIL representation for module `\FIFO18_36'. -Generating RTLIL representation for module `\FIFO36'. -Generating RTLIL representation for module `\FIFO36_72'. -Generating RTLIL representation for module `\RAMB18'. -Generating RTLIL representation for module `\RAMB36'. -Generating RTLIL representation for module `\RAMB18SDP'. -Generating RTLIL representation for module `\RAMB36SDP'. -Generating RTLIL representation for module `\FIFO18E1'. -Generating RTLIL representation for module `\FIFO36E1'. -Generating RTLIL representation for module `\RAMB18E1'. -Generating RTLIL representation for module `\RAMB36E1'. -Generating RTLIL representation for module `\FIFO18E2'. -Generating RTLIL representation for module `\FIFO36E2'. -Generating RTLIL representation for module `\RAMB18E2'. -Generating RTLIL representation for module `\RAMB36E2'. -Generating RTLIL representation for module `\URAM288'. -Generating RTLIL representation for module `\URAM288_BASE'. -Generating RTLIL representation for module `\DSP48'. -Generating RTLIL representation for module `\DSP48E'. -Generating RTLIL representation for module `\DSP48E2'. -Generating RTLIL representation for module `\IFDDRCPE'. -Generating RTLIL representation for module `\IFDDRRSE'. -Generating RTLIL representation for module `\OFDDRCPE'. -Generating RTLIL representation for module `\OFDDRRSE'. -Generating RTLIL representation for module `\OFDDRTCPE'. -Generating RTLIL representation for module `\OFDDRTRSE'. -Generating RTLIL representation for module `\IDDR2'. -Generating RTLIL representation for module `\ODDR2'. -Generating RTLIL representation for module `\IDDR'. -Generating RTLIL representation for module `\IDDR_2CLK'. -Generating RTLIL representation for module `\ODDR'. -Generating RTLIL representation for module `\IDELAYCTRL'. -Generating RTLIL representation for module `\IDELAY'. -Generating RTLIL representation for module `\ISERDES'. -Generating RTLIL representation for module `\OSERDES'. -Generating RTLIL representation for module `\IODELAY'. -Generating RTLIL representation for module `\ISERDES_NODELAY'. -Generating RTLIL representation for module `\IODELAYE1'. -Generating RTLIL representation for module `\ISERDESE1'. -Generating RTLIL representation for module `\OSERDESE1'. -Generating RTLIL representation for module `\IDELAYE2'. -Generating RTLIL representation for module `\ODELAYE2'. -Generating RTLIL representation for module `\ISERDESE2'. -Generating RTLIL representation for module `\OSERDESE2'. -Generating RTLIL representation for module `\PHASER_IN'. -Generating RTLIL representation for module `\PHASER_IN_PHY'. -Generating RTLIL representation for module `\PHASER_OUT'. -Generating RTLIL representation for module `\PHASER_OUT_PHY'. -Generating RTLIL representation for module `\PHASER_REF'. -Generating RTLIL representation for module `\PHY_CONTROL'. -Generating RTLIL representation for module `\IDDRE1'. -Generating RTLIL representation for module `\ODDRE1'. -Generating RTLIL representation for module `\IDELAYE3'. -Generating RTLIL representation for module `\ODELAYE3'. -Generating RTLIL representation for module `\ISERDESE3'. -Generating RTLIL representation for module `\OSERDESE3'. -Generating RTLIL representation for module `\BITSLICE_CONTROL'. -Generating RTLIL representation for module `\RIU_OR'. -Generating RTLIL representation for module `\RX_BITSLICE'. -Generating RTLIL representation for module `\RXTX_BITSLICE'. -Generating RTLIL representation for module `\TX_BITSLICE'. -Generating RTLIL representation for module `\TX_BITSLICE_TRI'. -Generating RTLIL representation for module `\IODELAY2'. -Generating RTLIL representation for module `\IODRP2'. -Generating RTLIL representation for module `\IODRP2_MCB'. -Generating RTLIL representation for module `\ISERDES2'. -Generating RTLIL representation for module `\OSERDES2'. -Generating RTLIL representation for module `\IBUF_DLY_ADJ'. -Generating RTLIL representation for module `\IBUF_IBUFDISABLE'. -Generating RTLIL representation for module `\IBUF_INTERMDISABLE'. -Generating RTLIL representation for module `\IBUF_ANALOG'. -Generating RTLIL representation for module `\IBUFE3'. -Generating RTLIL representation for module `\IBUFDS'. -Generating RTLIL representation for module `\IBUFDS_DLY_ADJ'. -Generating RTLIL representation for module `\IBUFDS_IBUFDISABLE'. -Generating RTLIL representation for module `\IBUFDS_INTERMDISABLE'. -Generating RTLIL representation for module `\IBUFDS_DIFF_OUT'. -Generating RTLIL representation for module `\IBUFDS_DIFF_OUT_IBUFDISABLE'. -Generating RTLIL representation for module `\IBUFDS_DIFF_OUT_INTERMDISABLE'. -Generating RTLIL representation for module `\IBUFDSE3'. -Generating RTLIL representation for module `\IBUFDS_DPHY'. -Generating RTLIL representation for module `\IBUFGDS'. -Generating RTLIL representation for module `\IBUFGDS_DIFF_OUT'. -Generating RTLIL representation for module `\IOBUF_DCIEN'. -Generating RTLIL representation for module `\IOBUF_INTERMDISABLE'. -Generating RTLIL representation for module `\IOBUFE3'. -Generating RTLIL representation for module `\IOBUFDS'. -Generating RTLIL representation for module `\IOBUFDS_DCIEN'. -Generating RTLIL representation for module `\IOBUFDS_INTERMDISABLE'. -Generating RTLIL representation for module `\IOBUFDS_DIFF_OUT'. -Generating RTLIL representation for module `\IOBUFDS_DIFF_OUT_DCIEN'. -Generating RTLIL representation for module `\IOBUFDS_DIFF_OUT_INTERMDISABLE'. -Generating RTLIL representation for module `\IOBUFDSE3'. -Generating RTLIL representation for module `\OBUFDS'. -Generating RTLIL representation for module `\OBUFDS_DPHY'. -Generating RTLIL representation for module `\OBUFTDS'. -Generating RTLIL representation for module `\KEEPER'. -Generating RTLIL representation for module `\PULLDOWN'. -Generating RTLIL representation for module `\PULLUP'. -Generating RTLIL representation for module `\DCIRESET'. -Generating RTLIL representation for module `\HPIO_VREF'. -Generating RTLIL representation for module `\BUFGCE'. -Generating RTLIL representation for module `\BUFGCE_1'. -Generating RTLIL representation for module `\BUFGMUX'. -Generating RTLIL representation for module `\BUFGMUX_1'. -Generating RTLIL representation for module `\BUFGMUX_CTRL'. -Generating RTLIL representation for module `\BUFGMUX_VIRTEX4'. -Generating RTLIL representation for module `\BUFG_GT'. -Generating RTLIL representation for module `\BUFG_GT_SYNC'. -Generating RTLIL representation for module `\BUFG_PS'. -Generating RTLIL representation for module `\BUFGCE_DIV'. -Generating RTLIL representation for module `\BUFH'. -Generating RTLIL representation for module `\BUFIO2'. -Generating RTLIL representation for module `\BUFIO2_2CLK'. -Generating RTLIL representation for module `\BUFIO2FB'. -Generating RTLIL representation for module `\BUFPLL'. -Generating RTLIL representation for module `\BUFPLL_MCB'. -Generating RTLIL representation for module `\BUFIO'. -Generating RTLIL representation for module `\BUFIODQS'. -Generating RTLIL representation for module `\BUFR'. -Generating RTLIL representation for module `\BUFMR'. -Generating RTLIL representation for module `\BUFMRCE'. -Generating RTLIL representation for module `\DCM'. -Generating RTLIL representation for module `\DCM_SP'. -Generating RTLIL representation for module `\DCM_CLKGEN'. -Generating RTLIL representation for module `\DCM_ADV'. -Generating RTLIL representation for module `\DCM_BASE'. -Generating RTLIL representation for module `\DCM_PS'. -Generating RTLIL representation for module `\PMCD'. -Generating RTLIL representation for module `\PLL_ADV'. -Generating RTLIL representation for module `\PLL_BASE'. -Generating RTLIL representation for module `\MMCM_ADV'. -Generating RTLIL representation for module `\MMCM_BASE'. -Generating RTLIL representation for module `\MMCME2_ADV'. -Generating RTLIL representation for module `\MMCME2_BASE'. -Generating RTLIL representation for module `\PLLE2_ADV'. -Generating RTLIL representation for module `\PLLE2_BASE'. -Generating RTLIL representation for module `\MMCME3_ADV'. -Generating RTLIL representation for module `\MMCME3_BASE'. -Generating RTLIL representation for module `\PLLE3_ADV'. -Generating RTLIL representation for module `\PLLE3_BASE'. -Generating RTLIL representation for module `\MMCME4_ADV'. -Generating RTLIL representation for module `\MMCME4_BASE'. -Generating RTLIL representation for module `\PLLE4_ADV'. -Generating RTLIL representation for module `\PLLE4_BASE'. -Generating RTLIL representation for module `\BUFT'. -Generating RTLIL representation for module `\IN_FIFO'. -Generating RTLIL representation for module `\OUT_FIFO'. -Generating RTLIL representation for module `\HARD_SYNC'. -Generating RTLIL representation for module `\STARTUP_SPARTAN3'. -Generating RTLIL representation for module `\STARTUP_SPARTAN3E'. -Generating RTLIL representation for module `\STARTUP_SPARTAN3A'. -Generating RTLIL representation for module `\STARTUP_SPARTAN6'. -Generating RTLIL representation for module `\STARTUP_VIRTEX4'. -Generating RTLIL representation for module `\STARTUP_VIRTEX5'. -Generating RTLIL representation for module `\STARTUP_VIRTEX6'. -Generating RTLIL representation for module `\STARTUPE2'. -Generating RTLIL representation for module `\STARTUPE3'. -Generating RTLIL representation for module `\CAPTURE_SPARTAN3'. -Generating RTLIL representation for module `\CAPTURE_SPARTAN3A'. -Generating RTLIL representation for module `\CAPTURE_VIRTEX4'. -Generating RTLIL representation for module `\CAPTURE_VIRTEX5'. -Generating RTLIL representation for module `\CAPTURE_VIRTEX6'. -Generating RTLIL representation for module `\CAPTUREE2'. -Generating RTLIL representation for module `\ICAP_SPARTAN3A'. -Generating RTLIL representation for module `\ICAP_SPARTAN6'. -Generating RTLIL representation for module `\ICAP_VIRTEX4'. -Generating RTLIL representation for module `\ICAP_VIRTEX5'. -Generating RTLIL representation for module `\ICAP_VIRTEX6'. -Generating RTLIL representation for module `\ICAPE2'. -Generating RTLIL representation for module `\ICAPE3'. -Generating RTLIL representation for module `\BSCAN_SPARTAN3'. -Generating RTLIL representation for module `\BSCAN_SPARTAN3A'. -Generating RTLIL representation for module `\BSCAN_SPARTAN6'. -Generating RTLIL representation for module `\BSCAN_VIRTEX4'. -Generating RTLIL representation for module `\BSCAN_VIRTEX5'. -Generating RTLIL representation for module `\BSCAN_VIRTEX6'. -Generating RTLIL representation for module `\BSCANE2'. -Generating RTLIL representation for module `\DNA_PORT'. -Generating RTLIL representation for module `\DNA_PORTE2'. -Generating RTLIL representation for module `\FRAME_ECC_VIRTEX4'. -Generating RTLIL representation for module `\FRAME_ECC_VIRTEX5'. -Generating RTLIL representation for module `\FRAME_ECC_VIRTEX6'. -Generating RTLIL representation for module `\FRAME_ECCE2'. -Generating RTLIL representation for module `\FRAME_ECCE3'. -Generating RTLIL representation for module `\USR_ACCESS_VIRTEX4'. -Generating RTLIL representation for module `\USR_ACCESS_VIRTEX5'. -Generating RTLIL representation for module `\USR_ACCESS_VIRTEX6'. -Generating RTLIL representation for module `\USR_ACCESSE2'. -Generating RTLIL representation for module `\POST_CRC_INTERNAL'. -Generating RTLIL representation for module `\SUSPEND_SYNC'. -Generating RTLIL representation for module `\KEY_CLEAR'. -Generating RTLIL representation for module `\MASTER_JTAG'. -Generating RTLIL representation for module `\SPI_ACCESS'. -Generating RTLIL representation for module `\EFUSE_USR'. -Generating RTLIL representation for module `\SYSMON'. -Generating RTLIL representation for module `\XADC'. -Generating RTLIL representation for module `\SYSMONE1'. -Generating RTLIL representation for module `\SYSMONE4'. -Generating RTLIL representation for module `\GTPA1_DUAL'. -Generating RTLIL representation for module `\GT11_CUSTOM'. -Generating RTLIL representation for module `\GT11_DUAL'. -Generating RTLIL representation for module `\GT11CLK'. -Generating RTLIL representation for module `\GT11CLK_MGT'. -Generating RTLIL representation for module `\GTP_DUAL'. -Generating RTLIL representation for module `\GTX_DUAL'. -Generating RTLIL representation for module `\CRC32'. -Generating RTLIL representation for module `\CRC64'. -Generating RTLIL representation for module `\GTHE1_QUAD'. -Generating RTLIL representation for module `\GTXE1'. -Generating RTLIL representation for module `\IBUFDS_GTXE1'. -Generating RTLIL representation for module `\IBUFDS_GTHE1'. -Generating RTLIL representation for module `\GTHE2_CHANNEL'. -Generating RTLIL representation for module `\GTHE2_COMMON'. -Generating RTLIL representation for module `\GTPE2_CHANNEL'. -Generating RTLIL representation for module `\GTPE2_COMMON'. -Generating RTLIL representation for module `\GTXE2_CHANNEL'. -Generating RTLIL representation for module `\GTXE2_COMMON'. -Generating RTLIL representation for module `\IBUFDS_GTE2'. -Generating RTLIL representation for module `\GTHE3_CHANNEL'. -Generating RTLIL representation for module `\GTHE3_COMMON'. -Generating RTLIL representation for module `\GTHE4_CHANNEL'. -Generating RTLIL representation for module `\GTHE4_COMMON'. -Generating RTLIL representation for module `\GTYE3_CHANNEL'. -Generating RTLIL representation for module `\GTYE3_COMMON'. -Generating RTLIL representation for module `\GTYE4_CHANNEL'. -Generating RTLIL representation for module `\GTYE4_COMMON'. -Generating RTLIL representation for module `\IBUFDS_GTE3'. -Generating RTLIL representation for module `\IBUFDS_GTE4'. -Generating RTLIL representation for module `\OBUFDS_GTE3'. -Generating RTLIL representation for module `\OBUFDS_GTE3_ADV'. -Generating RTLIL representation for module `\OBUFDS_GTE4'. -Generating RTLIL representation for module `\OBUFDS_GTE4_ADV'. -Generating RTLIL representation for module `\PCIE_A1'. -Generating RTLIL representation for module `\PCIE_EP'. -Generating RTLIL representation for module `\PCIE_2_0'. -Generating RTLIL representation for module `\PCIE_2_1'. -Generating RTLIL representation for module `\PCIE_3_0'. -Generating RTLIL representation for module `\PCIE_3_1'. -Generating RTLIL representation for module `\PCIE40E4'. -Generating RTLIL representation for module `\EMAC'. -Generating RTLIL representation for module `\TEMAC'. -Generating RTLIL representation for module `\TEMAC_SINGLE'. -Generating RTLIL representation for module `\CMAC'. -Generating RTLIL representation for module `\CMACE4'. -Generating RTLIL representation for module `\PPC405_ADV'. -Generating RTLIL representation for module `\PPC440'. -Generating RTLIL representation for module `\MCB'. -Generating RTLIL representation for module `\PS7'. -Generating RTLIL representation for module `\PS8'. -Generating RTLIL representation for module `\ILKN'. -Generating RTLIL representation for module `\ILKNE4'. -Successfully finished Verilog frontend. - -9.3. Executing HIERARCHY pass (managing design hierarchy). - -9.3.1. Analyzing design hierarchy.. -Top module: \block_ram - -9.3.2. Analyzing design hierarchy.. -Top module: \block_ram -Removing unused module `\distributed_ram'. -Removing unused module `\distributed_ram_manual'. -Removing unused module `\distributed_ram_manual_syn'. -Removed 3 unused modules. - -9.4. Executing PROC pass (convert processes to netlists). - -9.4.1. Executing PROC_CLEAN pass (remove empty switches from decision trees). -Cleaned up 0 empty switches. - -9.4.2. Executing PROC_RMDEAD pass (remove dead branches from decision trees). -Removed a total of 0 dead cases. - -9.4.3. Executing PROC_PRUNE pass (remove redundant assignments in processes). -Removed 0 redundant assignments. -Promoted 0 assignments to connections. - -9.4.4. Executing PROC_INIT pass (extract init attributes). - -9.4.5. Executing PROC_ARST pass (detect async resets in processes). - -9.4.6. Executing PROC_MUX pass (convert decision trees to multiplexers). - -9.4.7. Executing PROC_DLATCH pass (convert process syncs to latches). - -9.4.8. Executing PROC_DFF pass (convert process syncs to FFs). - -9.4.9. Executing PROC_CLEAN pass (remove empty switches from decision trees). -Cleaned up 0 empty switches. - -9.5. Executing TRIBUF pass. - -9.6. Executing DEMINOUT pass (demote inout ports to input or output). - -9.7. Executing OPT_EXPR pass (perform const folding). -Optimizing module block_ram. - -9.8. Executing OPT_CLEAN pass (remove unused cells and wires). -Finding unused cells or wires in module \block_ram.. - -9.9. Executing CHECK pass (checking for obvious problems). -checking module block_ram.. -found and reported 0 problems. - -9.10. Executing OPT pass (performing simple optimizations). - -9.10.1. Executing OPT_EXPR pass (perform const folding). -Optimizing module block_ram. - -9.10.2. Executing OPT_MERGE pass (detect identical cells). -Finding identical cells in module `\block_ram'. -Removed a total of 0 cells. - -9.10.3. Executing OPT_MUXTREE pass (detect dead branches in mux trees). -Running muxtree optimizer on module \block_ram.. - Creating internal representation of mux trees. - Evaluating internal representation of mux trees. - Analyzing evaluation results. -Removed 0 multiplexer ports. - - -9.10.4. Executing OPT_REDUCE pass (consolidate $*mux and $reduce_* inputs). - Optimizing cells in module \block_ram. -Performed a total of 0 changes. - -9.10.5. Executing OPT_MERGE pass (detect identical cells). -Finding identical cells in module `\block_ram'. -Removed a total of 0 cells. - -9.10.6. Executing OPT_RMDFF pass (remove dff with constant values). - -9.10.7. Executing OPT_CLEAN pass (remove unused cells and wires). -Finding unused cells or wires in module \block_ram.. - -9.10.8. Executing OPT_EXPR pass (perform const folding). -Optimizing module block_ram. - -9.10.9. Finished OPT passes. (There is nothing left to do.) - -9.11. Executing WREDUCE pass (reducing word size of cells). -Removed cell block_ram.$procmux$469 ($mux). -Removed cell block_ram.$procmux$467 ($mux). - -9.12. Executing PEEPOPT pass (run peephole optimizers). - -9.13. Executing OPT_CLEAN pass (remove unused cells and wires). -Finding unused cells or wires in module \block_ram.. -Removed 0 unused cells and 2 unused wires. - - -9.14. Executing PMUX2SHIFTX pass. - -9.15. Executing TECHMAP pass (map to technology primitives). - -9.15.1. Executing Verilog-2005 frontend: /opt/eda/fpga/FOSS/memattr/yosys_release/share/cmp2lut.v -Parsing Verilog input from `/opt/eda/fpga/FOSS/memattr/yosys_release/share/cmp2lut.v' to AST representation. -Generating RTLIL representation for module `\_90_lut_cmp_'. -Successfully finished Verilog frontend. - -9.15.2. Continuing TECHMAP pass. -No more expansions possible. - -9.16. Executing MEMORY_DFF pass (merging $dff cells to $memrd and $memwr). - -9.17. Executing TECHMAP pass (map to technology primitives). - -9.17.1. Executing Verilog-2005 frontend: /opt/eda/fpga/FOSS/memattr/yosys_release/share/mul2dsp.v -Parsing Verilog input from `/opt/eda/fpga/FOSS/memattr/yosys_release/share/mul2dsp.v' to AST representation. -Generating RTLIL representation for module `\_80_mul'. -Generating RTLIL representation for module `\_90_soft_mul'. -Successfully finished Verilog frontend. - -9.17.2. Executing Verilog-2005 frontend: /opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/xc7_dsp_map.v -Parsing Verilog input from `/opt/eda/fpga/FOSS/memattr/yosys_release/share/xilinx/xc7_dsp_map.v' to AST representation. -Generating RTLIL representation for module `\$__MUL25X18'. -Successfully finished Verilog frontend. - -9.17.3. Continuing TECHMAP pass. -No more expansions possible. - -9.18. Executing OPT_EXPR pass (perform const folding). - -9.19. Executing WREDUCE pass (reducing word size of cells). - -9.20. Executing XILINX_DSP pass (pack resources into DSPs). - -9.21. Executing ALUMACC pass (create $alu and $macc cells). -Extracting $alu and $macc cells in module block_ram: - created 0 $alu and 0 $macc cells. - -9.22. Executing SHARE pass (SAT-based resource sharing). -- cgit v1.2.3 From abcd82dacadc8b5af6b2b7f6d7cbdb635d276440 Mon Sep 17 00:00:00 2001 From: "N. Engelhardt" Date: Mon, 16 Dec 2019 13:09:31 +0100 Subject: add assert option to scratchpad command --- passes/cmds/scratchpad.cc | 49 ++++++++++++++++++++++++++++++++++++++++----- tests/various/scratchpad.sh | 14 ------------- tests/various/scratchpad.ys | 5 +++++ 3 files changed, 49 insertions(+), 19 deletions(-) delete mode 100755 tests/various/scratchpad.sh create mode 100644 tests/various/scratchpad.ys diff --git a/passes/cmds/scratchpad.cc b/passes/cmds/scratchpad.cc index 6bf14a6bd..805badc7e 100644 --- a/passes/cmds/scratchpad.cc +++ b/passes/cmds/scratchpad.cc @@ -34,15 +34,29 @@ struct ScratchpadPass : public Pass { log(" scratchpad [options]\n"); log("\n"); log("This pass allows to read and modify values from the scratchpad of the current\n"); - log("design. Options:\n\n"); + log("design. Options:\n"); + log("\n"); log(" -get \n"); - log(" print the value saved in the scratchpad under the given identifier.\n\n"); + log(" print the value saved in the scratchpad under the given identifier.\n"); + log("\n"); log(" -set \n"); - log(" save the given value in the scratchpad under the given identifier.\n\n"); + log(" save the given value in the scratchpad under the given identifier.\n"); + log("\n"); log(" -unset \n"); - log(" remove the entry for the given identifier from the scratchpad.\n\n"); + log(" remove the entry for the given identifier from the scratchpad.\n"); + log("\n"); log(" -copy \n"); - log(" copy the value of the first identifier to the second identifier.\n\n"); + log(" copy the value of the first identifier to the second identifier.\n"); + log("\n"); + log(" -assert \n"); + log(" assert that the entry for the given identifier is set to the given value.\n"); + log("\n"); + log(" -assert-set \n"); + log(" assert that the entry for the given identifier exists.\n"); + log("\n"); + log(" -assert-unset \n"); + log(" assert that the entry for the given identifier does not exist.\n"); + log("\n"); log("The identifier may not contain whitespace. By convention, it is usually prefixed\n"); log("by the name of the pass that uses it, e.g. 'opt.did_something'. If the value\n"); log("contains whitespace, it must be enclosed in double quotes.\n"); @@ -83,6 +97,31 @@ struct ScratchpadPass : public Pass { design->scratchpad_set_string(identifier_to, value); continue; } + if (args[argidx] == "-assert" && argidx+2 < args.size()) { + string identifier = args[++argidx]; + string expected = args[++argidx]; + if (expected.front() == '\"' && expected.back() == '\"') expected = expected.substr(1, expected.size() - 2); + if (design->scratchpad.count(identifier) == 0) + log_error("Assertion failed: scratchpad entry '%s' is not defined\n", identifier.c_str()); + string value = design->scratchpad_get_string(identifier); + if (value != expected) { + log_error("Assertion failed: scratchpad entry '%s' is set to '%s' instead of the asserted '%s'\n", + identifier.c_str(), value.c_str(), expected.c_str()); + } + continue; + } + if (args[argidx] == "-assert-set" && argidx+1 < args.size()) { + string identifier = args[++argidx]; + if (design->scratchpad.count(identifier) == 0) + log_error("Assertion failed: scratchpad entry '%s' is not defined\n", identifier.c_str()); + continue; + } + if (args[argidx] == "-assert-unset" && argidx+1 < args.size()) { + string identifier = args[++argidx]; + if (design->scratchpad.count(identifier) > 0) + log_error("Assertion failed: scratchpad entry '%s' is defined\n", identifier.c_str()); + continue; + } log("Unrecognized argument: %s\n", args[argidx].c_str()); break; } diff --git a/tests/various/scratchpad.sh b/tests/various/scratchpad.sh deleted file mode 100755 index 4e92473f8..000000000 --- a/tests/various/scratchpad.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/bash - -trap 'echo "ERROR in scratchpad.sh" >&2; exit 1' ERR - -../../yosys -qp "scratchpad -set foo \"bar baz\"; \ -scratchpad -copy foo oof; scratchpad -unset foo; \ -tee -o scratchpad1.log scratchpad -get oof; \ -tee -o scratchpad2.log scratchpad -get foo" - -test "$(cat scratchpad1.log)" = "bar baz" -test "$(cat scratchpad2.log)" = "\"foo\" not set" - -rm scratchpad1.log -rm scratchpad2.log diff --git a/tests/various/scratchpad.ys b/tests/various/scratchpad.ys new file mode 100644 index 000000000..dc94081ea --- /dev/null +++ b/tests/various/scratchpad.ys @@ -0,0 +1,5 @@ +scratchpad -set foo "bar baz" +scratchpad -copy foo oof +scratchpad -unset foo +scratchpad -assert oof "bar baz" +scratchpad -assert-unset foo -- cgit v1.2.3 From 87e21b0122bd682db8aeffae3e1ac503c9cea2d2 Mon Sep 17 00:00:00 2001 From: Diego H Date: Mon, 16 Dec 2019 10:23:45 -0600 Subject: Fixing compiler warning/issues. Moving test script to the correct place --- passes/memory/memory_bram.cc | 16 ++++---- .../common/memory_attributes/attributes_test.ys | 47 ---------------------- tests/arch/xilinx/attributes_test.ys | 47 ++++++++++++++++++++++ 3 files changed, 55 insertions(+), 55 deletions(-) delete mode 100644 tests/arch/common/memory_attributes/attributes_test.ys create mode 100644 tests/arch/xilinx/attributes_test.ys diff --git a/passes/memory/memory_bram.cc b/passes/memory/memory_bram.cc index 10b48e321..703e87f05 100644 --- a/passes/memory/memory_bram.cc +++ b/passes/memory/memory_bram.cc @@ -821,8 +821,8 @@ grow_read_ports:; log(" Updated properties: dups=%d waste=%d efficiency=%d\n", match_properties["dups"], match_properties["waste"], match_properties["efficiency"]); - for (auto& iter: match.attr_match) { - for (auto& iter: iter.second) { + for (auto iter: match.attr_match) { + for (auto iter: iter.second) { auto it = cell->attributes.find(iter.first); if (iter.second.empty()) { @@ -1124,8 +1124,8 @@ void handle_cell(Cell *cell, const rules_t &rules) goto next_match_rule; } - for (auto& iter: match.attr_match) { - for (auto& iter: iter.second) { + for (auto iter: match.attr_match) { + for (auto iter: iter.second) { auto it = cell->attributes.find(iter.first); if (it != cell->attributes.end()) { @@ -1149,10 +1149,10 @@ void handle_cell(Cell *cell, const rules_t &rules) if (!it->second.empty()) { if (it->second.decode_string().length() == 1) it->second = it->second.as_string().back(); - if (!it->second.decode_string().compare(iter.second.decode_string())) - goto next_match_rule; - log(" Rule for bram type %s is rejected: requirement 'attribute %s=\"%s\"' not met.\n", - log_id(match.name), log_id(iter.first), iter.second.decode_string().c_str()); + if (!it->second.decode_string().compare(iter.second.decode_string())) + goto next_match_rule; + log(" Rule for bram type %s is rejected: requirement 'attribute %s=\"%s\"' not met.\n", + log_id(match.name), log_id(iter.first), iter.second.decode_string().c_str()); } } } diff --git a/tests/arch/common/memory_attributes/attributes_test.ys b/tests/arch/common/memory_attributes/attributes_test.ys deleted file mode 100644 index 4e06a35e7..000000000 --- a/tests/arch/common/memory_attributes/attributes_test.ys +++ /dev/null @@ -1,47 +0,0 @@ -# Check that blockram memory without parameters is not modified -read_verilog attributes_test.v -hierarchy -top block_ram -synth_xilinx -top block_ram -cd block_ram # Constrain all select calls below inside the top module -select -assert-count 1 t:RAMB18E1 - -# Check that distributed memory without parameters is not modified -design -reset -read_verilog attributes_test.v -hierarchy -top distributed_ram -synth_xilinx -top distributed_ram -cd distributed_ram # Constrain all select calls below inside the top module -select -assert-count 8 t:RAM32X1D - -# Set ram_style distributed to blockram memory; will be implemented as distributed -design -reset -read_verilog attributes_test.v -prep -setattr -mod -set ram_style "distributed" block_ram -synth_xilinx -top block_ram -cd block_ram # Constrain all select calls below inside the top module -select -assert-count 32 t:RAM128X1D - -# Set synthesis, logic_block to blockram memory; will be implemented as distributed -design -reset -read_verilog attributes_test.v -prep -setattr -mod -set logic_block 1 block_ram -synth_xilinx -top block_ram -cd block_ram # Constrain all select calls below inside the top module -select -assert-count 0 t:RAMB18E1 -select -assert-count 32 t:RAM128X1D - -# Set ram_style block to a distributed memory; will be implemented as blockram -design -reset -read_verilog attributes_test.v -synth_xilinx -top distributed_ram_manual -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 attributes_test.v -synth_xilinx -top distributed_ram_manual_syn -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/attributes_test.ys b/tests/arch/xilinx/attributes_test.ys new file mode 100644 index 000000000..4c881b280 --- /dev/null +++ b/tests/arch/xilinx/attributes_test.ys @@ -0,0 +1,47 @@ +# 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 +cd block_ram # Constrain all select calls below inside the top module +select -assert-count 1 t:RAMB18E1 + +# Check that distributed memory without parameters is not modified +design -reset +read_verilog ../common/memory_attributes/attributes_test.v +hierarchy -top distributed_ram +synth_xilinx -top distributed_ram +cd distributed_ram # Constrain all select calls below inside the top module +select -assert-count 8 t:RAM32X1D + +# Set ram_style distributed to blockram memory; will be implemented as distributed +design -reset +read_verilog ../common/memory_attributes/attributes_test.v +prep +setattr -mod -set ram_style "distributed" block_ram +synth_xilinx -top block_ram +cd block_ram # Constrain all select calls below inside the top module +select -assert-count 32 t:RAM128X1D + +# Set synthesis, logic_block to blockram memory; will be implemented as distributed +design -reset +read_verilog ../common/memory_attributes/attributes_test.v +prep +setattr -mod -set logic_block 1 block_ram +synth_xilinx -top block_ram +cd block_ram # Constrain all select calls below inside the top module +select -assert-count 0 t:RAMB18E1 +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 +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 +cd distributed_ram_manual_syn # Constrain all select calls below inside the top module +select -assert-count 1 t:RAMB18E1 -- cgit v1.2.3 From 6c340112fee1bb8989cbd41923aaa627d77d5110 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 16 Dec 2019 10:21:08 -0800 Subject: write_xaiger: use sigmap bits more consistently --- backends/aiger/xaiger.cc | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index c080cca4d..cff3183c1 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -294,7 +294,7 @@ struct XAigerWriter output_bits.insert(b); if (!cell_known) - inout_bits.insert(b); + inout_bits.insert(I); } } } @@ -315,7 +315,7 @@ struct XAigerWriter SigBit O = sigmap(b); if (O != b) alias_map[O] = b; - input_bits.insert(b); + input_bits.insert(O); if (arrival) arrival_times[b] = arrival; @@ -542,9 +542,8 @@ struct XAigerWriter undriven_bits.erase(bit); } - // For inout ports, or keep-ed wires, then create a new wire with an - // $inout.out suffix, make it a PO driven by the existing inout, and - // inherit existing inout's drivers + // For inout ports, or keep-ed wires, which end up being both a PI and a + // a PO then replace the PO with a new wire with the $inout.out suffix for (auto bit : inout_bits) { RTLIL::Wire *wire = bit.wire; RTLIL::IdString wire_name = stringf("$%s$inout.out", wire->name.c_str()); -- cgit v1.2.3 From c4d37813cb112d7f3717049d7cf4e6e6b0456fbb Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 16 Dec 2019 10:41:13 -0800 Subject: Rename *RAM{32,64}M rules to RAM{32X2,64X1}Q --- techlibs/xilinx/lutrams.txt | 8 ++++---- techlibs/xilinx/lutrams_map.v | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/techlibs/xilinx/lutrams.txt b/techlibs/xilinx/lutrams.txt index ae629bce8..29f6b05cc 100644 --- a/techlibs/xilinx/lutrams.txt +++ b/techlibs/xilinx/lutrams.txt @@ -78,7 +78,7 @@ bram $__XILINX_RAM64X3SDP clkpol 0 2 endbram -bram $__XILINX_RAM32M +bram $__XILINX_RAM32X2Q init 1 abits 5 dbits 2 @@ -91,7 +91,7 @@ bram $__XILINX_RAM32M clkpol 0 2 endbram -bram $__XILINX_RAM64M +bram $__XILINX_RAM64X1Q init 1 abits 6 dbits 1 @@ -151,7 +151,7 @@ match $__XILINX_RAM64X3SDP or_next_if_better endmatch -match $__XILINX_RAM32M +match $__XILINX_RAM32X2Q min bits 5 min rports 3 min wports 1 @@ -159,7 +159,7 @@ match $__XILINX_RAM32M or_next_if_better endmatch -match $__XILINX_RAM64M +match $__XILINX_RAM64X1Q min bits 5 min rports 3 min wports 1 diff --git a/techlibs/xilinx/lutrams_map.v b/techlibs/xilinx/lutrams_map.v index d01508de5..884f709ab 100644 --- a/techlibs/xilinx/lutrams_map.v +++ b/techlibs/xilinx/lutrams_map.v @@ -200,7 +200,7 @@ module \$__XILINX_RAM64X3SDP (CLK1, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN); ); endmodule -module \$__XILINX_RAM32M (CLK1, A1ADDR, A1DATA, A2ADDR, A2DATA, A3ADDR, A3DATA, B1ADDR, B1DATA, B1EN); +module \$__XILINX_RAM32X2Q (CLK1, A1ADDR, A1DATA, A2ADDR, A2DATA, A3ADDR, A3DATA, B1ADDR, B1DATA, B1EN); parameter [63:0] INIT = 64'bx; parameter CLKPOL2 = 1; input CLK1; @@ -236,7 +236,7 @@ module \$__XILINX_RAM32M (CLK1, A1ADDR, A1DATA, A2ADDR, A2DATA, A3ADDR, A3DATA, ); endmodule -module \$__XILINX_RAM64M (CLK1, A1ADDR, A1DATA, A2ADDR, A2DATA, A3ADDR, A3DATA, B1ADDR, B1DATA, B1EN); +module \$__XILINX_RAM64X1Q (CLK1, A1ADDR, A1DATA, A2ADDR, A2DATA, A3ADDR, A3DATA, B1ADDR, B1DATA, B1EN); parameter [63:0] INIT = 64'bx; parameter CLKPOL2 = 1; input CLK1; -- cgit v1.2.3 From 7545ab3814a01047698f45739a04437045248da3 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 16 Dec 2019 11:56:26 -0800 Subject: Populate DID/DOD even if unused --- techlibs/xilinx/lutrams_map.v | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/techlibs/xilinx/lutrams_map.v b/techlibs/xilinx/lutrams_map.v index d01508de5..47424aa73 100644 --- a/techlibs/xilinx/lutrams_map.v +++ b/techlibs/xilinx/lutrams_map.v @@ -140,6 +140,8 @@ module \$__XILINX_RAM32X6SDP (CLK1, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN); input [5:0] B1DATA; input B1EN; + wire [1:0] DOD_unused; + RAM32M #( .INIT_A({INIT[187:186], INIT[181:180], INIT[175:174], INIT[169:168], INIT[163:162], INIT[157:156], INIT[151:150], INIT[145:144], INIT[139:138], INIT[133:132], INIT[127:126], INIT[121:120], INIT[115:114], INIT[109:108], INIT[103:102], INIT[ 97: 96], INIT[ 91: 90], INIT[ 85: 84], INIT[ 79: 78], INIT[ 73: 72], INIT[ 67: 66], INIT[ 61: 60], INIT[ 55: 54], INIT[ 49: 48], INIT[ 43: 42], INIT[ 37: 36], INIT[ 31: 30], INIT[ 25: 24], INIT[ 19: 18], INIT[ 13: 12], INIT[ 7: 6], INIT[ 1: 0]}), .INIT_B({INIT[189:188], INIT[183:182], INIT[177:176], INIT[171:170], INIT[165:164], INIT[159:158], INIT[153:152], INIT[147:146], INIT[141:140], INIT[135:134], INIT[129:128], INIT[123:122], INIT[117:116], INIT[111:110], INIT[105:104], INIT[ 99: 98], INIT[ 93: 92], INIT[ 87: 86], INIT[ 81: 80], INIT[ 75: 74], INIT[ 69: 68], INIT[ 63: 62], INIT[ 57: 56], INIT[ 51: 50], INIT[ 45: 44], INIT[ 39: 38], INIT[ 33: 32], INIT[ 27: 26], INIT[ 21: 20], INIT[ 15: 14], INIT[ 9: 8], INIT[ 3: 2]}), @@ -153,12 +155,13 @@ module \$__XILINX_RAM32X6SDP (CLK1, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN); .DOA(A1DATA[1:0]), .DOB(A1DATA[3:2]), .DOC(A1DATA[5:4]), + .DOD(DOD_unused), .ADDRD(B1ADDR), .DIA(B1DATA[1:0]), .DIB(B1DATA[3:2]), .DIC(B1DATA[5:4]), - .DID(), + .DID(2'b00), .WCLK(CLK1), .WE(B1EN) ); @@ -176,6 +179,8 @@ module \$__XILINX_RAM64X3SDP (CLK1, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN); input [2:0] B1DATA; input B1EN; + wire DOD_unused; + RAM64M #( .INIT_A({INIT[189], INIT[186], INIT[183], INIT[180], INIT[177], INIT[174], INIT[171], INIT[168], INIT[165], INIT[162], INIT[159], INIT[156], INIT[153], INIT[150], INIT[147], INIT[144], INIT[141], INIT[138], INIT[135], INIT[132], INIT[129], INIT[126], INIT[123], INIT[120], INIT[117], INIT[114], INIT[111], INIT[108], INIT[105], INIT[102], INIT[ 99], INIT[ 96], INIT[ 93], INIT[ 90], INIT[ 87], INIT[ 84], INIT[ 81], INIT[ 78], INIT[ 75], INIT[ 72], INIT[ 69], INIT[ 66], INIT[ 63], INIT[ 60], INIT[ 57], INIT[ 54], INIT[ 51], INIT[ 48], INIT[ 45], INIT[ 42], INIT[ 39], INIT[ 36], INIT[ 33], INIT[ 30], INIT[ 27], INIT[ 24], INIT[ 21], INIT[ 18], INIT[ 15], INIT[ 12], INIT[ 9], INIT[ 6], INIT[ 3], INIT[ 0]}), .INIT_B({INIT[190], INIT[187], INIT[184], INIT[181], INIT[178], INIT[175], INIT[172], INIT[169], INIT[166], INIT[163], INIT[160], INIT[157], INIT[154], INIT[151], INIT[148], INIT[145], INIT[142], INIT[139], INIT[136], INIT[133], INIT[130], INIT[127], INIT[124], INIT[121], INIT[118], INIT[115], INIT[112], INIT[109], INIT[106], INIT[103], INIT[100], INIT[ 97], INIT[ 94], INIT[ 91], INIT[ 88], INIT[ 85], INIT[ 82], INIT[ 79], INIT[ 76], INIT[ 73], INIT[ 70], INIT[ 67], INIT[ 64], INIT[ 61], INIT[ 58], INIT[ 55], INIT[ 52], INIT[ 49], INIT[ 46], INIT[ 43], INIT[ 40], INIT[ 37], INIT[ 34], INIT[ 31], INIT[ 28], INIT[ 25], INIT[ 22], INIT[ 19], INIT[ 16], INIT[ 13], INIT[ 10], INIT[ 7], INIT[ 4], INIT[ 1]}), @@ -189,12 +194,13 @@ module \$__XILINX_RAM64X3SDP (CLK1, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN); .DOA(A1DATA[0]), .DOB(A1DATA[1]), .DOC(A1DATA[2]), + .DOD(DOD_unused), .ADDRD(B1ADDR), .DIA(B1DATA[0]), .DIB(B1DATA[1]), .DIC(B1DATA[2]), - .DID(), + .DID(1'b0), .WCLK(CLK1), .WE(B1EN) ); -- cgit v1.2.3 From 503d1db551b5ab91a6ed262d011f5b9b2fa78d8e Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 16 Dec 2019 12:58:13 -0800 Subject: Implement 'attributes' grammar --- passes/memory/memory_bram.cc | 168 ++++++++++++++++++++++--------------------- 1 file changed, 88 insertions(+), 80 deletions(-) diff --git a/passes/memory/memory_bram.cc b/passes/memory/memory_bram.cc index 703e87f05..a1353e56d 100644 --- a/passes/memory/memory_bram.cc +++ b/passes/memory/memory_bram.cc @@ -134,9 +134,7 @@ struct rules_t dict min_limits, max_limits; bool or_next_if_better, make_transp, make_outreg; char shuffle_enable; - dict>> attr_match; - pair attr_val; - dict attr_unmatch; + vector>> attributes; }; dict> brams; @@ -331,29 +329,20 @@ struct rules_t } if (GetSize(tokens) >= 2 && tokens[0] == "attribute") { - if (GetSize(tokens) <=2) { - size_t notval = tokens[1].find("!"); - size_t val = tokens[1].find("="); - - if (notval != std::string::npos) { - if (val != std::string::npos) - data.attr_unmatch[RTLIL::escape_id(tokens[1].substr(1, val-1))] = tokens[1].substr(val+1); - else - data.attr_unmatch[RTLIL::escape_id(tokens[1].substr(notval+1))] = RTLIL::Const('1'); - } - continue; - } - - else if (GetSize(tokens) > 2) { - for (int idx=1; idx<= GetSize(tokens)-1; idx++) { - size_t val = tokens[idx].find("="); - if (val != std::string::npos) { - data.attr_val = make_pair(RTLIL::escape_id(tokens[idx].substr(0, val)), tokens[idx].substr(val+1)); - data.attr_match[RTLIL::escape_id(tokens[0])].push_back(data.attr_val); - } - } - continue; + data.attributes.emplace_back(); + for (int idx = 1; idx <= GetSize(tokens)-1; idx++) { + size_t c1 = tokens[1][0] == '!' ? 1 : 0; + size_t c2 = tokens[1].find("="); + if (c2 != std::string::npos) + c2--; + + bool exists = (c1 == 0); + IdString key = RTLIL::escape_id(tokens[1].substr(c1, c2)); + Const val = c2 != std::string::npos ? tokens[1].substr(c2) : RTLIL::Const(1); + + data.attributes.back().emplace_back(exists, key, val); } + continue; } syntax_error(); @@ -821,27 +810,6 @@ grow_read_ports:; log(" Updated properties: dups=%d waste=%d efficiency=%d\n", match_properties["dups"], match_properties["waste"], match_properties["efficiency"]); - for (auto iter: match.attr_match) { - for (auto iter: iter.second) { - auto it = cell->attributes.find(iter.first); - - if (iter.second.empty()) { - log(" Rule for bram type %s is rejected: requirement 'attribute %s=\"%s\"' not met.\n", - log_id(match.name), log_id(iter.first), iter.second.decode_string().c_str()); - return false; - } - - if (it != cell->attributes.end()) { - if (it->second == iter.second) - continue; - log(" Rule for bram type %s is rejected: requirement 'attribute %s=\"%s\"' not met.\n", - log_id(match.name), log_id(iter.first), iter.second.decode_string().c_str()); - return false; - } - return true; - } - } - for (auto it : match.min_limits) { if (!match_properties.count(it.first)) log_error("Unknown property '%s' in match rule for bram type %s.\n", @@ -863,6 +831,43 @@ grow_read_ports:; return false; } + for (const auto &sums : match.attributes) { + bool found = false; + for (const auto &term : sums) { + bool exists = std::get<0>(term); + IdString key = std::get<1>(term); + const Const &value = std::get<2>(term); + auto it = cell->attributes.find(key); + if (it == cell->attributes.end()) { + if (exists) + continue; + found = true; + break; + } + if (it->second != value) + continue; + found = true; + break; + } + if (!found) { + std::stringstream ss; + bool exists = std::get<0>(sums.front()); + if (!exists) + ss << "!"; + IdString key = std::get<1>(sums.front()); + ss << key.str(); + const Const &value = std::get<2>(sums.front()); + if (exists) + ss << "="; + if (value != Const(1)) + ss << "\"" << value.decode_string() << "\""; + + log(" Rule for bram type %s rejected: requirement 'attribute %s ...' not met.\n", + log_id(match.name), ss.str().c_str()); + return false; + } + } + if (mode == 1) return true; } @@ -1124,39 +1129,6 @@ void handle_cell(Cell *cell, const rules_t &rules) goto next_match_rule; } - for (auto iter: match.attr_match) { - for (auto iter: iter.second) { - auto it = cell->attributes.find(iter.first); - - if (it != cell->attributes.end()) { - if (!it->second.empty()) { - if (it->second.decode_string().length() == 1) - it->second = it->second.as_string().back(); - if (!it->second.decode_string().compare(iter.second.decode_string())) - goto attribute_matched; - else - log(" Rule for bram type %s is rejected: requirement 'attribute %s=\"%s\"' not met.\n", - log_id(match.name), log_id(iter.first), iter.second.decode_string().c_str()); - } - } - } - } - - for (auto& iter: match.attr_unmatch) { - auto it = cell->attributes.find(iter.first); - - if (it != cell->attributes.end()) { - if (!it->second.empty()) { - if (it->second.decode_string().length() == 1) - it->second = it->second.as_string().back(); - if (!it->second.decode_string().compare(iter.second.decode_string())) - goto next_match_rule; - log(" Rule for bram type %s is rejected: requirement 'attribute %s=\"%s\"' not met.\n", - log_id(match.name), log_id(iter.first), iter.second.decode_string().c_str()); - } - } - } - for (auto it : match.min_limits) { if (it.first == "waste" || it.first == "dups" || it.first == "acells" || it.first == "dcells" || it.first == "cells") continue; @@ -1183,7 +1155,43 @@ void handle_cell(Cell *cell, const rules_t &rules) goto next_match_rule; } - attribute_matched: + for (const auto &sums : match.attributes) { + bool found = false; + for (const auto &term : sums) { + bool exists = std::get<0>(term); + IdString key = std::get<1>(term); + const Const &value = std::get<2>(term); + auto it = cell->attributes.find(key); + if (it == cell->attributes.end()) { + if (exists) + continue; + found = true; + break; + } + if (it->second != value) + continue; + found = true; + break; + } + if (!found) { + std::stringstream ss; + bool exists = std::get<0>(sums.front()); + if (!exists) + ss << "!"; + IdString key = std::get<1>(sums.front()); + ss << key.str(); + const Const &value = std::get<2>(sums.front()); + if (exists) + ss << "="; + if (value != Const(1)) + ss << "\"" << value.decode_string() << "\""; + + log(" Rule for bram type %s (variant %d) rejected: requirement 'attribute %s ...' not met.\n", + log_id(bram.name), bram.variant, ss.str().c_str()); + goto next_match_rule; + } + } + log(" Rule #%d for bram type %s (variant %d) accepted.\n", i+1, log_id(bram.name), bram.variant); if (or_next_if_better || !best_rule_cache.empty()) -- cgit v1.2.3 From d910bec8e00b5e9eba2fc62dec1a6b734e429cc4 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 16 Dec 2019 13:00:58 -0800 Subject: Update xc7/xcu bram rules --- techlibs/xilinx/xc7_xcu_brams.txt | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/techlibs/xilinx/xc7_xcu_brams.txt b/techlibs/xilinx/xc7_xcu_brams.txt index 1374a0a36..60425fed9 100644 --- a/techlibs/xilinx/xc7_xcu_brams.txt +++ b/techlibs/xilinx/xc7_xcu_brams.txt @@ -77,8 +77,7 @@ endbram # https://www.xilinx.com/support/documentation/user_guides/ug473_7Series_Memory_Resources.pdf match $__XILINX_RAMB36_SDP - attribute ram_style=block ram_block=1 - attribute !ram_style + attribute !ram_style ram_style=block ram_block attribute !logic_block min bits 1024 min efficiency 5 @@ -88,8 +87,7 @@ match $__XILINX_RAMB36_SDP endmatch match $__XILINX_RAMB18_SDP - attribute ram_style=block ram_block=1 - attribute !ram_style + attribute !ram_style ram_style=block ram_block attribute !logic_block min bits 1024 min efficiency 5 @@ -99,8 +97,7 @@ match $__XILINX_RAMB18_SDP endmatch match $__XILINX_RAMB36_TDP - attribute ram_style=block ram_block=1 - attribute !ram_style + attribute !ram_style ram_style=block ram_block attribute !logic_block min bits 1024 min efficiency 5 @@ -110,8 +107,7 @@ match $__XILINX_RAMB36_TDP endmatch match $__XILINX_RAMB18_TDP - attribute ram_style=block ram_block=1 - attribute !ram_style + attribute !ram_style ram_style=block ram_block attribute !logic_block min bits 1024 min efficiency 5 -- cgit v1.2.3 From e990c013c57da8149dbbd2fe2633e953ec8f471b Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 16 Dec 2019 13:01:51 -0800 Subject: Merge blockram tests --- tests/arch/common/blockram.v | 45 ++++++++++++++++++++ tests/arch/common/blockram_params.v | 45 -------------------- tests/arch/xilinx/blockram.ys | 81 ++++++++++++++++++++++++++++++++++++ tests/arch/xilinx/blockram_params.ys | 47 --------------------- 4 files changed, 126 insertions(+), 92 deletions(-) create mode 100644 tests/arch/common/blockram.v delete mode 100644 tests/arch/common/blockram_params.v create mode 100644 tests/arch/xilinx/blockram.ys delete mode 100644 tests/arch/xilinx/blockram_params.ys diff --git a/tests/arch/common/blockram.v b/tests/arch/common/blockram.v new file mode 100644 index 000000000..dbc6ca65c --- /dev/null +++ b/tests/arch/common/blockram.v @@ -0,0 +1,45 @@ +`default_nettype none +module sync_ram_sp #(parameter DATA_WIDTH=8, ADDRESS_WIDTH=10) + (input wire write_enable, clk, + input wire [DATA_WIDTH-1:0] data_in, + input wire [ADDRESS_WIDTH-1:0] address_in, + output wire [DATA_WIDTH-1:0] data_out); + + localparam WORD = (DATA_WIDTH-1); + localparam DEPTH = (2**ADDRESS_WIDTH-1); + + reg [WORD:0] data_out_r; + reg [WORD:0] memory [0:DEPTH]; + + always @(posedge clk) begin + if (write_enable) + memory[address_in] <= data_in; + data_out_r <= memory[address_in]; + end + + assign data_out = data_out_r; +endmodule // sync_ram_sp + + +`default_nettype none +module sync_ram_sdp #(parameter DATA_WIDTH=8, ADDRESS_WIDTH=10) + (input wire clk, write_enable, + input wire [DATA_WIDTH-1:0] data_in, + input wire [ADDRESS_WIDTH-1:0] address_in_r, address_in_w, + output wire [DATA_WIDTH-1:0] data_out); + + localparam WORD = (DATA_WIDTH-1); + localparam DEPTH = (2**ADDRESS_WIDTH-1); + + reg [WORD:0] data_out_r; + reg [WORD:0] memory [0:DEPTH]; + + always @(posedge clk) begin + if (write_enable) + memory[address_in_w] <= data_in; + data_out_r <= memory[address_in_r]; + end + + assign data_out = data_out_r; +endmodule // sync_ram_sdp + diff --git a/tests/arch/common/blockram_params.v b/tests/arch/common/blockram_params.v deleted file mode 100644 index dbc6ca65c..000000000 --- a/tests/arch/common/blockram_params.v +++ /dev/null @@ -1,45 +0,0 @@ -`default_nettype none -module sync_ram_sp #(parameter DATA_WIDTH=8, ADDRESS_WIDTH=10) - (input wire write_enable, clk, - input wire [DATA_WIDTH-1:0] data_in, - input wire [ADDRESS_WIDTH-1:0] address_in, - output wire [DATA_WIDTH-1:0] data_out); - - localparam WORD = (DATA_WIDTH-1); - localparam DEPTH = (2**ADDRESS_WIDTH-1); - - reg [WORD:0] data_out_r; - reg [WORD:0] memory [0:DEPTH]; - - always @(posedge clk) begin - if (write_enable) - memory[address_in] <= data_in; - data_out_r <= memory[address_in]; - end - - assign data_out = data_out_r; -endmodule // sync_ram_sp - - -`default_nettype none -module sync_ram_sdp #(parameter DATA_WIDTH=8, ADDRESS_WIDTH=10) - (input wire clk, write_enable, - input wire [DATA_WIDTH-1:0] data_in, - input wire [ADDRESS_WIDTH-1:0] address_in_r, address_in_w, - output wire [DATA_WIDTH-1:0] data_out); - - localparam WORD = (DATA_WIDTH-1); - localparam DEPTH = (2**ADDRESS_WIDTH-1); - - reg [WORD:0] data_out_r; - reg [WORD:0] memory [0:DEPTH]; - - always @(posedge clk) begin - if (write_enable) - memory[address_in_w] <= data_in; - data_out_r <= memory[address_in_r]; - end - - assign data_out = data_out_r; -endmodule // sync_ram_sdp - diff --git a/tests/arch/xilinx/blockram.ys b/tests/arch/xilinx/blockram.ys new file mode 100644 index 000000000..362d33229 --- /dev/null +++ b/tests/arch/xilinx/blockram.ys @@ -0,0 +1,81 @@ +### TODO: Not running equivalence checking because BRAM models does not exists +### currently. Checking instance counts instead. +## 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 +#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 +#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 +#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 +#cd sync_ram_sdp +#select -assert-count 1 t:RAMB18E1 +# +## Anything memory bits < 1024 -> LUTRAM +#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 +#cd sync_ram_sdp +#select -assert-count 0 t:RAMB18E1 +#select -assert-count 4 t:RAM128X1D +# +## More than 18K bits, data width <= 36 (TDP), and address width from 10 to 15b (non-cascaded) -> RAMB36E1 +#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 +#cd sync_ram_sdp +#select -assert-count 1 t:RAMB36E1 +# +# +#### With parameters + +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 +cd sync_ram_sdp +select -assert-count 1 t:RAMB18E1 + +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 +cd sync_ram_sdp +select -assert-count 1 t:RAMB18E1 + +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 +cd sync_ram_sdp +select -assert-count 0 t:RAMB18E1 + +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 +cd sync_ram_sdp +select -assert-count 0 t:RAMB18E1 diff --git a/tests/arch/xilinx/blockram_params.ys b/tests/arch/xilinx/blockram_params.ys deleted file mode 100644 index 27a94834e..000000000 --- a/tests/arch/xilinx/blockram_params.ys +++ /dev/null @@ -1,47 +0,0 @@ -## TODO: Not running equivalence checking because BRAM models does not exists -## currently. Checking instance counts instead. -# Memory bits <= 18K; Data width <= 36; Address width <= 14: -> RAMB18E1 -read_verilog ../common/blockram_params.v -chparam -set ADDRESS_WIDTH 10 -set DATA_WIDTH 1 sync_ram_sdp -synth_xilinx -top sync_ram_sdp -cd sync_ram_sdp -select -assert-count 1 t:RAMB18E1 - -design -reset -read_verilog ../common/blockram_params.v -chparam -set ADDRESS_WIDTH 8 -set DATA_WIDTH 18 sync_ram_sdp -synth_xilinx -top sync_ram_sdp -cd sync_ram_sdp -select -assert-count 1 t:RAMB18E1 - -design -reset -read_verilog ../common/blockram_params.v -chparam -set ADDRESS_WIDTH 14 -set DATA_WIDTH 1 sync_ram_sdp -synth_xilinx -top sync_ram_sdp -cd sync_ram_sdp -select -assert-count 1 t:RAMB18E1 - -design -reset -read_verilog ../common/blockram_params.v -chparam -set ADDRESS_WIDTH 9 -set DATA_WIDTH 36 sync_ram_sdp -synth_xilinx -top sync_ram_sdp -cd sync_ram_sdp -select -assert-count 1 t:RAMB18E1 - -# Anything memory bits < 1024 -> LUTRAM -design -reset -read_verilog ../common/blockram_params.v -chparam -set ADDRESS_WIDTH 8 -set DATA_WIDTH 2 sync_ram_sdp -synth_xilinx -top sync_ram_sdp -cd sync_ram_sdp -select -assert-count 0 t:RAMB18E1 -select -assert-count 4 t:RAM128X1D - -# More than 18K bits, data width <= 36 (TDP), and address width from 10 to 15b (non-cascaded) -> RAMB36E1 -design -reset -read_verilog ../common/blockram_params.v -chparam -set ADDRESS_WIDTH 10 -set DATA_WIDTH 36 sync_ram_sdp -synth_xilinx -top sync_ram_sdp -cd sync_ram_sdp -select -assert-count 1 t:RAMB36E1 - -- cgit v1.2.3 From 6b384861e4b1e02b24bf11d266cf11f461115cd8 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 16 Dec 2019 13:31:05 -0800 Subject: Oops --- passes/memory/memory_bram.cc | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/passes/memory/memory_bram.cc b/passes/memory/memory_bram.cc index a1353e56d..7ce5e80e1 100644 --- a/passes/memory/memory_bram.cc +++ b/passes/memory/memory_bram.cc @@ -333,12 +333,9 @@ struct rules_t for (int idx = 1; idx <= GetSize(tokens)-1; idx++) { size_t c1 = tokens[1][0] == '!' ? 1 : 0; size_t c2 = tokens[1].find("="); - if (c2 != std::string::npos) - c2--; - bool exists = (c1 == 0); IdString key = RTLIL::escape_id(tokens[1].substr(c1, c2)); - Const val = c2 != std::string::npos ? tokens[1].substr(c2) : RTLIL::Const(1); + Const val = c2 != std::string::npos ? tokens[1].substr(c2+1) : RTLIL::Const(1); data.attributes.back().emplace_back(exists, key, val); } -- cgit v1.2.3 From 5a00d5578cea91ce84f3d95e6138c85d1a949b89 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 16 Dec 2019 13:31:15 -0800 Subject: Add unconditional match blocks for force RAM --- techlibs/xilinx/xc7_xcu_brams.txt | 40 +++++++++++++++++++++++++++++++++++---- tests/arch/xilinx/blockram.ys | 9 +++++++++ 2 files changed, 45 insertions(+), 4 deletions(-) diff --git a/techlibs/xilinx/xc7_xcu_brams.txt b/techlibs/xilinx/xc7_xcu_brams.txt index 60425fed9..c63218ae1 100644 --- a/techlibs/xilinx/xc7_xcu_brams.txt +++ b/techlibs/xilinx/xc7_xcu_brams.txt @@ -77,7 +77,7 @@ endbram # https://www.xilinx.com/support/documentation/user_guides/ug473_7Series_Memory_Resources.pdf match $__XILINX_RAMB36_SDP - attribute !ram_style ram_style=block ram_block + attribute !ram_style attribute !logic_block min bits 1024 min efficiency 5 @@ -86,8 +86,16 @@ match $__XILINX_RAMB36_SDP or_next_if_better endmatch +match $__XILINX_RAMB36_SDP + attribute ram_style=block ram_block + attribute !logic_block + shuffle_enable B + make_transp + or_next_if_better +endmatch + match $__XILINX_RAMB18_SDP - attribute !ram_style ram_style=block ram_block + attribute !ram_style attribute !logic_block min bits 1024 min efficiency 5 @@ -96,8 +104,16 @@ match $__XILINX_RAMB18_SDP or_next_if_better endmatch +match $__XILINX_RAMB18_SDP + attribute ram_style=block ram_block + attribute !logic_block + shuffle_enable B + make_transp + or_next_if_better +endmatch + match $__XILINX_RAMB36_TDP - attribute !ram_style ram_style=block ram_block + attribute !ram_style attribute !logic_block min bits 1024 min efficiency 5 @@ -106,12 +122,28 @@ match $__XILINX_RAMB36_TDP or_next_if_better endmatch +match $__XILINX_RAMB36_TDP + attribute ram_style=block ram_block + attribute !logic_block + shuffle_enable B + make_transp + or_next_if_better +endmatch + match $__XILINX_RAMB18_TDP - attribute !ram_style ram_style=block ram_block + attribute !ram_style attribute !logic_block min bits 1024 min efficiency 5 shuffle_enable B make_transp + or_next_if_better +endmatch + +match $__XILINX_RAMB18_TDP + attribute ram_style=block ram_block + attribute !logic_block + shuffle_enable B + make_transp endmatch diff --git a/tests/arch/xilinx/blockram.ys b/tests/arch/xilinx/blockram.ys index 362d33229..b6e105854 100644 --- a/tests/arch/xilinx/blockram.ys +++ b/tests/arch/xilinx/blockram.ys @@ -79,3 +79,12 @@ setattr -set logic_block 1 m:memory synth_xilinx -top sync_ram_sdp cd sync_ram_sdp select -assert-count 0 t:RAMB18E1 + +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 +dump m:* +synth_xilinx -top sync_ram_sdp +cd sync_ram_sdp +select -assert-count 1 t:RAMB18E1 -- cgit v1.2.3 From db0003410ff35ab39e3ea408684f600e75c16e78 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 16 Dec 2019 13:31:47 -0800 Subject: Accidentally commented out tests --- tests/arch/xilinx/blockram.ys | 94 +++++++++++++++++++++---------------------- 1 file changed, 47 insertions(+), 47 deletions(-) diff --git a/tests/arch/xilinx/blockram.ys b/tests/arch/xilinx/blockram.ys index b6e105854..4b7716739 100644 --- a/tests/arch/xilinx/blockram.ys +++ b/tests/arch/xilinx/blockram.ys @@ -1,52 +1,52 @@ ### TODO: Not running equivalence checking because BRAM models does not exists ### currently. Checking instance counts instead. -## 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 -#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 -#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 -#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 -#cd sync_ram_sdp -#select -assert-count 1 t:RAMB18E1 -# -## Anything memory bits < 1024 -> LUTRAM -#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 -#cd sync_ram_sdp -#select -assert-count 0 t:RAMB18E1 -#select -assert-count 4 t:RAM128X1D -# -## More than 18K bits, data width <= 36 (TDP), and address width from 10 to 15b (non-cascaded) -> RAMB36E1 -#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 -#cd sync_ram_sdp -#select -assert-count 1 t:RAMB36E1 -# -# -#### With parameters +# 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 +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 +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 +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 +cd sync_ram_sdp +select -assert-count 1 t:RAMB18E1 + +# Anything memory bits < 1024 -> LUTRAM +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 +cd sync_ram_sdp +select -assert-count 0 t:RAMB18E1 +select -assert-count 4 t:RAM128X1D + +# More than 18K bits, data width <= 36 (TDP), and address width from 10 to 15b (non-cascaded) -> RAMB36E1 +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 +cd sync_ram_sdp +select -assert-count 1 t:RAMB36E1 + + +### With parameters design -reset read_verilog ../common/blockram.v -- cgit v1.2.3 From 4158ce4eda4853e89187824daa32fcb57f6dfa27 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 16 Dec 2019 13:56:45 -0800 Subject: More sloppiness, thanks @dh73 for spotting --- passes/memory/memory_bram.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/passes/memory/memory_bram.cc b/passes/memory/memory_bram.cc index 7ce5e80e1..29dc4ce07 100644 --- a/passes/memory/memory_bram.cc +++ b/passes/memory/memory_bram.cc @@ -331,11 +331,11 @@ struct rules_t if (GetSize(tokens) >= 2 && tokens[0] == "attribute") { data.attributes.emplace_back(); for (int idx = 1; idx <= GetSize(tokens)-1; idx++) { - size_t c1 = tokens[1][0] == '!' ? 1 : 0; - size_t c2 = tokens[1].find("="); + size_t c1 = tokens[idx][0] == '!' ? 1 : 0; + size_t c2 = tokens[idx].find("="); bool exists = (c1 == 0); - IdString key = RTLIL::escape_id(tokens[1].substr(c1, c2)); - Const val = c2 != std::string::npos ? tokens[1].substr(c2+1) : RTLIL::Const(1); + IdString key = RTLIL::escape_id(tokens[idx].substr(c1, c2)); + Const val = c2 != std::string::npos ? tokens[idx].substr(c2+1) : RTLIL::Const(1); data.attributes.back().emplace_back(exists, key, val); } -- cgit v1.2.3 From 378d9e6e0c16e13cf161aec283ab366e2462745c Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 16 Dec 2019 13:57:55 -0800 Subject: Add another test --- tests/arch/xilinx/blockram.ys | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tests/arch/xilinx/blockram.ys b/tests/arch/xilinx/blockram.ys index 4b7716739..bb908cbbf 100644 --- a/tests/arch/xilinx/blockram.ys +++ b/tests/arch/xilinx/blockram.ys @@ -84,7 +84,14 @@ 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 -dump m:* +synth_xilinx -top sync_ram_sdp +cd sync_ram_sdp +select -assert-count 1 t:RAMB18E1 + +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 cd sync_ram_sdp select -assert-count 1 t:RAMB18E1 -- cgit v1.2.3 From 78c0246d4abbd290289ed55a0008968293119446 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 16 Dec 2019 14:35:35 -0800 Subject: Revert "write_xaiger: use sigmap bits more consistently" This reverts commit 6c340112fee1bb8989cbd41923aaa627d77d5110. --- backends/aiger/xaiger.cc | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index cff3183c1..c080cca4d 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -294,7 +294,7 @@ struct XAigerWriter output_bits.insert(b); if (!cell_known) - inout_bits.insert(I); + inout_bits.insert(b); } } } @@ -315,7 +315,7 @@ struct XAigerWriter SigBit O = sigmap(b); if (O != b) alias_map[O] = b; - input_bits.insert(O); + input_bits.insert(b); if (arrival) arrival_times[b] = arrival; @@ -542,8 +542,9 @@ struct XAigerWriter undriven_bits.erase(bit); } - // For inout ports, or keep-ed wires, which end up being both a PI and a - // a PO then replace the PO with a new wire with the $inout.out suffix + // For inout ports, or keep-ed wires, then create a new wire with an + // $inout.out suffix, make it a PO driven by the existing inout, and + // inherit existing inout's drivers for (auto bit : inout_bits) { RTLIL::Wire *wire = bit.wire; RTLIL::IdString wire_name = stringf("$%s$inout.out", wire->name.c_str()); -- cgit v1.2.3 From b19fc8839bdbf652d136790fe94cdaa1b520c75b Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 16 Dec 2019 14:39:13 -0800 Subject: Skip $inout transformation if not a PI --- backends/aiger/xaiger.cc | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index c080cca4d..6ca24bd7e 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -542,10 +542,12 @@ struct XAigerWriter undriven_bits.erase(bit); } - // For inout ports, or keep-ed wires, then create a new wire with an - // $inout.out suffix, make it a PO driven by the existing inout, and - // inherit existing inout's drivers + // For inout ports, or keep-ed wires, that end up as both a PI and a + // PO, then create a new PO with an $inout.out suffix that is driven + // by the existing inout, and inherit its drivers for (auto bit : inout_bits) { + if (!input_bits.count(bit)) + continue; RTLIL::Wire *wire = bit.wire; RTLIL::IdString wire_name = stringf("$%s$inout.out", wire->name.c_str()); RTLIL::Wire *new_wire = module->wire(wire_name); -- cgit v1.2.3 From 187e1c46e61dc910bf591625f7034b052ba928a7 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 16 Dec 2019 14:48:53 -0800 Subject: Update doc --- passes/memory/memory_bram.cc | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/passes/memory/memory_bram.cc b/passes/memory/memory_bram.cc index 29dc4ce07..7f551134a 100644 --- a/passes/memory/memory_bram.cc +++ b/passes/memory/memory_bram.cc @@ -1314,10 +1314,12 @@ struct MemoryBramPass : public Pass { log(" dcells ....... number of cells in 'data-direction'\n"); log(" cells ........ total number of cells (acells*dcells*dups)\n"); log("\n"); - log("A match containing the condition 'attribute' followed by a name and optional\n"); - log("value requires that the memory contains the given attribute name and value\n"); - log("(if specified) or that the attribute is not present (prepending a '!')\n"); - log("or the value is empty (if value is not specified\n)."); + log("A match containing the command 'attribute' followed by a list of space\n"); + log("separated 'name[=string_value]' values requires that the memory contains any\n"); + log("one of the given attribute name and string values (where specified), or name\n"); + log("and integer 1 value (if no string_value given, since Verilog will interpret\n"); + log("'(* attr *)' as '(* attr=1 *)').\n"); + log("A name prefixed with '!' indicates that the attribute must not exist.\n"); log("\n"); log("The interface for the created bram instances is derived from the bram\n"); log("description. Use 'techmap' to convert the created bram instances into\n"); -- cgit v1.2.3 From 42f990f3a6b7928841fa0e290fa2688925485907 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 16 Dec 2019 16:40:52 -0800 Subject: Use sigmap signal --- backends/aiger/xaiger.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 6ca24bd7e..e060efece 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -471,7 +471,7 @@ struct XAigerWriter SigBit O = sigmap(b); if (O != b) alias_map[O] = b; - input_bits.erase(b); + input_bits.erase(O); undriven_bits.erase(O); } } -- cgit v1.2.3 From d9bf7061cd6a5efc20c053bc96d05650f0fa3a14 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 16 Dec 2019 16:48:31 -0800 Subject: Put $__ABC9_{FF_,ASYNC} into same clock domain as abc9_flop --- passes/techmap/abc9.cc | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 8f2d45b62..34e122e7b 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -1095,7 +1095,7 @@ struct Abc9Pass : public Pass { std::map> cell_to_bit, cell_to_bit_up, cell_to_bit_down; std::map> bit_to_cell, bit_to_cell_up, bit_to_cell_down; - for (auto cell : all_cells) { + for (auto cell : all_cells) for (auto &conn : cell->connections()) for (auto bit : assign_map(conn.second)) if (bit.wire != nullptr) { @@ -1111,6 +1111,7 @@ struct Abc9Pass : public Pass { } } + for (auto cell : all_cells) { auto inst_module = design->module(cell->type); if (!inst_module || !inst_module->attributes.count("\\abc9_flop")) continue; @@ -1121,10 +1122,7 @@ struct Abc9Pass : public Pass { SigSpec abc9_clock = assign_map(abc9_clock_wire); unassigned_cells.erase(cell); - expand_queue.insert(cell); expand_queue_up.insert(cell); - expand_queue_down.insert(cell); - clkdomain_t key(abc9_clock, cell->type); assigned_cells[key].insert(cell->name); assigned_cells_reverse[cell] = key; @@ -1141,6 +1139,30 @@ struct Abc9Pass : public Pass { log_error("'%s.$abc9_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); + + // Also assign these special ABC9 cells to the + // same clock domain + for (auto b : cell_to_bit_down[cell]) + for (auto c : bit_to_cell_down[b]) + if (c->type == "$__ABC9_FF_") { + cell = c; + unassigned_cells.erase(cell); + assigned_cells[key].insert(cell->name); + assigned_cells_reverse[cell] = key; + break; + } + for (auto b : cell_to_bit_down[cell]) + for (auto c : bit_to_cell_down[b]) + if (c->type == "$__ABC9_ASYNC") { + cell = c; + unassigned_cells.erase(cell); + assigned_cells[key].insert(cell->name); + assigned_cells_reverse[cell] = key; + break; + } + + expand_queue.insert(cell); + expand_queue_down.insert(cell); } while (!expand_queue_up.empty() || !expand_queue_down.empty()) @@ -1153,7 +1175,7 @@ struct Abc9Pass : public Pass { for (auto bit : cell_to_bit_up[cell]) for (auto c : bit_to_cell_up[bit]) - if (unassigned_cells.count(c) && !c->type.in("$__ABC9_FF_", "$__ABC9_ASYNC_")) { + if (unassigned_cells.count(c)) { unassigned_cells.erase(c); next_expand_queue_up.insert(c); assigned_cells[key].insert(c->name); -- cgit v1.2.3 From 33e6d0558500d14e6711f7fc4ded1ebdb296bcaa Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 16 Dec 2019 17:06:30 -0800 Subject: Enforce non-existence --- passes/memory/memory_bram.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/passes/memory/memory_bram.cc b/passes/memory/memory_bram.cc index 7f551134a..e0970d192 100644 --- a/passes/memory/memory_bram.cc +++ b/passes/memory/memory_bram.cc @@ -841,6 +841,8 @@ grow_read_ports:; found = true; break; } + else if (!exists) + continue; if (it->second != value) continue; found = true; @@ -1165,6 +1167,8 @@ void handle_cell(Cell *cell, const rules_t &rules) found = true; break; } + else if (!exists) + continue; if (it->second != value) continue; found = true; -- cgit v1.2.3 From aed67dd020575a393b21a65baebcce1d1f49d22a Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 16 Dec 2019 18:41:56 -0800 Subject: abc9 needs a clean afterwards --- tests/simple_abc9/run-test.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) 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_ %%'" -- cgit v1.2.3 From 2e7113070010705b2c6c4a550cc2ebd3fd111ce0 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 17 Dec 2019 00:00:07 -0800 Subject: Revert "Use sigmap signal" This reverts commit 42f990f3a6b7928841fa0e290fa2688925485907. --- backends/aiger/xaiger.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index e060efece..6ca24bd7e 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -471,7 +471,7 @@ struct XAigerWriter SigBit O = sigmap(b); if (O != b) alias_map[O] = b; - input_bits.erase(O); + input_bits.erase(b); undriven_bits.erase(O); } } -- cgit v1.2.3 From e82a9bc642782ea84d46ca135d2c0b6a42b9e772 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 17 Dec 2019 00:03:03 -0800 Subject: Do not sigmap --- backends/aiger/xaiger.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 6ca24bd7e..8db166fc2 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -191,7 +191,7 @@ struct XAigerWriter } if (wire->port_input && wire->port_output) - inout_bits.insert(bit); + inout_bits.insert(wirebit); } // TODO: Speed up toposort -- ultimately we care about -- cgit v1.2.3 From dccd7eb39f897f7fb04b038ee8ac11e676a8ea77 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 17 Dec 2019 00:25:08 -0800 Subject: Cleanup --- passes/memory/memory_bram.cc | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/passes/memory/memory_bram.cc b/passes/memory/memory_bram.cc index e0970d192..24478f2ee 100644 --- a/passes/memory/memory_bram.cc +++ b/passes/memory/memory_bram.cc @@ -330,7 +330,7 @@ struct rules_t if (GetSize(tokens) >= 2 && tokens[0] == "attribute") { data.attributes.emplace_back(); - for (int idx = 1; idx <= GetSize(tokens)-1; idx++) { + for (int idx = 1; idx < GetSize(tokens); idx++) { size_t c1 = tokens[idx][0] == '!' ? 1 : 0; size_t c2 = tokens[idx].find("="); bool exists = (c1 == 0); @@ -854,12 +854,10 @@ grow_read_ports:; if (!exists) ss << "!"; IdString key = std::get<1>(sums.front()); - ss << key.str(); + ss << log_id(key); const Const &value = std::get<2>(sums.front()); - if (exists) - ss << "="; - if (value != Const(1)) - ss << "\"" << value.decode_string() << "\""; + if (exists && value != Const(1)) + ss << "=\"" << value.decode_string() << "\""; log(" Rule for bram type %s rejected: requirement 'attribute %s ...' not met.\n", log_id(match.name), ss.str().c_str()); @@ -1180,12 +1178,10 @@ void handle_cell(Cell *cell, const rules_t &rules) if (!exists) ss << "!"; IdString key = std::get<1>(sums.front()); - ss << key.str(); + ss << log_id(key); const Const &value = std::get<2>(sums.front()); - if (exists) - ss << "="; - if (value != Const(1)) - ss << "\"" << value.decode_string() << "\""; + if (exists && value != Const(1)) + ss << "=\"" << value.decode_string() << "\""; log(" Rule for bram type %s (variant %d) rejected: requirement 'attribute %s ...' not met.\n", log_id(bram.name), bram.variant, ss.str().c_str()); -- cgit v1.2.3 From 41ed6ca7a5a18aa3a2ce42e76012c43fdf2de73b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 17 Dec 2019 17:32:48 +0100 Subject: Fix sim for assignments with lhs --- passes/sat/sim.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/sat/sim.cc b/passes/sat/sim.cc index 4c3022c70..d5634b26d 100644 --- a/passes/sat/sim.cc +++ b/passes/sat/sim.cc @@ -230,7 +230,7 @@ struct SimInstance bool did_something = false; sig = sigmap(sig); - log_assert(GetSize(sig) == GetSize(value)); + log_assert(GetSize(sig) <= GetSize(value)); for (int i = 0; i < GetSize(sig); i++) if (state_nets.at(sig[i]) != value[i]) { -- cgit v1.2.3 From c8bc1793a4e8230c29fca4a34862414e8ab8722b Mon Sep 17 00:00:00 2001 From: "N. Engelhardt" Date: Tue, 17 Dec 2019 19:39:55 +0100 Subject: check scratchpad variable abc9.scriptfile --- passes/techmap/abc9.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 7fd235d6e..96642de54 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -334,6 +334,8 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri abc9_script += stringf("source %s", script_file.c_str()); } else if (design->scratchpad.count("abc9.script")) { abc9_script += design->scratchpad_get_string("abc9.script"); + } else if (design->scratchpad.count("abc9.scriptfile")) { + abc9_script += stringf("source %s", design->scratchpad_get_string("abc9.scriptfile").c_str()); } else if (!lut_costs.empty() || !lut_file.empty()) { //bool all_luts_cost_same = true; //for (int this_cost : lut_costs) -- cgit v1.2.3 From 0875a078710a2d60ec3c55e9b5a87d97fd643f3b Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 17 Dec 2019 15:43:21 -0800 Subject: read_xaiger to cope with optional '\n' after 'c' --- frontends/aiger/aigerparse.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc index 65a9e30ae..abc2f4144 100644 --- a/frontends/aiger/aigerparse.cc +++ b/frontends/aiger/aigerparse.cc @@ -379,8 +379,8 @@ void AigerReader::parse_xaiger(const dict &box_lookup) int c = f.get(); if (c != 'c') log_error("Line %u: cannot interpret first character '%c'!\n", line_count, c); - c = f.get(); - log_assert(c == '\n'); + if (f.peek() == '\n') + f.get(); // Parse footer (symbol table, comments, etc.) std::string s; -- cgit v1.2.3 From 5f50e4f1121d139c3c9b842514c86cfc7712b32e Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 17 Dec 2019 15:44:35 -0800 Subject: Cleanup xaiger, remove unnecessary complexity with inout --- backends/aiger/xaiger.cc | 81 +++++++++++-------------------------------- frontends/aiger/aigerparse.cc | 27 +++------------ 2 files changed, 24 insertions(+), 84 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 8db166fc2..af52daa0c 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -264,9 +264,22 @@ struct XAigerWriter bit_users[bit].insert(cell->name); } - if (port_wire->port_output) - for (auto bit : sigmap(conn.second)) + 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(); + } + + for (auto bit : sigmap(conn.second)) { bit_drivers[bit].insert(cell->name); + if (arrival) + arrival_times[bit] = arrival; + } + } + } if (inst_module->attributes.count("\\abc9_flop")) @@ -291,35 +304,12 @@ struct XAigerWriter SigBit I = sigmap(b); if (I != b) alias_map[b] = I; - output_bits.insert(b); - - if (!cell_known) - inout_bits.insert(b); - } - } - } - if (is_output) { - int arrival = 0; - if (port_wire) { - 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 (holes_mode) + output_bits.insert(b); + else + external_bits.insert(b); } } - - for (auto b : c.second) { - Wire *w = b.wire; - if (!w) continue; - SigBit O = sigmap(b); - if (O != b) - alias_map[O] = b; - input_bits.insert(b); - - if (arrival) - arrival_times[b] = arrival; - } } } @@ -471,7 +461,7 @@ struct XAigerWriter SigBit O = sigmap(b); if (O != b) alias_map[O] = b; - input_bits.erase(b); + input_bits.erase(O); undriven_bits.erase(O); } } @@ -542,37 +532,6 @@ struct XAigerWriter undriven_bits.erase(bit); } - // For inout ports, or keep-ed wires, that end up as both a PI and a - // PO, then create a new PO with an $inout.out suffix that is driven - // by the existing inout, and inherit its drivers - for (auto bit : inout_bits) { - if (!input_bits.count(bit)) - continue; - RTLIL::Wire *wire = bit.wire; - 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; - } - else if (and_map.count(bit)) { - auto a = and_map.at(bit); - and_map[new_bit] = a; - } - else if (alias_map.count(bit)) { - auto a = alias_map.at(bit); - alias_map[new_bit] = a; - } - else - alias_map[new_bit] = bit; - output_bits.erase(bit); - output_bits.insert(new_bit); - } - if (holes_mode) { struct sort_by_port_id { bool operator()(const RTLIL::SigBit& a, const RTLIL::SigBit& b) const { diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc index abc2f4144..613723966 100644 --- a/frontends/aiger/aigerparse.cc +++ b/frontends/aiger/aigerparse.cc @@ -887,16 +887,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; @@ -908,19 +899,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); -- cgit v1.2.3 From a6fdb9f5c1262e57d4aa292778c947773d9fe04d Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 17 Dec 2019 15:50:01 -0800 Subject: aiger frontend to user shorter, $-prefixed, names --- frontends/aiger/aigerparse.cc | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc index 613723966..9cb05dfb3 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,7 +335,7 @@ 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; } @@ -372,7 +372,7 @@ void AigerReader::parse_xaiger(const dict &box_lookup) else log_abort(); - RTLIL::Wire* n0 = module->wire("\\__0__"); + RTLIL::Wire* n0 = module->wire("$0"); if (n0) module->connect(n0, State::S0); @@ -396,13 +396,13 @@ void AigerReader::parse_xaiger(const dict &box_lookup) 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)); + 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)); + RTLIL::Wire *wire = module->wire(stringf("$%d", nodeID)); log_assert(wire); input_sig.append(wire); } @@ -419,10 +419,10 @@ void AigerReader::parse_xaiger(const dict &box_lookup) log_assert(o.wire == nullptr); lut_mask[gray] = o.data; } - RTLIL::Cell *output_cell = module->cell(stringf("\\__%d__$and", rootNodeID)); + 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)); + module->addLut(stringf("$%d$lut", rootNodeID), input_sig, output_sig, std::move(lut_mask)); } } else if (c == 'r') { @@ -456,7 +456,7 @@ void AigerReader::parse_xaiger(const dict &box_lookup) 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)); + RTLIL::Cell* cell = module->addCell(stringf("$__box%u", oldBoxNum), box_lookup.at(boxUniqueId)); boxes.emplace_back(cell); } } @@ -544,7 +544,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); @@ -613,7 +613,7 @@ void AigerReader::parse_aiger_binary() int digits = ceil(log10(I)); for (unsigned i = 1; i <= I; ++i) { log_debug2("%d is an input\n", i); - RTLIL::Wire *wire = module->addWire(stringf("\\i%0*d", digits, i)); + RTLIL::Wire *wire = module->addWire(stringf("$i%0*d", digits, i)); wire->port_input = true; module->connect(createWireIfNotExists(module, i << 1), wire); inputs.push_back(wire); @@ -671,7 +671,7 @@ void AigerReader::parse_aiger_binary() log_error("Line %u cannot be interpreted as an output!\n", line_count); log_debug2("%d is an output\n", l1); - RTLIL::Wire *wire = module->addWire(stringf("\\o%0*d", digits, i)); + 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); @@ -915,7 +915,7 @@ void AigerReader::post_process() 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()) { -- cgit v1.2.3 From b1b99e421eac9f960a08a17fe69e56a0b0661ebb Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 17 Dec 2019 16:10:40 -0800 Subject: Use pool<> instead of std::set<> to preserver ordering --- passes/techmap/abc9.cc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 34e122e7b..1f7585318 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -1082,18 +1082,18 @@ struct Abc9Pass : public Pass { assign_map.set(module); std::vector all_cells = module->selected_cells(); - std::set unassigned_cells(all_cells.begin(), all_cells.end()); + pool unassigned_cells(all_cells.begin(), all_cells.end()); - std::set expand_queue, next_expand_queue; - std::set expand_queue_up, next_expand_queue_up; - std::set expand_queue_down, next_expand_queue_down; + pool expand_queue, next_expand_queue; + pool expand_queue_up, next_expand_queue_up; + pool expand_queue_down, next_expand_queue_down; typedef std::pair clkdomain_t; std::map> assigned_cells; std::map assigned_cells_reverse; - std::map> cell_to_bit, cell_to_bit_up, cell_to_bit_down; - std::map> bit_to_cell, bit_to_cell_up, bit_to_cell_down; + std::map> cell_to_bit, cell_to_bit_up, cell_to_bit_down; + std::map> bit_to_cell, bit_to_cell_up, bit_to_cell_down; for (auto cell : all_cells) for (auto &conn : cell->connections()) -- cgit v1.2.3 From 5e206199f4639dbebfc9e2a0e6a8170db449b088 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 17 Dec 2019 16:11:37 -0800 Subject: Bump ABC for upstream fix --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index e484656c8..44d064896 100644 --- a/Makefile +++ b/Makefile @@ -128,7 +128,7 @@ bumpversion: # is just a symlink to your actual ABC working directory, as 'make mrproper' # will remove the 'abc' directory and you do not want to accidentally # delete your work on ABC.. -ABCREV = 451f2b0 +ABCREV = 02393a2 ABCPULL = 1 ABCURL ?= https://github.com/berkeley-abc/abc ABCMKARGS = CC="$(CXX)" CXX="$(CXX)" ABC_USE_LIBSTDCXX=1 -- cgit v1.2.3 From c9c77a90b32a1fea64823dbded7eeddf826617a1 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 17 Dec 2019 16:11:54 -0800 Subject: Remove &verify -s --- passes/techmap/abc9.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 1f7585318..8027c5131 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -30,7 +30,7 @@ "&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; &verify -s" +#define ABC_COMMAND_LUT "&st; &scorr; &sweep; &dc2; &st; &dch -f; &ps; &if {W} {D} -v; &mfs; &ps -l" #endif -- cgit v1.2.3 From 3671ecc7d0b3792c61ceee858435b3b75ad4739c Mon Sep 17 00:00:00 2001 From: "N. Engelhardt" Date: Wed, 18 Dec 2019 12:30:30 +0100 Subject: use extra_args --- passes/cmds/scratchpad.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/cmds/scratchpad.cc b/passes/cmds/scratchpad.cc index 805badc7e..7ec55b78e 100644 --- a/passes/cmds/scratchpad.cc +++ b/passes/cmds/scratchpad.cc @@ -122,9 +122,9 @@ struct ScratchpadPass : public Pass { log_error("Assertion failed: scratchpad entry '%s' is defined\n", identifier.c_str()); continue; } - log("Unrecognized argument: %s\n", args[argidx].c_str()); break; } + extra_args(args, argidx, design, false); } } ScratchpadPass; PRIVATE_NAMESPACE_END -- cgit v1.2.3 From 22dd9f107c8986463041709aabcd0c886c87d33f Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 18 Dec 2019 13:06:34 +0100 Subject: Send people to symbioticeda.com instead of verific.com Signed-off-by: Clifford Wolf --- frontends/verific/README | 8 ++++++-- frontends/verific/verific.cc | 23 ++++++++++++++++++++--- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/frontends/verific/README b/frontends/verific/README index 89584f2e8..c37d76343 100644 --- a/frontends/verific/README +++ b/frontends/verific/README @@ -1,7 +1,11 @@ - This directory contains Verific bindings for Yosys. -See http://www.verific.com/ for details. + +Use Symbiotic EDA Suite if you need Yosys+Verifc. +https://www.symbioticeda.com/seda-suite + +Contact office@symbioticeda.com for free evaluation +binaries of Symbiotic EDA Suite. Verific Features that should be enabled in your Verific library diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 843e7b9b4..9274cf5ca 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -2065,7 +2065,12 @@ struct VerificPass : public Pass { log(" -d \n"); log(" Dump the Verific netlist as a verilog file.\n"); log("\n"); - log("Visit http://verific.com/ for more information on Verific.\n"); + log("\n"); + log("Use Symbiotic EDA Suite if you need Yosys+Verifc.\n"); + log("https://www.symbioticeda.com/seda-suite\n"); + log("\n"); + log("Contact office@symbioticeda.com for free evaluation\n"); + log("binaries of Symbiotic EDA Suite.\n"); log("\n"); } #ifdef YOSYS_ENABLE_VERIFIC @@ -2074,7 +2079,13 @@ struct VerificPass : public Pass { static bool set_verific_global_flags = true; if (check_noverific_env()) - log_cmd_error("This version of Yosys is built without Verific support.\n"); + log_cmd_error("This version of Yosys is built without Verific support.\n" + "\n" + "Use Symbiotic EDA Suite if you need Yosys+Verifc.\n" + "https://www.symbioticeda.com/seda-suite\n" + "\n" + "Contact office@symbioticeda.com for free evaluation\n" + "binaries of Symbiotic EDA Suite.\n"); log_header(design, "Executing VERIFIC (loading SystemVerilog and VHDL designs using Verific).\n"); @@ -2493,7 +2504,13 @@ struct VerificPass : public Pass { } #else /* YOSYS_ENABLE_VERIFIC */ void execute(std::vector, RTLIL::Design *) YS_OVERRIDE { - log_cmd_error("This version of Yosys is built without Verific support.\n"); + log_cmd_error("This version of Yosys is built without Verific support.\n" + "\n" + "Use Symbiotic EDA Suite if you need Yosys+Verifc.\n" + "https://www.symbioticeda.com/seda-suite\n" + "\n" + "Contact office@symbioticeda.com for free evaluation\n" + "binaries of Symbiotic EDA Suite.\n"); } #endif } VerificPass; -- cgit v1.2.3 From aff6ad1ce09264fb7fbf43a7456a746a586bea90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20Ko=C5=9Bcielnicki?= Date: Thu, 21 Nov 2019 06:30:06 +0100 Subject: xilinx: Improve flip-flop handling. This adds support for infering more kinds of flip-flops: - FFs with async set/reset and clock enable - FFs with sync set/reset - FFs with sync set/reset and clock enable Some passes have been moved (and some added) in order for dff2dffs to work correctly. This gives us complete coverage of Virtex 6+ and Spartan 6 flip-flop capabilities (though not latch capabilities). Older FPGAs also support having both a set and a reset input, which will be handled at a later data. --- CHANGELOG | 2 + techlibs/xilinx/cells_map.v | 27 +++++++++ techlibs/xilinx/synth_xilinx.cc | 15 +++-- techlibs/xilinx/xc6s_ff_map.v | 130 ++++++++++++++++++++++++++++++++++------ techlibs/xilinx/xc7_ff_map.v | 94 ++++++++++++++++++++++++----- tests/arch/xilinx/adffs.ys | 9 ++- tests/arch/xilinx/fsm.ys | 11 ++-- tests/arch/xilinx/macc.ys | 3 +- 8 files changed, 242 insertions(+), 49 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index a49c27b05..cb2b7bf0c 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -50,6 +50,8 @@ Yosys 0.9 .. Yosys 0.9-dev - "synth_ecp5" to now infer DSP blocks (-nodsp to disable, experimental) - "synth_ice40 -dsp" to infer DSP blocks - Added latch support to synth_xilinx + - Added support for flip-flops with synchronous reset to synth_xilinx + - Added support for flip-flops with reset and enable to synth_xilinx - Added "check -mapped" - Added checking of SystemVerilog always block types (always_comb, always_latch and always_ff) diff --git a/techlibs/xilinx/cells_map.v b/techlibs/xilinx/cells_map.v index de2068bc5..cc180f2b9 100644 --- a/techlibs/xilinx/cells_map.v +++ b/techlibs/xilinx/cells_map.v @@ -28,6 +28,33 @@ module _90_dff_nn1_to_np1 (input D, C, R, output Q); \$_DFF_NP1_ _TECHMAP_REPL (* techmap_celltype = "$_DFF_PN1_" *) module _90_dff_pn1_to_pp1 (input D, C, R, output Q); \$_DFF_PP1_ _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R)); endmodule +(* techmap_celltype = "$__DFFE_NN0" *) +module _90_dffe_nn0_to_np0 (input D, C, R, E, output Q); \$__DFFE_NP0 _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R), .E(E)); endmodule +(* techmap_celltype = "$__DFFE_PN0" *) +module _90_dffe_pn0_to_pp0 (input D, C, R, E, output Q); \$__DFFE_PP0 _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R), .E(E)); endmodule +(* techmap_celltype = "$__DFFE_NN1" *) +module _90_dffe_nn1_to_np1 (input D, C, R, E, output Q); \$__DFFE_NP1 _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R), .E(E)); endmodule +(* techmap_celltype = "$__DFFE_PN1" *) +module _90_dffe_pn1_to_pp1 (input D, C, R, E, output Q); \$__DFFE_PP1 _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R), .E(E)); endmodule + +(* techmap_celltype = "$__DFFS_NN0_" *) +module _90_dffs_nn0_to_np0 (input D, C, R, output Q); \$__DFFS_NP0_ _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R)); endmodule +(* techmap_celltype = "$__DFFS_PN0_" *) +module _90_dffs_pn0_to_pp0 (input D, C, R, output Q); \$__DFFS_PP0_ _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R)); endmodule +(* techmap_celltype = "$__DFFS_NN1_" *) +module _90_dffs_nn1_to_np1 (input D, C, R, output Q); \$__DFFS_NP1_ _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R)); endmodule +(* techmap_celltype = "$__DFFS_PN1_" *) +module _90_dffs_pn1_to_pp1 (input D, C, R, output Q); \$__DFFS_PP1_ _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R)); endmodule + +(* techmap_celltype = "$__DFFSE_NN0" *) +module _90_dffse_nn0_to_np0 (input D, C, R, E, output Q); \$__DFFSE_NP0 _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R), .E(E)); endmodule +(* techmap_celltype = "$__DFFSE_PN0" *) +module _90_dffse_pn0_to_pp0 (input D, C, R, E, output Q); \$__DFFSE_PP0 _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R), .E(E)); endmodule +(* techmap_celltype = "$__DFFSE_NN1" *) +module _90_dffse_nn1_to_np1 (input D, C, R, E, output Q); \$__DFFSE_NP1 _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R), .E(E)); endmodule +(* techmap_celltype = "$__DFFSE_PN1" *) +module _90_dffse_pn1_to_pp1 (input D, C, R, E, output Q); \$__DFFSE_PP1 _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R), .E(E)); endmodule + module \$__SHREG_ (input C, input D, input E, output Q); parameter DEPTH = 0; parameter [DEPTH-1:0] INIT = 0; diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index 2c5686a35..a061c8dc0 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -444,6 +444,16 @@ struct SynthXilinxPass : public ScriptPass } if (check_label("map_ffram")) { + // Required for dffsr2dff to work. + run("simplemap t:$dff t:$adff t:$mux"); + // Needs to be done before opt -mux_bool happens. + run("dffsr2dff"); + if (help_mode) + run("dff2dffs [-match-init]", "(-match-init for xc6s only)"); + else if (family == "xc6s") + run("dff2dffs -match-init"); + else + run("dff2dffs"); if (widemux > 0) run("opt -fast -mux_bool -undriven -fine"); // Necessary to omit -mux_undef otherwise muxcover // performs less efficiently @@ -453,14 +463,11 @@ struct SynthXilinxPass : public ScriptPass } if (check_label("fine")) { - run("dffsr2dff"); - run("dff2dffe"); + run("dff2dffe -direct-match $_DFF_* -direct-match $__DFFS_*"); if (help_mode) { - run("simplemap t:$mux", " ('-widemux' only)"); run("muxcover , ('-widemux' only)"); } else if (widemux > 0) { - run("simplemap t:$mux"); constexpr int cost_mux2 = 100; std::string muxcover_args = stringf(" -nodecode -mux2=%d", cost_mux2); switch (widemux) { diff --git a/techlibs/xilinx/xc6s_ff_map.v b/techlibs/xilinx/xc6s_ff_map.v index bf35b09e5..c40f446e0 100644 --- a/techlibs/xilinx/xc6s_ff_map.v +++ b/techlibs/xilinx/xc6s_ff_map.v @@ -27,6 +27,8 @@ `ifndef _NO_FFS +// No reset. + module \$_DFF_N_ (input D, C, output Q); parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx; generate if (_TECHMAP_WIREINIT_Q_ === 1'b1) @@ -46,6 +48,8 @@ module \$_DFF_P_ (input D, C, output Q); wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule +// No reset, enable. + module \$_DFFE_NP_ (input D, C, E, output Q); parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx; generate if (_TECHMAP_WIREINIT_Q_ === 1'b1) @@ -65,80 +69,168 @@ module \$_DFFE_PP_ (input D, C, E, output Q); wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule -module \$_DFF_NN0_ (input D, C, R, output Q); +// Async reset. + +module \$_DFF_NP0_ (input D, C, R, output Q); parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx; generate if (_TECHMAP_WIREINIT_Q_ === 1'b1) $error("Spartan 6 doesn't support FFs with asynchronous reset initialized to 1"); else - FDCE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .CLR(!R)); + FDCE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .CLR( R)); endgenerate wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule -module \$_DFF_NP0_ (input D, C, R, output Q); +module \$_DFF_PP0_ (input D, C, R, output Q); parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx; generate if (_TECHMAP_WIREINIT_Q_ === 1'b1) $error("Spartan 6 doesn't support FFs with asynchronous reset initialized to 1"); else - FDCE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .CLR( R)); + FDCE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .CLR( R)); endgenerate wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule -module \$_DFF_PN0_ (input D, C, R, output Q); + +module \$_DFF_NP1_ (input D, C, R, output Q); + parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx; + generate if (_TECHMAP_WIREINIT_Q_ === 1'b0) + $error("Spartan 6 doesn't support FFs with asynchronous set initialized to 0"); + else + FDPE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .PRE( R)); + endgenerate + wire _TECHMAP_REMOVEINIT_Q_ = 1; +endmodule +module \$_DFF_PP1_ (input D, C, R, output Q); + parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx; + generate if (_TECHMAP_WIREINIT_Q_ === 1'b0) + $error("Spartan 6 doesn't support FFs with asynchronous set initialized to 0"); + else + FDPE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .PRE( R)); + endgenerate + wire _TECHMAP_REMOVEINIT_Q_ = 1; +endmodule + +// Async reset, enable. + +module \$__DFFE_NP0 (input D, C, E, R, output Q); parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx; generate if (_TECHMAP_WIREINIT_Q_ === 1'b1) $error("Spartan 6 doesn't support FFs with asynchronous reset initialized to 1"); else - FDCE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .CLR(!R)); + FDCE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .CLR( R)); endgenerate wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule -module \$_DFF_PP0_ (input D, C, R, output Q); +module \$__DFFE_PP0 (input D, C, E, R, output Q); parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx; generate if (_TECHMAP_WIREINIT_Q_ === 1'b1) $error("Spartan 6 doesn't support FFs with asynchronous reset initialized to 1"); else - FDCE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .CLR( R)); + FDCE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .CLR( R)); endgenerate wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule -module \$_DFF_NN1_ (input D, C, R, output Q); +module \$__DFFE_NP1 (input D, C, E, R, output Q); parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx; generate if (_TECHMAP_WIREINIT_Q_ === 1'b0) $error("Spartan 6 doesn't support FFs with asynchronous set initialized to 0"); else - FDPE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .PRE(!R)); + FDPE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .PRE( R)); endgenerate wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule -module \$_DFF_NP1_ (input D, C, R, output Q); +module \$__DFFE_PP1 (input D, C, E, R, output Q); parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx; generate if (_TECHMAP_WIREINIT_Q_ === 1'b0) $error("Spartan 6 doesn't support FFs with asynchronous set initialized to 0"); else - FDPE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .PRE( R)); + FDPE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .PRE( R)); + endgenerate + wire _TECHMAP_REMOVEINIT_Q_ = 1; +endmodule + +// Sync reset. + +module \$__DFFS_NP0_ (input D, C, R, output Q); + parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx; + generate if (_TECHMAP_WIREINIT_Q_ === 1'b1) + $error("Spartan 6 doesn't support FFs with reset initialized to 1"); + else + FDRE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .R( R)); endgenerate wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule -module \$_DFF_PN1_ (input D, C, R, output Q); +module \$__DFFS_PP0_ (input D, C, R, output Q); + parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx; + generate if (_TECHMAP_WIREINIT_Q_ === 1'b1) + $error("Spartan 6 doesn't support FFs with reset initialized to 1"); + else + FDRE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .R( R)); + endgenerate + wire _TECHMAP_REMOVEINIT_Q_ = 1; +endmodule + +module \$__DFFS_NP1_ (input D, C, R, output Q); parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx; generate if (_TECHMAP_WIREINIT_Q_ === 1'b0) - $error("Spartan 6 doesn't support FFs with asynchronous set initialized to 0"); + $error("Spartan 6 doesn't support FFs with set initialized to 0"); else - FDPE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .PRE(!R)); + FDSE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .S( R)); endgenerate wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule -module \$_DFF_PP1_ (input D, C, R, output Q); +module \$__DFFS_PP1_ (input D, C, R, output Q); parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx; generate if (_TECHMAP_WIREINIT_Q_ === 1'b0) - $error("Spartan 6 doesn't support FFs with asynchronous set initialized to 0"); + $error("Spartan 6 doesn't support FFs with set initialized to 0"); else - FDPE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .PRE( R)); + FDSE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .S( R)); endgenerate wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule +// Sync reset, enable. + +module \$__DFFSE_NP0 (input D, C, E, R, output Q); + parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx; + generate if (_TECHMAP_WIREINIT_Q_ === 1'b1) + $error("Spartan 6 doesn't support FFs with reset initialized to 1"); + else + FDRE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .R( R)); + endgenerate + wire _TECHMAP_REMOVEINIT_Q_ = 1; +endmodule +module \$__DFFSE_PP0 (input D, C, E, R, output Q); + parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx; + generate if (_TECHMAP_WIREINIT_Q_ === 1'b1) + $error("Spartan 6 doesn't support FFs with reset initialized to 1"); + else + FDRE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .R( R)); + endgenerate + wire _TECHMAP_REMOVEINIT_Q_ = 1; +endmodule + +module \$__DFFSE_NP1 (input D, C, E, R, output Q); + parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx; + generate if (_TECHMAP_WIREINIT_Q_ === 1'b0) + $error("Spartan 6 doesn't support FFs with set initialized to 0"); + else + FDSE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .S( R)); + endgenerate + wire _TECHMAP_REMOVEINIT_Q_ = 1; +endmodule +module \$__DFFSE_PP1 (input D, C, E, R, output Q); + parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx; + generate if (_TECHMAP_WIREINIT_Q_ === 1'b0) + $error("Spartan 6 doesn't support FFs with set initialized to 0"); + else + FDSE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .S( R)); + endgenerate + wire _TECHMAP_REMOVEINIT_Q_ = 1; +endmodule + +// Latches (no reset). + module \$_DLATCH_N_ (input E, D, output Q); parameter _TECHMAP_WIREINIT_Q_ = 1'bx; generate if (_TECHMAP_WIREINIT_Q_ === 1'b1) @@ -158,5 +250,7 @@ module \$_DLATCH_P_ (input E, D, output Q); wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule +// Latches with reset (TODO). + `endif diff --git a/techlibs/xilinx/xc7_ff_map.v b/techlibs/xilinx/xc7_ff_map.v index 32ca9f560..2bd874457 100644 --- a/techlibs/xilinx/xc7_ff_map.v +++ b/techlibs/xilinx/xc7_ff_map.v @@ -37,6 +37,8 @@ `ifndef _NO_FFS +// No reset. + module \$_DFF_N_ (input D, C, output Q); parameter _TECHMAP_WIREINIT_Q_ = 1'bx; FDRE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .R(1'b0)); @@ -48,6 +50,8 @@ module \$_DFF_P_ (input D, C, output Q); wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule +// No reset, enable. + module \$_DFFE_NP_ (input D, C, E, output Q); parameter _TECHMAP_WIREINIT_Q_ = 1'bx; FDRE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .R(1'b0)); @@ -59,47 +63,103 @@ module \$_DFFE_PP_ (input D, C, E, output Q); wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule -module \$_DFF_NN0_ (input D, C, R, output Q); +// Async reset. + +module \$_DFF_NP0_ (input D, C, R, output Q); parameter _TECHMAP_WIREINIT_Q_ = 1'bx; - FDCE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .CLR(!R)); + FDCE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .CLR( R)); wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule -module \$_DFF_NP0_ (input D, C, R, output Q); +module \$_DFF_PP0_ (input D, C, R, output Q); parameter _TECHMAP_WIREINIT_Q_ = 1'bx; - FDCE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .CLR( R)); + FDCE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .CLR( R)); wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule -module \$_DFF_PN0_ (input D, C, R, output Q); + +module \$_DFF_NP1_ (input D, C, R, output Q); parameter _TECHMAP_WIREINIT_Q_ = 1'bx; - FDCE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .CLR(!R)); + FDPE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .PRE( R)); wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule -module \$_DFF_PP0_ (input D, C, R, output Q); +module \$_DFF_PP1_ (input D, C, R, output Q); parameter _TECHMAP_WIREINIT_Q_ = 1'bx; - FDCE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .CLR( R)); + FDPE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .PRE( R)); wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule -module \$_DFF_NN1_ (input D, C, R, output Q); +// Async reset, enable. + +module \$__DFFE_NP0 (input D, C, E, R, output Q); parameter _TECHMAP_WIREINIT_Q_ = 1'bx; - FDPE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .PRE(!R)); + FDCE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .CLR( R)); wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule -module \$_DFF_NP1_ (input D, C, R, output Q); +module \$__DFFE_PP0 (input D, C, E, R, output Q); parameter _TECHMAP_WIREINIT_Q_ = 1'bx; - FDPE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .PRE( R)); + FDCE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .CLR( R)); wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule -module \$_DFF_PN1_ (input D, C, R, output Q); + +module \$__DFFE_NP1 (input D, C, E, R, output Q); parameter _TECHMAP_WIREINIT_Q_ = 1'bx; - FDPE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .PRE(!R)); + FDPE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .PRE( R)); wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule -module \$_DFF_PP1_ (input D, C, R, output Q); +module \$__DFFE_PP1 (input D, C, E, R, output Q); parameter _TECHMAP_WIREINIT_Q_ = 1'bx; - FDPE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .PRE( R)); + FDPE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .PRE( R)); + wire _TECHMAP_REMOVEINIT_Q_ = 1; +endmodule + +// Sync reset. + +module \$__DFFS_NP0_ (input D, C, R, output Q); + parameter _TECHMAP_WIREINIT_Q_ = 1'bx; + FDRE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .R( R)); wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule +module \$__DFFS_PP0_ (input D, C, R, output Q); + parameter _TECHMAP_WIREINIT_Q_ = 1'bx; + FDRE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .R( R)); + wire _TECHMAP_REMOVEINIT_Q_ = 1; +endmodule + +module \$__DFFS_NP1_ (input D, C, R, output Q); + parameter _TECHMAP_WIREINIT_Q_ = 1'bx; + FDSE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .S( R)); + wire _TECHMAP_REMOVEINIT_Q_ = 1; +endmodule +module \$__DFFS_PP1_ (input D, C, R, output Q); + parameter _TECHMAP_WIREINIT_Q_ = 1'bx; + FDSE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .S( R)); + wire _TECHMAP_REMOVEINIT_Q_ = 1; +endmodule + +// Sync reset, enable. + +module \$__DFFSE_NP0 (input D, C, E, R, output Q); + parameter _TECHMAP_WIREINIT_Q_ = 1'bx; + FDRE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .R( R)); + wire _TECHMAP_REMOVEINIT_Q_ = 1; +endmodule +module \$__DFFSE_PP0 (input D, C, E, R, output Q); + parameter _TECHMAP_WIREINIT_Q_ = 1'bx; + FDRE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .R( R)); + wire _TECHMAP_REMOVEINIT_Q_ = 1; +endmodule + +module \$__DFFSE_NP1 (input D, C, E, R, output Q); + parameter _TECHMAP_WIREINIT_Q_ = 1'bx; + FDSE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .S( R)); + wire _TECHMAP_REMOVEINIT_Q_ = 1; +endmodule +module \$__DFFSE_PP1 (input D, C, E, R, output Q); + parameter _TECHMAP_WIREINIT_Q_ = 1'bx; + FDSE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .S( R)); + wire _TECHMAP_REMOVEINIT_Q_ = 1; +endmodule + +// Latches (no reset). module \$_DLATCH_N_ (input E, D, output Q); parameter _TECHMAP_WIREINIT_Q_ = 1'bx; @@ -112,5 +172,7 @@ module \$_DLATCH_P_ (input E, D, output Q); wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule +// Latches with reset (TODO). + `endif diff --git a/tests/arch/xilinx/adffs.ys b/tests/arch/xilinx/adffs.ys index e73bfe0b9..c0ff6a2e2 100644 --- a/tests/arch/xilinx/adffs.ys +++ b/tests/arch/xilinx/adffs.ys @@ -32,10 +32,9 @@ equiv_opt -async2sync -assert -map +/xilinx/cells_sim.v synth_xilinx # equivale 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 -select -assert-count 1 t:FDRE -select -assert-count 1 t:LUT2 +select -assert-count 1 t:FDSE -select -assert-none t:BUFG t:FDRE t:LUT2 %% t:* %D +select -assert-none t:BUFG t:FDSE %% t:* %D design -load read @@ -46,6 +45,6 @@ design -load postopt # load the post-opt design (otherwise equiv_opt loads the p cd ndffnr # Constrain all select calls below inside the top module select -assert-count 1 t:BUFG select -assert-count 1 t:FDRE_1 -select -assert-count 1 t:LUT2 +select -assert-count 1 t:INV -select -assert-none t:BUFG t:FDRE_1 t:LUT2 %% t:* %D +select -assert-none t:BUFG t:FDRE_1 t:INV %% t:* %D diff --git a/tests/arch/xilinx/fsm.ys b/tests/arch/xilinx/fsm.ys index 2a72c34e8..4545cf6d7 100644 --- a/tests/arch/xilinx/fsm.ys +++ b/tests/arch/xilinx/fsm.ys @@ -11,8 +11,9 @@ design -load postopt # load the post-opt design (otherwise equiv_opt loads the p cd fsm # Constrain all select calls below inside the top module select -assert-count 1 t:BUFG -select -assert-count 5 t:FDRE -select -assert-count 1 t:LUT3 -select -assert-count 2 t:LUT4 -select -assert-count 4 t:LUT6 -select -assert-none t:BUFG t:FDRE t:LUT3 t:LUT4 t:LUT6 %% t:* %D +select -assert-count 4 t:FDRE +select -assert-count 1 t:FDSE +select -assert-count 1 t:LUT2 +select -assert-count 2 t:LUT3 +select -assert-count 4 t:LUT5 +select -assert-none t:BUFG t:FDRE t:FDSE t:LUT2 t:LUT3 t:LUT5 %% t:* %D diff --git a/tests/arch/xilinx/macc.ys b/tests/arch/xilinx/macc.ys index 6e884b35a..11e959976 100644 --- a/tests/arch/xilinx/macc.ys +++ b/tests/arch/xilinx/macc.ys @@ -23,9 +23,10 @@ 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) cd macc2 # Constrain all select calls below inside the top module + select -assert-count 1 t:BUFG select -assert-count 1 t:DSP48E1 select -assert-count 1 t:FDRE select -assert-count 1 t:LUT2 -select -assert-count 41 t:LUT3 +select -assert-count 40 t:LUT3 select -assert-none t:BUFG t:DSP48E1 t:FDRE t:LUT2 t:LUT3 %% t:* %D -- cgit v1.2.3 From a2352504031ee69efd0aac214fc947737303eb5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20Ko=C5=9Bcielnicki?= Date: Wed, 18 Dec 2019 13:42:26 +0100 Subject: xilinx: Add xilinx_dffopt pass (#1557) --- CHANGELOG | 1 + passes/equiv/equiv_opt.cc | 18 +- techlibs/xilinx/Makefile.inc | 1 + techlibs/xilinx/cells_sim.v | 35 +++ techlibs/xilinx/cells_xtra.py | 2 +- techlibs/xilinx/cells_xtra.v | 21 -- techlibs/xilinx/synth_xilinx.cc | 1 + techlibs/xilinx/xilinx_dffopt.cc | 351 ++++++++++++++++++++++++++ tests/arch/xilinx/fsm.ys | 6 +- tests/arch/xilinx/xilinx_dffopt.ys | 216 ++++++++++++++++ tests/arch/xilinx/xilinx_dffopt_blacklist.txt | 13 + 11 files changed, 638 insertions(+), 27 deletions(-) create mode 100644 techlibs/xilinx/xilinx_dffopt.cc create mode 100644 tests/arch/xilinx/xilinx_dffopt.ys create mode 100644 tests/arch/xilinx/xilinx_dffopt_blacklist.txt diff --git a/CHANGELOG b/CHANGELOG index cb2b7bf0c..9b87af8f0 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -55,6 +55,7 @@ Yosys 0.9 .. Yosys 0.9-dev - Added "check -mapped" - Added checking of SystemVerilog always block types (always_comb, always_latch and always_ff) + - Added "xilinx_dffopt" pass Yosys 0.8 .. Yosys 0.9 ---------------------- diff --git a/passes/equiv/equiv_opt.cc b/passes/equiv/equiv_opt.cc index c7e6d71a6..7c6c2e685 100644 --- a/passes/equiv/equiv_opt.cc +++ b/passes/equiv/equiv_opt.cc @@ -44,6 +44,10 @@ struct EquivOptPass:public ScriptPass log(" expand the modules in this file before proving equivalence. this is\n"); log(" useful for handling architecture-specific primitives.\n"); log("\n"); + log(" -blacklist \n"); + log(" Do not match cells or signals that match the names in the file\n"); + log(" (passed to equiv_make).\n"); + log("\n"); log(" -assert\n"); log(" produce an error if the circuits are not equivalent.\n"); log("\n"); @@ -61,13 +65,14 @@ struct EquivOptPass:public ScriptPass log("\n"); } - std::string command, techmap_opts; + std::string command, techmap_opts, make_opts; bool assert, undef, multiclock, async2sync; void clear_flags() YS_OVERRIDE { command = ""; techmap_opts = ""; + make_opts = ""; assert = false; undef = false; multiclock = false; @@ -93,6 +98,10 @@ struct EquivOptPass:public ScriptPass techmap_opts += " -map " + args[++argidx]; continue; } + if (args[argidx] == "-blacklist" && argidx + 1 < args.size()) { + make_opts += " -blacklist " + args[++argidx]; + continue; + } if (args[argidx] == "-assert") { assert = true; continue; @@ -170,7 +179,12 @@ struct EquivOptPass:public ScriptPass run("clk2fflogic", "(only with -multiclock)"); if (async2sync || help_mode) run("async2sync", " (only with -async2sync)"); - run("equiv_make gold gate equiv"); + string opts; + if (help_mode) + opts = " -blacklist ..."; + else + opts = make_opts; + run("equiv_make" + opts + " gold gate equiv"); if (help_mode) run("equiv_induct [-undef] equiv"); else if (undef) diff --git a/techlibs/xilinx/Makefile.inc b/techlibs/xilinx/Makefile.inc index 3ebc72fe8..3f2fbcc85 100644 --- a/techlibs/xilinx/Makefile.inc +++ b/techlibs/xilinx/Makefile.inc @@ -1,5 +1,6 @@ OBJS += techlibs/xilinx/synth_xilinx.o +OBJS += techlibs/xilinx/xilinx_dffopt.o GENFILES += techlibs/xilinx/brams_init_36.vh GENFILES += techlibs/xilinx/brams_init_32.vh diff --git a/techlibs/xilinx/cells_sim.v b/techlibs/xilinx/cells_sim.v index f9ce496ff..cf7923777 100644 --- a/techlibs/xilinx/cells_sim.v +++ b/techlibs/xilinx/cells_sim.v @@ -329,6 +329,41 @@ module FDSE ( endcase endgenerate endmodule +module FDRSE ( + output reg Q, + (* clkbuf_sink *) + (* invertible_pin = "IS_C_INVERTED" *) + input C, + (* invertible_pin = "IS_CE_INVERTED" *) + input CE, + (* invertible_pin = "IS_D_INVERTED" *) + input D, + (* invertible_pin = "IS_R_INVERTED" *) + input R, + (* invertible_pin = "IS_S_INVERTED" *) + input S +); + parameter [0:0] INIT = 1'b0; + parameter [0:0] IS_C_INVERTED = 1'b0; + parameter [0:0] IS_CE_INVERTED = 1'b0; + parameter [0:0] IS_D_INVERTED = 1'b0; + parameter [0:0] IS_R_INVERTED = 1'b0; + parameter [0:0] IS_S_INVERTED = 1'b0; + initial Q <= INIT; + wire c = C ^ IS_C_INVERTED; + wire ce = CE ^ IS_CE_INVERTED; + wire d = D ^ IS_D_INVERTED; + wire r = R ^ IS_R_INVERTED; + wire s = S ^ IS_S_INVERTED; + always @(posedge c) + if (r) + Q <= 0; + else if (s) + Q <= 1; + else if (ce) + Q <= d; +endmodule + module FDCE ( (* abc9_arrival=303 *) output reg Q, diff --git a/techlibs/xilinx/cells_xtra.py b/techlibs/xilinx/cells_xtra.py index e4c580b9d..6d5adf1aa 100644 --- a/techlibs/xilinx/cells_xtra.py +++ b/techlibs/xilinx/cells_xtra.py @@ -66,7 +66,7 @@ CELLS = [ # CLB -- registers/latches. # Virtex 1/2/4/5, Spartan 3. Cell('FDCPE', port_attrs={'C': ['clkbuf_sink']}), - Cell('FDRSE', port_attrs={'C': ['clkbuf_sink']}), + # Cell('FDRSE', port_attrs={'C': ['clkbuf_sink']}), Cell('LDCPE', port_attrs={'C': ['clkbuf_sink']}), # Virtex 6, Spartan 6, Series 7, Ultrascale. # Cell('FDCE'), diff --git a/techlibs/xilinx/cells_xtra.v b/techlibs/xilinx/cells_xtra.v index 8ac596459..66b7c583f 100644 --- a/techlibs/xilinx/cells_xtra.v +++ b/techlibs/xilinx/cells_xtra.v @@ -17,27 +17,6 @@ module FDCPE (...); input PRE; endmodule -module FDRSE (...); - parameter [0:0] INIT = 1'b0; - parameter [0:0] IS_C_INVERTED = 1'b0; - parameter [0:0] IS_CE_INVERTED = 1'b0; - parameter [0:0] IS_D_INVERTED = 1'b0; - parameter [0:0] IS_R_INVERTED = 1'b0; - parameter [0:0] IS_S_INVERTED = 1'b0; - output Q; - (* clkbuf_sink *) - (* invertible_pin = "IS_C_INVERTED" *) - input C; - (* invertible_pin = "IS_CE_INVERTED" *) - input CE; - (* invertible_pin = "IS_D_INVERTED" *) - input D; - (* invertible_pin = "IS_R_INVERTED" *) - input R; - (* invertible_pin = "IS_S_INVERTED" *) - input S; -endmodule - module LDCPE (...); parameter [0:0] INIT = 1'b0; parameter [0:0] IS_CLR_INVERTED = 1'b0; diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index a061c8dc0..971089b28 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -570,6 +570,7 @@ struct SynthXilinxPass : public ScriptPass else techmap_args += " -map " + ff_map_file; run("techmap " + techmap_args); + run("xilinx_dffopt"); run("clean"); } diff --git a/techlibs/xilinx/xilinx_dffopt.cc b/techlibs/xilinx/xilinx_dffopt.cc new file mode 100644 index 000000000..1256a08cb --- /dev/null +++ b/techlibs/xilinx/xilinx_dffopt.cc @@ -0,0 +1,351 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 Clifford Wolf + * + * 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/yosys.h" +#include "kernel/sigtools.h" + +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + +typedef std::pair> LutData; + +// Compute a LUT implementing (select ^ select_inv) ? alt_data : data. Returns true if successful. +bool merge_lut(LutData &result, const LutData &data, const LutData select, bool select_inv, SigBit alt_data, int max_lut_size) { + // First, gather input signals. + result.second = data.second; + int idx_alt = -1; + if (alt_data.wire) { + // Check if we already have it. + for (int i = 0; i < GetSize(result.second); i++) + if (result.second[i] == alt_data) + idx_alt = i; + // If not, add it. + if (idx_alt == -1) { + idx_alt = GetSize(result.second); + result.second.push_back(alt_data); + } + } + std::vector idx_sel; + for (auto bit : select.second) { + int idx = -1; + for (int i = 0; i < GetSize(result.second); i++) + if (result.second[i] == bit) + idx = i; + if (idx == -1) { + idx = GetSize(result.second); + result.second.push_back(bit); + } + idx_sel.push_back(idx); + } + + // If LUT would be too large, bail. + if (GetSize(result.second) > max_lut_size) + return false; + + // Okay, we're doing it — compute the LUT mask. + result.first = Const(0, 1 << GetSize(result.second)); + for (int i = 0; i < GetSize(result.first); i++) { + int sel_lut_idx = 0; + for (int j = 0; j < GetSize(select.second); j++) + if (i & 1 << idx_sel[j]) + sel_lut_idx |= 1 << j; + bool select_val = (select.first.bits[sel_lut_idx] == State::S1); + bool new_bit; + if (select_val ^ select_inv) { + // Use alt_data. + if (alt_data.wire) + new_bit = (i & 1 << idx_alt) != 0; + else + new_bit = alt_data.data == State::S1; + } else { + // Use original LUT. + int lut_idx = i & ((1 << GetSize(data.second)) - 1); + new_bit = data.first.bits[lut_idx] == State::S1; + } + result.first.bits[i] = new_bit ? State::S1 : State::S0; + } + return true; +} + +struct XilinxDffOptPass : public Pass { + XilinxDffOptPass() : Pass("xilinx_dffopt", "Xilinx: optimize FF control signal usage") { } + void help() YS_OVERRIDE + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" xilinx_dffopt [options] [selection]\n"); + log("\n"); + log("Converts hardware clock enable and set/reset signals on FFs to emulation\n"); + log("using LUTs, if doing so would improve area. Operates on post-techmap Xilinx\n"); + log("cells (LUT*, FD*).\n"); + log("\n"); + log(" -lut4\n"); + log(" Assume a LUT4-based device (instead of a LUT6-based device).\n"); + log("\n"); + } + void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE + { + log_header(design, "Executing XILINX_DFFOPT pass (optimize FF control signal usage).\n"); + + size_t argidx; + int max_lut_size = 6; + for (argidx = 1; argidx < args.size(); argidx++) + { + if (args[argidx] == "-lut4") { + max_lut_size = 4; + continue; + } + break; + } + extra_args(args, argidx, design); + + for (auto module : design->selected_modules()) + { + log("Optimizing FFs in %s.\n", log_id(module)); + + SigMap sigmap(module); + dict> bit_to_lut; + dict bit_uses; + + // Gather LUTs. + for (auto cell : module->selected_cells()) + { + for (auto port : cell->connections()) + for (auto bit : port.second) + bit_uses[sigmap(bit)]++; + if (cell->get_bool_attribute(ID::keep)) + continue; + if (cell->type == ID(INV)) { + SigBit sigout = sigmap(cell->getPort(ID(O))); + SigBit sigin = sigmap(cell->getPort(ID(I))); + bit_to_lut[sigout] = make_pair(LutData(Const(1, 2), {sigin}), cell); + } else if (cell->type.in(ID(LUT1), ID(LUT2), ID(LUT3), ID(LUT4), ID(LUT5), ID(LUT6))) { + SigBit sigout = sigmap(cell->getPort(ID(O))); + const Const &init = cell->getParam(ID(INIT)); + std::vector sigin; + sigin.push_back(sigmap(cell->getPort(ID(I0)))); + if (cell->type == ID(LUT1)) + goto lut_sigin_done; + sigin.push_back(sigmap(cell->getPort(ID(I1)))); + if (cell->type == ID(LUT2)) + goto lut_sigin_done; + sigin.push_back(sigmap(cell->getPort(ID(I2)))); + if (cell->type == ID(LUT3)) + goto lut_sigin_done; + sigin.push_back(sigmap(cell->getPort(ID(I3)))); + if (cell->type == ID(LUT4)) + goto lut_sigin_done; + sigin.push_back(sigmap(cell->getPort(ID(I4)))); + if (cell->type == ID(LUT5)) + goto lut_sigin_done; + sigin.push_back(sigmap(cell->getPort(ID(I5)))); +lut_sigin_done: + bit_to_lut[sigout] = make_pair(LutData(init, sigin), cell); + } + } + for (auto wire : module->wires()) + if (wire->port_output || wire->port_input) + for (int i = 0; i < GetSize(wire); i++) + bit_uses[sigmap(SigBit(wire, i))]++; + + // Iterate through FFs. + for (auto cell : module->selected_cells()) + { + bool has_s = false, has_r = false; + if (cell->type.in(ID(FDCE), ID(FDPE), ID(FDCPE), ID(FDCE_1), ID(FDPE_1), ID(FDCPE_1))) { + // Async reset. + } else if (cell->type.in(ID(FDRE), ID(FDRE_1))) { + has_r = true; + } else if (cell->type.in(ID(FDSE), ID(FDSE_1))) { + has_s = true; + } else if (cell->type.in(ID(FDRSE), ID(FDRSE_1))) { + has_r = true; + has_s = true; + } else { + // Not a FF. + continue; + } + if (cell->get_bool_attribute(ID::keep)) + continue; + + // Don't bother if D has more than one use. + SigBit sig_D = sigmap(cell->getPort(ID(D))); + if (bit_uses[sig_D] > 2) + continue; + + // Find the D LUT. + auto it_D = bit_to_lut.find(sig_D); + if (it_D == bit_to_lut.end()) + continue; + LutData lut_d = it_D->second.first; + Cell *cell_d = it_D->second.second; + if (cell->hasParam(ID(IS_D_INVERTED)) && cell->getParam(ID(IS_D_INVERTED)).as_bool()) { + // Flip all bits in the LUT. + for (int i = 0; i < GetSize(lut_d.first); i++) + lut_d.first.bits[i] = (lut_d.first.bits[i] == State::S1) ? State::S0 : State::S1; + } + + LutData lut_d_post_ce; + LutData lut_d_post_s; + LutData lut_d_post_r; + bool worthy_post_ce = false; + bool worthy_post_s = false; + bool worthy_post_r = false; + + // First, unmap CE. + SigBit sig_Q = sigmap(cell->getPort(ID(Q))); + SigBit sig_CE = sigmap(cell->getPort(ID(CE))); + LutData lut_ce = LutData(Const(2, 2), {sig_CE}); + auto it_CE = bit_to_lut.find(sig_CE); + if (it_CE != bit_to_lut.end()) + lut_ce = it_CE->second.first; + if (sig_CE.wire) { + // Merge CE LUT and D LUT into one. If it cannot be done, nothing to do about this FF. + if (!merge_lut(lut_d_post_ce, lut_d, lut_ce, true, sig_Q, max_lut_size)) + continue; + + // If this gets rid of a CE LUT, it's worth it. If not, it still may be worth it, if we can remove set/reset as well. + if (it_CE != bit_to_lut.end()) + worthy_post_ce = true; + } else if (sig_CE.data != State::S1) { + // Strange. Should not happen in a reasonable flow, so bail. + continue; + } else { + lut_d_post_ce = lut_d; + } + + // Second, unmap S, if any. + lut_d_post_s = lut_d_post_ce; + if (has_s) { + SigBit sig_S = sigmap(cell->getPort(ID(S))); + LutData lut_s = LutData(Const(2, 2), {sig_S}); + bool inv_s = cell->hasParam(ID(IS_S_INVERTED)) && cell->getParam(ID(IS_S_INVERTED)).as_bool(); + auto it_S = bit_to_lut.find(sig_S); + if (it_S != bit_to_lut.end()) + lut_s = it_S->second.first; + if (sig_S.wire) { + // Merge S LUT and D LUT into one. If it cannot be done, try to at least merge CE. + if (!merge_lut(lut_d_post_s, lut_d_post_ce, lut_s, inv_s, SigBit(State::S1), max_lut_size)) + goto unmap; + // If this gets rid of an S LUT, it's worth it. + if (it_S != bit_to_lut.end()) + worthy_post_s = true; + } else if (sig_S.data != (inv_s ? State::S1 : State::S0)) { + // Strange. Should not happen in a reasonable flow, so bail. + continue; + } + } + + // Third, unmap R, if any. + lut_d_post_r = lut_d_post_s; + if (has_r) { + SigBit sig_R = sigmap(cell->getPort(ID(R))); + LutData lut_r = LutData(Const(2, 2), {sig_R}); + bool inv_r = cell->hasParam(ID(IS_R_INVERTED)) && cell->getParam(ID(IS_R_INVERTED)).as_bool(); + auto it_R = bit_to_lut.find(sig_R); + if (it_R != bit_to_lut.end()) + lut_r = it_R->second.first; + if (sig_R.wire) { + // Merge R LUT and D LUT into one. If it cannot be done, try to at least merge CE/S. + if (!merge_lut(lut_d_post_r, lut_d_post_s, lut_r, inv_r, SigBit(State::S0), max_lut_size)) + goto unmap; + // If this gets rid of an S LUT, it's worth it. + if (it_R != bit_to_lut.end()) + worthy_post_r = true; + } else if (sig_R.data != (inv_r ? State::S1 : State::S0)) { + // Strange. Should not happen in a reasonable flow, so bail. + continue; + } + } + +unmap: + LutData final_lut; + if (worthy_post_r) { + final_lut = lut_d_post_r; + log(" Merging R LUT for %s/%s (%d -> %d)\n", log_id(cell), log_id(sig_Q.wire), GetSize(lut_d.second), GetSize(final_lut.second)); + } else if (worthy_post_s) { + final_lut = lut_d_post_s; + log(" Merging S LUT for %s/%s (%d -> %d)\n", log_id(cell), log_id(sig_Q.wire), GetSize(lut_d.second), GetSize(final_lut.second)); + } else if (worthy_post_ce) { + final_lut = lut_d_post_ce; + log(" Merging CE LUT for %s/%s (%d -> %d)\n", log_id(cell), log_id(sig_Q.wire), GetSize(lut_d.second), GetSize(final_lut.second)); + } else { + // Nothing to do here. + continue; + } + + // Okay, we're doing it. Unmap ports. + if (worthy_post_r) { + cell->unsetParam(ID(IS_R_INVERTED)); + cell->setPort(ID(R), Const(0, 1)); + } + if (has_s && (worthy_post_r || worthy_post_s)) { + cell->unsetParam(ID(IS_S_INVERTED)); + cell->setPort(ID(S), Const(0, 1)); + } + cell->setPort(ID(CE), Const(1, 1)); + cell->unsetParam(ID(IS_D_INVERTED)); + + // Create the new LUT. + Cell *lut_cell = 0; + switch (GetSize(final_lut.second)) { + case 1: + lut_cell = module->addCell(NEW_ID, ID(LUT1)); + break; + case 2: + lut_cell = module->addCell(NEW_ID, ID(LUT2)); + break; + case 3: + lut_cell = module->addCell(NEW_ID, ID(LUT3)); + break; + case 4: + lut_cell = module->addCell(NEW_ID, ID(LUT4)); + break; + case 5: + lut_cell = module->addCell(NEW_ID, ID(LUT5)); + break; + case 6: + lut_cell = module->addCell(NEW_ID, ID(LUT6)); + break; + default: + log_assert(!"unknown lut size"); + } + lut_cell->attributes = cell_d->attributes; + Wire *lut_out = module->addWire(NEW_ID); + lut_cell->setParam(ID(INIT), final_lut.first); + cell->setPort(ID(D), lut_out); + lut_cell->setPort(ID(O), lut_out); + lut_cell->setPort(ID(I0), final_lut.second[0]); + if (GetSize(final_lut.second) >= 2) + lut_cell->setPort(ID(I1), final_lut.second[1]); + if (GetSize(final_lut.second) >= 3) + lut_cell->setPort(ID(I2), final_lut.second[2]); + if (GetSize(final_lut.second) >= 4) + lut_cell->setPort(ID(I3), final_lut.second[3]); + if (GetSize(final_lut.second) >= 5) + lut_cell->setPort(ID(I4), final_lut.second[4]); + if (GetSize(final_lut.second) >= 6) + lut_cell->setPort(ID(I5), final_lut.second[5]); + } + } + } +} XilinxDffOptPass; + +PRIVATE_NAMESPACE_END + diff --git a/tests/arch/xilinx/fsm.ys b/tests/arch/xilinx/fsm.ys index 4545cf6d7..f03400fe7 100644 --- a/tests/arch/xilinx/fsm.ys +++ b/tests/arch/xilinx/fsm.ys @@ -14,6 +14,6 @@ select -assert-count 1 t:BUFG select -assert-count 4 t:FDRE select -assert-count 1 t:FDSE select -assert-count 1 t:LUT2 -select -assert-count 2 t:LUT3 -select -assert-count 4 t:LUT5 -select -assert-none t:BUFG t:FDRE t:FDSE t:LUT2 t:LUT3 t:LUT5 %% t:* %D +select -assert-count 3 t:LUT5 +select -assert-count 1 t:LUT6 +select -assert-none t:BUFG t:FDRE t:FDSE t:LUT2 t:LUT5 t:LUT6 %% t:* %D diff --git a/tests/arch/xilinx/xilinx_dffopt.ys b/tests/arch/xilinx/xilinx_dffopt.ys new file mode 100644 index 000000000..dc036acfd --- /dev/null +++ b/tests/arch/xilinx/xilinx_dffopt.ys @@ -0,0 +1,216 @@ +read_verilog << EOT + +// FDRE, mergeable CE and R. + +module t0 (...); +input wire clk; +input wire [7:0] i; +output wire [7:0] o; + +wire [7:0] tmp ; + +LUT2 #(.INIT(4'h6)) lut0 (.I0(i[0]), .I1(i[1]), .O(tmp[0])); +LUT2 #(.INIT(4'h6)) lut1 (.I0(i[1]), .I1(i[2]), .O(tmp[1])); +LUT2 #(.INIT(4'h6)) lut2 (.I0(i[3]), .I1(i[4]), .O(tmp[2])); + +FDRE ff (.D(tmp[0]), .CE(tmp[1]), .R(tmp[2]), .Q(o[0])); + +endmodule + +EOT + +design -save t0 + +equiv_opt -blacklist xilinx_dffopt_blacklist.txt -assert -map +/xilinx/cells_sim.v xilinx_dffopt +design -load postopt +clean + +select -assert-count 1 t:FDRE +select -assert-count 1 t:LUT6 +select -assert-count 3 t:LUT2 +select -assert-none t:FDRE t:LUT6 t:LUT2 %% t:* %D + +design -load t0 + +equiv_opt -blacklist xilinx_dffopt_blacklist.txt -assert -map +/xilinx/cells_sim.v xilinx_dffopt -lut4 +design -load postopt +clean + +select -assert-count 1 t:FDRE +select -assert-count 1 t:LUT4 +select -assert-count 3 t:LUT2 +select -assert-none t:FDRE t:LUT4 t:LUT2 %% t:* %D + +design -reset + + +read_verilog << EOT + +// FDSE, mergeable CE and S, inversions. + +module t0 (...); +input wire clk; +input wire [7:0] i; +output wire [7:0] o; + +wire [7:0] tmp ; + +LUT2 #(.INIT(4'h6)) lut0 (.I0(i[0]), .I1(i[1]), .O(tmp[0])); +LUT2 #(.INIT(4'h6)) lut1 (.I0(i[1]), .I1(i[2]), .O(tmp[1])); +LUT2 #(.INIT(4'h6)) lut2 (.I0(i[3]), .I1(i[4]), .O(tmp[2])); + +FDSE #(.IS_D_INVERTED(1'b1), .IS_S_INVERTED(1'b1)) ff (.D(tmp[0]), .CE(tmp[1]), .S(tmp[2]), .Q(o[0])); + +endmodule + +EOT + +design -save t0 + +equiv_opt -blacklist xilinx_dffopt_blacklist.txt -assert -map +/xilinx/cells_sim.v xilinx_dffopt +design -load postopt +clean + +select -assert-count 1 t:FDSE +select -assert-count 1 t:LUT6 +select -assert-count 3 t:LUT2 +select -assert-none t:FDSE t:LUT6 t:LUT2 %% t:* %D + +design -load t0 + +equiv_opt -blacklist xilinx_dffopt_blacklist.txt -assert -map +/xilinx/cells_sim.v xilinx_dffopt -lut4 +design -load postopt +clean + +select -assert-count 1 t:FDSE +select -assert-count 1 t:LUT4 +select -assert-count 3 t:LUT2 +select -assert-none t:FDSE t:LUT4 t:LUT2 %% t:* %D + +design -reset + + +read_verilog << EOT + +// FDCE, mergeable CE. + +module t0 (...); +input wire clk; +input wire [7:0] i; +output wire [7:0] o; + +wire [7:0] tmp ; + +LUT2 #(.INIT(4'h6)) lut0 (.I0(i[0]), .I1(i[1]), .O(tmp[0])); +LUT2 #(.INIT(4'h6)) lut1 (.I0(i[1]), .I1(i[2]), .O(tmp[1])); +LUT2 #(.INIT(4'h6)) lut2 (.I0(i[3]), .I1(i[4]), .O(tmp[2])); + +FDCE ff (.D(tmp[0]), .CE(tmp[1]), .CLR(tmp[2]), .Q(o[0])); + +endmodule + +EOT + +design -save t0 + +equiv_opt -async2sync -blacklist xilinx_dffopt_blacklist.txt -assert -map +/xilinx/cells_sim.v xilinx_dffopt +design -load postopt +clean + +select -assert-count 1 t:FDCE +select -assert-count 1 t:LUT4 +select -assert-count 3 t:LUT2 +select -assert-none t:FDCE t:LUT4 t:LUT2 %% t:* %D + +design -reset + + +read_verilog << EOT + +// FDSE, mergeable CE and S, but CE only not worth it. + +module t0 (...); +input wire clk; +input wire [7:0] i; +output wire [7:0] o; + +wire [7:0] tmp ; + +LUT2 #(.INIT(4'h6)) lut0 (.I0(i[0]), .I1(i[1]), .O(tmp[0])); +LUT2 #(.INIT(4'h6)) lut1 (.I0(i[1]), .I1(i[2]), .O(tmp[1])); + +FDSE ff (.D(tmp[0]), .CE(i[7]), .S(tmp[1]), .Q(o[0])); + +endmodule + +EOT + +design -save t0 + +equiv_opt -blacklist xilinx_dffopt_blacklist.txt -assert -map +/xilinx/cells_sim.v xilinx_dffopt +design -load postopt +clean + +select -assert-count 1 t:FDSE +select -assert-count 1 t:LUT5 +select -assert-count 2 t:LUT2 +select -assert-none t:FDSE t:LUT5 t:LUT2 %% t:* %D + +design -load t0 + +equiv_opt -blacklist xilinx_dffopt_blacklist.txt -assert -map +/xilinx/cells_sim.v xilinx_dffopt -lut4 +design -load postopt +clean + +select -assert-count 1 t:FDSE +select -assert-count 2 t:LUT2 +select -assert-none t:FDSE t:LUT2 %% t:* %D + +design -reset + + +read_verilog << EOT + +// FDRSE, mergeable CE, S, R. + +module t0 (...); +input wire clk; +input wire [7:0] i; +output wire [7:0] o; + +wire [7:0] tmp ; + +LUT2 #(.INIT(4'h6)) lut0 (.I0(i[0]), .I1(i[1]), .O(tmp[0])); +LUT2 #(.INIT(4'h6)) lut1 (.I0(i[1]), .I1(i[2]), .O(tmp[1])); +LUT2 #(.INIT(4'h8)) lut2 (.I0(i[2]), .I1(i[0]), .O(tmp[2])); +LUT2 #(.INIT(4'h6)) lut3 (.I0(i[3]), .I1(i[4]), .O(tmp[3])); + +FDRSE ff (.D(tmp[0]), .CE(tmp[1]), .S(tmp[2]), .R(tmp[3]), .Q(o[0])); + +endmodule + +EOT + +design -save t0 + +equiv_opt -blacklist xilinx_dffopt_blacklist.txt -assert -map +/xilinx/cells_sim.v xilinx_dffopt +design -load postopt +clean + +select -assert-count 1 t:FDRSE +select -assert-count 1 t:LUT6 +select -assert-count 4 t:LUT2 +select -assert-none t:FDRSE t:LUT6 t:LUT2 %% t:* %D + +design -load t0 + +equiv_opt -blacklist xilinx_dffopt_blacklist.txt -assert -map +/xilinx/cells_sim.v xilinx_dffopt -lut4 +design -load postopt +clean + +select -assert-count 1 t:FDRSE +select -assert-count 1 t:LUT4 +select -assert-count 4 t:LUT2 +select -assert-none t:FDRSE t:LUT4 t:LUT2 %% t:* %D + +design -reset diff --git a/tests/arch/xilinx/xilinx_dffopt_blacklist.txt b/tests/arch/xilinx/xilinx_dffopt_blacklist.txt new file mode 100644 index 000000000..6a31a0cd3 --- /dev/null +++ b/tests/arch/xilinx/xilinx_dffopt_blacklist.txt @@ -0,0 +1,13 @@ +lut0 +lut1 +lut2 +lut3 +ff +ff.D +ff.R +ff.S +ff.CE +ff.d +ff.r +ff.s +ff.ce -- cgit v1.2.3 From f382164d6ed4e6fd6820322db5becf081a74f272 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20Ko=C5=9Bcielnicki?= Date: Wed, 18 Dec 2019 15:53:20 +0100 Subject: tests/xilinx: fix flaky mux test --- tests/arch/xilinx/mux.ys | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/arch/xilinx/mux.ys b/tests/arch/xilinx/mux.ys index 821d0fab7..388272449 100644 --- a/tests/arch/xilinx/mux.ys +++ b/tests/arch/xilinx/mux.ys @@ -40,6 +40,8 @@ proc equiv_opt -assert -map +/xilinx/cells_sim.v synth_xilinx # 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 5 t:LUT6 +select -assert-min 5 t:LUT6 +select -assert-max 7 t:LUT6 +select -assert-max 2 t:MUXF7 -select -assert-none t:LUT6 %% t:* %D +select -assert-none t:LUT6 t:MUXF7 %% t:* %D -- cgit v1.2.3 From f52c6efd9da161e625538f9e8c23875efebda60f Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 18 Dec 2019 12:09:11 -0800 Subject: Add "scratchpad" to CHANGELOG --- CHANGELOG | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG b/CHANGELOG index 9b87af8f0..01ae17c2b 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -56,6 +56,7 @@ Yosys 0.9 .. Yosys 0.9-dev - Added checking of SystemVerilog always block types (always_comb, always_latch and always_ff) - Added "xilinx_dffopt" pass + - Added "scratchpad" pass Yosys 0.8 .. Yosys 0.9 ---------------------- -- cgit v1.2.3 From 3b559de6e9f8972c1e52ee8bf6d9a600bcfa187f Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 18 Dec 2019 12:21:12 -0800 Subject: Interpret "abc9 -lut" as lut string only if [0-9:] --- passes/techmap/abc9.cc | 37 ++++++++++++++++++------------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 8276c3c16..d03e5da8e 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -981,29 +981,28 @@ struct Abc9Pass : public Pass { //} if (arg == "-lut" && argidx+1 < args.size()) { string arg = args[++argidx]; - 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 { - pos = arg.find_first_of('.'); + 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_file = arg; - rewrite_filename(lut_file); - if (!lut_file.empty() && !is_absolute_path(lut_file)) - lut_file = std::string(pwd) + "/" + lut_file; - } - else { + 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; } - 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)); continue; } if (arg == "-luts" && argidx+1 < args.size()) { @@ -1072,7 +1071,7 @@ struct Abc9Pass : public Pass { box_file = "+/dummy.box"; rewrite_filename(box_file); - if (!box_file.empty() && !is_absolute_path(box_file)) + if (!box_file.empty() && !is_absolute_path(box_file) && box_file[0] != '+') box_file = std::string(pwd) + "/" + box_file; dict box_lookup; -- cgit v1.2.3 From 76ba06a79ea917a0e515aa0e99ae41f42e8bddc9 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 18 Dec 2019 15:14:38 -0800 Subject: Bump ABC again --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 44d064896..e268a4281 100644 --- a/Makefile +++ b/Makefile @@ -128,7 +128,7 @@ bumpversion: # is just a symlink to your actual ABC working directory, as 'make mrproper' # will remove the 'abc' directory and you do not want to accidentally # delete your work on ABC.. -ABCREV = 02393a2 +ABCREV = c4b12fa ABCPULL = 1 ABCURL ?= https://github.com/berkeley-abc/abc ABCMKARGS = CC="$(CXX)" CXX="$(CXX)" ABC_USE_LIBSTDCXX=1 -- cgit v1.2.3 From 561ae1c5c4e694656fb4ce9198e62f0efbe4c705 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20Ko=C5=9Bcielnicki?= Date: Thu, 19 Dec 2019 08:49:21 +0100 Subject: xilinx_dffopt: Keep order of LUT inputs. See rationale at https://github.com/YosysHQ/yosys/pull/1557#discussion_r359196549 --- techlibs/xilinx/xilinx_dffopt.cc | 46 ++++++++++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 16 deletions(-) diff --git a/techlibs/xilinx/xilinx_dffopt.cc b/techlibs/xilinx/xilinx_dffopt.cc index 1256a08cb..13a0b9b83 100644 --- a/techlibs/xilinx/xilinx_dffopt.cc +++ b/techlibs/xilinx/xilinx_dffopt.cc @@ -27,20 +27,13 @@ typedef std::pair> LutData; // Compute a LUT implementing (select ^ select_inv) ? alt_data : data. Returns true if successful. bool merge_lut(LutData &result, const LutData &data, const LutData select, bool select_inv, SigBit alt_data, int max_lut_size) { - // First, gather input signals. + // First, gather input signals -- insert new signals at the beginning + // of the vector, so they don't disturb the likely-critical D LUT input + // timings. result.second = data.second; - int idx_alt = -1; - if (alt_data.wire) { - // Check if we already have it. - for (int i = 0; i < GetSize(result.second); i++) - if (result.second[i] == alt_data) - idx_alt = i; - // If not, add it. - if (idx_alt == -1) { - idx_alt = GetSize(result.second); - result.second.push_back(alt_data); - } - } + // D lut inputs initially start at 0. + int idx_data = 0; + // Now add the control input LUT inputs. std::vector idx_sel; for (auto bit : select.second) { int idx = -1; @@ -48,11 +41,32 @@ bool merge_lut(LutData &result, const LutData &data, const LutData select, bool if (result.second[i] == bit) idx = i; if (idx == -1) { - idx = GetSize(result.second); - result.second.push_back(bit); + idx = 0; + // Insert new signal at the beginning and bump all indices. + result.second.insert(result.second.begin(), bit); + idx_data++; + for (int &sidx : idx_sel) + sidx++; } idx_sel.push_back(idx); } + // Insert the Q signal, if any, to the slowest input -- it will have + // no problem meeting timing. + int idx_alt = -1; + if (alt_data.wire) { + // Check if we already have it. + for (int i = 0; i < GetSize(result.second); i++) + if (result.second[i] == alt_data) + idx_alt = i; + // If not, add it. + if (idx_alt == -1) { + idx_alt = 0; + result.second.insert(result.second.begin(), alt_data); + idx_data++; + for (int &sidx : idx_sel) + sidx++; + } + } // If LUT would be too large, bail. if (GetSize(result.second) > max_lut_size) @@ -75,7 +89,7 @@ bool merge_lut(LutData &result, const LutData &data, const LutData select, bool new_bit = alt_data.data == State::S1; } else { // Use original LUT. - int lut_idx = i & ((1 << GetSize(data.second)) - 1); + int lut_idx = i >> idx_data & ((1 << GetSize(data.second)) - 1); new_bit = data.first.bits[lut_idx] == State::S1; } result.first.bits[i] = new_bit ? State::S1 : State::S0; -- cgit v1.2.3 From 8b2c9f4518aa27662a29de5d282df44f1bba6dc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20Ko=C5=9Bcielnicki?= Date: Wed, 27 Nov 2019 18:13:00 +0100 Subject: xilinx: Add simulation models for remaining CLB primitives. --- techlibs/xilinx/cells_sim.v | 201 +++++++++++++++++++++++++++++++++++++++++- techlibs/xilinx/cells_xtra.py | 26 +++--- techlibs/xilinx/cells_xtra.v | 139 ----------------------------- 3 files changed, 210 insertions(+), 156 deletions(-) diff --git a/techlibs/xilinx/cells_sim.v b/techlibs/xilinx/cells_sim.v index cf7923777..47ba794bf 100644 --- a/techlibs/xilinx/cells_sim.v +++ b/techlibs/xilinx/cells_sim.v @@ -227,6 +227,14 @@ module MUXCY(output O, input CI, DI, S); assign O = S ? CI : DI; endmodule +module MUXF5(output O, input I0, I1, S); + assign O = S ? I1 : I0; +endmodule + +module MUXF6(output O, input I0, I1, S); + assign O = S ? I1 : I0; +endmodule + (* abc9_box_id = 1, lib_whitebox *) module MUXF7(output O, input I0, I1, S); assign O = S ? I1 : I0; @@ -237,6 +245,10 @@ module MUXF8(output O, input I0, I1, S); assign O = S ? I1 : I0; endmodule +module MUXF9(output O, input I0, I1, S); + assign O = S ? I1 : I0; +endmodule + module XORCY(output O, input CI, LI); assign O = CI ^ LI; endmodule @@ -258,6 +270,26 @@ module CARRY4( assign CO[3] = S[3] ? CO[2] : DI[3]; endmodule +module CARRY8( + output [7:0] CO, + output [7:0] O, + input CI, + input CI_TOP, + input [7:0] DI, S +); + parameter CARRY_TYPE = "SINGLE_CY8"; + wire CI4 = (CARRY_TYPE == "DUAL_CY4" ? CI_TOP : CO[3]); + assign O = S ^ {CO[6:4], CI4, CO[2:0], CI}; + assign CO[0] = S[0] ? CI : DI[0]; + assign CO[1] = S[1] ? CO[0] : DI[1]; + assign CO[2] = S[2] ? CO[1] : DI[2]; + assign CO[3] = S[3] ? CO[2] : DI[3]; + assign CO[4] = S[4] ? CI4 : DI[4]; + assign CO[5] = S[5] ? CO[4] : DI[5]; + assign CO[6] = S[6] ? CO[5] : DI[6]; + assign CO[7] = S[7] ? CO[6] : DI[7]; +endmodule + `ifdef _EXPLICIT_CARRY module CARRY0(output CO_CHAIN, CO_FABRIC, O, input CI, CI_INIT, DI, S); @@ -281,6 +313,16 @@ endmodule `endif +module ORCY (output O, input CI, I); + assign O = CI | I; +endmodule + +module MULT_AND (output LO, input I0, I1); + assign LO = I0 & I1; +endmodule + +// Flip-flops and latches. + // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLL_L.sdf#L238-L250 module FDRE ( @@ -414,6 +456,51 @@ module FDPE ( endcase endgenerate endmodule +module FDCPE ( + output wire Q, + (* clkbuf_sink *) + (* invertible_pin = "IS_C_INVERTED" *) + input C, + input CE, + (* invertible_pin = "IS_CLR_INVERTED" *) + input CLR, + input D, + (* invertible_pin = "IS_PRE_INVERTED" *) + input PRE +); + parameter [0:0] INIT = 1'b0; + parameter [0:0] IS_C_INVERTED = 1'b0; + parameter [0:0] IS_CLR_INVERTED = 1'b0; + parameter [0:0] IS_PRE_INVERTED = 1'b0; + wire c = C ^ IS_C_INVERTED; + wire clr = CLR ^ IS_CLR_INVERTED; + wire pre = PRE ^ IS_PRE_INVERTED; + // Hacky model to avoid simulation-synthesis mismatches. + reg qc, qp, qs; + initial qc = INIT; + initial qp = INIT; + initial qs = 0; + always @(posedge c, posedge clr) begin + if (clr) + qc <= 0; + else if (CE) + qc <= D; + end + always @(posedge c, posedge pre) begin + if (pre) + qp <= 1; + else if (CE) + qp <= D; + end + always @* begin + if (clr) + qs <= 0; + else if (pre) + qs <= 1; + end + assign Q = qs ? qp : qc; +endmodule + module FDRE_1 ( (* abc9_arrival=303 *) output reg Q, @@ -480,8 +567,8 @@ module LDCE ( wire clr = CLR ^ IS_CLR_INVERTED; wire g = G ^ IS_G_INVERTED; always @* - if (clr) Q = 1'b0; - else if (GE && g) Q = D; + if (clr) Q <= 1'b0; + else if (GE && g) Q <= D; endmodule module LDPE ( @@ -502,8 +589,59 @@ module LDPE ( wire g = G ^ IS_G_INVERTED; wire pre = PRE ^ IS_PRE_INVERTED; always @* - if (pre) Q = 1'b1; - else if (GE && g) Q = D; + if (pre) Q <= 1'b1; + else if (GE && g) Q <= D; +endmodule + +module LDCPE ( + output reg Q, + (* invertible_pin = "IS_CLR_INVERTED" *) + input CLR, + (* invertible_pin = "IS_D_INVERTED" *) + input D, + (* invertible_pin = "IS_G_INVERTED" *) + input G, + (* invertible_pin = "IS_GE_INVERTED" *) + input GE, + (* invertible_pin = "IS_PRE_INVERTED" *) + input PRE +); + parameter [0:0] INIT = 1'b1; + parameter [0:0] IS_CLR_INVERTED = 1'b0; + parameter [0:0] IS_D_INVERTED = 1'b0; + parameter [0:0] IS_G_INVERTED = 1'b0; + parameter [0:0] IS_GE_INVERTED = 1'b0; + parameter [0:0] IS_PRE_INVERTED = 1'b0; + initial Q = INIT; + wire d = D ^ IS_D_INVERTED; + wire g = G ^ IS_G_INVERTED; + wire ge = GE ^ IS_GE_INVERTED; + wire clr = CLR ^ IS_CLR_INVERTED; + wire pre = PRE ^ IS_PRE_INVERTED; + always @* + if (clr) Q <= 1'b0; + else if (pre) Q <= 1'b1; + else if (ge && g) Q <= d; +endmodule + +module AND2B1L ( + output O, + input DI, + (* invertible_pin = "IS_SRI_INVERTED" *) + input SRI +); + parameter [0:0] IS_SRI_INVERTED = 1'b0; + assign O = DI & ~(SRI ^ IS_SRI_INVERTED); +endmodule + +module OR2L ( + output O, + input DI, + (* invertible_pin = "IS_SRI_INVERTED" *) + input SRI +); + parameter [0:0] IS_SRI_INVERTED = 1'b0; + assign O = DI | (SRI ^ IS_SRI_INVERTED); endmodule // LUTRAM. @@ -1369,6 +1507,20 @@ endmodule // Shift registers. +module SRL16 ( + output Q, + input A0, A1, A2, A3, + (* clkbuf_sink *) + input CLK, + input D +); + parameter [15:0] INIT = 16'h0000; + + reg [15:0] r = INIT; + assign Q = r[{A3,A2,A1,A0}]; + always @(posedge CLK) r <= { r[14:0], D }; +endmodule + module SRL16E ( // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L904-L905 (* abc9_arrival=1472 *) @@ -1393,6 +1545,22 @@ module SRL16E ( endgenerate endmodule +module SRLC16 ( + output Q, + output Q15, + input A0, A1, A2, A3, + (* clkbuf_sink *) + input CLK, + input D +); + parameter [15:0] INIT = 16'h0000; + + reg [15:0] r = INIT; + assign Q15 = r[15]; + assign Q = r[{A3,A2,A1,A0}]; + always @(posedge CLK) r <= { r[14:0], D }; +endmodule + module SRLC16E ( output Q, output Q15, @@ -1445,6 +1613,31 @@ module SRLC32E ( endgenerate endmodule +module CFGLUT5 ( + output CDO, + output O5, + output O6, + input I4, + input I3, + input I2, + input I1, + input I0, + input CDI, + input CE, + (* clkbuf_sink *) + (* invertible_pin = "IS_CLK_INVERTED" *) + input CLK +); + parameter [31:0] INIT = 32'h00000000; + parameter [0:0] IS_CLK_INVERTED = 1'b0; + wire clk = CLK ^ IS_CLK_INVERTED; + reg [31:0] r = INIT; + assign CDO = r[31]; + assign O5 = r[{1'b0, I3, I2, I1, I0}]; + assign O6 = r[{I4, I3, I2, I1, I0}]; + always @(posedge clk) if (CE) r <= {r[30:0], CDI}; +endmodule + // DSP // Virtex 2, Virtex 2 Pro, Spartan 3. diff --git a/techlibs/xilinx/cells_xtra.py b/techlibs/xilinx/cells_xtra.py index 6d5adf1aa..d5c58c5d7 100644 --- a/techlibs/xilinx/cells_xtra.py +++ b/techlibs/xilinx/cells_xtra.py @@ -65,9 +65,9 @@ CELLS = [ # CLB -- registers/latches. # Virtex 1/2/4/5, Spartan 3. - Cell('FDCPE', port_attrs={'C': ['clkbuf_sink']}), + # Cell('FDCPE', port_attrs={'C': ['clkbuf_sink']}), # Cell('FDRSE', port_attrs={'C': ['clkbuf_sink']}), - Cell('LDCPE', port_attrs={'C': ['clkbuf_sink']}), + # Cell('LDCPE', port_attrs={'C': ['clkbuf_sink']}), # Virtex 6, Spartan 6, Series 7, Ultrascale. # Cell('FDCE'), # Cell('FDPE'), @@ -75,8 +75,8 @@ CELLS = [ # Cell('FDSE'), # Cell('LDCE'), # Cell('LDPE'), - Cell('AND2B1L'), - Cell('OR2L'), + # Cell('AND2B1L'), + # Cell('OR2L'), # CLB -- other. # Cell('LUT1'), @@ -86,23 +86,23 @@ CELLS = [ # Cell('LUT5'), # Cell('LUT6'), # Cell('LUT6_2'), - Cell('MUXF5'), - Cell('MUXF6'), + # Cell('MUXF5'), + # Cell('MUXF6'), # Cell('MUXF7'), # Cell('MUXF8'), - Cell('MUXF9'), + # Cell('MUXF9'), # Cell('CARRY4'), - Cell('CARRY8'), + # Cell('CARRY8'), # Cell('MUXCY'), # Cell('XORCY'), - Cell('ORCY'), - Cell('MULT_AND'), - Cell('SRL16', port_attrs={'CLK': ['clkbuf_sink']}), + # Cell('ORCY'), + # Cell('MULT_AND'), + # Cell('SRL16', port_attrs={'CLK': ['clkbuf_sink']}), # Cell('SRL16E', port_attrs={'CLK': ['clkbuf_sink']}), - Cell('SRLC16', port_attrs={'CLK': ['clkbuf_sink']}), + # Cell('SRLC16', port_attrs={'CLK': ['clkbuf_sink']}), # Cell('SRLC16E', port_attrs={'CLK': ['clkbuf_sink']}), # Cell('SRLC32E', port_attrs={'CLK': ['clkbuf_sink']}), - Cell('CFGLUT5', port_attrs={'CLK': ['clkbuf_sink']}), + # Cell('CFGLUT5', port_attrs={'CLK': ['clkbuf_sink']}), # Block RAM. # Virtex. diff --git a/techlibs/xilinx/cells_xtra.v b/techlibs/xilinx/cells_xtra.v index 66b7c583f..c3e5c72f9 100644 --- a/techlibs/xilinx/cells_xtra.v +++ b/techlibs/xilinx/cells_xtra.v @@ -1,144 +1,5 @@ // Created by cells_xtra.py from Xilinx models -module FDCPE (...); - parameter [0:0] INIT = 1'b0; - parameter [0:0] IS_C_INVERTED = 1'b0; - parameter [0:0] IS_CLR_INVERTED = 1'b0; - parameter [0:0] IS_PRE_INVERTED = 1'b0; - output Q; - (* clkbuf_sink *) - (* invertible_pin = "IS_C_INVERTED" *) - input C; - input CE; - (* invertible_pin = "IS_CLR_INVERTED" *) - input CLR; - input D; - (* invertible_pin = "IS_PRE_INVERTED" *) - input PRE; -endmodule - -module LDCPE (...); - parameter [0:0] INIT = 1'b0; - parameter [0:0] IS_CLR_INVERTED = 1'b0; - parameter [0:0] IS_D_INVERTED = 1'b0; - parameter [0:0] IS_G_INVERTED = 1'b0; - parameter [0:0] IS_GE_INVERTED = 1'b0; - parameter [0:0] IS_PRE_INVERTED = 1'b0; - output Q; - (* invertible_pin = "IS_CLR_INVERTED" *) - input CLR; - (* invertible_pin = "IS_D_INVERTED" *) - input D; - (* invertible_pin = "IS_G_INVERTED" *) - input G; - (* invertible_pin = "IS_GE_INVERTED" *) - input GE; - (* invertible_pin = "IS_PRE_INVERTED" *) - input PRE; -endmodule - -module AND2B1L (...); - parameter [0:0] IS_SRI_INVERTED = 1'b0; - output O; - input DI; - (* invertible_pin = "IS_SRI_INVERTED" *) - input SRI; -endmodule - -module OR2L (...); - parameter [0:0] IS_SRI_INVERTED = 1'b0; - output O; - input DI; - (* invertible_pin = "IS_SRI_INVERTED" *) - input SRI; -endmodule - -module MUXF5 (...); - output O; - input I0; - input I1; - input S; -endmodule - -module MUXF6 (...); - output O; - input I0; - input I1; - input S; -endmodule - -module MUXF9 (...); - output O; - input I0; - input I1; - input S; -endmodule - -module CARRY8 (...); - parameter CARRY_TYPE = "SINGLE_CY8"; - output [7:0] CO; - output [7:0] O; - input CI; - input CI_TOP; - input [7:0] DI; - input [7:0] S; -endmodule - -module ORCY (...); - output O; - input CI; - input I; -endmodule - -module MULT_AND (...); - output LO; - input I0; - input I1; -endmodule - -module SRL16 (...); - parameter [15:0] INIT = 16'h0000; - output Q; - input A0; - input A1; - input A2; - input A3; - (* clkbuf_sink *) - input CLK; - input D; -endmodule - -module SRLC16 (...); - parameter [15:0] INIT = 16'h0000; - output Q; - output Q15; - input A0; - input A1; - input A2; - input A3; - (* clkbuf_sink *) - input CLK; - input D; -endmodule - -module CFGLUT5 (...); - parameter [31:0] INIT = 32'h00000000; - parameter [0:0] IS_CLK_INVERTED = 1'b0; - output CDO; - output O5; - output O6; - input I4; - input I3; - input I2; - input I1; - input I0; - input CDI; - input CE; - (* clkbuf_sink *) - (* invertible_pin = "IS_CLK_INVERTED" *) - input CLK; -endmodule - module RAMB16_S1 (...); parameter [0:0] INIT = 1'h0; parameter [0:0] SRVAL = 1'h0; -- cgit v1.2.3 From 979bf36fb00ec61ec7e27f074079e0464be03be7 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 19 Dec 2019 11:23:41 -0800 Subject: Split into $__ABC9_ASYNC[01], do not add cell->type to clkdomain_t --- passes/techmap/abc9.cc | 10 +++++----- techlibs/xilinx/abc9_map.v | 32 ++++++++++++++++++-------------- techlibs/xilinx/abc9_model.v | 14 +++++++++++--- techlibs/xilinx/abc9_unmap.v | 3 ++- techlibs/xilinx/abc9_xc7.box | 26 ++++++++++++++++---------- techlibs/xilinx/cells_sim.v | 16 ++++++++-------- 6 files changed, 60 insertions(+), 41 deletions(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 8027c5131..2bf495ec4 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -1088,7 +1088,7 @@ struct Abc9Pass : public Pass { pool expand_queue_up, next_expand_queue_up; pool expand_queue_down, next_expand_queue_down; - typedef std::pair clkdomain_t; + typedef SigSpec clkdomain_t; std::map> assigned_cells; std::map assigned_cells_reverse; @@ -1123,7 +1123,7 @@ struct Abc9Pass : public Pass { unassigned_cells.erase(cell); expand_queue_up.insert(cell); - clkdomain_t key(abc9_clock, cell->type); + clkdomain_t key(abc9_clock); assigned_cells[key].insert(cell->name); assigned_cells_reverse[cell] = key; @@ -1236,19 +1236,19 @@ struct Abc9Pass : public Pass { log_header(design, "Summary of detected clock domains:\n"); for (auto &it : assigned_cells) - log(" %d cells in clk=%s cell=%s\n", GetSize(it.second), log_signal(it.first.first), log_id(it.first.second)); + log(" %d cells in clk=%s\n", GetSize(it.second), log_signal(it.first)); design->selection_stack.emplace_back(false); design->selected_active_module = module->name.str(); for (auto &it : assigned_cells) { std::string target = delay_target; if (target.empty()) { - for (auto b : assign_map(it.first.first)) + for (auto b : assign_map(it.first)) if (b.wire) { auto jt = b.wire->attributes.find("\\abc9_period"); if (jt != b.wire->attributes.end()) { target = stringf("-D %d", jt->second.as_int()); - log("Target period = %s ps for clock domain %s\n", target.c_str(), log_signal(it.first.first)); + log("Target period = %s ps for clock domain %s\n", target.c_str(), log_signal(it.first)); break; } } diff --git a/techlibs/xilinx/abc9_map.v b/techlibs/xilinx/abc9_map.v index d04cdb5eb..b36d93c5d 100644 --- a/techlibs/xilinx/abc9_map.v +++ b/techlibs/xilinx/abc9_map.v @@ -161,8 +161,10 @@ module FDCE (output Q, input C, CE, D, CLR); // control is not directly // supported by abc9 but its // behaviour is captured by - // $__ABC9_ASYNC below + // $__ABC9_ASYNC1 below ); + // Since this is an async flop, async behaviour is dealt with here + \$__ABC9_ASYNC0 abc_async (.A($abc9_currQ), .S(CLR ^ IS_CLR_INVERTED), .Y(QQ)); end else begin assign Q = QQ; @@ -177,13 +179,12 @@ module FDCE (output Q, input C, CE, D, CLR); // control is not directly // supported by abc9 but its // behaviour is captured by - // $__ABC9_ASYNC below + // $__ABC9_ASYNC0 below ); + // Since this is an async flop, async behaviour is dealt with here + \$__ABC9_ASYNC1 abc_async (.A($abc9_currQ), .S(CLR ^ IS_CLR_INVERTED), .Y(QQ)); end endgenerate \$__ABC9_FF_ abc_dff (.D($nextQ), .Q($abc9_currQ)); - // Since this is an async flop, async behaviour is also dealt with - // using the $_ABC9_ASYNC box by abc9_map.v - \$__ABC9_ASYNC abc_async (.A($abc9_currQ), .S(CLR ^ IS_CLR_INVERTED), .Y(QQ)); // Special signals wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, IS_C_INVERTED}; @@ -203,8 +204,9 @@ module FDCE_1 (output Q, input C, CE, D, CLR); // control is not directly // supported by abc9 but its // behaviour is captured by - // $__ABC9_ASYNC below + // $__ABC9_ASYNC1 below ); + \$__ABC9_ASYNC1 abc_async (.A($abc9_currQ), .S(CLR), .Y(QQ)); end else begin assign Q = QQ; @@ -216,11 +218,11 @@ module FDCE_1 (output Q, input C, CE, D, CLR); // control is not directly // supported by abc9 but its // behaviour is captured by - // $__ABC9_ASYNC below + // $__ABC9_ASYNC0 below ); + \$__ABC9_ASYNC0 abc_async (.A($abc9_currQ), .S(CLR), .Y(QQ)); end endgenerate \$__ABC9_FF_ abc_dff (.D($nextQ), .Q($abc9_currQ)); - \$__ABC9_ASYNC abc_async (.A($abc9_currQ), .S(CLR), .Y(QQ)); // Special signals wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */}; @@ -247,8 +249,9 @@ module FDPE (output Q, input C, CE, D, PRE); // control is not directly // supported by abc9 but its // behaviour is captured by - // $__ABC9_ASYNC below + // $__ABC9_ASYNC0 below ); + \$__ABC9_ASYNC0 abc_async (.A($abc9_currQ), .S(PRE ^ IS_PRE_INVERTED), .Y(QQ)); end else begin assign Q = QQ; @@ -263,11 +266,11 @@ module FDPE (output Q, input C, CE, D, PRE); // control is not directly // supported by abc9 but its // behaviour is captured by - // $__ABC9_ASYNC below + // $__ABC9_ASYNC1 below ); + \$__ABC9_ASYNC1 abc_async (.A($abc9_currQ), .S(PRE ^ IS_PRE_INVERTED), .Y(QQ)); end endgenerate \$__ABC9_FF_ abc_dff (.D($nextQ), .Q($abc9_currQ)); - \$__ABC9_ASYNC abc_async (.A($abc9_currQ), .S(PRE ^ IS_PRE_INVERTED), .Y(QQ)); // Special signals wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, IS_C_INVERTED}; @@ -287,8 +290,9 @@ module FDPE_1 (output Q, input C, CE, D, PRE); // control is not directly // supported by abc9 but its // behaviour is captured by - // $__ABC9_ASYNC below + // $__ABC9_ASYNC0 below ); + \$__ABC9_ASYNC0 abc_async (.A($abc9_currQ), .S(PRE), .Y(QQ)); end else begin assign Q = QQ; @@ -300,11 +304,11 @@ module FDPE_1 (output Q, input C, CE, D, PRE); // control is not directly // supported by abc9 but its // behaviour is captured by - // $__ABC9_ASYNC below + // $__ABC9_ASYNC1 below ); + \$__ABC9_ASYNC1 abc_async (.A($abc9_currQ), .S(PRE), .Y(QQ)); end endgenerate \$__ABC9_FF_ abc_dff (.D($nextQ), .Q($abc9_currQ)); - \$__ABC9_ASYNC abc_async (.A($abc9_currQ), .S(PRE), .Y(QQ)); // Special signals wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */}; diff --git a/techlibs/xilinx/abc9_model.v b/techlibs/xilinx/abc9_model.v index cc0e5ec41..c793396a4 100644 --- a/techlibs/xilinx/abc9_model.v +++ b/techlibs/xilinx/abc9_model.v @@ -33,11 +33,19 @@ endmodule module \$__ABC9_FF_ (input D, output Q); endmodule +// Box to emulate async behaviour of FDC* (* abc_box_id = 1000 *) -module \$__ABC9_ASYNC (input A, S, output Y); +module \$__ABC9_ASYNC0 (input A, S, output Y); + assign Y = S ? 1'b0 : A; endmodule -// Box to emulate comb/seq behaviour of RAMD{32,64} and SRL{16,32} +// Box to emulate async behaviour of FDP* +(* abc_box_id = 1001 *) +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). @@ -46,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 21fe78d08..46526007d 100644 --- a/techlibs/xilinx/abc9_unmap.v +++ b/techlibs/xilinx/abc9_unmap.v @@ -20,7 +20,8 @@ // ============================================================================ -module \$__ABC9_ASYNC (input A, S, output Y); +(* techmap_celltype = "$__ABC9_ASYNC0 $__ABC9_ASYNC1" *) +module \$__ABC9_ASYNC01 (input A, S, output Y); assign Y = A; endmodule diff --git a/techlibs/xilinx/abc9_xc7.box b/techlibs/xilinx/abc9_xc7.box index 4e632c0fa..a2d119284 100644 --- a/techlibs/xilinx/abc9_xc7.box +++ b/techlibs/xilinx/abc9_xc7.box @@ -41,10 +41,16 @@ CARRY4 4 1 10 8 592 540 520 356 - 512 548 292 - 228 580 526 507 398 385 508 528 378 380 114 -# Box to emulate async behaviour of FD[CP]* +# Box to emulate async behaviour of FDC* # Inputs: A S # Outputs: Y -$__ABC9_ASYNC 1000 0 2 1 +$__ABC9_ASYNC0 1000 1 2 1 +0 764 + +# Box to emulate async behaviour of FDP* +# Inputs: A S +# Outputs: Y +$__ABC9_ASYNC1 1001 1 2 1 0 764 # The following FD*.{CE,R,CLR,PRE) are offset by 46ps to @@ -54,42 +60,42 @@ $__ABC9_ASYNC 1000 0 2 1 # Inputs: C CE D R \$currQ # Outputs: Q -FDRE 1001 1 5 1 +FDRE 1100 1 5 1 0 151 0 446 0 # Inputs: C CE D R \$currQ # Outputs: Q -FDRE_1 1002 1 5 1 +FDRE_1 1101 1 5 1 0 151 0 446 0 # Inputs: C CE CLR D \$currQ # Outputs: Q -FDCE 1003 1 5 1 +FDCE 1102 1 5 1 0 151 806 0 0 # Inputs: C CE CLR D \$currQ # Outputs: Q -FDCE_1 1004 1 5 1 +FDCE_1 1103 1 5 1 0 151 806 0 0 # Inputs: C CE D PRE \$currQ # Outputs: Q -FDPE 1005 1 5 1 +FDPE 1104 1 5 1 0 151 0 806 0 # Inputs: C CE D PRE \$currQ # Outputs: Q -FDPE_1 1006 1 5 1 +FDPE_1 1105 1 5 1 0 151 0 806 0 # Inputs: C CE D S \$currQ # Outputs: Q -FDSE 1007 1 5 1 +FDSE 1106 1 5 1 0 151 0 446 0 # Inputs: C CE D S \$currQ # Outputs: Q -FDSE_1 1008 1 5 1 +FDSE_1 1107 1 5 1 0 151 0 446 0 # SLICEM/A6LUT diff --git a/techlibs/xilinx/cells_sim.v b/techlibs/xilinx/cells_sim.v index 7941a94cd..d7dff8975 100644 --- a/techlibs/xilinx/cells_sim.v +++ b/techlibs/xilinx/cells_sim.v @@ -283,7 +283,7 @@ endmodule // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLL_L.sdf#L238-L250 -(* abc9_box_id=1001, lib_whitebox, abc9_flop *) +(* abc9_box_id=1100, lib_whitebox, abc9_flop *) module FDRE ( (* abc9_arrival=303 *) output reg Q, @@ -307,7 +307,7 @@ module FDRE ( endcase endgenerate endmodule -(* abc9_box_id=1002, lib_whitebox, abc9_flop *) +(* abc9_box_id=1101, lib_whitebox, abc9_flop *) module FDRE_1 ( (* abc9_arrival=303 *) output reg Q, @@ -355,7 +355,7 @@ module FDRSE ( Q <= d; endmodule -(* abc9_box_id=1003, lib_whitebox, abc9_flop *) +(* abc9_box_id=1102, lib_whitebox, abc9_flop *) module FDCE ( (* abc9_arrival=303 *) output reg Q, @@ -381,7 +381,7 @@ module FDCE ( endcase endgenerate endmodule -(* abc9_box_id=1004, lib_whitebox, abc9_flop *) +(* abc9_box_id=1103, lib_whitebox, abc9_flop *) module FDCE_1 ( (* abc9_arrival=303 *) output reg Q, @@ -394,7 +394,7 @@ module FDCE_1 ( always @(negedge C, posedge CLR) if (CLR) Q <= 1'b0; else if (CE) Q <= D; endmodule -(* abc9_box_id=1005, lib_whitebox, abc9_flop *) +(* abc9_box_id=1104, lib_whitebox, abc9_flop *) module FDPE ( (* abc9_arrival=303 *) output reg Q, @@ -420,7 +420,7 @@ module FDPE ( endcase endgenerate endmodule -(* abc9_box_id=1006, lib_whitebox, abc9_flop *) +(* abc9_box_id=1105, lib_whitebox, abc9_flop *) module FDPE_1 ( (* abc9_arrival=303 *) output reg Q, @@ -433,7 +433,7 @@ module FDPE_1 ( always @(negedge C, posedge PRE) if (PRE) Q <= 1'b1; else if (CE) Q <= D; endmodule -(* abc9_box_id=1007, lib_whitebox, abc9_flop *) +(* abc9_box_id=1106, lib_whitebox, abc9_flop *) module FDSE ( (* abc9_arrival=303 *) output reg Q, @@ -457,7 +457,7 @@ module FDSE ( endcase endgenerate endmodule -(* abc9_box_id=1008, lib_whitebox, abc9_flop *) +(* abc9_box_id=1107, lib_whitebox, abc9_flop *) module FDSE_1 ( (* abc9_arrival=303 *) output reg Q, -- cgit v1.2.3 From 45f0f1486bbe30cdbf22c94b165879568af1a37a Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 19 Dec 2019 11:24:39 -0800 Subject: Add RAM{32,64}M to abc9_map.v --- techlibs/xilinx/abc9_map.v | 78 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/techlibs/xilinx/abc9_map.v b/techlibs/xilinx/abc9_map.v index b36d93c5d..d2d7d9114 100644 --- a/techlibs/xilinx/abc9_map.v +++ b/techlibs/xilinx/abc9_map.v @@ -446,6 +446,84 @@ module RAM128X1D ( \$__ABC9_LUT7 dpo (.A(\$DPO ), .S(DPRA), .Y(DPO)); endmodule +module RAM32M ( + output [1:0] DOA, + output [1:0] DOB, + output [1:0] DOC, + output [1:0] DOD, + (* techmap_autopurge *) input [4:0] ADDRA, + (* techmap_autopurge *) input [4:0] ADDRB, + (* techmap_autopurge *) input [4:0] ADDRC, + (* techmap_autopurge *) input [4:0] ADDRD, + (* techmap_autopurge *) input [1:0] DIA, + (* techmap_autopurge *) input [1:0] DIB, + (* techmap_autopurge *) input [1:0] DIC, + (* techmap_autopurge *) input [1:0] DID, + (* techmap_autopurge *) input WCLK, + (* techmap_autopurge *) input WE +); + parameter [63:0] INIT_A = 64'h0000000000000000; + parameter [63:0] INIT_B = 64'h0000000000000000; + 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 ; + 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 ), + .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])); +endmodule + +module RAM64M ( + output DOA, + output DOB, + output DOC, + output DOD, + (* techmap_autopurge *) input [5:0] ADDRA, + (* techmap_autopurge *) input [5:0] ADDRB, + (* techmap_autopurge *) input [5:0] ADDRC, + (* techmap_autopurge *) input [5:0] ADDRD, + (* techmap_autopurge *) input DIA, + (* techmap_autopurge *) input DIB, + (* techmap_autopurge *) input DIC, + (* techmap_autopurge *) input DID, + (* techmap_autopurge *) input WCLK, + (* techmap_autopurge *) input WE +); + parameter [63:0] INIT_A = 64'h0000000000000000; + parameter [63:0] INIT_B = 64'h0000000000000000; + 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 ; + 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 ), + .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)); +endmodule + module SRL16E ( output Q, (* techmap_autopurge *) input A0, A1, A2, A3, CE, CLK, D -- cgit v1.2.3 From 2a8cfdebbba39782304afdf91b8fcfbf0bd58eb0 Mon Sep 17 00:00:00 2001 From: Graham Edgecombe Date: Tue, 19 Nov 2019 19:45:59 +0000 Subject: Add PYTHON_CONFIG variable to the Makefile --- Makefile | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/Makefile b/Makefile index 6e7681cf3..c60e0afa6 100644 --- a/Makefile +++ b/Makefile @@ -152,7 +152,8 @@ ifeq ($(ENABLE_PYOSYS),1) PYTHON_VERSION_TESTCODE := "import sys;t='{v[0]}.{v[1]}'.format(v=list(sys.version_info[:2]));print(t)" PYTHON_VERSION := $(shell $(PYTHON_EXECUTABLE) -c ""$(PYTHON_VERSION_TESTCODE)"") PYTHON_MAJOR_VERSION := $(shell echo $(PYTHON_VERSION) | cut -f1 -d.) -PYTHON_PREFIX := $(shell $(PYTHON_EXECUTABLE)-config --prefix) +PYTHON_CONFIG := $(PYTHON_EXECUTABLE)-config +PYTHON_PREFIX := $(shell $(PYTHON_CONFIG) --prefix) PYTHON_DESTDIR := $(PYTHON_PREFIX)/lib/python$(PYTHON_VERSION)/site-packages # Reload Makefile.conf to override python specific variables if defined @@ -305,17 +306,17 @@ ifeq ($(ENABLE_PYOSYS),1) #Detect name of boost_python library. Some distros usbe boost_python-py, other boost_python, some only use the major version number, some a concatenation of major and minor version numbers ifeq ($(OS), Darwin) BOOST_PYTHON_LIB ?= $(shell \ - if echo "int main(int argc, char ** argv) {return 0;}" | $(CXX) -xc -o /dev/null $(shell $(PYTHON_EXECUTABLE)-config --ldflags) -lboost_python-py$(subst .,,$(PYTHON_VERSION)) - > /dev/null 2>&1; then echo "-lboost_python-py$(subst .,,$(PYTHON_VERSION))"; else \ - if echo "int main(int argc, char ** argv) {return 0;}" | $(CXX) -xc -o /dev/null $(shell $(PYTHON_EXECUTABLE)-config --ldflags) -lboost_python-py$(subst .,,$(PYTHON_MAJOR_VERSION)) - > /dev/null 2>&1; then echo "-lboost_python-py$(subst .,,$(PYTHON_MAJOR_VERSION))"; else \ - if echo "int main(int argc, char ** argv) {return 0;}" | $(CXX) -xc -o /dev/null $(shell $(PYTHON_EXECUTABLE)-config --ldflags) -lboost_python$(subst .,,$(PYTHON_VERSION)) - > /dev/null 2>&1; then echo "-lboost_python$(subst .,,$(PYTHON_VERSION))"; else \ - if echo "int main(int argc, char ** argv) {return 0;}" | $(CXX) -xc -o /dev/null $(shell $(PYTHON_EXECUTABLE)-config --ldflags) -lboost_python$(subst .,,$(PYTHON_MAJOR_VERSION)) - > /dev/null 2>&1; then echo "-lboost_python$(subst .,,$(PYTHON_MAJOR_VERSION))"; else \ + if echo "int main(int argc, char ** argv) {return 0;}" | $(CXX) -xc -o /dev/null $(shell $(PYTHON_CONFIG) --ldflags) -lboost_python-py$(subst .,,$(PYTHON_VERSION)) - > /dev/null 2>&1; then echo "-lboost_python-py$(subst .,,$(PYTHON_VERSION))"; else \ + if echo "int main(int argc, char ** argv) {return 0;}" | $(CXX) -xc -o /dev/null $(shell $(PYTHON_CONFIG) --ldflags) -lboost_python-py$(subst .,,$(PYTHON_MAJOR_VERSION)) - > /dev/null 2>&1; then echo "-lboost_python-py$(subst .,,$(PYTHON_MAJOR_VERSION))"; else \ + if echo "int main(int argc, char ** argv) {return 0;}" | $(CXX) -xc -o /dev/null $(shell $(PYTHON_CONFIG) --ldflags) -lboost_python$(subst .,,$(PYTHON_VERSION)) - > /dev/null 2>&1; then echo "-lboost_python$(subst .,,$(PYTHON_VERSION))"; else \ + if echo "int main(int argc, char ** argv) {return 0;}" | $(CXX) -xc -o /dev/null $(shell $(PYTHON_CONFIG) --ldflags) -lboost_python$(subst .,,$(PYTHON_MAJOR_VERSION)) - > /dev/null 2>&1; then echo "-lboost_python$(subst .,,$(PYTHON_MAJOR_VERSION))"; else \ echo ""; fi; fi; fi; fi;) else BOOST_PYTHON_LIB ?= $(shell \ - if echo "int main(int argc, char ** argv) {return 0;}" | $(CXX) -xc -o /dev/null `$(PYTHON_EXECUTABLE)-config --libs` -lboost_python-py$(subst .,,$(PYTHON_VERSION)) - > /dev/null 2>&1; then echo "-lboost_python-py$(subst .,,$(PYTHON_VERSION))"; else \ - if echo "int main(int argc, char ** argv) {return 0;}" | $(CXX) -xc -o /dev/null `$(PYTHON_EXECUTABLE)-config --libs` -lboost_python-py$(subst .,,$(PYTHON_MAJOR_VERSION)) - > /dev/null 2>&1; then echo "-lboost_python-py$(subst .,,$(PYTHON_MAJOR_VERSION))"; else \ - if echo "int main(int argc, char ** argv) {return 0;}" | $(CXX) -xc -o /dev/null `$(PYTHON_EXECUTABLE)-config --libs` -lboost_python$(subst .,,$(PYTHON_VERSION)) - > /dev/null 2>&1; then echo "-lboost_python$(subst .,,$(PYTHON_VERSION))"; else \ - if echo "int main(int argc, char ** argv) {return 0;}" | $(CXX) -xc -o /dev/null `$(PYTHON_EXECUTABLE)-config --libs` -lboost_python$(subst .,,$(PYTHON_MAJOR_VERSION)) - > /dev/null 2>&1; then echo "-lboost_python$(subst .,,$(PYTHON_MAJOR_VERSION))"; else \ + if echo "int main(int argc, char ** argv) {return 0;}" | $(CXX) -xc -o /dev/null `$(PYTHON_CONFIG) --libs` -lboost_python-py$(subst .,,$(PYTHON_VERSION)) - > /dev/null 2>&1; then echo "-lboost_python-py$(subst .,,$(PYTHON_VERSION))"; else \ + if echo "int main(int argc, char ** argv) {return 0;}" | $(CXX) -xc -o /dev/null `$(PYTHON_CONFIG) --libs` -lboost_python-py$(subst .,,$(PYTHON_MAJOR_VERSION)) - > /dev/null 2>&1; then echo "-lboost_python-py$(subst .,,$(PYTHON_MAJOR_VERSION))"; else \ + if echo "int main(int argc, char ** argv) {return 0;}" | $(CXX) -xc -o /dev/null `$(PYTHON_CONFIG) --libs` -lboost_python$(subst .,,$(PYTHON_VERSION)) - > /dev/null 2>&1; then echo "-lboost_python$(subst .,,$(PYTHON_VERSION))"; else \ + if echo "int main(int argc, char ** argv) {return 0;}" | $(CXX) -xc -o /dev/null `$(PYTHON_CONFIG) --libs` -lboost_python$(subst .,,$(PYTHON_MAJOR_VERSION)) - > /dev/null 2>&1; then echo "-lboost_python$(subst .,,$(PYTHON_MAJOR_VERSION))"; else \ echo ""; fi; fi; fi; fi;) endif @@ -325,19 +326,19 @@ endif ifeq ($(OS), Darwin) ifeq ($(PYTHON_MAJOR_VERSION),3) -LDLIBS += $(shell $(PYTHON_EXECUTABLE)-config --ldflags) $(BOOST_PYTHON_LIB) -lboost_system -lboost_filesystem -CXXFLAGS += $(shell $(PYTHON_EXECUTABLE)-config --includes) -DWITH_PYTHON +LDLIBS += $(shell $(PYTHON_CONFIG) --ldflags) $(BOOST_PYTHON_LIB) -lboost_system -lboost_filesystem +CXXFLAGS += $(shell $(PYTHON_CONFIG) --includes) -DWITH_PYTHON else -LDLIBS += $(shell $(PYTHON_EXECUTABLE)-config --ldflags) $(BOOST_PYTHON_LIB) -lboost_system -lboost_filesystem -CXXFLAGS += $(shell $(PYTHON_EXECUTABLE)-config --includes) -DWITH_PYTHON +LDLIBS += $(shell $(PYTHON_CONFIG) --ldflags) $(BOOST_PYTHON_LIB) -lboost_system -lboost_filesystem +CXXFLAGS += $(shell $(PYTHON_CONFIG) --includes) -DWITH_PYTHON endif else ifeq ($(PYTHON_MAJOR_VERSION),3) -LDLIBS += $(shell $(PYTHON_EXECUTABLE)-config --libs) $(BOOST_PYTHON_LIB) -lboost_system -lboost_filesystem -CXXFLAGS += $(shell $(PYTHON_EXECUTABLE)-config --includes) -DWITH_PYTHON +LDLIBS += $(shell $(PYTHON_CONFIG) --libs) $(BOOST_PYTHON_LIB) -lboost_system -lboost_filesystem +CXXFLAGS += $(shell $(PYTHON_CONFIG) --includes) -DWITH_PYTHON else -LDLIBS += $(shell $(PYTHON_EXECUTABLE)-config --libs) $(BOOST_PYTHON_LIB) -lboost_system -lboost_filesystem -CXXFLAGS += $(shell $(PYTHON_EXECUTABLE)-config --includes) -DWITH_PYTHON +LDLIBS += $(shell $(PYTHON_CONFIG) --libs) $(BOOST_PYTHON_LIB) -lboost_system -lboost_filesystem +CXXFLAGS += $(shell $(PYTHON_CONFIG) --includes) -DWITH_PYTHON endif endif -- cgit v1.2.3 From 319cba70d37eafdb8bbd3ddf6a0f9c238d53d0c2 Mon Sep 17 00:00:00 2001 From: Graham Edgecombe Date: Tue, 19 Nov 2019 19:46:15 +0000 Subject: Fix linking with Python 3.8 The behaviour of python-config --libs has changed in Python 3.8. For example, compare the output of it with Python 3.7 and 3.8 on an ArchLinux system: $ python3.7-config --libs -lpython3.7m -lcrypt -lpthread -ldl -lutil -lm $ python3.8-config --libs -lcrypt -lpthread -ldl -lutil -lm -lm $ The lack of -lpython in the latter case causes the linker to fail when attempting to build Yosys against Python 3.8. Passing the new --embed flag to python-config adds -lpython, just like earlier versions of Python: $ python3.8-config --embed --libs -lpython3.8 -lcrypt -lpthread -ldl -lutil -lm -lm $ This commit adds code for automatically detecting support for the --embed flag. If it is supported, it is passed to all python-config invocations. This fixes building against Python 3.8. --- Makefile | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Makefile b/Makefile index c60e0afa6..a85f6350c 100644 --- a/Makefile +++ b/Makefile @@ -152,7 +152,14 @@ ifeq ($(ENABLE_PYOSYS),1) PYTHON_VERSION_TESTCODE := "import sys;t='{v[0]}.{v[1]}'.format(v=list(sys.version_info[:2]));print(t)" PYTHON_VERSION := $(shell $(PYTHON_EXECUTABLE) -c ""$(PYTHON_VERSION_TESTCODE)"") PYTHON_MAJOR_VERSION := $(shell echo $(PYTHON_VERSION) | cut -f1 -d.) + +ENABLE_PYTHON_CONFIG_EMBED ?= $(shell $(PYTHON_EXECUTABLE)-config --embed --libs > /dev/null && echo 1) +ifeq ($(ENABLE_PYTHON_CONFIG_EMBED),1) +PYTHON_CONFIG := $(PYTHON_EXECUTABLE)-config --embed +else PYTHON_CONFIG := $(PYTHON_EXECUTABLE)-config +endif + PYTHON_PREFIX := $(shell $(PYTHON_CONFIG) --prefix) PYTHON_DESTDIR := $(PYTHON_PREFIX)/lib/python$(PYTHON_VERSION)/site-packages -- cgit v1.2.3 From 10e82e103f7b95d5a50d2ac85bc8e07e4461e388 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 20 Dec 2019 12:05:45 -0800 Subject: Revert "Optimise write_xaiger" --- backends/aiger/xaiger.cc | 45 +++++++++++++++++++---------------------- techlibs/ecp5/synth_ecp5.cc | 5 ----- techlibs/ice40/synth_ice40.cc | 5 ----- techlibs/xilinx/synth_xilinx.cc | 5 ----- 4 files changed, 21 insertions(+), 39 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 8074fa835..627133314 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -605,25 +605,15 @@ struct XAigerWriter RTLIL::Module *holes_module = module->design->addModule("$__holes__"); log_assert(holes_module); - dict cell_cache; - int port_id = 1; int box_count = 0; for (auto cell : box_list) { RTLIL::Module* 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")) { + Cell *holes_cell = nullptr; + if (box_module->get_bool_attribute("\\whitebox")) { holes_cell = holes_module->addCell(cell->name, cell->type); holes_cell->parameters = cell->parameters; - r.first->second = holes_cell; } // NB: Assume box_module->ports are sorted alphabetically @@ -632,8 +622,8 @@ struct XAigerWriter RTLIL::Wire *w = box_module->wire(port_name); log_assert(w); RTLIL::Wire *holes_wire; - RTLIL::SigSpec port_sig; - if (w->port_input) + RTLIL::SigSpec port_wire; + if (w->port_input) { for (int i = 0; i < GetSize(w); i++) { box_inputs++; holes_wire = holes_module->wire(stringf("\\i%d", box_inputs)); @@ -644,29 +634,28 @@ struct XAigerWriter holes_module->ports.push_back(holes_wire->name); } if (holes_cell) - port_sig.append(holes_wire); + port_wire.append(holes_wire); } + if (!port_wire.empty()) + holes_cell->setPort(w->name, port_wire); + } if (w->port_output) { box_outputs += GetSize(w); for (int i = 0; i < GetSize(w); i++) { if (GetSize(w) == 1) - holes_wire = holes_module->addWire(stringf("%s.%s", cell->name.c_str(), log_id(w->name))); + holes_wire = holes_module->addWire(stringf("%s.%s", cell->name.c_str(), w->name.c_str())); else - holes_wire = holes_module->addWire(stringf("%s.%s[%d]", cell->name.c_str(), log_id(w->name), i)); + holes_wire = holes_module->addWire(stringf("%s.%s[%d]", cell->name.c_str(), w->name.c_str(), i)); holes_wire->port_output = true; holes_wire->port_id = port_id++; holes_module->ports.push_back(holes_wire->name); if (holes_cell) - port_sig.append(holes_wire); + port_wire.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); + if (!port_wire.empty()) + holes_cell->setPort(w->name, port_wire); } } @@ -696,8 +685,16 @@ struct XAigerWriter RTLIL::Selection& sel = holes_module->design->selection_stack.back(); sel.select(holes_module); + // TODO: Should not need to opt_merge if we only instantiate + // each box type once... + Pass::call(holes_module->design, "opt_merge -share_all"); + Pass::call(holes_module->design, "flatten -wb"); + // TODO: Should techmap/aigmap/check all lib_whitebox-es just once, + // instead of per write_xaiger call + Pass::call(holes_module->design, "techmap"); + Pass::call(holes_module->design, "aigmap"); for (auto cell : holes_module->cells()) if (!cell->type.in("$_NOT_", "$_AND_")) log_error("Whitebox contents cannot be represented as AIG. Please verify whiteboxes are synthesisable.\n"); diff --git a/techlibs/ecp5/synth_ecp5.cc b/techlibs/ecp5/synth_ecp5.cc index 16ff9c57a..b71bb2395 100644 --- a/techlibs/ecp5/synth_ecp5.cc +++ b/techlibs/ecp5/synth_ecp5.cc @@ -321,11 +321,6 @@ struct SynthEcp5Pass : public ScriptPass run("techmap " + techmap_args); if (abc9) { - run("select -set abc9_boxes A:abc9_box_id A:whitebox=1"); - run("wbflip @abc9_boxes"); - run("techmap -autoproc @abc9_boxes"); - run("aigmap @abc9_boxes"); - run("wbflip @abc9_boxes"); run("read_verilog -icells -lib +/ecp5/abc9_model.v"); if (nowidelut) run("abc9 -lut +/ecp5/abc9_5g_nowide.lut -box +/ecp5/abc9_5g.box -W 200 -nomfs"); diff --git a/techlibs/ice40/synth_ice40.cc b/techlibs/ice40/synth_ice40.cc index 5073ba917..ed7a16c08 100644 --- a/techlibs/ice40/synth_ice40.cc +++ b/techlibs/ice40/synth_ice40.cc @@ -350,11 +350,6 @@ struct SynthIce40Pass : public ScriptPass } if (!noabc) { if (abc == "abc9") { - run("select -set abc9_boxes A:abc9_box_id A:whitebox=1"); - run("wbflip @abc9_boxes"); - run("techmap -autoproc @abc9_boxes"); - run("aigmap @abc9_boxes"); - run("wbflip @abc9_boxes"); run("read_verilog -icells -lib +/ice40/abc9_model.v"); int wire_delay; if (device_opt == "lp") diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index ff530b819..971089b28 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -540,11 +540,6 @@ struct SynthXilinxPass : public ScriptPass 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"); - run("select -set abc9_boxes A:abc9_box_id A:whitebox=1"); - run("wbflip @abc9_boxes"); - run("techmap -autoproc @abc9_boxes"); - run("aigmap @abc9_boxes"); - run("wbflip @abc9_boxes"); 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); -- cgit v1.2.3 From a75e08c7094d7d6f623057ad936c63551f1ebfbe Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 20 Dec 2019 13:07:24 -0800 Subject: write_xaiger: only instantiate each whitebox cell type once --- backends/aiger/xaiger.cc | 46 +++++++++++++++++++++++++++------------------- 1 file changed, 27 insertions(+), 19 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 627133314..5729f045a 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -605,15 +605,25 @@ struct XAigerWriter RTLIL::Module *holes_module = module->design->addModule("$__holes__"); log_assert(holes_module); + dict cell_cache; + int port_id = 1; int box_count = 0; for (auto cell : box_list) { RTLIL::Module* 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; - Cell *holes_cell = nullptr; - if (box_module->get_bool_attribute("\\whitebox")) { + 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 @@ -622,8 +632,8 @@ struct XAigerWriter RTLIL::Wire *w = box_module->wire(port_name); log_assert(w); RTLIL::Wire *holes_wire; - RTLIL::SigSpec port_wire; - if (w->port_input) { + 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)); @@ -634,28 +644,29 @@ struct XAigerWriter holes_module->ports.push_back(holes_wire->name); } if (holes_cell) - port_wire.append(holes_wire); + port_sig.append(holes_wire); } - if (!port_wire.empty()) - holes_cell->setPort(w->name, port_wire); - } if (w->port_output) { box_outputs += GetSize(w); for (int i = 0; i < GetSize(w); i++) { if (GetSize(w) == 1) - holes_wire = holes_module->addWire(stringf("%s.%s", cell->name.c_str(), w->name.c_str())); + 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(), w->name.c_str(), i)); + 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_wire.append(holes_wire); + port_sig.append(holes_wire); else holes_module->connect(holes_wire, State::S0); } - if (!port_wire.empty()) - holes_cell->setPort(w->name, port_wire); + } + 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); } } @@ -685,14 +696,11 @@ struct XAigerWriter RTLIL::Selection& sel = holes_module->design->selection_stack.back(); sel.select(holes_module); - // TODO: Should not need to opt_merge if we only instantiate - // each box type once... - Pass::call(holes_module->design, "opt_merge -share_all"); - Pass::call(holes_module->design, "flatten -wb"); - // TODO: Should techmap/aigmap/check all lib_whitebox-es just once, - // instead of per write_xaiger call + // 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()) -- cgit v1.2.3 From ff2645ce0b8d0e639b0e83db35476036dde34f0d Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 20 Dec 2019 13:38:32 -0800 Subject: Put specify/endspecify inside `` --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 5cc52e842..0250c7846 100644 --- a/README.md +++ b/README.md @@ -454,10 +454,10 @@ Verilog Attributes and non-standard features expressions over parameters and constant values are allowed). The intended use for this is synthesis-time DRC. -- There is limited support for converting specify .. endspecify statements to - special ``$specify2``, ``$specify3``, and ``$specrule`` cells, for use in - blackboxes and whiteboxes. Use ``read_verilog -specify`` to enable this - functionality. (By default specify .. endspecify blocks are ignored.) +- There is limited support for converting ``specify`` .. ``endspecify`` + statements to special ``$specify2``, ``$specify3``, and ``$specrule`` cells, + for use in blackboxes and whiteboxes. Use ``read_verilog -specify`` to + enable this functionality. (By default these blocks are ignored.) Non-standard or SystemVerilog features for formal verification -- cgit v1.2.3 From 7928eb113c5a310924f4bb8ab26d0dafe902d6ec Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 19 Dec 2019 11:24:39 -0800 Subject: Add RAM{32,64}M to abc9_map.v --- techlibs/xilinx/abc9_map.v | 78 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/techlibs/xilinx/abc9_map.v b/techlibs/xilinx/abc9_map.v index 6fd73c1e0..7b9427b2f 100644 --- a/techlibs/xilinx/abc9_map.v +++ b/techlibs/xilinx/abc9_map.v @@ -88,6 +88,84 @@ module RAM128X1D ( \$__ABC9_LUT7 dpo (.A(\$DPO ), .S(DPRA), .Y(DPO)); endmodule +module RAM32M ( + output [1:0] DOA, + output [1:0] DOB, + output [1:0] DOC, + output [1:0] DOD, + (* techmap_autopurge *) input [4:0] ADDRA, + (* techmap_autopurge *) input [4:0] ADDRB, + (* techmap_autopurge *) input [4:0] ADDRC, + (* techmap_autopurge *) input [4:0] ADDRD, + (* techmap_autopurge *) input [1:0] DIA, + (* techmap_autopurge *) input [1:0] DIB, + (* techmap_autopurge *) input [1:0] DIC, + (* techmap_autopurge *) input [1:0] DID, + (* techmap_autopurge *) input WCLK, + (* techmap_autopurge *) input WE +); + parameter [63:0] INIT_A = 64'h0000000000000000; + parameter [63:0] INIT_B = 64'h0000000000000000; + 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 ; + 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 ), + .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])); +endmodule + +module RAM64M ( + output DOA, + output DOB, + output DOC, + output DOD, + (* techmap_autopurge *) input [5:0] ADDRA, + (* techmap_autopurge *) input [5:0] ADDRB, + (* techmap_autopurge *) input [5:0] ADDRC, + (* techmap_autopurge *) input [5:0] ADDRD, + (* techmap_autopurge *) input DIA, + (* techmap_autopurge *) input DIB, + (* techmap_autopurge *) input DIC, + (* techmap_autopurge *) input DID, + (* techmap_autopurge *) input WCLK, + (* techmap_autopurge *) input WE +); + parameter [63:0] INIT_A = 64'h0000000000000000; + parameter [63:0] INIT_B = 64'h0000000000000000; + 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 ; + 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 ), + .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)); +endmodule + module SRL16E ( output Q, (* techmap_autopurge *) input A0, A1, A2, A3, CE, CLK, D -- cgit v1.2.3 From 5986a4df40a9c19171624c772b39e4c003e9c6ff Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 20 Dec 2019 14:06:59 -0800 Subject: Add abc9_arrival times for RAM{32,64}M --- techlibs/xilinx/cells_sim.v | 34 ++++++++++------------------------ 1 file changed, 10 insertions(+), 24 deletions(-) diff --git a/techlibs/xilinx/cells_sim.v b/techlibs/xilinx/cells_sim.v index 47ba794bf..804c2d70f 100644 --- a/techlibs/xilinx/cells_sim.v +++ b/techlibs/xilinx/cells_sim.v @@ -1244,18 +1244,11 @@ endmodule // Multi port. module RAM32M ( - output [1:0] DOA, - output [1:0] DOB, - output [1:0] DOC, - output [1:0] DOD, - input [4:0] ADDRA, - input [4:0] ADDRB, - input [4:0] ADDRC, - input [4:0] ADDRD, - input [1:0] DIA, - input [1:0] DIB, - input [1:0] DIC, - input [1:0] DID, + // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L957 + (* abc9_arrival=1153 *) + output [1:0] DOA, DOB, DOC, DOD, + input [4:0] ADDRA, ADDRB, ADDRC, ADDRD, + input [1:0] DIA, DIB, DIC, DID, (* clkbuf_sink *) (* invertible_pin = "IS_WCLK_INVERTED" *) input WCLK, @@ -1354,18 +1347,11 @@ module RAM32M16 ( endmodule module RAM64M ( - output DOA, - output DOB, - output DOC, - output DOD, - input [5:0] ADDRA, - input [5:0] ADDRB, - input [5:0] ADDRC, - input [5:0] ADDRD, - input DIA, - input DIB, - input DIC, - input DID, + // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L957 + (* abc9_arrival=1153 *) + output DOA, DOB, DOC, DOD, + input [5:0] ADDRA, ADDRB, ADDRC, ADDRD, + input DIA, DIB, DIC, DID, (* clkbuf_sink *) (* invertible_pin = "IS_WCLK_INVERTED" *) input WCLK, -- cgit v1.2.3 From 2fcf683af427aa86ff57bcbed8b027e97fd03f96 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Sat, 21 Dec 2019 11:56:41 +0100 Subject: Make iopad option default for all xilinx flows --- techlibs/xilinx/synth_xilinx.cc | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index 971089b28..006679eb1 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,8 @@ 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\n"); log("\n"); log(" -noclkbuf\n"); log(" disable automatic clock buffer insertion\n"); @@ -122,7 +119,7 @@ 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, abc9; bool flatten_before_abc; int widemux; @@ -136,7 +133,6 @@ struct SynthXilinxPass : public ScriptPass retime = false; vpr = false; ise = false; - iopad = false; noiopad = false; noclkbuf = false; nocarry = false; @@ -212,10 +208,6 @@ struct SynthXilinxPass : public ScriptPass ise = true; continue; } - if (args[argidx] == "-iopad") { - iopad = true; - continue; - } if (args[argidx] == "-noiopad") { noiopad = true; continue; @@ -282,7 +274,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"; @@ -514,8 +505,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); -- cgit v1.2.3 From 477e43d921d204c6bc6403109fea6506802c948c Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Sat, 21 Dec 2019 13:18:44 +0100 Subject: Fix xilinx tests, when iopads are default --- tests/arch/xilinx/add_sub.ys | 2 +- tests/arch/xilinx/adffs.ys | 8 ++++---- tests/arch/xilinx/bug1460.ys | 2 +- tests/arch/xilinx/counter.ys | 2 +- tests/arch/xilinx/dffs.ys | 4 ++-- tests/arch/xilinx/dsp_fastfir.ys | 2 +- tests/arch/xilinx/fsm.ys | 2 +- tests/arch/xilinx/latches.ys | 6 +++--- tests/arch/xilinx/logic.ys | 2 +- tests/arch/xilinx/lutram.ys | 14 +++++++------- tests/arch/xilinx/macc.ys | 4 ++-- tests/arch/xilinx/mul.ys | 2 +- tests/arch/xilinx/mul_unsigned.ys | 2 +- tests/arch/xilinx/mux.ys | 8 ++++---- tests/arch/xilinx/shifter.ys | 2 +- tests/arch/xilinx/tribuf.ys | 6 ++++-- tests/arch/xilinx/xilinx_dffopt.ys | 18 +++++++++--------- 17 files changed, 44 insertions(+), 42 deletions(-) diff --git a/tests/arch/xilinx/add_sub.ys b/tests/arch/xilinx/add_sub.ys index 9dbddce47..920717a3d 100644 --- a/tests/arch/xilinx/add_sub.ys +++ b/tests/arch/xilinx/add_sub.ys @@ -7,5 +7,5 @@ cd top # Constrain all select calls below inside the top module select -assert-count 14 t:LUT2 select -assert-count 6 t:MUXCY select -assert-count 8 t:XORCY -select -assert-none t:LUT2 t:MUXCY t:XORCY %% t:* %D +select -assert-none t:LUT2 t:MUXCY t:XORCY t:IBUF t:OBUF %% t:* %D diff --git a/tests/arch/xilinx/adffs.ys b/tests/arch/xilinx/adffs.ys index c0ff6a2e2..ba9ddf90f 100644 --- a/tests/arch/xilinx/adffs.ys +++ b/tests/arch/xilinx/adffs.ys @@ -9,7 +9,7 @@ cd adff # Constrain all select calls below inside the top module select -assert-count 1 t:BUFG select -assert-count 1 t:FDCE -select -assert-none t:BUFG t:FDCE %% t:* %D +select -assert-none t:BUFG t:FDCE t:IBUF t:OBUF %% t:* %D design -load read @@ -22,7 +22,7 @@ select -assert-count 1 t:BUFG select -assert-count 1 t:FDCE select -assert-count 1 t:INV -select -assert-none t:BUFG t:FDCE t:INV %% t:* %D +select -assert-none t:BUFG t:FDCE t:INV t:IBUF t:OBUF %% t:* %D design -load read @@ -34,7 +34,7 @@ cd dffs # Constrain all select calls below inside the top module select -assert-count 1 t:BUFG select -assert-count 1 t:FDSE -select -assert-none t:BUFG t:FDSE %% t:* %D +select -assert-none t:BUFG t:FDSE t:IBUF t:OBUF %% t:* %D design -load read @@ -47,4 +47,4 @@ select -assert-count 1 t:BUFG select -assert-count 1 t:FDRE_1 select -assert-count 1 t:INV -select -assert-none t:BUFG t:FDRE_1 t:INV %% t:* %D +select -assert-none t:BUFG t:FDRE_1 t:INV t:IBUF t:OBUF %% t:* %D diff --git a/tests/arch/xilinx/bug1460.ys b/tests/arch/xilinx/bug1460.ys index 2018071cc..73fb662dc 100644 --- a/tests/arch/xilinx/bug1460.ys +++ b/tests/arch/xilinx/bug1460.ys @@ -31,4 +31,4 @@ EOT synth_xilinx cd register_file select -assert-count 32 t:RAM32M -select -assert-none t:* t:BUFG %d t:RAM32M %d +select -assert-none t:* t:BUFG %d t:IBUF %d t:OBUF %d t:RAM32M %d diff --git a/tests/arch/xilinx/counter.ys b/tests/arch/xilinx/counter.ys index 604acdbfc..e4217bbaf 100644 --- a/tests/arch/xilinx/counter.ys +++ b/tests/arch/xilinx/counter.ys @@ -11,4 +11,4 @@ select -assert-count 8 t:FDCE select -assert-count 1 t:INV select -assert-count 7 t:MUXCY select -assert-count 8 t:XORCY -select -assert-none t:BUFG t:FDCE t:INV t:MUXCY t:XORCY %% t:* %D +select -assert-none t:BUFG t:FDCE t:INV t:MUXCY t:XORCY t:IBUF t:OBUF %% t:* %D diff --git a/tests/arch/xilinx/dffs.ys b/tests/arch/xilinx/dffs.ys index 0bba4858f..b2cb70323 100644 --- a/tests/arch/xilinx/dffs.ys +++ b/tests/arch/xilinx/dffs.ys @@ -9,7 +9,7 @@ cd dff # Constrain all select calls below inside the top module select -assert-count 1 t:BUFG select -assert-count 1 t:FDRE -select -assert-none t:BUFG t:FDRE %% t:* %D +select -assert-none t:BUFG t:FDRE t:IBUF t:OBUF %% t:* %D design -load read @@ -21,5 +21,5 @@ cd dffe # Constrain all select calls below inside the top module select -assert-count 1 t:BUFG select -assert-count 1 t:FDRE -select -assert-none t:BUFG t:FDRE %% t:* %D +select -assert-none t:BUFG t:FDRE t:IBUF t:OBUF %% t:* %D diff --git a/tests/arch/xilinx/dsp_fastfir.ys b/tests/arch/xilinx/dsp_fastfir.ys index 0067a822b..05e1785d8 100644 --- a/tests/arch/xilinx/dsp_fastfir.ys +++ b/tests/arch/xilinx/dsp_fastfir.ys @@ -66,4 +66,4 @@ EOT synth_xilinx cd fastfir_dynamictaps select -assert-count 2 t:DSP48E1 -select -assert-none t:* t:DSP48E1 %d t:BUFG %d +select -assert-none t:* t:DSP48E1 %d t:BUFG %d t:IBUF %d t:OBUF %d diff --git a/tests/arch/xilinx/fsm.ys b/tests/arch/xilinx/fsm.ys index f03400fe7..d60695e2c 100644 --- a/tests/arch/xilinx/fsm.ys +++ b/tests/arch/xilinx/fsm.ys @@ -16,4 +16,4 @@ select -assert-count 1 t:FDSE select -assert-count 1 t:LUT2 select -assert-count 3 t:LUT5 select -assert-count 1 t:LUT6 -select -assert-none t:BUFG t:FDRE t:FDSE t:LUT2 t:LUT5 t:LUT6 %% t:* %D +select -assert-none t:BUFG t:IBUF t:OBUF t:FDRE t:FDSE t:LUT2 t:LUT5 t:LUT6 %% t:* %D diff --git a/tests/arch/xilinx/latches.ys b/tests/arch/xilinx/latches.ys index c87a8e38b..c1caea27a 100644 --- a/tests/arch/xilinx/latches.ys +++ b/tests/arch/xilinx/latches.ys @@ -8,7 +8,7 @@ design -load postopt # load the post-opt design (otherwise equiv_opt loads the p cd latchp # Constrain all select calls below inside the top module select -assert-count 1 t:LDCE -select -assert-none t:LDCE %% t:* %D +select -assert-none t:LDCE t:IBUF t:OBUF %% t:* %D design -load read @@ -20,7 +20,7 @@ cd latchn # Constrain all select calls below inside the top module select -assert-count 1 t:LDCE select -assert-count 1 t:INV -select -assert-none t:LDCE t:INV %% t:* %D +select -assert-none t:LDCE t:INV t:IBUF t:OBUF %% t:* %D design -load read @@ -32,4 +32,4 @@ cd latchsr # Constrain all select calls below inside the top module select -assert-count 1 t:LDCE select -assert-count 2 t:LUT3 -select -assert-none t:LDCE t:LUT3 %% t:* %D +select -assert-none t:LDCE t:LUT3 t:IBUF t:OBUF %% t:* %D diff --git a/tests/arch/xilinx/logic.ys b/tests/arch/xilinx/logic.ys index d5b5c1a37..2372cca61 100644 --- a/tests/arch/xilinx/logic.ys +++ b/tests/arch/xilinx/logic.ys @@ -8,4 +8,4 @@ cd top # Constrain all select calls below inside the top module select -assert-count 1 t:INV select -assert-count 6 t:LUT2 select -assert-count 2 t:LUT4 -select -assert-none t:INV t:LUT2 t:LUT4 %% t:* %D +select -assert-none t:INV t:LUT2 t:LUT4 t:IBUF t:OBUF %% t:* %D diff --git a/tests/arch/xilinx/lutram.ys b/tests/arch/xilinx/lutram.ys index 6c9d1eae1..951517fa9 100644 --- a/tests/arch/xilinx/lutram.ys +++ b/tests/arch/xilinx/lutram.ys @@ -14,7 +14,7 @@ #select -assert-count 1 t:BUFG #select -assert-count 8 t:FDRE #select -assert-count 8 t:RAM16X1D -#select -assert-none t:BUFG t:FDRE t:RAM16X1D %% t:* %D +#select -assert-none t:BUFG t:FDRE t:RAM16X1D t:IBUF t:OBUF %% t:* %D design -reset @@ -34,7 +34,7 @@ cd lutram_1w1r select -assert-count 1 t:BUFG select -assert-count 8 t:FDRE select -assert-count 8 t:RAM32X1D -select -assert-none t:BUFG t:FDRE t:RAM32X1D %% t:* %D +select -assert-none t:BUFG t:FDRE t:RAM32X1D t:IBUF t:OBUF %% t:* %D design -reset @@ -54,7 +54,7 @@ cd lutram_1w1r select -assert-count 1 t:BUFG select -assert-count 8 t:FDRE select -assert-count 8 t:RAM64X1D -select -assert-none t:BUFG t:FDRE t:RAM64X1D %% t:* %D +select -assert-none t:BUFG t:FDRE t:RAM64X1D t:IBUF t:OBUF %% t:* %D design -reset @@ -74,7 +74,7 @@ cd lutram_1w3r select -assert-count 1 t:BUFG select -assert-count 24 t:FDRE select -assert-count 4 t:RAM32M -select -assert-none t:BUFG t:FDRE t:RAM32M %% t:* %D +select -assert-none t:BUFG t:FDRE t:RAM32M t:IBUF t:OBUF %% t:* %D design -reset @@ -94,7 +94,7 @@ cd lutram_1w3r select -assert-count 1 t:BUFG select -assert-count 24 t:FDRE select -assert-count 8 t:RAM64M -select -assert-none t:BUFG t:FDRE t:RAM64M %% t:* %D +select -assert-none t:BUFG t:FDRE t:RAM64M t:IBUF t:OBUF %% t:* %D design -reset @@ -114,7 +114,7 @@ cd lutram_1w1r select -assert-count 1 t:BUFG select -assert-count 6 t:FDRE select -assert-count 1 t:RAM32M -select -assert-none t:BUFG t:FDRE t:RAM32M %% t:* %D +select -assert-none t:BUFG t:FDRE t:RAM32M t:IBUF t:OBUF %% t:* %D design -reset @@ -134,4 +134,4 @@ cd lutram_1w1r select -assert-count 1 t:BUFG select -assert-count 6 t:FDRE select -assert-count 2 t:RAM64M -select -assert-none t:BUFG t:FDRE t:RAM64M %% t:* %D +select -assert-none t:BUFG t:FDRE t:RAM64M t:IBUF t:OBUF %% t:* %D diff --git a/tests/arch/xilinx/macc.ys b/tests/arch/xilinx/macc.ys index 11e959976..0869a8dae 100644 --- a/tests/arch/xilinx/macc.ys +++ b/tests/arch/xilinx/macc.ys @@ -12,7 +12,7 @@ cd macc # Constrain all select calls below inside the top module select -assert-count 1 t:BUFG select -assert-count 1 t:FDRE select -assert-count 1 t:DSP48E1 -select -assert-none t:BUFG t:FDRE t:DSP48E1 %% t:* %D +select -assert-none t:BUFG t:FDRE t:DSP48E1 t:IBUF t:OBUF %% t:* %D design -load read hierarchy -top macc2 @@ -29,4 +29,4 @@ select -assert-count 1 t:DSP48E1 select -assert-count 1 t:FDRE select -assert-count 1 t:LUT2 select -assert-count 40 t:LUT3 -select -assert-none t:BUFG t:DSP48E1 t:FDRE t:LUT2 t:LUT3 %% t:* %D +select -assert-none t:BUFG t:DSP48E1 t:FDRE t:LUT2 t:LUT3 t:IBUF t:OBUF %% t:* %D diff --git a/tests/arch/xilinx/mul.ys b/tests/arch/xilinx/mul.ys index d76814966..100de6629 100644 --- a/tests/arch/xilinx/mul.ys +++ b/tests/arch/xilinx/mul.ys @@ -6,4 +6,4 @@ design -load postopt # load the post-opt design (otherwise equiv_opt loads the p cd top # Constrain all select calls below inside the top module select -assert-count 1 t:DSP48E1 -select -assert-none t:DSP48E1 %% t:* %D +select -assert-none t:DSP48E1 t:IBUF t:OBUF %% t:* %D diff --git a/tests/arch/xilinx/mul_unsigned.ys b/tests/arch/xilinx/mul_unsigned.ys index 62495b90c..59ead5cda 100644 --- a/tests/arch/xilinx/mul_unsigned.ys +++ b/tests/arch/xilinx/mul_unsigned.ys @@ -8,4 +8,4 @@ cd mul_unsigned # Constrain all select calls below inside the top module select -assert-count 1 t:BUFG select -assert-count 1 t:DSP48E1 select -assert-count 30 t:FDRE -select -assert-none t:DSP48E1 t:FDRE t:BUFG %% t:* %D +select -assert-none t:DSP48E1 t:FDRE t:BUFG t:IBUF t:OBUF %% t:* %D diff --git a/tests/arch/xilinx/mux.ys b/tests/arch/xilinx/mux.ys index 388272449..faad64cc5 100644 --- a/tests/arch/xilinx/mux.ys +++ b/tests/arch/xilinx/mux.ys @@ -8,7 +8,7 @@ design -load postopt # load the post-opt design (otherwise equiv_opt loads the p cd mux2 # Constrain all select calls below inside the top module select -assert-count 1 t:LUT3 -select -assert-none t:LUT3 %% t:* %D +select -assert-none t:LUT3 t:IBUF t:OBUF %% t:* %D design -load read @@ -19,7 +19,7 @@ design -load postopt # load the post-opt design (otherwise equiv_opt loads the p cd mux4 # Constrain all select calls below inside the top module select -assert-count 1 t:LUT6 -select -assert-none t:LUT6 %% t:* %D +select -assert-none t:LUT6 t:IBUF t:OBUF %% t:* %D design -load read @@ -31,7 +31,7 @@ cd mux8 # Constrain all select calls below inside the top module select -assert-count 1 t:LUT3 select -assert-count 2 t:LUT6 -select -assert-none t:LUT3 t:LUT6 %% t:* %D +select -assert-none t:LUT3 t:LUT6 t:IBUF t:OBUF %% t:* %D design -load read @@ -44,4 +44,4 @@ select -assert-min 5 t:LUT6 select -assert-max 7 t:LUT6 select -assert-max 2 t:MUXF7 -select -assert-none t:LUT6 t:MUXF7 %% t:* %D +select -assert-none t:LUT6 t:MUXF7 t:IBUF t:OBUF %% t:* %D diff --git a/tests/arch/xilinx/shifter.ys b/tests/arch/xilinx/shifter.ys index 455437f18..4d63ba9c2 100644 --- a/tests/arch/xilinx/shifter.ys +++ b/tests/arch/xilinx/shifter.ys @@ -8,4 +8,4 @@ cd top # Constrain all select calls below inside the top module select -assert-count 1 t:BUFG select -assert-count 8 t:FDRE -select -assert-none t:BUFG t:FDRE %% t:* %D +select -assert-none t:BUFG t:FDRE t:IBUF t:OBUF %% t:* %D diff --git a/tests/arch/xilinx/tribuf.ys b/tests/arch/xilinx/tribuf.ys index 4697703ca..55e20c37b 100644 --- a/tests/arch/xilinx/tribuf.ys +++ b/tests/arch/xilinx/tribuf.ys @@ -8,5 +8,7 @@ equiv_opt -assert -map +/xilinx/cells_sim.v -map +/simcells.v synth_xilinx # equ 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/arch/xilinx/xilinx_dffopt.ys b/tests/arch/xilinx/xilinx_dffopt.ys index dc036acfd..5dbe11b27 100644 --- a/tests/arch/xilinx/xilinx_dffopt.ys +++ b/tests/arch/xilinx/xilinx_dffopt.ys @@ -28,7 +28,7 @@ clean select -assert-count 1 t:FDRE select -assert-count 1 t:LUT6 select -assert-count 3 t:LUT2 -select -assert-none t:FDRE t:LUT6 t:LUT2 %% t:* %D +select -assert-none t:FDRE t:LUT6 t:LUT2 t:IBUF t:OBUF %% t:* %D design -load t0 @@ -39,7 +39,7 @@ clean select -assert-count 1 t:FDRE select -assert-count 1 t:LUT4 select -assert-count 3 t:LUT2 -select -assert-none t:FDRE t:LUT4 t:LUT2 %% t:* %D +select -assert-none t:FDRE t:LUT4 t:LUT2 t:IBUF t:OBUF %% t:* %D design -reset @@ -74,7 +74,7 @@ clean select -assert-count 1 t:FDSE select -assert-count 1 t:LUT6 select -assert-count 3 t:LUT2 -select -assert-none t:FDSE t:LUT6 t:LUT2 %% t:* %D +select -assert-none t:FDSE t:LUT6 t:LUT2 t:IBUF t:OBUF %% t:* %D design -load t0 @@ -85,7 +85,7 @@ clean select -assert-count 1 t:FDSE select -assert-count 1 t:LUT4 select -assert-count 3 t:LUT2 -select -assert-none t:FDSE t:LUT4 t:LUT2 %% t:* %D +select -assert-none t:FDSE t:LUT4 t:LUT2 t:IBUF t:OBUF %% t:* %D design -reset @@ -120,7 +120,7 @@ clean select -assert-count 1 t:FDCE select -assert-count 1 t:LUT4 select -assert-count 3 t:LUT2 -select -assert-none t:FDCE t:LUT4 t:LUT2 %% t:* %D +select -assert-none t:FDCE t:LUT4 t:LUT2 t:IBUF t:OBUF %% t:* %D design -reset @@ -154,7 +154,7 @@ clean select -assert-count 1 t:FDSE select -assert-count 1 t:LUT5 select -assert-count 2 t:LUT2 -select -assert-none t:FDSE t:LUT5 t:LUT2 %% t:* %D +select -assert-none t:FDSE t:LUT5 t:LUT2 t:IBUF t:OBUF %% t:* %D design -load t0 @@ -164,7 +164,7 @@ clean select -assert-count 1 t:FDSE select -assert-count 2 t:LUT2 -select -assert-none t:FDSE t:LUT2 %% t:* %D +select -assert-none t:FDSE t:LUT2 t:IBUF t:OBUF %% t:* %D design -reset @@ -200,7 +200,7 @@ clean select -assert-count 1 t:FDRSE select -assert-count 1 t:LUT6 select -assert-count 4 t:LUT2 -select -assert-none t:FDRSE t:LUT6 t:LUT2 %% t:* %D +select -assert-none t:FDRSE t:LUT6 t:LUT2 t:IBUF t:OBUF %% t:* %D design -load t0 @@ -211,6 +211,6 @@ clean select -assert-count 1 t:FDRSE select -assert-count 1 t:LUT4 select -assert-count 4 t:LUT2 -select -assert-none t:FDRSE t:LUT4 t:LUT2 %% t:* %D +select -assert-none t:FDRSE t:LUT4 t:LUT2 t:IBUF t:OBUF %% t:* %D design -reset -- cgit v1.2.3 From 1937091f622a37d8050e5cc1e7c486707fd90b2f Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Sat, 21 Dec 2019 13:21:45 +0100 Subject: iopad no op for compatibility with old scripts --- techlibs/xilinx/synth_xilinx.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index 006679eb1..c66e1d750 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -208,6 +208,9 @@ struct SynthXilinxPass : public ScriptPass ise = true; continue; } + if (args[argidx] == "-iopad") { + continue; + } if (args[argidx] == "-noiopad") { noiopad = true; continue; -- cgit v1.2.3 From 436fea9e6990c66369d7c30b571920ae115efb44 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Sat, 21 Dec 2019 20:23:23 +0100 Subject: Addressed review comments --- techlibs/xilinx/synth_xilinx.cc | 5 +++-- tests/arch/xilinx/tribuf.ys | 1 - 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index c66e1d750..90ab688e5 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -85,7 +85,8 @@ struct SynthXilinxPass : public ScriptPass log(" do not use DSP48E1s to implement multipliers and associated logic\n"); log("\n"); log(" -noiopad\n"); - log(" disable I/O buffer insertion\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"); @@ -210,7 +211,7 @@ struct SynthXilinxPass : public ScriptPass } if (args[argidx] == "-iopad") { continue; - } + } if (args[argidx] == "-noiopad") { noiopad = true; continue; diff --git a/tests/arch/xilinx/tribuf.ys b/tests/arch/xilinx/tribuf.ys index 55e20c37b..eaccab126 100644 --- a/tests/arch/xilinx/tribuf.ys +++ b/tests/arch/xilinx/tribuf.ys @@ -7,7 +7,6 @@ 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 2 t:IBUF select -assert-count 1 t:INV select -assert-count 1 t:OBUFT -- cgit v1.2.3 From 666c6128a90de588ab26c876a257ea48edfded30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20Ko=C5=9Bcielnicki?= Date: Sun, 22 Dec 2019 20:43:39 +0100 Subject: xilinx_dsp: Initial DSP48A/DSP48A1 support. --- passes/pmgen/Makefile.inc | 3 +- passes/pmgen/xilinx_dsp.cc | 212 +++++++++++- passes/pmgen/xilinx_dsp48a.pmg | 673 ++++++++++++++++++++++++++++++++++++++ passes/pmgen/xilinx_dsp_CREG.pmg | 9 +- techlibs/xilinx/synth_xilinx.cc | 5 +- techlibs/xilinx/xc3sda_dsp_map.v | 2 +- techlibs/xilinx/xc6s_dsp_map.v | 2 +- tests/arch/xilinx/macc.sh | 3 + tests/arch/xilinx/mul.ys | 12 + tests/arch/xilinx/mul_unsigned.ys | 14 + 10 files changed, 921 insertions(+), 14 deletions(-) create mode 100644 passes/pmgen/xilinx_dsp48a.pmg diff --git a/passes/pmgen/Makefile.inc b/passes/pmgen/Makefile.inc index 145d2ebf9..1a57bef7d 100644 --- a/passes/pmgen/Makefile.inc +++ b/passes/pmgen/Makefile.inc @@ -22,8 +22,9 @@ $(eval $(call add_extra_objs,passes/pmgen/ice40_wrapcarry_pm.h)) # -------------------------------------- OBJS += passes/pmgen/xilinx_dsp.o -passes/pmgen/xilinx_dsp.o: passes/pmgen/xilinx_dsp_pm.h passes/pmgen/xilinx_dsp_CREG_pm.h passes/pmgen/xilinx_dsp_cascade_pm.h +passes/pmgen/xilinx_dsp.o: passes/pmgen/xilinx_dsp_pm.h passes/pmgen/xilinx_dsp48a_pm.h passes/pmgen/xilinx_dsp_CREG_pm.h passes/pmgen/xilinx_dsp_cascade_pm.h $(eval $(call add_extra_objs,passes/pmgen/xilinx_dsp_pm.h)) +$(eval $(call add_extra_objs,passes/pmgen/xilinx_dsp48a_pm.h)) $(eval $(call add_extra_objs,passes/pmgen/xilinx_dsp_CREG_pm.h)) $(eval $(call add_extra_objs,passes/pmgen/xilinx_dsp_cascade_pm.h)) diff --git a/passes/pmgen/xilinx_dsp.cc b/passes/pmgen/xilinx_dsp.cc index 054e123e4..81c3c57c4 100644 --- a/passes/pmgen/xilinx_dsp.cc +++ b/passes/pmgen/xilinx_dsp.cc @@ -26,6 +26,7 @@ USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN #include "passes/pmgen/xilinx_dsp_pm.h" +#include "passes/pmgen/xilinx_dsp48a_pm.h" #include "passes/pmgen/xilinx_dsp_CREG_pm.h" #include "passes/pmgen/xilinx_dsp_cascade_pm.h" @@ -487,6 +488,190 @@ void xilinx_dsp_pack(xilinx_dsp_pm &pm) pm.blacklist(cell); } +void xilinx_dsp48a_pack(xilinx_dsp48a_pm &pm) +{ + auto &st = pm.st_xilinx_dsp48a_pack; + + log("Analysing %s.%s for Xilinx DSP48A/DSP48A1 packing.\n", log_id(pm.module), log_id(st.dsp)); + + log_debug("preAdd: %s\n", log_id(st.preAdd, "--")); + log_debug("ffA1: %s %s %s\n", log_id(st.ffA1, "--"), log_id(st.ffA1cemux, "--"), log_id(st.ffA1rstmux, "--")); + log_debug("ffA0: %s %s %s\n", log_id(st.ffA0, "--"), log_id(st.ffA0cemux, "--"), log_id(st.ffA0rstmux, "--")); + log_debug("ffB1: %s %s %s\n", log_id(st.ffB1, "--"), log_id(st.ffB1cemux, "--"), log_id(st.ffB1rstmux, "--")); + log_debug("ffB0: %s %s %s\n", log_id(st.ffB0, "--"), log_id(st.ffB0cemux, "--"), log_id(st.ffB0rstmux, "--")); + log_debug("ffD: %s %s %s\n", log_id(st.ffD, "--"), log_id(st.ffDcemux, "--"), log_id(st.ffDrstmux, "--")); + log_debug("dsp: %s\n", log_id(st.dsp, "--")); + log_debug("ffM: %s %s %s\n", log_id(st.ffM, "--"), log_id(st.ffMcemux, "--"), log_id(st.ffMrstmux, "--")); + log_debug("postAdd: %s\n", log_id(st.postAdd, "--")); + log_debug("postAddMux: %s\n", log_id(st.postAddMux, "--")); + log_debug("ffP: %s %s %s\n", log_id(st.ffP, "--"), log_id(st.ffPcemux, "--"), log_id(st.ffPrstmux, "--")); + + Cell *cell = st.dsp; + SigSpec &opmode = cell->connections_.at(ID(OPMODE)); + + if (st.preAdd) { + log(" preadder %s (%s)\n", log_id(st.preAdd), log_id(st.preAdd->type)); + bool D_SIGNED = st.preAdd->getParam(ID(A_SIGNED)).as_bool(); + bool B_SIGNED = st.preAdd->getParam(ID(B_SIGNED)).as_bool(); + st.sigB.extend_u0(18, B_SIGNED); + st.sigD.extend_u0(18, D_SIGNED); + cell->setPort(ID(B), st.sigB); + cell->setPort(ID(D), st.sigD); + opmode[4] = State::S1; + if (st.preAdd->type == ID($add)) + opmode[6] = State::S0; + else if (st.preAdd->type == ID($sub)) + opmode[6] = State::S1; + else + log_assert(!"strange pre-adder type"); + + pm.autoremove(st.preAdd); + } + if (st.postAdd) { + log(" postadder %s (%s)\n", log_id(st.postAdd), log_id(st.postAdd->type)); + + if (st.postAddMux) { + log_assert(st.ffP); + opmode[2] = st.postAddMux->getPort(ID(S)); + pm.autoremove(st.postAddMux); + } + else if (st.ffP && st.sigC == st.sigP) + opmode[2] = State::S0; + else + opmode[2] = State::S1; + opmode[3] = State::S1; + + if (opmode[2] != State::S0) { + if (st.postAddMuxAB == ID(A)) + st.sigC.extend_u0(48, st.postAdd->getParam(ID(B_SIGNED)).as_bool()); + else + st.sigC.extend_u0(48, st.postAdd->getParam(ID(A_SIGNED)).as_bool()); + cell->setPort(ID(C), st.sigC); + } + + pm.autoremove(st.postAdd); + } + + if (st.clock != SigBit()) + { + cell->setPort(ID(CLK), st.clock); + + auto f = [&pm,cell](SigSpec &A, Cell* ff, Cell* cemux, bool cepol, IdString ceport, Cell* rstmux, bool rstpol, IdString rstport) { + SigSpec D = ff->getPort(ID(D)); + SigSpec Q = pm.sigmap(ff->getPort(ID(Q))); + if (!A.empty()) + A.replace(Q, D); + if (rstmux) { + SigSpec Y = rstmux->getPort(ID(Y)); + SigSpec AB = rstmux->getPort(rstpol ? ID(A) : ID(B)); + if (!A.empty()) + A.replace(Y, AB); + if (rstport != IdString()) { + SigSpec S = rstmux->getPort(ID(S)); + cell->setPort(rstport, rstpol ? S : pm.module->Not(NEW_ID, S)); + } + } + else if (rstport != IdString()) + cell->setPort(rstport, State::S0); + if (cemux) { + SigSpec Y = cemux->getPort(ID(Y)); + SigSpec BA = cemux->getPort(cepol ? ID(B) : ID(A)); + SigSpec S = cemux->getPort(ID(S)); + if (!A.empty()) + A.replace(Y, BA); + cell->setPort(ceport, cepol ? S : pm.module->Not(NEW_ID, S)); + } + else + cell->setPort(ceport, State::S1); + + for (auto c : Q.chunks()) { + auto it = c.wire->attributes.find(ID(init)); + if (it == c.wire->attributes.end()) + continue; + for (int i = c.offset; i < c.offset+c.width; i++) { + log_assert(it->second[i] == State::S0 || it->second[i] == State::Sx); + it->second[i] = State::Sx; + } + } + }; + + if (st.ffA0 || st.ffA1) { + SigSpec A = cell->getPort(ID(A)); + if (st.ffA1) { + f(A, st.ffA1, st.ffA1cemux, st.ffAcepol, ID(CEA), st.ffA1rstmux, st.ffArstpol, ID(RSTA)); + cell->setParam(ID(A1REG), 1); + } + if (st.ffA0) { + f(A, st.ffA0, st.ffA0cemux, st.ffAcepol, ID(CEA), st.ffA0rstmux, st.ffArstpol, ID(RSTA)); + cell->setParam(ID(A0REG), 1); + } + pm.add_siguser(A, cell); + cell->setPort(ID(A), A); + } + if (st.ffB0 || st.ffB1) { + SigSpec B = cell->getPort(ID(B)); + if (st.ffB1) { + f(B, st.ffB1, st.ffB1cemux, st.ffBcepol, ID(CEB), st.ffB1rstmux, st.ffBrstpol, ID(RSTB)); + cell->setParam(ID(B1REG), 1); + } + if (st.ffB0) { + f(B, st.ffB0, st.ffB0cemux, st.ffBcepol, ID(CEB), st.ffB0rstmux, st.ffBrstpol, ID(RSTB)); + cell->setParam(ID(B0REG), 1); + } + pm.add_siguser(B, cell); + cell->setPort(ID(B), B); + } + if (st.ffD) { + SigSpec D = cell->getPort(ID(D)); + f(D, st.ffD, st.ffDcemux, st.ffDcepol, ID(CED), st.ffDrstmux, st.ffDrstpol, ID(RSTD)); + pm.add_siguser(D, cell); + cell->setPort(ID(D), D); + cell->setParam(ID(DREG), 1); + } + if (st.ffM) { + SigSpec M; // unused + f(M, st.ffM, st.ffMcemux, st.ffMcepol, ID(CEM), st.ffMrstmux, st.ffMrstpol, ID(RSTM)); + st.ffM->connections_.at(ID(Q)).replace(st.sigM, pm.module->addWire(NEW_ID, GetSize(st.sigM))); + cell->setParam(ID(MREG), State::S1); + } + if (st.ffP) { + SigSpec P; // unused + f(P, st.ffP, st.ffPcemux, st.ffPcepol, ID(CEP), st.ffPrstmux, st.ffPrstpol, ID(RSTP)); + st.ffP->connections_.at(ID(Q)).replace(st.sigP, pm.module->addWire(NEW_ID, GetSize(st.sigP))); + cell->setParam(ID(PREG), State::S1); + } + + log(" clock: %s (%s)", log_signal(st.clock), "posedge"); + + if (st.ffA0) + log(" ffA0:%s", log_id(st.ffA0)); + if (st.ffA1) + log(" ffA1:%s", log_id(st.ffA1)); + + if (st.ffB0) + log(" ffB0:%s", log_id(st.ffB0)); + if (st.ffB1) + log(" ffB1:%s", log_id(st.ffB1)); + + if (st.ffD) + log(" ffD:%s", log_id(st.ffD)); + + if (st.ffM) + log(" ffM:%s", log_id(st.ffM)); + + if (st.ffP) + log(" ffP:%s", log_id(st.ffP)); + } + log("\n"); + + SigSpec P = st.sigP; + if (GetSize(P) < 48) + P.append(pm.module->addWire(NEW_ID, 48-GetSize(P))); + cell->setPort(ID(P), P); + + pm.blacklist(cell); +} + void xilinx_dsp_packC(xilinx_dsp_CREG_pm &pm) { auto &st = pm.st_xilinx_dsp_packC; @@ -592,33 +777,48 @@ struct XilinxDspPass : public Pass { log("P output implementing the operation \"(P >= )\" will be transformed\n"); log("into using the DSP48E1's pattern detector feature for overflow detection.\n"); log("\n"); + log(" -family {xcup|xcu|xc7|xc6v|xc5v|xc4v|xc6s|xc3sda}\n"); + log(" select the family to target\n"); + log(" default: xc7\n"); + log("\n"); } void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE { log_header(design, "Executing XILINX_DSP pass (pack resources into DSPs).\n"); + std::string family = "xc7"; size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) { - // if (args[argidx] == "-singleton") { - // singleton_mode = true; - // continue; - // } + if ((args[argidx] == "-family" || args[argidx] == "-arch") && argidx+1 < args.size()) { + family = args[++argidx]; + continue; + } break; } extra_args(args, argidx, design); + // Don't bother distinguishing between those. + if (family == "xc6v") + family = "xc7"; + if (family == "xcup") + family = "xcu"; + for (auto module : design->selected_modules()) { // Experimental feature: pack $add/$sub cells with // (* use_dsp48="simd" *) into DSP48E1's using its // SIMD feature - xilinx_simd_pack(module, module->selected_cells()); + if (family == "xc7") + xilinx_simd_pack(module, module->selected_cells()); // Match for all features ([ABDMP][12]?REG, pre-adder, // post-adder, pattern detector, etc.) except for CREG - { + if (family == "xc7") { xilinx_dsp_pm pm(module, module->selected_cells()); pm.run_xilinx_dsp_pack(xilinx_dsp_pack); + } else if (family == "xc6s" || family == "xc3sda") { + xilinx_dsp48a_pm pm(module, module->selected_cells()); + pm.run_xilinx_dsp48a_pack(xilinx_dsp48a_pack); } // Separating out CREG packing is necessary since there // is no guarantee that the cell ordering corresponds diff --git a/passes/pmgen/xilinx_dsp48a.pmg b/passes/pmgen/xilinx_dsp48a.pmg new file mode 100644 index 000000000..97d5c5ccd --- /dev/null +++ b/passes/pmgen/xilinx_dsp48a.pmg @@ -0,0 +1,673 @@ +// This file describes the main pattern matcher setup (of three total) that +// forms the `xilinx_dsp` pass described in xilinx_dsp.cc — version for +// DSP48A/DSP48A1 (Spartan 3A DSP, Spartan 6). +// At a high level, it works as follows: +// ( 1) Starting from a DSP48A/DSP48A1 cell +// ( 2) Match the driver of the 'B' input to a possible $dff cell (B1REG) +// (attached to at most two $mux cells that implement clock-enable or +// reset functionality, using a subpattern discussed below) +// If B1REG matched, treat 'B' input as input of B1REG +// ( 3) Match the driver of the 'B' and 'D' inputs for a possible $add cell +// (pre-adder) +// ( 4) Match 'B' input for B0REG +// ( 5) Match 'A' input for A1REG +// If A1REG, then match 'A' input for A0REG +// ( 6) Match 'D' input for DREG +// ( 7) Match 'P' output that exclusively drives an MREG +// ( 8) Match 'P' output that exclusively drives one of two inputs to an $add +// cell (post-adder). +// The other input to the adder is assumed to come in from the 'C' input +// (note: 'P' -> 'C' connections that exist for accumulators are +// recognised in xilinx_dsp.cc). +// ( 9) Match 'P' output that exclusively drives a PREG +// (10) If post-adder and PREG both present, match for a $mux cell driving +// the 'C' input, where one of the $mux's inputs is the PREG output. +// This indicates an accumulator situation, and one where a $mux exists +// to override the accumulated value: +// +--------------------------------+ +// | ____ | +// +--| \ | +// |$mux|-+ | +// 'C' ---|____/ | | +// | /-------\ +----+ | +// +----+ +-| post- |___|PREG|---+ 'P' +// |MREG|------ | adder | +----+ +// +----+ \-------/ +// Notes: see the notes in xilinx_dsp.pmg + +pattern xilinx_dsp48a_pack + +state clock +state sigA sigB sigC sigD sigM sigP +state postAddAB postAddMuxAB +state ffAcepol ffBcepol ffDcepol ffMcepol ffPcepol +state ffArstpol ffBrstpol ffDrstpol ffMrstpol ffPrstpol +state ffA0 ffA0cemux ffA0rstmux ffA1 ffA1cemux ffA1rstmux +state ffB0 ffB0cemux ffB0rstmux ffB1 ffB1cemux ffB1rstmux +state ffD ffDcemux ffDrstmux ffM ffMcemux ffMrstmux ffP ffPcemux ffPrstmux + +// Variables used for subpatterns +state argQ argD +state ffcepol ffrstpol +state ffoffset +udata dffD dffQ +udata dffclock +udata dff dffcemux dffrstmux +udata dffcepol dffrstpol + +// (1) Starting from a DSP48A/DSP48A1 cell +match dsp + select dsp->type.in(\DSP48A, \DSP48A1) +endmatch + +code sigA sigB sigC sigD sigM clock + auto unextend = [](const SigSpec &sig) { + int i; + for (i = GetSize(sig)-1; i > 0; i--) + if (sig[i] != sig[i-1]) + break; + // Do not remove non-const sign bit + if (sig[i].wire) + ++i; + return sig.extract(0, i); + }; + sigA = unextend(port(dsp, \A)); + sigB = unextend(port(dsp, \B)); + + sigC = port(dsp, \C, SigSpec()); + sigD = port(dsp, \D, SigSpec()); + + SigSpec P = port(dsp, \P); + // Only care about those bits that are used + int i; + for (i = GetSize(P)-1; i >= 0; i--) + if (nusers(P[i]) > 1) + break; + i++; + log_assert(nusers(P.extract_end(i)) <= 1); + // This sigM could have no users if downstream sinks (e.g. $add) is + // narrower than $mul result, for example + if (i == 0) + reject; + sigM = P.extract(0, i); + + clock = port(dsp, \CLK, SigBit()); +endcode + +// (2) Match the driver of the 'B' input to a possible $dff cell (B1REG) +// (attached to at most two $mux cells that implement clock-enable or +// reset functionality, using a subpattern discussed above) +// If matched, treat 'B' input as input of B1REG +code argQ ffB1 ffB1cemux ffB1rstmux ffBcepol ffBrstpol sigB clock + if (param(dsp, \B1REG).as_int() == 0 && param(dsp, \B0REG).as_int() == 0 && port(dsp, \OPMODE, SigSpec()).extract(4, 1).is_fully_zero()) { + argQ = sigB; + subpattern(in_dffe); + if (dff) { + ffB1 = dff; + clock = dffclock; + if (dffrstmux) { + ffB1rstmux = dffrstmux; + ffBrstpol = dffrstpol; + } + if (dffcemux) { + ffB1cemux = dffcemux; + ffBcepol = dffcepol; + } + sigB = dffD; + } + } +endcode + +// (3) Match the driver of the 'B' and 'D' inputs for a possible $add cell +// (pre-adder) +match preAdd + if sigD.empty() || sigD.is_fully_zero() + if param(dsp, \B0REG).as_int() == 0 + // Ensure that preAdder not already used + if port(dsp, \OPMODE, SigSpec()).extract(4, 1).is_fully_zero() + + select preAdd->type.in($add, $sub) + // Output has to be 18 bits or less + select GetSize(port(preAdd, \Y)) <= 18 + select nusers(port(preAdd, \Y)) == 2 + // D port has to be 18 bits or less + select GetSize(port(preAdd, \A)) <= 18 + // B port has to be 18 bits or less + select GetSize(port(preAdd, \B)) <= 18 + index port(preAdd, \Y) === sigB + + optional +endmatch + +code sigB sigD + if (preAdd) { + sigD = port(preAdd, \A); + sigB = port(preAdd, \B); + } +endcode + +// (4) Match 'B' input for B0REG +code argQ ffB0 ffB0cemux ffB0rstmux ffBcepol ffBrstpol sigB clock + if (param(dsp, \B0REG).as_int() == 0) { + argQ = sigB; + subpattern(in_dffe); + if (dff) { + if (ffB1) { + if ((ffB1rstmux != nullptr) ^ (dffrstmux != nullptr)) + goto ffB0_end; + if ((ffB1cemux != nullptr) ^ (dffcemux != nullptr)) + goto ffB0_end; + if (dffrstmux) { + if (ffBrstpol != dffrstpol) + goto ffB0_end; + if (port(ffB1rstmux, \S) != port(dffrstmux, \S)) + goto ffB0_end; + ffB0rstmux = dffrstmux; + } + if (dffcemux) { + if (ffBcepol != dffcepol) + goto ffB0_end; + if (port(ffB1cemux, \S) != port(dffcemux, \S)) + goto ffB0_end; + ffB0cemux = dffcemux; + } + } + ffB0 = dff; + clock = dffclock; + if (dffrstmux) { + ffB0rstmux = dffrstmux; + ffBrstpol = dffrstpol; + } + if (dffcemux) { + ffB0cemux = dffcemux; + ffBcepol = dffcepol; + } + sigB = dffD; + } + } +ffB0_end: +endcode + +// (5) Match 'A' input for A1REG +// If A1REG, then match 'A' input for A0REG +code argQ ffA1 ffA1cemux ffA1rstmux ffAcepol ffArstpol sigA clock ffA0 ffA0cemux ffA0rstmux + if (param(dsp, \A0REG).as_int() == 0 && param(dsp, \A1REG).as_int() == 0) { + argQ = sigA; + subpattern(in_dffe); + if (dff) { + ffA1 = dff; + clock = dffclock; + if (dffrstmux) { + ffA1rstmux = dffrstmux; + ffArstpol = dffrstpol; + } + if (dffcemux) { + ffA1cemux = dffcemux; + ffAcepol = dffcepol; + } + sigA = dffD; + + // Now attempt to match A0 + if (ffA1) { + argQ = sigA; + subpattern(in_dffe); + if (dff) { + if ((ffA1rstmux != nullptr) ^ (dffrstmux != nullptr)) + goto ffA0_end; + if ((ffA1cemux != nullptr) ^ (dffcemux != nullptr)) + goto ffA0_end; + if (dffrstmux) { + if (ffArstpol != dffrstpol) + goto ffA0_end; + if (port(ffA1rstmux, \S) != port(dffrstmux, \S)) + goto ffA0_end; + ffA0rstmux = dffrstmux; + } + if (dffcemux) { + if (ffAcepol != dffcepol) + goto ffA0_end; + if (port(ffA1cemux, \S) != port(dffcemux, \S)) + goto ffA0_end; + ffA0cemux = dffcemux; + } + + ffA0 = dff; + clock = dffclock; + + if (dffcemux) { + ffA0cemux = dffcemux; + ffAcepol = dffcepol; + } + sigA = dffD; + +ffA0_end: ; + } + } + + } + } +endcode + +// (6) Match 'D' input for DREG +code argQ ffD ffDcemux ffDrstmux ffDcepol ffDrstpol sigD clock + if (param(dsp, \DREG).as_int() == 0) { + argQ = sigD; + subpattern(in_dffe); + if (dff) { + ffD = dff; + clock = dffclock; + if (dffrstmux) { + ffDrstmux = dffrstmux; + ffDrstpol = dffrstpol; + } + if (dffcemux) { + ffDcemux = dffcemux; + ffDcepol = dffcepol; + } + sigD = dffD; + } + } +endcode + +// (7) Match 'P' output that exclusively drives an MREG +code argD ffM ffMcemux ffMrstmux ffMcepol ffMrstpol sigM sigP clock + if (param(dsp, \MREG).as_int() == 0 && nusers(sigM) == 2) { + argD = sigM; + subpattern(out_dffe); + if (dff) { + ffM = dff; + clock = dffclock; + if (dffrstmux) { + ffMrstmux = dffrstmux; + ffMrstpol = dffrstpol; + } + if (dffcemux) { + ffMcemux = dffcemux; + ffMcepol = dffcepol; + } + sigM = dffQ; + } + } + sigP = sigM; +endcode + +// (8) Match 'P' output that exclusively drives one of two inputs to an $add +// cell (post-adder). +// The other input to the adder is assumed to come in from the 'C' input +// (note: 'P' -> 'C' connections that exist for accumulators are +// recognised in xilinx_dsp.cc). +match postAdd + // Ensure that Z mux is not already used + if port(dsp, \OPMODE, SigSpec()).extract(2,2).is_fully_zero() + + select postAdd->type.in($add) + select GetSize(port(postAdd, \Y)) <= 48 + choice AB {\A, \B} + select nusers(port(postAdd, AB)) <= 3 + filter ffMcemux || nusers(port(postAdd, AB)) == 2 + filter !ffMcemux || nusers(port(postAdd, AB)) == 3 + + index port(postAdd, AB)[0] === sigP[0] + filter GetSize(port(postAdd, AB)) >= GetSize(sigP) + filter port(postAdd, AB).extract(0, GetSize(sigP)) == sigP + // Check that remainder of AB is a sign- or zero-extension + filter port(postAdd, AB).extract_end(GetSize(sigP)) == SigSpec(sigP[GetSize(sigP)-1], GetSize(port(postAdd, AB))-GetSize(sigP)) || port(postAdd, AB).extract_end(GetSize(sigP)) == SigSpec(State::S0, GetSize(port(postAdd, AB))-GetSize(sigP)) + + set postAddAB AB + optional +endmatch + +code sigC sigP + if (postAdd) { + sigC = port(postAdd, postAddAB == \A ? \B : \A); + sigP = port(postAdd, \Y); + } +endcode + +// (9) Match 'P' output that exclusively drives a PREG +code argD ffP ffPcemux ffPrstmux ffPcepol ffPrstpol sigP clock + if (param(dsp, \PREG).as_int() == 0) { + int users = 2; + // If ffMcemux and no postAdd new-value net must have three users: ffMcemux, ffM and ffPcemux + if (ffMcemux && !postAdd) users++; + if (nusers(sigP) == users) { + argD = sigP; + subpattern(out_dffe); + if (dff) { + ffP = dff; + clock = dffclock; + if (dffrstmux) { + ffPrstmux = dffrstmux; + ffPrstpol = dffrstpol; + } + if (dffcemux) { + ffPcemux = dffcemux; + ffPcepol = dffcepol; + } + sigP = dffQ; + } + } + } +endcode + +// (10) If post-adder and PREG both present, match for a $mux cell driving +// the 'C' input, where one of the $mux's inputs is the PREG output. +// This indicates an accumulator situation, and one where a $mux exists +// to override the accumulated value: +// +--------------------------------+ +// | ____ | +// +--| \ | +// |$mux|-+ | +// 'C' ---|____/ | | +// | /-------\ +----+ | +// +----+ +-| post- |___|PREG|---+ 'P' +// |MREG|------ | adder | +----+ +// +----+ \-------/ +match postAddMux + if postAdd + if ffP + select postAddMux->type.in($mux) + select nusers(port(postAddMux, \Y)) == 2 + choice AB {\A, \B} + index port(postAddMux, AB) === sigP + index port(postAddMux, \Y) === sigC + set postAddMuxAB AB + optional +endmatch + +code sigC + if (postAddMux) + sigC = port(postAddMux, postAddMuxAB == \A ? \B : \A); +endcode + +code + accept; +endcode + +// ####################### + +// Subpattern for matching against input registers, based on knowledge of the +// 'Q' input. Typically, identifying registers with clock-enable and reset +// capability would be a task would be handled by other Yosys passes such as +// dff2dffe, but since DSP inference happens much before this, these patterns +// have to be manually identified. +// At a high level: +// (1) Starting from a $dff cell that (partially or fully) drives the given +// 'Q' argument +// (2) Match for a $mux cell implementing synchronous reset semantics --- +// one that exclusively drives the 'D' input of the $dff, with one of its +// $mux inputs being fully zero +// (3) Match for a $mux cell implement clock enable semantics --- one that +// exclusively drives the 'D' input of the $dff (or the other input of +// the reset $mux) and where one of this $mux's inputs is connected to +// the 'Q' output of the $dff +subpattern in_dffe +arg argD argQ clock + +code + dff = nullptr; + if (GetSize(argQ) == 0) + reject; + for (const auto &c : argQ.chunks()) { + // Abandon matches when 'Q' is a constant + if (!c.wire) + reject; + // Abandon matches when 'Q' has the keep attribute set + if (c.wire->get_bool_attribute(\keep)) + reject; + // Abandon matches when 'Q' has a non-zero init attribute set + // (not supported by DSP48E1) + Const init = c.wire->attributes.at(\init, Const()); + if (!init.empty()) + for (auto b : init.extract(c.offset, c.width)) + if (b != State::Sx && b != State::S0) + reject; + } +endcode + +// (1) Starting from a $dff cell that (partially or fully) drives the given +// 'Q' argument +match ff + select ff->type.in($dff) + // DSP48E1 does not support clock inversion + select param(ff, \CLK_POLARITY).as_bool() + + slice offset GetSize(port(ff, \D)) + index port(ff, \Q)[offset] === argQ[0] + + // Check that the rest of argQ is present + filter GetSize(port(ff, \Q)) >= offset + GetSize(argQ) + filter port(ff, \Q).extract(offset, GetSize(argQ)) == argQ + + filter clock == SigBit() || port(ff, \CLK) == clock + + set ffoffset offset +endmatch + +code argQ argD + SigSpec Q = port(ff, \Q); + dff = ff; + dffclock = port(ff, \CLK); + dffD = argQ; + argD = port(ff, \D); + argQ = Q; + dffD.replace(argQ, argD); + // Only search for ffrstmux if dffD only + // has two (ff, ffrstmux) users + if (nusers(dffD) > 2) + argD = SigSpec(); +endcode + +// (2) Match for a $mux cell implementing synchronous reset semantics --- +// exclusively drives the 'D' input of the $dff, with one of the $mux +// inputs being fully zero +match ffrstmux + if !argD.empty() + select ffrstmux->type.in($mux) + index port(ffrstmux, \Y) === argD + + choice BA {\B, \A} + // DSP48E1 only supports reset to zero + select port(ffrstmux, BA).is_fully_zero() + + define pol (BA == \B) + set ffrstpol pol + semioptional +endmatch + +code argD + if (ffrstmux) { + dffrstmux = ffrstmux; + dffrstpol = ffrstpol; + argD = port(ffrstmux, ffrstpol ? \A : \B); + dffD.replace(port(ffrstmux, \Y), argD); + + // Only search for ffcemux if argQ has at + // least 3 users (ff, , ffrstmux) and + // dffD only has two (ff, ffrstmux) + if (!(nusers(argQ) >= 3 && nusers(dffD) == 2)) + argD = SigSpec(); + } + else + dffrstmux = nullptr; +endcode + +// (3) Match for a $mux cell implement clock enable semantics --- one that +// exclusively drives the 'D' input of the $dff (or the other input of +// the reset $mux) and where one of this $mux's inputs is connected to +// the 'Q' output of the $dff +match ffcemux + if !argD.empty() + select ffcemux->type.in($mux) + index port(ffcemux, \Y) === argD + choice AB {\A, \B} + index port(ffcemux, AB) === argQ + define pol (AB == \A) + set ffcepol pol + semioptional +endmatch + +code argD + if (ffcemux) { + dffcemux = ffcemux; + dffcepol = ffcepol; + argD = port(ffcemux, ffcepol ? \B : \A); + dffD.replace(port(ffcemux, \Y), argD); + } + else + dffcemux = nullptr; +endcode + +// ####################### + +// Subpattern for matching against output registers, based on knowledge of the +// 'D' input. +// At a high level: +// (1) Starting from an optional $mux cell that implements clock enable +// semantics --- one where the given 'D' argument (partially or fully) +// drives one of its two inputs +// (2) Starting from, or continuing onto, another optional $mux cell that +// implements synchronous reset semantics --- one where the given 'D' +// argument (or the clock enable $mux output) drives one of its two inputs +// and where the other input is fully zero +// (3) Match for a $dff cell (whose 'D' input is the 'D' argument, or the +// output of the previous clock enable or reset $mux cells) +subpattern out_dffe +arg argD argQ clock + +code + dff = nullptr; + for (auto c : argD.chunks()) + // Abandon matches when 'D' has the keep attribute set + if (c.wire->get_bool_attribute(\keep)) + reject; +endcode + +// (1) Starting from an optional $mux cell that implements clock enable +// semantics --- one where the given 'D' argument (partially or fully) +// drives one of its two inputs +match ffcemux + select ffcemux->type.in($mux) + // ffcemux output must have two users: ffcemux and ff.D + select nusers(port(ffcemux, \Y)) == 2 + + choice AB {\A, \B} + // keep-last-value net must have at least three users: ffcemux, ff, downstream sink(s) + select nusers(port(ffcemux, AB)) >= 3 + + slice offset GetSize(port(ffcemux, \Y)) + define BA (AB == \A ? \B : \A) + index port(ffcemux, BA)[offset] === argD[0] + + // Check that the rest of argD is present + filter GetSize(port(ffcemux, BA)) >= offset + GetSize(argD) + filter port(ffcemux, BA).extract(offset, GetSize(argD)) == argD + + set ffoffset offset + define pol (AB == \A) + set ffcepol pol + + semioptional +endmatch + +code argD argQ + dffcemux = ffcemux; + if (ffcemux) { + SigSpec BA = port(ffcemux, ffcepol ? \B : \A); + SigSpec Y = port(ffcemux, \Y); + argQ = argD; + argD.replace(BA, Y); + argQ.replace(BA, port(ffcemux, ffcepol ? \A : \B)); + + dffcemux = ffcemux; + dffcepol = ffcepol; + } +endcode + +// (2) Starting from, or continuing onto, another optional $mux cell that +// implements synchronous reset semantics --- one where the given 'D' +// argument (or the clock enable $mux output) drives one of its two inputs +// and where the other input is fully zero +match ffrstmux + select ffrstmux->type.in($mux) + // ffrstmux output must have two users: ffrstmux and ff.D + select nusers(port(ffrstmux, \Y)) == 2 + + choice BA {\B, \A} + // DSP48E1 only supports reset to zero + select port(ffrstmux, BA).is_fully_zero() + + slice offset GetSize(port(ffrstmux, \Y)) + define AB (BA == \B ? \A : \B) + index port(ffrstmux, AB)[offset] === argD[0] + + // Check that offset is consistent + filter !ffcemux || ffoffset == offset + // Check that the rest of argD is present + filter GetSize(port(ffrstmux, AB)) >= offset + GetSize(argD) + filter port(ffrstmux, AB).extract(offset, GetSize(argD)) == argD + + set ffoffset offset + define pol (AB == \A) + set ffrstpol pol + + semioptional +endmatch + +code argD argQ + dffrstmux = ffrstmux; + if (ffrstmux) { + SigSpec AB = port(ffrstmux, ffrstpol ? \A : \B); + SigSpec Y = port(ffrstmux, \Y); + argD.replace(AB, Y); + + dffrstmux = ffrstmux; + dffrstpol = ffrstpol; + } +endcode + +// (3) Match for a $dff cell (whose 'D' input is the 'D' argument, or the +// output of the previous clock enable or reset $mux cells) +match ff + select ff->type.in($dff) + // DSP48E1 does not support clock inversion + select param(ff, \CLK_POLARITY).as_bool() + + slice offset GetSize(port(ff, \D)) + index port(ff, \D)[offset] === argD[0] + + // Check that offset is consistent + filter (!ffcemux && !ffrstmux) || ffoffset == offset + // Check that the rest of argD is present + filter GetSize(port(ff, \D)) >= offset + GetSize(argD) + filter port(ff, \D).extract(offset, GetSize(argD)) == argD + // Check that FF.Q is connected to CE-mux + filter !ffcemux || port(ff, \Q).extract(offset, GetSize(argQ)) == argQ + + filter clock == SigBit() || port(ff, \CLK) == clock + + set ffoffset offset +endmatch + +code argQ + SigSpec D = port(ff, \D); + SigSpec Q = port(ff, \Q); + if (!ffcemux) { + argQ = argD; + argQ.replace(D, Q); + } + + // Abandon matches when 'Q' has a non-zero init attribute set + // (not supported by DSP48E1) + for (auto c : argQ.chunks()) { + Const init = c.wire->attributes.at(\init, Const()); + if (!init.empty()) + for (auto b : init.extract(c.offset, c.width)) + if (b != State::Sx && b != State::S0) + reject; + } + + dff = ff; + dffQ = argQ; + dffclock = port(ff, \CLK); +endcode diff --git a/passes/pmgen/xilinx_dsp_CREG.pmg b/passes/pmgen/xilinx_dsp_CREG.pmg index 5cd34162e..b20e4f458 100644 --- a/passes/pmgen/xilinx_dsp_CREG.pmg +++ b/passes/pmgen/xilinx_dsp_CREG.pmg @@ -1,7 +1,7 @@ // This file describes the second of three pattern matcher setups that // forms the `xilinx_dsp` pass described in xilinx_dsp.cc // At a high level, it works as follows: -// (1) Starting from a DSP48E1 cell that (a) doesn't have a CREG already, +// (1) Starting from a DSP48* cell that (a) doesn't have a CREG already, // and (b) uses the 'C' port // (2) Match the driver of the 'C' input to a possible $dff cell (CREG) // (attached to at most two $mux cells that implement clock-enable or @@ -38,10 +38,10 @@ udata dffclock udata dff dffcemux dffrstmux udata dffcepol dffrstpol -// (1) Starting from a DSP48E1 cell that (a) doesn't have a CREG already, +// (1) Starting from a DSP48* cell that (a) doesn't have a CREG already, // and (b) uses the 'C' port match dsp - select dsp->type.in(\DSP48E1) + select dsp->type.in(\DSP48A, \DSP48A1, \DSP48E1) select param(dsp, \CREG, 1).as_int() == 0 select nusers(port(dsp, \C, SigSpec())) > 1 endmatch @@ -60,7 +60,8 @@ code sigC sigP clock sigC = unextend(port(dsp, \C, SigSpec())); SigSpec P = port(dsp, \P); - if (param(dsp, \USE_MULT, Const("MULTIPLY")).decode_string() == "MULTIPLY") { + if (!dsp->type.in(\DSP48E1) || + param(dsp, \USE_MULT, Const("MULTIPLY")).decode_string() == "MULTIPLY") { // Only care about those bits that are used int i; for (i = GetSize(P)-1; i >= 0; i--) diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index 971089b28..a19046911 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -387,7 +387,10 @@ struct SynthXilinxPass : public ScriptPass run("opt_expr -fine"); run("wreduce"); run("select -clear"); - run("xilinx_dsp"); + if (help_mode) + run("xilinx_dsp -family "); + else + run("xilinx_dsp -family " + family); run("chtype -set $mul t:$__soft_mul"); } } diff --git a/techlibs/xilinx/xc3sda_dsp_map.v b/techlibs/xilinx/xc3sda_dsp_map.v index 87348a173..258f90395 100644 --- a/techlibs/xilinx/xc3sda_dsp_map.v +++ b/techlibs/xilinx/xc3sda_dsp_map.v @@ -27,7 +27,7 @@ module \$__MUL18X18 (input [17:0] A, input [17:0] B, output [35:0] Y); .D(18'b0), .P(P_48), - .OPMODE(8'b0000010) + .OPMODE(8'b0000001) ); assign Y = P_48; endmodule diff --git a/techlibs/xilinx/xc6s_dsp_map.v b/techlibs/xilinx/xc6s_dsp_map.v index e8705723b..bdce60c14 100644 --- a/techlibs/xilinx/xc6s_dsp_map.v +++ b/techlibs/xilinx/xc6s_dsp_map.v @@ -27,7 +27,7 @@ module \$__MUL18X18 (input [17:0] A, input [17:0] B, output [35:0] Y); .D(18'b0), .P(P_48), - .OPMODE(8'b0000010) + .OPMODE(8'b0000001) ); assign Y = P_48; endmodule diff --git a/tests/arch/xilinx/macc.sh b/tests/arch/xilinx/macc.sh index 154a29848..58b97b646 100644 --- a/tests/arch/xilinx/macc.sh +++ b/tests/arch/xilinx/macc.sh @@ -1,3 +1,6 @@ ../../../yosys -qp "synth_xilinx -top macc2; rename -top macc2_uut" -o macc_uut.v macc.v iverilog -o test_macc macc_tb.v macc_uut.v macc.v ../../../techlibs/xilinx/cells_sim.v vvp -N ./test_macc +../../../yosys -qp "synth_xilinx -family xc6s -top macc2; rename -top macc2_uut" -o macc_uut.v macc.v +iverilog -o test_macc macc_tb.v macc_uut.v macc.v ../../../techlibs/xilinx/cells_sim.v +vvp -N ./test_macc diff --git a/tests/arch/xilinx/mul.ys b/tests/arch/xilinx/mul.ys index d76814966..6cf994fbf 100644 --- a/tests/arch/xilinx/mul.ys +++ b/tests/arch/xilinx/mul.ys @@ -7,3 +7,15 @@ cd top # Constrain all select calls below inside the top module select -assert-count 1 t:DSP48E1 select -assert-none t:DSP48E1 %% t:* %D + +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 +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:DSP48A1 +select -assert-none t:DSP48A1 %% t:* %D diff --git a/tests/arch/xilinx/mul_unsigned.ys b/tests/arch/xilinx/mul_unsigned.ys index 62495b90c..c714680af 100644 --- a/tests/arch/xilinx/mul_unsigned.ys +++ b/tests/arch/xilinx/mul_unsigned.ys @@ -9,3 +9,17 @@ select -assert-count 1 t:BUFG select -assert-count 1 t:DSP48E1 select -assert-count 30 t:FDRE select -assert-none t:DSP48E1 t:FDRE t:BUFG %% t:* %D + +design -reset + +read_verilog mul_unsigned.v +hierarchy -top mul_unsigned +proc + +equiv_opt -assert -map +/xilinx/cells_sim.v synth_xilinx -family xc6s # 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 +select -assert-count 1 t:DSP48A1 +select -assert-count 30 t:FDRE +select -assert-none t:DSP48A1 t:FDRE t:BUFG %% t:* %D -- cgit v1.2.3 From 6eadd4390a3c9650912bac9fbf8bd309f0088217 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 23 Dec 2019 08:35:53 -0800 Subject: write_xaiger to opt instead of just clean whiteboxes --- backends/aiger/xaiger.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index af52daa0c..78496b13c 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -876,7 +876,7 @@ struct XAigerWriter RTLIL::Design *holes_design = new RTLIL::Design; module->design->modules_.erase(holes_module->name); holes_design->add(holes_module); - Pass::call(holes_design, "clean -purge"); + Pass::call(holes_design, "opt -purge"); std::stringstream a_buffer; XAigerWriter writer(holes_module, true /* holes_mode */); -- cgit v1.2.3 From 509070f82fa458ccc8515eb4b09f1e4ab7068110 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 23 Dec 2019 08:36:20 -0800 Subject: Disable clock domain partitioning in Yosys pass, let ABC do it --- passes/techmap/abc9.cc | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index def347c21..857f1a0a6 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -1080,14 +1080,17 @@ struct Abc9Pass : public Pass { assign_map.set(module); + typedef SigSpec clkdomain_t; + dict clk_to_mergeability; + std::vector all_cells = module->selected_cells(); +#if 0 pool unassigned_cells(all_cells.begin(), all_cells.end()); pool expand_queue, next_expand_queue; pool expand_queue_up, next_expand_queue_up; pool expand_queue_down, next_expand_queue_down; - typedef SigSpec clkdomain_t; std::map> assigned_cells; std::map assigned_cells_reverse; @@ -1109,6 +1112,7 @@ struct Abc9Pass : public Pass { bit_to_cell_up[bit].insert(cell); } } +#endif for (auto cell : all_cells) { auto inst_module = design->module(cell->type); @@ -1120,13 +1124,16 @@ struct Abc9Pass : public Pass { log_error("'%s$abc9_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); +#if 0 unassigned_cells.erase(cell); expand_queue_up.insert(cell); - clkdomain_t key(abc9_clock); assigned_cells[key].insert(cell->name); assigned_cells_reverse[cell] = key; +#endif - auto YS_ATTRIBUTE(unused) r2 = cell->attributes.insert(std::make_pair(ID(abc9_mergeability), 1)); + 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.$abc9_init", cell->name.c_str())); @@ -1139,6 +1146,7 @@ struct Abc9Pass : public Pass { r2 = cell->attributes.insert(std::make_pair(ID(abc9_init), abc9_init.as_const())); log_assert(r2.second); +#if 0 // Also assign these special ABC9 cells to the // same clock domain for (auto b : cell_to_bit_down[cell]) @@ -1162,8 +1170,10 @@ struct Abc9Pass : public Pass { expand_queue.insert(cell); expand_queue_down.insert(cell); +#endif } +#if 0 while (!expand_queue_up.empty() || !expand_queue_down.empty()) { if (!expand_queue_up.empty()) @@ -1234,11 +1244,14 @@ struct Abc9Pass : public Pass { } log_header(design, "Summary of detected clock domains:\n"); - for (auto &it : assigned_cells) + for (auto &it : assigned_cells) { log(" %d cells in clk=%s\n", GetSize(it.second), log_signal(it.first)); + } +#endif - design->selection_stack.emplace_back(false); design->selected_active_module = module->name.str(); +#if 0 + design->selection_stack.emplace_back(false); for (auto &it : assigned_cells) { std::string target = delay_target; if (target.empty()) { @@ -1254,12 +1267,15 @@ struct Abc9Pass : public Pass { } RTLIL::Selection& sel = design->selection_stack.back(); sel.selected_members[module->name] = std::move(it.second); +#endif abc9_module(design, module, script_file, exe_file, cleanup, lut_costs, false, "$", - keepff, target, lutin_shared, fast_mode, show_tempdir, + keepff, delay_target, lutin_shared, fast_mode, show_tempdir, box_file, lut_file, wire_delay, box_lookup, nomfs); +#if 0 assign_map.set(module); } design->selection_stack.pop_back(); +#endif design->selected_active_module.clear(); } -- cgit v1.2.3 From dadaf7ed788370c94a463e5e479bed4d540cdf4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20Ko=C5=9Bcielnicki?= Date: Sun, 22 Dec 2019 14:30:04 +0000 Subject: xilinx: Test our DSP48A/DSP48A1 simulation models. --- techlibs/xilinx/cells_sim.v | 6 +- techlibs/xilinx/tests/.gitignore | 4 + techlibs/xilinx/tests/test_dsp48a1_model.sh | 17 ++ techlibs/xilinx/tests/test_dsp48a1_model.v | 331 ++++++++++++++++++++++++++++ techlibs/xilinx/tests/test_dsp_model.sh | 11 +- 5 files changed, 362 insertions(+), 7 deletions(-) create mode 100644 techlibs/xilinx/tests/test_dsp48a1_model.sh create mode 100644 techlibs/xilinx/tests/test_dsp48a1_model.v diff --git a/techlibs/xilinx/cells_sim.v b/techlibs/xilinx/cells_sim.v index 804c2d70f..3bcbfc9aa 100644 --- a/techlibs/xilinx/cells_sim.v +++ b/techlibs/xilinx/cells_sim.v @@ -2099,7 +2099,7 @@ always @* begin 2'b00: XMUX <= 0; 2'b01: XMUX <= M; 2'b10: XMUX <= P; - 2'b11: XMUX <= {D_OUT[11:0], B1_OUT, A1_OUT}; + 2'b11: XMUX <= {D_OUT[11:0], A1_OUT, B1_OUT}; default: XMUX <= 48'hxxxxxxxxxxxx; endcase end @@ -2117,8 +2117,8 @@ end // The post-adder. wire signed [48:0] X_EXT; wire signed [48:0] Z_EXT; -assign X_EXT = XMUX; -assign Z_EXT = ZMUX; +assign X_EXT = {1'b0, XMUX}; +assign Z_EXT = {1'b0, ZMUX}; assign {CARRYOUT_IN, P_IN} = OPMODE_OUT[7] ? (Z_EXT - (X_EXT + CARRYIN_OUT)) : (Z_EXT + X_EXT + CARRYIN_OUT); // Cascade outputs. diff --git a/techlibs/xilinx/tests/.gitignore b/techlibs/xilinx/tests/.gitignore index ef3699bd2..848f88d53 100644 --- a/techlibs/xilinx/tests/.gitignore +++ b/techlibs/xilinx/tests/.gitignore @@ -8,4 +8,8 @@ dsp_work*/ test_dsp_model_ref.v test_dsp_model_uut.v test_dsp_model +test_dsp48a_model_ref.v +test_dsp48a1_model_ref.v +test_dsp48a1_model_uut.v +test_dsp48a1_model *.vcd diff --git a/techlibs/xilinx/tests/test_dsp48a1_model.sh b/techlibs/xilinx/tests/test_dsp48a1_model.sh new file mode 100644 index 000000000..a14a78e72 --- /dev/null +++ b/techlibs/xilinx/tests/test_dsp48a1_model.sh @@ -0,0 +1,17 @@ +#!/bin/bash +set -ex +if [ -z $ISE_DIR ]; then + ISE_DIR=/opt/Xilinx/ISE/14.7 +fi +sed 's/DSP48A1/MARKER1/; s/DSP48A/DSP48A_UUT/; s/MARKER1/DSP48A1_UUT/; /module DSP48A_UUT/,/endmodule/ p; /module DSP48A1_UUT/,/endmodule/ p; d;' < ../cells_sim.v > test_dsp48a1_model_uut.v +if [ ! -f "test_dsp48a1_model_ref.v" ]; then + cp $ISE_DIR/ISE_DS/ISE/verilog/src/unisims/DSP48A1.v test_dsp48a1_model_ref.v +fi +if [ ! -f "test_dsp48a_model_ref.v" ]; then + cp $ISE_DIR/ISE_DS/ISE/verilog/src/unisims/DSP48A.v test_dsp48a_model_ref.v +fi +for tb in mult_allreg mult_noreg mult_inreg +do + iverilog -s $tb -s glbl -o test_dsp48a1_model test_dsp48a1_model.v test_dsp48a1_model_uut.v test_dsp48a1_model_ref.v test_dsp48a_model_ref.v $ISE_DIR/ISE_DS/ISE/verilog/src/glbl.v + vvp -N ./test_dsp48a1_model +done diff --git a/techlibs/xilinx/tests/test_dsp48a1_model.v b/techlibs/xilinx/tests/test_dsp48a1_model.v new file mode 100644 index 000000000..66346b47b --- /dev/null +++ b/techlibs/xilinx/tests/test_dsp48a1_model.v @@ -0,0 +1,331 @@ +`timescale 1ns / 1ps + +module testbench; + parameter integer A0REG = 1; + parameter integer A1REG = 1; + parameter integer B0REG = 1; + parameter integer B1REG = 1; + parameter integer CREG = 1; + parameter integer DREG = 1; + parameter integer MREG = 1; + parameter integer PREG = 1; + parameter integer CARRYINREG = 1; + parameter integer CARRYOUTREG = 1; + parameter integer OPMODEREG = 1; + parameter CARRYINSEL = "OPMODE5"; + parameter RSTTYPE = "SYNC"; + + reg CLK; + reg CEA, CEB, CEC, CED, CEM, CEP, CECARRYIN, CEOPMODE; + reg RSTA, RSTB, RSTC, RSTD, RSTM, RSTP, RSTCARRYIN, RSTOPMODE; + reg [17:0] A; + reg [17:0] B; + reg [47:0] C; + reg [17:0] D; + reg [47:0] PCIN; + reg [7:0] OPMODE; + reg CARRYIN; + + output CARRYOUTF, REF_CARRYOUTF; + output CARRYOUT, REF_CARRYOUT, REF_OLD_CARRYOUT; + output [35:0] M, REF_M; + output [47:0] P, REF_P, REF_OLD_P; + output [17:0] BCOUT, REF_BCOUT, REF_OLD_BCOUT; + output [47:0] PCOUT, REF_PCOUT, REF_OLD_PCOUT; + + integer errcount = 0; + + reg ERROR_FLAG = 0; + + task clkcycle; + begin + #5; + CLK = ~CLK; + #10; + CLK = ~CLK; + #2; + ERROR_FLAG = 0; + if (REF_BCOUT !== BCOUT || REF_OLD_BCOUT != BCOUT) begin + $display("ERROR at %1t: REF_BCOUT=%b REF_OLD_BCOUT=%b UUT_BCOUT=%b DIFF=%b", $time, REF_BCOUT, REF_OLD_BCOUT, BCOUT, REF_BCOUT ^ BCOUT); + errcount = errcount + 1; + ERROR_FLAG = 1; + end + if (REF_M !== M) begin + $display("ERROR at %1t: REF_M=%b UUT_M=%b DIFF=%b", $time, REF_M, M, REF_M ^ M); + errcount = errcount + 1; + ERROR_FLAG = 1; + end + if (REF_P !== P || REF_OLD_P != P) begin + $display("ERROR at %1t: REF_P=%b REF_OLD_P=%b UUT_P=%b DIFF=%b", $time, REF_P, REF_OLD_P, P, REF_P ^ P); + errcount = errcount + 1; + ERROR_FLAG = 1; + end + if (REF_PCOUT !== PCOUT || REF_OLD_PCOUT != PCOUT) begin + $display("ERROR at %1t: REF_PCOUT=%b REF_OLD_PCOUT=%b UUT_PCOUT=%b DIFF=%b", $time, REF_PCOUT, REF_OLD_PCOUT, PCOUT, REF_PCOUT ^ PCOUT); + errcount = errcount + 1; + ERROR_FLAG = 1; + end + if (REF_CARRYOUT !== CARRYOUT || (REF_OLD_CARRYOUT != CARRYOUT && !CARRYOUTREG)) begin + $display("ERROR at %1t: REF_CARRYOUT=%b REF_OLD_CARRYOUT=%b UUT_CARRYOUT=%b DIFF=%b", $time, REF_CARRYOUT, REF_OLD_CARRYOUT, CARRYOUT, REF_CARRYOUT ^ CARRYOUT); + errcount = errcount + 1; + ERROR_FLAG = 1; + end + if (REF_CARRYOUTF !== CARRYOUTF) begin + $display("ERROR at %1t: REF_CARRYOUTF=%b UUT_CARRYOUTF=%b", $time, REF_CARRYOUTF, CARRYOUTF); + errcount = errcount + 1; + ERROR_FLAG = 1; + end + #3; + end + endtask + + reg config_valid = 0; + task drc; + begin + config_valid = 1; + + if (OPMODE[1:0] == 2'b10 && PREG != 1) config_valid = 0; + if (OPMODE[3:2] == 2'b10 && PREG != 1) config_valid = 0; + end + endtask + + initial begin + $dumpfile("test_dsp48a1_model.vcd"); + $dumpvars(0, testbench); + + #2; + CLK = 1'b0; + {CEA, CEB, CEC, CED, CEM, CEP, CECARRYIN, CEOPMODE} = 8'b11111111; + {A, B, C, D, PCIN, OPMODE, CARRYIN} = 0; + {RSTA, RSTB, RSTC, RSTD, RSTM, RSTP, RSTCARRYIN, RSTOPMODE} = 8'b11111111; + repeat (10) begin + #10; + CLK = 1'b1; + #10; + CLK = 1'b0; + #10; + CLK = 1'b1; + #10; + CLK = 1'b0; + end + {RSTA, RSTB, RSTC, RSTD, RSTM, RSTP, RSTCARRYIN, RSTOPMODE} = 0; + + repeat (10000) begin + clkcycle; + config_valid = 0; + while (!config_valid) begin + A = $urandom; + B = $urandom; + C = {$urandom, $urandom}; + D = $urandom; + PCIN = {$urandom, $urandom}; + + {CEA, CEB, CEC, CED, CEM, CEP, CECARRYIN, CEOPMODE} = $urandom | $urandom | $urandom; + {RSTA, RSTB, RSTC, RSTD, RSTM, RSTP, RSTCARRYIN, RSTOPMODE} = $urandom & $urandom & $urandom & $urandom & $urandom & $urandom; + {CARRYIN, OPMODE} = $urandom; + + drc; + end + end + + if (errcount == 0) begin + $display("All tests passed."); + $finish; + end else begin + $display("Caught %1d errors.", errcount); + $stop; + end + end + + DSP48A #( + .A0REG (A0REG), + .A1REG (A1REG), + .B0REG (B0REG), + .B1REG (B1REG), + .CREG (CREG), + .DREG (DREG), + .MREG (MREG), + .PREG (PREG), + .CARRYINREG (CARRYINREG), + .OPMODEREG (OPMODEREG), + .CARRYINSEL (CARRYINSEL), + .RSTTYPE (RSTTYPE) + ) ref_old ( + .A (A), + .B (B), + .C (C), + .D (D), + .PCIN (PCIN), + .CARRYIN (CARRYIN), + .OPMODE (OPMODE), + .BCOUT (REF_OLD_BCOUT), + .CARRYOUT (REF_OLD_CARRYOUT), + .P (REF_OLD_P), + .PCOUT (REF_OLD_PCOUT), + .CEA (CEA), + .CEB (CEB), + .CEC (CEC), + .CED (CED), + .CEM (CEM), + .CEP (CEP), + .CECARRYIN (CECARRYIN), + .CEOPMODE (CEOPMODE), + .CLK (CLK), + .RSTA (RSTA), + .RSTB (RSTB), + .RSTC (RSTC), + .RSTD (RSTD), + .RSTM (RSTM), + .RSTP (RSTP), + .RSTCARRYIN (RSTCARRYIN), + .RSTOPMODE (RSTOPMODE) + ); + + DSP48A1 #( + .A0REG (A0REG), + .A1REG (A1REG), + .B0REG (B0REG), + .B1REG (B1REG), + .CREG (CREG), + .DREG (DREG), + .MREG (MREG), + .PREG (PREG), + .CARRYINREG (CARRYINREG), + .CARRYOUTREG (CARRYOUTREG), + .OPMODEREG (OPMODEREG), + .CARRYINSEL (CARRYINSEL), + .RSTTYPE (RSTTYPE) + ) ref ( + .A (A), + .B (B), + .C (C), + .D (D), + .PCIN (PCIN), + .CARRYIN (CARRYIN), + .OPMODE (OPMODE), + .BCOUT (REF_BCOUT), + .CARRYOUTF (REF_CARRYOUTF), + .CARRYOUT (REF_CARRYOUT), + .P (REF_P), + .M (REF_M), + .PCOUT (REF_PCOUT), + .CEA (CEA), + .CEB (CEB), + .CEC (CEC), + .CED (CED), + .CEM (CEM), + .CEP (CEP), + .CECARRYIN (CECARRYIN), + .CEOPMODE (CEOPMODE), + .CLK (CLK), + .RSTA (RSTA), + .RSTB (RSTB), + .RSTC (RSTC), + .RSTD (RSTD), + .RSTM (RSTM), + .RSTP (RSTP), + .RSTCARRYIN (RSTCARRYIN), + .RSTOPMODE (RSTOPMODE) + ); + + DSP48A1_UUT #( + .A0REG (A0REG), + .A1REG (A1REG), + .B0REG (B0REG), + .B1REG (B1REG), + .CREG (CREG), + .DREG (DREG), + .MREG (MREG), + .PREG (PREG), + .CARRYINREG (CARRYINREG), + .CARRYOUTREG (CARRYOUTREG), + .OPMODEREG (OPMODEREG), + .CARRYINSEL (CARRYINSEL), + .RSTTYPE (RSTTYPE) + ) uut ( + .A (A), + .B (B), + .C (C), + .D (D), + .PCIN (PCIN), + .CARRYIN (CARRYIN), + .OPMODE (OPMODE), + .BCOUT (BCOUT), + .CARRYOUTF (CARRYOUTF), + .CARRYOUT (CARRYOUT), + .P (P), + .M (M), + .PCOUT (PCOUT), + .CEA (CEA), + .CEB (CEB), + .CEC (CEC), + .CED (CED), + .CEM (CEM), + .CEP (CEP), + .CECARRYIN (CECARRYIN), + .CEOPMODE (CEOPMODE), + .CLK (CLK), + .RSTA (RSTA), + .RSTB (RSTB), + .RSTC (RSTC), + .RSTD (RSTD), + .RSTM (RSTM), + .RSTP (RSTP), + .RSTCARRYIN (RSTCARRYIN), + .RSTOPMODE (RSTOPMODE) + ); +endmodule + +module mult_noreg; + testbench #( + .A0REG (0), + .A1REG (0), + .B0REG (0), + .B1REG (0), + .CREG (0), + .DREG (0), + .MREG (0), + .PREG (0), + .CARRYINREG (0), + .CARRYOUTREG (0), + .OPMODEREG (0), + .CARRYINSEL ("CARRYIN"), + .RSTTYPE ("SYNC") + ) testbench (); +endmodule + +module mult_allreg; + testbench #( + .A0REG (1), + .A1REG (1), + .B0REG (1), + .B1REG (1), + .CREG (1), + .DREG (1), + .MREG (1), + .PREG (1), + .CARRYINREG (1), + .CARRYOUTREG (1), + .OPMODEREG (1), + .CARRYINSEL ("OPMODE5"), + .RSTTYPE ("SYNC") + ) testbench (); +endmodule + +module mult_inreg; + testbench #( + .A0REG (1), + .A1REG (1), + .B0REG (1), + .B1REG (1), + .CREG (1), + .DREG (1), + .MREG (0), + .PREG (0), + .CARRYINREG (1), + .CARRYOUTREG (0), + .OPMODEREG (0), + .CARRYINSEL ("CARRYIN"), + .RSTTYPE ("SYNC") + ) testbench (); +endmodule diff --git a/techlibs/xilinx/tests/test_dsp_model.sh b/techlibs/xilinx/tests/test_dsp_model.sh index ae925c402..d005cd40c 100644 --- a/techlibs/xilinx/tests/test_dsp_model.sh +++ b/techlibs/xilinx/tests/test_dsp_model.sh @@ -1,14 +1,17 @@ #!/bin/bash set -ex +if [ -z $VIVADO_DIR ]; then + VIVADO_DIR=/opt/Xilinx/Vivado/2019.1 +fi sed 's/DSP48E1/DSP48E1_UUT/; /DSP48E1_UUT/,/endmodule/ p; d;' < ../cells_sim.v > test_dsp_model_uut.v if [ ! -f "test_dsp_model_ref.v" ]; then - cat /opt/Xilinx/Vivado/2019.1/data/verilog/src/unisims/DSP48E1.v > test_dsp_model_ref.v + cp $VIVADO_DIR/data/verilog/src/unisims/DSP48E1.v test_dsp_model_ref.v fi for tb in macc_overflow_underflow \ - simd24_preadd_noreg_nocasc simd12_preadd_noreg_nocasc \ - mult_allreg_nopreadd_nocasc mult_noreg_nopreadd_nocasc \ + simd24_preadd_noreg_nocasc simd12_preadd_noreg_nocasc \ + mult_allreg_nopreadd_nocasc mult_noreg_nopreadd_nocasc \ mult_allreg_preadd_nocasc mult_noreg_preadd_nocasc mult_inreg_preadd_nocasc do - iverilog -s $tb -s glbl -o test_dsp_model test_dsp_model.v test_dsp_model_uut.v test_dsp_model_ref.v /opt/Xilinx/Vivado/2019.1/data/verilog/src/glbl.v + iverilog -s $tb -s glbl -o test_dsp_model test_dsp_model.v test_dsp_model_uut.v test_dsp_model_ref.v $VIVADO_DIR/data/verilog/src/glbl.v vvp -N ./test_dsp_model done -- cgit v1.2.3 From d00533eaa81b0c9dd80679bdde4aba60c8b1eece Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 23 Dec 2019 11:42:46 -0800 Subject: Add DSP48A* PCOUT -> PCIN cascade support --- passes/pmgen/xilinx_dsp_cascade.pmg | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/passes/pmgen/xilinx_dsp_cascade.pmg b/passes/pmgen/xilinx_dsp_cascade.pmg index 7a32df2b7..9763facdf 100644 --- a/passes/pmgen/xilinx_dsp_cascade.pmg +++ b/passes/pmgen/xilinx_dsp_cascade.pmg @@ -62,12 +62,11 @@ code #define MAX_DSP_CASCADE 20 endcode -// (1) Starting from a DSP48E1 cell that (a) has the Z multiplexer -// (controlled by OPMODE[6:4]) set to zero and (b) doesn't already -// use the 'PCOUT' port +// (1) Starting from a DSP48* cell that (a) has the Z multiplexer +// (controlled by OPMODE[3:2] for DSP48A*, by OPMODE[6:4] for DSP48E1) +// set to zero and (b) doesn't already use the 'PCOUT' port match first - select first->type.in(\DSP48E1) - select port(first, \OPMODE, Const(0, 7)).extract(4,3) == Const::from_string("000") + select (first->type.in(\DSP48A, \DSP48A1) && port(first, \OPMODE, Const(0, 7)).extract(2,2) == Const::from_string("00")) || (first->type.in(\DSP48E1) && port(first, \OPMODE, Const(0, 7)).extract(4,3) == Const::from_string("000")) select nusers(port(first, \PCOUT, SigSpec())) <= 1 endmatch @@ -156,22 +155,21 @@ subpattern tail arg first arg next -// (2.1) Match another DSP48E1 cell that (a) does not have the CREG enabled, +// (2.1) Match another DSP48* cell that (a) does not have the CREG enabled, // (b) has its Z multiplexer output set to the 'C' port, which is // driven by the 'P' output of the previous DSP cell, and (c) has its // 'PCIN' port unused match nextP - select nextP->type.in(\DSP48E1) select !param(nextP, \CREG, State::S1).as_bool() - select port(nextP, \OPMODE, Const(0, 7)).extract(4,3) == Const::from_string("011") + select (nextP->type.in(\DSP48A, \DSP48A1) && port(nextP, \OPMODE, Const(0, 7)).extract(2,2) == Const::from_string("11")) || (nextP->type.in(\DSP48E1) && port(nextP, \OPMODE, Const(0, 7)).extract(4,3) == Const::from_string("011")) select nusers(port(nextP, \C, SigSpec())) > 1 select nusers(port(nextP, \PCIN, SigSpec())) == 0 index port(nextP, \C)[0] === port(std::get<0>(chain.back()), \P)[0] semioptional endmatch -// (2.2) Same as (2.1) but with the 'C' port driven by the 'P' output of the -// previous DSP cell right-shifted by 17 bits +// (2.2) For DSP48E1 only, same as (2.1) but with the 'C' port driven +// by the 'P' output of the previous DSP cell right-shifted by 17 bits match nextP_shift17 if !nextP select nextP_shift17->type.in(\DSP48E1) @@ -188,6 +186,8 @@ code next if (!nextP) next = nextP_shift17; if (next) { + if (next->type != first->type) + reject; unextend = [](const SigSpec &sig) { int i; for (i = GetSize(sig)-1; i > 0; i--) -- cgit v1.2.3 From 71cac30309ec19bb72ff64ae5f5471ba0ecfaf46 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 23 Dec 2019 12:38:18 -0800 Subject: Support unregistered cascades for A and B inputs --- passes/pmgen/xilinx_dsp_cascade.pmg | 121 ++++++++++++++++++++++-------------- 1 file changed, 74 insertions(+), 47 deletions(-) diff --git a/passes/pmgen/xilinx_dsp_cascade.pmg b/passes/pmgen/xilinx_dsp_cascade.pmg index 9763facdf..7a310764c 100644 --- a/passes/pmgen/xilinx_dsp_cascade.pmg +++ b/passes/pmgen/xilinx_dsp_cascade.pmg @@ -119,21 +119,42 @@ finally add_siguser(cascade, dsp_pcin); add_siguser(cascade, dsp); - dsp->setParam(ID(ACASCREG), AREG); + if (dsp->type.in(\DSP48E1)) + dsp->setParam(ID(ACASCREG), AREG); dsp_pcin->setParam(ID(A_INPUT), Const("CASCADE")); log_debug("ACOUT -> ACIN cascade for %s -> %s\n", log_id(dsp), log_id(dsp_pcin)); } if (BREG >= 0) { Wire *cascade = module->addWire(NEW_ID, 18); - dsp_pcin->setPort(ID(B), Const(0, 18)); - dsp_pcin->setPort(ID(BCIN), cascade); + if (dsp->type.in(\DSP48A, \DSP48A1)) { + // According to UG389 p9 [https://www.xilinx.com/support/documentation/user_guides/ug389.pdf] + // "The DSP48A1 component uses this input when cascading + // BCOUT from an adjacent DSP48A1 slice. The tools then + // translate BCOUT cascading to the dedicated BCIN input + // and set the B_INPUT attribute for implementation." + dsp_pcin->setPort(ID(B), cascade); + } + else { + dsp_pcin->setPort(ID(B), Const(0, 18)); + dsp_pcin->setPort(ID(BCIN), cascade); + } dsp->setPort(ID(BCOUT), cascade); add_siguser(cascade, dsp_pcin); add_siguser(cascade, dsp); - dsp->setParam(ID(BCASCREG), BREG); - dsp_pcin->setParam(ID(B_INPUT), Const("CASCADE")); + if (dsp->type.in(\DSP48E1)) { + dsp->setParam(ID(BCASCREG), BREG); + // According to UG389 p13 [https://www.xilinx.com/support/documentation/user_guides/ug389.pdf] + // "The attribute is only used by place and route tools and + // is not necessary for the users to set for synthesis. The + // attribute is determined by the connection to the B port + // of the DSP48A1 slice. If the B port is connected to the + // BCOUT of another DSP48A1 slice, then the tools automatically + // set the attribute to 'CASCADE', otherwise it is set to + // 'DIRECT'". + dsp_pcin->setParam(ID(B_INPUT), Const("CASCADE")); + } log_debug("BCOUT -> BCIN cascade for %s -> %s\n", log_id(dsp), log_id(dsp_pcin)); } @@ -202,36 +223,39 @@ code next endcode // (3) For this subequent DSP48E1 match (i.e. PCOUT -> PCIN cascade exists) -// if (a) the previous DSP48E1 uses either the A2REG or A1REG, (b) this -// DSP48 does not use A2REG nor A1REG, (c) this DSP48E1 does not already -// have an ACOUT -> ACIN cascade, (d) the previous DSP does not already -// use its ACOUT port, then examine if an ACOUT -> ACIN cascade -// opportunity exists by matching for a $dff-with-optional-clock-enable- -// or-reset and checking that the 'D' input of this register is the same -// as the 'A' input of the previous DSP +// if (a) this DSP48 does not use A2REG nor A1REG, (b) this DSP48E1 does +// not already have an ACOUT -> ACIN cascade, (c) the previous DSP does +// not already use its ACOUT port, then examine if an ACOUT -> ACIN cascade +// opportunity exists if (i) A ports are identical, or (ii) separated by a +// $dff-with-optional-clock-enable-or-reset and checking that the 'D' input +// of this register is the same as the 'A' input of the previous DSP +// TODO: Check for two levels of flops, instead of just one code argQ clock AREG AREG = -1; - if (next) { + if (next && next->type.in(\DSP48E1)) { Cell *prev = std::get<0>(chain.back()); - if (param(prev, \AREG, 2).as_int() > 0 && - param(next, \AREG, 2).as_int() > 0 && + if (param(next, \AREG, 2).as_int() == 0 && param(next, \A_INPUT, Const("DIRECT")).decode_string() == "DIRECT" && nusers(port(prev, \ACOUT, SigSpec())) <= 1) { - argQ = unextend(port(next, \A)); - clock = port(prev, \CLK); - subpattern(in_dffe); - if (dff) { - if (!dffrstmux && port(prev, \RSTA, State::S0) != State::S0) - goto reject_AREG; - if (dffrstmux && port(dffrstmux, \S) != port(prev, \RSTA, State::S0)) - goto reject_AREG; - if (!dffcemux && port(prev, \CEA2, State::S0) != State::S0) - goto reject_AREG; - if (dffcemux && port(dffcemux, \S) != port(prev, \CEA2, State::S0)) - goto reject_AREG; - if (dffD == unextend(port(prev, \A))) - AREG = 1; -reject_AREG: ; + if (port(prev, \A) == port(next, \A)) + AREG = 0; + else { + argQ = unextend(port(next, \A)); + clock = port(prev, \CLK); + subpattern(in_dffe); + if (dff) { + if (!dffrstmux && port(prev, \RSTA, State::S0) != State::S0) + goto reject_AREG; + if (dffrstmux && port(dffrstmux, \S) != port(prev, \RSTA, State::S0)) + goto reject_AREG; + if (!dffcemux && port(prev, \CEA2, State::S0) != State::S0) + goto reject_AREG; + if (dffcemux && port(dffcemux, \S) != port(prev, \CEA2, State::S0)) + goto reject_AREG; + if (dffD == unextend(port(prev, \A))) + AREG = 1; +reject_AREG: ; + } } } } @@ -242,26 +266,29 @@ code argQ clock BREG BREG = -1; if (next) { Cell *prev = std::get<0>(chain.back()); - if (param(prev, \BREG, 2).as_int() > 0 && - param(next, \BREG, 2).as_int() > 0 && + if (((next->type.in(\DSP48A, \DSP48A1) && param(next, \B1REG, 1) == 0) || (next->type.in(\DSP48E1) && param(next, \BREG, 2).as_int() == 0)) && param(next, \B_INPUT, Const("DIRECT")).decode_string() == "DIRECT" && port(next, \BCIN, SigSpec()).is_fully_zero() && nusers(port(prev, \BCOUT, SigSpec())) <= 1) { - argQ = unextend(port(next, \B)); - clock = port(prev, \CLK); - subpattern(in_dffe); - if (dff) { - if (!dffrstmux && port(prev, \RSTB, State::S0) != State::S0) - goto reject_BREG; - if (dffrstmux && port(dffrstmux, \S) != port(prev, \RSTB, State::S0)) - goto reject_BREG; - if (!dffcemux && port(prev, \CEB2, State::S0) != State::S0) - goto reject_BREG; - if (dffcemux && port(dffcemux, \S) != port(prev, \CEB2, State::S0)) - goto reject_BREG; - if (dffD == unextend(port(prev, \B))) - BREG = 1; -reject_BREG: ; + if (port(prev, \B) == port(next, \B)) + BREG = 0; + else { + argQ = unextend(port(next, \B)); + clock = port(prev, \CLK); + subpattern(in_dffe); + if (dff) { + if (!dffrstmux && port(prev, \RSTB, State::S0) != State::S0) + goto reject_BREG; + if (dffrstmux && port(dffrstmux, \S) != port(prev, \RSTB, State::S0)) + goto reject_BREG; + if (!dffcemux && port(prev, \CEB2, State::S0) != State::S0) + goto reject_BREG; + if (dffcemux && port(dffcemux, \S) != port(prev, \CEB2, State::S0)) + goto reject_BREG; + if (dffD == unextend(port(prev, \B))) + BREG = 1; +reject_BREG: ; + } } } } -- cgit v1.2.3 From edabe73377e08ebdc1315d9a907f0a4ff8bfddd3 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 23 Dec 2019 13:41:26 -0800 Subject: Fix checking CE[AB] and for direct connections --- passes/pmgen/xilinx_dsp_cascade.pmg | 58 +++++++++++++++++++++++++------------ 1 file changed, 40 insertions(+), 18 deletions(-) diff --git a/passes/pmgen/xilinx_dsp_cascade.pmg b/passes/pmgen/xilinx_dsp_cascade.pmg index 7a310764c..1116afd41 100644 --- a/passes/pmgen/xilinx_dsp_cascade.pmg +++ b/passes/pmgen/xilinx_dsp_cascade.pmg @@ -223,10 +223,10 @@ code next endcode // (3) For this subequent DSP48E1 match (i.e. PCOUT -> PCIN cascade exists) -// if (a) this DSP48 does not use A2REG nor A1REG, (b) this DSP48E1 does -// not already have an ACOUT -> ACIN cascade, (c) the previous DSP does -// not already use its ACOUT port, then examine if an ACOUT -> ACIN cascade -// opportunity exists if (i) A ports are identical, or (ii) separated by a +// if (a) this DSP48E1 does not already have an ACOUT -> ACIN cascade, +// (b) the previous DSP does not already use its ACOUT port, then +// examine if an ACOUT -> ACIN cascade opportunity exists if +// (i) A ports are identical, or (ii) separated by a // $dff-with-optional-clock-enable-or-reset and checking that the 'D' input // of this register is the same as the 'A' input of the previous DSP // TODO: Check for two levels of flops, instead of just one @@ -234,11 +234,14 @@ code argQ clock AREG AREG = -1; if (next && next->type.in(\DSP48E1)) { Cell *prev = std::get<0>(chain.back()); - if (param(next, \AREG, 2).as_int() == 0 && - param(next, \A_INPUT, Const("DIRECT")).decode_string() == "DIRECT" && + + if (param(next, \A_INPUT, Const("DIRECT")).decode_string() == "DIRECT" && + port(next, \ACIN, SigSpec()).is_fully_zero() && nusers(port(prev, \ACOUT, SigSpec())) <= 1) { - if (port(prev, \A) == port(next, \A)) - AREG = 0; + if (param(prev, \AREG, 2) == 0) { + if (port(prev, \A) == port(next, \A)) + AREG = 0; + } else { argQ = unextend(port(next, \A)); clock = port(prev, \CLK); @@ -248,16 +251,22 @@ code argQ clock AREG goto reject_AREG; if (dffrstmux && port(dffrstmux, \S) != port(prev, \RSTA, State::S0)) goto reject_AREG; - if (!dffcemux && port(prev, \CEA2, State::S0) != State::S0) + IdString CEA; + if (param(prev, \AREG, 2) == 1) + CEA = \CEA2; + else if (param(prev, \AREG, 2) == 2) + CEA = \CEA1; + else log_abort(); + if (!dffcemux && port(prev, CEA, State::S0) != State::S0) goto reject_AREG; - if (dffcemux && port(dffcemux, \S) != port(prev, \CEA2, State::S0)) + if (dffcemux && port(dffcemux, \S) != port(prev, CEA, State::S0)) goto reject_AREG; if (dffD == unextend(port(prev, \A))) AREG = 1; -reject_AREG: ; } } } +reject_AREG: ; } endcode @@ -266,12 +275,14 @@ code argQ clock BREG BREG = -1; if (next) { Cell *prev = std::get<0>(chain.back()); - if (((next->type.in(\DSP48A, \DSP48A1) && param(next, \B1REG, 1) == 0) || (next->type.in(\DSP48E1) && param(next, \BREG, 2).as_int() == 0)) && - param(next, \B_INPUT, Const("DIRECT")).decode_string() == "DIRECT" && + if (param(next, \B_INPUT, Const("DIRECT")).decode_string() == "DIRECT" && port(next, \BCIN, SigSpec()).is_fully_zero() && nusers(port(prev, \BCOUT, SigSpec())) <= 1) { - if (port(prev, \B) == port(next, \B)) - BREG = 0; + if ((next->type.in(\DSP48A, \DSP48A1) && param(prev, \B0REG, 0) == 0 && param(prev, \B1REG, 1) == 0) || + (next->type.in(\DSP48E1) && param(prev, \BREG, 2) == 0)) { + if (port(prev, \B) == port(next, \B)) + BREG = 0; + } else { argQ = unextend(port(next, \B)); clock = port(prev, \CLK); @@ -281,16 +292,27 @@ code argQ clock BREG goto reject_BREG; if (dffrstmux && port(dffrstmux, \S) != port(prev, \RSTB, State::S0)) goto reject_BREG; - if (!dffcemux && port(prev, \CEB2, State::S0) != State::S0) + IdString CEB; + if (next->type.in(\DSP48A, \DSP48A1)) + CEB = \CEB; + else if (next->type.in(\DSP48E1)) { + if (param(prev, \BREG, 2) == 1) + CEB = \CEB2; + else if (param(prev, \BREG, 2) == 2) + CEB = \CEB1; + else log_abort(); + } + else log_abort(); + if (!dffcemux && port(prev, CEB, State::S0) != State::S0) goto reject_BREG; - if (dffcemux && port(dffcemux, \S) != port(prev, \CEB2, State::S0)) + if (dffcemux && port(dffcemux, \S) != port(prev, CEB, State::S0)) goto reject_BREG; if (dffD == unextend(port(prev, \B))) BREG = 1; -reject_BREG: ; } } } +reject_BREG: ; } endcode -- cgit v1.2.3 From 75acaff6f5416137fdf515bda5c214ccc228df98 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 23 Dec 2019 14:22:13 -0800 Subject: Fix CEA/CEB check --- passes/pmgen/xilinx_dsp_cascade.pmg | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/passes/pmgen/xilinx_dsp_cascade.pmg b/passes/pmgen/xilinx_dsp_cascade.pmg index 1116afd41..9fdefff31 100644 --- a/passes/pmgen/xilinx_dsp_cascade.pmg +++ b/passes/pmgen/xilinx_dsp_cascade.pmg @@ -257,7 +257,7 @@ code argQ clock AREG else if (param(prev, \AREG, 2) == 2) CEA = \CEA1; else log_abort(); - if (!dffcemux && port(prev, CEA, State::S0) != State::S0) + if (!dffcemux && port(prev, CEA, State::S0) != State::S1) goto reject_AREG; if (dffcemux && port(dffcemux, \S) != port(prev, CEA, State::S0)) goto reject_AREG; @@ -303,7 +303,7 @@ code argQ clock BREG else log_abort(); } else log_abort(); - if (!dffcemux && port(prev, CEB, State::S0) != State::S0) + if (!dffcemux && port(prev, CEB, State::S0) != State::S1) goto reject_BREG; if (dffcemux && port(dffcemux, \S) != port(prev, CEB, State::S0)) goto reject_BREG; -- cgit v1.2.3 From 1d0ac659ad37af7fa3d32a95bf04c4ce0e009792 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 23 Dec 2019 14:40:59 -0800 Subject: Fix OPMODE for PCIN->PCOUT cascades in xc6s, check B[01]REG too --- passes/pmgen/xilinx_dsp_cascade.pmg | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/passes/pmgen/xilinx_dsp_cascade.pmg b/passes/pmgen/xilinx_dsp_cascade.pmg index 9fdefff31..b4c2b348f 100644 --- a/passes/pmgen/xilinx_dsp_cascade.pmg +++ b/passes/pmgen/xilinx_dsp_cascade.pmg @@ -99,14 +99,21 @@ finally add_siguser(cascade, dsp); SigSpec opmode = port(dsp_pcin, \OPMODE, Const(0, 7)); - if (P == 17) - opmode[6] = State::S1; - else if (P == 0) - opmode[6] = State::S0; - else log_abort(); + if (dsp->type.in(\DSP48A, \DSP48A1)) { + log_assert(P == 0); + opmode[3] = State::S0; + opmode[2] = State::S1; + } + else if (dsp->type.in(\DSP48E1)) { + if (P == 17) + opmode[6] = State::S1; + else if (P == 0) + opmode[6] = State::S0; + else log_abort(); - opmode[5] = State::S0; - opmode[4] = State::S1; + opmode[5] = State::S0; + opmode[4] = State::S1; + } dsp_pcin->setPort(\OPMODE, opmode); log_debug("PCOUT -> PCIN cascade for %s -> %s\n", log_id(dsp), log_id(dsp_pcin)); @@ -307,8 +314,11 @@ code argQ clock BREG goto reject_BREG; if (dffcemux && port(dffcemux, \S) != port(prev, CEB, State::S0)) goto reject_BREG; - if (dffD == unextend(port(prev, \B))) + if (dffD == unextend(port(prev, \B))) { + if (next->type.in(\DSP48A, \DSP48A1) && param(prev, \B0REG, 0) != 0) + goto reject_BREG; BREG = 1; + } } } } -- cgit v1.2.3 From 2e21aa59a296c666f8e8fa0033efce4504ebd9ba Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 23 Dec 2019 14:58:06 -0800 Subject: Add DSP cascade tests --- tests/arch/xilinx/dsp_cascade.ys | 89 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 tests/arch/xilinx/dsp_cascade.ys diff --git a/tests/arch/xilinx/dsp_cascade.ys b/tests/arch/xilinx/dsp_cascade.ys new file mode 100644 index 000000000..f9185551b --- /dev/null +++ b/tests/arch/xilinx/dsp_cascade.ys @@ -0,0 +1,89 @@ +design -reset +read_verilog < DSP48E1.PCIN +# (i.e. Take all DSP48E1s, expand to find all wires connected +# to its PCOUT port, then remove all DSP48E1s from this +# selection, then expand again to find all cells where +# those wires are connected to the PCIN port, then remove +# all wires from this selection, and lastly intersect +# this selection with all DSP48E1 cells (to check that +# the connected cells are indeed DSPs) +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 +design -load postopt +cd cascade +select -assert-count 3 t:DSP48A1 +select -assert-count 5 t:FDRE # No cascade for A input +select -assert-none t:DSP48A1 t:BUFG t:FDRE %% t:* %D +# Very crude method of checking that DSP48E1.PCOUT -> DSP48E1.PCIN +# (see above for explanation) +select -assert-count 2 t:DSP48A1 %co:+[PCOUT] t:DSP48A1 %d %co:+[PCIN] w:* %d t:DSP48A1 %i + +design -reset +read_verilog < DSP48E1.PCIN +# (see above for explanation) +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 +design -load postopt +cd cascade +select -assert-count 2 t:DSP48A1 +select -assert-count 10 t:FDRE # Cannot cascade because first 'm' DSP + # uses both B0REG and B1REG, whereas 'o' + # only requires 1 +select -assert-none t:DSP48A1 t:BUFG t:FDRE %% t:* %D +# Very crude method of checking that DSP48E1.PCOUT -> DSP48E1.PCIN +# (see above for explanation) +select -assert-count 1 t:DSP48A1 %co:+[PCOUT] t:DSP48A1 %d %co:+[PCIN] w:* %d t:DSP48A1 %i + -- cgit v1.2.3 From e226a8f7f1e2fa55102890462fc2a0097a04092b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20Ko=C5=9Bcielnicki?= Date: Wed, 25 Dec 2019 15:39:40 +0100 Subject: Minor nit fixes --- passes/pmgen/xilinx_dsp_cascade.pmg | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/passes/pmgen/xilinx_dsp_cascade.pmg b/passes/pmgen/xilinx_dsp_cascade.pmg index b4c2b348f..b14a1ee0a 100644 --- a/passes/pmgen/xilinx_dsp_cascade.pmg +++ b/passes/pmgen/xilinx_dsp_cascade.pmg @@ -66,7 +66,7 @@ endcode // (controlled by OPMODE[3:2] for DSP48A*, by OPMODE[6:4] for DSP48E1) // set to zero and (b) doesn't already use the 'PCOUT' port match first - select (first->type.in(\DSP48A, \DSP48A1) && port(first, \OPMODE, Const(0, 7)).extract(2,2) == Const::from_string("00")) || (first->type.in(\DSP48E1) && port(first, \OPMODE, Const(0, 7)).extract(4,3) == Const::from_string("000")) + select (first->type.in(\DSP48A, \DSP48A1) && port(first, \OPMODE, Const(0, 8)).extract(2,2) == Const::from_string("00")) || (first->type.in(\DSP48E1) && port(first, \OPMODE, Const(0, 7)).extract(4,3) == Const::from_string("000")) select nusers(port(first, \PCOUT, SigSpec())) <= 1 endmatch @@ -189,7 +189,7 @@ arg next // 'PCIN' port unused match nextP select !param(nextP, \CREG, State::S1).as_bool() - select (nextP->type.in(\DSP48A, \DSP48A1) && port(nextP, \OPMODE, Const(0, 7)).extract(2,2) == Const::from_string("11")) || (nextP->type.in(\DSP48E1) && port(nextP, \OPMODE, Const(0, 7)).extract(4,3) == Const::from_string("011")) + select (nextP->type.in(\DSP48A, \DSP48A1) && port(nextP, \OPMODE, Const(0, 8)).extract(2,2) == Const::from_string("11")) || (nextP->type.in(\DSP48E1) && port(nextP, \OPMODE, Const(0, 7)).extract(4,3) == Const::from_string("011")) select nusers(port(nextP, \C, SigSpec())) > 1 select nusers(port(nextP, \PCIN, SigSpec())) == 0 index port(nextP, \C)[0] === port(std::get<0>(chain.back()), \P)[0] -- cgit v1.2.3 From a24596def375bd9edcbeac1b73d7c3ea76244a77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20Ko=C5=9Bcielnicki?= Date: Sun, 22 Dec 2019 01:08:56 +0100 Subject: iopadmap: Emit tristate buffers with const OE for some edge cases. --- passes/techmap/iopadmap.cc | 91 ++++++++++++++++++++++++++++++++++------------ tests/techmap/iopadmap.ys | 23 ++++++++++++ 2 files changed, 91 insertions(+), 23 deletions(-) diff --git a/passes/techmap/iopadmap.cc b/passes/techmap/iopadmap.cc index 90cfef71e..47da98b06 100644 --- a/passes/techmap/iopadmap.cc +++ b/passes/techmap/iopadmap.cc @@ -192,11 +192,28 @@ struct IopadmapPass : public Pass { if (!toutpad_celltype.empty() || !tinoutpad_celltype.empty()) { dict tbuf_bits; + pool driven_bits; + // Gather tristate buffers and always-on drivers. for (auto cell : module->cells()) if (cell->type == ID($_TBUF_)) { SigBit bit = cell->getPort(ID::Y).as_bit(); tbuf_bits[bit] = cell; + } else { + for (auto port : cell->connections()) + if (!cell->known() || cell->output(port.first)) + for (auto bit : port.second) + driven_bits.insert(bit); + } + + // If a wire is a target of an assignment, it is driven, unless the source is 'z. + for (auto &conn : module->connections()) + for (int i = 0; i < GetSize(conn.first); i++) { + SigBit dstbit = conn.first[i]; + SigBit srcbit = conn.second[i]; + if (!srcbit.wire && srcbit.data == State::Sz) + continue; + driven_bits.insert(dstbit); } for (auto wire : module->selected_wires()) @@ -204,41 +221,68 @@ struct IopadmapPass : public Pass { if (!wire->port_output) continue; + // Don't handle inout ports if we have no suitable buffer type. + if (wire->port_input && tinoutpad_celltype.empty()) + continue; + + // likewise for output ports. + if (!wire->port_input && toutpad_celltype.empty()) + continue; + for (int i = 0; i < GetSize(wire); i++) { SigBit wire_bit(wire, i); + Cell *tbuf_cell = nullptr; + + if (tbuf_bits.count(wire_bit)) + tbuf_cell = tbuf_bits.at(wire_bit); + + SigBit en_sig; + SigBit data_sig; + bool is_driven = driven_bits.count(wire_bit); + + if (tbuf_cell != nullptr) { + // Found a tristate buffer — use it. + en_sig = tbuf_cell->getPort(ID(E)).as_bit(); + data_sig = tbuf_cell->getPort(ID::A).as_bit(); + } else if (is_driven) { + // No tristate buffer, but an always-on driver is present. + // If this is an inout port, we're creating a tinoutpad + // anyway, just with a constant 1 as enable. + if (!wire->port_input) + continue; + en_sig = SigBit(State::S1); + data_sig = wire_bit; + } else { + // No driver on a wire. Create a tristate pad with always-0 + // enable. + en_sig = SigBit(State::S0); + data_sig = SigBit(State::Sx); + } - if (tbuf_bits.count(wire_bit) == 0) - continue; - - Cell *tbuf_cell = tbuf_bits.at(wire_bit); - - if (tbuf_cell == nullptr) - continue; - - SigBit en_sig = tbuf_cell->getPort(ID(E)).as_bit(); - SigBit data_sig = tbuf_cell->getPort(ID::A).as_bit(); - - if (wire->port_input && !tinoutpad_celltype.empty()) + if (wire->port_input) { log("Mapping port %s.%s[%d] using %s.\n", log_id(module), log_id(wire), i, tinoutpad_celltype.c_str()); Cell *cell = module->addCell(NEW_ID, RTLIL::escape_id(tinoutpad_celltype)); cell->setPort(RTLIL::escape_id(tinoutpad_portname_oe), en_sig); - cell->setPort(RTLIL::escape_id(tinoutpad_portname_o), wire_bit); - cell->setPort(RTLIL::escape_id(tinoutpad_portname_i), data_sig); cell->attributes[ID::keep] = RTLIL::Const(1); - module->remove(tbuf_cell); + if (tbuf_cell) { + module->remove(tbuf_cell); + cell->setPort(RTLIL::escape_id(tinoutpad_portname_o), wire_bit); + cell->setPort(RTLIL::escape_id(tinoutpad_portname_i), data_sig); + } else if (is_driven) { + cell->setPort(RTLIL::escape_id(tinoutpad_portname_i), wire_bit); + } else { + cell->setPort(RTLIL::escape_id(tinoutpad_portname_o), wire_bit); + cell->setPort(RTLIL::escape_id(tinoutpad_portname_i), data_sig); + } skip_wire_bits.insert(wire_bit); if (!tinoutpad_portname_pad.empty()) rewrite_bits[wire][i] = make_pair(cell, RTLIL::escape_id(tinoutpad_portname_pad)); - continue; - } - - if (!wire->port_input && !toutpad_celltype.empty()) - { + } else { log("Mapping port %s.%s[%d] using %s.\n", log_id(module), log_id(wire), i, toutpad_celltype.c_str()); Cell *cell = module->addCell(NEW_ID, RTLIL::escape_id(toutpad_celltype)); @@ -247,12 +291,13 @@ struct IopadmapPass : public Pass { cell->setPort(RTLIL::escape_id(toutpad_portname_i), data_sig); cell->attributes[ID::keep] = RTLIL::Const(1); - module->remove(tbuf_cell); - module->connect(wire_bit, data_sig); + if (tbuf_cell) { + module->remove(tbuf_cell); + module->connect(wire_bit, data_sig); + } skip_wire_bits.insert(wire_bit); if (!toutpad_portname_pad.empty()) rewrite_bits[wire][i] = make_pair(cell, RTLIL::escape_id(toutpad_portname_pad)); - continue; } } } diff --git a/tests/techmap/iopadmap.ys b/tests/techmap/iopadmap.ys index f4345e906..c058d1607 100644 --- a/tests/techmap/iopadmap.ys +++ b/tests/techmap/iopadmap.ys @@ -28,6 +28,20 @@ assign io = oe ? i : 1'bz; assign o2 = io; assign o3 = ~io; endmodule + +module f(output o, o2); +assign o = 1'bz; +endmodule + +module g(inout io, output o); +assign o = io; +endmodule + +module h(inout io, output o, input i); +assign io = i; +assign o = io; +endmodule + EOT opt_clean @@ -97,3 +111,12 @@ select -assert-count 1 @oeb %co %co @iob %i select -assert-count 1 @iob %co %co @o2b %i select -assert-count 1 @iob %co %co t:$_NOT_ %i select -assert-count 1 @o3b %ci %ci t:$_NOT_ %i + +select -assert-count 2 f/t:obuft + +select -assert-count 1 g/t:obuf +select -assert-count 1 g/t:iobuf + +select -assert-count 1 h/t:ibuf +select -assert-count 1 h/t:iobuf +select -assert-count 1 h/t:obuf -- cgit v1.2.3 From 3e14ff16676884a1f65cf0eeb0ca9cb1958b8804 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Wed, 25 Dec 2019 20:38:48 +0100 Subject: fixed invalid char --- passes/pmgen/xilinx_dsp48a.pmg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/pmgen/xilinx_dsp48a.pmg b/passes/pmgen/xilinx_dsp48a.pmg index 97d5c5ccd..16f5e598d 100644 --- a/passes/pmgen/xilinx_dsp48a.pmg +++ b/passes/pmgen/xilinx_dsp48a.pmg @@ -1,5 +1,5 @@ // This file describes the main pattern matcher setup (of three total) that -// forms the `xilinx_dsp` pass described in xilinx_dsp.cc — version for +// forms the `xilinx_dsp` pass described in xilinx_dsp.cc - version for // DSP48A/DSP48A1 (Spartan 3A DSP, Spartan 6). // At a high level, it works as follows: // ( 1) Starting from a DSP48A/DSP48A1 cell -- cgit v1.2.3 From 49881b4468bbd02ac141495dd3b30c9739eb5072 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 27 Dec 2019 11:30:18 -0800 Subject: write_xaiger: fix arrival times for non boxes --- backends/aiger/xaiger.cc | 43 +++++++++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 78496b13c..e03f95eaa 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -250,41 +250,48 @@ struct XAigerWriter } RTLIL::Module* inst_module = module->design->module(cell->type); - if (inst_module && inst_module->attributes.count("\\abc9_box_id")) { - abc9_box_seen = true; - - toposort.node(cell->name); + if (inst_module) { + bool abc9_box = inst_module->attributes.count("\\abc9_box_id"); 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); - } + int arrival = 0; 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(); } + } - for (auto bit : sigmap(conn.second)) { - bit_drivers[bit].insert(cell->name); - if (arrival) - arrival_times[bit] = arrival; + if (abc9_box) { + if (port_wire->port_input) { + // Ignore inout for the sake of topographical ordering + if (port_wire->port_output) continue; + for (auto bit : sigmap(conn.second)) + bit_users[bit].insert(cell->name); } + if (port_wire->port_output) + for (auto bit : sigmap(conn.second)) { + bit_drivers[bit].insert(cell->name); + if (arrival) + arrival_times[bit] = arrival; + } } } - if (inst_module->attributes.count("\\abc9_flop")) - flop_boxes.push_back(cell); - continue; + if (abc9_box) { + abc9_box_seen = true; + + toposort.node(cell->name); + + if (inst_module->attributes.count("\\abc9_flop")) + flop_boxes.push_back(cell); + continue; + } } bool cell_known = inst_module || cell->known(); -- cgit v1.2.3 From dd503a5f3f50ec9762aa7301b5e0c5112aff1866 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 27 Dec 2019 15:18:55 -0800 Subject: Really fix it! --- backends/aiger/xaiger.cc | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index e03f95eaa..80077c10a 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -255,32 +255,29 @@ struct XAigerWriter for (const auto &conn : cell->connections()) { auto port_wire = inst_module->wire(conn.first); - int arrival = 0; 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)) + arrival_times[bit] = arrival; } if (abc9_box) { - if (port_wire->port_input) { - // Ignore inout for the sake of topographical ordering - if (port_wire->port_output) continue; + // Ignore inout for the sake of topographical ordering + if (port_wire->port_input && !port_wire->port_output) for (auto bit : sigmap(conn.second)) bit_users[bit].insert(cell->name); - } if (port_wire->port_output) - for (auto bit : sigmap(conn.second)) { + for (auto bit : sigmap(conn.second)) bit_drivers[bit].insert(cell->name); - if (arrival) - arrival_times[bit] = arrival; - } } - } if (abc9_box) { -- cgit v1.2.3 From df31ade3b3b4f19e997c3cc8800a4a88e0a71177 Mon Sep 17 00:00:00 2001 From: David Shah Date: Fri, 27 Dec 2019 23:25:20 +0000 Subject: Revert "write_xaiger: only instantiate each whitebox cell type once" --- backends/aiger/xaiger.cc | 46 +++++++++++++++++++--------------------------- 1 file changed, 19 insertions(+), 27 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 5729f045a..627133314 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -605,25 +605,15 @@ struct XAigerWriter RTLIL::Module *holes_module = module->design->addModule("$__holes__"); log_assert(holes_module); - dict cell_cache; - int port_id = 1; int box_count = 0; for (auto cell : box_list) { RTLIL::Module* 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")) { + Cell *holes_cell = nullptr; + if (box_module->get_bool_attribute("\\whitebox")) { holes_cell = holes_module->addCell(cell->name, cell->type); holes_cell->parameters = cell->parameters; - r.first->second = holes_cell; } // NB: Assume box_module->ports are sorted alphabetically @@ -632,8 +622,8 @@ struct XAigerWriter RTLIL::Wire *w = box_module->wire(port_name); log_assert(w); RTLIL::Wire *holes_wire; - RTLIL::SigSpec port_sig; - if (w->port_input) + RTLIL::SigSpec port_wire; + if (w->port_input) { for (int i = 0; i < GetSize(w); i++) { box_inputs++; holes_wire = holes_module->wire(stringf("\\i%d", box_inputs)); @@ -644,29 +634,28 @@ struct XAigerWriter holes_module->ports.push_back(holes_wire->name); } if (holes_cell) - port_sig.append(holes_wire); + port_wire.append(holes_wire); } + if (!port_wire.empty()) + holes_cell->setPort(w->name, port_wire); + } if (w->port_output) { box_outputs += GetSize(w); for (int i = 0; i < GetSize(w); i++) { if (GetSize(w) == 1) - holes_wire = holes_module->addWire(stringf("%s.%s", cell->name.c_str(), log_id(w->name))); + holes_wire = holes_module->addWire(stringf("%s.%s", cell->name.c_str(), w->name.c_str())); else - holes_wire = holes_module->addWire(stringf("%s.%s[%d]", cell->name.c_str(), log_id(w->name), i)); + holes_wire = holes_module->addWire(stringf("%s.%s[%d]", cell->name.c_str(), w->name.c_str(), i)); holes_wire->port_output = true; holes_wire->port_id = port_id++; holes_module->ports.push_back(holes_wire->name); if (holes_cell) - port_sig.append(holes_wire); + port_wire.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); + if (!port_wire.empty()) + holes_cell->setPort(w->name, port_wire); } } @@ -696,11 +685,14 @@ struct XAigerWriter RTLIL::Selection& sel = holes_module->design->selection_stack.back(); sel.select(holes_module); + // TODO: Should not need to opt_merge if we only instantiate + // each box type once... + Pass::call(holes_module->design, "opt_merge -share_all"); + Pass::call(holes_module->design, "flatten -wb"); - // 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 ... + // TODO: Should techmap/aigmap/check all lib_whitebox-es just once, + // instead of per write_xaiger call Pass::call(holes_module->design, "techmap"); Pass::call(holes_module->design, "aigmap"); for (auto cell : holes_module->cells()) -- cgit v1.2.3 From 3d4644804ea779831b617fe7d12473e3161a93b9 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 27 Dec 2019 15:35:19 -0800 Subject: write_xaiger: simplify c{i,o}_bits --- backends/aiger/xaiger.cc | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 5729f045a..68d1b1e69 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -81,8 +81,7 @@ struct XAigerWriter pool input_bits, output_bits; dict not_map, alias_map; dict> and_map; - vector> ci_bits; - vector> co_bits; + vector ci_bits, co_bits; dict arrival_times; vector> aig_gates; @@ -367,7 +366,6 @@ struct XAigerWriter cell->setPort(port_name, rhs); } - int offset = 0; for (auto b : rhs.bits()) { SigBit I = sigmap(b); if (b == RTLIL::Sx) @@ -378,7 +376,7 @@ struct XAigerWriter else alias_map[b] = I; } - co_bits.emplace_back(b, cell, port_name, offset++, 0); + co_bits.emplace_back(b); unused_bits.erase(b); } } @@ -398,9 +396,8 @@ struct XAigerWriter cell->setPort(port_name, rhs); } - int offset = 0; for (const auto &b : rhs.bits()) { - ci_bits.emplace_back(b, cell, port_name, offset++); + ci_bits.emplace_back(b); SigBit O = sigmap(b); if (O != b) alias_map[O] = b; @@ -487,15 +484,13 @@ struct XAigerWriter aig_map[bit] = 2*aig_m; } - for (auto &c : ci_bits) { - RTLIL::SigBit bit = std::get<0>(c); + for (auto bit : ci_bits) { aig_m++, aig_i++; aig_map[bit] = 2*aig_m; } - for (auto &c : co_bits) { - RTLIL::SigBit bit = std::get<0>(c); - std::get<4>(c) = ordered_outputs[bit] = aig_o++; + for (auto bit : co_bits) { + ordered_outputs[bit] = aig_o++; aig_outputs.push_back(bit2aig(bit)); } @@ -508,7 +503,6 @@ struct XAigerWriter ordered_outputs[bit] = aig_o++; aig_outputs.push_back(bit2aig(bit)); } - } void write_aiger(std::ostream &f, bool ascii_mode) -- cgit v1.2.3 From a56d6970f24ae6044e02bea333c484035fd5cdfa Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 27 Dec 2019 16:05:58 -0800 Subject: Revert "Merge pull request #1598 from YosysHQ/revert-1588-eddie/xaiger_cleanup" This reverts commit 92654f73ea92ee9e390c8ab50d8cb51c47a7ffa9, reversing changes made to 3e14ff16676884a1f65cf0eeb0ca9cb1958b8804. --- backends/aiger/xaiger.cc | 46 +++++++++++++++++++++++++++------------------- 1 file changed, 27 insertions(+), 19 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 3599e19e3..68d1b1e69 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -599,15 +599,25 @@ struct XAigerWriter RTLIL::Module *holes_module = module->design->addModule("$__holes__"); log_assert(holes_module); + dict cell_cache; + int port_id = 1; int box_count = 0; for (auto cell : box_list) { RTLIL::Module* 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; - Cell *holes_cell = nullptr; - if (box_module->get_bool_attribute("\\whitebox")) { + 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 @@ -616,8 +626,8 @@ struct XAigerWriter RTLIL::Wire *w = box_module->wire(port_name); log_assert(w); RTLIL::Wire *holes_wire; - RTLIL::SigSpec port_wire; - if (w->port_input) { + 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)); @@ -628,28 +638,29 @@ struct XAigerWriter holes_module->ports.push_back(holes_wire->name); } if (holes_cell) - port_wire.append(holes_wire); + port_sig.append(holes_wire); } - if (!port_wire.empty()) - holes_cell->setPort(w->name, port_wire); - } if (w->port_output) { box_outputs += GetSize(w); for (int i = 0; i < GetSize(w); i++) { if (GetSize(w) == 1) - holes_wire = holes_module->addWire(stringf("%s.%s", cell->name.c_str(), w->name.c_str())); + 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(), w->name.c_str(), i)); + 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_wire.append(holes_wire); + port_sig.append(holes_wire); else holes_module->connect(holes_wire, State::S0); } - if (!port_wire.empty()) - holes_cell->setPort(w->name, port_wire); + } + 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); } } @@ -679,14 +690,11 @@ struct XAigerWriter RTLIL::Selection& sel = holes_module->design->selection_stack.back(); sel.select(holes_module); - // TODO: Should not need to opt_merge if we only instantiate - // each box type once... - Pass::call(holes_module->design, "opt_merge -share_all"); - Pass::call(holes_module->design, "flatten -wb"); - // TODO: Should techmap/aigmap/check all lib_whitebox-es just once, - // instead of per write_xaiger call + // 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()) -- cgit v1.2.3 From 237415e78cab2c15d783657c4c2bc959efb298bb Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 27 Dec 2019 16:44:18 -0800 Subject: write_xaiger: inherit port ordering from original module --- backends/aiger/xaiger.cc | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 68d1b1e69..445103771 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -604,27 +604,38 @@ struct XAigerWriter int port_id = 1; int box_count = 0; for (auto cell : box_list) { - 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); + RTLIL::Module* orig_box_module = module->design->module(cell->type); + log_assert(orig_box_module); + IdString derived_name = orig_box_module->derive(module->design, cell->parameters); + RTLIL::Module* box_module = module->design->module(derived_name); if (box_module->has_processes()) 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")) { + if (r.second && box_module->get_bool_attribute("\\whitebox")) { holes_cell = holes_module->addCell(cell->name, cell->type); holes_cell->parameters = cell->parameters; r.first->second = holes_cell; + + // Since Module::derive() will create a new module, there + // is a chance that the ports will be alphabetically ordered + // again, which is a problem when carry-chains are involved. + // Inherit the port ordering from the original module here... + // (and set the port_id below, when iterating through those) + log_assert(GetSize(box_module->ports) == GetSize(orig_box_module->ports)); + box_module->ports = orig_box_module->ports; } // NB: Assume box_module->ports are sorted alphabetically // (as RTLIL::Module::fixup_ports() would do) + int box_port_id = 1; for (const auto &port_name : box_module->ports) { RTLIL::Wire *w = box_module->wire(port_name); log_assert(w); + if (r.second) + w->port_id = box_port_id++; RTLIL::Wire *holes_wire; RTLIL::SigSpec port_sig; if (w->port_input) -- cgit v1.2.3 From d45869855c6fc86dc6a0225018a8e383866dacb4 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 27 Dec 2019 16:44:57 -0800 Subject: Add #1598 testcase --- tests/arch/ecp5/bug1598.ys | 16 ++++++++++++++++ tests/arch/ice40/bug1598.ys | 16 ++++++++++++++++ tests/arch/xilinx/bug1598.ys | 16 ++++++++++++++++ 3 files changed, 48 insertions(+) create mode 100644 tests/arch/ecp5/bug1598.ys create mode 100644 tests/arch/ice40/bug1598.ys create mode 100644 tests/arch/xilinx/bug1598.ys 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 < Date: Fri, 27 Dec 2019 16:57:08 -0800 Subject: Nitpick cleanup for ecp5 --- techlibs/ecp5/cells_sim.v | 12 ++---------- techlibs/ecp5/synth_ecp5.cc | 2 +- 2 files changed, 3 insertions(+), 11 deletions(-) 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/synth_ecp5.cc b/techlibs/ecp5/synth_ecp5.cc index b71bb2395..a0ea6d1f9 100644 --- a/techlibs/ecp5/synth_ecp5.cc +++ b/techlibs/ecp5/synth_ecp5.cc @@ -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_opt.c_str())); } -- cgit v1.2.3 From 011f749ecfe37711552be7b9c7712931e82c3757 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Sat, 28 Dec 2019 02:15:11 -0800 Subject: Update resource count --- tests/arch/ecp5/mux.ys | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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 -- cgit v1.2.3 From ec2539480867fcc05c904043747b2f3cba9a9866 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Sat, 28 Dec 2019 03:16:28 -0800 Subject: Rename abc9.cc -> abc9_techmap.cc --- passes/techmap/Makefile.inc | 1 + passes/techmap/abc9.cc | 1310 ---------------------------------------- passes/techmap/abc9_techmap.cc | 1310 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 1311 insertions(+), 1310 deletions(-) delete mode 100644 passes/techmap/abc9.cc create mode 100644 passes/techmap/abc9_techmap.cc diff --git a/passes/techmap/Makefile.inc b/passes/techmap/Makefile.inc index cd357d72a..a7c8d8c2b 100644 --- a/passes/techmap/Makefile.inc +++ b/passes/techmap/Makefile.inc @@ -8,6 +8,7 @@ OBJS += passes/techmap/libparse.o ifeq ($(ENABLE_ABC),1) OBJS += passes/techmap/abc.o OBJS += passes/techmap/abc9.o +OBJS += passes/techmap/abc9_techmap.o ifneq ($(ABCEXTERNAL),) passes/techmap/abc.o: CXXFLAGS += -DABCEXTERNAL='"$(ABCEXTERNAL)"' passes/techmap/abc9.o: CXXFLAGS += -DABCEXTERNAL='"$(ABCEXTERNAL)"' diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc deleted file mode 100644 index d03e5da8e..000000000 --- a/passes/techmap/abc9.cc +++ /dev/null @@ -1,1310 +0,0 @@ -/* - * yosys -- Yosys Open SYnthesis Suite - * - * Copyright (C) 2012 Clifford Wolf - * 2019 Eddie Hung - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - */ - -// [[CITE]] ABC -// Berkeley Logic Synthesis and Verification Group, ABC: A System for Sequential Synthesis and Verification -// http://www.eecs.berkeley.edu/~alanmi/abc/ - -#if 0 -// Based on &flow3 - better QoR but more experimental -#define ABC_COMMAND_LUT "&st; &ps -l; &sweep -v; &scorr; " \ - "&st; &if {W}; &save; &st; &syn2; &if {W} -v; &save; &load; "\ - "&st; &if -g -K 6; &dch -f; &if {W} -v; &save; &load; "\ - "&st; &if -g -K 6; &synch2; &if {W} -v; &save; &load; "\ - "&mfs; &ps -l" -#else -#define ABC_COMMAND_LUT "&st; &scorr; &sweep; &dc2; &st; &dch -f; &ps; &if {W} {D} -v; &mfs; &ps -l" -#endif - - -#define ABC_FAST_COMMAND_LUT "&st; &if {W} {D}" - -#include "kernel/register.h" -#include "kernel/sigtools.h" -#include "kernel/celltypes.h" -#include "kernel/cost.h" -#include "kernel/log.h" -#include -#include -#include -#include -#include -#include - -#ifndef _WIN32 -# include -# include -#endif - -#include "frontends/aiger/aigerparse.h" -#include "kernel/utils.h" - -#ifdef YOSYS_LINK_ABC -extern "C" int Abc_RealMain(int argc, char *argv[]); -#endif - -USING_YOSYS_NAMESPACE -PRIVATE_NAMESPACE_BEGIN - -bool markgroups; -int map_autoidx; -SigMap assign_map; -RTLIL::Module *module; - -bool clk_polarity, en_polarity; -RTLIL::SigSpec clk_sig, en_sig; - -inline std::string remap_name(RTLIL::IdString abc9_name) -{ - return stringf("$abc$%d$%s", map_autoidx, abc9_name.c_str()+1); -} - -void handle_loops(RTLIL::Design *design) -{ - Pass::call(design, "scc -set_attr abc9_scc_id {}"); - - // For every unique SCC found, (arbitrarily) find the first - // cell in the component, and select (and mark) all its output - // wires - pool ids_seen; - for (auto cell : module->cells()) { - auto it = cell->attributes.find(ID(abc9_scc_id)); - if (it != cell->attributes.end()) { - auto r = ids_seen.insert(it->second); - if (r.second) { - for (auto &c : cell->connections_) { - if (c.second.is_fully_const()) continue; - if (cell->output(c.first)) { - SigBit b = c.second.as_bit(); - Wire *w = b.wire; - if (w->port_input) { - // In this case, hopefully the loop break has been already created - // Get the non-prefixed wire - Wire *wo = module->wire(stringf("%s.abco", b.wire->name.c_str())); - log_assert(wo != nullptr); - log_assert(wo->port_output); - log_assert(b.offset < GetSize(wo)); - c.second = RTLIL::SigBit(wo, b.offset); - } - else { - // Create a new output/input loop break - w->port_input = true; - w = module->wire(stringf("%s.abco", w->name.c_str())); - if (!w) { - w = module->addWire(stringf("%s.abco", b.wire->name.c_str()), GetSize(b.wire)); - w->port_output = true; - } - else { - log_assert(w->port_input); - log_assert(b.offset < GetSize(w)); - } - w->set_bool_attribute(ID(abc9_scc_break)); - c.second = RTLIL::SigBit(w, b.offset); - } - } - } - } - cell->attributes.erase(it); - } - } - - module->fixup_ports(); -} - -std::string add_echos_to_abc9_cmd(std::string str) -{ - std::string new_str, token; - for (size_t i = 0; i < str.size(); i++) { - token += str[i]; - if (str[i] == ';') { - while (i+1 < str.size() && str[i+1] == ' ') - i++; - new_str += "echo + " + token + " " + token + " "; - token.clear(); - } - } - - if (!token.empty()) { - if (!new_str.empty()) - new_str += "echo + " + token + "; "; - new_str += token; - } - - return new_str; -} - -std::string fold_abc9_cmd(std::string str) -{ - std::string token, new_str = " "; - int char_counter = 10; - - for (size_t i = 0; i <= str.size(); i++) { - if (i < str.size()) - token += str[i]; - if (i == str.size() || str[i] == ';') { - if (char_counter + token.size() > 75) - new_str += "\n ", char_counter = 14; - new_str += token, char_counter += token.size(); - token.clear(); - } - } - - return new_str; -} - -std::string replace_tempdir(std::string text, std::string tempdir_name, bool show_tempdir) -{ - if (show_tempdir) - return text; - - while (1) { - size_t pos = text.find(tempdir_name); - if (pos == std::string::npos) - break; - text = text.substr(0, pos) + "" + text.substr(pos + GetSize(tempdir_name)); - } - - std::string selfdir_name = proc_self_dirname(); - if (selfdir_name != "/") { - while (1) { - size_t pos = text.find(selfdir_name); - if (pos == std::string::npos) - break; - text = text.substr(0, pos) + "/" + text.substr(pos + GetSize(selfdir_name)); - } - } - - return text; -} - -struct abc9_output_filter -{ - bool got_cr; - int escape_seq_state; - std::string linebuf; - std::string tempdir_name; - bool show_tempdir; - - abc9_output_filter(std::string tempdir_name, bool show_tempdir) : tempdir_name(tempdir_name), show_tempdir(show_tempdir) - { - got_cr = false; - escape_seq_state = 0; - } - - void next_char(char ch) - { - if (escape_seq_state == 0 && ch == '\033') { - escape_seq_state = 1; - return; - } - if (escape_seq_state == 1) { - escape_seq_state = ch == '[' ? 2 : 0; - return; - } - if (escape_seq_state == 2) { - if ((ch < '0' || '9' < ch) && ch != ';') - escape_seq_state = 0; - return; - } - escape_seq_state = 0; - if (ch == '\r') { - got_cr = true; - return; - } - if (ch == '\n') { - log("ABC: %s\n", replace_tempdir(linebuf, tempdir_name, show_tempdir).c_str()); - got_cr = false, linebuf.clear(); - return; - } - if (got_cr) - got_cr = false, linebuf.clear(); - linebuf += ch; - } - - void next_line(const std::string &line) - { - //int pi, po; - //if (sscanf(line.c_str(), "Start-point = pi%d. End-point = po%d.", &pi, &po) == 2) { - // log("ABC: Start-point = pi%d (%s). End-point = po%d (%s).\n", - // pi, pi_map.count(pi) ? pi_map.at(pi).c_str() : "???", - // po, po_map.count(po) ? po_map.at(po).c_str() : "???"); - // return; - //} - - for (char ch : line) - next_char(ch); - } -}; - -void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::string script_file, std::string exe_file, - bool cleanup, vector lut_costs, bool dff_mode, std::string clk_str, - bool /*keepff*/, std::string delay_target, std::string /*lutin_shared*/, bool fast_mode, - bool show_tempdir, std::string box_file, std::string lut_file, - std::string wire_delay, const dict &box_lookup, bool nomfs -) -{ - module = current_module; - map_autoidx = autoidx++; - - if (clk_str != "$") - { - clk_polarity = true; - clk_sig = RTLIL::SigSpec(); - - en_polarity = true; - en_sig = RTLIL::SigSpec(); - } - - if (!clk_str.empty() && clk_str != "$") - { - if (clk_str.find(',') != std::string::npos) { - int pos = clk_str.find(','); - std::string en_str = clk_str.substr(pos+1); - clk_str = clk_str.substr(0, pos); - if (en_str[0] == '!') { - en_polarity = false; - en_str = en_str.substr(1); - } - if (module->wires_.count(RTLIL::escape_id(en_str)) != 0) - en_sig = assign_map(RTLIL::SigSpec(module->wires_.at(RTLIL::escape_id(en_str)), 0)); - } - if (clk_str[0] == '!') { - clk_polarity = false; - clk_str = clk_str.substr(1); - } - if (module->wires_.count(RTLIL::escape_id(clk_str)) != 0) - clk_sig = assign_map(RTLIL::SigSpec(module->wires_.at(RTLIL::escape_id(clk_str)), 0)); - } - - if (dff_mode && clk_sig.empty()) - log_cmd_error("Clock domain %s not found.\n", clk_str.c_str()); - - std::string tempdir_name = "/tmp/yosys-abc-XXXXXX"; - if (!cleanup) - tempdir_name[0] = tempdir_name[4] = '_'; - tempdir_name = make_temp_dir(tempdir_name); - log_header(design, "Extracting gate netlist of module `%s' to `%s/input.xaig'..\n", - module->name.c_str(), replace_tempdir(tempdir_name, tempdir_name, show_tempdir).c_str()); - - std::string abc9_script; - - if (!lut_costs.empty()) { - abc9_script += stringf("read_lut %s/lutdefs.txt; ", tempdir_name.c_str()); - if (!box_file.empty()) - abc9_script += stringf("read_box -v %s; ", box_file.c_str()); - } - else - if (!lut_file.empty()) { - abc9_script += stringf("read_lut %s; ", lut_file.c_str()); - if (!box_file.empty()) - abc9_script += stringf("read_box -v %s; ", box_file.c_str()); - } - else - log_abort(); - - abc9_script += stringf("&read %s/input.xaig; &ps; ", tempdir_name.c_str()); - - if (!script_file.empty()) { - if (script_file[0] == '+') { - for (size_t i = 1; i < script_file.size(); i++) - if (script_file[i] == '\'') - abc9_script += "'\\''"; - else if (script_file[i] == ',') - abc9_script += " "; - else - abc9_script += script_file[i]; - } else - abc9_script += stringf("source %s", script_file.c_str()); - } else if (!lut_costs.empty() || !lut_file.empty()) { - //bool all_luts_cost_same = true; - //for (int this_cost : lut_costs) - // if (this_cost != lut_costs.front()) - // all_luts_cost_same = false; - abc9_script += fast_mode ? ABC_FAST_COMMAND_LUT : ABC_COMMAND_LUT; - //if (all_luts_cost_same && !fast_mode) - // abc9_script += "; lutpack {S}"; - } else - log_abort(); - - //if (script_file.empty() && !delay_target.empty()) - // for (size_t pos = abc9_script.find("dretime;"); pos != std::string::npos; pos = abc9_script.find("dretime;", pos+1)) - // abc9_script = abc9_script.substr(0, pos) + "dretime; retime -o {D};" + abc9_script.substr(pos+8); - - for (size_t pos = abc9_script.find("{D}"); pos != std::string::npos; pos = abc9_script.find("{D}", pos)) - abc9_script = abc9_script.substr(0, pos) + delay_target + abc9_script.substr(pos+3); - - //for (size_t pos = abc9_script.find("{S}"); pos != std::string::npos; pos = abc9_script.find("{S}", pos)) - // abc9_script = abc9_script.substr(0, pos) + lutin_shared + abc9_script.substr(pos+3); - - for (size_t pos = abc9_script.find("{W}"); pos != std::string::npos; pos = abc9_script.find("{W}", pos)) - abc9_script = abc9_script.substr(0, pos) + wire_delay + abc9_script.substr(pos+3); - - if (nomfs) - for (size_t pos = abc9_script.find("&mfs"); pos != std::string::npos; pos = abc9_script.find("&mfs", pos)) - abc9_script = abc9_script.erase(pos, strlen("&mfs")); - - abc9_script += stringf("; &write %s/output.aig", tempdir_name.c_str()); - abc9_script = add_echos_to_abc9_cmd(abc9_script); - - for (size_t i = 0; i+1 < abc9_script.size(); i++) - if (abc9_script[i] == ';' && abc9_script[i+1] == ' ') - abc9_script[i+1] = '\n'; - - FILE *f = fopen(stringf("%s/abc.script", tempdir_name.c_str()).c_str(), "wt"); - fprintf(f, "%s\n", abc9_script.c_str()); - fclose(f); - - if (dff_mode || !clk_str.empty()) - { - if (clk_sig.size() == 0) - log("No%s clock domain found. Not extracting any FF cells.\n", clk_str.empty() ? "" : " matching"); - else { - log("Found%s %s clock domain: %s", clk_str.empty() ? "" : " matching", clk_polarity ? "posedge" : "negedge", log_signal(clk_sig)); - if (en_sig.size() != 0) - log(", enabled by %s%s", en_polarity ? "" : "!", log_signal(en_sig)); - log("\n"); - } - } - - bool count_output = false; - for (auto port_name : module->ports) { - RTLIL::Wire *port_wire = module->wire(port_name); - log_assert(port_wire); - if (port_wire->port_output) { - count_output = true; - break; - } - } - - log_push(); - - if (count_output) - { - design->selection_stack.emplace_back(false); - RTLIL::Selection& sel = design->selection_stack.back(); - sel.select(module); - - handle_loops(design); - - Pass::call(design, "aigmap"); - - //log("Extracted %d gates and %d wires to a netlist network with %d inputs and %d outputs.\n", - // count_gates, GetSize(signal_list), count_input, count_output); - - Pass::call(design, stringf("write_xaiger -map %s/input.sym %s/input.xaig", tempdir_name.c_str(), tempdir_name.c_str())); - - std::string buffer; - std::ifstream ifs; -#if 0 - buffer = stringf("%s/%s", tempdir_name.c_str(), "input.xaig"); - ifs.open(buffer); - if (ifs.fail()) - log_error("Can't open ABC output file `%s'.\n", buffer.c_str()); - buffer = stringf("%s/%s", tempdir_name.c_str(), "input.sym"); - log_assert(!design->module(ID($__abc9__))); - { - AigerReader reader(design, ifs, ID($__abc9__), "" /* clk_name */, buffer.c_str() /* map_filename */, true /* wideports */); - reader.parse_xaiger(); - } - ifs.close(); - Pass::call(design, stringf("write_verilog -noexpr -norename")); - design->remove(design->module(ID($__abc9__))); -#endif - - design->selection_stack.pop_back(); - - log_header(design, "Executing ABC9.\n"); - - if (!lut_costs.empty()) { - buffer = stringf("%s/lutdefs.txt", tempdir_name.c_str()); - f = fopen(buffer.c_str(), "wt"); - if (f == NULL) - log_error("Opening %s for writing failed: %s\n", buffer.c_str(), strerror(errno)); - for (int i = 0; i < GetSize(lut_costs); i++) - fprintf(f, "%d %d.00 1.00\n", i+1, lut_costs.at(i)); - fclose(f); - } - - buffer = stringf("%s -s -f %s/abc.script 2>&1", exe_file.c_str(), tempdir_name.c_str()); - log("Running ABC command: %s\n", replace_tempdir(buffer, tempdir_name, show_tempdir).c_str()); - -#ifndef YOSYS_LINK_ABC - abc9_output_filter filt(tempdir_name, show_tempdir); - int ret = run_command(buffer, std::bind(&abc9_output_filter::next_line, filt, std::placeholders::_1)); -#else - // These needs to be mutable, supposedly due to getopt - char *abc9_argv[5]; - string tmp_script_name = stringf("%s/abc.script", tempdir_name.c_str()); - abc9_argv[0] = strdup(exe_file.c_str()); - abc9_argv[1] = strdup("-s"); - abc9_argv[2] = strdup("-f"); - abc9_argv[3] = strdup(tmp_script_name.c_str()); - abc9_argv[4] = 0; - int ret = Abc_RealMain(4, abc9_argv); - free(abc9_argv[0]); - free(abc9_argv[1]); - free(abc9_argv[2]); - free(abc9_argv[3]); -#endif - if (ret != 0) - log_error("ABC: execution of command \"%s\" failed: return code %d.\n", buffer.c_str(), ret); - - buffer = stringf("%s/%s", tempdir_name.c_str(), "output.aig"); - ifs.open(buffer, std::ifstream::binary); - if (ifs.fail()) - log_error("Can't open ABC output file `%s'.\n", buffer.c_str()); - - buffer = stringf("%s/%s", tempdir_name.c_str(), "input.sym"); - log_assert(!design->module(ID($__abc9__))); - - AigerReader reader(design, ifs, ID($__abc9__), "" /* clk_name */, buffer.c_str() /* map_filename */, true /* wideports */); - reader.parse_xaiger(box_lookup); - ifs.close(); - -#if 0 - Pass::call(design, stringf("write_verilog -noexpr -norename")); -#endif - - log_header(design, "Re-integrating ABC9 results.\n"); - RTLIL::Module *mapped_mod = design->module(ID($__abc9__)); - if (mapped_mod == NULL) - log_error("ABC output file does not contain a module `$__abc9__'.\n"); - - pool output_bits; - for (auto &it : mapped_mod->wires_) { - RTLIL::Wire *w = it.second; - RTLIL::Wire *remap_wire = module->addWire(remap_name(w->name), GetSize(w)); - if (markgroups) remap_wire->attributes[ID(abcgroup)] = map_autoidx; - if (w->port_output) { - RTLIL::Wire *wire = module->wire(w->name); - log_assert(wire); - for (int i = 0; i < GetSize(w); i++) - output_bits.insert({wire, i}); - } - } - - for (auto &it : module->connections_) { - auto &signal = it.first; - auto bits = signal.bits(); - for (auto &b : bits) - if (output_bits.count(b)) - b = module->addWire(NEW_ID); - signal = std::move(bits); - } - - dict abc9_box; - vector boxes; - for (const auto &it : module->cells_) { - auto cell = it.second; - if (cell->type.in(ID($_AND_), ID($_NOT_))) { - module->remove(cell); - continue; - } - auto jt = abc9_box.find(cell->type); - if (jt == abc9_box.end()) { - RTLIL::Module* box_module = design->module(cell->type); - jt = abc9_box.insert(std::make_pair(cell->type, box_module && box_module->attributes.count(ID(abc9_box_id)))).first; - } - if (jt->second) - boxes.emplace_back(cell); - } - - dict> bit_drivers, bit_users; - TopoSort toposort; - dict not2drivers; - dict> bit2sinks; - - std::map cell_stats; - for (auto c : mapped_mod->cells()) - { - toposort.node(c->name); - - RTLIL::Cell *cell = nullptr; - if (c->type == ID($_NOT_)) { - RTLIL::SigBit a_bit = c->getPort(ID::A); - RTLIL::SigBit y_bit = c->getPort(ID::Y); - bit_users[a_bit].insert(c->name); - bit_drivers[y_bit].insert(c->name); - - if (!a_bit.wire) { - c->setPort(ID::Y, module->addWire(NEW_ID)); - RTLIL::Wire *wire = module->wire(remap_name(y_bit.wire->name)); - log_assert(wire); - module->connect(RTLIL::SigBit(wire, y_bit.offset), State::S1); - } - else if (!lut_costs.empty() || !lut_file.empty()) { - RTLIL::Cell* driver_lut = nullptr; - // ABC can return NOT gates that drive POs - if (!a_bit.wire->port_input) { - // If it's not a NOT gate that that comes from a PI directly, - // find the driver LUT and clone that to guarantee that we won't - // increase the max logic depth - // (TODO: Optimise by not cloning unless will increase depth) - RTLIL::IdString driver_name; - if (GetSize(a_bit.wire) == 1) - driver_name = stringf("%s$lut", a_bit.wire->name.c_str()); - else - driver_name = stringf("%s[%d]$lut", a_bit.wire->name.c_str(), a_bit.offset); - driver_lut = mapped_mod->cell(driver_name); - } - - if (!driver_lut) { - // If a driver couldn't be found (could be from PI or box CI) - // then implement using a LUT - cell = module->addLut(remap_name(stringf("%s$lut", c->name.c_str())), - RTLIL::SigBit(module->wires_.at(remap_name(a_bit.wire->name)), a_bit.offset), - RTLIL::SigBit(module->wires_.at(remap_name(y_bit.wire->name)), y_bit.offset), - RTLIL::Const::from_string("01")); - bit2sinks[cell->getPort(ID::A)].push_back(cell); - cell_stats[ID($lut)]++; - } - else - not2drivers[c] = driver_lut; - continue; - } - else - log_abort(); - if (cell && markgroups) cell->attributes[ID(abcgroup)] = map_autoidx; - continue; - } - cell_stats[c->type]++; - - RTLIL::Cell *existing_cell = nullptr; - if (c->type == ID($lut)) { - if (GetSize(c->getPort(ID::A)) == 1 && c->getParam(ID(LUT)) == RTLIL::Const::from_string("01")) { - SigSpec my_a = module->wires_.at(remap_name(c->getPort(ID::A).as_wire()->name)); - SigSpec my_y = module->wires_.at(remap_name(c->getPort(ID::Y).as_wire()->name)); - module->connect(my_y, my_a); - if (markgroups) c->attributes[ID(abcgroup)] = map_autoidx; - log_abort(); - continue; - } - cell = module->addCell(remap_name(c->name), c->type); - } - else { - existing_cell = module->cell(c->name); - log_assert(existing_cell); - cell = module->addCell(remap_name(c->name), c->type); - } - - if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx; - if (existing_cell) { - cell->parameters = existing_cell->parameters; - cell->attributes = existing_cell->attributes; - } - else { - cell->parameters = c->parameters; - cell->attributes = c->attributes; - } - for (auto &conn : c->connections()) { - RTLIL::SigSpec newsig; - for (auto c : conn.second.chunks()) { - if (c.width == 0) - continue; - //log_assert(c.width == 1); - if (c.wire) - c.wire = module->wires_.at(remap_name(c.wire->name)); - newsig.append(c); - } - cell->setPort(conn.first, newsig); - - if (cell->input(conn.first)) { - for (auto i : newsig) - bit2sinks[i].push_back(cell); - for (auto i : conn.second) - bit_users[i].insert(c->name); - } - if (cell->output(conn.first)) - for (auto i : conn.second) - bit_drivers[i].insert(c->name); - } - } - - for (auto existing_cell : boxes) { - Cell *cell = module->cell(remap_name(existing_cell->name)); - if (cell) { - for (auto &conn : existing_cell->connections()) { - if (!conn.second.is_wire()) - continue; - Wire *wire = conn.second.as_wire(); - if (!wire->get_bool_attribute(ID(abc9_padding))) - continue; - cell->unsetPort(conn.first); - log_debug("Dropping padded port connection for %s (%s) .%s (%s )\n", log_id(cell), cell->type.c_str(), log_id(conn.first), log_signal(conn.second)); - } - module->swap_names(cell, existing_cell); - } - module->remove(existing_cell); - } - - // Copy connections (and rename) from mapped_mod to module - for (auto conn : mapped_mod->connections()) { - if (!conn.first.is_fully_const()) { - auto chunks = conn.first.chunks(); - for (auto &c : chunks) - c.wire = module->wires_.at(remap_name(c.wire->name)); - conn.first = std::move(chunks); - } - if (!conn.second.is_fully_const()) { - auto chunks = conn.second.chunks(); - for (auto &c : chunks) - if (c.wire) - c.wire = module->wires_.at(remap_name(c.wire->name)); - conn.second = std::move(chunks); - } - module->connect(conn); - } - - for (auto &it : cell_stats) - log("ABC RESULTS: %15s cells: %8d\n", it.first.c_str(), it.second); - int in_wires = 0, out_wires = 0; - - // Stitch in mapped_mod's inputs/outputs into module - for (auto port : mapped_mod->ports) { - RTLIL::Wire *w = mapped_mod->wire(port); - RTLIL::Wire *wire = module->wire(port); - log_assert(wire); - RTLIL::Wire *remap_wire = module->wire(remap_name(port)); - RTLIL::SigSpec signal = RTLIL::SigSpec(wire, 0, GetSize(remap_wire)); - log_assert(GetSize(signal) >= GetSize(remap_wire)); - - RTLIL::SigSig conn; - if (w->port_output) { - conn.first = signal; - conn.second = remap_wire; - out_wires++; - module->connect(conn); - } - else if (w->port_input) { - conn.first = remap_wire; - conn.second = signal; - in_wires++; - module->connect(conn); - } - } - - for (auto &it : bit_users) - if (bit_drivers.count(it.first)) - for (auto driver_cell : bit_drivers.at(it.first)) - for (auto user_cell : it.second) - toposort.edge(driver_cell, user_cell); - bool no_loops YS_ATTRIBUTE(unused) = toposort.sort(); - log_assert(no_loops); - - for (auto ii = toposort.sorted.rbegin(); ii != toposort.sorted.rend(); ii++) { - RTLIL::Cell *not_cell = mapped_mod->cell(*ii); - log_assert(not_cell); - if (not_cell->type != ID($_NOT_)) - continue; - auto it = not2drivers.find(not_cell); - if (it == not2drivers.end()) - continue; - RTLIL::Cell *driver_lut = it->second; - RTLIL::SigBit a_bit = not_cell->getPort(ID::A); - RTLIL::SigBit y_bit = not_cell->getPort(ID::Y); - RTLIL::Const driver_mask; - - a_bit.wire = module->wires_.at(remap_name(a_bit.wire->name)); - y_bit.wire = module->wires_.at(remap_name(y_bit.wire->name)); - - auto jt = bit2sinks.find(a_bit); - if (jt == bit2sinks.end()) - goto clone_lut; - - for (auto sink_cell : jt->second) - if (sink_cell->type != ID($lut)) - goto clone_lut; - - // Push downstream LUTs past inverter - for (auto sink_cell : jt->second) { - SigSpec A = sink_cell->getPort(ID::A); - RTLIL::Const mask = sink_cell->getParam(ID(LUT)); - int index = 0; - for (; index < GetSize(A); index++) - if (A[index] == a_bit) - break; - log_assert(index < GetSize(A)); - int i = 0; - while (i < GetSize(mask)) { - for (int j = 0; j < (1 << index); j++) - std::swap(mask[i+j], mask[i+j+(1 << index)]); - i += 1 << (index+1); - } - A[index] = y_bit; - sink_cell->setPort(ID::A, A); - sink_cell->setParam(ID(LUT), mask); - } - - // Since we have rewritten all sinks (which we know - // to be only LUTs) to be after the inverter, we can - // go ahead and clone the LUT with the expectation - // that the original driving LUT will become dangling - // and get cleaned away -clone_lut: - driver_mask = driver_lut->getParam(ID(LUT)); - for (auto &b : driver_mask.bits) { - if (b == RTLIL::State::S0) b = RTLIL::State::S1; - else if (b == RTLIL::State::S1) b = RTLIL::State::S0; - } - auto cell = module->addLut(NEW_ID, - driver_lut->getPort(ID::A), - y_bit, - driver_mask); - for (auto &bit : cell->connections_.at(ID::A)) { - bit.wire = module->wires_.at(remap_name(bit.wire->name)); - bit2sinks[bit].push_back(cell); - } - } - - // Now 'unexpose' those wires by undoing - // the expose operation -- remove them from PO/PI - // and re-connecting them back together - for (auto wire : module->wires()) { - auto it = wire->attributes.find(ID(abc9_scc_break)); - if (it != wire->attributes.end()) { - wire->attributes.erase(it); - log_assert(wire->port_output); - wire->port_output = false; - std::string name = wire->name.str(); - RTLIL::Wire *i_wire = module->wire(name.substr(0, GetSize(name) - 5)); - log_assert(i_wire); - log_assert(i_wire->port_input); - i_wire->port_input = false; - module->connect(i_wire, wire); - } - } - module->fixup_ports(); - - //log("ABC RESULTS: internal signals: %8d\n", int(signal_list.size()) - in_wires - out_wires); - log("ABC RESULTS: input signals: %8d\n", in_wires); - log("ABC RESULTS: output signals: %8d\n", out_wires); - - design->remove(mapped_mod); - } - else - { - log("Don't call ABC as there is nothing to map.\n"); - } - - if (cleanup) - { - log("Removing temp directory.\n"); - remove_directory(tempdir_name); - } - - log_pop(); -} - -struct Abc9Pass : public Pass { - Abc9Pass() : Pass("abc9", "use ABC9 for technology mapping") { } - void help() YS_OVERRIDE - { - // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| - log("\n"); - log(" abc9 [options] [selection]\n"); - log("\n"); - log("This pass uses the ABC tool [1] for technology mapping of yosys's internal gate\n"); - log("library to a target architecture.\n"); - log("\n"); - log(" -exe \n"); -#ifdef ABCEXTERNAL - log(" use the specified command instead of \"" ABCEXTERNAL "\" to execute ABC.\n"); -#else - log(" use the specified command instead of \"/yosys-abc\" to execute ABC.\n"); -#endif - log(" This can e.g. be used to call a specific version of ABC or a wrapper.\n"); - log("\n"); - log(" -script \n"); - log(" use the specified ABC script file instead of the default script.\n"); - log("\n"); - log(" if starts with a plus sign (+), then the rest of the filename\n"); - log(" string is interpreted as the command string to be passed to ABC. The\n"); - log(" leading plus sign is removed and all commas (,) in the string are\n"); - log(" replaced with blanks before the string is passed to ABC.\n"); - log("\n"); - log(" if no -script parameter is given, the following scripts are used:\n"); - log("\n"); - log(" for -lut/-luts (only one LUT size):\n"); - log("%s\n", fold_abc9_cmd(ABC_COMMAND_LUT /*"; lutpack {S}"*/).c_str()); - log("\n"); - log(" for -lut/-luts (different LUT sizes):\n"); - log("%s\n", fold_abc9_cmd(ABC_COMMAND_LUT).c_str()); - log("\n"); - log(" -fast\n"); - log(" use different default scripts that are slightly faster (at the cost\n"); - log(" of output quality):\n"); - log("\n"); - log(" for -lut/-luts:\n"); - log("%s\n", fold_abc9_cmd(ABC_FAST_COMMAND_LUT).c_str()); - log("\n"); - log(" -D \n"); - log(" set delay target. the string {D} in the default scripts above is\n"); - log(" replaced by this option when used, and an empty string otherwise\n"); - log(" (indicating best possible delay).\n"); -// log(" This also replaces 'dretime' with 'dretime; retime -o {D}' in the\n"); -// log(" default scripts above.\n"); - log("\n"); -// log(" -S \n"); -// log(" maximum number of LUT inputs shared.\n"); -// log(" (replaces {S} in the default scripts above, default: -S 1)\n"); -// log("\n"); - log(" -lut \n"); - log(" generate netlist using luts of (max) the specified width.\n"); - log("\n"); - log(" -lut :\n"); - log(" generate netlist using luts of (max) the specified width . All\n"); - log(" luts with width <= have constant cost. for luts larger than \n"); - log(" the area cost doubles with each additional input bit. the delay cost\n"); - log(" is still constant for all lut widths.\n"); - log("\n"); - log(" -lut \n"); - log(" pass this file with lut library to ABC.\n"); - log("\n"); - log(" -luts ,,,:,..\n"); - log(" generate netlist using luts. Use the specified costs for luts with 1,\n"); - log(" 2, 3, .. inputs.\n"); - log("\n"); -// log(" -dff\n"); -// log(" also pass $_DFF_?_ and $_DFFE_??_ cells through ABC. modules with many\n"); -// log(" clock domains are automatically partitioned in clock domains and each\n"); -// log(" domain is passed through ABC independently.\n"); -// log("\n"); -// log(" -clk [!][,[!]]\n"); -// log(" use only the specified clock domain. this is like -dff, but only FF\n"); -// log(" cells that belong to the specified clock domain are used.\n"); -// log("\n"); -// log(" -keepff\n"); -// log(" set the \"keep\" attribute on flip-flop output wires. (and thus preserve\n"); -// log(" them, for example for equivalence checking.)\n"); -// log("\n"); - log(" -nocleanup\n"); - log(" when this option is used, the temporary files created by this pass\n"); - log(" are not removed. this is useful for debugging.\n"); - log("\n"); - log(" -showtmp\n"); - log(" print the temp dir name in log. usually this is suppressed so that the\n"); - log(" command output is identical across runs.\n"); - log("\n"); - log(" -markgroups\n"); - log(" set a 'abcgroup' attribute on all objects created by ABC. The value of\n"); - log(" this attribute is a unique integer for each ABC process started. This\n"); - log(" is useful for debugging the partitioning of clock domains.\n"); - log("\n"); - log(" -box \n"); - log(" pass this file with box library to ABC. Use with -lut.\n"); - log("\n"); - log("Note that this is a logic optimization pass within Yosys that is calling ABC\n"); - log("internally. This is not going to \"run ABC on your design\". It will instead run\n"); - log("ABC on logic snippets extracted from your design. You will not get any useful\n"); - log("output when passing an ABC script that writes a file. Instead write your full\n"); - log("design as BLIF file with write_blif and then load that into ABC externally if\n"); - log("you want to use ABC to convert your design into another format.\n"); - log("\n"); - log("[1] http://www.eecs.berkeley.edu/~alanmi/abc/\n"); - log("\n"); - } - void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE - { - log_header(design, "Executing ABC9 pass (technology mapping using ABC9).\n"); - log_push(); - - assign_map.clear(); - -#ifdef ABCEXTERNAL - std::string exe_file = ABCEXTERNAL; -#else - std::string exe_file = proc_self_dirname() + "yosys-abc"; -#endif - std::string script_file, clk_str, box_file, lut_file; - std::string delay_target, lutin_shared = "-S 1", wire_delay; - bool fast_mode = false, dff_mode = false, keepff = false, cleanup = true; - bool show_tempdir = false; - bool nomfs = false; - vector lut_costs; - markgroups = false; - -#if 0 - cleanup = false; - show_tempdir = true; -#endif - -#ifdef _WIN32 -#ifndef ABCEXTERNAL - if (!check_file_exists(exe_file + ".exe") && check_file_exists(proc_self_dirname() + "..\\yosys-abc.exe")) - exe_file = proc_self_dirname() + "..\\yosys-abc"; -#endif -#endif - - size_t argidx; - char pwd [PATH_MAX]; - if (!getcwd(pwd, sizeof(pwd))) { - log_cmd_error("getcwd failed: %s\n", strerror(errno)); - log_abort(); - } - for (argidx = 1; argidx < args.size(); argidx++) { - std::string arg = args[argidx]; - if (arg == "-exe" && argidx+1 < args.size()) { - exe_file = args[++argidx]; - continue; - } - if (arg == "-script" && argidx+1 < args.size()) { - script_file = args[++argidx]; - rewrite_filename(script_file); - if (!script_file.empty() && !is_absolute_path(script_file) && script_file[0] != '+') - script_file = std::string(pwd) + "/" + script_file; - continue; - } - if (arg == "-D" && argidx+1 < args.size()) { - delay_target = "-D " + args[++argidx]; - continue; - } - //if (arg == "-S" && argidx+1 < args.size()) { - // lutin_shared = "-S " + args[++argidx]; - // continue; - //} - if (arg == "-lut" && argidx+1 < args.size()) { - string arg = args[++argidx]; - if (arg.find_first_not_of("0123456789:") == std::string::npos) { - size_t pos = arg.find_first_of(':'); - int lut_mode = 0, lut_mode2 = 0; - if (pos != string::npos) { - lut_mode = atoi(arg.substr(0, pos).c_str()); - lut_mode2 = atoi(arg.substr(pos+1).c_str()); - } else { - lut_mode = atoi(arg.c_str()); - lut_mode2 = lut_mode; - } - lut_costs.clear(); - for (int i = 0; i < lut_mode; i++) - lut_costs.push_back(1); - for (int i = lut_mode; i < lut_mode2; i++) - lut_costs.push_back(2 << (i - lut_mode)); - } - else { - lut_file = arg; - rewrite_filename(lut_file); - if (!lut_file.empty() && !is_absolute_path(lut_file) && lut_file[0] != '+') - lut_file = std::string(pwd) + "/" + lut_file; - } - continue; - } - if (arg == "-luts" && argidx+1 < args.size()) { - lut_costs.clear(); - for (auto &tok : split_tokens(args[++argidx], ",")) { - auto parts = split_tokens(tok, ":"); - if (GetSize(parts) == 0 && !lut_costs.empty()) - lut_costs.push_back(lut_costs.back()); - else if (GetSize(parts) == 1) - lut_costs.push_back(atoi(parts.at(0).c_str())); - else if (GetSize(parts) == 2) - while (GetSize(lut_costs) < atoi(parts.at(0).c_str())) - lut_costs.push_back(atoi(parts.at(1).c_str())); - else - log_cmd_error("Invalid -luts syntax.\n"); - } - continue; - } - if (arg == "-fast") { - fast_mode = true; - continue; - } - //if (arg == "-dff") { - // dff_mode = true; - // continue; - //} - //if (arg == "-clk" && argidx+1 < args.size()) { - // clk_str = args[++argidx]; - // dff_mode = true; - // continue; - //} - //if (arg == "-keepff") { - // keepff = true; - // continue; - //} - if (arg == "-nocleanup") { - cleanup = false; - continue; - } - if (arg == "-showtmp") { - show_tempdir = true; - continue; - } - if (arg == "-markgroups") { - markgroups = true; - continue; - } - if (arg == "-box" && argidx+1 < args.size()) { - box_file = args[++argidx]; - continue; - } - if (arg == "-W" && argidx+1 < args.size()) { - wire_delay = "-W " + args[++argidx]; - continue; - } - if (arg == "-nomfs") { - nomfs = true; - continue; - } - break; - } - extra_args(args, argidx, design); - - // ABC expects a box file for XAIG - if (box_file.empty()) - box_file = "+/dummy.box"; - - rewrite_filename(box_file); - if (!box_file.empty() && !is_absolute_path(box_file) && box_file[0] != '+') - box_file = std::string(pwd) + "/" + box_file; - - dict box_lookup; - for (auto m : design->modules()) { - auto it = m->attributes.find(ID(abc9_box_id)); - if (it == m->attributes.end()) - continue; - if (m->name.begins_with("$paramod")) - continue; - auto id = it->second.as_int(); - auto r = box_lookup.insert(std::make_pair(id, m->name)); - if (!r.second) - log_error("Module '%s' has the same abc9_box_id = %d value as '%s'.\n", - log_id(m), id, log_id(r.first->second)); - log_assert(r.second); - - RTLIL::Wire *carry_in = nullptr, *carry_out = nullptr; - for (auto p : m->ports) { - auto w = m->wire(p); - log_assert(w); - if (w->attributes.count(ID(abc9_carry))) { - if (w->port_input) { - if (carry_in) - log_error("Module '%s' contains more than one 'abc9_carry' input port.\n", log_id(m)); - carry_in = w; - } - else if (w->port_output) { - if (carry_out) - log_error("Module '%s' contains more than one 'abc9_carry' input port.\n", log_id(m)); - carry_out = w; - } - } - } - if (carry_in || carry_out) { - if (carry_in && !carry_out) - log_error("Module '%s' contains an 'abc9_carry' input port but no output port.\n", log_id(m)); - if (!carry_in && carry_out) - log_error("Module '%s' contains an 'abc9_carry' output port but no input port.\n", log_id(m)); - // Make carry_in the last PI, and carry_out the last PO - // since ABC requires it this way - auto &ports = m->ports; - for (auto it = ports.begin(); it != ports.end(); ) { - RTLIL::Wire* w = m->wire(*it); - log_assert(w); - if (w == carry_in || w == carry_out) { - it = ports.erase(it); - continue; - } - if (w->port_id > carry_in->port_id) - --w->port_id; - if (w->port_id > carry_out->port_id) - --w->port_id; - log_assert(w->port_input || w->port_output); - log_assert(ports[w->port_id-1] == w->name); - ++it; - } - ports.push_back(carry_in->name); - carry_in->port_id = ports.size(); - ports.push_back(carry_out->name); - carry_out->port_id = ports.size(); - } - } - - for (auto mod : design->selected_modules()) - { - if (mod->attributes.count(ID(abc9_box_id))) - continue; - - if (mod->processes.size() > 0) { - log("Skipping module %s as it contains processes.\n", log_id(mod)); - continue; - } - - assign_map.set(mod); - - if (!dff_mode || !clk_str.empty()) { - abc9_module(design, mod, script_file, exe_file, cleanup, lut_costs, dff_mode, clk_str, keepff, - delay_target, lutin_shared, fast_mode, show_tempdir, - box_file, lut_file, wire_delay, box_lookup, nomfs); - continue; - } - - CellTypes ct(design); - - std::vector all_cells = mod->selected_cells(); - std::set unassigned_cells(all_cells.begin(), all_cells.end()); - - std::set expand_queue, next_expand_queue; - std::set expand_queue_up, next_expand_queue_up; - std::set expand_queue_down, next_expand_queue_down; - - typedef tuple clkdomain_t; - std::map> assigned_cells; - std::map assigned_cells_reverse; - - std::map> cell_to_bit, cell_to_bit_up, cell_to_bit_down; - std::map> bit_to_cell, bit_to_cell_up, bit_to_cell_down; - - for (auto cell : all_cells) - { - clkdomain_t key; - - for (auto &conn : cell->connections()) - for (auto bit : conn.second) { - bit = assign_map(bit); - if (bit.wire != nullptr) { - cell_to_bit[cell].insert(bit); - bit_to_cell[bit].insert(cell); - if (ct.cell_input(cell->type, conn.first)) { - cell_to_bit_up[cell].insert(bit); - bit_to_cell_down[bit].insert(cell); - } - if (ct.cell_output(cell->type, conn.first)) { - cell_to_bit_down[cell].insert(bit); - bit_to_cell_up[bit].insert(cell); - } - } - } - - if (cell->type.in(ID($_DFF_N_), ID($_DFF_P_))) - { - key = clkdomain_t(cell->type == ID($_DFF_P_), assign_map(cell->getPort(ID(C))), true, RTLIL::SigSpec()); - } - else - if (cell->type.in(ID($_DFFE_NN_), ID($_DFFE_NP_), ID($_DFFE_PN_), ID($_DFFE_PP_))) - { - bool this_clk_pol = cell->type.in(ID($_DFFE_PN_), ID($_DFFE_PP_)); - bool this_en_pol = cell->type.in(ID($_DFFE_NP_), ID($_DFFE_PP_)); - key = clkdomain_t(this_clk_pol, assign_map(cell->getPort(ID(C))), this_en_pol, assign_map(cell->getPort(ID(E)))); - } - else - continue; - - unassigned_cells.erase(cell); - expand_queue.insert(cell); - expand_queue_up.insert(cell); - expand_queue_down.insert(cell); - - assigned_cells[key].push_back(cell); - assigned_cells_reverse[cell] = key; - } - - while (!expand_queue_up.empty() || !expand_queue_down.empty()) - { - if (!expand_queue_up.empty()) - { - RTLIL::Cell *cell = *expand_queue_up.begin(); - clkdomain_t key = assigned_cells_reverse.at(cell); - expand_queue_up.erase(cell); - - for (auto bit : cell_to_bit_up[cell]) - for (auto c : bit_to_cell_up[bit]) - if (unassigned_cells.count(c)) { - unassigned_cells.erase(c); - next_expand_queue_up.insert(c); - assigned_cells[key].push_back(c); - assigned_cells_reverse[c] = key; - expand_queue.insert(c); - } - } - - if (!expand_queue_down.empty()) - { - RTLIL::Cell *cell = *expand_queue_down.begin(); - clkdomain_t key = assigned_cells_reverse.at(cell); - expand_queue_down.erase(cell); - - for (auto bit : cell_to_bit_down[cell]) - for (auto c : bit_to_cell_down[bit]) - if (unassigned_cells.count(c)) { - unassigned_cells.erase(c); - next_expand_queue_up.insert(c); - assigned_cells[key].push_back(c); - assigned_cells_reverse[c] = key; - expand_queue.insert(c); - } - } - - if (expand_queue_up.empty() && expand_queue_down.empty()) { - expand_queue_up.swap(next_expand_queue_up); - expand_queue_down.swap(next_expand_queue_down); - } - } - - while (!expand_queue.empty()) - { - RTLIL::Cell *cell = *expand_queue.begin(); - clkdomain_t key = assigned_cells_reverse.at(cell); - expand_queue.erase(cell); - - for (auto bit : cell_to_bit.at(cell)) { - for (auto c : bit_to_cell[bit]) - if (unassigned_cells.count(c)) { - unassigned_cells.erase(c); - next_expand_queue.insert(c); - assigned_cells[key].push_back(c); - assigned_cells_reverse[c] = key; - } - bit_to_cell[bit].clear(); - } - - if (expand_queue.empty()) - expand_queue.swap(next_expand_queue); - } - - clkdomain_t key(true, RTLIL::SigSpec(), true, RTLIL::SigSpec()); - for (auto cell : unassigned_cells) { - assigned_cells[key].push_back(cell); - assigned_cells_reverse[cell] = key; - } - - log_header(design, "Summary of detected clock domains:\n"); - for (auto &it : assigned_cells) - log(" %d cells in clk=%s%s, en=%s%s\n", GetSize(it.second), - std::get<0>(it.first) ? "" : "!", log_signal(std::get<1>(it.first)), - std::get<2>(it.first) ? "" : "!", log_signal(std::get<3>(it.first))); - - for (auto &it : assigned_cells) { - clk_polarity = std::get<0>(it.first); - clk_sig = assign_map(std::get<1>(it.first)); - en_polarity = std::get<2>(it.first); - en_sig = assign_map(std::get<3>(it.first)); - abc9_module(design, mod, script_file, exe_file, cleanup, lut_costs, !clk_sig.empty(), "$", - keepff, delay_target, lutin_shared, fast_mode, show_tempdir, - box_file, lut_file, wire_delay, box_lookup, nomfs); - assign_map.set(mod); - } - } - - assign_map.clear(); - - log_pop(); - } -} Abc9Pass; - -PRIVATE_NAMESPACE_END diff --git a/passes/techmap/abc9_techmap.cc b/passes/techmap/abc9_techmap.cc new file mode 100644 index 000000000..7ff68f382 --- /dev/null +++ b/passes/techmap/abc9_techmap.cc @@ -0,0 +1,1310 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 Clifford Wolf + * 2019 Eddie Hung + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +// [[CITE]] ABC +// Berkeley Logic Synthesis and Verification Group, ABC: A System for Sequential Synthesis and Verification +// http://www.eecs.berkeley.edu/~alanmi/abc/ + +#if 0 +// Based on &flow3 - better QoR but more experimental +#define ABC_COMMAND_LUT "&st; &ps -l; &sweep -v; &scorr; " \ + "&st; &if {W}; &save; &st; &syn2; &if {W} -v; &save; &load; "\ + "&st; &if -g -K 6; &dch -f; &if {W} -v; &save; &load; "\ + "&st; &if -g -K 6; &synch2; &if {W} -v; &save; &load; "\ + "&mfs; &ps -l" +#else +#define ABC_COMMAND_LUT "&st; &scorr; &sweep; &dc2; &st; &dch -f; &ps; &if {W} {D} -v; &mfs; &ps -l" +#endif + + +#define ABC_FAST_COMMAND_LUT "&st; &if {W} {D}" + +#include "kernel/register.h" +#include "kernel/sigtools.h" +#include "kernel/celltypes.h" +#include "kernel/cost.h" +#include "kernel/log.h" +#include +#include +#include +#include +#include +#include + +#ifndef _WIN32 +# include +# include +#endif + +#include "frontends/aiger/aigerparse.h" +#include "kernel/utils.h" + +#ifdef YOSYS_LINK_ABC +extern "C" int Abc_RealMain(int argc, char *argv[]); +#endif + +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + +bool markgroups; +int map_autoidx; +SigMap assign_map; +RTLIL::Module *module; + +bool clk_polarity, en_polarity; +RTLIL::SigSpec clk_sig, en_sig; + +inline std::string remap_name(RTLIL::IdString abc9_name) +{ + return stringf("$abc$%d$%s", map_autoidx, abc9_name.c_str()+1); +} + +void handle_loops(RTLIL::Design *design) +{ + Pass::call(design, "scc -set_attr abc9_scc_id {}"); + + // For every unique SCC found, (arbitrarily) find the first + // cell in the component, and select (and mark) all its output + // wires + pool ids_seen; + for (auto cell : module->cells()) { + auto it = cell->attributes.find(ID(abc9_scc_id)); + if (it != cell->attributes.end()) { + auto r = ids_seen.insert(it->second); + if (r.second) { + for (auto &c : cell->connections_) { + if (c.second.is_fully_const()) continue; + if (cell->output(c.first)) { + SigBit b = c.second.as_bit(); + Wire *w = b.wire; + if (w->port_input) { + // In this case, hopefully the loop break has been already created + // Get the non-prefixed wire + Wire *wo = module->wire(stringf("%s.abco", b.wire->name.c_str())); + log_assert(wo != nullptr); + log_assert(wo->port_output); + log_assert(b.offset < GetSize(wo)); + c.second = RTLIL::SigBit(wo, b.offset); + } + else { + // Create a new output/input loop break + w->port_input = true; + w = module->wire(stringf("%s.abco", w->name.c_str())); + if (!w) { + w = module->addWire(stringf("%s.abco", b.wire->name.c_str()), GetSize(b.wire)); + w->port_output = true; + } + else { + log_assert(w->port_input); + log_assert(b.offset < GetSize(w)); + } + w->set_bool_attribute(ID(abc9_scc_break)); + c.second = RTLIL::SigBit(w, b.offset); + } + } + } + } + cell->attributes.erase(it); + } + } + + module->fixup_ports(); +} + +std::string add_echos_to_abc9_cmd(std::string str) +{ + std::string new_str, token; + for (size_t i = 0; i < str.size(); i++) { + token += str[i]; + if (str[i] == ';') { + while (i+1 < str.size() && str[i+1] == ' ') + i++; + new_str += "echo + " + token + " " + token + " "; + token.clear(); + } + } + + if (!token.empty()) { + if (!new_str.empty()) + new_str += "echo + " + token + "; "; + new_str += token; + } + + return new_str; +} + +std::string fold_abc9_cmd(std::string str) +{ + std::string token, new_str = " "; + int char_counter = 10; + + for (size_t i = 0; i <= str.size(); i++) { + if (i < str.size()) + token += str[i]; + if (i == str.size() || str[i] == ';') { + if (char_counter + token.size() > 75) + new_str += "\n ", char_counter = 14; + new_str += token, char_counter += token.size(); + token.clear(); + } + } + + return new_str; +} + +std::string replace_tempdir(std::string text, std::string tempdir_name, bool show_tempdir) +{ + if (show_tempdir) + return text; + + while (1) { + size_t pos = text.find(tempdir_name); + if (pos == std::string::npos) + break; + text = text.substr(0, pos) + "" + text.substr(pos + GetSize(tempdir_name)); + } + + std::string selfdir_name = proc_self_dirname(); + if (selfdir_name != "/") { + while (1) { + size_t pos = text.find(selfdir_name); + if (pos == std::string::npos) + break; + text = text.substr(0, pos) + "/" + text.substr(pos + GetSize(selfdir_name)); + } + } + + return text; +} + +struct abc9_output_filter +{ + bool got_cr; + int escape_seq_state; + std::string linebuf; + std::string tempdir_name; + bool show_tempdir; + + abc9_output_filter(std::string tempdir_name, bool show_tempdir) : tempdir_name(tempdir_name), show_tempdir(show_tempdir) + { + got_cr = false; + escape_seq_state = 0; + } + + void next_char(char ch) + { + if (escape_seq_state == 0 && ch == '\033') { + escape_seq_state = 1; + return; + } + if (escape_seq_state == 1) { + escape_seq_state = ch == '[' ? 2 : 0; + return; + } + if (escape_seq_state == 2) { + if ((ch < '0' || '9' < ch) && ch != ';') + escape_seq_state = 0; + return; + } + escape_seq_state = 0; + if (ch == '\r') { + got_cr = true; + return; + } + if (ch == '\n') { + log("ABC: %s\n", replace_tempdir(linebuf, tempdir_name, show_tempdir).c_str()); + got_cr = false, linebuf.clear(); + return; + } + if (got_cr) + got_cr = false, linebuf.clear(); + linebuf += ch; + } + + void next_line(const std::string &line) + { + //int pi, po; + //if (sscanf(line.c_str(), "Start-point = pi%d. End-point = po%d.", &pi, &po) == 2) { + // log("ABC: Start-point = pi%d (%s). End-point = po%d (%s).\n", + // pi, pi_map.count(pi) ? pi_map.at(pi).c_str() : "???", + // po, po_map.count(po) ? po_map.at(po).c_str() : "???"); + // return; + //} + + for (char ch : line) + next_char(ch); + } +}; + +void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::string script_file, std::string exe_file, + bool cleanup, vector lut_costs, bool dff_mode, std::string clk_str, + bool /*keepff*/, std::string delay_target, std::string /*lutin_shared*/, bool fast_mode, + bool show_tempdir, std::string box_file, std::string lut_file, + std::string wire_delay, const dict &box_lookup, bool nomfs +) +{ + module = current_module; + map_autoidx = autoidx++; + + if (clk_str != "$") + { + clk_polarity = true; + clk_sig = RTLIL::SigSpec(); + + en_polarity = true; + en_sig = RTLIL::SigSpec(); + } + + if (!clk_str.empty() && clk_str != "$") + { + if (clk_str.find(',') != std::string::npos) { + int pos = clk_str.find(','); + std::string en_str = clk_str.substr(pos+1); + clk_str = clk_str.substr(0, pos); + if (en_str[0] == '!') { + en_polarity = false; + en_str = en_str.substr(1); + } + if (module->wires_.count(RTLIL::escape_id(en_str)) != 0) + en_sig = assign_map(RTLIL::SigSpec(module->wires_.at(RTLIL::escape_id(en_str)), 0)); + } + if (clk_str[0] == '!') { + clk_polarity = false; + clk_str = clk_str.substr(1); + } + if (module->wires_.count(RTLIL::escape_id(clk_str)) != 0) + clk_sig = assign_map(RTLIL::SigSpec(module->wires_.at(RTLIL::escape_id(clk_str)), 0)); + } + + if (dff_mode && clk_sig.empty()) + log_cmd_error("Clock domain %s not found.\n", clk_str.c_str()); + + std::string tempdir_name = "/tmp/yosys-abc-XXXXXX"; + if (!cleanup) + tempdir_name[0] = tempdir_name[4] = '_'; + tempdir_name = make_temp_dir(tempdir_name); + log_header(design, "Extracting gate netlist of module `%s' to `%s/input.xaig'..\n", + module->name.c_str(), replace_tempdir(tempdir_name, tempdir_name, show_tempdir).c_str()); + + std::string abc9_script; + + if (!lut_costs.empty()) { + abc9_script += stringf("read_lut %s/lutdefs.txt; ", tempdir_name.c_str()); + if (!box_file.empty()) + abc9_script += stringf("read_box -v %s; ", box_file.c_str()); + } + else + if (!lut_file.empty()) { + abc9_script += stringf("read_lut %s; ", lut_file.c_str()); + if (!box_file.empty()) + abc9_script += stringf("read_box -v %s; ", box_file.c_str()); + } + else + log_abort(); + + abc9_script += stringf("&read %s/input.xaig; &ps; ", tempdir_name.c_str()); + + if (!script_file.empty()) { + if (script_file[0] == '+') { + for (size_t i = 1; i < script_file.size(); i++) + if (script_file[i] == '\'') + abc9_script += "'\\''"; + else if (script_file[i] == ',') + abc9_script += " "; + else + abc9_script += script_file[i]; + } else + abc9_script += stringf("source %s", script_file.c_str()); + } else if (!lut_costs.empty() || !lut_file.empty()) { + //bool all_luts_cost_same = true; + //for (int this_cost : lut_costs) + // if (this_cost != lut_costs.front()) + // all_luts_cost_same = false; + abc9_script += fast_mode ? ABC_FAST_COMMAND_LUT : ABC_COMMAND_LUT; + //if (all_luts_cost_same && !fast_mode) + // abc9_script += "; lutpack {S}"; + } else + log_abort(); + + //if (script_file.empty() && !delay_target.empty()) + // for (size_t pos = abc9_script.find("dretime;"); pos != std::string::npos; pos = abc9_script.find("dretime;", pos+1)) + // abc9_script = abc9_script.substr(0, pos) + "dretime; retime -o {D};" + abc9_script.substr(pos+8); + + for (size_t pos = abc9_script.find("{D}"); pos != std::string::npos; pos = abc9_script.find("{D}", pos)) + abc9_script = abc9_script.substr(0, pos) + delay_target + abc9_script.substr(pos+3); + + //for (size_t pos = abc9_script.find("{S}"); pos != std::string::npos; pos = abc9_script.find("{S}", pos)) + // abc9_script = abc9_script.substr(0, pos) + lutin_shared + abc9_script.substr(pos+3); + + for (size_t pos = abc9_script.find("{W}"); pos != std::string::npos; pos = abc9_script.find("{W}", pos)) + abc9_script = abc9_script.substr(0, pos) + wire_delay + abc9_script.substr(pos+3); + + if (nomfs) + for (size_t pos = abc9_script.find("&mfs"); pos != std::string::npos; pos = abc9_script.find("&mfs", pos)) + abc9_script = abc9_script.erase(pos, strlen("&mfs")); + + abc9_script += stringf("; &write %s/output.aig", tempdir_name.c_str()); + abc9_script = add_echos_to_abc9_cmd(abc9_script); + + for (size_t i = 0; i+1 < abc9_script.size(); i++) + if (abc9_script[i] == ';' && abc9_script[i+1] == ' ') + abc9_script[i+1] = '\n'; + + FILE *f = fopen(stringf("%s/abc.script", tempdir_name.c_str()).c_str(), "wt"); + fprintf(f, "%s\n", abc9_script.c_str()); + fclose(f); + + if (dff_mode || !clk_str.empty()) + { + if (clk_sig.size() == 0) + log("No%s clock domain found. Not extracting any FF cells.\n", clk_str.empty() ? "" : " matching"); + else { + log("Found%s %s clock domain: %s", clk_str.empty() ? "" : " matching", clk_polarity ? "posedge" : "negedge", log_signal(clk_sig)); + if (en_sig.size() != 0) + log(", enabled by %s%s", en_polarity ? "" : "!", log_signal(en_sig)); + log("\n"); + } + } + + bool count_output = false; + for (auto port_name : module->ports) { + RTLIL::Wire *port_wire = module->wire(port_name); + log_assert(port_wire); + if (port_wire->port_output) { + count_output = true; + break; + } + } + + log_push(); + + if (count_output) + { + design->selection_stack.emplace_back(false); + RTLIL::Selection& sel = design->selection_stack.back(); + sel.select(module); + + handle_loops(design); + + Pass::call(design, "aigmap"); + + //log("Extracted %d gates and %d wires to a netlist network with %d inputs and %d outputs.\n", + // count_gates, GetSize(signal_list), count_input, count_output); + + Pass::call(design, stringf("write_xaiger -map %s/input.sym %s/input.xaig", tempdir_name.c_str(), tempdir_name.c_str())); + + std::string buffer; + std::ifstream ifs; +#if 0 + buffer = stringf("%s/%s", tempdir_name.c_str(), "input.xaig"); + ifs.open(buffer); + if (ifs.fail()) + log_error("Can't open ABC output file `%s'.\n", buffer.c_str()); + buffer = stringf("%s/%s", tempdir_name.c_str(), "input.sym"); + log_assert(!design->module(ID($__abc9__))); + { + AigerReader reader(design, ifs, ID($__abc9__), "" /* clk_name */, buffer.c_str() /* map_filename */, true /* wideports */); + reader.parse_xaiger(); + } + ifs.close(); + Pass::call(design, stringf("write_verilog -noexpr -norename")); + design->remove(design->module(ID($__abc9__))); +#endif + + design->selection_stack.pop_back(); + + log_header(design, "Executing ABC9_MAP.\n"); + + if (!lut_costs.empty()) { + buffer = stringf("%s/lutdefs.txt", tempdir_name.c_str()); + f = fopen(buffer.c_str(), "wt"); + if (f == NULL) + log_error("Opening %s for writing failed: %s\n", buffer.c_str(), strerror(errno)); + for (int i = 0; i < GetSize(lut_costs); i++) + fprintf(f, "%d %d.00 1.00\n", i+1, lut_costs.at(i)); + fclose(f); + } + + buffer = stringf("%s -s -f %s/abc.script 2>&1", exe_file.c_str(), tempdir_name.c_str()); + log("Running ABC command: %s\n", replace_tempdir(buffer, tempdir_name, show_tempdir).c_str()); + +#ifndef YOSYS_LINK_ABC + abc9_output_filter filt(tempdir_name, show_tempdir); + int ret = run_command(buffer, std::bind(&abc9_output_filter::next_line, filt, std::placeholders::_1)); +#else + // These needs to be mutable, supposedly due to getopt + char *abc9_argv[5]; + string tmp_script_name = stringf("%s/abc.script", tempdir_name.c_str()); + abc9_argv[0] = strdup(exe_file.c_str()); + abc9_argv[1] = strdup("-s"); + abc9_argv[2] = strdup("-f"); + abc9_argv[3] = strdup(tmp_script_name.c_str()); + abc9_argv[4] = 0; + int ret = Abc_RealMain(4, abc9_argv); + free(abc9_argv[0]); + free(abc9_argv[1]); + free(abc9_argv[2]); + free(abc9_argv[3]); +#endif + if (ret != 0) + log_error("ABC: execution of command \"%s\" failed: return code %d.\n", buffer.c_str(), ret); + + buffer = stringf("%s/%s", tempdir_name.c_str(), "output.aig"); + ifs.open(buffer, std::ifstream::binary); + if (ifs.fail()) + log_error("Can't open ABC output file `%s'.\n", buffer.c_str()); + + buffer = stringf("%s/%s", tempdir_name.c_str(), "input.sym"); + log_assert(!design->module(ID($__abc9__))); + + AigerReader reader(design, ifs, ID($__abc9__), "" /* clk_name */, buffer.c_str() /* map_filename */, true /* wideports */); + reader.parse_xaiger(box_lookup); + ifs.close(); + +#if 0 + Pass::call(design, stringf("write_verilog -noexpr -norename")); +#endif + + log_header(design, "Re-integrating ABC9 results.\n"); + RTLIL::Module *mapped_mod = design->module(ID($__abc9__)); + if (mapped_mod == NULL) + log_error("ABC output file does not contain a module `$__abc9__'.\n"); + + pool output_bits; + for (auto &it : mapped_mod->wires_) { + RTLIL::Wire *w = it.second; + RTLIL::Wire *remap_wire = module->addWire(remap_name(w->name), GetSize(w)); + if (markgroups) remap_wire->attributes[ID(abcgroup)] = map_autoidx; + if (w->port_output) { + RTLIL::Wire *wire = module->wire(w->name); + log_assert(wire); + for (int i = 0; i < GetSize(w); i++) + output_bits.insert({wire, i}); + } + } + + for (auto &it : module->connections_) { + auto &signal = it.first; + auto bits = signal.bits(); + for (auto &b : bits) + if (output_bits.count(b)) + b = module->addWire(NEW_ID); + signal = std::move(bits); + } + + dict abc9_box; + vector boxes; + for (const auto &it : module->cells_) { + auto cell = it.second; + if (cell->type.in(ID($_AND_), ID($_NOT_))) { + module->remove(cell); + continue; + } + auto jt = abc9_box.find(cell->type); + if (jt == abc9_box.end()) { + RTLIL::Module* box_module = design->module(cell->type); + jt = abc9_box.insert(std::make_pair(cell->type, box_module && box_module->attributes.count(ID(abc9_box_id)))).first; + } + if (jt->second) + boxes.emplace_back(cell); + } + + dict> bit_drivers, bit_users; + TopoSort toposort; + dict not2drivers; + dict> bit2sinks; + + std::map cell_stats; + for (auto c : mapped_mod->cells()) + { + toposort.node(c->name); + + RTLIL::Cell *cell = nullptr; + if (c->type == ID($_NOT_)) { + RTLIL::SigBit a_bit = c->getPort(ID::A); + RTLIL::SigBit y_bit = c->getPort(ID::Y); + bit_users[a_bit].insert(c->name); + bit_drivers[y_bit].insert(c->name); + + if (!a_bit.wire) { + c->setPort(ID::Y, module->addWire(NEW_ID)); + RTLIL::Wire *wire = module->wire(remap_name(y_bit.wire->name)); + log_assert(wire); + module->connect(RTLIL::SigBit(wire, y_bit.offset), State::S1); + } + else if (!lut_costs.empty() || !lut_file.empty()) { + RTLIL::Cell* driver_lut = nullptr; + // ABC can return NOT gates that drive POs + if (!a_bit.wire->port_input) { + // If it's not a NOT gate that that comes from a PI directly, + // find the driver LUT and clone that to guarantee that we won't + // increase the max logic depth + // (TODO: Optimise by not cloning unless will increase depth) + RTLIL::IdString driver_name; + if (GetSize(a_bit.wire) == 1) + driver_name = stringf("%s$lut", a_bit.wire->name.c_str()); + else + driver_name = stringf("%s[%d]$lut", a_bit.wire->name.c_str(), a_bit.offset); + driver_lut = mapped_mod->cell(driver_name); + } + + if (!driver_lut) { + // If a driver couldn't be found (could be from PI or box CI) + // then implement using a LUT + cell = module->addLut(remap_name(stringf("%s$lut", c->name.c_str())), + RTLIL::SigBit(module->wires_.at(remap_name(a_bit.wire->name)), a_bit.offset), + RTLIL::SigBit(module->wires_.at(remap_name(y_bit.wire->name)), y_bit.offset), + RTLIL::Const::from_string("01")); + bit2sinks[cell->getPort(ID::A)].push_back(cell); + cell_stats[ID($lut)]++; + } + else + not2drivers[c] = driver_lut; + continue; + } + else + log_abort(); + if (cell && markgroups) cell->attributes[ID(abcgroup)] = map_autoidx; + continue; + } + cell_stats[c->type]++; + + RTLIL::Cell *existing_cell = nullptr; + if (c->type == ID($lut)) { + if (GetSize(c->getPort(ID::A)) == 1 && c->getParam(ID(LUT)) == RTLIL::Const::from_string("01")) { + SigSpec my_a = module->wires_.at(remap_name(c->getPort(ID::A).as_wire()->name)); + SigSpec my_y = module->wires_.at(remap_name(c->getPort(ID::Y).as_wire()->name)); + module->connect(my_y, my_a); + if (markgroups) c->attributes[ID(abcgroup)] = map_autoidx; + log_abort(); + continue; + } + cell = module->addCell(remap_name(c->name), c->type); + } + else { + existing_cell = module->cell(c->name); + log_assert(existing_cell); + cell = module->addCell(remap_name(c->name), c->type); + } + + if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx; + if (existing_cell) { + cell->parameters = existing_cell->parameters; + cell->attributes = existing_cell->attributes; + } + else { + cell->parameters = c->parameters; + cell->attributes = c->attributes; + } + for (auto &conn : c->connections()) { + RTLIL::SigSpec newsig; + for (auto c : conn.second.chunks()) { + if (c.width == 0) + continue; + //log_assert(c.width == 1); + if (c.wire) + c.wire = module->wires_.at(remap_name(c.wire->name)); + newsig.append(c); + } + cell->setPort(conn.first, newsig); + + if (cell->input(conn.first)) { + for (auto i : newsig) + bit2sinks[i].push_back(cell); + for (auto i : conn.second) + bit_users[i].insert(c->name); + } + if (cell->output(conn.first)) + for (auto i : conn.second) + bit_drivers[i].insert(c->name); + } + } + + for (auto existing_cell : boxes) { + Cell *cell = module->cell(remap_name(existing_cell->name)); + if (cell) { + for (auto &conn : existing_cell->connections()) { + if (!conn.second.is_wire()) + continue; + Wire *wire = conn.second.as_wire(); + if (!wire->get_bool_attribute(ID(abc9_padding))) + continue; + cell->unsetPort(conn.first); + log_debug("Dropping padded port connection for %s (%s) .%s (%s )\n", log_id(cell), cell->type.c_str(), log_id(conn.first), log_signal(conn.second)); + } + module->swap_names(cell, existing_cell); + } + module->remove(existing_cell); + } + + // Copy connections (and rename) from mapped_mod to module + for (auto conn : mapped_mod->connections()) { + if (!conn.first.is_fully_const()) { + auto chunks = conn.first.chunks(); + for (auto &c : chunks) + c.wire = module->wires_.at(remap_name(c.wire->name)); + conn.first = std::move(chunks); + } + if (!conn.second.is_fully_const()) { + auto chunks = conn.second.chunks(); + for (auto &c : chunks) + if (c.wire) + c.wire = module->wires_.at(remap_name(c.wire->name)); + conn.second = std::move(chunks); + } + module->connect(conn); + } + + for (auto &it : cell_stats) + log("ABC RESULTS: %15s cells: %8d\n", it.first.c_str(), it.second); + int in_wires = 0, out_wires = 0; + + // Stitch in mapped_mod's inputs/outputs into module + for (auto port : mapped_mod->ports) { + RTLIL::Wire *w = mapped_mod->wire(port); + RTLIL::Wire *wire = module->wire(port); + log_assert(wire); + RTLIL::Wire *remap_wire = module->wire(remap_name(port)); + RTLIL::SigSpec signal = RTLIL::SigSpec(wire, 0, GetSize(remap_wire)); + log_assert(GetSize(signal) >= GetSize(remap_wire)); + + RTLIL::SigSig conn; + if (w->port_output) { + conn.first = signal; + conn.second = remap_wire; + out_wires++; + module->connect(conn); + } + else if (w->port_input) { + conn.first = remap_wire; + conn.second = signal; + in_wires++; + module->connect(conn); + } + } + + for (auto &it : bit_users) + if (bit_drivers.count(it.first)) + for (auto driver_cell : bit_drivers.at(it.first)) + for (auto user_cell : it.second) + toposort.edge(driver_cell, user_cell); + bool no_loops YS_ATTRIBUTE(unused) = toposort.sort(); + log_assert(no_loops); + + for (auto ii = toposort.sorted.rbegin(); ii != toposort.sorted.rend(); ii++) { + RTLIL::Cell *not_cell = mapped_mod->cell(*ii); + log_assert(not_cell); + if (not_cell->type != ID($_NOT_)) + continue; + auto it = not2drivers.find(not_cell); + if (it == not2drivers.end()) + continue; + RTLIL::Cell *driver_lut = it->second; + RTLIL::SigBit a_bit = not_cell->getPort(ID::A); + RTLIL::SigBit y_bit = not_cell->getPort(ID::Y); + RTLIL::Const driver_mask; + + a_bit.wire = module->wires_.at(remap_name(a_bit.wire->name)); + y_bit.wire = module->wires_.at(remap_name(y_bit.wire->name)); + + auto jt = bit2sinks.find(a_bit); + if (jt == bit2sinks.end()) + goto clone_lut; + + for (auto sink_cell : jt->second) + if (sink_cell->type != ID($lut)) + goto clone_lut; + + // Push downstream LUTs past inverter + for (auto sink_cell : jt->second) { + SigSpec A = sink_cell->getPort(ID::A); + RTLIL::Const mask = sink_cell->getParam(ID(LUT)); + int index = 0; + for (; index < GetSize(A); index++) + if (A[index] == a_bit) + break; + log_assert(index < GetSize(A)); + int i = 0; + while (i < GetSize(mask)) { + for (int j = 0; j < (1 << index); j++) + std::swap(mask[i+j], mask[i+j+(1 << index)]); + i += 1 << (index+1); + } + A[index] = y_bit; + sink_cell->setPort(ID::A, A); + sink_cell->setParam(ID(LUT), mask); + } + + // Since we have rewritten all sinks (which we know + // to be only LUTs) to be after the inverter, we can + // go ahead and clone the LUT with the expectation + // that the original driving LUT will become dangling + // and get cleaned away +clone_lut: + driver_mask = driver_lut->getParam(ID(LUT)); + for (auto &b : driver_mask.bits) { + if (b == RTLIL::State::S0) b = RTLIL::State::S1; + else if (b == RTLIL::State::S1) b = RTLIL::State::S0; + } + auto cell = module->addLut(NEW_ID, + driver_lut->getPort(ID::A), + y_bit, + driver_mask); + for (auto &bit : cell->connections_.at(ID::A)) { + bit.wire = module->wires_.at(remap_name(bit.wire->name)); + bit2sinks[bit].push_back(cell); + } + } + + // Now 'unexpose' those wires by undoing + // the expose operation -- remove them from PO/PI + // and re-connecting them back together + for (auto wire : module->wires()) { + auto it = wire->attributes.find(ID(abc9_scc_break)); + if (it != wire->attributes.end()) { + wire->attributes.erase(it); + log_assert(wire->port_output); + wire->port_output = false; + std::string name = wire->name.str(); + RTLIL::Wire *i_wire = module->wire(name.substr(0, GetSize(name) - 5)); + log_assert(i_wire); + log_assert(i_wire->port_input); + i_wire->port_input = false; + module->connect(i_wire, wire); + } + } + module->fixup_ports(); + + //log("ABC RESULTS: internal signals: %8d\n", int(signal_list.size()) - in_wires - out_wires); + log("ABC RESULTS: input signals: %8d\n", in_wires); + log("ABC RESULTS: output signals: %8d\n", out_wires); + + design->remove(mapped_mod); + } + else + { + log("Don't call ABC as there is nothing to map.\n"); + } + + if (cleanup) + { + log("Removing temp directory.\n"); + remove_directory(tempdir_name); + } + + log_pop(); +} + +struct Abc9TechmapPass : public Pass { + Abc9TechmapPass() : 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 \n"); +#ifdef ABCEXTERNAL + log(" use the specified command instead of \"" ABCEXTERNAL "\" to execute ABC.\n"); +#else + log(" use the specified command instead of \"/yosys-abc\" to execute ABC.\n"); +#endif + log(" This can e.g. be used to call a specific version of ABC or a wrapper.\n"); + log("\n"); + log(" -script \n"); + log(" use the specified ABC script file instead of the default script.\n"); + log("\n"); + log(" if starts with a plus sign (+), then the rest of the filename\n"); + log(" string is interpreted as the command string to be passed to ABC. The\n"); + log(" leading plus sign is removed and all commas (,) in the string are\n"); + log(" replaced with blanks before the string is passed to ABC.\n"); + log("\n"); + log(" if no -script parameter is given, the following scripts are used:\n"); + log("\n"); + log(" for -lut/-luts (only one LUT size):\n"); + log("%s\n", fold_abc9_cmd(ABC_COMMAND_LUT /*"; lutpack {S}"*/).c_str()); + log("\n"); + log(" for -lut/-luts (different LUT sizes):\n"); + log("%s\n", fold_abc9_cmd(ABC_COMMAND_LUT).c_str()); + log("\n"); + log(" -fast\n"); + log(" use different default scripts that are slightly faster (at the cost\n"); + log(" of output quality):\n"); + log("\n"); + log(" for -lut/-luts:\n"); + log("%s\n", fold_abc9_cmd(ABC_FAST_COMMAND_LUT).c_str()); + log("\n"); + log(" -D \n"); + log(" set delay target. the string {D} in the default scripts above is\n"); + log(" replaced by this option when used, and an empty string otherwise\n"); + log(" (indicating best possible delay).\n"); +// log(" This also replaces 'dretime' with 'dretime; retime -o {D}' in the\n"); +// log(" default scripts above.\n"); + log("\n"); +// log(" -S \n"); +// log(" maximum number of LUT inputs shared.\n"); +// log(" (replaces {S} in the default scripts above, default: -S 1)\n"); +// log("\n"); + log(" -lut \n"); + log(" generate netlist using luts of (max) the specified width.\n"); + log("\n"); + log(" -lut :\n"); + log(" generate netlist using luts of (max) the specified width . All\n"); + log(" luts with width <= have constant cost. for luts larger than \n"); + log(" the area cost doubles with each additional input bit. the delay cost\n"); + log(" is still constant for all lut widths.\n"); + log("\n"); + log(" -lut \n"); + log(" pass this file with lut library to ABC.\n"); + log("\n"); + log(" -luts ,,,:,..\n"); + log(" generate netlist using luts. Use the specified costs for luts with 1,\n"); + log(" 2, 3, .. inputs.\n"); + log("\n"); +// log(" -dff\n"); +// log(" also pass $_DFF_?_ and $_DFFE_??_ cells through ABC. modules with many\n"); +// log(" clock domains are automatically partitioned in clock domains and each\n"); +// log(" domain is passed through ABC independently.\n"); +// log("\n"); +// log(" -clk [!][,[!]]\n"); +// log(" use only the specified clock domain. this is like -dff, but only FF\n"); +// log(" cells that belong to the specified clock domain are used.\n"); +// log("\n"); +// log(" -keepff\n"); +// log(" set the \"keep\" attribute on flip-flop output wires. (and thus preserve\n"); +// log(" them, for example for equivalence checking.)\n"); +// log("\n"); + log(" -nocleanup\n"); + log(" when this option is used, the temporary files created by this pass\n"); + log(" are not removed. this is useful for debugging.\n"); + log("\n"); + log(" -showtmp\n"); + log(" print the temp dir name in log. usually this is suppressed so that the\n"); + log(" command output is identical across runs.\n"); + log("\n"); + log(" -markgroups\n"); + log(" set a 'abcgroup' attribute on all objects created by ABC. The value of\n"); + log(" this attribute is a unique integer for each ABC process started. This\n"); + log(" is useful for debugging the partitioning of clock domains.\n"); + log("\n"); + log(" -box \n"); + log(" pass this file with box library to ABC. Use with -lut.\n"); + log("\n"); + log("Note that this is a logic optimization pass within Yosys that is calling ABC\n"); + log("internally. This is not going to \"run ABC on your design\". It will instead run\n"); + log("ABC on logic snippets extracted from your design. You will not get any useful\n"); + log("output when passing an ABC script that writes a file. Instead write your full\n"); + log("design as BLIF file with write_blif and then load that into ABC externally if\n"); + log("you want to use ABC to convert your design into another format.\n"); + log("\n"); + log("[1] http://www.eecs.berkeley.edu/~alanmi/abc/\n"); + log("\n"); + } + void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE + { + log_header(design, "Executing ABC9 pass (technology mapping using ABC9).\n"); + log_push(); + + assign_map.clear(); + +#ifdef ABCEXTERNAL + std::string exe_file = ABCEXTERNAL; +#else + std::string exe_file = proc_self_dirname() + "yosys-abc"; +#endif + std::string script_file, clk_str, box_file, lut_file; + std::string delay_target, lutin_shared = "-S 1", wire_delay; + bool fast_mode = false, dff_mode = false, keepff = false, cleanup = true; + bool show_tempdir = false; + bool nomfs = false; + vector lut_costs; + markgroups = false; + +#if 0 + cleanup = false; + show_tempdir = true; +#endif + +#ifdef _WIN32 +#ifndef ABCEXTERNAL + if (!check_file_exists(exe_file + ".exe") && check_file_exists(proc_self_dirname() + "..\\yosys-abc.exe")) + exe_file = proc_self_dirname() + "..\\yosys-abc"; +#endif +#endif + + size_t argidx; + char pwd [PATH_MAX]; + if (!getcwd(pwd, sizeof(pwd))) { + log_cmd_error("getcwd failed: %s\n", strerror(errno)); + log_abort(); + } + for (argidx = 1; argidx < args.size(); argidx++) { + std::string arg = args[argidx]; + if (arg == "-exe" && argidx+1 < args.size()) { + exe_file = args[++argidx]; + continue; + } + if (arg == "-script" && argidx+1 < args.size()) { + script_file = args[++argidx]; + rewrite_filename(script_file); + if (!script_file.empty() && !is_absolute_path(script_file) && script_file[0] != '+') + script_file = std::string(pwd) + "/" + script_file; + continue; + } + if (arg == "-D" && argidx+1 < args.size()) { + delay_target = "-D " + args[++argidx]; + continue; + } + //if (arg == "-S" && argidx+1 < args.size()) { + // lutin_shared = "-S " + args[++argidx]; + // continue; + //} + if (arg == "-lut" && argidx+1 < args.size()) { + string arg = args[++argidx]; + if (arg.find_first_not_of("0123456789:") == std::string::npos) { + size_t pos = arg.find_first_of(':'); + int lut_mode = 0, lut_mode2 = 0; + if (pos != string::npos) { + lut_mode = atoi(arg.substr(0, pos).c_str()); + lut_mode2 = atoi(arg.substr(pos+1).c_str()); + } else { + lut_mode = atoi(arg.c_str()); + lut_mode2 = lut_mode; + } + lut_costs.clear(); + for (int i = 0; i < lut_mode; i++) + lut_costs.push_back(1); + for (int i = lut_mode; i < lut_mode2; i++) + lut_costs.push_back(2 << (i - lut_mode)); + } + else { + lut_file = arg; + rewrite_filename(lut_file); + if (!lut_file.empty() && !is_absolute_path(lut_file) && lut_file[0] != '+') + lut_file = std::string(pwd) + "/" + lut_file; + } + continue; + } + if (arg == "-luts" && argidx+1 < args.size()) { + lut_costs.clear(); + for (auto &tok : split_tokens(args[++argidx], ",")) { + auto parts = split_tokens(tok, ":"); + if (GetSize(parts) == 0 && !lut_costs.empty()) + lut_costs.push_back(lut_costs.back()); + else if (GetSize(parts) == 1) + lut_costs.push_back(atoi(parts.at(0).c_str())); + else if (GetSize(parts) == 2) + while (GetSize(lut_costs) < atoi(parts.at(0).c_str())) + lut_costs.push_back(atoi(parts.at(1).c_str())); + else + log_cmd_error("Invalid -luts syntax.\n"); + } + continue; + } + if (arg == "-fast") { + fast_mode = true; + continue; + } + //if (arg == "-dff") { + // dff_mode = true; + // continue; + //} + //if (arg == "-clk" && argidx+1 < args.size()) { + // clk_str = args[++argidx]; + // dff_mode = true; + // continue; + //} + //if (arg == "-keepff") { + // keepff = true; + // continue; + //} + if (arg == "-nocleanup") { + cleanup = false; + continue; + } + if (arg == "-showtmp") { + show_tempdir = true; + continue; + } + if (arg == "-markgroups") { + markgroups = true; + continue; + } + if (arg == "-box" && argidx+1 < args.size()) { + box_file = args[++argidx]; + continue; + } + if (arg == "-W" && argidx+1 < args.size()) { + wire_delay = "-W " + args[++argidx]; + continue; + } + if (arg == "-nomfs") { + nomfs = true; + continue; + } + break; + } + extra_args(args, argidx, design); + + // ABC expects a box file for XAIG + if (box_file.empty()) + box_file = "+/dummy.box"; + + rewrite_filename(box_file); + if (!box_file.empty() && !is_absolute_path(box_file) && box_file[0] != '+') + box_file = std::string(pwd) + "/" + box_file; + + dict box_lookup; + for (auto m : design->modules()) { + auto it = m->attributes.find(ID(abc9_box_id)); + if (it == m->attributes.end()) + continue; + if (m->name.begins_with("$paramod")) + continue; + auto id = it->second.as_int(); + auto r = box_lookup.insert(std::make_pair(id, m->name)); + if (!r.second) + log_error("Module '%s' has the same abc9_box_id = %d value as '%s'.\n", + log_id(m), id, log_id(r.first->second)); + log_assert(r.second); + + RTLIL::Wire *carry_in = nullptr, *carry_out = nullptr; + for (auto p : m->ports) { + auto w = m->wire(p); + log_assert(w); + if (w->attributes.count(ID(abc9_carry))) { + if (w->port_input) { + if (carry_in) + log_error("Module '%s' contains more than one 'abc9_carry' input port.\n", log_id(m)); + carry_in = w; + } + else if (w->port_output) { + if (carry_out) + log_error("Module '%s' contains more than one 'abc9_carry' input port.\n", log_id(m)); + carry_out = w; + } + } + } + if (carry_in || carry_out) { + if (carry_in && !carry_out) + log_error("Module '%s' contains an 'abc9_carry' input port but no output port.\n", log_id(m)); + if (!carry_in && carry_out) + log_error("Module '%s' contains an 'abc9_carry' output port but no input port.\n", log_id(m)); + // Make carry_in the last PI, and carry_out the last PO + // since ABC requires it this way + auto &ports = m->ports; + for (auto it = ports.begin(); it != ports.end(); ) { + RTLIL::Wire* w = m->wire(*it); + log_assert(w); + if (w == carry_in || w == carry_out) { + it = ports.erase(it); + continue; + } + if (w->port_id > carry_in->port_id) + --w->port_id; + if (w->port_id > carry_out->port_id) + --w->port_id; + log_assert(w->port_input || w->port_output); + log_assert(ports[w->port_id-1] == w->name); + ++it; + } + ports.push_back(carry_in->name); + carry_in->port_id = ports.size(); + ports.push_back(carry_out->name); + carry_out->port_id = ports.size(); + } + } + + for (auto mod : design->selected_modules()) + { + if (mod->attributes.count(ID(abc9_box_id))) + continue; + + if (mod->processes.size() > 0) { + log("Skipping module %s as it contains processes.\n", log_id(mod)); + continue; + } + + assign_map.set(mod); + + if (!dff_mode || !clk_str.empty()) { + abc9_module(design, mod, script_file, exe_file, cleanup, lut_costs, dff_mode, clk_str, keepff, + delay_target, lutin_shared, fast_mode, show_tempdir, + box_file, lut_file, wire_delay, box_lookup, nomfs); + continue; + } + + CellTypes ct(design); + + std::vector all_cells = mod->selected_cells(); + std::set unassigned_cells(all_cells.begin(), all_cells.end()); + + std::set expand_queue, next_expand_queue; + std::set expand_queue_up, next_expand_queue_up; + std::set expand_queue_down, next_expand_queue_down; + + typedef tuple clkdomain_t; + std::map> assigned_cells; + std::map assigned_cells_reverse; + + std::map> cell_to_bit, cell_to_bit_up, cell_to_bit_down; + std::map> bit_to_cell, bit_to_cell_up, bit_to_cell_down; + + for (auto cell : all_cells) + { + clkdomain_t key; + + for (auto &conn : cell->connections()) + for (auto bit : conn.second) { + bit = assign_map(bit); + if (bit.wire != nullptr) { + cell_to_bit[cell].insert(bit); + bit_to_cell[bit].insert(cell); + if (ct.cell_input(cell->type, conn.first)) { + cell_to_bit_up[cell].insert(bit); + bit_to_cell_down[bit].insert(cell); + } + if (ct.cell_output(cell->type, conn.first)) { + cell_to_bit_down[cell].insert(bit); + bit_to_cell_up[bit].insert(cell); + } + } + } + + if (cell->type.in(ID($_DFF_N_), ID($_DFF_P_))) + { + key = clkdomain_t(cell->type == ID($_DFF_P_), assign_map(cell->getPort(ID(C))), true, RTLIL::SigSpec()); + } + else + if (cell->type.in(ID($_DFFE_NN_), ID($_DFFE_NP_), ID($_DFFE_PN_), ID($_DFFE_PP_))) + { + bool this_clk_pol = cell->type.in(ID($_DFFE_PN_), ID($_DFFE_PP_)); + bool this_en_pol = cell->type.in(ID($_DFFE_NP_), ID($_DFFE_PP_)); + key = clkdomain_t(this_clk_pol, assign_map(cell->getPort(ID(C))), this_en_pol, assign_map(cell->getPort(ID(E)))); + } + else + continue; + + unassigned_cells.erase(cell); + expand_queue.insert(cell); + expand_queue_up.insert(cell); + expand_queue_down.insert(cell); + + assigned_cells[key].push_back(cell); + assigned_cells_reverse[cell] = key; + } + + while (!expand_queue_up.empty() || !expand_queue_down.empty()) + { + if (!expand_queue_up.empty()) + { + RTLIL::Cell *cell = *expand_queue_up.begin(); + clkdomain_t key = assigned_cells_reverse.at(cell); + expand_queue_up.erase(cell); + + for (auto bit : cell_to_bit_up[cell]) + for (auto c : bit_to_cell_up[bit]) + if (unassigned_cells.count(c)) { + unassigned_cells.erase(c); + next_expand_queue_up.insert(c); + assigned_cells[key].push_back(c); + assigned_cells_reverse[c] = key; + expand_queue.insert(c); + } + } + + if (!expand_queue_down.empty()) + { + RTLIL::Cell *cell = *expand_queue_down.begin(); + clkdomain_t key = assigned_cells_reverse.at(cell); + expand_queue_down.erase(cell); + + for (auto bit : cell_to_bit_down[cell]) + for (auto c : bit_to_cell_down[bit]) + if (unassigned_cells.count(c)) { + unassigned_cells.erase(c); + next_expand_queue_up.insert(c); + assigned_cells[key].push_back(c); + assigned_cells_reverse[c] = key; + expand_queue.insert(c); + } + } + + if (expand_queue_up.empty() && expand_queue_down.empty()) { + expand_queue_up.swap(next_expand_queue_up); + expand_queue_down.swap(next_expand_queue_down); + } + } + + while (!expand_queue.empty()) + { + RTLIL::Cell *cell = *expand_queue.begin(); + clkdomain_t key = assigned_cells_reverse.at(cell); + expand_queue.erase(cell); + + for (auto bit : cell_to_bit.at(cell)) { + for (auto c : bit_to_cell[bit]) + if (unassigned_cells.count(c)) { + unassigned_cells.erase(c); + next_expand_queue.insert(c); + assigned_cells[key].push_back(c); + assigned_cells_reverse[c] = key; + } + bit_to_cell[bit].clear(); + } + + if (expand_queue.empty()) + expand_queue.swap(next_expand_queue); + } + + clkdomain_t key(true, RTLIL::SigSpec(), true, RTLIL::SigSpec()); + for (auto cell : unassigned_cells) { + assigned_cells[key].push_back(cell); + assigned_cells_reverse[cell] = key; + } + + log_header(design, "Summary of detected clock domains:\n"); + for (auto &it : assigned_cells) + log(" %d cells in clk=%s%s, en=%s%s\n", GetSize(it.second), + std::get<0>(it.first) ? "" : "!", log_signal(std::get<1>(it.first)), + std::get<2>(it.first) ? "" : "!", log_signal(std::get<3>(it.first))); + + for (auto &it : assigned_cells) { + clk_polarity = std::get<0>(it.first); + clk_sig = assign_map(std::get<1>(it.first)); + en_polarity = std::get<2>(it.first); + en_sig = assign_map(std::get<3>(it.first)); + abc9_module(design, mod, script_file, exe_file, cleanup, lut_costs, !clk_sig.empty(), "$", + keepff, delay_target, lutin_shared, fast_mode, show_tempdir, + box_file, lut_file, wire_delay, box_lookup, nomfs); + assign_map.set(mod); + } + } + + assign_map.clear(); + + log_pop(); + } +} Abc9TechmapPass; + +PRIVATE_NAMESPACE_END -- cgit v1.2.3 From f348ffa44d4ec00537499ffe79ce627beeeefe85 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Sat, 28 Dec 2019 05:07:46 -0800 Subject: abc9_techmap -> _map; called from abc9 script pass along with abc9_ops --- passes/techmap/Makefile.inc | 3 +- passes/techmap/abc9.cc | 231 +++++++ passes/techmap/abc9_map.cc | 1215 +++++++++++++++++++++++++++++++++++++ passes/techmap/abc9_ops.cc | 139 +++++ passes/techmap/abc9_techmap.cc | 1310 ---------------------------------------- 5 files changed, 1587 insertions(+), 1311 deletions(-) create mode 100644 passes/techmap/abc9.cc create mode 100644 passes/techmap/abc9_map.cc create mode 100644 passes/techmap/abc9_ops.cc delete mode 100644 passes/techmap/abc9_techmap.cc diff --git a/passes/techmap/Makefile.inc b/passes/techmap/Makefile.inc index a7c8d8c2b..734d6c10f 100644 --- a/passes/techmap/Makefile.inc +++ b/passes/techmap/Makefile.inc @@ -8,7 +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_techmap.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/abc9.cc b/passes/techmap/abc9.cc new file mode 100644 index 000000000..e1cf188ce --- /dev/null +++ b/passes/techmap/abc9.cc @@ -0,0 +1,231 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 Clifford Wolf + * (C) 2019 Eddie Hung + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#include "kernel/register.h" +#include "kernel/celltypes.h" +#include "kernel/rtlil.h" +#include "kernel/log.h" + +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + +#define XC7_WIRE_DELAY 300 // Number with which ABC will map a 6-input gate + // to one LUT6 (instead of a LUT5 + LUT2) + +struct Abc9Pass : public ScriptPass +{ + Abc9Pass() : ScriptPass("abc9", "use ABC9 for technology mapping") { } + + void help() YS_OVERRIDE + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" abc9 [options] [selection]\n"); + log("\n"); + log("This pass uses the ABC tool [1] for technology mapping of yosys's internal gate\n"); + log("library to a target architecture.\n"); + log("\n"); + log(" -exe \n"); +#ifdef ABCEXTERNAL + log(" use the specified command instead of \"" ABCEXTERNAL "\" to execute ABC.\n"); +#else + log(" use the specified command instead of \"/yosys-abc\" to execute ABC.\n"); +#endif + log(" This can e.g. be used to call a specific version of ABC or a wrapper.\n"); + log("\n"); + log(" -script \n"); + log(" use the specified ABC script file instead of the default script.\n"); + log("\n"); + log(" if starts with a plus sign (+), then the rest of the filename\n"); + log(" string is interpreted as the command string to be passed to ABC. The\n"); + log(" leading plus sign is removed and all commas (,) in the string are\n"); + log(" replaced with blanks before the string is passed to ABC.\n"); + log("\n"); + log(" if no -script parameter is given, the following scripts are used:\n"); + log("\n"); + log(" for -lut/-luts (only one LUT size):\n"); + // FIXME + //log("%s\n", fold_abc9_cmd(ABC_COMMAND_LUT /*"; lutpack {S}"*/).c_str()); + log("\n"); + log(" for -lut/-luts (different LUT sizes):\n"); + // FIXME + //log("%s\n", fold_abc9_cmd(ABC_COMMAND_LUT).c_str()); + log("\n"); + log(" -fast\n"); + log(" use different default scripts that are slightly faster (at the cost\n"); + log(" of output quality):\n"); + log("\n"); + log(" for -lut/-luts:\n"); + // FIXME + //log("%s\n", fold_abc9_cmd(ABC_FAST_COMMAND_LUT).c_str()); + log("\n"); + log(" -D \n"); + log(" set delay target. the string {D} in the default scripts above is\n"); + log(" replaced by this option when used, and an empty string otherwise\n"); + log(" (indicating best possible delay).\n"); +// log(" This also replaces 'dretime' with 'dretime; retime -o {D}' in the\n"); +// log(" default scripts above.\n"); + log("\n"); +// log(" -S \n"); +// log(" maximum number of LUT inputs shared.\n"); +// log(" (replaces {S} in the default scripts above, default: -S 1)\n"); +// log("\n"); + log(" -lut \n"); + log(" generate netlist using luts of (max) the specified width.\n"); + log("\n"); + log(" -lut :\n"); + log(" generate netlist using luts of (max) the specified width . All\n"); + log(" luts with width <= have constant cost. for luts larger than \n"); + log(" the area cost doubles with each additional input bit. the delay cost\n"); + log(" is still constant for all lut widths.\n"); + log("\n"); + log(" -lut \n"); + log(" pass this file with lut library to ABC.\n"); + log("\n"); + log(" -luts ,,,:,..\n"); + log(" generate netlist using luts. Use the specified costs for luts with 1,\n"); + log(" 2, 3, .. inputs.\n"); + log("\n"); +// log(" -dff\n"); +// log(" also pass $_DFF_?_ and $_DFFE_??_ cells through ABC. modules with many\n"); +// log(" clock domains are automatically partitioned in clock domains and each\n"); +// log(" domain is passed through ABC independently.\n"); +// log("\n"); +// log(" -clk [!][,[!]]\n"); +// log(" use only the specified clock domain. this is like -dff, but only FF\n"); +// log(" cells that belong to the specified clock domain are used.\n"); +// log("\n"); +// log(" -keepff\n"); +// log(" set the \"keep\" attribute on flip-flop output wires. (and thus preserve\n"); +// log(" them, for example for equivalence checking.)\n"); +// log("\n"); + log(" -nocleanup\n"); + log(" when this option is used, the temporary files created by this pass\n"); + log(" are not removed. this is useful for debugging.\n"); + log("\n"); + log(" -showtmp\n"); + log(" print the temp dir name in log. usually this is suppressed so that the\n"); + log(" command output is identical across runs.\n"); + log("\n"); + log(" -markgroups\n"); + log(" set a 'abcgroup' attribute on all objects created by ABC. The value of\n"); + log(" this attribute is a unique integer for each ABC process started. This\n"); + log(" is useful for debugging the partitioning of clock domains.\n"); + log("\n"); + log(" -box \n"); + log(" pass this file with box library to ABC. Use with -lut.\n"); + log("\n"); + log("Note that this is a logic optimization pass within Yosys that is calling ABC\n"); + log("internally. This is not going to \"run ABC on your design\". It will instead run\n"); + log("ABC on logic snippets extracted from your design. You will not get any useful\n"); + log("output when passing an ABC script that writes a file. Instead write your full\n"); + log("design as BLIF file with write_blif and then load that into ABC externally if\n"); + log("you want to use ABC to convert your design into another format.\n"); + log("\n"); + log("[1] http://www.eecs.berkeley.edu/~alanmi/abc/\n"); + log("\n"); + help_script(); + log("\n"); + } + + std::stringstream map_cmd; + bool cleanup; + + void clear_flags() YS_OVERRIDE + { + map_cmd.str(""); + map_cmd << "abc9_map"; + cleanup = true; + } + + void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE + { + std::string run_from, run_to; + clear_flags(); + + size_t argidx; + for (argidx = 1; argidx < args.size(); argidx++) { + std::string arg = args[argidx]; + if ((arg == "-exe" || arg == "-script" || arg == "-D" || + /* arg == "-S" || */ arg == "-lut" || arg == "-luts" || + arg == "-clk" || arg == "-box" || arg == "-W") && + argidx+1 < args.size()) { + map_cmd << " " << arg << " " << args[++argidx]; + continue; + } + if (arg == "-fast" || /*arg == "-dff" ||*/ arg == "-keepff" + /*|| arg == "-nocleanup"*/ || arg == "-showtmp" || arg == "-markgroups" + || arg == "-nomfs") { + map_cmd << " " << arg; + continue; + } + if (arg == "-nocleanup") { + cleanup = false; + continue; + } + break; + } + extra_args(args, argidx, design); + + log_header(design, "Executing ABC9 pass.\n"); + + run_script(design, run_from, run_to); + } + + void script() YS_OVERRIDE + { + auto selected_modules = active_design->selected_modules(); + active_design->selection_stack.emplace_back(false); + + for (auto mod : selected_modules) { + log_push(); + + active_design->selection().select(mod); + + std::string tempdir_name = "/tmp/yosys-abc-XXXXXX"; + if (!cleanup) + tempdir_name[0] = tempdir_name[4] = '_'; + tempdir_name = make_temp_dir(tempdir_name); + + run("scc -set_attr abc9_scc_id {}"); + run("abc9_ops -break_scc"); + run("aigmap"); + run(stringf("write_xaiger -map %s/input.sym %s/input.xaig", tempdir_name.c_str(), tempdir_name.c_str()), + "write_xaiger -map /input.sym /input.xaig"); + run(stringf("%s -tempdir %s", map_cmd.str().c_str(), tempdir_name.c_str()), + "abc9_map [options] -tempdir "); + run("abc9_ops -unbreak_scc"); + + if (cleanup) + { + log("Removing temp directory.\n"); + remove_directory(tempdir_name); + } + + active_design->selection().selected_modules.clear(); + + log_pop(); + } + + active_design->selection_stack.pop_back(); + } +} Abc9Pass; + +PRIVATE_NAMESPACE_END diff --git a/passes/techmap/abc9_map.cc b/passes/techmap/abc9_map.cc new file mode 100644 index 000000000..40ff4bbf0 --- /dev/null +++ b/passes/techmap/abc9_map.cc @@ -0,0 +1,1215 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 Clifford Wolf + * 2019 Eddie Hung + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +// [[CITE]] ABC +// Berkeley Logic Synthesis and Verification Group, ABC: A System for Sequential Synthesis and Verification +// http://www.eecs.berkeley.edu/~alanmi/abc/ + +#if 0 +// Based on &flow3 - better QoR but more experimental +#define ABC_COMMAND_LUT "&st; &ps -l; &sweep -v; &scorr; " \ + "&st; &if {W}; &save; &st; &syn2; &if {W} -v; &save; &load; "\ + "&st; &if -g -K 6; &dch -f; &if {W} -v; &save; &load; "\ + "&st; &if -g -K 6; &synch2; &if {W} -v; &save; &load; "\ + "&mfs; &ps -l" +#else +#define ABC_COMMAND_LUT "&st; &scorr; &sweep; &dc2; &st; &dch -f; &ps; &if {W} {D} -v; &mfs; &ps -l" +#endif + + +#define ABC_FAST_COMMAND_LUT "&st; &if {W} {D}" + +#include "kernel/register.h" +#include "kernel/sigtools.h" +#include "kernel/celltypes.h" +#include "kernel/cost.h" +#include "kernel/log.h" +#include +#include +#include +#include +#include +#include + +#ifndef _WIN32 +# include +# include +#endif + +#include "frontends/aiger/aigerparse.h" +#include "kernel/utils.h" + +#ifdef YOSYS_LINK_ABC +extern "C" int Abc_RealMain(int argc, char *argv[]); +#endif + +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + +bool markgroups; +int map_autoidx; +SigMap assign_map; +RTLIL::Module *module; + +bool clk_polarity, en_polarity; +RTLIL::SigSpec clk_sig, en_sig; + +inline std::string remap_name(RTLIL::IdString abc9_name) +{ + return stringf("$abc$%d$%s", map_autoidx, abc9_name.c_str()+1); +} + +std::string add_echos_to_abc9_cmd(std::string str) +{ + std::string new_str, token; + for (size_t i = 0; i < str.size(); i++) { + token += str[i]; + if (str[i] == ';') { + while (i+1 < str.size() && str[i+1] == ' ') + i++; + new_str += "echo + " + token + " " + token + " "; + token.clear(); + } + } + + if (!token.empty()) { + if (!new_str.empty()) + new_str += "echo + " + token + "; "; + new_str += token; + } + + return new_str; +} + +std::string fold_abc9_cmd(std::string str) +{ + std::string token, new_str = " "; + int char_counter = 10; + + for (size_t i = 0; i <= str.size(); i++) { + if (i < str.size()) + token += str[i]; + if (i == str.size() || str[i] == ';') { + if (char_counter + token.size() > 75) + new_str += "\n ", char_counter = 14; + new_str += token, char_counter += token.size(); + token.clear(); + } + } + + return new_str; +} + +std::string replace_tempdir(std::string text, std::string tempdir_name, bool show_tempdir) +{ + if (show_tempdir) + return text; + + while (1) { + size_t pos = text.find(tempdir_name); + if (pos == std::string::npos) + break; + text = text.substr(0, pos) + "" + text.substr(pos + GetSize(tempdir_name)); + } + + std::string selfdir_name = proc_self_dirname(); + if (selfdir_name != "/") { + while (1) { + size_t pos = text.find(selfdir_name); + if (pos == std::string::npos) + break; + text = text.substr(0, pos) + "/" + text.substr(pos + GetSize(selfdir_name)); + } + } + + return text; +} + +struct abc9_output_filter +{ + bool got_cr; + int escape_seq_state; + std::string linebuf; + std::string tempdir_name; + bool show_tempdir; + + abc9_output_filter(std::string tempdir_name, bool show_tempdir) : tempdir_name(tempdir_name), show_tempdir(show_tempdir) + { + got_cr = false; + escape_seq_state = 0; + } + + void next_char(char ch) + { + if (escape_seq_state == 0 && ch == '\033') { + escape_seq_state = 1; + return; + } + if (escape_seq_state == 1) { + escape_seq_state = ch == '[' ? 2 : 0; + return; + } + if (escape_seq_state == 2) { + if ((ch < '0' || '9' < ch) && ch != ';') + escape_seq_state = 0; + return; + } + escape_seq_state = 0; + if (ch == '\r') { + got_cr = true; + return; + } + if (ch == '\n') { + log("ABC: %s\n", replace_tempdir(linebuf, tempdir_name, show_tempdir).c_str()); + got_cr = false, linebuf.clear(); + return; + } + if (got_cr) + got_cr = false, linebuf.clear(); + linebuf += ch; + } + + void next_line(const std::string &line) + { + //int pi, po; + //if (sscanf(line.c_str(), "Start-point = pi%d. End-point = po%d.", &pi, &po) == 2) { + // log("ABC: Start-point = pi%d (%s). End-point = po%d (%s).\n", + // pi, pi_map.count(pi) ? pi_map.at(pi).c_str() : "???", + // po, po_map.count(po) ? po_map.at(po).c_str() : "???"); + // return; + //} + + for (char ch : line) + next_char(ch); + } +}; + +void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::string script_file, std::string exe_file, + /*bool cleanup,*/ vector lut_costs, bool dff_mode, std::string clk_str, + bool /*keepff*/, std::string delay_target, std::string /*lutin_shared*/, bool fast_mode, + bool show_tempdir, std::string box_file, std::string lut_file, + std::string wire_delay, const dict &box_lookup, bool nomfs, std::string tempdir_name +) +{ + 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()); + + 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"); + } + } + + log_push(); + + //if (count_output) + { + 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 + + log_header(design, "Executing ABC9_MAP.\n"); + + if (!lut_costs.empty()) { + buffer = stringf("%s/lutdefs.txt", tempdir_name.c_str()); + f = fopen(buffer.c_str(), "wt"); + if (f == NULL) + log_error("Opening %s for writing failed: %s\n", buffer.c_str(), strerror(errno)); + for (int i = 0; i < GetSize(lut_costs); i++) + fprintf(f, "%d %d.00 1.00\n", i+1, lut_costs.at(i)); + fclose(f); + } + + buffer = stringf("%s -s -f %s/abc.script 2>&1", exe_file.c_str(), tempdir_name.c_str()); + log("Running ABC command: %s\n", replace_tempdir(buffer, tempdir_name, show_tempdir).c_str()); + +#ifndef YOSYS_LINK_ABC + abc9_output_filter filt(tempdir_name, show_tempdir); + int ret = run_command(buffer, std::bind(&abc9_output_filter::next_line, filt, std::placeholders::_1)); +#else + // These needs to be mutable, supposedly due to getopt + char *abc9_argv[5]; + string tmp_script_name = stringf("%s/abc.script", tempdir_name.c_str()); + abc9_argv[0] = strdup(exe_file.c_str()); + abc9_argv[1] = strdup("-s"); + abc9_argv[2] = strdup("-f"); + abc9_argv[3] = strdup(tmp_script_name.c_str()); + abc9_argv[4] = 0; + int ret = Abc_RealMain(4, abc9_argv); + free(abc9_argv[0]); + free(abc9_argv[1]); + free(abc9_argv[2]); + free(abc9_argv[3]); +#endif + if (ret != 0) + log_error("ABC: execution of command \"%s\" failed: return code %d.\n", buffer.c_str(), ret); + + buffer = stringf("%s/%s", tempdir_name.c_str(), "output.aig"); + ifs.open(buffer, std::ifstream::binary); + if (ifs.fail()) + log_error("Can't open ABC output file `%s'.\n", buffer.c_str()); + + buffer = stringf("%s/%s", tempdir_name.c_str(), "input.sym"); + log_assert(!design->module(ID($__abc9__))); + + AigerReader reader(design, ifs, ID($__abc9__), "" /* clk_name */, buffer.c_str() /* map_filename */, true /* wideports */); + reader.parse_xaiger(box_lookup); + ifs.close(); + +#if 0 + Pass::call(design, stringf("write_verilog -noexpr -norename")); +#endif + + log_header(design, "Re-integrating ABC9 results.\n"); + RTLIL::Module *mapped_mod = design->module(ID($__abc9__)); + if (mapped_mod == NULL) + log_error("ABC output file does not contain a module `$__abc9__'.\n"); + + pool output_bits; + for (auto &it : mapped_mod->wires_) { + RTLIL::Wire *w = it.second; + RTLIL::Wire *remap_wire = module->addWire(remap_name(w->name), GetSize(w)); + if (markgroups) remap_wire->attributes[ID(abcgroup)] = map_autoidx; + if (w->port_output) { + RTLIL::Wire *wire = module->wire(w->name); + log_assert(wire); + for (int i = 0; i < GetSize(w); i++) + output_bits.insert({wire, i}); + } + } + + for (auto &it : module->connections_) { + auto &signal = it.first; + auto bits = signal.bits(); + for (auto &b : bits) + if (output_bits.count(b)) + b = module->addWire(NEW_ID); + signal = std::move(bits); + } + + dict abc9_box; + vector boxes; + for (const auto &it : module->cells_) { + auto cell = it.second; + if (cell->type.in(ID($_AND_), ID($_NOT_))) { + module->remove(cell); + continue; + } + auto jt = abc9_box.find(cell->type); + if (jt == abc9_box.end()) { + RTLIL::Module* box_module = design->module(cell->type); + jt = abc9_box.insert(std::make_pair(cell->type, box_module && box_module->attributes.count(ID(abc9_box_id)))).first; + } + if (jt->second) + boxes.emplace_back(cell); + } + + dict> bit_drivers, bit_users; + TopoSort toposort; + dict not2drivers; + dict> bit2sinks; + + std::map cell_stats; + for (auto c : mapped_mod->cells()) + { + toposort.node(c->name); + + RTLIL::Cell *cell = nullptr; + if (c->type == ID($_NOT_)) { + RTLIL::SigBit a_bit = c->getPort(ID::A); + RTLIL::SigBit y_bit = c->getPort(ID::Y); + bit_users[a_bit].insert(c->name); + bit_drivers[y_bit].insert(c->name); + + if (!a_bit.wire) { + c->setPort(ID::Y, module->addWire(NEW_ID)); + RTLIL::Wire *wire = module->wire(remap_name(y_bit.wire->name)); + log_assert(wire); + module->connect(RTLIL::SigBit(wire, y_bit.offset), State::S1); + } + else if (!lut_costs.empty() || !lut_file.empty()) { + RTLIL::Cell* driver_lut = nullptr; + // ABC can return NOT gates that drive POs + if (!a_bit.wire->port_input) { + // If it's not a NOT gate that that comes from a PI directly, + // find the driver LUT and clone that to guarantee that we won't + // increase the max logic depth + // (TODO: Optimise by not cloning unless will increase depth) + RTLIL::IdString driver_name; + if (GetSize(a_bit.wire) == 1) + driver_name = stringf("%s$lut", a_bit.wire->name.c_str()); + else + driver_name = stringf("%s[%d]$lut", a_bit.wire->name.c_str(), a_bit.offset); + driver_lut = mapped_mod->cell(driver_name); + } + + if (!driver_lut) { + // If a driver couldn't be found (could be from PI or box CI) + // then implement using a LUT + cell = module->addLut(remap_name(stringf("%s$lut", c->name.c_str())), + RTLIL::SigBit(module->wires_.at(remap_name(a_bit.wire->name)), a_bit.offset), + RTLIL::SigBit(module->wires_.at(remap_name(y_bit.wire->name)), y_bit.offset), + RTLIL::Const::from_string("01")); + bit2sinks[cell->getPort(ID::A)].push_back(cell); + cell_stats[ID($lut)]++; + } + else + not2drivers[c] = driver_lut; + continue; + } + else + log_abort(); + if (cell && markgroups) cell->attributes[ID(abcgroup)] = map_autoidx; + continue; + } + cell_stats[c->type]++; + + RTLIL::Cell *existing_cell = nullptr; + if (c->type == ID($lut)) { + if (GetSize(c->getPort(ID::A)) == 1 && c->getParam(ID(LUT)) == RTLIL::Const::from_string("01")) { + SigSpec my_a = module->wires_.at(remap_name(c->getPort(ID::A).as_wire()->name)); + SigSpec my_y = module->wires_.at(remap_name(c->getPort(ID::Y).as_wire()->name)); + module->connect(my_y, my_a); + if (markgroups) c->attributes[ID(abcgroup)] = map_autoidx; + log_abort(); + continue; + } + cell = module->addCell(remap_name(c->name), c->type); + } + else { + existing_cell = module->cell(c->name); + log_assert(existing_cell); + cell = module->addCell(remap_name(c->name), c->type); + } + + if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx; + if (existing_cell) { + cell->parameters = existing_cell->parameters; + cell->attributes = existing_cell->attributes; + } + else { + cell->parameters = c->parameters; + cell->attributes = c->attributes; + } + for (auto &conn : c->connections()) { + RTLIL::SigSpec newsig; + for (auto c : conn.second.chunks()) { + if (c.width == 0) + continue; + //log_assert(c.width == 1); + if (c.wire) + c.wire = module->wires_.at(remap_name(c.wire->name)); + newsig.append(c); + } + cell->setPort(conn.first, newsig); + + if (cell->input(conn.first)) { + for (auto i : newsig) + bit2sinks[i].push_back(cell); + for (auto i : conn.second) + bit_users[i].insert(c->name); + } + if (cell->output(conn.first)) + for (auto i : conn.second) + bit_drivers[i].insert(c->name); + } + } + + for (auto existing_cell : boxes) { + Cell *cell = module->cell(remap_name(existing_cell->name)); + if (cell) { + for (auto &conn : existing_cell->connections()) { + if (!conn.second.is_wire()) + continue; + Wire *wire = conn.second.as_wire(); + if (!wire->get_bool_attribute(ID(abc9_padding))) + continue; + cell->unsetPort(conn.first); + log_debug("Dropping padded port connection for %s (%s) .%s (%s )\n", log_id(cell), cell->type.c_str(), log_id(conn.first), log_signal(conn.second)); + } + module->swap_names(cell, existing_cell); + } + module->remove(existing_cell); + } + + // Copy connections (and rename) from mapped_mod to module + for (auto conn : mapped_mod->connections()) { + if (!conn.first.is_fully_const()) { + auto chunks = conn.first.chunks(); + for (auto &c : chunks) + c.wire = module->wires_.at(remap_name(c.wire->name)); + conn.first = std::move(chunks); + } + if (!conn.second.is_fully_const()) { + auto chunks = conn.second.chunks(); + for (auto &c : chunks) + if (c.wire) + c.wire = module->wires_.at(remap_name(c.wire->name)); + conn.second = std::move(chunks); + } + module->connect(conn); + } + + for (auto &it : cell_stats) + log("ABC RESULTS: %15s cells: %8d\n", it.first.c_str(), it.second); + int in_wires = 0, out_wires = 0; + + // Stitch in mapped_mod's inputs/outputs into module + for (auto port : mapped_mod->ports) { + RTLIL::Wire *w = mapped_mod->wire(port); + RTLIL::Wire *wire = module->wire(port); + log_assert(wire); + RTLIL::Wire *remap_wire = module->wire(remap_name(port)); + RTLIL::SigSpec signal = RTLIL::SigSpec(wire, 0, GetSize(remap_wire)); + log_assert(GetSize(signal) >= GetSize(remap_wire)); + + RTLIL::SigSig conn; + if (w->port_output) { + conn.first = signal; + conn.second = remap_wire; + out_wires++; + module->connect(conn); + } + else if (w->port_input) { + conn.first = remap_wire; + conn.second = signal; + in_wires++; + module->connect(conn); + } + } + + for (auto &it : bit_users) + if (bit_drivers.count(it.first)) + for (auto driver_cell : bit_drivers.at(it.first)) + for (auto user_cell : it.second) + toposort.edge(driver_cell, user_cell); + bool no_loops YS_ATTRIBUTE(unused) = toposort.sort(); + log_assert(no_loops); + + for (auto ii = toposort.sorted.rbegin(); ii != toposort.sorted.rend(); ii++) { + RTLIL::Cell *not_cell = mapped_mod->cell(*ii); + log_assert(not_cell); + if (not_cell->type != ID($_NOT_)) + continue; + auto it = not2drivers.find(not_cell); + if (it == not2drivers.end()) + continue; + RTLIL::Cell *driver_lut = it->second; + RTLIL::SigBit a_bit = not_cell->getPort(ID::A); + RTLIL::SigBit y_bit = not_cell->getPort(ID::Y); + RTLIL::Const driver_mask; + + a_bit.wire = module->wires_.at(remap_name(a_bit.wire->name)); + y_bit.wire = module->wires_.at(remap_name(y_bit.wire->name)); + + auto jt = bit2sinks.find(a_bit); + if (jt == bit2sinks.end()) + goto clone_lut; + + for (auto sink_cell : jt->second) + if (sink_cell->type != ID($lut)) + goto clone_lut; + + // Push downstream LUTs past inverter + for (auto sink_cell : jt->second) { + SigSpec A = sink_cell->getPort(ID::A); + RTLIL::Const mask = sink_cell->getParam(ID(LUT)); + int index = 0; + for (; index < GetSize(A); index++) + if (A[index] == a_bit) + break; + log_assert(index < GetSize(A)); + int i = 0; + while (i < GetSize(mask)) { + for (int j = 0; j < (1 << index); j++) + std::swap(mask[i+j], mask[i+j+(1 << index)]); + i += 1 << (index+1); + } + A[index] = y_bit; + sink_cell->setPort(ID::A, A); + sink_cell->setParam(ID(LUT), mask); + } + + // Since we have rewritten all sinks (which we know + // to be only LUTs) to be after the inverter, we can + // go ahead and clone the LUT with the expectation + // that the original driving LUT will become dangling + // and get cleaned away +clone_lut: + driver_mask = driver_lut->getParam(ID(LUT)); + for (auto &b : driver_mask.bits) { + if (b == RTLIL::State::S0) b = RTLIL::State::S1; + else if (b == RTLIL::State::S1) b = RTLIL::State::S0; + } + auto cell = module->addLut(NEW_ID, + driver_lut->getPort(ID::A), + y_bit, + driver_mask); + for (auto &bit : cell->connections_.at(ID::A)) { + bit.wire = module->wires_.at(remap_name(bit.wire->name)); + bit2sinks[bit].push_back(cell); + } + } + + //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"); + //} + + log_pop(); +} + +struct Abc9TechmapPass : public Pass { + Abc9TechmapPass() : 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 \n"); +#ifdef ABCEXTERNAL + log(" use the specified command instead of \"" ABCEXTERNAL "\" to execute ABC.\n"); +#else + log(" use the specified command instead of \"/yosys-abc\" to execute ABC.\n"); +#endif + log(" This can e.g. be used to call a specific version of ABC or a wrapper.\n"); + log("\n"); + log(" -script \n"); + log(" use the specified ABC script file instead of the default script.\n"); + log("\n"); + log(" if starts with a plus sign (+), then the rest of the filename\n"); + log(" string is interpreted as the command string to be passed to ABC. The\n"); + log(" leading plus sign is removed and all commas (,) in the string are\n"); + log(" replaced with blanks before the string is passed to ABC.\n"); + log("\n"); + log(" if no -script parameter is given, the following scripts are used:\n"); + log("\n"); + log(" for -lut/-luts (only one LUT size):\n"); + log("%s\n", fold_abc9_cmd(ABC_COMMAND_LUT /*"; lutpack {S}"*/).c_str()); + log("\n"); + log(" for -lut/-luts (different LUT sizes):\n"); + log("%s\n", fold_abc9_cmd(ABC_COMMAND_LUT).c_str()); + log("\n"); + log(" -fast\n"); + log(" use different default scripts that are slightly faster (at the cost\n"); + log(" of output quality):\n"); + log("\n"); + log(" for -lut/-luts:\n"); + log("%s\n", fold_abc9_cmd(ABC_FAST_COMMAND_LUT).c_str()); + log("\n"); + log(" -D \n"); + log(" set delay target. the string {D} in the default scripts above is\n"); + log(" replaced by this option when used, and an empty string otherwise\n"); + log(" (indicating best possible delay).\n"); +// log(" This also replaces 'dretime' with 'dretime; retime -o {D}' in the\n"); +// log(" default scripts above.\n"); + log("\n"); +// log(" -S \n"); +// log(" maximum number of LUT inputs shared.\n"); +// log(" (replaces {S} in the default scripts above, default: -S 1)\n"); +// log("\n"); + log(" -lut \n"); + log(" generate netlist using luts of (max) the specified width.\n"); + log("\n"); + log(" -lut :\n"); + log(" generate netlist using luts of (max) the specified width . All\n"); + log(" luts with width <= have constant cost. for luts larger than \n"); + log(" the area cost doubles with each additional input bit. the delay cost\n"); + log(" is still constant for all lut widths.\n"); + log("\n"); + log(" -lut \n"); + log(" pass this file with lut library to ABC.\n"); + log("\n"); + log(" -luts ,,,:,..\n"); + log(" generate netlist using luts. Use the specified costs for luts with 1,\n"); + log(" 2, 3, .. inputs.\n"); + log("\n"); +// log(" -dff\n"); +// log(" also pass $_DFF_?_ and $_DFFE_??_ cells through ABC. modules with many\n"); +// log(" clock domains are automatically partitioned in clock domains and each\n"); +// log(" domain is passed through ABC independently.\n"); +// log("\n"); +// log(" -clk [!][,[!]]\n"); +// log(" use only the specified clock domain. this is like -dff, but only FF\n"); +// log(" cells that belong to the specified clock domain are used.\n"); +// log("\n"); +// log(" -keepff\n"); +// log(" set the \"keep\" attribute on flip-flop output wires. (and thus preserve\n"); +// log(" them, for example for equivalence checking.)\n"); +// log("\n"); +// log(" -nocleanup\n"); +// log(" when this option is used, the temporary files created by this pass\n"); +// log(" are not removed. this is useful for debugging.\n"); +// log("\n"); + log(" -showtmp\n"); + log(" print the temp dir name in log. usually this is suppressed so that the\n"); + log(" command output is identical across runs.\n"); + log("\n"); + log(" -markgroups\n"); + log(" set a 'abcgroup' attribute on all objects created by ABC. The value of\n"); + log(" this attribute is a unique integer for each ABC process started. This\n"); + log(" is useful for debugging the partitioning of clock domains.\n"); + log("\n"); + log(" -box \n"); + log(" pass this file with box library to ABC. Use with -lut.\n"); + log("\n"); + log(" -tempdir \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 args, RTLIL::Design *design) YS_OVERRIDE + { + log_header(design, "Executing ABC9_MAP pass (technology mapping using ABC9).\n"); + log_push(); + + assign_map.clear(); + +#ifdef ABCEXTERNAL + std::string exe_file = ABCEXTERNAL; +#else + std::string exe_file = proc_self_dirname() + "yosys-abc"; +#endif + std::string script_file, clk_str, box_file, lut_file; + std::string delay_target, lutin_shared = "-S 1", wire_delay; + std::string tempdir_name; + bool fast_mode = false, dff_mode = false, keepff = false /*, cleanup = true*/; + bool show_tempdir = false; + bool nomfs = false; + vector lut_costs; + markgroups = false; + +#if 0 + cleanup = false; + show_tempdir = true; +#endif + +#ifdef _WIN32 +#ifndef ABCEXTERNAL + if (!check_file_exists(exe_file + ".exe") && check_file_exists(proc_self_dirname() + "..\\yosys-abc.exe")) + exe_file = proc_self_dirname() + "..\\yosys-abc"; +#endif +#endif + + size_t argidx; + char pwd [PATH_MAX]; + if (!getcwd(pwd, sizeof(pwd))) { + log_cmd_error("getcwd failed: %s\n", strerror(errno)); + log_abort(); + } + for (argidx = 1; argidx < args.size(); argidx++) { + std::string arg = args[argidx]; + if (arg == "-exe" && argidx+1 < args.size()) { + exe_file = args[++argidx]; + continue; + } + if (arg == "-script" && argidx+1 < args.size()) { + script_file = args[++argidx]; + rewrite_filename(script_file); + if (!script_file.empty() && !is_absolute_path(script_file) && script_file[0] != '+') + script_file = std::string(pwd) + "/" + script_file; + continue; + } + if (arg == "-D" && argidx+1 < args.size()) { + delay_target = "-D " + args[++argidx]; + continue; + } + //if (arg == "-S" && argidx+1 < args.size()) { + // lutin_shared = "-S " + args[++argidx]; + // continue; + //} + if (arg == "-lut" && argidx+1 < args.size()) { + string arg = args[++argidx]; + if (arg.find_first_not_of("0123456789:") == std::string::npos) { + size_t pos = arg.find_first_of(':'); + int lut_mode = 0, lut_mode2 = 0; + if (pos != string::npos) { + lut_mode = atoi(arg.substr(0, pos).c_str()); + lut_mode2 = atoi(arg.substr(pos+1).c_str()); + } else { + lut_mode = atoi(arg.c_str()); + lut_mode2 = lut_mode; + } + lut_costs.clear(); + for (int i = 0; i < lut_mode; i++) + lut_costs.push_back(1); + for (int i = lut_mode; i < lut_mode2; i++) + lut_costs.push_back(2 << (i - lut_mode)); + } + else { + lut_file = arg; + rewrite_filename(lut_file); + if (!lut_file.empty() && !is_absolute_path(lut_file) && lut_file[0] != '+') + lut_file = std::string(pwd) + "/" + lut_file; + } + continue; + } + if (arg == "-luts" && argidx+1 < args.size()) { + lut_costs.clear(); + for (auto &tok : split_tokens(args[++argidx], ",")) { + auto parts = split_tokens(tok, ":"); + if (GetSize(parts) == 0 && !lut_costs.empty()) + lut_costs.push_back(lut_costs.back()); + else if (GetSize(parts) == 1) + lut_costs.push_back(atoi(parts.at(0).c_str())); + else if (GetSize(parts) == 2) + while (GetSize(lut_costs) < atoi(parts.at(0).c_str())) + lut_costs.push_back(atoi(parts.at(1).c_str())); + else + log_cmd_error("Invalid -luts syntax.\n"); + } + continue; + } + if (arg == "-fast") { + fast_mode = true; + continue; + } + //if (arg == "-dff") { + // dff_mode = true; + // continue; + //} + //if (arg == "-clk" && argidx+1 < args.size()) { + // clk_str = args[++argidx]; + // dff_mode = true; + // continue; + //} + //if (arg == "-keepff") { + // keepff = true; + // continue; + //} + //if (arg == "-nocleanup") { + // cleanup = false; + // continue; + //} + if (arg == "-showtmp") { + show_tempdir = true; + continue; + } + if (arg == "-markgroups") { + markgroups = true; + continue; + } + if (arg == "-box" && argidx+1 < args.size()) { + box_file = args[++argidx]; + continue; + } + if (arg == "-W" && argidx+1 < args.size()) { + wire_delay = "-W " + args[++argidx]; + continue; + } + if (arg == "-nomfs") { + nomfs = true; + continue; + } + 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"); + + dict box_lookup; + for (auto m : design->modules()) { + auto it = m->attributes.find(ID(abc9_box_id)); + if (it == m->attributes.end()) + continue; + if (m->name.begins_with("$paramod")) + continue; + auto id = it->second.as_int(); + auto r = box_lookup.insert(std::make_pair(id, m->name)); + if (!r.second) + log_error("Module '%s' has the same abc9_box_id = %d value as '%s'.\n", + log_id(m), id, log_id(r.first->second)); + log_assert(r.second); + + RTLIL::Wire *carry_in = nullptr, *carry_out = nullptr; + for (auto p : m->ports) { + auto w = m->wire(p); + log_assert(w); + if (w->attributes.count(ID(abc9_carry))) { + if (w->port_input) { + if (carry_in) + log_error("Module '%s' contains more than one 'abc9_carry' input port.\n", log_id(m)); + carry_in = w; + } + else if (w->port_output) { + if (carry_out) + log_error("Module '%s' contains more than one 'abc9_carry' input port.\n", log_id(m)); + carry_out = w; + } + } + } + if (carry_in || carry_out) { + if (carry_in && !carry_out) + log_error("Module '%s' contains an 'abc9_carry' input port but no output port.\n", log_id(m)); + if (!carry_in && carry_out) + log_error("Module '%s' contains an 'abc9_carry' output port but no input port.\n", log_id(m)); + // Make carry_in the last PI, and carry_out the last PO + // since ABC requires it this way + auto &ports = m->ports; + for (auto it = ports.begin(); it != ports.end(); ) { + RTLIL::Wire* w = m->wire(*it); + log_assert(w); + if (w == carry_in || w == carry_out) { + it = ports.erase(it); + continue; + } + if (w->port_id > carry_in->port_id) + --w->port_id; + if (w->port_id > carry_out->port_id) + --w->port_id; + log_assert(w->port_input || w->port_output); + log_assert(ports[w->port_id-1] == w->name); + ++it; + } + ports.push_back(carry_in->name); + carry_in->port_id = ports.size(); + ports.push_back(carry_out->name); + carry_out->port_id = ports.size(); + } + } + + for (auto mod : design->selected_modules()) + { + if (mod->attributes.count(ID(abc9_box_id))) + continue; + + if (mod->processes.size() > 0) { + log("Skipping module %s as it contains processes.\n", log_id(mod)); + continue; + } + + assign_map.set(mod); + + if (!dff_mode || !clk_str.empty()) { + abc9_module(design, mod, script_file, exe_file, /*cleanup,*/ lut_costs, dff_mode, clk_str, keepff, + delay_target, lutin_shared, fast_mode, show_tempdir, + box_file, lut_file, wire_delay, box_lookup, nomfs, tempdir_name); + continue; + } + + CellTypes ct(design); + + std::vector all_cells = mod->selected_cells(); + std::set unassigned_cells(all_cells.begin(), all_cells.end()); + + std::set expand_queue, next_expand_queue; + std::set expand_queue_up, next_expand_queue_up; + std::set expand_queue_down, next_expand_queue_down; + + typedef tuple clkdomain_t; + std::map> assigned_cells; + std::map assigned_cells_reverse; + + std::map> cell_to_bit, cell_to_bit_up, cell_to_bit_down; + std::map> bit_to_cell, bit_to_cell_up, bit_to_cell_down; + + for (auto cell : all_cells) + { + clkdomain_t key; + + for (auto &conn : cell->connections()) + for (auto bit : conn.second) { + bit = assign_map(bit); + if (bit.wire != nullptr) { + cell_to_bit[cell].insert(bit); + bit_to_cell[bit].insert(cell); + if (ct.cell_input(cell->type, conn.first)) { + cell_to_bit_up[cell].insert(bit); + bit_to_cell_down[bit].insert(cell); + } + if (ct.cell_output(cell->type, conn.first)) { + cell_to_bit_down[cell].insert(bit); + bit_to_cell_up[bit].insert(cell); + } + } + } + + if (cell->type.in(ID($_DFF_N_), ID($_DFF_P_))) + { + key = clkdomain_t(cell->type == ID($_DFF_P_), assign_map(cell->getPort(ID(C))), true, RTLIL::SigSpec()); + } + else + if (cell->type.in(ID($_DFFE_NN_), ID($_DFFE_NP_), ID($_DFFE_PN_), ID($_DFFE_PP_))) + { + bool this_clk_pol = cell->type.in(ID($_DFFE_PN_), ID($_DFFE_PP_)); + bool this_en_pol = cell->type.in(ID($_DFFE_NP_), ID($_DFFE_PP_)); + key = clkdomain_t(this_clk_pol, assign_map(cell->getPort(ID(C))), this_en_pol, assign_map(cell->getPort(ID(E)))); + } + else + continue; + + unassigned_cells.erase(cell); + expand_queue.insert(cell); + expand_queue_up.insert(cell); + expand_queue_down.insert(cell); + + assigned_cells[key].push_back(cell); + assigned_cells_reverse[cell] = key; + } + + while (!expand_queue_up.empty() || !expand_queue_down.empty()) + { + if (!expand_queue_up.empty()) + { + RTLIL::Cell *cell = *expand_queue_up.begin(); + clkdomain_t key = assigned_cells_reverse.at(cell); + expand_queue_up.erase(cell); + + for (auto bit : cell_to_bit_up[cell]) + for (auto c : bit_to_cell_up[bit]) + if (unassigned_cells.count(c)) { + unassigned_cells.erase(c); + next_expand_queue_up.insert(c); + assigned_cells[key].push_back(c); + assigned_cells_reverse[c] = key; + expand_queue.insert(c); + } + } + + if (!expand_queue_down.empty()) + { + RTLIL::Cell *cell = *expand_queue_down.begin(); + clkdomain_t key = assigned_cells_reverse.at(cell); + expand_queue_down.erase(cell); + + for (auto bit : cell_to_bit_down[cell]) + for (auto c : bit_to_cell_down[bit]) + if (unassigned_cells.count(c)) { + unassigned_cells.erase(c); + next_expand_queue_up.insert(c); + assigned_cells[key].push_back(c); + assigned_cells_reverse[c] = key; + expand_queue.insert(c); + } + } + + if (expand_queue_up.empty() && expand_queue_down.empty()) { + expand_queue_up.swap(next_expand_queue_up); + expand_queue_down.swap(next_expand_queue_down); + } + } + + while (!expand_queue.empty()) + { + RTLIL::Cell *cell = *expand_queue.begin(); + clkdomain_t key = assigned_cells_reverse.at(cell); + expand_queue.erase(cell); + + for (auto bit : cell_to_bit.at(cell)) { + for (auto c : bit_to_cell[bit]) + if (unassigned_cells.count(c)) { + unassigned_cells.erase(c); + next_expand_queue.insert(c); + assigned_cells[key].push_back(c); + assigned_cells_reverse[c] = key; + } + bit_to_cell[bit].clear(); + } + + if (expand_queue.empty()) + expand_queue.swap(next_expand_queue); + } + + clkdomain_t key(true, RTLIL::SigSpec(), true, RTLIL::SigSpec()); + for (auto cell : unassigned_cells) { + assigned_cells[key].push_back(cell); + assigned_cells_reverse[cell] = key; + } + + log_header(design, "Summary of detected clock domains:\n"); + for (auto &it : assigned_cells) + log(" %d cells in clk=%s%s, en=%s%s\n", GetSize(it.second), + std::get<0>(it.first) ? "" : "!", log_signal(std::get<1>(it.first)), + std::get<2>(it.first) ? "" : "!", log_signal(std::get<3>(it.first))); + + for (auto &it : assigned_cells) { + clk_polarity = std::get<0>(it.first); + clk_sig = assign_map(std::get<1>(it.first)); + en_polarity = std::get<2>(it.first); + en_sig = assign_map(std::get<3>(it.first)); + abc9_module(design, mod, script_file, exe_file, /*cleanup,*/ lut_costs, !clk_sig.empty(), "$", + keepff, delay_target, lutin_shared, fast_mode, show_tempdir, + box_file, lut_file, wire_delay, box_lookup, nomfs, tempdir_name); + assign_map.set(mod); + } + } + + assign_map.clear(); + + log_pop(); + } +} Abc9TechmapPass; + +PRIVATE_NAMESPACE_END diff --git a/passes/techmap/abc9_ops.cc b/passes/techmap/abc9_ops.cc new file mode 100644 index 000000000..4c30efd06 --- /dev/null +++ b/passes/techmap/abc9_ops.cc @@ -0,0 +1,139 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 Clifford Wolf + * 2019 Eddie Hung + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#include "kernel/register.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 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(); +} + +struct Abc9PrepPass : public Pass { + Abc9PrepPass() : 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 args, RTLIL::Design *design) YS_OVERRIDE + { + log_header(design, "Executing ABC9_OPS pass (helper functions for ABC9).\n"); + log_push(); + + bool break_scc_mode = false; + bool unbreak_scc_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; + } + break; + } + extra_args(args, argidx, design); + + for (auto mod : design->selected_modules()) { + if (break_scc_mode) + break_scc(mod); + if (unbreak_scc_mode) + unbreak_scc(mod); + } + } +} Abc9PrepPass; + +PRIVATE_NAMESPACE_END diff --git a/passes/techmap/abc9_techmap.cc b/passes/techmap/abc9_techmap.cc deleted file mode 100644 index 7ff68f382..000000000 --- a/passes/techmap/abc9_techmap.cc +++ /dev/null @@ -1,1310 +0,0 @@ -/* - * yosys -- Yosys Open SYnthesis Suite - * - * Copyright (C) 2012 Clifford Wolf - * 2019 Eddie Hung - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - */ - -// [[CITE]] ABC -// Berkeley Logic Synthesis and Verification Group, ABC: A System for Sequential Synthesis and Verification -// http://www.eecs.berkeley.edu/~alanmi/abc/ - -#if 0 -// Based on &flow3 - better QoR but more experimental -#define ABC_COMMAND_LUT "&st; &ps -l; &sweep -v; &scorr; " \ - "&st; &if {W}; &save; &st; &syn2; &if {W} -v; &save; &load; "\ - "&st; &if -g -K 6; &dch -f; &if {W} -v; &save; &load; "\ - "&st; &if -g -K 6; &synch2; &if {W} -v; &save; &load; "\ - "&mfs; &ps -l" -#else -#define ABC_COMMAND_LUT "&st; &scorr; &sweep; &dc2; &st; &dch -f; &ps; &if {W} {D} -v; &mfs; &ps -l" -#endif - - -#define ABC_FAST_COMMAND_LUT "&st; &if {W} {D}" - -#include "kernel/register.h" -#include "kernel/sigtools.h" -#include "kernel/celltypes.h" -#include "kernel/cost.h" -#include "kernel/log.h" -#include -#include -#include -#include -#include -#include - -#ifndef _WIN32 -# include -# include -#endif - -#include "frontends/aiger/aigerparse.h" -#include "kernel/utils.h" - -#ifdef YOSYS_LINK_ABC -extern "C" int Abc_RealMain(int argc, char *argv[]); -#endif - -USING_YOSYS_NAMESPACE -PRIVATE_NAMESPACE_BEGIN - -bool markgroups; -int map_autoidx; -SigMap assign_map; -RTLIL::Module *module; - -bool clk_polarity, en_polarity; -RTLIL::SigSpec clk_sig, en_sig; - -inline std::string remap_name(RTLIL::IdString abc9_name) -{ - return stringf("$abc$%d$%s", map_autoidx, abc9_name.c_str()+1); -} - -void handle_loops(RTLIL::Design *design) -{ - Pass::call(design, "scc -set_attr abc9_scc_id {}"); - - // For every unique SCC found, (arbitrarily) find the first - // cell in the component, and select (and mark) all its output - // wires - pool ids_seen; - for (auto cell : module->cells()) { - auto it = cell->attributes.find(ID(abc9_scc_id)); - if (it != cell->attributes.end()) { - auto r = ids_seen.insert(it->second); - if (r.second) { - for (auto &c : cell->connections_) { - if (c.second.is_fully_const()) continue; - if (cell->output(c.first)) { - SigBit b = c.second.as_bit(); - Wire *w = b.wire; - if (w->port_input) { - // In this case, hopefully the loop break has been already created - // Get the non-prefixed wire - Wire *wo = module->wire(stringf("%s.abco", b.wire->name.c_str())); - log_assert(wo != nullptr); - log_assert(wo->port_output); - log_assert(b.offset < GetSize(wo)); - c.second = RTLIL::SigBit(wo, b.offset); - } - else { - // Create a new output/input loop break - w->port_input = true; - w = module->wire(stringf("%s.abco", w->name.c_str())); - if (!w) { - w = module->addWire(stringf("%s.abco", b.wire->name.c_str()), GetSize(b.wire)); - w->port_output = true; - } - else { - log_assert(w->port_input); - log_assert(b.offset < GetSize(w)); - } - w->set_bool_attribute(ID(abc9_scc_break)); - c.second = RTLIL::SigBit(w, b.offset); - } - } - } - } - cell->attributes.erase(it); - } - } - - module->fixup_ports(); -} - -std::string add_echos_to_abc9_cmd(std::string str) -{ - std::string new_str, token; - for (size_t i = 0; i < str.size(); i++) { - token += str[i]; - if (str[i] == ';') { - while (i+1 < str.size() && str[i+1] == ' ') - i++; - new_str += "echo + " + token + " " + token + " "; - token.clear(); - } - } - - if (!token.empty()) { - if (!new_str.empty()) - new_str += "echo + " + token + "; "; - new_str += token; - } - - return new_str; -} - -std::string fold_abc9_cmd(std::string str) -{ - std::string token, new_str = " "; - int char_counter = 10; - - for (size_t i = 0; i <= str.size(); i++) { - if (i < str.size()) - token += str[i]; - if (i == str.size() || str[i] == ';') { - if (char_counter + token.size() > 75) - new_str += "\n ", char_counter = 14; - new_str += token, char_counter += token.size(); - token.clear(); - } - } - - return new_str; -} - -std::string replace_tempdir(std::string text, std::string tempdir_name, bool show_tempdir) -{ - if (show_tempdir) - return text; - - while (1) { - size_t pos = text.find(tempdir_name); - if (pos == std::string::npos) - break; - text = text.substr(0, pos) + "" + text.substr(pos + GetSize(tempdir_name)); - } - - std::string selfdir_name = proc_self_dirname(); - if (selfdir_name != "/") { - while (1) { - size_t pos = text.find(selfdir_name); - if (pos == std::string::npos) - break; - text = text.substr(0, pos) + "/" + text.substr(pos + GetSize(selfdir_name)); - } - } - - return text; -} - -struct abc9_output_filter -{ - bool got_cr; - int escape_seq_state; - std::string linebuf; - std::string tempdir_name; - bool show_tempdir; - - abc9_output_filter(std::string tempdir_name, bool show_tempdir) : tempdir_name(tempdir_name), show_tempdir(show_tempdir) - { - got_cr = false; - escape_seq_state = 0; - } - - void next_char(char ch) - { - if (escape_seq_state == 0 && ch == '\033') { - escape_seq_state = 1; - return; - } - if (escape_seq_state == 1) { - escape_seq_state = ch == '[' ? 2 : 0; - return; - } - if (escape_seq_state == 2) { - if ((ch < '0' || '9' < ch) && ch != ';') - escape_seq_state = 0; - return; - } - escape_seq_state = 0; - if (ch == '\r') { - got_cr = true; - return; - } - if (ch == '\n') { - log("ABC: %s\n", replace_tempdir(linebuf, tempdir_name, show_tempdir).c_str()); - got_cr = false, linebuf.clear(); - return; - } - if (got_cr) - got_cr = false, linebuf.clear(); - linebuf += ch; - } - - void next_line(const std::string &line) - { - //int pi, po; - //if (sscanf(line.c_str(), "Start-point = pi%d. End-point = po%d.", &pi, &po) == 2) { - // log("ABC: Start-point = pi%d (%s). End-point = po%d (%s).\n", - // pi, pi_map.count(pi) ? pi_map.at(pi).c_str() : "???", - // po, po_map.count(po) ? po_map.at(po).c_str() : "???"); - // return; - //} - - for (char ch : line) - next_char(ch); - } -}; - -void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::string script_file, std::string exe_file, - bool cleanup, vector lut_costs, bool dff_mode, std::string clk_str, - bool /*keepff*/, std::string delay_target, std::string /*lutin_shared*/, bool fast_mode, - bool show_tempdir, std::string box_file, std::string lut_file, - std::string wire_delay, const dict &box_lookup, bool nomfs -) -{ - module = current_module; - map_autoidx = autoidx++; - - if (clk_str != "$") - { - clk_polarity = true; - clk_sig = RTLIL::SigSpec(); - - en_polarity = true; - en_sig = RTLIL::SigSpec(); - } - - if (!clk_str.empty() && clk_str != "$") - { - if (clk_str.find(',') != std::string::npos) { - int pos = clk_str.find(','); - std::string en_str = clk_str.substr(pos+1); - clk_str = clk_str.substr(0, pos); - if (en_str[0] == '!') { - en_polarity = false; - en_str = en_str.substr(1); - } - if (module->wires_.count(RTLIL::escape_id(en_str)) != 0) - en_sig = assign_map(RTLIL::SigSpec(module->wires_.at(RTLIL::escape_id(en_str)), 0)); - } - if (clk_str[0] == '!') { - clk_polarity = false; - clk_str = clk_str.substr(1); - } - if (module->wires_.count(RTLIL::escape_id(clk_str)) != 0) - clk_sig = assign_map(RTLIL::SigSpec(module->wires_.at(RTLIL::escape_id(clk_str)), 0)); - } - - if (dff_mode && clk_sig.empty()) - log_cmd_error("Clock domain %s not found.\n", clk_str.c_str()); - - std::string tempdir_name = "/tmp/yosys-abc-XXXXXX"; - if (!cleanup) - tempdir_name[0] = tempdir_name[4] = '_'; - tempdir_name = make_temp_dir(tempdir_name); - log_header(design, "Extracting gate netlist of module `%s' to `%s/input.xaig'..\n", - module->name.c_str(), replace_tempdir(tempdir_name, tempdir_name, show_tempdir).c_str()); - - std::string abc9_script; - - if (!lut_costs.empty()) { - abc9_script += stringf("read_lut %s/lutdefs.txt; ", tempdir_name.c_str()); - if (!box_file.empty()) - abc9_script += stringf("read_box -v %s; ", box_file.c_str()); - } - else - if (!lut_file.empty()) { - abc9_script += stringf("read_lut %s; ", lut_file.c_str()); - if (!box_file.empty()) - abc9_script += stringf("read_box -v %s; ", box_file.c_str()); - } - else - log_abort(); - - abc9_script += stringf("&read %s/input.xaig; &ps; ", tempdir_name.c_str()); - - if (!script_file.empty()) { - if (script_file[0] == '+') { - for (size_t i = 1; i < script_file.size(); i++) - if (script_file[i] == '\'') - abc9_script += "'\\''"; - else if (script_file[i] == ',') - abc9_script += " "; - else - abc9_script += script_file[i]; - } else - abc9_script += stringf("source %s", script_file.c_str()); - } else if (!lut_costs.empty() || !lut_file.empty()) { - //bool all_luts_cost_same = true; - //for (int this_cost : lut_costs) - // if (this_cost != lut_costs.front()) - // all_luts_cost_same = false; - abc9_script += fast_mode ? ABC_FAST_COMMAND_LUT : ABC_COMMAND_LUT; - //if (all_luts_cost_same && !fast_mode) - // abc9_script += "; lutpack {S}"; - } else - log_abort(); - - //if (script_file.empty() && !delay_target.empty()) - // for (size_t pos = abc9_script.find("dretime;"); pos != std::string::npos; pos = abc9_script.find("dretime;", pos+1)) - // abc9_script = abc9_script.substr(0, pos) + "dretime; retime -o {D};" + abc9_script.substr(pos+8); - - for (size_t pos = abc9_script.find("{D}"); pos != std::string::npos; pos = abc9_script.find("{D}", pos)) - abc9_script = abc9_script.substr(0, pos) + delay_target + abc9_script.substr(pos+3); - - //for (size_t pos = abc9_script.find("{S}"); pos != std::string::npos; pos = abc9_script.find("{S}", pos)) - // abc9_script = abc9_script.substr(0, pos) + lutin_shared + abc9_script.substr(pos+3); - - for (size_t pos = abc9_script.find("{W}"); pos != std::string::npos; pos = abc9_script.find("{W}", pos)) - abc9_script = abc9_script.substr(0, pos) + wire_delay + abc9_script.substr(pos+3); - - if (nomfs) - for (size_t pos = abc9_script.find("&mfs"); pos != std::string::npos; pos = abc9_script.find("&mfs", pos)) - abc9_script = abc9_script.erase(pos, strlen("&mfs")); - - abc9_script += stringf("; &write %s/output.aig", tempdir_name.c_str()); - abc9_script = add_echos_to_abc9_cmd(abc9_script); - - for (size_t i = 0; i+1 < abc9_script.size(); i++) - if (abc9_script[i] == ';' && abc9_script[i+1] == ' ') - abc9_script[i+1] = '\n'; - - FILE *f = fopen(stringf("%s/abc.script", tempdir_name.c_str()).c_str(), "wt"); - fprintf(f, "%s\n", abc9_script.c_str()); - fclose(f); - - if (dff_mode || !clk_str.empty()) - { - if (clk_sig.size() == 0) - log("No%s clock domain found. Not extracting any FF cells.\n", clk_str.empty() ? "" : " matching"); - else { - log("Found%s %s clock domain: %s", clk_str.empty() ? "" : " matching", clk_polarity ? "posedge" : "negedge", log_signal(clk_sig)); - if (en_sig.size() != 0) - log(", enabled by %s%s", en_polarity ? "" : "!", log_signal(en_sig)); - log("\n"); - } - } - - bool count_output = false; - for (auto port_name : module->ports) { - RTLIL::Wire *port_wire = module->wire(port_name); - log_assert(port_wire); - if (port_wire->port_output) { - count_output = true; - break; - } - } - - log_push(); - - if (count_output) - { - design->selection_stack.emplace_back(false); - RTLIL::Selection& sel = design->selection_stack.back(); - sel.select(module); - - handle_loops(design); - - Pass::call(design, "aigmap"); - - //log("Extracted %d gates and %d wires to a netlist network with %d inputs and %d outputs.\n", - // count_gates, GetSize(signal_list), count_input, count_output); - - Pass::call(design, stringf("write_xaiger -map %s/input.sym %s/input.xaig", tempdir_name.c_str(), tempdir_name.c_str())); - - std::string buffer; - std::ifstream ifs; -#if 0 - buffer = stringf("%s/%s", tempdir_name.c_str(), "input.xaig"); - ifs.open(buffer); - if (ifs.fail()) - log_error("Can't open ABC output file `%s'.\n", buffer.c_str()); - buffer = stringf("%s/%s", tempdir_name.c_str(), "input.sym"); - log_assert(!design->module(ID($__abc9__))); - { - AigerReader reader(design, ifs, ID($__abc9__), "" /* clk_name */, buffer.c_str() /* map_filename */, true /* wideports */); - reader.parse_xaiger(); - } - ifs.close(); - Pass::call(design, stringf("write_verilog -noexpr -norename")); - design->remove(design->module(ID($__abc9__))); -#endif - - design->selection_stack.pop_back(); - - log_header(design, "Executing ABC9_MAP.\n"); - - if (!lut_costs.empty()) { - buffer = stringf("%s/lutdefs.txt", tempdir_name.c_str()); - f = fopen(buffer.c_str(), "wt"); - if (f == NULL) - log_error("Opening %s for writing failed: %s\n", buffer.c_str(), strerror(errno)); - for (int i = 0; i < GetSize(lut_costs); i++) - fprintf(f, "%d %d.00 1.00\n", i+1, lut_costs.at(i)); - fclose(f); - } - - buffer = stringf("%s -s -f %s/abc.script 2>&1", exe_file.c_str(), tempdir_name.c_str()); - log("Running ABC command: %s\n", replace_tempdir(buffer, tempdir_name, show_tempdir).c_str()); - -#ifndef YOSYS_LINK_ABC - abc9_output_filter filt(tempdir_name, show_tempdir); - int ret = run_command(buffer, std::bind(&abc9_output_filter::next_line, filt, std::placeholders::_1)); -#else - // These needs to be mutable, supposedly due to getopt - char *abc9_argv[5]; - string tmp_script_name = stringf("%s/abc.script", tempdir_name.c_str()); - abc9_argv[0] = strdup(exe_file.c_str()); - abc9_argv[1] = strdup("-s"); - abc9_argv[2] = strdup("-f"); - abc9_argv[3] = strdup(tmp_script_name.c_str()); - abc9_argv[4] = 0; - int ret = Abc_RealMain(4, abc9_argv); - free(abc9_argv[0]); - free(abc9_argv[1]); - free(abc9_argv[2]); - free(abc9_argv[3]); -#endif - if (ret != 0) - log_error("ABC: execution of command \"%s\" failed: return code %d.\n", buffer.c_str(), ret); - - buffer = stringf("%s/%s", tempdir_name.c_str(), "output.aig"); - ifs.open(buffer, std::ifstream::binary); - if (ifs.fail()) - log_error("Can't open ABC output file `%s'.\n", buffer.c_str()); - - buffer = stringf("%s/%s", tempdir_name.c_str(), "input.sym"); - log_assert(!design->module(ID($__abc9__))); - - AigerReader reader(design, ifs, ID($__abc9__), "" /* clk_name */, buffer.c_str() /* map_filename */, true /* wideports */); - reader.parse_xaiger(box_lookup); - ifs.close(); - -#if 0 - Pass::call(design, stringf("write_verilog -noexpr -norename")); -#endif - - log_header(design, "Re-integrating ABC9 results.\n"); - RTLIL::Module *mapped_mod = design->module(ID($__abc9__)); - if (mapped_mod == NULL) - log_error("ABC output file does not contain a module `$__abc9__'.\n"); - - pool output_bits; - for (auto &it : mapped_mod->wires_) { - RTLIL::Wire *w = it.second; - RTLIL::Wire *remap_wire = module->addWire(remap_name(w->name), GetSize(w)); - if (markgroups) remap_wire->attributes[ID(abcgroup)] = map_autoidx; - if (w->port_output) { - RTLIL::Wire *wire = module->wire(w->name); - log_assert(wire); - for (int i = 0; i < GetSize(w); i++) - output_bits.insert({wire, i}); - } - } - - for (auto &it : module->connections_) { - auto &signal = it.first; - auto bits = signal.bits(); - for (auto &b : bits) - if (output_bits.count(b)) - b = module->addWire(NEW_ID); - signal = std::move(bits); - } - - dict abc9_box; - vector boxes; - for (const auto &it : module->cells_) { - auto cell = it.second; - if (cell->type.in(ID($_AND_), ID($_NOT_))) { - module->remove(cell); - continue; - } - auto jt = abc9_box.find(cell->type); - if (jt == abc9_box.end()) { - RTLIL::Module* box_module = design->module(cell->type); - jt = abc9_box.insert(std::make_pair(cell->type, box_module && box_module->attributes.count(ID(abc9_box_id)))).first; - } - if (jt->second) - boxes.emplace_back(cell); - } - - dict> bit_drivers, bit_users; - TopoSort toposort; - dict not2drivers; - dict> bit2sinks; - - std::map cell_stats; - for (auto c : mapped_mod->cells()) - { - toposort.node(c->name); - - RTLIL::Cell *cell = nullptr; - if (c->type == ID($_NOT_)) { - RTLIL::SigBit a_bit = c->getPort(ID::A); - RTLIL::SigBit y_bit = c->getPort(ID::Y); - bit_users[a_bit].insert(c->name); - bit_drivers[y_bit].insert(c->name); - - if (!a_bit.wire) { - c->setPort(ID::Y, module->addWire(NEW_ID)); - RTLIL::Wire *wire = module->wire(remap_name(y_bit.wire->name)); - log_assert(wire); - module->connect(RTLIL::SigBit(wire, y_bit.offset), State::S1); - } - else if (!lut_costs.empty() || !lut_file.empty()) { - RTLIL::Cell* driver_lut = nullptr; - // ABC can return NOT gates that drive POs - if (!a_bit.wire->port_input) { - // If it's not a NOT gate that that comes from a PI directly, - // find the driver LUT and clone that to guarantee that we won't - // increase the max logic depth - // (TODO: Optimise by not cloning unless will increase depth) - RTLIL::IdString driver_name; - if (GetSize(a_bit.wire) == 1) - driver_name = stringf("%s$lut", a_bit.wire->name.c_str()); - else - driver_name = stringf("%s[%d]$lut", a_bit.wire->name.c_str(), a_bit.offset); - driver_lut = mapped_mod->cell(driver_name); - } - - if (!driver_lut) { - // If a driver couldn't be found (could be from PI or box CI) - // then implement using a LUT - cell = module->addLut(remap_name(stringf("%s$lut", c->name.c_str())), - RTLIL::SigBit(module->wires_.at(remap_name(a_bit.wire->name)), a_bit.offset), - RTLIL::SigBit(module->wires_.at(remap_name(y_bit.wire->name)), y_bit.offset), - RTLIL::Const::from_string("01")); - bit2sinks[cell->getPort(ID::A)].push_back(cell); - cell_stats[ID($lut)]++; - } - else - not2drivers[c] = driver_lut; - continue; - } - else - log_abort(); - if (cell && markgroups) cell->attributes[ID(abcgroup)] = map_autoidx; - continue; - } - cell_stats[c->type]++; - - RTLIL::Cell *existing_cell = nullptr; - if (c->type == ID($lut)) { - if (GetSize(c->getPort(ID::A)) == 1 && c->getParam(ID(LUT)) == RTLIL::Const::from_string("01")) { - SigSpec my_a = module->wires_.at(remap_name(c->getPort(ID::A).as_wire()->name)); - SigSpec my_y = module->wires_.at(remap_name(c->getPort(ID::Y).as_wire()->name)); - module->connect(my_y, my_a); - if (markgroups) c->attributes[ID(abcgroup)] = map_autoidx; - log_abort(); - continue; - } - cell = module->addCell(remap_name(c->name), c->type); - } - else { - existing_cell = module->cell(c->name); - log_assert(existing_cell); - cell = module->addCell(remap_name(c->name), c->type); - } - - if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx; - if (existing_cell) { - cell->parameters = existing_cell->parameters; - cell->attributes = existing_cell->attributes; - } - else { - cell->parameters = c->parameters; - cell->attributes = c->attributes; - } - for (auto &conn : c->connections()) { - RTLIL::SigSpec newsig; - for (auto c : conn.second.chunks()) { - if (c.width == 0) - continue; - //log_assert(c.width == 1); - if (c.wire) - c.wire = module->wires_.at(remap_name(c.wire->name)); - newsig.append(c); - } - cell->setPort(conn.first, newsig); - - if (cell->input(conn.first)) { - for (auto i : newsig) - bit2sinks[i].push_back(cell); - for (auto i : conn.second) - bit_users[i].insert(c->name); - } - if (cell->output(conn.first)) - for (auto i : conn.second) - bit_drivers[i].insert(c->name); - } - } - - for (auto existing_cell : boxes) { - Cell *cell = module->cell(remap_name(existing_cell->name)); - if (cell) { - for (auto &conn : existing_cell->connections()) { - if (!conn.second.is_wire()) - continue; - Wire *wire = conn.second.as_wire(); - if (!wire->get_bool_attribute(ID(abc9_padding))) - continue; - cell->unsetPort(conn.first); - log_debug("Dropping padded port connection for %s (%s) .%s (%s )\n", log_id(cell), cell->type.c_str(), log_id(conn.first), log_signal(conn.second)); - } - module->swap_names(cell, existing_cell); - } - module->remove(existing_cell); - } - - // Copy connections (and rename) from mapped_mod to module - for (auto conn : mapped_mod->connections()) { - if (!conn.first.is_fully_const()) { - auto chunks = conn.first.chunks(); - for (auto &c : chunks) - c.wire = module->wires_.at(remap_name(c.wire->name)); - conn.first = std::move(chunks); - } - if (!conn.second.is_fully_const()) { - auto chunks = conn.second.chunks(); - for (auto &c : chunks) - if (c.wire) - c.wire = module->wires_.at(remap_name(c.wire->name)); - conn.second = std::move(chunks); - } - module->connect(conn); - } - - for (auto &it : cell_stats) - log("ABC RESULTS: %15s cells: %8d\n", it.first.c_str(), it.second); - int in_wires = 0, out_wires = 0; - - // Stitch in mapped_mod's inputs/outputs into module - for (auto port : mapped_mod->ports) { - RTLIL::Wire *w = mapped_mod->wire(port); - RTLIL::Wire *wire = module->wire(port); - log_assert(wire); - RTLIL::Wire *remap_wire = module->wire(remap_name(port)); - RTLIL::SigSpec signal = RTLIL::SigSpec(wire, 0, GetSize(remap_wire)); - log_assert(GetSize(signal) >= GetSize(remap_wire)); - - RTLIL::SigSig conn; - if (w->port_output) { - conn.first = signal; - conn.second = remap_wire; - out_wires++; - module->connect(conn); - } - else if (w->port_input) { - conn.first = remap_wire; - conn.second = signal; - in_wires++; - module->connect(conn); - } - } - - for (auto &it : bit_users) - if (bit_drivers.count(it.first)) - for (auto driver_cell : bit_drivers.at(it.first)) - for (auto user_cell : it.second) - toposort.edge(driver_cell, user_cell); - bool no_loops YS_ATTRIBUTE(unused) = toposort.sort(); - log_assert(no_loops); - - for (auto ii = toposort.sorted.rbegin(); ii != toposort.sorted.rend(); ii++) { - RTLIL::Cell *not_cell = mapped_mod->cell(*ii); - log_assert(not_cell); - if (not_cell->type != ID($_NOT_)) - continue; - auto it = not2drivers.find(not_cell); - if (it == not2drivers.end()) - continue; - RTLIL::Cell *driver_lut = it->second; - RTLIL::SigBit a_bit = not_cell->getPort(ID::A); - RTLIL::SigBit y_bit = not_cell->getPort(ID::Y); - RTLIL::Const driver_mask; - - a_bit.wire = module->wires_.at(remap_name(a_bit.wire->name)); - y_bit.wire = module->wires_.at(remap_name(y_bit.wire->name)); - - auto jt = bit2sinks.find(a_bit); - if (jt == bit2sinks.end()) - goto clone_lut; - - for (auto sink_cell : jt->second) - if (sink_cell->type != ID($lut)) - goto clone_lut; - - // Push downstream LUTs past inverter - for (auto sink_cell : jt->second) { - SigSpec A = sink_cell->getPort(ID::A); - RTLIL::Const mask = sink_cell->getParam(ID(LUT)); - int index = 0; - for (; index < GetSize(A); index++) - if (A[index] == a_bit) - break; - log_assert(index < GetSize(A)); - int i = 0; - while (i < GetSize(mask)) { - for (int j = 0; j < (1 << index); j++) - std::swap(mask[i+j], mask[i+j+(1 << index)]); - i += 1 << (index+1); - } - A[index] = y_bit; - sink_cell->setPort(ID::A, A); - sink_cell->setParam(ID(LUT), mask); - } - - // Since we have rewritten all sinks (which we know - // to be only LUTs) to be after the inverter, we can - // go ahead and clone the LUT with the expectation - // that the original driving LUT will become dangling - // and get cleaned away -clone_lut: - driver_mask = driver_lut->getParam(ID(LUT)); - for (auto &b : driver_mask.bits) { - if (b == RTLIL::State::S0) b = RTLIL::State::S1; - else if (b == RTLIL::State::S1) b = RTLIL::State::S0; - } - auto cell = module->addLut(NEW_ID, - driver_lut->getPort(ID::A), - y_bit, - driver_mask); - for (auto &bit : cell->connections_.at(ID::A)) { - bit.wire = module->wires_.at(remap_name(bit.wire->name)); - bit2sinks[bit].push_back(cell); - } - } - - // Now 'unexpose' those wires by undoing - // the expose operation -- remove them from PO/PI - // and re-connecting them back together - for (auto wire : module->wires()) { - auto it = wire->attributes.find(ID(abc9_scc_break)); - if (it != wire->attributes.end()) { - wire->attributes.erase(it); - log_assert(wire->port_output); - wire->port_output = false; - std::string name = wire->name.str(); - RTLIL::Wire *i_wire = module->wire(name.substr(0, GetSize(name) - 5)); - log_assert(i_wire); - log_assert(i_wire->port_input); - i_wire->port_input = false; - module->connect(i_wire, wire); - } - } - module->fixup_ports(); - - //log("ABC RESULTS: internal signals: %8d\n", int(signal_list.size()) - in_wires - out_wires); - log("ABC RESULTS: input signals: %8d\n", in_wires); - log("ABC RESULTS: output signals: %8d\n", out_wires); - - design->remove(mapped_mod); - } - else - { - log("Don't call ABC as there is nothing to map.\n"); - } - - if (cleanup) - { - log("Removing temp directory.\n"); - remove_directory(tempdir_name); - } - - log_pop(); -} - -struct Abc9TechmapPass : public Pass { - Abc9TechmapPass() : 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 \n"); -#ifdef ABCEXTERNAL - log(" use the specified command instead of \"" ABCEXTERNAL "\" to execute ABC.\n"); -#else - log(" use the specified command instead of \"/yosys-abc\" to execute ABC.\n"); -#endif - log(" This can e.g. be used to call a specific version of ABC or a wrapper.\n"); - log("\n"); - log(" -script \n"); - log(" use the specified ABC script file instead of the default script.\n"); - log("\n"); - log(" if starts with a plus sign (+), then the rest of the filename\n"); - log(" string is interpreted as the command string to be passed to ABC. The\n"); - log(" leading plus sign is removed and all commas (,) in the string are\n"); - log(" replaced with blanks before the string is passed to ABC.\n"); - log("\n"); - log(" if no -script parameter is given, the following scripts are used:\n"); - log("\n"); - log(" for -lut/-luts (only one LUT size):\n"); - log("%s\n", fold_abc9_cmd(ABC_COMMAND_LUT /*"; lutpack {S}"*/).c_str()); - log("\n"); - log(" for -lut/-luts (different LUT sizes):\n"); - log("%s\n", fold_abc9_cmd(ABC_COMMAND_LUT).c_str()); - log("\n"); - log(" -fast\n"); - log(" use different default scripts that are slightly faster (at the cost\n"); - log(" of output quality):\n"); - log("\n"); - log(" for -lut/-luts:\n"); - log("%s\n", fold_abc9_cmd(ABC_FAST_COMMAND_LUT).c_str()); - log("\n"); - log(" -D \n"); - log(" set delay target. the string {D} in the default scripts above is\n"); - log(" replaced by this option when used, and an empty string otherwise\n"); - log(" (indicating best possible delay).\n"); -// log(" This also replaces 'dretime' with 'dretime; retime -o {D}' in the\n"); -// log(" default scripts above.\n"); - log("\n"); -// log(" -S \n"); -// log(" maximum number of LUT inputs shared.\n"); -// log(" (replaces {S} in the default scripts above, default: -S 1)\n"); -// log("\n"); - log(" -lut \n"); - log(" generate netlist using luts of (max) the specified width.\n"); - log("\n"); - log(" -lut :\n"); - log(" generate netlist using luts of (max) the specified width . All\n"); - log(" luts with width <= have constant cost. for luts larger than \n"); - log(" the area cost doubles with each additional input bit. the delay cost\n"); - log(" is still constant for all lut widths.\n"); - log("\n"); - log(" -lut \n"); - log(" pass this file with lut library to ABC.\n"); - log("\n"); - log(" -luts ,,,:,..\n"); - log(" generate netlist using luts. Use the specified costs for luts with 1,\n"); - log(" 2, 3, .. inputs.\n"); - log("\n"); -// log(" -dff\n"); -// log(" also pass $_DFF_?_ and $_DFFE_??_ cells through ABC. modules with many\n"); -// log(" clock domains are automatically partitioned in clock domains and each\n"); -// log(" domain is passed through ABC independently.\n"); -// log("\n"); -// log(" -clk [!][,[!]]\n"); -// log(" use only the specified clock domain. this is like -dff, but only FF\n"); -// log(" cells that belong to the specified clock domain are used.\n"); -// log("\n"); -// log(" -keepff\n"); -// log(" set the \"keep\" attribute on flip-flop output wires. (and thus preserve\n"); -// log(" them, for example for equivalence checking.)\n"); -// log("\n"); - log(" -nocleanup\n"); - log(" when this option is used, the temporary files created by this pass\n"); - log(" are not removed. this is useful for debugging.\n"); - log("\n"); - log(" -showtmp\n"); - log(" print the temp dir name in log. usually this is suppressed so that the\n"); - log(" command output is identical across runs.\n"); - log("\n"); - log(" -markgroups\n"); - log(" set a 'abcgroup' attribute on all objects created by ABC. The value of\n"); - log(" this attribute is a unique integer for each ABC process started. This\n"); - log(" is useful for debugging the partitioning of clock domains.\n"); - log("\n"); - log(" -box \n"); - log(" pass this file with box library to ABC. Use with -lut.\n"); - log("\n"); - log("Note that this is a logic optimization pass within Yosys that is calling ABC\n"); - log("internally. This is not going to \"run ABC on your design\". It will instead run\n"); - log("ABC on logic snippets extracted from your design. You will not get any useful\n"); - log("output when passing an ABC script that writes a file. Instead write your full\n"); - log("design as BLIF file with write_blif and then load that into ABC externally if\n"); - log("you want to use ABC to convert your design into another format.\n"); - log("\n"); - log("[1] http://www.eecs.berkeley.edu/~alanmi/abc/\n"); - log("\n"); - } - void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE - { - log_header(design, "Executing ABC9 pass (technology mapping using ABC9).\n"); - log_push(); - - assign_map.clear(); - -#ifdef ABCEXTERNAL - std::string exe_file = ABCEXTERNAL; -#else - std::string exe_file = proc_self_dirname() + "yosys-abc"; -#endif - std::string script_file, clk_str, box_file, lut_file; - std::string delay_target, lutin_shared = "-S 1", wire_delay; - bool fast_mode = false, dff_mode = false, keepff = false, cleanup = true; - bool show_tempdir = false; - bool nomfs = false; - vector lut_costs; - markgroups = false; - -#if 0 - cleanup = false; - show_tempdir = true; -#endif - -#ifdef _WIN32 -#ifndef ABCEXTERNAL - if (!check_file_exists(exe_file + ".exe") && check_file_exists(proc_self_dirname() + "..\\yosys-abc.exe")) - exe_file = proc_self_dirname() + "..\\yosys-abc"; -#endif -#endif - - size_t argidx; - char pwd [PATH_MAX]; - if (!getcwd(pwd, sizeof(pwd))) { - log_cmd_error("getcwd failed: %s\n", strerror(errno)); - log_abort(); - } - for (argidx = 1; argidx < args.size(); argidx++) { - std::string arg = args[argidx]; - if (arg == "-exe" && argidx+1 < args.size()) { - exe_file = args[++argidx]; - continue; - } - if (arg == "-script" && argidx+1 < args.size()) { - script_file = args[++argidx]; - rewrite_filename(script_file); - if (!script_file.empty() && !is_absolute_path(script_file) && script_file[0] != '+') - script_file = std::string(pwd) + "/" + script_file; - continue; - } - if (arg == "-D" && argidx+1 < args.size()) { - delay_target = "-D " + args[++argidx]; - continue; - } - //if (arg == "-S" && argidx+1 < args.size()) { - // lutin_shared = "-S " + args[++argidx]; - // continue; - //} - if (arg == "-lut" && argidx+1 < args.size()) { - string arg = args[++argidx]; - if (arg.find_first_not_of("0123456789:") == std::string::npos) { - size_t pos = arg.find_first_of(':'); - int lut_mode = 0, lut_mode2 = 0; - if (pos != string::npos) { - lut_mode = atoi(arg.substr(0, pos).c_str()); - lut_mode2 = atoi(arg.substr(pos+1).c_str()); - } else { - lut_mode = atoi(arg.c_str()); - lut_mode2 = lut_mode; - } - lut_costs.clear(); - for (int i = 0; i < lut_mode; i++) - lut_costs.push_back(1); - for (int i = lut_mode; i < lut_mode2; i++) - lut_costs.push_back(2 << (i - lut_mode)); - } - else { - lut_file = arg; - rewrite_filename(lut_file); - if (!lut_file.empty() && !is_absolute_path(lut_file) && lut_file[0] != '+') - lut_file = std::string(pwd) + "/" + lut_file; - } - continue; - } - if (arg == "-luts" && argidx+1 < args.size()) { - lut_costs.clear(); - for (auto &tok : split_tokens(args[++argidx], ",")) { - auto parts = split_tokens(tok, ":"); - if (GetSize(parts) == 0 && !lut_costs.empty()) - lut_costs.push_back(lut_costs.back()); - else if (GetSize(parts) == 1) - lut_costs.push_back(atoi(parts.at(0).c_str())); - else if (GetSize(parts) == 2) - while (GetSize(lut_costs) < atoi(parts.at(0).c_str())) - lut_costs.push_back(atoi(parts.at(1).c_str())); - else - log_cmd_error("Invalid -luts syntax.\n"); - } - continue; - } - if (arg == "-fast") { - fast_mode = true; - continue; - } - //if (arg == "-dff") { - // dff_mode = true; - // continue; - //} - //if (arg == "-clk" && argidx+1 < args.size()) { - // clk_str = args[++argidx]; - // dff_mode = true; - // continue; - //} - //if (arg == "-keepff") { - // keepff = true; - // continue; - //} - if (arg == "-nocleanup") { - cleanup = false; - continue; - } - if (arg == "-showtmp") { - show_tempdir = true; - continue; - } - if (arg == "-markgroups") { - markgroups = true; - continue; - } - if (arg == "-box" && argidx+1 < args.size()) { - box_file = args[++argidx]; - continue; - } - if (arg == "-W" && argidx+1 < args.size()) { - wire_delay = "-W " + args[++argidx]; - continue; - } - if (arg == "-nomfs") { - nomfs = true; - continue; - } - break; - } - extra_args(args, argidx, design); - - // ABC expects a box file for XAIG - if (box_file.empty()) - box_file = "+/dummy.box"; - - rewrite_filename(box_file); - if (!box_file.empty() && !is_absolute_path(box_file) && box_file[0] != '+') - box_file = std::string(pwd) + "/" + box_file; - - dict box_lookup; - for (auto m : design->modules()) { - auto it = m->attributes.find(ID(abc9_box_id)); - if (it == m->attributes.end()) - continue; - if (m->name.begins_with("$paramod")) - continue; - auto id = it->second.as_int(); - auto r = box_lookup.insert(std::make_pair(id, m->name)); - if (!r.second) - log_error("Module '%s' has the same abc9_box_id = %d value as '%s'.\n", - log_id(m), id, log_id(r.first->second)); - log_assert(r.second); - - RTLIL::Wire *carry_in = nullptr, *carry_out = nullptr; - for (auto p : m->ports) { - auto w = m->wire(p); - log_assert(w); - if (w->attributes.count(ID(abc9_carry))) { - if (w->port_input) { - if (carry_in) - log_error("Module '%s' contains more than one 'abc9_carry' input port.\n", log_id(m)); - carry_in = w; - } - else if (w->port_output) { - if (carry_out) - log_error("Module '%s' contains more than one 'abc9_carry' input port.\n", log_id(m)); - carry_out = w; - } - } - } - if (carry_in || carry_out) { - if (carry_in && !carry_out) - log_error("Module '%s' contains an 'abc9_carry' input port but no output port.\n", log_id(m)); - if (!carry_in && carry_out) - log_error("Module '%s' contains an 'abc9_carry' output port but no input port.\n", log_id(m)); - // Make carry_in the last PI, and carry_out the last PO - // since ABC requires it this way - auto &ports = m->ports; - for (auto it = ports.begin(); it != ports.end(); ) { - RTLIL::Wire* w = m->wire(*it); - log_assert(w); - if (w == carry_in || w == carry_out) { - it = ports.erase(it); - continue; - } - if (w->port_id > carry_in->port_id) - --w->port_id; - if (w->port_id > carry_out->port_id) - --w->port_id; - log_assert(w->port_input || w->port_output); - log_assert(ports[w->port_id-1] == w->name); - ++it; - } - ports.push_back(carry_in->name); - carry_in->port_id = ports.size(); - ports.push_back(carry_out->name); - carry_out->port_id = ports.size(); - } - } - - for (auto mod : design->selected_modules()) - { - if (mod->attributes.count(ID(abc9_box_id))) - continue; - - if (mod->processes.size() > 0) { - log("Skipping module %s as it contains processes.\n", log_id(mod)); - continue; - } - - assign_map.set(mod); - - if (!dff_mode || !clk_str.empty()) { - abc9_module(design, mod, script_file, exe_file, cleanup, lut_costs, dff_mode, clk_str, keepff, - delay_target, lutin_shared, fast_mode, show_tempdir, - box_file, lut_file, wire_delay, box_lookup, nomfs); - continue; - } - - CellTypes ct(design); - - std::vector all_cells = mod->selected_cells(); - std::set unassigned_cells(all_cells.begin(), all_cells.end()); - - std::set expand_queue, next_expand_queue; - std::set expand_queue_up, next_expand_queue_up; - std::set expand_queue_down, next_expand_queue_down; - - typedef tuple clkdomain_t; - std::map> assigned_cells; - std::map assigned_cells_reverse; - - std::map> cell_to_bit, cell_to_bit_up, cell_to_bit_down; - std::map> bit_to_cell, bit_to_cell_up, bit_to_cell_down; - - for (auto cell : all_cells) - { - clkdomain_t key; - - for (auto &conn : cell->connections()) - for (auto bit : conn.second) { - bit = assign_map(bit); - if (bit.wire != nullptr) { - cell_to_bit[cell].insert(bit); - bit_to_cell[bit].insert(cell); - if (ct.cell_input(cell->type, conn.first)) { - cell_to_bit_up[cell].insert(bit); - bit_to_cell_down[bit].insert(cell); - } - if (ct.cell_output(cell->type, conn.first)) { - cell_to_bit_down[cell].insert(bit); - bit_to_cell_up[bit].insert(cell); - } - } - } - - if (cell->type.in(ID($_DFF_N_), ID($_DFF_P_))) - { - key = clkdomain_t(cell->type == ID($_DFF_P_), assign_map(cell->getPort(ID(C))), true, RTLIL::SigSpec()); - } - else - if (cell->type.in(ID($_DFFE_NN_), ID($_DFFE_NP_), ID($_DFFE_PN_), ID($_DFFE_PP_))) - { - bool this_clk_pol = cell->type.in(ID($_DFFE_PN_), ID($_DFFE_PP_)); - bool this_en_pol = cell->type.in(ID($_DFFE_NP_), ID($_DFFE_PP_)); - key = clkdomain_t(this_clk_pol, assign_map(cell->getPort(ID(C))), this_en_pol, assign_map(cell->getPort(ID(E)))); - } - else - continue; - - unassigned_cells.erase(cell); - expand_queue.insert(cell); - expand_queue_up.insert(cell); - expand_queue_down.insert(cell); - - assigned_cells[key].push_back(cell); - assigned_cells_reverse[cell] = key; - } - - while (!expand_queue_up.empty() || !expand_queue_down.empty()) - { - if (!expand_queue_up.empty()) - { - RTLIL::Cell *cell = *expand_queue_up.begin(); - clkdomain_t key = assigned_cells_reverse.at(cell); - expand_queue_up.erase(cell); - - for (auto bit : cell_to_bit_up[cell]) - for (auto c : bit_to_cell_up[bit]) - if (unassigned_cells.count(c)) { - unassigned_cells.erase(c); - next_expand_queue_up.insert(c); - assigned_cells[key].push_back(c); - assigned_cells_reverse[c] = key; - expand_queue.insert(c); - } - } - - if (!expand_queue_down.empty()) - { - RTLIL::Cell *cell = *expand_queue_down.begin(); - clkdomain_t key = assigned_cells_reverse.at(cell); - expand_queue_down.erase(cell); - - for (auto bit : cell_to_bit_down[cell]) - for (auto c : bit_to_cell_down[bit]) - if (unassigned_cells.count(c)) { - unassigned_cells.erase(c); - next_expand_queue_up.insert(c); - assigned_cells[key].push_back(c); - assigned_cells_reverse[c] = key; - expand_queue.insert(c); - } - } - - if (expand_queue_up.empty() && expand_queue_down.empty()) { - expand_queue_up.swap(next_expand_queue_up); - expand_queue_down.swap(next_expand_queue_down); - } - } - - while (!expand_queue.empty()) - { - RTLIL::Cell *cell = *expand_queue.begin(); - clkdomain_t key = assigned_cells_reverse.at(cell); - expand_queue.erase(cell); - - for (auto bit : cell_to_bit.at(cell)) { - for (auto c : bit_to_cell[bit]) - if (unassigned_cells.count(c)) { - unassigned_cells.erase(c); - next_expand_queue.insert(c); - assigned_cells[key].push_back(c); - assigned_cells_reverse[c] = key; - } - bit_to_cell[bit].clear(); - } - - if (expand_queue.empty()) - expand_queue.swap(next_expand_queue); - } - - clkdomain_t key(true, RTLIL::SigSpec(), true, RTLIL::SigSpec()); - for (auto cell : unassigned_cells) { - assigned_cells[key].push_back(cell); - assigned_cells_reverse[cell] = key; - } - - log_header(design, "Summary of detected clock domains:\n"); - for (auto &it : assigned_cells) - log(" %d cells in clk=%s%s, en=%s%s\n", GetSize(it.second), - std::get<0>(it.first) ? "" : "!", log_signal(std::get<1>(it.first)), - std::get<2>(it.first) ? "" : "!", log_signal(std::get<3>(it.first))); - - for (auto &it : assigned_cells) { - clk_polarity = std::get<0>(it.first); - clk_sig = assign_map(std::get<1>(it.first)); - en_polarity = std::get<2>(it.first); - en_sig = assign_map(std::get<3>(it.first)); - abc9_module(design, mod, script_file, exe_file, cleanup, lut_costs, !clk_sig.empty(), "$", - keepff, delay_target, lutin_shared, fast_mode, show_tempdir, - box_file, lut_file, wire_delay, box_lookup, nomfs); - assign_map.set(mod); - } - } - - assign_map.clear(); - - log_pop(); - } -} Abc9TechmapPass; - -PRIVATE_NAMESPACE_END -- cgit v1.2.3 From 509da7ed1a1e27066451f57868108b473cf516a0 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Sat, 28 Dec 2019 16:12:45 +0100 Subject: Revert "Fix xilinx tests, when iopads are default" This reverts commit 477e43d921d204c6bc6403109fea6506802c948c. --- tests/arch/xilinx/add_sub.ys | 2 +- tests/arch/xilinx/adffs.ys | 8 ++++---- tests/arch/xilinx/bug1460.ys | 2 +- tests/arch/xilinx/counter.ys | 2 +- tests/arch/xilinx/dffs.ys | 4 ++-- tests/arch/xilinx/dsp_fastfir.ys | 2 +- tests/arch/xilinx/fsm.ys | 2 +- tests/arch/xilinx/latches.ys | 6 +++--- tests/arch/xilinx/logic.ys | 2 +- tests/arch/xilinx/lutram.ys | 14 +++++++------- tests/arch/xilinx/macc.ys | 4 ++-- tests/arch/xilinx/mul.ys | 2 +- tests/arch/xilinx/mul_unsigned.ys | 2 +- tests/arch/xilinx/mux.ys | 8 ++++---- tests/arch/xilinx/shifter.ys | 2 +- tests/arch/xilinx/xilinx_dffopt.ys | 18 +++++++++--------- 16 files changed, 40 insertions(+), 40 deletions(-) diff --git a/tests/arch/xilinx/add_sub.ys b/tests/arch/xilinx/add_sub.ys index 920717a3d..9dbddce47 100644 --- a/tests/arch/xilinx/add_sub.ys +++ b/tests/arch/xilinx/add_sub.ys @@ -7,5 +7,5 @@ cd top # Constrain all select calls below inside the top module select -assert-count 14 t:LUT2 select -assert-count 6 t:MUXCY select -assert-count 8 t:XORCY -select -assert-none t:LUT2 t:MUXCY t:XORCY t:IBUF t:OBUF %% t:* %D +select -assert-none t:LUT2 t:MUXCY t:XORCY %% t:* %D diff --git a/tests/arch/xilinx/adffs.ys b/tests/arch/xilinx/adffs.ys index ba9ddf90f..c0ff6a2e2 100644 --- a/tests/arch/xilinx/adffs.ys +++ b/tests/arch/xilinx/adffs.ys @@ -9,7 +9,7 @@ cd adff # Constrain all select calls below inside the top module select -assert-count 1 t:BUFG select -assert-count 1 t:FDCE -select -assert-none t:BUFG t:FDCE t:IBUF t:OBUF %% t:* %D +select -assert-none t:BUFG t:FDCE %% t:* %D design -load read @@ -22,7 +22,7 @@ select -assert-count 1 t:BUFG select -assert-count 1 t:FDCE select -assert-count 1 t:INV -select -assert-none t:BUFG t:FDCE t:INV t:IBUF t:OBUF %% t:* %D +select -assert-none t:BUFG t:FDCE t:INV %% t:* %D design -load read @@ -34,7 +34,7 @@ cd dffs # Constrain all select calls below inside the top module select -assert-count 1 t:BUFG select -assert-count 1 t:FDSE -select -assert-none t:BUFG t:FDSE t:IBUF t:OBUF %% t:* %D +select -assert-none t:BUFG t:FDSE %% t:* %D design -load read @@ -47,4 +47,4 @@ select -assert-count 1 t:BUFG select -assert-count 1 t:FDRE_1 select -assert-count 1 t:INV -select -assert-none t:BUFG t:FDRE_1 t:INV t:IBUF t:OBUF %% t:* %D +select -assert-none t:BUFG t:FDRE_1 t:INV %% t:* %D diff --git a/tests/arch/xilinx/bug1460.ys b/tests/arch/xilinx/bug1460.ys index 73fb662dc..2018071cc 100644 --- a/tests/arch/xilinx/bug1460.ys +++ b/tests/arch/xilinx/bug1460.ys @@ -31,4 +31,4 @@ EOT synth_xilinx cd register_file select -assert-count 32 t:RAM32M -select -assert-none t:* t:BUFG %d t:IBUF %d t:OBUF %d t:RAM32M %d +select -assert-none t:* t:BUFG %d t:RAM32M %d diff --git a/tests/arch/xilinx/counter.ys b/tests/arch/xilinx/counter.ys index e4217bbaf..604acdbfc 100644 --- a/tests/arch/xilinx/counter.ys +++ b/tests/arch/xilinx/counter.ys @@ -11,4 +11,4 @@ select -assert-count 8 t:FDCE select -assert-count 1 t:INV select -assert-count 7 t:MUXCY select -assert-count 8 t:XORCY -select -assert-none t:BUFG t:FDCE t:INV t:MUXCY t:XORCY t:IBUF t:OBUF %% t:* %D +select -assert-none t:BUFG t:FDCE t:INV t:MUXCY t:XORCY %% t:* %D diff --git a/tests/arch/xilinx/dffs.ys b/tests/arch/xilinx/dffs.ys index b2cb70323..0bba4858f 100644 --- a/tests/arch/xilinx/dffs.ys +++ b/tests/arch/xilinx/dffs.ys @@ -9,7 +9,7 @@ cd dff # Constrain all select calls below inside the top module select -assert-count 1 t:BUFG select -assert-count 1 t:FDRE -select -assert-none t:BUFG t:FDRE t:IBUF t:OBUF %% t:* %D +select -assert-none t:BUFG t:FDRE %% t:* %D design -load read @@ -21,5 +21,5 @@ cd dffe # Constrain all select calls below inside the top module select -assert-count 1 t:BUFG select -assert-count 1 t:FDRE -select -assert-none t:BUFG t:FDRE t:IBUF t:OBUF %% t:* %D +select -assert-none t:BUFG t:FDRE %% t:* %D diff --git a/tests/arch/xilinx/dsp_fastfir.ys b/tests/arch/xilinx/dsp_fastfir.ys index 05e1785d8..0067a822b 100644 --- a/tests/arch/xilinx/dsp_fastfir.ys +++ b/tests/arch/xilinx/dsp_fastfir.ys @@ -66,4 +66,4 @@ EOT synth_xilinx cd fastfir_dynamictaps select -assert-count 2 t:DSP48E1 -select -assert-none t:* t:DSP48E1 %d t:BUFG %d t:IBUF %d t:OBUF %d +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 d60695e2c..f03400fe7 100644 --- a/tests/arch/xilinx/fsm.ys +++ b/tests/arch/xilinx/fsm.ys @@ -16,4 +16,4 @@ select -assert-count 1 t:FDSE select -assert-count 1 t:LUT2 select -assert-count 3 t:LUT5 select -assert-count 1 t:LUT6 -select -assert-none t:BUFG t:IBUF t:OBUF t:FDRE t:FDSE t:LUT2 t:LUT5 t:LUT6 %% t:* %D +select -assert-none t:BUFG t:FDRE t:FDSE t:LUT2 t:LUT5 t:LUT6 %% t:* %D diff --git a/tests/arch/xilinx/latches.ys b/tests/arch/xilinx/latches.ys index c1caea27a..c87a8e38b 100644 --- a/tests/arch/xilinx/latches.ys +++ b/tests/arch/xilinx/latches.ys @@ -8,7 +8,7 @@ design -load postopt # load the post-opt design (otherwise equiv_opt loads the p cd latchp # Constrain all select calls below inside the top module select -assert-count 1 t:LDCE -select -assert-none t:LDCE t:IBUF t:OBUF %% t:* %D +select -assert-none t:LDCE %% t:* %D design -load read @@ -20,7 +20,7 @@ cd latchn # Constrain all select calls below inside the top module select -assert-count 1 t:LDCE select -assert-count 1 t:INV -select -assert-none t:LDCE t:INV t:IBUF t:OBUF %% t:* %D +select -assert-none t:LDCE t:INV %% t:* %D design -load read @@ -32,4 +32,4 @@ cd latchsr # Constrain all select calls below inside the top module select -assert-count 1 t:LDCE select -assert-count 2 t:LUT3 -select -assert-none t:LDCE t:LUT3 t:IBUF t:OBUF %% t:* %D +select -assert-none t:LDCE t:LUT3 %% t:* %D diff --git a/tests/arch/xilinx/logic.ys b/tests/arch/xilinx/logic.ys index 2372cca61..d5b5c1a37 100644 --- a/tests/arch/xilinx/logic.ys +++ b/tests/arch/xilinx/logic.ys @@ -8,4 +8,4 @@ cd top # Constrain all select calls below inside the top module select -assert-count 1 t:INV select -assert-count 6 t:LUT2 select -assert-count 2 t:LUT4 -select -assert-none t:INV t:LUT2 t:LUT4 t:IBUF t:OBUF %% t:* %D +select -assert-none t:INV t:LUT2 t:LUT4 %% t:* %D diff --git a/tests/arch/xilinx/lutram.ys b/tests/arch/xilinx/lutram.ys index 951517fa9..6c9d1eae1 100644 --- a/tests/arch/xilinx/lutram.ys +++ b/tests/arch/xilinx/lutram.ys @@ -14,7 +14,7 @@ #select -assert-count 1 t:BUFG #select -assert-count 8 t:FDRE #select -assert-count 8 t:RAM16X1D -#select -assert-none t:BUFG t:FDRE t:RAM16X1D t:IBUF t:OBUF %% t:* %D +#select -assert-none t:BUFG t:FDRE t:RAM16X1D %% t:* %D design -reset @@ -34,7 +34,7 @@ cd lutram_1w1r select -assert-count 1 t:BUFG select -assert-count 8 t:FDRE select -assert-count 8 t:RAM32X1D -select -assert-none t:BUFG t:FDRE t:RAM32X1D t:IBUF t:OBUF %% t:* %D +select -assert-none t:BUFG t:FDRE t:RAM32X1D %% t:* %D design -reset @@ -54,7 +54,7 @@ cd lutram_1w1r select -assert-count 1 t:BUFG select -assert-count 8 t:FDRE select -assert-count 8 t:RAM64X1D -select -assert-none t:BUFG t:FDRE t:RAM64X1D t:IBUF t:OBUF %% t:* %D +select -assert-none t:BUFG t:FDRE t:RAM64X1D %% t:* %D design -reset @@ -74,7 +74,7 @@ cd lutram_1w3r select -assert-count 1 t:BUFG select -assert-count 24 t:FDRE select -assert-count 4 t:RAM32M -select -assert-none t:BUFG t:FDRE t:RAM32M t:IBUF t:OBUF %% t:* %D +select -assert-none t:BUFG t:FDRE t:RAM32M %% t:* %D design -reset @@ -94,7 +94,7 @@ cd lutram_1w3r select -assert-count 1 t:BUFG select -assert-count 24 t:FDRE select -assert-count 8 t:RAM64M -select -assert-none t:BUFG t:FDRE t:RAM64M t:IBUF t:OBUF %% t:* %D +select -assert-none t:BUFG t:FDRE t:RAM64M %% t:* %D design -reset @@ -114,7 +114,7 @@ cd lutram_1w1r select -assert-count 1 t:BUFG select -assert-count 6 t:FDRE select -assert-count 1 t:RAM32M -select -assert-none t:BUFG t:FDRE t:RAM32M t:IBUF t:OBUF %% t:* %D +select -assert-none t:BUFG t:FDRE t:RAM32M %% t:* %D design -reset @@ -134,4 +134,4 @@ cd lutram_1w1r select -assert-count 1 t:BUFG select -assert-count 6 t:FDRE select -assert-count 2 t:RAM64M -select -assert-none t:BUFG t:FDRE t:RAM64M t:IBUF t:OBUF %% t:* %D +select -assert-none t:BUFG t:FDRE t:RAM64M %% t:* %D diff --git a/tests/arch/xilinx/macc.ys b/tests/arch/xilinx/macc.ys index 0869a8dae..11e959976 100644 --- a/tests/arch/xilinx/macc.ys +++ b/tests/arch/xilinx/macc.ys @@ -12,7 +12,7 @@ cd macc # Constrain all select calls below inside the top module select -assert-count 1 t:BUFG select -assert-count 1 t:FDRE select -assert-count 1 t:DSP48E1 -select -assert-none t:BUFG t:FDRE t:DSP48E1 t:IBUF t:OBUF %% t:* %D +select -assert-none t:BUFG t:FDRE t:DSP48E1 %% t:* %D design -load read hierarchy -top macc2 @@ -29,4 +29,4 @@ select -assert-count 1 t:DSP48E1 select -assert-count 1 t:FDRE select -assert-count 1 t:LUT2 select -assert-count 40 t:LUT3 -select -assert-none t:BUFG t:DSP48E1 t:FDRE t:LUT2 t:LUT3 t:IBUF t:OBUF %% t:* %D +select -assert-none t:BUFG t:DSP48E1 t:FDRE t:LUT2 t:LUT3 %% t:* %D diff --git a/tests/arch/xilinx/mul.ys b/tests/arch/xilinx/mul.ys index 100de6629..d76814966 100644 --- a/tests/arch/xilinx/mul.ys +++ b/tests/arch/xilinx/mul.ys @@ -6,4 +6,4 @@ design -load postopt # load the post-opt design (otherwise equiv_opt loads the p cd top # Constrain all select calls below inside the top module select -assert-count 1 t:DSP48E1 -select -assert-none t:DSP48E1 t:IBUF t:OBUF %% t:* %D +select -assert-none t:DSP48E1 %% t:* %D diff --git a/tests/arch/xilinx/mul_unsigned.ys b/tests/arch/xilinx/mul_unsigned.ys index 59ead5cda..62495b90c 100644 --- a/tests/arch/xilinx/mul_unsigned.ys +++ b/tests/arch/xilinx/mul_unsigned.ys @@ -8,4 +8,4 @@ cd mul_unsigned # Constrain all select calls below inside the top module select -assert-count 1 t:BUFG select -assert-count 1 t:DSP48E1 select -assert-count 30 t:FDRE -select -assert-none t:DSP48E1 t:FDRE t:BUFG t:IBUF t:OBUF %% t:* %D +select -assert-none t:DSP48E1 t:FDRE t:BUFG %% t:* %D diff --git a/tests/arch/xilinx/mux.ys b/tests/arch/xilinx/mux.ys index faad64cc5..388272449 100644 --- a/tests/arch/xilinx/mux.ys +++ b/tests/arch/xilinx/mux.ys @@ -8,7 +8,7 @@ design -load postopt # load the post-opt design (otherwise equiv_opt loads the p cd mux2 # Constrain all select calls below inside the top module select -assert-count 1 t:LUT3 -select -assert-none t:LUT3 t:IBUF t:OBUF %% t:* %D +select -assert-none t:LUT3 %% t:* %D design -load read @@ -19,7 +19,7 @@ design -load postopt # load the post-opt design (otherwise equiv_opt loads the p cd mux4 # Constrain all select calls below inside the top module select -assert-count 1 t:LUT6 -select -assert-none t:LUT6 t:IBUF t:OBUF %% t:* %D +select -assert-none t:LUT6 %% t:* %D design -load read @@ -31,7 +31,7 @@ cd mux8 # Constrain all select calls below inside the top module select -assert-count 1 t:LUT3 select -assert-count 2 t:LUT6 -select -assert-none t:LUT3 t:LUT6 t:IBUF t:OBUF %% t:* %D +select -assert-none t:LUT3 t:LUT6 %% t:* %D design -load read @@ -44,4 +44,4 @@ select -assert-min 5 t:LUT6 select -assert-max 7 t:LUT6 select -assert-max 2 t:MUXF7 -select -assert-none t:LUT6 t:MUXF7 t:IBUF t:OBUF %% t:* %D +select -assert-none t:LUT6 t:MUXF7 %% t:* %D diff --git a/tests/arch/xilinx/shifter.ys b/tests/arch/xilinx/shifter.ys index 4d63ba9c2..455437f18 100644 --- a/tests/arch/xilinx/shifter.ys +++ b/tests/arch/xilinx/shifter.ys @@ -8,4 +8,4 @@ cd top # Constrain all select calls below inside the top module select -assert-count 1 t:BUFG select -assert-count 8 t:FDRE -select -assert-none t:BUFG t:FDRE t:IBUF t:OBUF %% t:* %D +select -assert-none t:BUFG t:FDRE %% t:* %D diff --git a/tests/arch/xilinx/xilinx_dffopt.ys b/tests/arch/xilinx/xilinx_dffopt.ys index 5dbe11b27..dc036acfd 100644 --- a/tests/arch/xilinx/xilinx_dffopt.ys +++ b/tests/arch/xilinx/xilinx_dffopt.ys @@ -28,7 +28,7 @@ clean select -assert-count 1 t:FDRE select -assert-count 1 t:LUT6 select -assert-count 3 t:LUT2 -select -assert-none t:FDRE t:LUT6 t:LUT2 t:IBUF t:OBUF %% t:* %D +select -assert-none t:FDRE t:LUT6 t:LUT2 %% t:* %D design -load t0 @@ -39,7 +39,7 @@ clean select -assert-count 1 t:FDRE select -assert-count 1 t:LUT4 select -assert-count 3 t:LUT2 -select -assert-none t:FDRE t:LUT4 t:LUT2 t:IBUF t:OBUF %% t:* %D +select -assert-none t:FDRE t:LUT4 t:LUT2 %% t:* %D design -reset @@ -74,7 +74,7 @@ clean select -assert-count 1 t:FDSE select -assert-count 1 t:LUT6 select -assert-count 3 t:LUT2 -select -assert-none t:FDSE t:LUT6 t:LUT2 t:IBUF t:OBUF %% t:* %D +select -assert-none t:FDSE t:LUT6 t:LUT2 %% t:* %D design -load t0 @@ -85,7 +85,7 @@ clean select -assert-count 1 t:FDSE select -assert-count 1 t:LUT4 select -assert-count 3 t:LUT2 -select -assert-none t:FDSE t:LUT4 t:LUT2 t:IBUF t:OBUF %% t:* %D +select -assert-none t:FDSE t:LUT4 t:LUT2 %% t:* %D design -reset @@ -120,7 +120,7 @@ clean select -assert-count 1 t:FDCE select -assert-count 1 t:LUT4 select -assert-count 3 t:LUT2 -select -assert-none t:FDCE t:LUT4 t:LUT2 t:IBUF t:OBUF %% t:* %D +select -assert-none t:FDCE t:LUT4 t:LUT2 %% t:* %D design -reset @@ -154,7 +154,7 @@ clean select -assert-count 1 t:FDSE select -assert-count 1 t:LUT5 select -assert-count 2 t:LUT2 -select -assert-none t:FDSE t:LUT5 t:LUT2 t:IBUF t:OBUF %% t:* %D +select -assert-none t:FDSE t:LUT5 t:LUT2 %% t:* %D design -load t0 @@ -164,7 +164,7 @@ clean select -assert-count 1 t:FDSE select -assert-count 2 t:LUT2 -select -assert-none t:FDSE t:LUT2 t:IBUF t:OBUF %% t:* %D +select -assert-none t:FDSE t:LUT2 %% t:* %D design -reset @@ -200,7 +200,7 @@ clean select -assert-count 1 t:FDRSE select -assert-count 1 t:LUT6 select -assert-count 4 t:LUT2 -select -assert-none t:FDRSE t:LUT6 t:LUT2 t:IBUF t:OBUF %% t:* %D +select -assert-none t:FDRSE t:LUT6 t:LUT2 %% t:* %D design -load t0 @@ -211,6 +211,6 @@ clean select -assert-count 1 t:FDRSE select -assert-count 1 t:LUT4 select -assert-count 4 t:LUT2 -select -assert-none t:FDRSE t:LUT4 t:LUT2 t:IBUF t:OBUF %% t:* %D +select -assert-none t:FDRSE t:LUT4 t:LUT2 %% t:* %D design -reset -- cgit v1.2.3 From a82c701668d8197c01e54cb68bc45f2278f3172f Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Sat, 28 Dec 2019 16:22:24 +0100 Subject: Make test without iopads --- tests/arch/xilinx/add_sub.ys | 2 +- tests/arch/xilinx/adffs.ys | 8 ++++---- tests/arch/xilinx/attributes_test.ys | 12 ++++++------ tests/arch/xilinx/blockram.ys | 24 ++++++++++++------------ tests/arch/xilinx/bug1460.ys | 2 +- tests/arch/xilinx/counter.ys | 2 +- tests/arch/xilinx/dffs.ys | 4 ++-- tests/arch/xilinx/dsp_fastfir.ys | 2 +- tests/arch/xilinx/fsm.ys | 2 +- tests/arch/xilinx/latches.ys | 6 +++--- tests/arch/xilinx/logic.ys | 2 +- tests/arch/xilinx/lutram.ys | 14 +++++++------- tests/arch/xilinx/macc.ys | 8 ++++---- tests/arch/xilinx/mul.ys | 2 +- tests/arch/xilinx/mul_unsigned.ys | 2 +- tests/arch/xilinx/mux.ys | 8 ++++---- tests/arch/xilinx/shifter.ys | 2 +- 17 files changed, 51 insertions(+), 51 deletions(-) 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/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_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 d76814966..b04833a43 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 diff --git a/tests/arch/xilinx/mul_unsigned.ys b/tests/arch/xilinx/mul_unsigned.ys index 62495b90c..0a7644b65 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 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 -- cgit v1.2.3 From f9749c202c93e1c9c6edb522999eacc323039b95 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Sat, 28 Dec 2019 16:43:19 +0100 Subject: Fix new tests --- tests/arch/xilinx/dsp_cascade.ys | 8 ++++---- tests/arch/xilinx/mul.ys | 2 +- tests/arch/xilinx/mul_unsigned.ys | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) 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/mul.ys b/tests/arch/xilinx/mul.ys index 049a3da7e..490846ff1 100644 --- a/tests/arch/xilinx/mul.ys +++ b/tests/arch/xilinx/mul.ys @@ -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 830dd639c..980263cbd 100644 --- a/tests/arch/xilinx/mul_unsigned.ys +++ b/tests/arch/xilinx/mul_unsigned.ys @@ -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 -- cgit v1.2.3 From 52a27700e2b985d56821ffefb3c61f88cfb96e1a Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 30 Dec 2019 12:26:39 -0800 Subject: Grammar --- passes/techmap/abc.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/techmap/abc.cc b/passes/techmap/abc.cc index b29480e26..279b32223 100644 --- a/passes/techmap/abc.cc +++ b/passes/techmap/abc.cc @@ -1767,7 +1767,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"); -- cgit v1.2.3 From 566d9fb77f8688022ae7247fa9466a4327b2adb7 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 30 Dec 2019 11:57:18 -0800 Subject: Revert "ABC to call retime all the time" This reverts commit 9aa94370a54c016421740d2ce32ef0aa338d0dbd. --- passes/techmap/abc.cc | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/passes/techmap/abc.cc b/passes/techmap/abc.cc index b29480e26..1852cacc0 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); -- cgit v1.2.3 From aa6d06c1b5b0083096ad547b0ad2600fcdc854f4 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 30 Dec 2019 12:09:53 -0800 Subject: Revert "Revert "synth_* with -retime option now calls abc with -D 1 as well"" This reverts commit 6008bb7002f874e5c748eaa2050e7b6c17b32745. --- techlibs/achronix/synth_achronix.cc | 4 ++-- techlibs/anlogic/synth_anlogic.cc | 2 +- techlibs/coolrunner2/synth_coolrunner2.cc | 2 +- techlibs/easic/synth_easic.cc | 2 +- techlibs/ecp5/synth_ecp5.cc | 2 +- techlibs/gowin/synth_gowin.cc | 2 +- techlibs/greenpak4/synth_greenpak4.cc | 2 +- techlibs/ice40/synth_ice40.cc | 2 +- techlibs/intel/synth_intel.cc | 2 +- techlibs/sf2/synth_sf2.cc | 2 +- techlibs/xilinx/synth_xilinx.cc | 4 ++-- 11 files changed, 13 insertions(+), 13 deletions(-) diff --git a/techlibs/achronix/synth_achronix.cc b/techlibs/achronix/synth_achronix.cc index 626860d9c..3dbf20911 100755 --- a/techlibs/achronix/synth_achronix.cc +++ b/techlibs/achronix/synth_achronix.cc @@ -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/synth_anlogic.cc b/techlibs/anlogic/synth_anlogic.cc index b87fc8566..310c9c76c 100644 --- a/techlibs/anlogic/synth_anlogic.cc +++ b/techlibs/anlogic/synth_anlogic.cc @@ -164,7 +164,7 @@ struct SynthAnlogicPass : public ScriptPass run("opt -undriven -fine"); 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")) diff --git a/techlibs/coolrunner2/synth_coolrunner2.cc b/techlibs/coolrunner2/synth_coolrunner2.cc index 014c68622..d73241fa8 100644 --- a/techlibs/coolrunner2/synth_coolrunner2.cc +++ b/techlibs/coolrunner2/synth_coolrunner2.cc @@ -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..7bacc7890 100644 --- a/techlibs/easic/synth_easic.cc +++ b/techlibs/easic/synth_easic.cc @@ -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/synth_ecp5.cc b/techlibs/ecp5/synth_ecp5.cc index a0ea6d1f9..24e300fa8 100644 --- a/techlibs/ecp5/synth_ecp5.cc +++ b/techlibs/ecp5/synth_ecp5.cc @@ -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/gowin/synth_gowin.cc b/techlibs/gowin/synth_gowin.cc index 6cf058f29..5acc096a3 100644 --- a/techlibs/gowin/synth_gowin.cc +++ b/techlibs/gowin/synth_gowin.cc @@ -209,7 +209,7 @@ struct SynthGowinPass : public ScriptPass 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"); } diff --git a/techlibs/greenpak4/synth_greenpak4.cc b/techlibs/greenpak4/synth_greenpak4.cc index eeb001b46..3222be2e3 100644 --- a/techlibs/greenpak4/synth_greenpak4.cc +++ b/techlibs/greenpak4/synth_greenpak4.cc @@ -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/synth_ice40.cc b/techlibs/ice40/synth_ice40.cc index ed7a16c08..fe1228165 100644 --- a/techlibs/ice40/synth_ice40.cc +++ b/techlibs/ice40/synth_ice40.cc @@ -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..f033f3acc 100644 --- a/techlibs/intel/synth_intel.cc +++ b/techlibs/intel/synth_intel.cc @@ -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")) { diff --git a/techlibs/sf2/synth_sf2.cc b/techlibs/sf2/synth_sf2.cc index 0924df7a6..3c5a58b4c 100644 --- a/techlibs/sf2/synth_sf2.cc +++ b/techlibs/sf2/synth_sf2.cc @@ -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/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index a19046911..afe4d483b 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -555,9 +555,9 @@ struct SynthXilinxPass : public ScriptPass } else { if (nowidelut) - run("abc -luts 2:2,3,6:5" + string(retime ? " -dff" : "")); + run("abc -luts 2:2,3,6:5" + string(retime ? " -dff -D 1" : "")); else - run("abc -luts 2:2,3,6:5,10,20" + string(retime ? " -dff" : "")); + run("abc -luts 2:2,3,6:5,10,20" + string(retime ? " -dff -D 1" : "")); } run("clean"); -- cgit v1.2.3 From c9e3b26412d6e5c5405f131b7526dec632fbb315 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 30 Dec 2019 12:05:52 -0800 Subject: Disable synth_gowin -abc9 as it offers no advantages yet --- techlibs/gowin/synth_gowin.cc | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/techlibs/gowin/synth_gowin.cc b/techlibs/gowin/synth_gowin.cc index 5acc096a3..8431473f0 100644 --- a/techlibs/gowin/synth_gowin.cc +++ b/techlibs/gowin/synth_gowin.cc @@ -62,16 +62,16 @@ struct SynthGowinPass : 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(" -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"); @@ -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; @@ -227,13 +227,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"); -- cgit v1.2.3 From 79448f9be035c88589b4e9c0de6b2bdc5acbd4df Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 30 Dec 2019 12:11:45 -0800 Subject: Update doc that "-retime" calls abc with "-dff -D 1" --- techlibs/achronix/synth_achronix.cc | 2 +- techlibs/anlogic/synth_anlogic.cc | 2 +- techlibs/coolrunner2/synth_coolrunner2.cc | 2 +- techlibs/easic/synth_easic.cc | 2 +- techlibs/ecp5/synth_ecp5.cc | 2 +- techlibs/efinix/synth_efinix.cc | 4 ++-- techlibs/greenpak4/synth_greenpak4.cc | 2 +- techlibs/ice40/synth_ice40.cc | 2 +- techlibs/intel/synth_intel.cc | 2 +- techlibs/sf2/synth_sf2.cc | 2 +- techlibs/xilinx/synth_xilinx.cc | 2 +- 11 files changed, 12 insertions(+), 12 deletions(-) diff --git a/techlibs/achronix/synth_achronix.cc b/techlibs/achronix/synth_achronix.cc index 3dbf20911..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"); diff --git a/techlibs/anlogic/synth_anlogic.cc b/techlibs/anlogic/synth_anlogic.cc index 310c9c76c..57b8a2b26 100644 --- a/techlibs/anlogic/synth_anlogic.cc +++ b/techlibs/anlogic/synth_anlogic.cc @@ -58,7 +58,7 @@ 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("\n"); log("The following commands are executed by this synthesis command:\n"); diff --git a/techlibs/coolrunner2/synth_coolrunner2.cc b/techlibs/coolrunner2/synth_coolrunner2.cc index d73241fa8..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"); diff --git a/techlibs/easic/synth_easic.cc b/techlibs/easic/synth_easic.cc index 7bacc7890..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"); diff --git a/techlibs/ecp5/synth_ecp5.cc b/techlibs/ecp5/synth_ecp5.cc index 24e300fa8..1ecb9cac3 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"); diff --git a/techlibs/efinix/synth_efinix.cc b/techlibs/efinix/synth_efinix.cc index 26a8d4eda..6fe0182ac 100644 --- a/techlibs/efinix/synth_efinix.cc +++ b/techlibs/efinix/synth_efinix.cc @@ -58,7 +58,7 @@ 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("\n"); log("The following commands are executed by this synthesis command:\n"); @@ -164,7 +164,7 @@ struct SynthEfinixPass : public ScriptPass run("opt -undriven -fine"); 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")) diff --git a/techlibs/greenpak4/synth_greenpak4.cc b/techlibs/greenpak4/synth_greenpak4.cc index 3222be2e3..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"); diff --git a/techlibs/ice40/synth_ice40.cc b/techlibs/ice40/synth_ice40.cc index fe1228165..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"); diff --git a/techlibs/intel/synth_intel.cc b/techlibs/intel/synth_intel.cc index f033f3acc..a3d346407 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(); diff --git a/techlibs/sf2/synth_sf2.cc b/techlibs/sf2/synth_sf2.cc index 3c5a58b4c..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"); diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index afe4d483b..215a48f95 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -110,7 +110,7 @@ struct SynthXilinxPass : public ScriptPass log(" 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(" -abc9\n"); log(" use new ABC9 flow (EXPERIMENTAL)\n"); -- cgit v1.2.3 From d7ada6649766cfa32b077a744e066476278afd02 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 30 Dec 2019 14:13:16 -0800 Subject: Add "synth_xilinx -dff" option, cleanup abc9 --- backends/aiger/xaiger.cc | 5 ++- passes/techmap/abc9.cc | 68 ++++++++++----------------------- techlibs/xilinx/abc9_map.v | 84 +++++++++++++++++++++++++++++++++++++++++ techlibs/xilinx/synth_xilinx.cc | 16 +++++++- 4 files changed, 120 insertions(+), 53 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 80077c10a..d27e0cde5 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -251,7 +251,7 @@ struct XAigerWriter RTLIL::Module* inst_module = module->design->module(cell->type); if (inst_module) { - bool abc9_box = inst_module->attributes.count("\\abc9_box_id"); + bool abc9_box = inst_module->attributes.count("\\abc9_box_id") && !cell->get_bool_attribute("\\abc9_keep"); for (const auto &conn : cell->connections()) { auto port_wire = inst_module->wire(conn.first); @@ -403,7 +403,8 @@ struct XAigerWriter log_assert(cell); RTLIL::Module* box_module = module->design->module(cell->type); - if (!box_module || !box_module->attributes.count("\\abc9_box_id")) + if (!box_module || !box_module->attributes.count("\\abc9_box_id") + || cell->get_bool_attribute("\\abc9_keep")) continue; bool blackbox = box_module->get_blackbox_attribute(true /* ignore_wb */); diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 857f1a0a6..19a1d2ccb 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -249,9 +249,8 @@ struct abc9_output_filter }; void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string script_file, std::string exe_file, - bool cleanup, vector lut_costs, bool /*dff_mode*/, std::string /*clk_str*/, - bool /*keepff*/, std::string delay_target, std::string /*lutin_shared*/, bool fast_mode, - bool show_tempdir, std::string box_file, std::string lut_file, + bool cleanup, vector lut_costs, std::string delay_target, std::string /*lutin_shared*/, bool fast_mode, + const std::vector &/*cells*/, bool show_tempdir, std::string box_file, std::string lut_file, std::string wire_delay, const dict &box_lookup, bool nomfs ) { @@ -294,20 +293,10 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip } 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); @@ -439,8 +428,16 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip 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); + if (jt->second) { + auto kt = cell->attributes.find("\\abc9_keep"); + bool abc9_keep = false; + if (kt != cell->attributes.end()) { + abc9_keep = kt->second.as_bool(); + cell->attributes.erase(kt); + } + if (!abc9_keep) + boxes.emplace_back(cell); + } } dict> bit_drivers, bit_users; @@ -766,7 +763,7 @@ 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()); + log("%s\n", fold_abc9_cmd(ABC_COMMAND_LUT).c_str()); log("\n"); log(" for -lut/-luts (different LUT sizes):\n"); log("%s\n", fold_abc9_cmd(ABC_COMMAND_LUT).c_str()); @@ -782,8 +779,6 @@ struct Abc9Pass : public Pass { log(" set delay target. the string {D} in the default scripts above is\n"); log(" replaced by this option when used, and an empty string otherwise\n"); log(" (indicating best possible delay).\n"); -// log(" This also replaces 'dretime' with 'dretime; retime -o {D}' in the\n"); -// log(" default scripts above.\n"); log("\n"); // log(" -S \n"); // log(" maximum number of LUT inputs shared.\n"); @@ -805,19 +800,6 @@ 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 [!][,[!]]\n"); -// log(" use only the specified clock domain. this is like -dff, but only FF\n"); -// log(" cells that belong to the specified clock domain are used.\n"); -// log("\n"); -// log(" -keepff\n"); -// log(" set the \"keep\" attribute on flip-flop output wires. (and thus preserve\n"); -// log(" them, for example for equivalence checking.)\n"); -// log("\n"); log(" -nocleanup\n"); log(" when this option is used, the temporary files created by this pass\n"); log(" are not removed. this is useful for debugging.\n"); @@ -865,7 +847,7 @@ struct Abc9Pass : public Pass { #endif std::string script_file, clk_str, box_file, lut_file; std::string delay_target, lutin_shared = "-S 1", wire_delay; - bool fast_mode = false, /*dff_mode = false,*/ keepff = false, cleanup = true; + bool fast_mode = false, cleanup = true; bool show_tempdir = false; bool nomfs = false; vector lut_costs; @@ -956,19 +938,6 @@ struct Abc9Pass : public Pass { 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; @@ -1083,7 +1052,7 @@ struct Abc9Pass : public Pass { typedef SigSpec clkdomain_t; dict clk_to_mergeability; - std::vector all_cells = module->selected_cells(); + const std::vector all_cells = module->selected_cells(); #if 0 pool unassigned_cells(all_cells.begin(), all_cells.end()); @@ -1116,7 +1085,8 @@ struct Abc9Pass : public Pass { for (auto cell : all_cells) { auto inst_module = design->module(cell->type); - if (!inst_module || !inst_module->attributes.count("\\abc9_flop")) + if (!inst_module || !inst_module->attributes.count("\\abc9_flop") + || cell->get_bool_attribute("\\abc9_keep")) continue; Wire *abc9_clock_wire = module->wire(stringf("%s.$abc9_clock", cell->name.c_str())); @@ -1268,8 +1238,8 @@ struct Abc9Pass : public Pass { RTLIL::Selection& sel = design->selection_stack.back(); sel.selected_members[module->name] = std::move(it.second); #endif - abc9_module(design, module, script_file, exe_file, cleanup, lut_costs, false, "$", - keepff, delay_target, lutin_shared, fast_mode, show_tempdir, + abc9_module(design, module, script_file, exe_file, cleanup, lut_costs, + delay_target, lutin_shared, fast_mode, all_cells, show_tempdir, box_file, lut_file, wire_delay, box_lookup, nomfs); #if 0 assign_map.set(module); diff --git a/techlibs/xilinx/abc9_map.v b/techlibs/xilinx/abc9_map.v index d2d7d9114..1e17d4766 100644 --- a/techlibs/xilinx/abc9_map.v +++ b/techlibs/xilinx/abc9_map.v @@ -83,6 +83,7 @@ module FDRE (output Q, input C, CE, D, R); parameter [0:0] IS_C_INVERTED = 1'b0; parameter [0:0] IS_D_INVERTED = 1'b0; parameter [0:0] IS_R_INVERTED = 1'b0; +`ifdef DFF_MODE wire QQ, $nextQ; generate if (INIT == 1'b1) begin assign Q = ~QQ; @@ -113,9 +114,21 @@ module FDRE (output Q, input C, CE, D, R); wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, IS_C_INVERTED}; wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = QQ; +`else + (* abc9_keep *) + FDRE #( + .INIT(INIT), + .IS_C_INVERTED(IS_C_INVERTED), + .IS_D_INVERTED(IS_D_INVERTED), + .IS_R_INVERTED(IS_R_INVERTED) + ) _TECHMAP_REPLACE_ ( + .D(D), .Q(Q), .C(C), .CE(CE), .R(R) + ); +`endif endmodule module FDRE_1 (output Q, input C, CE, D, R); parameter [0:0] INIT = 1'b0; +`ifdef DFF_MODE wire QQ, $nextQ; generate if (INIT == 1'b1) begin assign Q = ~QQ; @@ -140,6 +153,14 @@ module FDRE_1 (output Q, input C, CE, D, R); wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */}; wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = QQ; +`else + (* abc9_keep *) + FDRE_1 #( + .INIT(INIT) + ) _TECHMAP_REPLACE_ ( + .D(D), .Q(Q), .C(C), .CE(CE), .R(R) + ); +`endif endmodule module FDCE (output Q, input C, CE, D, CLR); @@ -147,6 +168,7 @@ module FDCE (output Q, input C, CE, D, CLR); parameter [0:0] IS_C_INVERTED = 1'b0; parameter [0:0] IS_D_INVERTED = 1'b0; parameter [0:0] IS_CLR_INVERTED = 1'b0; +`ifdef DFF_MODE wire QQ, $nextQ, $abc9_currQ; generate if (INIT == 1'b1) begin assign Q = ~QQ; @@ -190,9 +212,21 @@ module FDCE (output Q, input C, CE, D, CLR); wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, IS_C_INVERTED}; wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ; +`else + (* abc9_keep *) + FDCE #( + .INIT(INIT), + .IS_C_INVERTED(IS_C_INVERTED), + .IS_D_INVERTED(IS_D_INVERTED), + .IS_CLR_INVERTED(IS_CLR_INVERTED) + ) _TECHMAP_REPLACE_ ( + .D(D), .Q(Q), .C(C), .CE(CE), .CLR(CLR) + ); +`endif endmodule module FDCE_1 (output Q, input C, CE, D, CLR); parameter [0:0] INIT = 1'b0; +`ifdef DFF_MODE wire QQ, $nextQ, $abc9_currQ; generate if (INIT == 1'b1) begin assign Q = ~QQ; @@ -228,6 +262,14 @@ module FDCE_1 (output Q, input C, CE, D, CLR); wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */}; wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ; +`else + (* abc9_keep *) + FDCE_1 #( + .INIT(INIT) + ) _TECHMAP_REPLACE_ ( + .D(D), .Q(Q), .C(C), .CE(CE), .CLR(CLR) + ); +`endif endmodule module FDPE (output Q, input C, CE, D, PRE); @@ -235,6 +277,7 @@ module FDPE (output Q, input C, CE, D, PRE); parameter [0:0] IS_C_INVERTED = 1'b0; parameter [0:0] IS_D_INVERTED = 1'b0; parameter [0:0] IS_PRE_INVERTED = 1'b0; +`ifdef DFF_MODE wire QQ, $nextQ, $abc9_currQ; generate if (INIT == 1'b1) begin assign Q = ~QQ; @@ -276,9 +319,21 @@ module FDPE (output Q, input C, CE, D, PRE); wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, IS_C_INVERTED}; wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ; +`else + (* abc9_keep *) + FDPE #( + .INIT(INIT), + .IS_C_INVERTED(IS_C_INVERTED), + .IS_D_INVERTED(IS_D_INVERTED), + .IS_PRE_INVERTED(IS_PRE_INVERTED), + ) _TECHMAP_REPLACE_ ( + .D(D), .Q(Q), .C(C), .CE(CE), .PRE(PRE) + ); +`endif endmodule module FDPE_1 (output Q, input C, CE, D, PRE); parameter [0:0] INIT = 1'b1; +`ifdef DFF_MODE wire QQ, $nextQ, $abc9_currQ; generate if (INIT == 1'b1) begin assign Q = ~QQ; @@ -314,6 +369,14 @@ module FDPE_1 (output Q, input C, CE, D, PRE); wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */}; wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ; +`else + (* abc9_keep *) + FDPE_1 #( + .INIT(INIT) + ) _TECHMAP_REPLACE_ ( + .D(D), .Q(Q), .C(C), .CE(CE), .PRE(PRE) + ); +`endif endmodule module FDSE (output Q, input C, CE, D, S); @@ -321,6 +384,7 @@ module FDSE (output Q, input C, CE, D, S); parameter [0:0] IS_C_INVERTED = 1'b0; parameter [0:0] IS_D_INVERTED = 1'b0; parameter [0:0] IS_S_INVERTED = 1'b0; +`ifdef DFF_MODE wire QQ, $nextQ; generate if (INIT == 1'b1) begin assign Q = ~QQ; @@ -350,9 +414,21 @@ module FDSE (output Q, input C, CE, D, S); wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, IS_C_INVERTED}; wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = QQ; +`else + (* abc9_keep *) + FDSE #( + .INIT(INIT), + .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) + ); +`endif endmodule module FDSE_1 (output Q, input C, CE, D, S); parameter [0:0] INIT = 1'b1; +`ifdef DFF_MODE wire QQ, $nextQ; generate if (INIT == 1'b1) begin assign Q = ~QQ; @@ -376,6 +452,14 @@ module FDSE_1 (output Q, input C, CE, D, S); wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */}; wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = QQ; +`else + (* abc9_keep *) + FDSE_1 #( + .INIT(INIT) + ) _TECHMAP_REPLACE_ ( + .D(D), .Q(Q), .C(C), .CE(CE), .S(S) + ); +`endif endmodule module RAM32X1D ( diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index ac6fedc58..e7069f286 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -109,6 +109,9 @@ struct SynthXilinxPass : public ScriptPass log(" -flatten\n"); log(" flatten design before synthesis\n"); log("\n"); + log(" -dff\n"); + log(" run 'abc9' with -dff option\n"); + log("\n"); log(" -retime\n"); log(" run 'abc' with -dff option\n"); log("\n"); @@ -122,7 +125,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, iopad, noiopad, noclkbuf, nobram, nolutram, nosrl, nocarry, nowidelut, nodsp, uram; + bool abc9, dff_mode; bool flatten_before_abc; int widemux; @@ -148,6 +152,7 @@ struct SynthXilinxPass : public ScriptPass nodsp = false; uram = false; abc9 = false; + dff_mode = false; flatten_before_abc = false; widemux = 0; } @@ -256,6 +261,10 @@ struct SynthXilinxPass : public ScriptPass uram = true; continue; } + if (args[argidx] == "-dff") { + dff_mode = true; + continue; + } break; } extra_args(args, argidx, design); @@ -540,7 +549,10 @@ struct SynthXilinxPass : public ScriptPass 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); -- cgit v1.2.3 From a038294a87b44a8eadfb62453f1fd76eec5a04ef Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 30 Dec 2019 14:19:29 -0800 Subject: Tidy up abc9_map.v --- techlibs/xilinx/abc9_map.v | 206 ++++++++++++++++++++++----------------------- 1 file changed, 103 insertions(+), 103 deletions(-) diff --git a/techlibs/xilinx/abc9_map.v b/techlibs/xilinx/abc9_map.v index 1e17d4766..2cabe57d7 100644 --- a/techlibs/xilinx/abc9_map.v +++ b/techlibs/xilinx/abc9_map.v @@ -49,10 +49,10 @@ // || Comb box || // || || // || /\/\/\/\ || -// D -->>-----< > || +------+ -// R -->>-----< Comb. > || |$__ABC| -// CE -->>-----< logic >--->>-- $nextQ --| _FF_ |--+-->> Q -// $abc9_currQ +-->>-----< > || +------+ | +// D -->>-----< > || +// R -->>-----< Comb. > || +----------+ +// CE -->>-----< logic >--->>-- $Q --|$__ABC_FF_|--+-->> Q +// $abc9_currQ +-->>-----< > || +----------+ | // | || \/\/\/\/ || | // | || || | // | ++==================++ | @@ -84,7 +84,7 @@ module FDRE (output Q, input C, CE, D, R); parameter [0:0] IS_D_INVERTED = 1'b0; parameter [0:0] IS_R_INVERTED = 1'b0; `ifdef DFF_MODE - wire QQ, $nextQ; + wire QQ, $Q; generate if (INIT == 1'b1) begin assign Q = ~QQ; FDSE #( @@ -93,7 +93,7 @@ module FDRE (output Q, input C, CE, D, R); .IS_D_INVERTED(IS_D_INVERTED), .IS_S_INVERTED(IS_R_INVERTED) ) _TECHMAP_REPLACE_ ( - .D(~D), .Q($nextQ), .C(C), .CE(CE), .S(R) + .D(~D), .Q($Q), .C(C), .CE(CE), .S(R) ); end else begin @@ -104,11 +104,11 @@ module FDRE (output Q, input C, CE, D, R); .IS_D_INVERTED(IS_D_INVERTED), .IS_R_INVERTED(IS_R_INVERTED) ) _TECHMAP_REPLACE_ ( - .D(D), .Q($nextQ), .C(C), .CE(CE), .R(R) + .D(D), .Q($Q), .C(C), .CE(CE), .R(R) ); end endgenerate - \$__ABC9_FF_ abc_dff (.D($nextQ), .Q(QQ)); + $__ABC9_FF_ abc_dff (.D($Q), .Q(QQ)); // Special signals wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, IS_C_INVERTED}; @@ -129,13 +129,13 @@ endmodule module FDRE_1 (output Q, input C, CE, D, R); parameter [0:0] INIT = 1'b0; `ifdef DFF_MODE - wire QQ, $nextQ; + wire QQ, $Q; generate if (INIT == 1'b1) begin assign Q = ~QQ; FDSE_1 #( .INIT(1'b0) ) _TECHMAP_REPLACE_ ( - .D(~D), .Q($nextQ), .C(C), .CE(CE), .S(R) + .D(~D), .Q($Q), .C(C), .CE(CE), .S(R) ); end else begin @@ -143,11 +143,11 @@ module FDRE_1 (output Q, input C, CE, D, R); FDRE_1 #( .INIT(1'b0) ) _TECHMAP_REPLACE_ ( - .D(D), .Q($nextQ), .C(C), .CE(CE), .R(R) + .D(D), .Q($Q), .C(C), .CE(CE), .R(R) ); end endgenerate - \$__ABC9_FF_ abc_dff (.D($nextQ), .Q(QQ)); + $__ABC9_FF_ abc_dff (.D($Q), .Q(QQ)); // Special signals wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */}; @@ -169,7 +169,7 @@ module FDCE (output Q, input C, CE, D, CLR); parameter [0:0] IS_D_INVERTED = 1'b0; parameter [0:0] IS_CLR_INVERTED = 1'b0; `ifdef DFF_MODE - wire QQ, $nextQ, $abc9_currQ; + wire QQ, $Q, $abc9_currQ; generate if (INIT == 1'b1) begin assign Q = ~QQ; FDPE #( @@ -178,7 +178,7 @@ module FDCE (output Q, input C, CE, D, CLR); .IS_D_INVERTED(IS_D_INVERTED), .IS_PRE_INVERTED(IS_CLR_INVERTED) ) _TECHMAP_REPLACE_ ( - .D(~D), .Q($nextQ), .C(C), .CE(CE), .PRE(CLR) + .D(~D), .Q($Q), .C(C), .CE(CE), .PRE(CLR) // ^^^ Note that async // control is not directly // supported by abc9 but its @@ -186,7 +186,7 @@ module FDCE (output Q, input C, CE, D, CLR); // $__ABC9_ASYNC1 below ); // Since this is an async flop, async behaviour is dealt with here - \$__ABC9_ASYNC0 abc_async (.A($abc9_currQ), .S(CLR ^ IS_CLR_INVERTED), .Y(QQ)); + $__ABC9_ASYNC0 abc_async (.A($abc9_currQ), .S(CLR ^ IS_CLR_INVERTED), .Y(QQ)); end else begin assign Q = QQ; @@ -196,7 +196,7 @@ module FDCE (output Q, input C, CE, D, CLR); .IS_D_INVERTED(IS_D_INVERTED), .IS_CLR_INVERTED(IS_CLR_INVERTED) ) _TECHMAP_REPLACE_ ( - .D(D), .Q($nextQ), .C(C), .CE(CE), .CLR(CLR) + .D(D), .Q($Q), .C(C), .CE(CE), .CLR(CLR) // ^^^ Note that async // control is not directly // supported by abc9 but its @@ -204,9 +204,9 @@ module FDCE (output Q, input C, CE, D, CLR); // $__ABC9_ASYNC0 below ); // Since this is an async flop, async behaviour is dealt with here - \$__ABC9_ASYNC1 abc_async (.A($abc9_currQ), .S(CLR ^ IS_CLR_INVERTED), .Y(QQ)); + $__ABC9_ASYNC1 abc_async (.A($abc9_currQ), .S(CLR ^ IS_CLR_INVERTED), .Y(QQ)); end endgenerate - \$__ABC9_FF_ abc_dff (.D($nextQ), .Q($abc9_currQ)); + $__ABC9_FF_ abc_dff (.D($Q), .Q($abc9_currQ)); // Special signals wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, IS_C_INVERTED}; @@ -227,36 +227,36 @@ endmodule module FDCE_1 (output Q, input C, CE, D, CLR); parameter [0:0] INIT = 1'b0; `ifdef DFF_MODE - wire QQ, $nextQ, $abc9_currQ; + wire QQ, $Q, $abc9_currQ; generate if (INIT == 1'b1) begin assign Q = ~QQ; FDPE_1 #( .INIT(1'b0) ) _TECHMAP_REPLACE_ ( - .D(~D), .Q($nextQ), .C(C), .CE(CE), .PRE(CLR) + .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($abc9_currQ), .S(CLR), .Y(QQ)); + $__ABC9_ASYNC1 abc_async (.A($abc9_currQ), .S(CLR), .Y(QQ)); end else begin assign Q = QQ; FDCE_1 #( .INIT(1'b0) ) _TECHMAP_REPLACE_ ( - .D(D), .Q($nextQ), .C(C), .CE(CE), .CLR(CLR) + .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($abc9_currQ), .S(CLR), .Y(QQ)); + $__ABC9_ASYNC0 abc_async (.A($abc9_currQ), .S(CLR), .Y(QQ)); end endgenerate - \$__ABC9_FF_ abc_dff (.D($nextQ), .Q($abc9_currQ)); + $__ABC9_FF_ abc_dff (.D($Q), .Q($abc9_currQ)); // Special signals wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */}; @@ -278,7 +278,7 @@ module FDPE (output Q, input C, CE, D, PRE); parameter [0:0] IS_D_INVERTED = 1'b0; parameter [0:0] IS_PRE_INVERTED = 1'b0; `ifdef DFF_MODE - wire QQ, $nextQ, $abc9_currQ; + wire QQ, $Q, $abc9_currQ; generate if (INIT == 1'b1) begin assign Q = ~QQ; FDCE #( @@ -287,14 +287,14 @@ module FDPE (output Q, input C, CE, D, PRE); .IS_D_INVERTED(IS_D_INVERTED), .IS_CLR_INVERTED(IS_PRE_INVERTED), ) _TECHMAP_REPLACE_ ( - .D(~D), .Q($nextQ), .C(C), .CE(CE), .CLR(PRE) + .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($abc9_currQ), .S(PRE ^ IS_PRE_INVERTED), .Y(QQ)); + $__ABC9_ASYNC0 abc_async (.A($abc9_currQ), .S(PRE ^ IS_PRE_INVERTED), .Y(QQ)); end else begin assign Q = QQ; @@ -304,16 +304,16 @@ module FDPE (output Q, input C, CE, D, PRE); .IS_D_INVERTED(IS_D_INVERTED), .IS_PRE_INVERTED(IS_PRE_INVERTED), ) _TECHMAP_REPLACE_ ( - .D(D), .Q($nextQ), .C(C), .CE(CE), .PRE(PRE) + .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($abc9_currQ), .S(PRE ^ IS_PRE_INVERTED), .Y(QQ)); + $__ABC9_ASYNC1 abc_async (.A($abc9_currQ), .S(PRE ^ IS_PRE_INVERTED), .Y(QQ)); end endgenerate - \$__ABC9_FF_ abc_dff (.D($nextQ), .Q($abc9_currQ)); + $__ABC9_FF_ abc_dff (.D($Q), .Q($abc9_currQ)); // Special signals wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, IS_C_INVERTED}; @@ -334,36 +334,36 @@ endmodule module FDPE_1 (output Q, input C, CE, D, PRE); parameter [0:0] INIT = 1'b1; `ifdef DFF_MODE - wire QQ, $nextQ, $abc9_currQ; + wire QQ, $Q, $abc9_currQ; generate if (INIT == 1'b1) begin assign Q = ~QQ; FDCE_1 #( .INIT(1'b0) ) _TECHMAP_REPLACE_ ( - .D(~D), .Q($nextQ), .C(C), .CE(CE), .CLR(PRE) + .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($abc9_currQ), .S(PRE), .Y(QQ)); + $__ABC9_ASYNC0 abc_async (.A($abc9_currQ), .S(PRE), .Y(QQ)); end else begin assign Q = QQ; FDPE_1 #( .INIT(1'b0) ) _TECHMAP_REPLACE_ ( - .D(D), .Q($nextQ), .C(C), .CE(CE), .PRE(PRE) + .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($abc9_currQ), .S(PRE), .Y(QQ)); + $__ABC9_ASYNC1 abc_async (.A($abc9_currQ), .S(PRE), .Y(QQ)); end endgenerate - \$__ABC9_FF_ abc_dff (.D($nextQ), .Q($abc9_currQ)); + $__ABC9_FF_ abc_dff (.D($Q), .Q($abc9_currQ)); // Special signals wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */}; @@ -385,7 +385,7 @@ module FDSE (output Q, input C, CE, D, S); parameter [0:0] IS_D_INVERTED = 1'b0; parameter [0:0] IS_S_INVERTED = 1'b0; `ifdef DFF_MODE - wire QQ, $nextQ; + wire QQ, $Q; generate if (INIT == 1'b1) begin assign Q = ~QQ; FDRE #( @@ -394,7 +394,7 @@ module FDSE (output Q, input C, CE, D, S); .IS_D_INVERTED(IS_D_INVERTED), .IS_R_INVERTED(IS_S_INVERTED) ) _TECHMAP_REPLACE_ ( - .D(~D), .Q($nextQ), .C(C), .CE(CE), .R(S) + .D(~D), .Q($Q), .C(C), .CE(CE), .R(S) ); end else begin @@ -405,10 +405,10 @@ module FDSE (output Q, input C, CE, D, S); .IS_D_INVERTED(IS_D_INVERTED), .IS_S_INVERTED(IS_S_INVERTED) ) _TECHMAP_REPLACE_ ( - .D(D), .Q($nextQ), .C(C), .CE(CE), .S(S) + .D(D), .Q($Q), .C(C), .CE(CE), .S(S) ); end endgenerate - \$__ABC9_FF_ abc_dff (.D($nextQ), .Q(QQ)); + $__ABC9_FF_ abc_dff (.D($Q), .Q(QQ)); // Special signals wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, IS_C_INVERTED}; @@ -429,13 +429,13 @@ endmodule module FDSE_1 (output Q, input C, CE, D, S); parameter [0:0] INIT = 1'b1; `ifdef DFF_MODE - wire QQ, $nextQ; + wire QQ, $Q; generate if (INIT == 1'b1) begin assign Q = ~QQ; FDRE_1 #( .INIT(1'b0) ) _TECHMAP_REPLACE_ ( - .D(~D), .Q($nextQ), .C(C), .CE(CE), .R(S) + .D(~D), .Q($Q), .C(C), .CE(CE), .R(S) ); end else begin @@ -443,10 +443,10 @@ module FDSE_1 (output Q, input C, CE, D, S); FDSE_1 #( .INIT(1'b0) ) _TECHMAP_REPLACE_ ( - .D(D), .Q($nextQ), .C(C), .CE(CE), .S(S) + .D(D), .Q($Q), .C(C), .CE(CE), .S(S) ); end endgenerate - \$__ABC9_FF_ abc_dff (.D($nextQ), .Q(QQ)); + $__ABC9_FF_ abc_dff (.D($Q), .Q(QQ)); // Special signals wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */}; @@ -472,17 +472,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 ( @@ -495,17 +495,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 ( @@ -517,17 +517,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 ( @@ -551,24 +551,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 ( @@ -592,20 +592,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 ( @@ -614,14 +614,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 ( @@ -632,14 +632,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 ( @@ -828,15 +828,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) @@ -847,27 +847,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 @@ -875,26 +875,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; @@ -902,21 +902,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 @@ -924,15 +924,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; @@ -943,7 +943,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; @@ -951,14 +951,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"); -- cgit v1.2.3 From ece423415cbc17654c6ac81a0f4b15783c558660 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 30 Dec 2019 14:24:58 -0800 Subject: Add CHANGELOG entry, add abc9_{flop,keep} attr to README.md --- CHANGELOG | 1 + README.md | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 01ae17c2b..fc0cdc92e 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -57,6 +57,7 @@ Yosys 0.9 .. Yosys 0.9-dev always_latch and always_ff) - Added "xilinx_dffopt" pass - Added "scratchpad" pass + - Added "synth_xilinx -dff" Yosys 0.8 .. Yosys 0.9 ---------------------- diff --git a/README.md b/README.md index 0250c7846..c04e2b9ec 100644 --- a/README.md +++ b/README.md @@ -378,6 +378,12 @@ 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 cell attribute ``abc9_keep`` is a boolean indicating that this black/ + white box should be preserved through `abc9` mapping. + - 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 -- cgit v1.2.3 From 3cbbae251fc4a4b10abe21fde9c7316bb940a957 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 30 Dec 2019 14:33:05 -0800 Subject: Call "proc" if processes inside whiteboxes --- backends/aiger/xaiger.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index bfdae7160..8e8f29457 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -706,7 +706,7 @@ struct XAigerWriter IdString derived_name = orig_box_module->derive(module->design, cell->parameters); RTLIL::Module* box_module = module->design->module(derived_name); if (box_module->has_processes()) - log_error("ABC9 box '%s' contains processes!\n", box_module->name.c_str()); + Pass::call_on_module(module->design, box_module, "proc"); int box_inputs = 0, box_outputs = 0; auto r = cell_cache.insert(std::make_pair(derived_name, nullptr)); -- cgit v1.2.3 From eb4e767053f4731c9f4b82c4dd53504e5fe50802 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 27 Dec 2019 12:03:19 -0800 Subject: Do not offset FD* box timings due to -46ps Tsu --- techlibs/xilinx/abc9_xc7.box | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/techlibs/xilinx/abc9_xc7.box b/techlibs/xilinx/abc9_xc7.box index a2d119284..16606d14e 100644 --- a/techlibs/xilinx/abc9_xc7.box +++ b/techlibs/xilinx/abc9_xc7.box @@ -53,50 +53,59 @@ $__ABC9_ASYNC0 1000 1 2 1 $__ABC9_ASYNC1 1001 1 2 1 0 764 -# The following FD*.{CE,R,CLR,PRE) are offset by 46ps to -# reflect the -46ps Tsu -# https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L237-L251 -# https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L265-L277 +# 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 + +# NB: Inputs/Outputs must be ordered alphabetically +# (with exception for \$currQ) # Inputs: C CE D R \$currQ # Outputs: Q FDRE 1100 1 5 1 -0 151 0 446 0 +#0 109 -46 404 0 +0 109 0 404 0 # Clamp -46ps Tsu # Inputs: C CE D R \$currQ # Outputs: Q FDRE_1 1101 1 5 1 -0 151 0 446 0 +#0 109 0 -46 404 +0 109 0 0 404 # Clamp -46ps Tsu # Inputs: C CE CLR D \$currQ # Outputs: Q FDCE 1102 1 5 1 -0 151 806 0 0 +#0 109 764 -46 0 +0 109 764 0 0 # Clamp -46ps Tsu # Inputs: C CE CLR D \$currQ # Outputs: Q FDCE_1 1103 1 5 1 -0 151 806 0 0 +#0 109 764 -46 0 +0 109 764 0 0 # Clamp -46ps Tsu # Inputs: C CE D PRE \$currQ # Outputs: Q FDPE 1104 1 5 1 -0 151 0 806 0 +#0 109 -46 764 0 +0 109 0 764 0 # Clamp -46ps Tsu # Inputs: C CE D PRE \$currQ # Outputs: Q FDPE_1 1105 1 5 1 -0 151 0 806 0 +#0 109 -46 764 0 +0 109 0 764 0 # Clamp -46ps Tsu # Inputs: C CE D S \$currQ # Outputs: Q FDSE 1106 1 5 1 -0 151 0 446 0 +#0 109 -46 446 0 +0 109 0 446 0 # Clamp -46ps Tsu # Inputs: C CE D S \$currQ # Outputs: Q FDSE_1 1107 1 5 1 -0 151 0 446 0 +#0 109 -46 446 0 +0 109 0 446 0 # Clamp -46ps Tsu # SLICEM/A6LUT # Box to emulate comb/seq behaviour of RAMD{32,64} and SRL{16,32} -- cgit v1.2.3 From d1fccd5a2d63b265c1866cb4d54aba8f2c9d225c Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 30 Dec 2019 14:35:52 -0800 Subject: Remove unused --- backends/aiger/xaiger.cc | 5 ----- 1 file changed, 5 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 8e8f29457..ce7b479ff 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -927,7 +927,6 @@ struct XAigerWriter void write_map(std::ostream &f, bool verbose_map) { dict input_lines; - dict init_lines; dict output_lines; dict wire_lines; @@ -969,10 +968,6 @@ struct XAigerWriter f << it.second; log_assert(input_lines.size() == input_bits.size()); - init_lines.sort(); - for (auto &it : init_lines) - f << it.second; - int box_count = 0; for (auto cell : box_list) f << stringf("box %d %d %s\n", box_count++, 0, log_id(cell->name)); -- cgit v1.2.3 From 543bd2de6c00f98577263439ebdada7bcda249ab Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 27 Dec 2019 12:15:33 -0800 Subject: Update timings for Xilinx S7 cells --- techlibs/xilinx/cells_sim.v | 50 +++++++++++++++++++++++++++++++-------------- 1 file changed, 35 insertions(+), 15 deletions(-) diff --git a/techlibs/xilinx/cells_sim.v b/techlibs/xilinx/cells_sim.v index 3bcbfc9aa..72e684af5 100644 --- a/techlibs/xilinx/cells_sim.v +++ b/techlibs/xilinx/cells_sim.v @@ -1112,8 +1112,8 @@ module RAM16X1D_1 ( endmodule module RAM32X1D ( - // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L957 - (* abc9_arrival=1153 *) + // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L857 + (* abc9_arrival=1188 *) output DPO, SPO, input D, (* clkbuf_sink *) @@ -1135,8 +1135,8 @@ module RAM32X1D ( endmodule module RAM32X1D_1 ( - // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L957 - (* abc9_arrival=1153 *) + // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L857 + (* abc9_arrival=1188 *) output DPO, SPO, input D, (* clkbuf_sink *) @@ -1158,7 +1158,7 @@ module RAM32X1D_1 ( endmodule module RAM64X1D ( - // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L957 + // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L889 (* abc9_arrival=1153 *) output DPO, SPO, input D, @@ -1181,7 +1181,7 @@ module RAM64X1D ( endmodule module RAM64X1D_1 ( - // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L957 + // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L889 (* abc9_arrival=1153 *) output DPO, SPO, input D, @@ -1204,8 +1204,9 @@ module RAM64X1D_1 ( endmodule module RAM128X1D ( - // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L957 - (* abc9_arrival=1153 *) + // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L889 + // plus 204ps to cross MUXF7 + (* abc9_arrival=1357 *) output DPO, SPO, input D, (* clkbuf_sink *) @@ -1244,9 +1245,18 @@ endmodule // Multi port. module RAM32M ( - // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L957 - (* abc9_arrival=1153 *) - output [1:0] DOA, DOB, DOC, DOD, + // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L857 + (* abc9_arrival=1188 *) + output [1:0] DOA, + // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L925 + (* abc9_arrival=1187 *) + output [1:0] DOB, + // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L993 + (* abc9_arrival=1180 *) + output [1:0] DOC, + // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L1061 + (* abc9_arrival=1190 *) + output [1:0] DOD, input [4:0] ADDRA, ADDRB, ADDRC, ADDRD, input [1:0] DIA, DIB, DIC, DID, (* clkbuf_sink *) @@ -1347,9 +1357,18 @@ module RAM32M16 ( endmodule module RAM64M ( - // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L957 + // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L889 (* abc9_arrival=1153 *) - output DOA, DOB, DOC, DOD, + output DOA, + // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L957 + (* abc9_arrival=1161 *) + output DOB, + // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L1025 + (* abc9_arrival=1158 *) + output DOC, + // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L1093 + (* abc9_arrival=1163 *) + output DOD, input [5:0] ADDRA, ADDRB, ADDRC, ADDRD, input DIA, DIB, DIC, DID, (* clkbuf_sink *) @@ -1508,7 +1527,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, @@ -1572,9 +1591,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, -- cgit v1.2.3 From fc4b8b89912c14f42b04a7c9f2ce350db3ce7c0b Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 30 Dec 2019 14:56:14 -0800 Subject: Remove submod changes --- passes/hierarchy/submod.cc | 136 ++++++++++++--------------------------------- tests/various/submod.ys | 102 ---------------------------------- 2 files changed, 37 insertions(+), 201 deletions(-) delete mode 100644 tests/various/submod.ys diff --git a/passes/hierarchy/submod.cc b/passes/hierarchy/submod.cc index 3b4f33a60..ec242aa1f 100644 --- a/passes/hierarchy/submod.cc +++ b/passes/hierarchy/submod.cc @@ -20,7 +20,6 @@ #include "kernel/register.h" #include "kernel/celltypes.h" #include "kernel/log.h" -#include "kernel/sigtools.h" #include #include #include @@ -33,56 +32,49 @@ struct SubmodWorker CellTypes ct; RTLIL::Design *design; RTLIL::Module *module; - SigMap sigmap; bool copy_mode; - bool hidden_mode; std::string opt_name; struct SubModule { std::string name, full_name; - pool cells; + std::set cells; }; std::map submodules; struct wire_flags_t { RTLIL::Wire *new_wire; - RTLIL::Const is_int_driven; - bool is_int_used, is_ext_driven, is_ext_used; - wire_flags_t(RTLIL::Wire* wire) : new_wire(NULL), is_int_driven(State::S0, GetSize(wire)), is_int_used(false), is_ext_driven(false), is_ext_used(false) { } + bool is_int_driven, is_int_used, is_ext_driven, is_ext_used; + wire_flags_t() : new_wire(NULL), is_int_driven(false), is_int_used(false), is_ext_driven(false), is_ext_used(false) { } }; std::map wire_flags; bool flag_found_something; - void flag_wire(RTLIL::Wire *wire, bool create, bool set_int_used, bool set_ext_driven, bool set_ext_used) + void flag_wire(RTLIL::Wire *wire, bool create, bool set_int_driven, bool set_int_used, bool set_ext_driven, bool set_ext_used) { if (wire_flags.count(wire) == 0) { if (!create) return; - wire_flags.emplace(wire, wire); + wire_flags[wire] = wire_flags_t(); } + if (set_int_driven) + wire_flags[wire].is_int_driven = true; if (set_int_used) - wire_flags.at(wire).is_int_used = true; + wire_flags[wire].is_int_used = true; if (set_ext_driven) - wire_flags.at(wire).is_ext_driven = true; + wire_flags[wire].is_ext_driven = true; if (set_ext_used) - wire_flags.at(wire).is_ext_used = true; + wire_flags[wire].is_ext_used = true; flag_found_something = true; } void flag_signal(const RTLIL::SigSpec &sig, bool create, bool set_int_driven, bool set_int_used, bool set_ext_driven, bool set_ext_used) { for (auto &c : sig.chunks()) - if (c.wire != NULL) { - flag_wire(c.wire, create, set_int_used, set_ext_driven, set_ext_used); - if (set_int_driven) - for (int i = c.offset; i < c.offset+c.width; i++) { - wire_flags.at(c.wire).is_int_driven[i] = State::S1; - flag_found_something = true; - } - } + if (c.wire != NULL) + flag_wire(c.wire, create, set_int_driven, set_int_used, set_ext_driven, set_ext_used); } void handle_submodule(SubModule &submod) @@ -135,39 +127,27 @@ struct SubmodWorker flags.is_ext_driven = true; if (wire->port_output) flags.is_ext_used = true; - else { - auto sig = sigmap(wire); - for (auto c : sig.chunks()) - if (c.wire && c.wire->port_output) { - flags.is_ext_used = true; - break; - } - } bool new_wire_port_input = false; bool new_wire_port_output = false; - if (!flags.is_int_driven.is_fully_zero() && flags.is_ext_used) + if (flags.is_int_driven && flags.is_ext_used) new_wire_port_output = true; if (flags.is_ext_driven && flags.is_int_used) new_wire_port_input = true; - if (!flags.is_int_driven.is_fully_zero() && flags.is_ext_driven) + if (flags.is_int_driven && flags.is_ext_driven) new_wire_port_input = true, new_wire_port_output = true; std::string new_wire_name = wire->name.str(); if (new_wire_port_input || new_wire_port_output) { - if (new_wire_name[0] == '$') - while (1) { - std::string next_wire_name = stringf("%s\\n%d", hidden_mode ? "$submod" : "", auto_name_counter++); - if (all_wire_names.count(next_wire_name) == 0) { - all_wire_names.insert(next_wire_name); - new_wire_name = next_wire_name; - break; - } + while (new_wire_name[0] == '$') { + std::string next_wire_name = stringf("\\n%d", auto_name_counter++); + if (all_wire_names.count(next_wire_name) == 0) { + all_wire_names.insert(next_wire_name); + new_wire_name = next_wire_name; } - else if (hidden_mode) - new_wire_name = stringf("$submod%s", new_wire_name.c_str()); + } } RTLIL::Wire *new_wire = new_mod->addWire(new_wire_name, wire->width); @@ -175,22 +155,6 @@ struct SubmodWorker new_wire->port_output = new_wire_port_output; new_wire->start_offset = wire->start_offset; new_wire->attributes = wire->attributes; - if (!flags.is_int_driven.is_fully_zero()) { - new_wire->attributes.erase(ID(init)); - auto sig = sigmap(wire); - for (int i = 0; i < GetSize(sig); i++) { - if (flags.is_int_driven[i] == State::S0) - continue; - if (!sig[i].wire) - continue; - auto it = sig[i].wire->attributes.find(ID(init)); - if (it != sig[i].wire->attributes.end()) { - auto jt = new_wire->attributes.insert(std::make_pair(ID(init), Const(State::Sx, GetSize(sig)))).first; - jt->second[i] = it->second[sig[i].offset]; - it->second[sig[i].offset] = State::Sx; - } - } - } if (new_wire->port_input && new_wire->port_output) log(" signal %s: inout %s\n", wire->name.c_str(), new_wire->name.c_str()); @@ -213,7 +177,7 @@ struct SubmodWorker for (auto &bit : conn.second) if (bit.wire != NULL) { log_assert(wire_flags.count(bit.wire) > 0); - bit.wire = wire_flags.at(bit.wire).new_wire; + bit.wire = wire_flags[bit.wire].new_wire; } log(" cell %s (%s)\n", new_cell->name.c_str(), new_cell->type.c_str()); if (!copy_mode) @@ -225,27 +189,16 @@ struct SubmodWorker RTLIL::Cell *new_cell = module->addCell(submod.full_name, submod.full_name); for (auto &it : wire_flags) { - RTLIL::SigSpec old_sig = sigmap(it.first); + RTLIL::Wire *old_wire = it.first; RTLIL::Wire *new_wire = it.second.new_wire; - if (new_wire->port_id > 0) { - if (new_wire->port_output) - for (int i = 0; i < GetSize(old_sig); i++) { - auto &b = old_sig[i]; - // Prevents "ERROR: Mismatch in directionality ..." when flattening - if (!b.wire) - b = module->addWire(NEW_ID); - // Prevents "Warning: multiple conflicting drivers ..." - else if (!it.second.is_int_driven[i]) - b = module->addWire(NEW_ID); - } - new_cell->setPort(new_wire->name, old_sig); - } + if (new_wire->port_id > 0) + new_cell->setPort(new_wire->name, RTLIL::SigSpec(old_wire)); } } } - SubmodWorker(RTLIL::Design *design, RTLIL::Module *module, bool copy_mode = false, bool hidden_mode = false, std::string opt_name = std::string()) : - design(design), module(module), sigmap(module), copy_mode(copy_mode), hidden_mode(hidden_mode), opt_name(opt_name) + SubmodWorker(RTLIL::Design *design, RTLIL::Module *module, bool copy_mode = false, std::string opt_name = std::string()) : + design(design), module(module), copy_mode(copy_mode), opt_name(opt_name) { if (!design->selected_whole_module(module->name) && opt_name.empty()) return; @@ -266,12 +219,6 @@ struct SubmodWorker ct.setup_stdcells_mem(); ct.setup_design(design); - for (auto port : module->ports) { - auto wire = module->wire(port); - if (wire->port_output) - sigmap.add(wire); - } - if (opt_name.empty()) { for (auto &it : module->wires_) @@ -326,7 +273,7 @@ struct SubmodPass : public Pass { { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); - log(" submod [options] [selection]\n"); + log(" submod [-copy] [selection]\n"); log("\n"); log("This pass identifies all cells with the 'submod' attribute and moves them to\n"); log("a newly created module. The value of the attribute is used as name for the\n"); @@ -338,20 +285,16 @@ struct SubmodPass : public Pass { log("This pass only operates on completely selected modules with no processes\n"); log("or memories.\n"); log("\n"); - log(" -copy\n"); - log(" by default the cells are 'moved' from the source module and the source\n"); - log(" module will use an instance of the new module after this command is\n"); - log(" finished. call with -copy to not modify the source module.\n"); log("\n"); - log(" -name \n"); - log(" don't use the 'submod' attribute but instead use the selection. only\n"); - log(" objects from one module might be selected. the value of the -name option\n"); - log(" is used as the value of the 'submod' attribute instead.\n"); + log(" submod -name [-copy] [selection]\n"); + log("\n"); + log("As above, but don't use the 'submod' attribute but instead use the selection.\n"); + log("Only objects from one module might be selected. The value of the -name option\n"); + log("is used as the value of the 'submod' attribute above.\n"); log("\n"); - log(" -hidden\n"); - log(" instead of creating submodule ports with public names, create ports with\n"); - log(" private names so that a subsequent 'flatten; clean' call will restore the\n"); - log(" original module with original public names.\n"); + log("By default the cells are 'moved' from the source module and the source module\n"); + log("will use an instance of the new module after this command is finished. Call\n"); + log("with -copy to not modify the source module.\n"); log("\n"); } void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE @@ -361,7 +304,6 @@ struct SubmodPass : public Pass { std::string opt_name; bool copy_mode = false; - bool hidden_mode = false; size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) { @@ -373,10 +315,6 @@ struct SubmodPass : public Pass { copy_mode = true; continue; } - if (args[argidx] == "-hidden") { - hidden_mode = true; - continue; - } break; } extra_args(args, argidx, design); @@ -397,7 +335,7 @@ struct SubmodPass : public Pass { queued_modules.push_back(mod_it.first); for (auto &modname : queued_modules) if (design->modules_.count(modname) != 0) { - SubmodWorker worker(design, design->modules_[modname], copy_mode, hidden_mode); + SubmodWorker worker(design, design->modules_[modname], copy_mode); handled_modules.insert(modname); did_something = true; } @@ -420,7 +358,7 @@ struct SubmodPass : public Pass { else { Pass::call_on_module(design, module, "opt_clean"); log_header(design, "Continuing SUBMOD pass.\n"); - SubmodWorker worker(design, module, copy_mode, hidden_mode, opt_name); + SubmodWorker worker(design, module, copy_mode, opt_name); } } diff --git a/tests/various/submod.ys b/tests/various/submod.ys deleted file mode 100644 index 9d7dabdd7..000000000 --- a/tests/various/submod.ys +++ /dev/null @@ -1,102 +0,0 @@ -read_verilog < Date: Mon, 30 Dec 2019 12:26:39 -0800 Subject: Grammar --- passes/techmap/abc.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/techmap/abc.cc b/passes/techmap/abc.cc index b29480e26..279b32223 100644 --- a/passes/techmap/abc.cc +++ b/passes/techmap/abc.cc @@ -1767,7 +1767,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"); -- cgit v1.2.3 From 07355729341e5104cf83210af280cb0cc6e8c7de Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 30 Dec 2019 15:35:33 -0800 Subject: write_xaiger to use scratchpad for stats; cleanup abc9 --- backends/aiger/xaiger.cc | 22 ++---- passes/techmap/abc9.cc | 188 ++++------------------------------------------- 2 files changed, 20 insertions(+), 190 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index ce7b479ff..e7d767721 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -93,7 +93,6 @@ struct XAigerWriter dict ordered_outputs; vector box_list; - bool omode = false; int mkgate(int a0, int a1) { @@ -579,11 +578,6 @@ struct XAigerWriter aig_outputs.push_back(bit2aig(bit)); } - if (output_bits.empty()) { - output_bits.insert(State::S0); - omode = true; - } - for (auto bit : output_bits) { ordered_outputs[bit] = aig_o++; aig_outputs.push_back(bit2aig(bit)); @@ -594,12 +588,6 @@ struct XAigerWriter aig_o++; aig_outputs.push_back(ff_aig_map.at(bit)); } - - if (output_bits.empty()) { - aig_o++; - aig_outputs.push_back(0); - omode = true; - } } void write_aiger(std::ostream &f, bool ascii_mode) @@ -661,7 +649,6 @@ struct XAigerWriter f << "c"; - log_assert(!output_bits.empty()); auto write_buffer = [](std::stringstream &buffer, int i32) { int32_t i32_be = to_big_endian(i32); buffer.write(reinterpret_cast(&i32_be), sizeof(i32_be)); @@ -922,6 +909,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) @@ -973,13 +965,9 @@ struct XAigerWriter f << stringf("box %d %d %s\n", box_count++, 0, log_id(cell->name)); output_lines.sort(); - if (omode) - output_lines[State::S0] = "output 0 0 $__dummy__\n"; for (auto &it : output_lines) f << it.second; log_assert(output_lines.size() == output_bits.size()); - if (omode && output_bits.empty()) - f << "output " << output_lines.size() << " 0 $__dummy__\n"; wire_lines.sort(); for (auto &it : wire_lines) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 19a1d2ccb..a0403535b 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -268,13 +268,13 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip 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()); + 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 -v %s; ", box_file.c_str()); + abc9_script += stringf("read_box %s; ", box_file.c_str()); } else log_abort(); @@ -321,20 +321,22 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip fprintf(f, "%s\n", abc9_script.c_str()); fclose(f); - //bool count_output = false; log_push(); - //if (count_output) - { - handle_loops(design, module); + handle_loops(design, module); - Pass::call(design, "aigmap -select"); + Pass::call(design, "aigmap -select"); - //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())); - Pass::call(design, stringf("write_xaiger -map %s/input.sym %s/input.xaig", tempdir_name.c_str(), tempdir_name.c_str())); + 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 @@ -1053,35 +1055,6 @@ struct Abc9Pass : public Pass { dict clk_to_mergeability; const std::vector all_cells = module->selected_cells(); -#if 0 - pool unassigned_cells(all_cells.begin(), all_cells.end()); - - pool expand_queue, next_expand_queue; - pool expand_queue_up, next_expand_queue_up; - pool expand_queue_down, next_expand_queue_down; - - std::map> assigned_cells; - std::map assigned_cells_reverse; - - std::map> cell_to_bit, cell_to_bit_up, cell_to_bit_down; - std::map> bit_to_cell, bit_to_cell_up, bit_to_cell_down; - - for (auto cell : all_cells) - for (auto &conn : cell->connections()) - for (auto bit : assign_map(conn.second)) - 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); - } - } -#endif for (auto cell : all_cells) { auto inst_module = design->module(cell->type); @@ -1095,12 +1068,6 @@ struct Abc9Pass : public Pass { SigSpec abc9_clock = assign_map(abc9_clock_wire); clkdomain_t key(abc9_clock); -#if 0 - unassigned_cells.erase(cell); - expand_queue_up.insert(cell); - assigned_cells[key].insert(cell->name); - assigned_cells_reverse[cell] = key; -#endif 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)); @@ -1115,137 +1082,12 @@ struct Abc9Pass : public Pass { log_error("'%s.$abc9_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); - -#if 0 - // Also assign these special ABC9 cells to the - // same clock domain - for (auto b : cell_to_bit_down[cell]) - for (auto c : bit_to_cell_down[b]) - if (c->type == "$__ABC9_FF_") { - cell = c; - unassigned_cells.erase(cell); - assigned_cells[key].insert(cell->name); - assigned_cells_reverse[cell] = key; - break; - } - for (auto b : cell_to_bit_down[cell]) - for (auto c : bit_to_cell_down[b]) - if (c->type == "$__ABC9_ASYNC") { - cell = c; - unassigned_cells.erase(cell); - assigned_cells[key].insert(cell->name); - assigned_cells_reverse[cell] = key; - break; - } - - expand_queue.insert(cell); - expand_queue_down.insert(cell); -#endif } -#if 0 - while (!expand_queue_up.empty() || !expand_queue_down.empty()) - { - if (!expand_queue_up.empty()) - { - RTLIL::Cell *cell = *expand_queue_up.begin(); - auto 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].insert(c->name); - assigned_cells_reverse[c] = key; - expand_queue.insert(c); - } - } - - if (!expand_queue_down.empty()) - { - RTLIL::Cell *cell = *expand_queue_down.begin(); - auto 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].insert(c->name); - 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(); - auto 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].insert(c->name); - assigned_cells_reverse[c] = key; - } - bit_to_cell[bit].clear(); - } - - if (expand_queue.empty()) - expand_queue.swap(next_expand_queue); - } - - clkdomain_t key; - for (auto cell : unassigned_cells) { - assigned_cells[key].insert(cell->name); - 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\n", GetSize(it.second), log_signal(it.first)); - } -#endif - design->selected_active_module = module->name.str(); -#if 0 - design->selection_stack.emplace_back(false); - for (auto &it : assigned_cells) { - std::string target = delay_target; - if (target.empty()) { - for (auto b : assign_map(it.first)) - if (b.wire) { - auto jt = b.wire->attributes.find("\\abc9_period"); - if (jt != b.wire->attributes.end()) { - target = stringf("-D %d", jt->second.as_int()); - log("Target period = %s ps for clock domain %s\n", target.c_str(), log_signal(it.first)); - break; - } - } - } - RTLIL::Selection& sel = design->selection_stack.back(); - sel.selected_members[module->name] = std::move(it.second); -#endif - abc9_module(design, module, script_file, exe_file, cleanup, lut_costs, - delay_target, lutin_shared, fast_mode, all_cells, show_tempdir, - box_file, lut_file, wire_delay, box_lookup, nomfs); -#if 0 - assign_map.set(module); - } - design->selection_stack.pop_back(); -#endif + abc9_module(design, module, script_file, exe_file, cleanup, lut_costs, + delay_target, lutin_shared, fast_mode, all_cells, show_tempdir, + box_file, lut_file, wire_delay, box_lookup, nomfs); design->selected_active_module.clear(); } -- cgit v1.2.3 From 4c3f517425d7aa7a4349696cd1c21d46aa9ad03f Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 30 Dec 2019 16:11:42 -0800 Subject: Remove delay targets doc --- passes/techmap/abc9.cc | 9 --------- 1 file changed, 9 deletions(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index a0403535b..b63a1aa6c 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -825,15 +825,6 @@ struct Abc9Pass : public Pass { log("design as an XAIGER file with write_xaiger and then load that into ABC externally\n"); log("if you want to use ABC to convert your design into another format.\n"); log("\n"); - // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| - log("Delay targets can also be specified on a per clock basis by attaching a\n"); - log("'(* abc9_period = *)' attribute onto clock wires (specifically, onto wires\n"); - log("that appear inside any special '$abc9_clock' wires inserted by abc9_map.v). This\n"); - log("can be achieved by modifying the source directly, or through a `setattr`\n"); - log("invocation. Since such attributes cannot yet be propagated through a\n"); - log("hierarchical design (whether or not it has been uniquified) it is recommended\n"); - log("that the design be flattened when using this feature.\n"); - log("\n"); log("[1] http://www.eecs.berkeley.edu/~alanmi/abc/\n"); log("\n"); } -- cgit v1.2.3 From dbffbeef5c2df2345c786e195d2006d7bb23578a Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 30 Dec 2019 16:21:20 -0800 Subject: Fix struct name --- passes/techmap/abc9_map.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/passes/techmap/abc9_map.cc b/passes/techmap/abc9_map.cc index 6c431b185..7d53db5ea 100644 --- a/passes/techmap/abc9_map.cc +++ b/passes/techmap/abc9_map.cc @@ -650,8 +650,8 @@ clone_lut: log_pop(); } -struct Abc9TechmapPass : public Pass { - Abc9TechmapPass() : Pass("abc9_map", "use ABC9 for technology mapping") { } +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---| @@ -1017,6 +1017,6 @@ struct Abc9TechmapPass : public Pass { log_pop(); } -} Abc9TechmapPass; +} Abc9MapPass; PRIVATE_NAMESPACE_END -- cgit v1.2.3 From 88b9c8d46ddac513831dc79d370f8abb23ab68fc Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 30 Dec 2019 16:29:08 -0800 Subject: Restore count_outputs, move process check to abc --- passes/techmap/abc9.cc | 10 +++++++++- passes/techmap/abc9_map.cc | 14 ++++---------- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index d507a6973..ac64ae86d 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -164,7 +164,7 @@ struct Abc9Pass : public ScriptPass map_cmd << " " << arg << " " << args[++argidx]; continue; } - if (arg == "-fast" || /*arg == "-dff" ||*/ arg == "-keepff" + if (arg == "-fast" /*|| arg == "-nocleanup"*/ || arg == "-showtmp" || arg == "-markgroups" || arg == "-nomfs") { map_cmd << " " << arg; @@ -189,6 +189,14 @@ struct Abc9Pass : public ScriptPass active_design->selection_stack.emplace_back(false); for (auto mod : selected_modules) { + if (module->attributes.count(ID(abc9_box_id))) + continue; + + if (module->processes.size() > 0) { + log("Skipping module %s as it contains processes.\n", log_id(module)); + continue; + } + log_push(); active_design->selection().select(mod); diff --git a/passes/techmap/abc9_map.cc b/passes/techmap/abc9_map.cc index 7d53db5ea..83f90a762 100644 --- a/passes/techmap/abc9_map.cc +++ b/passes/techmap/abc9_map.cc @@ -268,15 +268,14 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip log_push(); - // FIXME: - /*int count_outputs = design->scratchpad_get_int("write_xaiger.num_outputs"); + 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)*/ { + if (count_outputs > 0) { std::string buffer; std::ifstream ifs; #if 0 @@ -965,13 +964,8 @@ struct Abc9MapPass : public Pass { CellTypes ct(design); for (auto module : design->selected_modules()) { - if (module->attributes.count(ID(abc9_box_id))) - continue; - - if (module->processes.size() > 0) { - log("Skipping module %s as it contains processes.\n", log_id(module)); - continue; - } + if (module->processes.size() > 0) + log_error("Module '%s' has processes!\n", log_id(module)); assign_map.set(module); -- cgit v1.2.3 From 16c4ec7edaa3cb66ced2f856d3c48f30d7d2acf1 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 30 Dec 2019 16:36:33 -0800 Subject: Add abc9_ops -prep_dff --- passes/techmap/abc9.cc | 8 ++++---- passes/techmap/abc9_map.cc | 35 ----------------------------------- passes/techmap/abc9_ops.cc | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 39 deletions(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index ac64ae86d..cd798cfbe 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -189,11 +189,11 @@ struct Abc9Pass : public ScriptPass active_design->selection_stack.emplace_back(false); for (auto mod : selected_modules) { - if (module->attributes.count(ID(abc9_box_id))) + if (mod->attributes.count(ID(abc9_box_id))) continue; - if (module->processes.size() > 0) { - log("Skipping module %s as it contains processes.\n", log_id(module)); + if (mod->processes.size() > 0) { + log("Skipping module %s as it contains processes.\n", log_id(mod)); continue; } @@ -207,7 +207,7 @@ struct Abc9Pass : public ScriptPass tempdir_name = make_temp_dir(tempdir_name); run("scc -set_attr abc9_scc_id {}"); - run("abc9_ops -break_scc"); + run("abc9_ops -break_scc -prep_dff"); run("aigmap"); run(stringf("write_xaiger -map %s/input.sym %s/input.xaig", tempdir_name.c_str(), tempdir_name.c_str()), "write_xaiger -map /input.sym /input.xaig"); diff --git a/passes/techmap/abc9_map.cc b/passes/techmap/abc9_map.cc index 83f90a762..6b9d0afff 100644 --- a/passes/techmap/abc9_map.cc +++ b/passes/techmap/abc9_map.cc @@ -960,48 +960,13 @@ struct Abc9MapPass : public Pass { } } - SigMap assign_map; - CellTypes ct(design); for (auto module : design->selected_modules()) { if (module->processes.size() > 0) log_error("Module '%s' has processes!\n", log_id(module)); - assign_map.set(module); - - typedef SigSpec clkdomain_t; - dict clk_to_mergeability; - const std::vector all_cells = module->selected_cells(); - for (auto cell : all_cells) { - auto inst_module = design->module(cell->type); - if (!inst_module || !inst_module->attributes.count("\\abc9_flop") - || cell->get_bool_attribute("\\abc9_keep")) - continue; - - Wire *abc9_clock_wire = module->wire(stringf("%s.$abc9_clock", cell->name.c_str())); - if (abc9_clock_wire == NULL) - log_error("'%s$abc9_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.$abc9_init", cell->name.c_str())); - if (abc9_init_wire == NULL) - log_error("'%s.$abc9_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.$abc9_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); - } - design->selected_active_module = module->name.str(); abc9_module(design, module, script_file, exe_file, lut_costs, delay_target, lutin_shared, fast_mode, all_cells, show_tempdir, diff --git a/passes/techmap/abc9_ops.cc b/passes/techmap/abc9_ops.cc index 4c30efd06..3e7e5ec7f 100644 --- a/passes/techmap/abc9_ops.cc +++ b/passes/techmap/abc9_ops.cc @@ -19,6 +19,7 @@ */ #include "kernel/register.h" +#include "kernel/sigtools.h" USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN @@ -95,6 +96,44 @@ void unbreak_scc(RTLIL::Module *module) { 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 clk_to_mergeability; + + for (auto cell : module->selected_cells()) { + auto inst_module = design->module(cell->type); + if (!inst_module || !inst_module->attributes.count("\\abc9_flop") + || cell->get_bool_attribute("\\abc9_keep")) + continue; + + Wire *abc9_clock_wire = module->wire(stringf("%s.$abc9_clock", cell->name.c_str())); + if (abc9_clock_wire == NULL) + log_error("'%s$abc9_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.$abc9_init", cell->name.c_str())); + if (abc9_init_wire == NULL) + log_error("'%s.$abc9_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.$abc9_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); + } +} + struct Abc9PrepPass : public Pass { Abc9PrepPass() : Pass("abc9_ops", "helper functions for ABC9") { } void help() YS_OVERRIDE @@ -111,6 +150,7 @@ struct Abc9PrepPass : public Pass { bool break_scc_mode = false; bool unbreak_scc_mode = false; + bool prep_dff_mode = false; size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) { @@ -123,6 +163,10 @@ struct Abc9PrepPass : public Pass { unbreak_scc_mode = true; continue; } + if (arg == "-prep_dff") { + prep_dff_mode = true; + continue; + } break; } extra_args(args, argidx, design); @@ -132,6 +176,8 @@ struct Abc9PrepPass : public Pass { break_scc(mod); if (unbreak_scc_mode) unbreak_scc(mod); + if (prep_dff_mode) + prep_dff(mod); } } } Abc9PrepPass; -- cgit v1.2.3 From 379dcda1398ea7a1325f82340148359ffe2bf548 Mon Sep 17 00:00:00 2001 From: Niklas Nisbeth Date: Tue, 31 Dec 2019 02:38:10 +0100 Subject: ice40: Demote conflicting FF init values to a warning --- techlibs/ice40/ice40_ffinit.cc | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/techlibs/ice40/ice40_ffinit.cc b/techlibs/ice40/ice40_ffinit.cc index 3089d8932..c098736e9 100644 --- a/techlibs/ice40/ice40_ffinit.cc +++ b/techlibs/ice40/ice40_ffinit.cc @@ -78,10 +78,12 @@ struct Ice40FfinitPass : public Pass { continue; if (initbits.count(bit)) { - if (initbits.at(bit) != val) - log_error("Conflicting init values for signal %s (%s = %s, %s = %s).\n", + if (initbits.at(bit) != val) { + log_warning("Conflicting init values for signal %s (%s = %s, %s = %s).\n", log_signal(bit), log_signal(SigBit(wire, i)), log_signal(val), log_signal(initbit_to_wire[bit]), log_signal(initbits.at(bit))); + initbits.at(bit) = State::Sx; + } continue; } @@ -114,6 +116,10 @@ struct Ice40FfinitPass : public Pass { continue; State val = initbits.at(bit_q); + + if (val == State::Sx) + continue; + handled_initbits.insert(bit_q); log("FF init value for cell %s (%s): %s = %c\n", log_id(cell), log_id(cell->type), -- cgit v1.2.3 From b50de28c045e786f3140c95ab23cb2f426918093 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 30 Dec 2019 18:00:49 -0800 Subject: Add abc9_ops -prep_holes --- backends/aiger/xaiger.cc | 140 ++------------------ passes/techmap/abc9.cc | 2 +- passes/techmap/abc9_ops.cc | 314 ++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 321 insertions(+), 135 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index e7d767721..73af3bdfb 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -680,12 +680,11 @@ struct XAigerWriter // write_o_buffer(0); if (!box_list.empty() || !ff_bits.empty()) { - RTLIL::Module *holes_module = module->design->addModule("$__holes__"); + RTLIL::Module *holes_module = module->design->module(stringf("%s$holes", module->name.c_str())); log_assert(holes_module); dict cell_cache; - int port_id = 1; int box_count = 0; for (auto cell : box_list) { RTLIL::Module* orig_box_module = module->design->module(cell->type); @@ -696,85 +695,21 @@ struct XAigerWriter Pass::call_on_module(module->design, box_module, "proc"); int box_inputs = 0, box_outputs = 0; - auto r = cell_cache.insert(std::make_pair(derived_name, nullptr)); - Cell *holes_cell = r.first->second; - if (r.second && box_module->get_bool_attribute("\\whitebox")) { - holes_cell = holes_module->addCell(cell->name, cell->type); - holes_cell->parameters = cell->parameters; - r.first->second = holes_cell; - - // Since Module::derive() will create a new module, there - // is a chance that the ports will be alphabetically ordered - // again, which is a problem when carry-chains are involved. - // Inherit the port ordering from the original module here... - // (and set the port_id below, when iterating through those) - log_assert(GetSize(box_module->ports) == GetSize(orig_box_module->ports)); - box_module->ports = orig_box_module->ports; - } - // NB: Assume box_module->ports are sorted alphabetically // (as RTLIL::Module::fixup_ports() would do) - int box_port_id = 1; for (const auto &port_name : box_module->ports) { RTLIL::Wire *w = box_module->wire(port_name); log_assert(w); - if (r.second) - w->port_id = box_port_id++; - RTLIL::Wire *holes_wire; - RTLIL::SigSpec port_sig; if (w->port_input) - for (int i = 0; i < GetSize(w); i++) { - box_inputs++; - holes_wire = holes_module->wire(stringf("\\i%d", box_inputs)); - if (!holes_wire) { - holes_wire = holes_module->addWire(stringf("\\i%d", box_inputs)); - holes_wire->port_input = true; - holes_wire->port_id = port_id++; - holes_module->ports.push_back(holes_wire->name); - } - if (holes_cell) - port_sig.append(holes_wire); - } - if (w->port_output) { + box_inputs += GetSize(w); + if (w->port_output) box_outputs += GetSize(w); - for (int i = 0; i < GetSize(w); i++) { - if (GetSize(w) == 1) - holes_wire = holes_module->addWire(stringf("$abc%s.%s", cell->name.c_str(), log_id(w->name))); - else - holes_wire = holes_module->addWire(stringf("$abc%s.%s[%d]", cell->name.c_str(), log_id(w->name), i)); - holes_wire->port_output = true; - holes_wire->port_id = port_id++; - holes_module->ports.push_back(holes_wire->name); - if (holes_cell) - port_sig.append(holes_wire); - else - holes_module->connect(holes_wire, State::S0); - } - } - if (!port_sig.empty()) { - if (r.second) - holes_cell->setPort(w->name, port_sig); - else - holes_module->connect(holes_cell->getPort(w->name), port_sig); - } } // For flops only, create an extra 1-bit input that drives a new wire // called ".$abc9_currQ" that is used below - if (box_module->get_bool_attribute("\\abc9_flop")) { - log_assert(holes_cell); - + if (box_module->get_bool_attribute("\\abc9_flop")) box_inputs++; - Wire *holes_wire = holes_module->wire(stringf("\\i%d", box_inputs)); - if (!holes_wire) { - holes_wire = holes_module->addWire(stringf("\\i%d", box_inputs)); - holes_wire->port_input = true; - holes_wire->port_id = port_id++; - holes_module->ports.push_back(holes_wire->name); - } - Wire *w = holes_module->addWire(stringf("%s.$abc9_currQ", cell->name.c_str())); - holes_module->connect(w, holes_wire); - } write_h_buffer(box_inputs); write_h_buffer(box_outputs); @@ -815,79 +750,20 @@ struct XAigerWriter f.write(buffer_str.data(), buffer_str.size()); if (holes_module) { - log_push(); - - // NB: fixup_ports() will sort ports by name - //holes_module->fixup_ports(); - holes_module->check(); - - // Cannot techmap/aigmap/check all lib_whitebox-es outside of write_xaiger - // since boxes may contain parameters in which case `flatten` would have - // created a new $paramod ... - Pass::call_on_module(holes_module->design, holes_module, "flatten -wb; techmap; aigmap"); - - dict replace; - for (auto it = holes_module->cells_.begin(); it != holes_module->cells_.end(); ) { - auto cell = it->second; - if (cell->type.in("$_DFF_N_", "$_DFF_NN0_", "$_DFF_NN1_", "$_DFF_NP0_", "$_DFF_NP1_", - "$_DFF_P_", "$_DFF_PN0_", "$_DFF_PN1", "$_DFF_PP0_", "$_DFF_PP1_")) { - SigBit D = cell->getPort("\\D"); - SigBit Q = cell->getPort("\\Q"); - // Remove the DFF cell from what needs to be a combinatorial box - it = holes_module->cells_.erase(it); - Wire *port; - if (GetSize(Q.wire) == 1) - port = holes_module->wire(stringf("$abc%s", Q.wire->name.c_str())); - else - port = holes_module->wire(stringf("$abc%s[%d]", Q.wire->name.c_str(), Q.offset)); - log_assert(port); - // Prepare to replace "assign = DFF.Q;" with "assign = DFF.D;" - // in order to extract the combinatorial control logic that feeds the box - // (i.e. clock enable, synchronous reset, etc.) - replace.insert(std::make_pair(SigSig(port,Q), SigSig(port,D))); - // Since `flatten` above would have created wires named ".Q", - // extract the pre-techmap cell name - auto pos = Q.wire->name.str().rfind("."); - log_assert(pos != std::string::npos); - IdString driver = Q.wire->name.substr(0, pos); - // And drive the signal that was previously driven by "DFF.Q" (typically - // used to implement clock-enable functionality) with the ".$abc9_currQ" - // wire (which itself is driven an input port) we inserted above - Wire *currQ = holes_module->wire(stringf("%s.$abc9_currQ", driver.c_str())); - log_assert(currQ); - holes_module->connect(Q, currQ); - continue; - } - else if (!cell->type.in("$_NOT_", "$_AND_")) - log_error("Whitebox contents cannot be represented as AIG. Please verify whiteboxes are synthesisable.\n"); - ++it; - } - - for (auto &conn : holes_module->connections_) { - auto it = replace.find(conn); - if (it != replace.end()) - conn = it->second; - } - - // Move into a new (temporary) design so that "clean" will only - // operate (and run checks on) this one module - RTLIL::Design *holes_design = new RTLIL::Design; - module->design->modules_.erase(holes_module->name); - holes_design->add(holes_module); - Pass::call(holes_design, "opt -purge"); + module->design->selection_stack.emplace_back(false); + module->design->selection().select(holes_module); std::stringstream a_buffer; XAigerWriter writer(holes_module, true /* holes_mode */); writer.write_aiger(a_buffer, false /*ascii_mode*/); - delete holes_design; + + module->design->selection_stack.pop_back(); f << "a"; std::string buffer_str = a_buffer.str(); int32_t buffer_size_be = to_big_endian(buffer_str.size()); f.write(reinterpret_cast(&buffer_size_be), sizeof(buffer_size_be)); f.write(buffer_str.data(), buffer_str.size()); - - log_pop(); } } diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index cd798cfbe..e11b15065 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -207,7 +207,7 @@ struct Abc9Pass : public ScriptPass tempdir_name = make_temp_dir(tempdir_name); run("scc -set_attr abc9_scc_id {}"); - run("abc9_ops -break_scc -prep_dff"); + run("abc9_ops -break_scc -prep_dff -prep_holes"); run("aigmap"); run(stringf("write_xaiger -map %s/input.sym %s/input.xaig", tempdir_name.c_str(), tempdir_name.c_str()), "write_xaiger -map /input.sym /input.xaig"); diff --git a/passes/techmap/abc9_ops.cc b/passes/techmap/abc9_ops.cc index 3e7e5ec7f..8eb935e1f 100644 --- a/passes/techmap/abc9_ops.cc +++ b/passes/techmap/abc9_ops.cc @@ -20,6 +20,7 @@ #include "kernel/register.h" #include "kernel/sigtools.h" +#include "kernel/utils.h" USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN @@ -75,7 +76,8 @@ void break_scc(RTLIL::Module *module) module->fixup_ports(); } -void unbreak_scc(RTLIL::Module *module) { +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 @@ -96,7 +98,8 @@ void unbreak_scc(RTLIL::Module *module) { module->fixup_ports(); } -void prep_dff(RTLIL::Module *module) { +void prep_dff(RTLIL::Module *module) +{ auto design = module->design; log_assert(design); @@ -134,6 +137,306 @@ void prep_dff(RTLIL::Module *module) { } } +void prep_holes(RTLIL::Module *module) +{ + auto design = module->design; + log_assert(design); + + SigMap sigmap(module); + + // TODO: Speed up toposort -- ultimately we care about + // box ordering, but not individual AIG cells + dict> bit_drivers, bit_users; + TopoSort toposort; + bool abc9_box_seen = false; + + for (auto cell : module->selected_cells()) { + if (cell->type == "$_NOT_") + { + SigBit A = sigmap(cell->getPort("\\A").as_bit()); + SigBit Y = sigmap(cell->getPort("\\Y").as_bit()); + toposort.node(cell->name); + bit_users[A].insert(cell->name); + bit_drivers[Y].insert(cell->name); + continue; + } + + if (cell->type == "$_AND_") + { + SigBit A = sigmap(cell->getPort("\\A").as_bit()); + SigBit B = sigmap(cell->getPort("\\B").as_bit()); + SigBit Y = sigmap(cell->getPort("\\Y").as_bit()); + toposort.node(cell->name); + bit_users[A].insert(cell->name); + bit_users[B].insert(cell->name); + bit_drivers[Y].insert(cell->name); + continue; + } + + if (cell->type == "$__ABC9_FF_") + continue; + + RTLIL::Module* inst_module = design->module(cell->type); + if (inst_module) { + if (!inst_module->attributes.count("\\abc9_box_id") || cell->get_bool_attribute("\\abc9_keep")) + continue; + + for (const auto &conn : cell->connections()) { + auto port_wire = inst_module->wire(conn.first); + // Ignore inout for the sake of topographical ordering + if (port_wire->port_input && !port_wire->port_output) + for (auto bit : sigmap(conn.second)) + bit_users[bit].insert(cell->name); + if (port_wire->port_output) + for (auto bit : sigmap(conn.second)) + bit_drivers[bit].insert(cell->name); + } + + abc9_box_seen = true; + + 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 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") + || cell->get_bool_attribute("\\abc9_keep")) + continue; + + bool blackbox = box_module->get_blackbox_attribute(true /* ignore_wb */); + + // Fully pad all unused input connections of this box cell with S0 + // Fully pad all undriven output connections of this box cell with anonymous wires + // NB: Assume box_module->ports are sorted alphabetically + // (as RTLIL::Module::fixup_ports() would do) + for (const auto &port_name : box_module->ports) { + RTLIL::Wire* w = box_module->wire(port_name); + log_assert(w); + 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->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); + } + } + } + + 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); + + dict cell_cache; + + 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; + + // Since Module::derive() will create a new module, there + // is a chance that the ports will be alphabetically ordered + // again, which is a problem when carry-chains are involved. + // Inherit the port ordering from the original module here... + // (and set the port_id below, when iterating through those) + log_assert(GetSize(box_module->ports) == GetSize(orig_box_module->ports)); + box_module->ports = orig_box_module->ports; + } + + // NB: Assume box_module->ports are sorted alphabetically + // (as RTLIL::Module::fixup_ports() would do) + int box_port_id = 1; + for (const auto &port_name : box_module->ports) { + RTLIL::Wire *w = box_module->wire(port_name); + log_assert(w); + if (r.second) + w->port_id = box_port_id++; + RTLIL::Wire *holes_wire; + RTLIL::SigSpec port_sig; + if (w->port_input) + for (int i = 0; i < GetSize(w); i++) { + box_inputs++; + holes_wire = holes_module->wire(stringf("\\i%d", box_inputs)); + if (!holes_wire) { + holes_wire = holes_module->addWire(stringf("\\i%d", box_inputs)); + holes_wire->port_input = true; + holes_wire->port_id = port_id++; + holes_module->ports.push_back(holes_wire->name); + } + if (holes_cell) + port_sig.append(holes_wire); + } + if (w->port_output) + for (int i = 0; i < GetSize(w); i++) { + if (GetSize(w) == 1) + holes_wire = holes_module->addWire(stringf("$abc%s.%s", cell->name.c_str(), log_id(w->name))); + else + holes_wire = holes_module->addWire(stringf("$abc%s.%s[%d]", cell->name.c_str(), log_id(w->name), i)); + holes_wire->port_output = true; + holes_wire->port_id = port_id++; + holes_module->ports.push_back(holes_wire->name); + if (holes_cell) + port_sig.append(holes_wire); + else + holes_module->connect(holes_wire, State::S0); + } + if (!port_sig.empty()) { + if (r.second) + holes_cell->setPort(w->name, port_sig); + else + holes_module->connect(holes_cell->getPort(w->name), port_sig); + } + } + + // For flops only, create an extra 1-bit input that drives a new wire + // called ".$abc9_currQ" that is used below + if (box_module->get_bool_attribute("\\abc9_flop")) { + log_assert(holes_cell); + + box_inputs++; + Wire *holes_wire = holes_module->wire(stringf("\\i%d", box_inputs)); + if (!holes_wire) { + holes_wire = holes_module->addWire(stringf("\\i%d", box_inputs)); + holes_wire->port_input = true; + holes_wire->port_id = port_id++; + holes_module->ports.push_back(holes_wire->name); + } + Wire *w = holes_module->addWire(stringf("%s.$abc9_currQ", cell->name.c_str())); + holes_module->connect(w, holes_wire); + } + } + + log_push(); + + // NB: fixup_ports() will sort ports by name + //holes_module->fixup_ports(); + holes_module->check(); + + // Cannot techmap/aigmap/check all lib_whitebox-es outside of write_xaiger + // since boxes may contain parameters in which case `flatten` would have + // created a new $paramod ... + Pass::call_on_module(design, holes_module, "flatten -wb; techmap; aigmap"); + + dict replace; + for (auto it = holes_module->cells_.begin(); it != holes_module->cells_.end(); ) { + auto cell = it->second; + if (cell->type.in("$_DFF_N_", "$_DFF_NN0_", "$_DFF_NN1_", "$_DFF_NP0_", "$_DFF_NP1_", + "$_DFF_P_", "$_DFF_PN0_", "$_DFF_PN1", "$_DFF_PP0_", "$_DFF_PP1_")) { + SigBit D = cell->getPort("\\D"); + SigBit Q = cell->getPort("\\Q"); + // Remove the DFF cell from what needs to be a combinatorial box + it = holes_module->cells_.erase(it); + Wire *port; + if (GetSize(Q.wire) == 1) + port = holes_module->wire(stringf("$abc%s", Q.wire->name.c_str())); + else + port = holes_module->wire(stringf("$abc%s[%d]", Q.wire->name.c_str(), Q.offset)); + log_assert(port); + // Prepare to replace "assign = DFF.Q;" with "assign = DFF.D;" + // in order to extract the combinatorial control logic that feeds the box + // (i.e. clock enable, synchronous reset, etc.) + replace.insert(std::make_pair(SigSig(port,Q), SigSig(port,D))); + // Since `flatten` above would have created wires named ".Q", + // extract the pre-techmap cell name + auto pos = Q.wire->name.str().rfind("."); + log_assert(pos != std::string::npos); + IdString driver = Q.wire->name.substr(0, pos); + // And drive the signal that was previously driven by "DFF.Q" (typically + // used to implement clock-enable functionality) with the ".$abc9_currQ" + // wire (which itself is driven an input port) we inserted above + Wire *currQ = holes_module->wire(stringf("%s.$abc9_currQ", driver.c_str())); + log_assert(currQ); + holes_module->connect(Q, currQ); + continue; + } + else if (!cell->type.in("$_NOT_", "$_AND_")) + log_error("Whitebox contents cannot be represented as AIG. Please verify whiteboxes are synthesisable.\n"); + ++it; + } + + for (auto &conn : holes_module->connections_) { + auto it = replace.find(conn); + if (it != replace.end()) + conn = it->second; + } + + // Move into a new (temporary) design so that "clean" will only + // operate (and run checks on) this one module + RTLIL::Design *holes_design = new RTLIL::Design; + holes_design->add(holes_module); + Pass::call(holes_design, "opt -purge"); + holes_design->modules_.erase(holes_module->name); + holes_module->design = design; + + log_pop(); +} + struct Abc9PrepPass : public Pass { Abc9PrepPass() : Pass("abc9_ops", "helper functions for ABC9") { } void help() YS_OVERRIDE @@ -151,6 +454,7 @@ struct Abc9PrepPass : public Pass { bool break_scc_mode = false; bool unbreak_scc_mode = false; bool prep_dff_mode = false; + bool prep_holes_mode = false; size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) { @@ -167,6 +471,10 @@ struct Abc9PrepPass : public Pass { prep_dff_mode = true; continue; } + if (arg == "-prep_holes") { + prep_holes_mode = true; + continue; + } break; } extra_args(args, argidx, design); @@ -178,6 +486,8 @@ struct Abc9PrepPass : public Pass { unbreak_scc(mod); if (prep_dff_mode) prep_dff(mod); + if (prep_holes_mode) + prep_holes(mod); } } } Abc9PrepPass; -- cgit v1.2.3 From e2bbe33a88c11b89e5a011c43d5a9c6b4623f9a7 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 30 Dec 2019 18:24:29 -0800 Subject: Get rid of holes_mode --- backends/aiger/xaiger.cc | 105 ++++++++++++++++------------------------------- 1 file changed, 35 insertions(+), 70 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 73af3bdfb..877e0e58a 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -78,7 +78,7 @@ struct XAigerWriter Module *module; SigMap sigmap; - pool input_bits, output_bits, external_bits; + pool input_bits, output_bits; dict not_map, alias_map; dict> and_map; vector ci_bits, co_bits; @@ -136,7 +136,7 @@ struct XAigerWriter return a; } - XAigerWriter(Module *module, bool holes_mode=false) : module(module), sigmap(module) + XAigerWriter(Module *module) : module(module), sigmap(module) { pool undriven_bits; pool unused_bits; @@ -166,9 +166,7 @@ struct XAigerWriter if (bit.wire == nullptr) { if (wire->port_output) { aig_map[wirebit] = (bit == State::S1) ? 1 : 0; - if (holes_mode) - output_bits.insert(wirebit); - //external_bits.insert(wirebit); + output_bits.insert(wirebit); } continue; } @@ -182,10 +180,7 @@ struct XAigerWriter if (wire->port_output) { if (bit != wirebit) alias_map[wirebit] = bit; - if (holes_mode) - output_bits.insert(wirebit); - else - external_bits.insert(wirebit); + output_bits.insert(wirebit); } if (wire->port_input && wire->port_output) @@ -207,11 +202,9 @@ struct XAigerWriter unused_bits.erase(A); undriven_bits.erase(Y); not_map[Y] = A; - if (!holes_mode) { - toposort.node(cell->name); - bit_users[A].insert(cell->name); - bit_drivers[Y].insert(cell->name); - } + toposort.node(cell->name); + bit_users[A].insert(cell->name); + bit_drivers[Y].insert(cell->name); continue; } @@ -224,17 +217,13 @@ struct XAigerWriter unused_bits.erase(B); undriven_bits.erase(Y); and_map[Y] = make_pair(A, B); - if (!holes_mode) { - toposort.node(cell->name); - bit_users[A].insert(cell->name); - bit_users[B].insert(cell->name); - bit_drivers[Y].insert(cell->name); - } + toposort.node(cell->name); + bit_users[A].insert(cell->name); + bit_users[B].insert(cell->name); + bit_drivers[Y].insert(cell->name); continue; } - log_assert(!holes_mode); - if (cell->type == "$__ABC9_FF_") { SigBit D = sigmap(cell->getPort("\\D").as_bit()); @@ -298,7 +287,7 @@ struct XAigerWriter if (!is_input && !is_output) log_error("Connection '%s' on cell '%s' (type '%s') not recognised!\n", log_id(c.first), log_id(cell), log_id(cell->type)); - if (is_input) { + if (is_input) for (auto b : c.second) { Wire *w = b.wire; if (!w) continue; @@ -306,13 +295,19 @@ struct XAigerWriter SigBit I = sigmap(b); if (I != b) alias_map[b] = I; - if (holes_mode) - output_bits.insert(b); - else - external_bits.insert(b); + output_bits.insert(b); } } - } + + if (is_output) + for (auto b : c.second) { + Wire *w = b.wire; + if (!w) continue; + SigBit O = sigmap(b); + if (O != b) + alias_map[O] = b; + input_bits.insert(O); + } } //log_warning("Unsupported cell type: %s (%s)\n", log_id(cell->type), log_id(cell)); @@ -495,57 +490,27 @@ struct XAigerWriter // TODO: Free memory from toposort, bit_drivers, bit_users } - if (!holes_mode) - for (auto cell : module->cells()) - if (!module->selected(cell)) - for (auto &conn : cell->connections()) - if (cell->input(conn.first)) - for (auto wirebit : conn.second) - if (sigmap(wirebit).wire) - external_bits.insert(wirebit); - - // For all bits consumed outside of the selected cells, - // but driven from a selected cell, then add it as - // a primary output - for (auto wirebit : external_bits) { - SigBit bit = sigmap(wirebit); - if (!bit.wire) - continue; - if (!undriven_bits.count(bit)) { - if (bit != wirebit) - alias_map[wirebit] = bit; - output_bits.insert(wirebit); - } - } - for (auto bit : input_bits) - undriven_bits.erase(sigmap(bit)); + undriven_bits.erase(bit); for (auto bit : output_bits) unused_bits.erase(sigmap(bit)); for (auto bit : unused_bits) undriven_bits.erase(bit); - - // Make all undriven bits a primary input - if (!holes_mode) + if (!undriven_bits.empty()) { for (auto bit : undriven_bits) { + log_warning("Treating undriven bit %s.%s like $anyseq.\n", log_id(module), log_signal(bit)); input_bits.insert(bit); - undriven_bits.erase(bit); } - - if (holes_mode) { - struct sort_by_port_id { - bool operator()(const RTLIL::SigBit& a, const RTLIL::SigBit& b) const { - return a.wire->port_id < b.wire->port_id; - } - }; - input_bits.sort(sort_by_port_id()); - output_bits.sort(sort_by_port_id()); - } - else { - input_bits.sort(); - output_bits.sort(); + log_warning("Treating a total of %d undriven bits in %s like $anyseq.\n", GetSize(undriven_bits), log_id(module)); } + struct sort_by_port_id { + bool operator()(const RTLIL::SigBit& a, const RTLIL::SigBit& b) const { + return a.wire->port_id < b.wire->port_id; + } + }; + input_bits.sort(sort_by_port_id()); + output_bits.sort(sort_by_port_id()); not_map.sort(); and_map.sort(); @@ -754,7 +719,7 @@ struct XAigerWriter module->design->selection().select(holes_module); std::stringstream a_buffer; - XAigerWriter writer(holes_module, true /* holes_mode */); + XAigerWriter writer(holes_module); writer.write_aiger(a_buffer, false /*ascii_mode*/); module->design->selection_stack.pop_back(); -- cgit v1.2.3 From 65baefecd39b3be641b9a6be350d2ae83854cacc Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 30 Dec 2019 18:26:35 -0800 Subject: Rid unnecessary if --- backends/aiger/xaiger.cc | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 877e0e58a..35fb8d5dc 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -714,22 +714,20 @@ struct XAigerWriter f.write(reinterpret_cast(&buffer_size_be), sizeof(buffer_size_be)); f.write(buffer_str.data(), buffer_str.size()); - if (holes_module) { - module->design->selection_stack.emplace_back(false); - module->design->selection().select(holes_module); + module->design->selection_stack.emplace_back(false); + module->design->selection().select(holes_module); - std::stringstream a_buffer; - XAigerWriter writer(holes_module); - writer.write_aiger(a_buffer, false /*ascii_mode*/); + std::stringstream a_buffer; + XAigerWriter writer(holes_module); + writer.write_aiger(a_buffer, false /*ascii_mode*/); - module->design->selection_stack.pop_back(); + module->design->selection_stack.pop_back(); - f << "a"; - std::string buffer_str = a_buffer.str(); - int32_t buffer_size_be = to_big_endian(buffer_str.size()); - f.write(reinterpret_cast(&buffer_size_be), sizeof(buffer_size_be)); - f.write(buffer_str.data(), buffer_str.size()); - } + f << "a"; + buffer_str = a_buffer.str(); + buffer_size_be = to_big_endian(buffer_str.size()); + f.write(reinterpret_cast(&buffer_size_be), sizeof(buffer_size_be)); + f.write(buffer_str.data(), buffer_str.size()); } f << "h"; -- cgit v1.2.3 From 0317a2b476f5ec78cab35b79a02d166c84c0f53e Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 30 Dec 2019 18:46:22 -0800 Subject: holes_module to be whitebox --- passes/techmap/abc9_ops.cc | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/passes/techmap/abc9_ops.cc b/passes/techmap/abc9_ops.cc index 8eb935e1f..e65b16fc6 100644 --- a/passes/techmap/abc9_ops.cc +++ b/passes/techmap/abc9_ops.cc @@ -434,6 +434,8 @@ void prep_holes(RTLIL::Module *module) holes_design->modules_.erase(holes_module->name); holes_module->design = design; + holes_module->set_bool_attribute(ID::whitebox); + log_pop(); } @@ -480,6 +482,14 @@ struct Abc9PrepPass : public Pass { extra_args(args, argidx, design); for (auto mod : design->selected_modules()) { + if (mod->get_blackbox_attribute()) + continue; + + if (mod->processes.size() > 0) { + log("Skipping module %s as it contains processes.\n", log_id(mod)); + continue; + } + if (break_scc_mode) break_scc(mod); if (unbreak_scc_mode) -- cgit v1.2.3 From 52f649dcfd2bba3e4efc219b53e7937281a658c6 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 30 Dec 2019 18:47:06 -0800 Subject: Use function arg --- passes/techmap/abc9_map.cc | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/passes/techmap/abc9_map.cc b/passes/techmap/abc9_map.cc index 6b9d0afff..9764d057c 100644 --- a/passes/techmap/abc9_map.cc +++ b/passes/techmap/abc9_map.cc @@ -198,7 +198,7 @@ struct abc9_output_filter void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string script_file, std::string exe_file, vector lut_costs, std::string delay_target, std::string /*lutin_shared*/, bool fast_mode, - const std::vector &/*cells*/, bool show_tempdir, std::string box_file, std::string lut_file, + const std::vector &cells, bool show_tempdir, std::string box_file, std::string lut_file, std::string wire_delay, const dict &box_lookup, bool nomfs, std::string tempdir_name ) { @@ -359,7 +359,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip dict abc9_box; vector boxes; - for (auto cell : module->selected_cells()) { + for (auto cell : cells) { if (cell->type.in(ID($_AND_), ID($_NOT_), ID($__ABC9_FF_))) { module->remove(cell); continue; @@ -960,18 +960,18 @@ struct Abc9MapPass : public Pass { } } - for (auto module : design->selected_modules()) + for (auto mod : design->selected_modules()) { - if (module->processes.size() > 0) - log_error("Module '%s' has processes!\n", log_id(module)); + if (mod->processes.size() > 0) { + log("Skipping module %s as it contains processes.\n", log_id(mod)); + continue; + } - const std::vector all_cells = module->selected_cells(); + const std::vector all_cells = mod->selected_cells(); - design->selected_active_module = module->name.str(); - abc9_module(design, module, script_file, exe_file, lut_costs, + abc9_module(design, mod, script_file, exe_file, lut_costs, delay_target, lutin_shared, fast_mode, all_cells, show_tempdir, box_file, lut_file, wire_delay, box_lookup, nomfs, tempdir_name); - design->selected_active_module.clear(); } log_pop(); -- cgit v1.2.3 From 88334cab891d47778931c1ea0060fd107052e189 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 30 Dec 2019 18:49:33 -0800 Subject: Cleanup --- backends/aiger/xaiger.cc | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 35fb8d5dc..9e0a56963 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -645,19 +645,12 @@ struct XAigerWriter // write_o_buffer(0); if (!box_list.empty() || !ff_bits.empty()) { - RTLIL::Module *holes_module = module->design->module(stringf("%s$holes", module->name.c_str())); - log_assert(holes_module); - - dict cell_cache; - int box_count = 0; for (auto cell : box_list) { RTLIL::Module* orig_box_module = module->design->module(cell->type); log_assert(orig_box_module); IdString derived_name = orig_box_module->derive(module->design, cell->parameters); RTLIL::Module* box_module = module->design->module(derived_name); - if (box_module->has_processes()) - Pass::call_on_module(module->design, box_module, "proc"); int box_inputs = 0, box_outputs = 0; // NB: Assume box_module->ports are sorted alphabetically @@ -714,6 +707,9 @@ struct XAigerWriter f.write(reinterpret_cast(&buffer_size_be), sizeof(buffer_size_be)); f.write(buffer_str.data(), buffer_str.size()); + RTLIL::Module *holes_module = module->design->module(stringf("%s$holes", module->name.c_str())); + log_assert(holes_module); + module->design->selection_stack.emplace_back(false); module->design->selection().select(holes_module); -- cgit v1.2.3 From b42b64e8ed713b0e9810f18db7cafcf356e2b4f6 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 30 Dec 2019 19:23:54 -0800 Subject: Move Pass::call() out of abc9_ops into abc9 --- backends/aiger/xaiger.cc | 4 ++ passes/techmap/abc9.cc | 14 +++++- passes/techmap/abc9_ops.cc | 113 +++++++++++++++++++-------------------------- 3 files changed, 63 insertions(+), 68 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 9e0a56963..830c86787 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -710,6 +710,10 @@ struct XAigerWriter RTLIL::Module *holes_module = module->design->module(stringf("%s$holes", module->name.c_str())); log_assert(holes_module); + for (auto cell : holes_module->cells()) + if (!cell->type.in("$_NOT_", "$_AND_")) + log_error("Whitebox contents cannot be represented as AIG. Please verify whiteboxes are synthesisable.\n"); + module->design->selection_stack.emplace_back(false); module->design->selection().select(holes_module); diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index e11b15065..7d922df56 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -185,11 +185,21 @@ struct Abc9Pass : public ScriptPass void script() YS_OVERRIDE { + run("abc9_ops -prep_holes"); + run("select -set abc9_holes A:abc9_holes"); + run("flatten -wb @abc9_holes"); + run("techmap @abc9_holes"); + run("aigmap @abc9_holes"); + run("select -list @abc9_holes"); + run("abc9_ops -prep_dff"); + run("opt -purge @abc9_holes"); + run("setattr -mod -set whitebox 1 @abc9_holes"); + auto selected_modules = active_design->selected_modules(); active_design->selection_stack.emplace_back(false); for (auto mod : selected_modules) { - if (mod->attributes.count(ID(abc9_box_id))) + if (mod->get_blackbox_attribute()) continue; if (mod->processes.size() > 0) { @@ -207,7 +217,7 @@ struct Abc9Pass : public ScriptPass tempdir_name = make_temp_dir(tempdir_name); run("scc -set_attr abc9_scc_id {}"); - run("abc9_ops -break_scc -prep_dff -prep_holes"); + run("abc9_ops -break_scc"); run("aigmap"); run(stringf("write_xaiger -map %s/input.sym %s/input.xaig", tempdir_name.c_str(), tempdir_name.c_str()), "write_xaiger -map /input.sym /input.xaig"); diff --git a/passes/techmap/abc9_ops.cc b/passes/techmap/abc9_ops.cc index e65b16fc6..b52382972 100644 --- a/passes/techmap/abc9_ops.cc +++ b/passes/techmap/abc9_ops.cc @@ -135,6 +135,50 @@ void prep_dff(RTLIL::Module *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())); + log_assert(holes_module); + + dict replace; + for (auto it = holes_module->cells_.begin(); it != holes_module->cells_.end(); ) { + auto cell = it->second; + if (cell->type.in("$_DFF_N_", "$_DFF_NN0_", "$_DFF_NN1_", "$_DFF_NP0_", "$_DFF_NP1_", + "$_DFF_P_", "$_DFF_PN0_", "$_DFF_PN1", "$_DFF_PP0_", "$_DFF_PP1_")) { + SigBit D = cell->getPort("\\D"); + SigBit Q = cell->getPort("\\Q"); + // Remove the DFF cell from what needs to be a combinatorial box + it = holes_module->cells_.erase(it); + Wire *port; + if (GetSize(Q.wire) == 1) + port = holes_module->wire(stringf("$abc%s", Q.wire->name.c_str())); + else + port = holes_module->wire(stringf("$abc%s[%d]", Q.wire->name.c_str(), Q.offset)); + log_assert(port); + // Prepare to replace "assign = DFF.Q;" with "assign = DFF.D;" + // in order to extract the combinatorial control logic that feeds the box + // (i.e. clock enable, synchronous reset, etc.) + replace.insert(std::make_pair(SigSig(port,Q), SigSig(port,D))); + // Since `flatten` above would have created wires named ".Q", + // extract the pre-techmap cell name + auto pos = Q.wire->name.str().rfind("."); + log_assert(pos != std::string::npos); + IdString driver = Q.wire->name.substr(0, pos); + // And drive the signal that was previously driven by "DFF.Q" (typically + // used to implement clock-enable functionality) with the ".$abc9_currQ" + // wire (which itself is driven an input port) we inserted above + Wire *currQ = holes_module->wire(stringf("%s.$abc9_currQ", driver.c_str())); + log_assert(currQ); + holes_module->connect(Q, currQ); + } + 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) @@ -280,6 +324,7 @@ void prep_holes(RTLIL::Module *module) 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 cell_cache; @@ -371,72 +416,6 @@ void prep_holes(RTLIL::Module *module) holes_module->connect(w, holes_wire); } } - - log_push(); - - // NB: fixup_ports() will sort ports by name - //holes_module->fixup_ports(); - holes_module->check(); - - // Cannot techmap/aigmap/check all lib_whitebox-es outside of write_xaiger - // since boxes may contain parameters in which case `flatten` would have - // created a new $paramod ... - Pass::call_on_module(design, holes_module, "flatten -wb; techmap; aigmap"); - - dict replace; - for (auto it = holes_module->cells_.begin(); it != holes_module->cells_.end(); ) { - auto cell = it->second; - if (cell->type.in("$_DFF_N_", "$_DFF_NN0_", "$_DFF_NN1_", "$_DFF_NP0_", "$_DFF_NP1_", - "$_DFF_P_", "$_DFF_PN0_", "$_DFF_PN1", "$_DFF_PP0_", "$_DFF_PP1_")) { - SigBit D = cell->getPort("\\D"); - SigBit Q = cell->getPort("\\Q"); - // Remove the DFF cell from what needs to be a combinatorial box - it = holes_module->cells_.erase(it); - Wire *port; - if (GetSize(Q.wire) == 1) - port = holes_module->wire(stringf("$abc%s", Q.wire->name.c_str())); - else - port = holes_module->wire(stringf("$abc%s[%d]", Q.wire->name.c_str(), Q.offset)); - log_assert(port); - // Prepare to replace "assign = DFF.Q;" with "assign = DFF.D;" - // in order to extract the combinatorial control logic that feeds the box - // (i.e. clock enable, synchronous reset, etc.) - replace.insert(std::make_pair(SigSig(port,Q), SigSig(port,D))); - // Since `flatten` above would have created wires named ".Q", - // extract the pre-techmap cell name - auto pos = Q.wire->name.str().rfind("."); - log_assert(pos != std::string::npos); - IdString driver = Q.wire->name.substr(0, pos); - // And drive the signal that was previously driven by "DFF.Q" (typically - // used to implement clock-enable functionality) with the ".$abc9_currQ" - // wire (which itself is driven an input port) we inserted above - Wire *currQ = holes_module->wire(stringf("%s.$abc9_currQ", driver.c_str())); - log_assert(currQ); - holes_module->connect(Q, currQ); - continue; - } - else if (!cell->type.in("$_NOT_", "$_AND_")) - log_error("Whitebox contents cannot be represented as AIG. Please verify whiteboxes are synthesisable.\n"); - ++it; - } - - for (auto &conn : holes_module->connections_) { - auto it = replace.find(conn); - if (it != replace.end()) - conn = it->second; - } - - // Move into a new (temporary) design so that "clean" will only - // operate (and run checks on) this one module - RTLIL::Design *holes_design = new RTLIL::Design; - holes_design->add(holes_module); - Pass::call(holes_design, "opt -purge"); - holes_design->modules_.erase(holes_module->name); - holes_module->design = design; - - holes_module->set_bool_attribute(ID::whitebox); - - log_pop(); } struct Abc9PrepPass : public Pass { @@ -484,6 +463,8 @@ struct Abc9PrepPass : public Pass { 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)); -- cgit v1.2.3 From 0c4be94a02a70de495343258ecda19eb20b3616b Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 30 Dec 2019 20:13:25 -0800 Subject: Add -D DFF_MODE to abc9_map test --- tests/arch/xilinx/abc9_map.ys | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/arch/xilinx/abc9_map.ys b/tests/arch/xilinx/abc9_map.ys index 6823589f1..4a7b9384a 100644 --- a/tests/arch/xilinx/abc9_map.ys +++ b/tests/arch/xilinx/abc9_map.ys @@ -6,7 +6,7 @@ endmodule EOT design -save gold -techmap -map +/xilinx/abc9_map.v -max_iter 1 +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 @@ -29,7 +29,7 @@ endmodule EOT design -save gold -techmap -map +/xilinx/abc9_map.v -max_iter 1 +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 @@ -52,7 +52,7 @@ endmodule EOT design -save gold -techmap -map +/xilinx/abc9_map.v -max_iter 1 +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 @@ -76,7 +76,7 @@ endmodule EOT design -save gold -techmap -map +/xilinx/abc9_map.v -max_iter 1 +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 -- cgit v1.2.3 From 7997e2a90fd37886241b7eb657408177ef7f6fa7 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 30 Dec 2019 18:24:29 -0800 Subject: Get rid of holes_mode --- backends/aiger/xaiger.cc | 105 ++++++++++++++++------------------------------- 1 file changed, 35 insertions(+), 70 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index e7d767721..277017dfd 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -78,7 +78,7 @@ struct XAigerWriter Module *module; SigMap sigmap; - pool input_bits, output_bits, external_bits; + pool input_bits, output_bits; dict not_map, alias_map; dict> and_map; vector ci_bits, co_bits; @@ -136,7 +136,7 @@ struct XAigerWriter return a; } - XAigerWriter(Module *module, bool holes_mode=false) : module(module), sigmap(module) + XAigerWriter(Module *module) : module(module), sigmap(module) { pool undriven_bits; pool unused_bits; @@ -166,9 +166,7 @@ struct XAigerWriter if (bit.wire == nullptr) { if (wire->port_output) { aig_map[wirebit] = (bit == State::S1) ? 1 : 0; - if (holes_mode) - output_bits.insert(wirebit); - //external_bits.insert(wirebit); + output_bits.insert(wirebit); } continue; } @@ -182,10 +180,7 @@ struct XAigerWriter if (wire->port_output) { if (bit != wirebit) alias_map[wirebit] = bit; - if (holes_mode) - output_bits.insert(wirebit); - else - external_bits.insert(wirebit); + output_bits.insert(wirebit); } if (wire->port_input && wire->port_output) @@ -207,11 +202,9 @@ struct XAigerWriter unused_bits.erase(A); undriven_bits.erase(Y); not_map[Y] = A; - if (!holes_mode) { - toposort.node(cell->name); - bit_users[A].insert(cell->name); - bit_drivers[Y].insert(cell->name); - } + toposort.node(cell->name); + bit_users[A].insert(cell->name); + bit_drivers[Y].insert(cell->name); continue; } @@ -224,17 +217,13 @@ struct XAigerWriter unused_bits.erase(B); undriven_bits.erase(Y); and_map[Y] = make_pair(A, B); - if (!holes_mode) { - toposort.node(cell->name); - bit_users[A].insert(cell->name); - bit_users[B].insert(cell->name); - bit_drivers[Y].insert(cell->name); - } + toposort.node(cell->name); + bit_users[A].insert(cell->name); + bit_users[B].insert(cell->name); + bit_drivers[Y].insert(cell->name); continue; } - log_assert(!holes_mode); - if (cell->type == "$__ABC9_FF_") { SigBit D = sigmap(cell->getPort("\\D").as_bit()); @@ -298,7 +287,7 @@ struct XAigerWriter if (!is_input && !is_output) log_error("Connection '%s' on cell '%s' (type '%s') not recognised!\n", log_id(c.first), log_id(cell), log_id(cell->type)); - if (is_input) { + if (is_input) for (auto b : c.second) { Wire *w = b.wire; if (!w) continue; @@ -306,13 +295,19 @@ struct XAigerWriter SigBit I = sigmap(b); if (I != b) alias_map[b] = I; - if (holes_mode) - output_bits.insert(b); - else - external_bits.insert(b); + output_bits.insert(b); } } - } + + if (is_output) + for (auto b : c.second) { + Wire *w = b.wire; + if (!w) continue; + SigBit O = sigmap(b); + if (O != b) + alias_map[O] = b; + input_bits.insert(O); + } } //log_warning("Unsupported cell type: %s (%s)\n", log_id(cell->type), log_id(cell)); @@ -495,57 +490,27 @@ struct XAigerWriter // TODO: Free memory from toposort, bit_drivers, bit_users } - if (!holes_mode) - for (auto cell : module->cells()) - if (!module->selected(cell)) - for (auto &conn : cell->connections()) - if (cell->input(conn.first)) - for (auto wirebit : conn.second) - if (sigmap(wirebit).wire) - external_bits.insert(wirebit); - - // For all bits consumed outside of the selected cells, - // but driven from a selected cell, then add it as - // a primary output - for (auto wirebit : external_bits) { - SigBit bit = sigmap(wirebit); - if (!bit.wire) - continue; - if (!undriven_bits.count(bit)) { - if (bit != wirebit) - alias_map[wirebit] = bit; - output_bits.insert(wirebit); - } - } - for (auto bit : input_bits) - undriven_bits.erase(sigmap(bit)); + undriven_bits.erase(bit); for (auto bit : output_bits) unused_bits.erase(sigmap(bit)); for (auto bit : unused_bits) undriven_bits.erase(bit); - - // Make all undriven bits a primary input - if (!holes_mode) + if (!undriven_bits.empty()) { for (auto bit : undriven_bits) { + log_warning("Treating undriven bit %s.%s like $anyseq.\n", log_id(module), log_signal(bit)); input_bits.insert(bit); - undriven_bits.erase(bit); } - - if (holes_mode) { - struct sort_by_port_id { - bool operator()(const RTLIL::SigBit& a, const RTLIL::SigBit& b) const { - return a.wire->port_id < b.wire->port_id; - } - }; - input_bits.sort(sort_by_port_id()); - output_bits.sort(sort_by_port_id()); - } - else { - input_bits.sort(); - output_bits.sort(); + log_warning("Treating a total of %d undriven bits in %s like $anyseq.\n", GetSize(undriven_bits), log_id(module)); } + struct sort_by_port_id { + bool operator()(const RTLIL::SigBit& a, const RTLIL::SigBit& b) const { + return a.wire->port_id < b.wire->port_id; + } + }; + input_bits.sort(sort_by_port_id()); + output_bits.sort(sort_by_port_id()); not_map.sort(); and_map.sort(); @@ -877,7 +842,7 @@ struct XAigerWriter Pass::call(holes_design, "opt -purge"); 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; -- cgit v1.2.3 From a367f703ea0633a4a6289415ae8a4545440ee705 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 30 Dec 2019 22:56:19 -0800 Subject: Rename struct --- passes/techmap/abc9_ops.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/passes/techmap/abc9_ops.cc b/passes/techmap/abc9_ops.cc index b52382972..271b76a39 100644 --- a/passes/techmap/abc9_ops.cc +++ b/passes/techmap/abc9_ops.cc @@ -418,8 +418,8 @@ void prep_holes(RTLIL::Module *module) } } -struct Abc9PrepPass : public Pass { - Abc9PrepPass() : Pass("abc9_ops", "helper functions for ABC9") { } +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---| @@ -481,6 +481,6 @@ struct Abc9PrepPass : public Pass { prep_holes(mod); } } -} Abc9PrepPass; +} Abc9OpsPass; PRIVATE_NAMESPACE_END -- cgit v1.2.3 From f1bf44ae8f66e81b7de6a2ec47c4a9dffe7e6587 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 30 Dec 2019 22:58:39 -0800 Subject: abc9_ops -prep_dff cope with lack of holes module --- passes/techmap/abc9_ops.cc | 76 +++++++++++++++++++++++----------------------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/passes/techmap/abc9_ops.cc b/passes/techmap/abc9_ops.cc index 271b76a39..019868adb 100644 --- a/passes/techmap/abc9_ops.cc +++ b/passes/techmap/abc9_ops.cc @@ -137,47 +137,47 @@ void prep_dff(RTLIL::Module *module) } RTLIL::Module *holes_module = design->module(stringf("%s$holes", module->name.c_str())); - log_assert(holes_module); - - dict replace; - for (auto it = holes_module->cells_.begin(); it != holes_module->cells_.end(); ) { - auto cell = it->second; - if (cell->type.in("$_DFF_N_", "$_DFF_NN0_", "$_DFF_NN1_", "$_DFF_NP0_", "$_DFF_NP1_", - "$_DFF_P_", "$_DFF_PN0_", "$_DFF_PN1", "$_DFF_PP0_", "$_DFF_PP1_")) { - SigBit D = cell->getPort("\\D"); - SigBit Q = cell->getPort("\\Q"); - // Remove the DFF cell from what needs to be a combinatorial box - it = holes_module->cells_.erase(it); - Wire *port; - if (GetSize(Q.wire) == 1) - port = holes_module->wire(stringf("$abc%s", Q.wire->name.c_str())); + if (holes_module) { + dict replace; + for (auto it = holes_module->cells_.begin(); it != holes_module->cells_.end(); ) { + auto cell = it->second; + if (cell->type.in("$_DFF_N_", "$_DFF_NN0_", "$_DFF_NN1_", "$_DFF_NP0_", "$_DFF_NP1_", + "$_DFF_P_", "$_DFF_PN0_", "$_DFF_PN1", "$_DFF_PP0_", "$_DFF_PP1_")) { + SigBit D = cell->getPort("\\D"); + SigBit Q = cell->getPort("\\Q"); + // Remove the DFF cell from what needs to be a combinatorial box + it = holes_module->cells_.erase(it); + Wire *port; + if (GetSize(Q.wire) == 1) + port = holes_module->wire(stringf("$abc%s", Q.wire->name.c_str())); + else + port = holes_module->wire(stringf("$abc%s[%d]", Q.wire->name.c_str(), Q.offset)); + log_assert(port); + // Prepare to replace "assign = DFF.Q;" with "assign = DFF.D;" + // in order to extract the combinatorial control logic that feeds the box + // (i.e. clock enable, synchronous reset, etc.) + replace.insert(std::make_pair(SigSig(port,Q), SigSig(port,D))); + // Since `flatten` above would have created wires named ".Q", + // extract the pre-techmap cell name + auto pos = Q.wire->name.str().rfind("."); + log_assert(pos != std::string::npos); + IdString driver = Q.wire->name.substr(0, pos); + // And drive the signal that was previously driven by "DFF.Q" (typically + // used to implement clock-enable functionality) with the ".$abc9_currQ" + // wire (which itself is driven an input port) we inserted above + Wire *currQ = holes_module->wire(stringf("%s.$abc9_currQ", driver.c_str())); + log_assert(currQ); + holes_module->connect(Q, currQ); + } else - port = holes_module->wire(stringf("$abc%s[%d]", Q.wire->name.c_str(), Q.offset)); - log_assert(port); - // Prepare to replace "assign = DFF.Q;" with "assign = DFF.D;" - // in order to extract the combinatorial control logic that feeds the box - // (i.e. clock enable, synchronous reset, etc.) - replace.insert(std::make_pair(SigSig(port,Q), SigSig(port,D))); - // Since `flatten` above would have created wires named ".Q", - // extract the pre-techmap cell name - auto pos = Q.wire->name.str().rfind("."); - log_assert(pos != std::string::npos); - IdString driver = Q.wire->name.substr(0, pos); - // And drive the signal that was previously driven by "DFF.Q" (typically - // used to implement clock-enable functionality) with the ".$abc9_currQ" - // wire (which itself is driven an input port) we inserted above - Wire *currQ = holes_module->wire(stringf("%s.$abc9_currQ", driver.c_str())); - log_assert(currQ); - holes_module->connect(Q, currQ); + ++it; } - else - ++it; - } - for (auto &conn : holes_module->connections_) { - auto it = replace.find(conn); - if (it != replace.end()) - conn = it->second; + for (auto &conn : holes_module->connections_) { + auto it = replace.find(conn); + if (it != replace.end()) + conn = it->second; + } } } -- cgit v1.2.3 From dacdc6cc941015aff45d1fde4d5365ab5e36e883 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 30 Dec 2019 22:59:14 -0800 Subject: Remove abc9 -clk option --- passes/techmap/abc9.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 9e1318700..f44e3df06 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -150,7 +150,7 @@ struct Abc9Pass : public ScriptPass std::string arg = args[argidx]; if ((arg == "-exe" || arg == "-script" || arg == "-D" || /* arg == "-S" || */ arg == "-lut" || arg == "-luts" || - arg == "-clk" || arg == "-box" || arg == "-W") && + arg == "-box" || arg == "-W") && argidx+1 < args.size()) { map_cmd << " " << arg << " " << args[++argidx]; continue; -- cgit v1.2.3 From 436c96e2fba0d7f73adb0ebb2b69821fe1dfc58c Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 30 Dec 2019 23:29:14 -0800 Subject: Revert "Get rid of holes_mode" This reverts commit 7997e2a90fd37886241b7eb657408177ef7f6fa7. --- backends/aiger/xaiger.cc | 105 +++++++++++++++++++++++++++++++---------------- 1 file changed, 70 insertions(+), 35 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 277017dfd..e7d767721 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -78,7 +78,7 @@ struct XAigerWriter Module *module; SigMap sigmap; - pool input_bits, output_bits; + pool input_bits, output_bits, external_bits; dict not_map, alias_map; dict> and_map; vector ci_bits, co_bits; @@ -136,7 +136,7 @@ struct XAigerWriter return a; } - XAigerWriter(Module *module) : module(module), sigmap(module) + XAigerWriter(Module *module, bool holes_mode=false) : module(module), sigmap(module) { pool undriven_bits; pool unused_bits; @@ -166,7 +166,9 @@ struct XAigerWriter if (bit.wire == nullptr) { if (wire->port_output) { aig_map[wirebit] = (bit == State::S1) ? 1 : 0; - output_bits.insert(wirebit); + if (holes_mode) + output_bits.insert(wirebit); + //external_bits.insert(wirebit); } continue; } @@ -180,7 +182,10 @@ struct XAigerWriter if (wire->port_output) { if (bit != wirebit) alias_map[wirebit] = bit; - output_bits.insert(wirebit); + if (holes_mode) + output_bits.insert(wirebit); + else + external_bits.insert(wirebit); } if (wire->port_input && wire->port_output) @@ -202,9 +207,11 @@ struct XAigerWriter unused_bits.erase(A); undriven_bits.erase(Y); not_map[Y] = A; - toposort.node(cell->name); - bit_users[A].insert(cell->name); - bit_drivers[Y].insert(cell->name); + if (!holes_mode) { + toposort.node(cell->name); + bit_users[A].insert(cell->name); + bit_drivers[Y].insert(cell->name); + } continue; } @@ -217,13 +224,17 @@ struct XAigerWriter unused_bits.erase(B); undriven_bits.erase(Y); and_map[Y] = make_pair(A, B); - toposort.node(cell->name); - bit_users[A].insert(cell->name); - bit_users[B].insert(cell->name); - bit_drivers[Y].insert(cell->name); + 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_") { SigBit D = sigmap(cell->getPort("\\D").as_bit()); @@ -287,7 +298,7 @@ struct XAigerWriter if (!is_input && !is_output) log_error("Connection '%s' on cell '%s' (type '%s') not recognised!\n", log_id(c.first), log_id(cell), log_id(cell->type)); - if (is_input) + if (is_input) { for (auto b : c.second) { Wire *w = b.wire; if (!w) continue; @@ -295,19 +306,13 @@ struct XAigerWriter SigBit I = sigmap(b); if (I != b) alias_map[b] = I; - output_bits.insert(b); + if (holes_mode) + output_bits.insert(b); + else + external_bits.insert(b); } } - - if (is_output) - for (auto b : c.second) { - Wire *w = b.wire; - if (!w) continue; - SigBit O = sigmap(b); - if (O != b) - alias_map[O] = b; - input_bits.insert(O); - } + } } //log_warning("Unsupported cell type: %s (%s)\n", log_id(cell->type), log_id(cell)); @@ -490,27 +495,57 @@ struct XAigerWriter // TODO: Free memory from toposort, bit_drivers, bit_users } + if (!holes_mode) + for (auto cell : module->cells()) + if (!module->selected(cell)) + for (auto &conn : cell->connections()) + if (cell->input(conn.first)) + for (auto wirebit : conn.second) + if (sigmap(wirebit).wire) + external_bits.insert(wirebit); + + // For all bits consumed outside of the selected cells, + // but driven from a selected cell, then add it as + // a primary output + for (auto wirebit : external_bits) { + SigBit bit = sigmap(wirebit); + if (!bit.wire) + continue; + if (!undriven_bits.count(bit)) { + if (bit != wirebit) + alias_map[wirebit] = bit; + output_bits.insert(wirebit); + } + } + for (auto bit : input_bits) - undriven_bits.erase(bit); + undriven_bits.erase(sigmap(bit)); for (auto bit : output_bits) unused_bits.erase(sigmap(bit)); for (auto bit : unused_bits) undriven_bits.erase(bit); - if (!undriven_bits.empty()) { + + // Make all undriven bits a primary input + if (!holes_mode) for (auto bit : undriven_bits) { - log_warning("Treating undriven bit %s.%s like $anyseq.\n", log_id(module), log_signal(bit)); input_bits.insert(bit); + undriven_bits.erase(bit); } - 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(); } - struct sort_by_port_id { - bool operator()(const RTLIL::SigBit& a, const RTLIL::SigBit& b) const { - return a.wire->port_id < b.wire->port_id; - } - }; - input_bits.sort(sort_by_port_id()); - output_bits.sort(sort_by_port_id()); not_map.sort(); and_map.sort(); @@ -842,7 +877,7 @@ struct XAigerWriter Pass::call(holes_design, "opt -purge"); std::stringstream a_buffer; - XAigerWriter writer(holes_module); + XAigerWriter writer(holes_module, true /* holes_mode */); writer.write_aiger(a_buffer, false /*ascii_mode*/); delete holes_design; -- cgit v1.2.3 From 3798fa3bead6b944ebdee892c9bf5231559766f1 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 31 Dec 2019 09:59:17 -0800 Subject: Retry getting rid of write_xaiger's holes_mode --- backends/aiger/xaiger.cc | 122 ++++++++++++++++------------------------------- 1 file changed, 41 insertions(+), 81 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index e7d767721..40cf72548 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -136,11 +136,10 @@ struct XAigerWriter return a; } - XAigerWriter(Module *module, bool holes_mode=false) : module(module), sigmap(module) + XAigerWriter(Module *module) : module(module), sigmap(module) { pool undriven_bits; pool unused_bits; - pool inout_bits; // promote public wires for (auto wire : module->wires()) @@ -157,7 +156,12 @@ struct XAigerWriter if (wire->get_bool_attribute(ID::keep)) sigmap.add(wire); - for (auto wire : module->wires()) + // 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); @@ -166,30 +170,32 @@ struct XAigerWriter if (bit.wire == nullptr) { if (wire->port_output) { aig_map[wirebit] = (bit == State::S1) ? 1 : 0; - if (holes_mode) - output_bits.insert(wirebit); - //external_bits.insert(wirebit); + output_bits.insert(wirebit); } continue; } - undriven_bits.insert(bit); - unused_bits.insert(bit); - if (wire->port_input) input_bits.insert(bit); if (wire->port_output) { if (bit != wirebit) alias_map[wirebit] = bit; - if (holes_mode) - output_bits.insert(wirebit); - else - external_bits.insert(wirebit); + output_bits.insert(wirebit); } + } + } + + for (auto wire : module->wires()) + for (int i = 0; i < GetSize(wire); i++) + { + SigBit wirebit(wire, i); + SigBit bit = sigmap(wirebit); - if (wire->port_input && wire->port_output) - inout_bits.insert(wirebit); + if (bit.wire) { + undriven_bits.insert(bit); + unused_bits.insert(bit); + } } // TODO: Speed up toposort -- ultimately we care about @@ -207,11 +213,9 @@ struct XAigerWriter unused_bits.erase(A); undriven_bits.erase(Y); not_map[Y] = A; - if (!holes_mode) { - toposort.node(cell->name); - bit_users[A].insert(cell->name); - bit_drivers[Y].insert(cell->name); - } + toposort.node(cell->name); + bit_users[A].insert(cell->name); + bit_drivers[Y].insert(cell->name); continue; } @@ -224,17 +228,13 @@ struct XAigerWriter unused_bits.erase(B); undriven_bits.erase(Y); and_map[Y] = make_pair(A, B); - if (!holes_mode) { - toposort.node(cell->name); - bit_users[A].insert(cell->name); - bit_users[B].insert(cell->name); - bit_drivers[Y].insert(cell->name); - } + toposort.node(cell->name); + bit_users[A].insert(cell->name); + bit_users[B].insert(cell->name); + bit_drivers[Y].insert(cell->name); continue; } - log_assert(!holes_mode); - if (cell->type == "$__ABC9_FF_") { SigBit D = sigmap(cell->getPort("\\D").as_bit()); @@ -298,7 +298,7 @@ struct XAigerWriter if (!is_input && !is_output) log_error("Connection '%s' on cell '%s' (type '%s') not recognised!\n", log_id(c.first), log_id(cell), log_id(cell->type)); - if (is_input) { + if (is_input) for (auto b : c.second) { Wire *w = b.wire; if (!w) continue; @@ -306,13 +306,9 @@ struct XAigerWriter SigBit I = sigmap(b); if (I != b) alias_map[b] = I; - if (holes_mode) - output_bits.insert(b); - else - external_bits.insert(b); + output_bits.insert(b); } } - } } //log_warning("Unsupported cell type: %s (%s)\n", log_id(cell->type), log_id(cell)); @@ -495,29 +491,6 @@ struct XAigerWriter // TODO: Free memory from toposort, bit_drivers, bit_users } - if (!holes_mode) - for (auto cell : module->cells()) - if (!module->selected(cell)) - for (auto &conn : cell->connections()) - if (cell->input(conn.first)) - for (auto wirebit : conn.second) - if (sigmap(wirebit).wire) - external_bits.insert(wirebit); - - // For all bits consumed outside of the selected cells, - // but driven from a selected cell, then add it as - // a primary output - for (auto wirebit : external_bits) { - SigBit bit = sigmap(wirebit); - if (!bit.wire) - continue; - if (!undriven_bits.count(bit)) { - if (bit != wirebit) - alias_map[wirebit] = bit; - output_bits.insert(wirebit); - } - } - for (auto bit : input_bits) undriven_bits.erase(sigmap(bit)); for (auto bit : output_bits) @@ -526,33 +499,18 @@ struct XAigerWriter undriven_bits.erase(bit); // Make all undriven bits a primary input - if (!holes_mode) - for (auto bit : undriven_bits) { - input_bits.insert(bit); - undriven_bits.erase(bit); - } - - if (holes_mode) { - struct sort_by_port_id { - bool operator()(const RTLIL::SigBit& a, const RTLIL::SigBit& b) const { - return a.wire->port_id < b.wire->port_id; - } - }; - input_bits.sort(sort_by_port_id()); - output_bits.sort(sort_by_port_id()); - } - else { - input_bits.sort(); - output_bits.sort(); + 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); + log_dump(bit, i); aig_m++, aig_i++; log_assert(!aig_map.count(bit)); aig_map[bit] = 2*aig_m; @@ -578,7 +536,9 @@ struct XAigerWriter aig_outputs.push_back(bit2aig(bit)); } - 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)); } @@ -877,7 +837,7 @@ struct XAigerWriter Pass::call(holes_design, "opt -purge"); 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; -- cgit v1.2.3 From 134e70e8e7798dd1e841b8deac2165c9f334ba09 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 31 Dec 2019 10:21:11 -0800 Subject: write_xaiger: be more precise with ff_bits, remove ff_aig_map --- backends/aiger/xaiger.cc | 40 +++++++++++++++++++--------------------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 40cf72548..650ceba7a 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -82,7 +82,7 @@ struct XAigerWriter dict not_map, alias_map; dict> and_map; vector ci_bits, co_bits; - dict> ff_bits; + dict> ff_bits; dict arrival_times; vector> aig_gates; @@ -242,7 +242,7 @@ struct XAigerWriter unused_bits.erase(D); undriven_bits.erase(Q); alias_map[Q] = D; - auto r = ff_bits.insert(std::make_pair(D, std::make_pair(0, 2))); + auto r = ff_bits.insert(std::make_pair(D, std::make_tuple(Q, 0, 2))); log_assert(r.second); continue; } @@ -348,25 +348,26 @@ struct XAigerWriter auto it = cell->attributes.find(ID(abc9_mergeability)); log_assert(it != cell->attributes.end()); - rhs.first = it->second.as_int(); + std::get<1>(rhs) = it->second.as_int(); cell->attributes.erase(it); it = cell->attributes.find(ID(abc9_init)); log_assert(it != cell->attributes.end()); log_assert(GetSize(it->second) == 1); if (it->second[0] == State::S1) - rhs.second = 1; + std::get<2>(rhs) = 1; else if (it->second[0] == State::S0) - rhs.second = 0; + std::get<2>(rhs) = 0; else { log_assert(it->second[0] == State::Sx); - rhs.second = 0; + std::get<2>(rhs) = 0; } cell->attributes.erase(it); + const SigBit &q = std::get<0>(rhs); auto arrival = r.first->second.second; if (arrival) - arrival_times[d] = arrival; + arrival_times[q] = arrival; } for (auto &it : bit_users) @@ -510,25 +511,22 @@ struct XAigerWriter // pool<> iterates in LIFO order... for (int i = input_bits.size()-1; i >= 0; i--) { const auto &bit = *input_bits.element(i); - log_dump(bit, i); aig_m++, aig_i++; log_assert(!aig_map.count(bit)); aig_map[bit] = 2*aig_m; } for (const auto &i : ff_bits) { - const SigBit &bit = i.first; + const SigBit &q = std::get<0>(i.second); aig_m++, aig_i++; - log_assert(!aig_map.count(bit)); - aig_map[bit] = 2*aig_m; + log_assert(!aig_map.count(q)); + aig_map[q] = 2*aig_m; } - dict ff_aig_map; for (auto &bit : ci_bits) { aig_m++, aig_i++; - auto r = aig_map.insert(std::make_pair(bit, 2*aig_m)); - if (!r.second) - ff_aig_map[bit] = 2*aig_m; + log_assert(!aig_map.count(bit)); + aig_map[bit] = 2*aig_m; } for (auto bit : co_bits) { @@ -544,9 +542,9 @@ struct XAigerWriter } for (auto &i : ff_bits) { - const SigBit &bit = i.first; + const SigBit &d = i.first; aig_o++; - aig_outputs.push_back(ff_aig_map.at(bit)); + aig_outputs.push_back(aig_map.at(d)); } } @@ -752,13 +750,13 @@ struct XAigerWriter write_s_buffer(ff_bits.size()); for (const auto &i : ff_bits) { - const SigBit &bit = i.first; - int mergeability = i.second.first; + const SigBit &q = std::get<0>(i.second); + int mergeability = std::get<1>(i.second); log_assert(mergeability > 0); write_r_buffer(mergeability); - int init = i.second.second; + int init = std::get<2>(i.second); write_s_buffer(init); - write_i_buffer(arrival_times.at(bit, 0)); + write_i_buffer(arrival_times.at(q, 0)); //write_o_buffer(0); } -- cgit v1.2.3 From 789211d9b3a6892c72d22a09bf2299075337f9f9 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 31 Dec 2019 11:13:50 -0800 Subject: Fix incorrect $__ABC9_ASYNC[01] box --- techlibs/xilinx/abc9_map.v | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/techlibs/xilinx/abc9_map.v b/techlibs/xilinx/abc9_map.v index 2cabe57d7..a3f9e311e 100644 --- a/techlibs/xilinx/abc9_map.v +++ b/techlibs/xilinx/abc9_map.v @@ -186,7 +186,7 @@ module FDCE (output Q, input C, CE, D, CLR); // $__ABC9_ASYNC1 below ); // Since this is an async flop, async behaviour is dealt with here - $__ABC9_ASYNC0 abc_async (.A($abc9_currQ), .S(CLR ^ IS_CLR_INVERTED), .Y(QQ)); + $__ABC9_ASYNC1 abc_async (.A($abc9_currQ), .S(CLR ^ IS_CLR_INVERTED), .Y(QQ)); end else begin assign Q = QQ; @@ -204,7 +204,7 @@ module FDCE (output Q, input C, CE, D, CLR); // $__ABC9_ASYNC0 below ); // Since this is an async flop, async behaviour is dealt with here - $__ABC9_ASYNC1 abc_async (.A($abc9_currQ), .S(CLR ^ IS_CLR_INVERTED), .Y(QQ)); + $__ABC9_ASYNC0 abc_async (.A($abc9_currQ), .S(CLR ^ IS_CLR_INVERTED), .Y(QQ)); end endgenerate $__ABC9_FF_ abc_dff (.D($Q), .Q($abc9_currQ)); -- cgit v1.2.3 From b4663a987bc1bac3aa4cccab99dc191825902205 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 31 Dec 2019 11:14:11 -0800 Subject: Fix attributes on $__ABC9_ASYNC[01] whitebox --- techlibs/xilinx/abc9_model.v | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/techlibs/xilinx/abc9_model.v b/techlibs/xilinx/abc9_model.v index c793396a4..11250123d 100644 --- a/techlibs/xilinx/abc9_model.v +++ b/techlibs/xilinx/abc9_model.v @@ -34,13 +34,13 @@ module \$__ABC9_FF_ (input D, output Q); endmodule // Box to emulate async behaviour of FDC* -(* abc_box_id = 1000 *) +(* 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* -(* abc_box_id = 1001 *) +(* abc9_box_id = 1001, lib_whitebox *) module \$__ABC9_ASYNC1 (input A, S, output Y); assign Y = S ? 1'b0 : A; endmodule -- cgit v1.2.3 From 4cdba00e25d892b90c0ee48716c17dec60e472db Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 31 Dec 2019 15:24:02 -0800 Subject: FDCE ports to be alphabetical --- techlibs/xilinx/cells_sim.v | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/techlibs/xilinx/cells_sim.v b/techlibs/xilinx/cells_sim.v index 4d20e1d2c..982ccad72 100644 --- a/techlibs/xilinx/cells_sim.v +++ b/techlibs/xilinx/cells_sim.v @@ -405,10 +405,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; -- cgit v1.2.3 From 6b825c719b5bf6f63d3397cfadf8293b5d14dde6 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 31 Dec 2019 15:25:46 -0800 Subject: Update abc9_xc7.box comments --- techlibs/xilinx/abc9_xc7.box | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/techlibs/xilinx/abc9_xc7.box b/techlibs/xilinx/abc9_xc7.box index 16606d14e..67523124a 100644 --- a/techlibs/xilinx/abc9_xc7.box +++ b/techlibs/xilinx/abc9_xc7.box @@ -1,8 +1,9 @@ # 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 @@ -15,7 +16,7 @@ MUXF7 1 1 3 1 MUXF8 2 1 3 1 104 94 273 -# Box containing MUXF7.[AB] + MUXF8, +# Box containing MUXF7.[AB] + MUXF8 # Necessary to make these an atomic unit so that # ABC cannot optimise just one of the MUXF7 away # and expect to save on its delay @@ -27,8 +28,8 @@ $__MUXF78 3 1 6 1 # 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 +# (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 @@ -53,55 +54,54 @@ $__ABC9_ASYNC0 1000 1 2 1 $__ABC9_ASYNC1 1001 1 2 1 0 764 -# 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 +# 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 -# NB: Inputs/Outputs must be ordered alphabetically -# (with exception for \$currQ) - -# Inputs: C CE D R \$currQ +# Inputs: C CE D R $abc9_currQ # Outputs: Q FDRE 1100 1 5 1 #0 109 -46 404 0 0 109 0 404 0 # Clamp -46ps Tsu -# Inputs: C CE D R \$currQ +# Inputs: C CE D R $abc9_currQ # Outputs: Q FDRE_1 1101 1 5 1 #0 109 0 -46 404 0 109 0 0 404 # Clamp -46ps Tsu -# Inputs: C CE CLR D \$currQ +# Inputs: C CE CLR D $abc9_currQ # Outputs: Q FDCE 1102 1 5 1 #0 109 764 -46 0 0 109 764 0 0 # Clamp -46ps Tsu -# Inputs: C CE CLR D \$currQ +# Inputs: C CE CLR D $abc9_currQ # Outputs: Q FDCE_1 1103 1 5 1 #0 109 764 -46 0 0 109 764 0 0 # Clamp -46ps Tsu -# Inputs: C CE D PRE \$currQ +# Inputs: C CE D PRE $abc9_currQ # Outputs: Q FDPE 1104 1 5 1 #0 109 -46 764 0 0 109 0 764 0 # Clamp -46ps Tsu -# Inputs: C CE D PRE \$currQ +# Inputs: C CE D PRE $abc9_currQ # Outputs: Q FDPE_1 1105 1 5 1 #0 109 -46 764 0 0 109 0 764 0 # Clamp -46ps Tsu -# Inputs: C CE D S \$currQ +# Inputs: C CE D S $abc9_currQ # Outputs: Q FDSE 1106 1 5 1 #0 109 -46 446 0 0 109 0 446 0 # Clamp -46ps Tsu -# Inputs: C CE D S \$currQ +# Inputs: C CE D S $abc9_currQ # Outputs: Q FDSE_1 1107 1 5 1 #0 109 -46 446 0 -- cgit v1.2.3 From cac7f5d82eb2760bcc248d15315b0d8460c92cb0 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 31 Dec 2019 16:12:40 -0800 Subject: Do not re-order carry chain ports, just precompute iteration order --- backends/aiger/xaiger.cc | 54 ++++++++++++++++++++++++++++-------------------- passes/techmap/abc9.cc | 22 -------------------- 2 files changed, 32 insertions(+), 44 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 650ceba7a..3e40562b7 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -93,6 +93,7 @@ struct XAigerWriter dict ordered_outputs; vector box_list; + dict> box_ports; int mkgate(int a0, int a1) { @@ -404,12 +405,34 @@ struct XAigerWriter bool blackbox = box_module->get_blackbox_attribute(true /* ignore_wb */); + auto r = box_ports.insert(cell->type); + if (r.second) { + // Make carry in the last PI, and carry out the last PO + // since ABC requires it this way + IdString carry_in, carry_out; + for (const auto &port_name : box_module->ports) { + auto w = box_module->wire(port_name); + log_assert(w); + if (w->get_bool_attribute("\\abc9_carry")) { + if (w->port_input) + carry_in = port_name; + if (w->port_output) + carry_out = port_name; + } + 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); + } + } + // 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) - for (const auto &port_name : box_module->ports) { - RTLIL::Wire* w = box_module->wire(port_name); + for (auto port_name : r.first->second) { + auto w = box_module->wire(port_name); log_assert(w); auto it = cell->connections_.find(port_name); if (w->port_input) { @@ -424,7 +447,7 @@ struct XAigerWriter cell->setPort(port_name, rhs); } - for (auto b : rhs.bits()) { + for (auto b : rhs) { SigBit I = sigmap(b); if (b == RTLIL::Sx) b = State::S0; @@ -455,11 +478,10 @@ struct XAigerWriter } for (const auto &b : rhs.bits()) { - ci_bits.emplace_back(b); SigBit O = sigmap(b); if (O != b) alias_map[O] = b; - input_bits.erase(O); + ci_bits.emplace_back(b); undriven_bits.erase(O); } } @@ -653,33 +675,21 @@ struct XAigerWriter if (box_module->has_processes()) Pass::call_on_module(module->design, box_module, "proc"); - int box_inputs = 0, box_outputs = 0; auto r = cell_cache.insert(std::make_pair(derived_name, nullptr)); Cell *holes_cell = r.first->second; if (r.second && box_module->get_bool_attribute("\\whitebox")) { holes_cell = holes_module->addCell(cell->name, cell->type); holes_cell->parameters = cell->parameters; r.first->second = holes_cell; - - // Since Module::derive() will create a new module, there - // is a chance that the ports will be alphabetically ordered - // again, which is a problem when carry-chains are involved. - // Inherit the port ordering from the original module here... - // (and set the port_id below, when iterating through those) - log_assert(GetSize(box_module->ports) == GetSize(orig_box_module->ports)); - box_module->ports = orig_box_module->ports; } - // NB: Assume box_module->ports are sorted alphabetically - // (as RTLIL::Module::fixup_ports() would do) - int box_port_id = 1; - for (const auto &port_name : box_module->ports) { + int box_inputs = 0, box_outputs = 0; + for (auto port_name : box_ports.at(cell->type)) { RTLIL::Wire *w = box_module->wire(port_name); log_assert(w); - if (r.second) - w->port_id = box_port_id++; RTLIL::Wire *holes_wire; RTLIL::SigSpec port_sig; + if (w->port_input) for (int i = 0; i < GetSize(w); i++) { box_inputs++; diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index b63a1aa6c..1ae1637bd 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -1003,28 +1003,6 @@ struct Abc9Pass : public Pass { 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(); } } -- cgit v1.2.3 From ccc0a740d254e6895b49037681bc484d6572342d Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 31 Dec 2019 16:16:05 -0800 Subject: Add some abc9 dff tests --- tests/arch/xilinx/abc9_dff.ys | 55 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 tests/arch/xilinx/abc9_dff.ys diff --git a/tests/arch/xilinx/abc9_dff.ys b/tests/arch/xilinx/abc9_dff.ys new file mode 100644 index 000000000..6611b4f18 --- /dev/null +++ b/tests/arch/xilinx/abc9_dff.ys @@ -0,0 +1,55 @@ +read_verilog < Date: Tue, 31 Dec 2019 16:50:22 -0800 Subject: parse_xaiger to reorder ports too --- frontends/aiger/aigerparse.cc | 67 +++++++++++++++++-------------------------- 1 file changed, 26 insertions(+), 41 deletions(-) diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc index 9cb05dfb3..3d00aee10 100644 --- a/frontends/aiger/aigerparse.cc +++ b/frontends/aiger/aigerparse.cc @@ -722,6 +722,7 @@ void AigerReader::post_process() { pool seen_boxes; pool flops; + dict> box_ports; unsigned ci_count = 0, co_count = 0, flop_count = 0; for (auto cell : boxes) { RTLIL::Module* box_module = design->module(cell->type); @@ -734,51 +735,35 @@ void AigerReader::post_process() flops.insert(cell->type); is_flop = true; } - 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; - } - 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 is_flop = flops.count(cell->type); - // NB: Assume box_module->ports are sorted alphabetically - // (as RTLIL::Module::fixup_ports() would do) - for (auto port_name : box_module->ports) { + 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; + } + 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); + } + } + + for (auto port_name : box_ports.at(cell->type)) { RTLIL::Wire* port = box_module->wire(port_name); log_assert(port); RTLIL::SigSpec rhs; -- cgit v1.2.3 From 96db05aaefd970c819ba1f75b7246c5958527b8b Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 31 Dec 2019 17:06:03 -0800 Subject: parse_xaiger to not take box_lookup --- backends/aiger/xaiger.cc | 15 ++++++++++++-- frontends/aiger/aigerparse.cc | 36 +++++++++++++++++---------------- frontends/aiger/aigerparse.h | 2 +- passes/techmap/abc9.cc | 47 ++++--------------------------------------- 4 files changed, 37 insertions(+), 63 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 3e40562b7..be900f0e7 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -414,14 +414,25 @@ struct XAigerWriter auto w = box_module->wire(port_name); log_assert(w); if (w->get_bool_attribute("\\abc9_carry")) { - if (w->port_input) + 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 (w->port_output) { + if (carry_out != IdString()) + log_error("Module '%s' contains more than one 'abc9_carry' output port.\n", log_id(box_module)); carry_out = port_name; + } } else r.first->second.push_back(port_name); } + + 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()) { log_assert(carry_out != IdString()); r.first->second.push_back(carry_in); diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc index 3d00aee10..f030933ec 100644 --- a/frontends/aiger/aigerparse.cc +++ b/frontends/aiger/aigerparse.cc @@ -340,7 +340,7 @@ static RTLIL::Wire* createWireIfNotExists(RTLIL::Module *module, unsigned litera return wire; } -void AigerReader::parse_xaiger(const dict &box_lookup) +void AigerReader::parse_xaiger() { std::string header; f >> header; @@ -382,6 +382,21 @@ void AigerReader::parse_xaiger(const dict &box_lookup) if (f.peek() == '\n') f.get(); + dict box_lookup; + for (auto m : design->modules()) { + auto it = m->attributes.find(ID(abc9_box_id)); + if (it == m->attributes.end()) + continue; + if (m->name.begins_with("$paramod")) + continue; + auto id = it->second.as_int(); + auto r = box_lookup.insert(std::make_pair(id, m->name)); + if (!r.second) + log_error("Module '%s' has the same abc9_box_id = %d value as '%s'.\n", + log_id(m), id, log_id(r.first->second)); + log_assert(r.second); + } + // Parse footer (symbol table, comments, etc.) std::string s; for (int c = f.get(); c != EOF; c = f.get()) { @@ -456,7 +471,7 @@ void AigerReader::parse_xaiger(const dict &box_lookup) 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)); + RTLIL::Cell* cell = module->addCell(stringf("$box%u", oldBoxNum), box_lookup.at(boxUniqueId)); boxes.emplace_back(cell); } } @@ -720,25 +735,12 @@ void AigerReader::parse_aiger_binary() void AigerReader::post_process() { - pool seen_boxes; - pool flops; dict> 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); - bool is_flop = false; - if (seen_boxes.insert(cell->type).second) { - if (box_module->attributes.count("\\abc9_flop")) { - log_assert(flop_count < flopNum); - flops.insert(cell->type); - is_flop = true; - } - } - else - is_flop = flops.count(cell->type); - auto r = box_ports.insert(cell->type); if (r.second) { // Make carry in the last PI, and carry out the last PO @@ -788,7 +790,7 @@ void AigerReader::post_process() cell->setPort(port_name, rhs); } - if (is_flop) { + if (box_module->attributes.count("\\abc9_flop")) { log_assert(co_count < outputs.size()); Wire *wire = outputs[co_count++]; log_assert(wire); @@ -900,7 +902,7 @@ void AigerReader::post_process() 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()) { 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 &box_lookup); + void parse_xaiger(); void parse_aiger_ascii(); void parse_aiger_binary(); void post_process(); diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 1ae1637bd..3c53a5223 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -251,7 +251,7 @@ struct abc9_output_filter void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string script_file, std::string exe_file, bool cleanup, vector lut_costs, std::string delay_target, std::string /*lutin_shared*/, bool fast_mode, const std::vector &/*cells*/, bool show_tempdir, std::string box_file, std::string lut_file, - std::string wire_delay, const dict &box_lookup, bool nomfs + std::string wire_delay, bool nomfs ) { map_autoidx = autoidx++; @@ -348,7 +348,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip 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); + reader.parse_xaiger(); } ifs.close(); Pass::call_on_module(design, design->module(ID($__abc9__)), stringf("write_verilog -noexpr -norename -selected")); @@ -400,7 +400,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip 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); + reader.parse_xaiger(); ifs.close(); #if 0 @@ -967,45 +967,6 @@ struct Abc9Pass : public Pass { if (!box_file.empty() && !is_absolute_path(box_file) && box_file[0] != '+') box_file = std::string(pwd) + "/" + box_file; - dict box_lookup; - for (auto m : design->modules()) { - auto it = m->attributes.find(ID(abc9_box_id)); - if (it == m->attributes.end()) - continue; - if (m->name.begins_with("$paramod")) - continue; - auto id = it->second.as_int(); - auto r = box_lookup.insert(std::make_pair(id, m->name)); - if (!r.second) - log_error("Module '%s' has the same abc9_box_id = %d value as '%s'.\n", - log_id(m), id, log_id(r.first->second)); - log_assert(r.second); - - RTLIL::Wire *carry_in = nullptr, *carry_out = nullptr; - for (auto p : m->ports) { - auto w = m->wire(p); - log_assert(w); - if (w->attributes.count(ID(abc9_carry))) { - if (w->port_input) { - if (carry_in) - log_error("Module '%s' contains more than one 'abc9_carry' input port.\n", log_id(m)); - carry_in = w; - } - else if (w->port_output) { - if (carry_out) - log_error("Module '%s' contains more than one 'abc9_carry' input port.\n", log_id(m)); - carry_out = w; - } - } - } - if (carry_in || carry_out) { - if (carry_in && !carry_out) - log_error("Module '%s' contains an 'abc9_carry' input port but no output port.\n", log_id(m)); - if (!carry_in && carry_out) - log_error("Module '%s' contains an 'abc9_carry' output port but no input port.\n", log_id(m)); - } - } - SigMap assign_map; CellTypes ct(design); for (auto module : design->selected_modules()) @@ -1056,7 +1017,7 @@ struct Abc9Pass : public Pass { design->selected_active_module = module->name.str(); abc9_module(design, module, script_file, exe_file, cleanup, lut_costs, delay_target, lutin_shared, fast_mode, all_cells, show_tempdir, - box_file, lut_file, wire_delay, box_lookup, nomfs); + box_file, lut_file, wire_delay, nomfs); design->selected_active_module.clear(); } -- cgit v1.2.3 From b2046a2114add3d24c0affd9d885b7ee320dba27 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 31 Dec 2019 18:29:29 -0800 Subject: Cleanup ecp5 boxes --- techlibs/ecp5/abc9_5g.box | 41 +++++++++++++++++------------------------ techlibs/ecp5/abc9_map.v | 19 +++++++++++-------- techlibs/ecp5/abc9_model.v | 2 +- techlibs/ecp5/abc9_unmap.v | 4 ++-- 4 files changed, 31 insertions(+), 35 deletions(-) diff --git a/techlibs/ecp5/abc9_5g.box b/techlibs/ecp5/abc9_5g.box index 2bc945a54..5c7f52ab1 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 +#$D0 $D1 $D2 $D3 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 -- cgit v1.2.3 From 2358320f5168edd691882bba0f759d82308291d6 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 31 Dec 2019 18:29:37 -0800 Subject: Cleanup ice40 boxes --- techlibs/ice40/abc9_hx.box | 24 ++++++++++++++---------- techlibs/ice40/abc9_lp.box | 24 ++++++++++++++---------- techlibs/ice40/abc9_u.box | 25 +++++++++++++++---------- 3 files changed, 43 insertions(+), 30 deletions(-) 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 -- cgit v1.2.3 From 35c659be74396db7824bc98428137dc9a5ac1d16 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 31 Dec 2019 18:29:44 -0800 Subject: Cleanup xilinx boxes --- techlibs/xilinx/abc9_map.v | 3 + techlibs/xilinx/abc9_xc7.box | 813 ++++++++++++++++++++++--------------------- 2 files changed, 425 insertions(+), 391 deletions(-) diff --git a/techlibs/xilinx/abc9_map.v b/techlibs/xilinx/abc9_map.v index a3f9e311e..4ab8e1564 100644 --- a/techlibs/xilinx/abc9_map.v +++ b/techlibs/xilinx/abc9_map.v @@ -462,6 +462,9 @@ module FDSE_1 (output Q, input C, CE, D, S); `endif endmodule +// 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, diff --git a/techlibs/xilinx/abc9_xc7.box b/techlibs/xilinx/abc9_xc7.box index 67523124a..302487041 100644 --- a/techlibs/xilinx/abc9_xc7.box +++ b/techlibs/xilinx/abc9_xc7.box @@ -5,126 +5,138 @@ # 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 -$__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 +# 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 to emulate async behaviour of FDC* -# Inputs: A S -# Outputs: Y -$__ABC9_ASYNC0 1000 1 2 1 -0 764 +# 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 to emulate async behaviour of FDP* -# Inputs: A S -# Outputs: 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 -0 764 +#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 -# Inputs: C CE D R $abc9_currQ -# Outputs: Q -FDRE 1100 1 5 1 +# 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 # Clamp -46ps Tsu +0 109 0 404 0 # Q (-46ps Tsu clamped to 0) -# Inputs: C CE D R $abc9_currQ -# Outputs: Q -FDRE_1 1101 1 5 1 -#0 109 0 -46 404 -0 109 0 0 404 # Clamp -46ps Tsu +# 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) -# Inputs: C CE CLR D $abc9_currQ -# Outputs: Q -FDCE 1102 1 5 1 +# Box 1102 : FDCE +# name ID w/b ins outs +FDCE 1102 1 5 1 +#C CE CLR D $abc9_currQ #0 109 764 -46 0 -0 109 764 0 0 # Clamp -46ps Tsu +0 109 764 0 0 # Q (-46ps Tsu clamped to 0) -# Inputs: C CE CLR D $abc9_currQ -# Outputs: Q -FDCE_1 1103 1 5 1 +# Box 1103 : FDCE_1 +# name ID w/b ins outs +FDCE_1 1103 1 5 1 +#C CE CLR D $abc9_currQ #0 109 764 -46 0 -0 109 764 0 0 # Clamp -46ps Tsu +0 109 764 0 0 # Q (-46ps Tsu clamped to 0) -# Inputs: C CE D PRE $abc9_currQ -# Outputs: Q -FDPE 1104 1 5 1 +# Box 1104 : FDPE +# name ID w/b ins outs +FDPE 1104 1 5 1 +#C CE D PRE $abc9_currQ #0 109 -46 764 0 -0 109 0 764 0 # Clamp -46ps Tsu +0 109 -46 764 0 # Q (-46ps Tsu clamped to 0) -# Inputs: C CE D PRE $abc9_currQ -# Outputs: Q -FDPE_1 1105 1 5 1 +# Box 1105 : FDPE_1 +# name ID w/b ins outs +FDPE_1 1105 1 5 1 +#C CE D PRE $abc9_currQ #0 109 -46 764 0 -0 109 0 764 0 # Clamp -46ps Tsu +0 109 -46 764 0 # Q (-46ps Tsu clamped to 0) -# Inputs: C CE D S $abc9_currQ -# Outputs: Q -FDSE 1106 1 5 1 -#0 109 -46 446 0 -0 109 0 446 0 # Clamp -46ps Tsu +# Box 1106 : FDSE +# name ID w/b ins outs +FDSE 1106 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) -# Inputs: C CE D S $abc9_currQ -# Outputs: Q -FDSE_1 1107 1 5 1 -#0 109 -46 446 0 -0 109 0 446 0 # Clamp -46ps Tsu +# Box 1107 : FDSE_1 +# name ID w/b ins outs +FDSE_1 1107 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 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: Y +# 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 @@ -136,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 - @@ -701,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 - @@ -965,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 - -- cgit v1.2.3 From c082329af33cd428f53f5afbcb51fab8de545090 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 31 Dec 2019 18:39:32 -0800 Subject: Call equiv_opt with -multiclock and -assert --- tests/arch/anlogic/counter.ys | 2 +- tests/arch/ecp5/counter.ys | 2 +- tests/arch/efinix/counter.ys | 2 +- tests/arch/gowin/counter.ys | 2 +- tests/arch/ice40/counter.ys | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) 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/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/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/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 -- cgit v1.2.3 From a59016b146e91311324bc87f9a9437d7ff31d9f2 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 31 Dec 2019 18:40:11 -0800 Subject: Fix warnings --- tests/arch/ice40/mul.ys | 2 +- tests/arch/ice40/rom.v | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) 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..c4c677c1e 100644 --- a/tests/arch/ice40/rom.v +++ b/tests/arch/ice40/rom.v @@ -2,7 +2,7 @@ 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 reg [3:0] data; input [4:0] addr; always @(addr) begin case (addr) -- cgit v1.2.3 From 713484fa66da705d2a274cdea590bd4634f48d5d Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 31 Dec 2019 18:40:30 -0800 Subject: Do not do call equiv_opt when no sim model exists --- tests/arch/ecp5/macc.ys | 4 ++-- tests/arch/ecp5/mul.ys | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) 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 -- cgit v1.2.3 From f7793a29564881245239e81326e0c7afeb15f6e9 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 31 Dec 2019 18:42:11 -0800 Subject: Missing character --- techlibs/ecp5/abc9_5g.box | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/techlibs/ecp5/abc9_5g.box b/techlibs/ecp5/abc9_5g.box index 5c7f52ab1..f153a665e 100644 --- a/techlibs/ecp5/abc9_5g.box +++ b/techlibs/ecp5/abc9_5g.box @@ -17,7 +17,7 @@ CCU2C 1 1 9 3 # Box 2 : TRELLIS_DPR16X4_COMB (16x4 dist ram) # name ID w/b ins outs $__ABC9_DPR16X4_COMB 2 0 8 4 -#$D0 $D1 $D2 $D3 RAD0 RAD1 RAD2 RAD3 +#$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 -- cgit v1.2.3 From 44d9fb0e7cee7d8986ed037429e3c9fdd1b29ba1 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 31 Dec 2019 18:47:38 -0800 Subject: Re-arrange FD order --- techlibs/xilinx/abc9_map.v | 166 +++++++++++++++++++++---------------------- techlibs/xilinx/abc9_xc7.box | 44 ++++++------ techlibs/xilinx/cells_sim.v | 154 +++++++++++++++++++-------------------- 3 files changed, 182 insertions(+), 182 deletions(-) diff --git a/techlibs/xilinx/abc9_map.v b/techlibs/xilinx/abc9_map.v index 4ab8e1564..6d93e508f 100644 --- a/techlibs/xilinx/abc9_map.v +++ b/techlibs/xilinx/abc9_map.v @@ -163,6 +163,89 @@ module FDRE_1 (output Q, input C, CE, D, R); `endif 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; +`ifdef DFF_MODE + 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_ abc_dff (.D($Q), .Q(QQ)); + + // Special signals + wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, IS_C_INVERTED}; + wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; + wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = QQ; +`else + (* abc9_keep *) + FDSE #( + .INIT(INIT), + .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) + ); +`endif +endmodule +module FDSE_1 (output Q, input C, CE, D, S); + parameter [0:0] INIT = 1'b1; +`ifdef DFF_MODE + 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_ abc_dff (.D($Q), .Q(QQ)); + + // Special signals + wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */}; + wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; + wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = QQ; +`else + (* abc9_keep *) + FDSE_1 #( + .INIT(INIT) + ) _TECHMAP_REPLACE_ ( + .D(D), .Q(Q), .C(C), .CE(CE), .S(S) + ); +`endif +endmodule + module FDCE (output Q, input C, CE, D, CLR); parameter [0:0] INIT = 1'b0; parameter [0:0] IS_C_INVERTED = 1'b0; @@ -379,89 +462,6 @@ module FDPE_1 (output Q, input C, CE, D, PRE); `endif 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; -`ifdef DFF_MODE - 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_ abc_dff (.D($Q), .Q(QQ)); - - // Special signals - wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, IS_C_INVERTED}; - wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; - wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = QQ; -`else - (* abc9_keep *) - FDSE #( - .INIT(INIT), - .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) - ); -`endif -endmodule -module FDSE_1 (output Q, input C, CE, D, S); - parameter [0:0] INIT = 1'b1; -`ifdef DFF_MODE - 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_ abc_dff (.D($Q), .Q(QQ)); - - // Special signals - wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */}; - wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; - wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = QQ; -`else - (* abc9_keep *) - FDSE_1 #( - .INIT(INIT) - ) _TECHMAP_REPLACE_ ( - .D(D), .Q(Q), .C(C), .CE(CE), .S(S) - ); -`endif -endmodule - // Attach a (combinatorial) black-box onto the output // of thes LUTRAM primitives to capture their // asynchronous read behaviour diff --git a/techlibs/xilinx/abc9_xc7.box b/techlibs/xilinx/abc9_xc7.box index 302487041..43c39544e 100644 --- a/techlibs/xilinx/abc9_xc7.box +++ b/techlibs/xilinx/abc9_xc7.box @@ -81,48 +81,48 @@ FDRE_1 1101 1 5 1 #0 109 -46 404 0 0 109 0 404 0 # Q (-46ps Tsu clamped to 0) -# Box 1102 : FDCE +# Box 1102 : FDSE # name ID w/b ins outs -FDCE 1102 1 5 1 +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 1103 : FDCE_1 +# Box 1105 : FDCE_1 # name ID w/b ins outs -FDCE_1 1103 1 5 1 +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 1104 : FDPE +# Box 1106 : FDPE # name ID w/b ins outs -FDPE 1104 1 5 1 +FDPE 1106 1 5 1 #C CE D PRE $abc9_currQ #0 109 -46 764 0 0 109 -46 764 0 # Q (-46ps Tsu clamped to 0) -# Box 1105 : FDPE_1 +# Box 1107 : FDPE_1 # name ID w/b ins outs -FDPE_1 1105 1 5 1 +FDPE_1 1107 1 5 1 #C CE D PRE $abc9_currQ #0 109 -46 764 0 0 109 -46 764 0 # Q (-46ps Tsu clamped to 0) -# Box 1106 : FDSE -# name ID w/b ins outs -FDSE 1106 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 1107 : FDSE_1 -# name ID w/b ins outs -FDSE_1 1107 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 2000 : $__ABC9_LUT6 # (private cell to emulate async behaviour of LUTRAMs) # SLICEM/A6LUT diff --git a/techlibs/xilinx/cells_sim.v b/techlibs/xilinx/cells_sim.v index 982ccad72..c22bcdc27 100644 --- a/techlibs/xilinx/cells_sim.v +++ b/techlibs/xilinx/cells_sim.v @@ -362,6 +362,43 @@ module FDRE_1 ( 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, + (* clkbuf_sink *) + (* invertible_pin = "IS_C_INVERTED" *) + input C, + input CE, + (* invertible_pin = "IS_D_INVERTED" *) + input D, + (* invertible_pin = "IS_S_INVERTED" *) + input 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; + initial Q <= INIT; + generate case (|IS_C_INVERTED) + 1'b0: always @(posedge C) if (S == !IS_S_INVERTED) Q <= 1'b1; else if (CE) Q <= D ^ IS_D_INVERTED; + 1'b1: always @(negedge C) if (S == !IS_S_INVERTED) Q <= 1'b1; else if (CE) Q <= D ^ IS_D_INVERTED; + 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 *) @@ -397,7 +434,7 @@ module FDRSE ( Q <= d; endmodule -(* abc9_box_id=1102, lib_whitebox, abc9_flop *) +(* abc9_box_id=1104, lib_whitebox, abc9_flop *) module FDCE ( (* abc9_arrival=303 *) output reg Q, @@ -423,7 +460,7 @@ module FDCE ( endcase endgenerate endmodule -(* abc9_box_id=1103, lib_whitebox, abc9_flop *) +(* abc9_box_id=1105, lib_whitebox, abc9_flop *) module FDCE_1 ( (* abc9_arrival=303 *) output reg Q, @@ -436,52 +473,7 @@ module FDCE_1 ( always @(negedge C, posedge CLR) if (CLR) Q <= 1'b0; else if (CE) Q <= D; endmodule -module FDCPE ( - output wire Q, - (* clkbuf_sink *) - (* invertible_pin = "IS_C_INVERTED" *) - input C, - input CE, - (* invertible_pin = "IS_CLR_INVERTED" *) - input CLR, - input D, - (* invertible_pin = "IS_PRE_INVERTED" *) - input PRE -); - parameter [0:0] INIT = 1'b0; - parameter [0:0] IS_C_INVERTED = 1'b0; - parameter [0:0] IS_CLR_INVERTED = 1'b0; - parameter [0:0] IS_PRE_INVERTED = 1'b0; - wire c = C ^ IS_C_INVERTED; - wire clr = CLR ^ IS_CLR_INVERTED; - wire pre = PRE ^ IS_PRE_INVERTED; - // Hacky model to avoid simulation-synthesis mismatches. - reg qc, qp, qs; - initial qc = INIT; - initial qp = INIT; - initial qs = 0; - always @(posedge c, posedge clr) begin - if (clr) - qc <= 0; - else if (CE) - qc <= D; - end - always @(posedge c, posedge pre) begin - if (pre) - qp <= 1; - else if (CE) - qp <= D; - end - always @* begin - if (clr) - qs <= 0; - else if (pre) - qs <= 1; - end - assign Q = qs ? qp : qc; -endmodule - -(* abc9_box_id=1104, lib_whitebox, abc9_flop *) +(* abc9_box_id=1106, lib_whitebox, abc9_flop *) module FDPE ( (* abc9_arrival=303 *) output reg Q, @@ -507,7 +499,7 @@ module FDPE ( endcase endgenerate endmodule -(* abc9_box_id=1105, lib_whitebox, abc9_flop *) +(* abc9_box_id=1107, lib_whitebox, abc9_flop *) module FDPE_1 ( (* abc9_arrival=303 *) output reg Q, @@ -520,41 +512,49 @@ module FDPE_1 ( always @(negedge C, posedge PRE) if (PRE) Q <= 1'b1; else if (CE) Q <= D; endmodule -(* abc9_box_id=1106, lib_whitebox, abc9_flop *) -module FDSE ( - (* abc9_arrival=303 *) - output reg Q, +module FDCPE ( + output wire Q, (* clkbuf_sink *) (* invertible_pin = "IS_C_INVERTED" *) input C, input CE, - (* invertible_pin = "IS_D_INVERTED" *) + (* invertible_pin = "IS_CLR_INVERTED" *) + input CLR, input D, - (* invertible_pin = "IS_S_INVERTED" *) - input S + (* invertible_pin = "IS_PRE_INVERTED" *) + input PRE ); - parameter [0:0] INIT = 1'b1; + 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_S_INVERTED = 1'b0; - initial Q <= INIT; - generate case (|IS_C_INVERTED) - 1'b0: always @(posedge C) if (S == !IS_S_INVERTED) Q <= 1'b1; else if (CE) Q <= D ^ IS_D_INVERTED; - 1'b1: always @(negedge C) if (S == !IS_S_INVERTED) Q <= 1'b1; else if (CE) Q <= D ^ IS_D_INVERTED; - endcase endgenerate -endmodule - -(* abc9_box_id=1107, 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; + parameter [0:0] IS_CLR_INVERTED = 1'b0; + parameter [0:0] IS_PRE_INVERTED = 1'b0; + wire c = C ^ IS_C_INVERTED; + wire clr = CLR ^ IS_CLR_INVERTED; + wire pre = PRE ^ IS_PRE_INVERTED; + // Hacky model to avoid simulation-synthesis mismatches. + reg qc, qp, qs; + initial qc = INIT; + initial qp = INIT; + initial qs = 0; + always @(posedge c, posedge clr) begin + if (clr) + qc <= 0; + else if (CE) + qc <= D; + end + always @(posedge c, posedge pre) begin + if (pre) + qp <= 1; + else if (CE) + qp <= D; + end + always @* begin + if (clr) + qs <= 0; + else if (pre) + qs <= 1; + end + assign Q = qs ? qp : qc; endmodule module LDCE ( -- cgit v1.2.3 From 550310e2647c7aac1e49b79d9ff912436103062f Mon Sep 17 00:00:00 2001 From: whitequark Date: Wed, 1 Jan 2020 12:30:00 +0000 Subject: Harmonize BRAM/LUTRAM descriptions across all of Yosys. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit: * renames all remaining instances of "DRAM" (which is ambiguous) to "LUTRAM" (which is not), finishing the work started in the commit 698ab9be; * renames memory rule files to brams.txt/lutrams.txt; * adds/renames script labels map_bram/map_lutram; * extracts where necessary script labels map_ffram and map_gates; * adds where necessary options -nobram/-nolutram. The end result is that BRAM/LUTRAM/FFRAM aspects of every target are now consistent with each other. Per architecture: * anlogic: rename drams.txt→lutrams.txt, add -nolutram, add :map_lutram, :map_ffram, :map_gates * ecp5: rename bram.txt→brams.txt, lutram.txt→lutrams.txt * efinix: rename bram.txt→brams.txt, add -nobram, add :map_ffram, :map_gates * gowin: rename bram.txt→brams.txt, dram.txt→lutrams.txt, rename -nodram→-nolutram (-nodram still recognized), rename :bram→:map_bram, :dram→:map_lutram, add :map_ffram, :map_gates --- techlibs/anlogic/Makefile.inc | 6 ++--- techlibs/anlogic/dram_init_16x4.vh | 16 ----------- techlibs/anlogic/drams.txt | 16 ----------- techlibs/anlogic/drams_map.v | 22 --------------- techlibs/anlogic/lutram_init_16x4.vh | 16 +++++++++++ techlibs/anlogic/lutrams.txt | 16 +++++++++++ techlibs/anlogic/lutrams_map.v | 22 +++++++++++++++ techlibs/anlogic/synth_anlogic.cc | 24 ++++++++++++----- techlibs/ecp5/Makefile.inc | 4 +-- techlibs/ecp5/bram.txt | 52 ------------------------------------ techlibs/ecp5/brams.txt | 52 ++++++++++++++++++++++++++++++++++++ techlibs/ecp5/lutram.txt | 17 ------------ techlibs/ecp5/lutrams.txt | 17 ++++++++++++ techlibs/ecp5/synth_ecp5.cc | 4 +-- techlibs/efinix/Makefile.inc | 2 +- techlibs/efinix/bram.txt | 32 ---------------------- techlibs/efinix/brams.txt | 32 ++++++++++++++++++++++ techlibs/efinix/synth_efinix.cc | 22 +++++++++++---- techlibs/gowin/Makefile.inc | 6 ++--- techlibs/gowin/bram.txt | 31 --------------------- techlibs/gowin/brams.txt | 31 +++++++++++++++++++++ techlibs/gowin/dram.txt | 17 ------------ techlibs/gowin/drams_map.v | 31 --------------------- techlibs/gowin/lutrams.txt | 17 ++++++++++++ techlibs/gowin/lutrams_map.v | 31 +++++++++++++++++++++ techlibs/gowin/synth_gowin.cc | 27 ++++++++++--------- techlibs/intel/synth_intel.cc | 10 +++---- 27 files changed, 300 insertions(+), 273 deletions(-) delete mode 100644 techlibs/anlogic/dram_init_16x4.vh delete mode 100644 techlibs/anlogic/drams.txt delete mode 100644 techlibs/anlogic/drams_map.v create mode 100644 techlibs/anlogic/lutram_init_16x4.vh create mode 100644 techlibs/anlogic/lutrams.txt create mode 100644 techlibs/anlogic/lutrams_map.v delete mode 100644 techlibs/ecp5/bram.txt create mode 100644 techlibs/ecp5/brams.txt delete mode 100644 techlibs/ecp5/lutram.txt create mode 100644 techlibs/ecp5/lutrams.txt delete mode 100644 techlibs/efinix/bram.txt create mode 100644 techlibs/efinix/brams.txt delete mode 100644 techlibs/gowin/bram.txt create mode 100644 techlibs/gowin/brams.txt delete mode 100644 techlibs/gowin/dram.txt delete mode 100644 techlibs/gowin/drams_map.v create mode 100644 techlibs/gowin/lutrams.txt create mode 100644 techlibs/gowin/lutrams_map.v 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/dram_init_16x4.vh b/techlibs/anlogic/dram_init_16x4.vh deleted file mode 100644 index 32fb1578c..000000000 --- a/techlibs/anlogic/dram_init_16x4.vh +++ /dev/null @@ -1,16 +0,0 @@ -.INIT_D0({INIT[15*4+0], INIT[14*4+0], INIT[13*4+0], INIT[12*4+0], - INIT[11*4+0], INIT[10*4+0], INIT[9*4+0], INIT[8*4+0], - INIT[7*4+0], INIT[6*4+0], INIT[5*4+0], INIT[4*4+0], - INIT[3*4+0], INIT[2*4+0], INIT[1*4+0], INIT[0*4+0]}), -.INIT_D1({INIT[15*4+1], INIT[14*4+1], INIT[13*4+1], INIT[12*4+1], - INIT[11*4+1], INIT[10*4+1], INIT[9*4+1], INIT[8*4+1], - INIT[7*4+1], INIT[6*4+1], INIT[5*4+1], INIT[4*4+1], - INIT[3*4+1], INIT[2*4+1], INIT[1*4+1], INIT[0*4+1]}), -.INIT_D2({INIT[15*4+2], INIT[14*4+2], INIT[13*4+2], INIT[12*4+2], - INIT[11*4+2], INIT[10*4+2], INIT[9*4+2], INIT[8*4+2], - INIT[7*4+2], INIT[6*4+2], INIT[5*4+2], INIT[4*4+2], - INIT[3*4+2], INIT[2*4+2], INIT[1*4+2], INIT[0*4+2]}), -.INIT_D3({INIT[15*4+3], INIT[14*4+3], INIT[13*4+3], INIT[12*4+3], - INIT[11*4+3], INIT[10*4+3], INIT[9*4+3], INIT[8*4+3], - INIT[7*4+3], INIT[6*4+3], INIT[5*4+3], INIT[4*4+3], - INIT[3*4+3], INIT[2*4+3], INIT[1*4+3], INIT[0*4+3]}) diff --git a/techlibs/anlogic/drams.txt b/techlibs/anlogic/drams.txt deleted file mode 100644 index 4e903c0a2..000000000 --- a/techlibs/anlogic/drams.txt +++ /dev/null @@ -1,16 +0,0 @@ -bram $__ANLOGIC_DRAM16X4 - init 1 - abits 4 - dbits 4 - groups 2 - ports 1 1 - wrmode 0 1 - enable 0 1 - transp 0 0 - clocks 0 1 - clkpol 0 1 -endbram - -match $__ANLOGIC_DRAM16X4 - make_outreg -endmatch diff --git a/techlibs/anlogic/drams_map.v b/techlibs/anlogic/drams_map.v deleted file mode 100644 index 084e2a25f..000000000 --- a/techlibs/anlogic/drams_map.v +++ /dev/null @@ -1,22 +0,0 @@ -module \$__ANLOGIC_DRAM16X4 (CLK1, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN); - parameter [63:0]INIT = 64'bx; - input CLK1; - - input [3:0] A1ADDR; - output [3:0] A1DATA; - - input [3:0] B1ADDR; - input [3:0] B1DATA; - input B1EN; - - EG_LOGIC_DRAM16X4 #( - `include "dram_init_16x4.vh" - ) _TECHMAP_REPLACE_ ( - .di(B1DATA), - .waddr(B1ADDR), - .wclk(CLK1), - .we(B1EN), - .raddr(A1ADDR), - .do(A1DATA) - ); -endmodule diff --git a/techlibs/anlogic/lutram_init_16x4.vh b/techlibs/anlogic/lutram_init_16x4.vh new file mode 100644 index 000000000..32fb1578c --- /dev/null +++ b/techlibs/anlogic/lutram_init_16x4.vh @@ -0,0 +1,16 @@ +.INIT_D0({INIT[15*4+0], INIT[14*4+0], INIT[13*4+0], INIT[12*4+0], + INIT[11*4+0], INIT[10*4+0], INIT[9*4+0], INIT[8*4+0], + INIT[7*4+0], INIT[6*4+0], INIT[5*4+0], INIT[4*4+0], + INIT[3*4+0], INIT[2*4+0], INIT[1*4+0], INIT[0*4+0]}), +.INIT_D1({INIT[15*4+1], INIT[14*4+1], INIT[13*4+1], INIT[12*4+1], + INIT[11*4+1], INIT[10*4+1], INIT[9*4+1], INIT[8*4+1], + INIT[7*4+1], INIT[6*4+1], INIT[5*4+1], INIT[4*4+1], + INIT[3*4+1], INIT[2*4+1], INIT[1*4+1], INIT[0*4+1]}), +.INIT_D2({INIT[15*4+2], INIT[14*4+2], INIT[13*4+2], INIT[12*4+2], + INIT[11*4+2], INIT[10*4+2], INIT[9*4+2], INIT[8*4+2], + INIT[7*4+2], INIT[6*4+2], INIT[5*4+2], INIT[4*4+2], + INIT[3*4+2], INIT[2*4+2], INIT[1*4+2], INIT[0*4+2]}), +.INIT_D3({INIT[15*4+3], INIT[14*4+3], INIT[13*4+3], INIT[12*4+3], + INIT[11*4+3], INIT[10*4+3], INIT[9*4+3], INIT[8*4+3], + INIT[7*4+3], INIT[6*4+3], INIT[5*4+3], INIT[4*4+3], + INIT[3*4+3], INIT[2*4+3], INIT[1*4+3], INIT[0*4+3]}) diff --git a/techlibs/anlogic/lutrams.txt b/techlibs/anlogic/lutrams.txt new file mode 100644 index 000000000..4e903c0a2 --- /dev/null +++ b/techlibs/anlogic/lutrams.txt @@ -0,0 +1,16 @@ +bram $__ANLOGIC_DRAM16X4 + init 1 + abits 4 + dbits 4 + groups 2 + ports 1 1 + wrmode 0 1 + enable 0 1 + transp 0 0 + clocks 0 1 + clkpol 0 1 +endbram + +match $__ANLOGIC_DRAM16X4 + make_outreg +endmatch diff --git a/techlibs/anlogic/lutrams_map.v b/techlibs/anlogic/lutrams_map.v new file mode 100644 index 000000000..5a464cafc --- /dev/null +++ b/techlibs/anlogic/lutrams_map.v @@ -0,0 +1,22 @@ +module \$__ANLOGIC_DRAM16X4 (CLK1, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN); + parameter [63:0]INIT = 64'bx; + input CLK1; + + input [3:0] A1ADDR; + output [3:0] A1DATA; + + input [3:0] B1ADDR; + input [3:0] B1DATA; + input B1EN; + + EG_LOGIC_DRAM16X4 #( + `include "lutram_init_16x4.vh" + ) _TECHMAP_REPLACE_ ( + .di(B1DATA), + .waddr(B1ADDR), + .wclk(CLK1), + .we(B1EN), + .raddr(A1ADDR), + .do(A1DATA) + ); +endmodule diff --git a/techlibs/anlogic/synth_anlogic.cc b/techlibs/anlogic/synth_anlogic.cc index b87fc8566..3a1992588 100644 --- a/techlibs/anlogic/synth_anlogic.cc +++ b/techlibs/anlogic/synth_anlogic.cc @@ -60,6 +60,9 @@ struct SynthAnlogicPass : public ScriptPass log(" -retime\n"); log(" run 'abc' with -dff option\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"); help_script(); @@ -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 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,18 +158,22 @@ 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)"); @@ -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/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/bram.txt b/techlibs/ecp5/bram.txt deleted file mode 100644 index 777ccaa2e..000000000 --- a/techlibs/ecp5/bram.txt +++ /dev/null @@ -1,52 +0,0 @@ -bram $__ECP5_PDPW16KD - init 1 - - abits 9 - dbits 36 - - groups 2 - ports 1 1 - wrmode 1 0 - enable 4 1 - transp 0 0 - clocks 2 3 - clkpol 2 3 -endbram - -bram $__ECP5_DP16KD - init 1 - - abits 10 @a10d18 - dbits 18 @a10d18 - abits 11 @a11d9 - dbits 9 @a11d9 - abits 12 @a12d4 - dbits 4 @a12d4 - abits 13 @a13d2 - dbits 2 @a13d2 - abits 14 @a14d1 - dbits 1 @a14d1 - - groups 2 - ports 1 1 - wrmode 1 0 - enable 2 1 @a10d18 - enable 1 1 @a11d9 @a12d4 @a13d2 @a14d1 - transp 0 2 - clocks 2 3 - clkpol 2 3 -endbram - -match $__ECP5_PDPW16KD - min bits 2048 - min efficiency 5 - shuffle_enable A - make_transp - or_next_if_better -endmatch - -match $__ECP5_DP16KD - min bits 2048 - min efficiency 5 - shuffle_enable A -endmatch diff --git a/techlibs/ecp5/brams.txt b/techlibs/ecp5/brams.txt new file mode 100644 index 000000000..777ccaa2e --- /dev/null +++ b/techlibs/ecp5/brams.txt @@ -0,0 +1,52 @@ +bram $__ECP5_PDPW16KD + init 1 + + abits 9 + dbits 36 + + groups 2 + ports 1 1 + wrmode 1 0 + enable 4 1 + transp 0 0 + clocks 2 3 + clkpol 2 3 +endbram + +bram $__ECP5_DP16KD + init 1 + + abits 10 @a10d18 + dbits 18 @a10d18 + abits 11 @a11d9 + dbits 9 @a11d9 + abits 12 @a12d4 + dbits 4 @a12d4 + abits 13 @a13d2 + dbits 2 @a13d2 + abits 14 @a14d1 + dbits 1 @a14d1 + + groups 2 + ports 1 1 + wrmode 1 0 + enable 2 1 @a10d18 + enable 1 1 @a11d9 @a12d4 @a13d2 @a14d1 + transp 0 2 + clocks 2 3 + clkpol 2 3 +endbram + +match $__ECP5_PDPW16KD + min bits 2048 + min efficiency 5 + shuffle_enable A + make_transp + or_next_if_better +endmatch + +match $__ECP5_DP16KD + min bits 2048 + min efficiency 5 + shuffle_enable A +endmatch diff --git a/techlibs/ecp5/lutram.txt b/techlibs/ecp5/lutram.txt deleted file mode 100644 index b94357429..000000000 --- a/techlibs/ecp5/lutram.txt +++ /dev/null @@ -1,17 +0,0 @@ -bram $__TRELLIS_DPR16X4 - init 1 - abits 4 - dbits 4 - groups 2 - ports 1 1 - wrmode 0 1 - enable 0 1 - transp 0 0 - clocks 0 1 - clkpol 0 2 -endbram - -match $__TRELLIS_DPR16X4 - make_outreg - min wports 1 -endmatch diff --git a/techlibs/ecp5/lutrams.txt b/techlibs/ecp5/lutrams.txt new file mode 100644 index 000000000..b94357429 --- /dev/null +++ b/techlibs/ecp5/lutrams.txt @@ -0,0 +1,17 @@ +bram $__TRELLIS_DPR16X4 + init 1 + abits 4 + dbits 4 + groups 2 + ports 1 1 + wrmode 0 1 + enable 0 1 + transp 0 0 + clocks 0 1 + clkpol 0 2 +endbram + +match $__TRELLIS_DPR16X4 + make_outreg + min wports 1 +endmatch diff --git a/techlibs/ecp5/synth_ecp5.cc b/techlibs/ecp5/synth_ecp5.cc index a0ea6d1f9..3985da57a 100644 --- a/techlibs/ecp5/synth_ecp5.cc +++ b/techlibs/ecp5/synth_ecp5.cc @@ -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"); } 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/bram.txt deleted file mode 100644 index 0b3fd9308..000000000 --- a/techlibs/efinix/bram.txt +++ /dev/null @@ -1,32 +0,0 @@ -bram $__EFINIX_5K - init 1 - - abits 8 @a8d16 - dbits 16 @a8d16 - abits 9 @a9d8 - dbits 8 @a9d8 - abits 10 @a10d4 - dbits 4 @a10d4 - abits 11 @a11d2 - dbits 2 @a11d2 - abits 12 @a12d1 - dbits 1 @a12d1 - abits 8 @a8d20 - dbits 20 @a8d20 - abits 9 @a9d10 - dbits 10 @a9d10 - - groups 2 - ports 1 1 - wrmode 1 0 - enable 1 1 - transp 0 2 - clocks 2 3 - clkpol 2 3 -endbram - -match $__EFINIX_5K - min bits 256 - min efficiency 5 - shuffle_enable B -endmatch diff --git a/techlibs/efinix/brams.txt b/techlibs/efinix/brams.txt new file mode 100644 index 000000000..0b3fd9308 --- /dev/null +++ b/techlibs/efinix/brams.txt @@ -0,0 +1,32 @@ +bram $__EFINIX_5K + init 1 + + abits 8 @a8d16 + dbits 16 @a8d16 + abits 9 @a9d8 + dbits 8 @a9d8 + abits 10 @a10d4 + dbits 4 @a10d4 + abits 11 @a11d2 + dbits 2 @a11d2 + abits 12 @a12d1 + dbits 1 @a12d1 + abits 8 @a8d20 + dbits 20 @a8d20 + abits 9 @a9d10 + dbits 10 @a9d10 + + groups 2 + ports 1 1 + wrmode 1 0 + enable 1 1 + transp 0 2 + clocks 2 3 + clkpol 2 3 +endbram + +match $__EFINIX_5K + min bits 256 + min efficiency 5 + shuffle_enable B +endmatch diff --git a/techlibs/efinix/synth_efinix.cc b/techlibs/efinix/synth_efinix.cc index 26a8d4eda..3e5274385 100644 --- a/techlibs/efinix/synth_efinix.cc +++ b/techlibs/efinix/synth_efinix.cc @@ -60,6 +60,9 @@ struct SynthEfinixPass : public ScriptPass log(" -retime\n"); log(" run 'abc' with -dff option\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"); help_script(); @@ -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 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,18 +158,22 @@ 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)"); @@ -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/bram.txt deleted file mode 100644 index e406f9c51..000000000 --- a/techlibs/gowin/bram.txt +++ /dev/null @@ -1,31 +0,0 @@ -bram $__GW1NR_SDP - init 1 - abits 9 @a9d36 - dbits 32 @a9d36 - abits 10 @a10d18 - dbits 16 @a10d18 - abits 11 @a11d9 - dbits 8 @a11d9 - abits 12 @a12d4 - dbits 4 @a12d4 - abits 13 @a13d2 - dbits 2 @a13d2 - abits 14 @a14d1 - dbits 1 @a14d1 - groups 2 - ports 1 1 - wrmode 1 0 - enable 4 1 @a9d36 - enable 2 1 @a10d18 - enable 1 1 @a11d9 @a12d4 @a13d2 @a14d1 - transp 0 0 - clocks 2 3 - clkpol 2 3 -endbram - -match $__GW1NR_SDP - min bits 2048 - min efficiency 5 - shuffle_enable A - make_transp -endmatch diff --git a/techlibs/gowin/brams.txt b/techlibs/gowin/brams.txt new file mode 100644 index 000000000..e406f9c51 --- /dev/null +++ b/techlibs/gowin/brams.txt @@ -0,0 +1,31 @@ +bram $__GW1NR_SDP + init 1 + abits 9 @a9d36 + dbits 32 @a9d36 + abits 10 @a10d18 + dbits 16 @a10d18 + abits 11 @a11d9 + dbits 8 @a11d9 + abits 12 @a12d4 + dbits 4 @a12d4 + abits 13 @a13d2 + dbits 2 @a13d2 + abits 14 @a14d1 + dbits 1 @a14d1 + groups 2 + ports 1 1 + wrmode 1 0 + enable 4 1 @a9d36 + enable 2 1 @a10d18 + enable 1 1 @a11d9 @a12d4 @a13d2 @a14d1 + transp 0 0 + clocks 2 3 + clkpol 2 3 +endbram + +match $__GW1NR_SDP + min bits 2048 + min efficiency 5 + shuffle_enable A + make_transp +endmatch diff --git a/techlibs/gowin/dram.txt b/techlibs/gowin/dram.txt deleted file mode 100644 index 9db530251..000000000 --- a/techlibs/gowin/dram.txt +++ /dev/null @@ -1,17 +0,0 @@ -bram $__GW1NR_RAM16S4 - init 1 - abits 4 - dbits 4 - groups 2 - ports 1 1 - wrmode 0 1 - enable 0 1 - transp 0 1 - clocks 0 1 - clkpol 0 1 -endbram - -match $__GW1NR_RAM16S4 - make_outreg - min wports 1 -endmatch diff --git a/techlibs/gowin/drams_map.v b/techlibs/gowin/drams_map.v deleted file mode 100644 index a50ab365a..000000000 --- a/techlibs/gowin/drams_map.v +++ /dev/null @@ -1,31 +0,0 @@ -module \$__GW1NR_RAM16S4 (CLK1, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN); - parameter CFG_ABITS = 4; - parameter CFG_DBITS = 4; - - parameter [63:0] INIT = 64'bx; - input CLK1; - - input [CFG_ABITS-1:0] A1ADDR; - output [CFG_DBITS-1:0] A1DATA; - input A1EN; - - input [CFG_ABITS-1:0] B1ADDR; - input [CFG_DBITS-1:0] B1DATA; - input B1EN; - - `include "brams_init3.vh" - - RAM16S4 - #(.INIT_0(INIT_0), - .INIT_1(INIT_1), - .INIT_2(INIT_2), - .INIT_3(INIT_3)) - _TECHMAP_REPLACE_ - (.AD(B1ADDR), - .DI(B1DATA), - .DO(A1DATA), - .CLK(CLK1), - .WRE(B1EN)); - - -endmodule diff --git a/techlibs/gowin/lutrams.txt b/techlibs/gowin/lutrams.txt new file mode 100644 index 000000000..9db530251 --- /dev/null +++ b/techlibs/gowin/lutrams.txt @@ -0,0 +1,17 @@ +bram $__GW1NR_RAM16S4 + init 1 + abits 4 + dbits 4 + groups 2 + ports 1 1 + wrmode 0 1 + enable 0 1 + transp 0 1 + clocks 0 1 + clkpol 0 1 +endbram + +match $__GW1NR_RAM16S4 + make_outreg + min wports 1 +endmatch diff --git a/techlibs/gowin/lutrams_map.v b/techlibs/gowin/lutrams_map.v new file mode 100644 index 000000000..a50ab365a --- /dev/null +++ b/techlibs/gowin/lutrams_map.v @@ -0,0 +1,31 @@ +module \$__GW1NR_RAM16S4 (CLK1, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN); + parameter CFG_ABITS = 4; + parameter CFG_DBITS = 4; + + parameter [63:0] INIT = 64'bx; + input CLK1; + + input [CFG_ABITS-1:0] A1ADDR; + output [CFG_DBITS-1:0] A1DATA; + input A1EN; + + input [CFG_ABITS-1:0] B1ADDR; + input [CFG_DBITS-1:0] B1DATA; + input B1EN; + + `include "brams_init3.vh" + + RAM16S4 + #(.INIT_0(INIT_0), + .INIT_1(INIT_1), + .INIT_2(INIT_2), + .INIT_3(INIT_3)) + _TECHMAP_REPLACE_ + (.AD(B1ADDR), + .DI(B1DATA), + .DO(A1DATA), + .CLK(CLK1), + .WRE(B1EN)); + + +endmodule diff --git a/techlibs/gowin/synth_gowin.cc b/techlibs/gowin/synth_gowin.cc index 6cf058f29..785f2802b 100644 --- a/techlibs/gowin/synth_gowin.cc +++ b/techlibs/gowin/synth_gowin.cc @@ -55,7 +55,7 @@ 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"); @@ -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") { @@ -188,24 +188,28 @@ 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) @@ -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/intel/synth_intel.cc b/techlibs/intel/synth_intel.cc index c8c690e45..5aa1a12d4 100644 --- a/techlibs/intel/synth_intel.cc +++ b/techlibs/intel/synth_intel.cc @@ -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 { @@ -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"); } -- cgit v1.2.3 From e0c879684f510ae6fd1169c90d137e660c88e6be Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Wed, 1 Jan 2020 16:13:14 +0100 Subject: take skip wire bits into account --- passes/techmap/iopadmap.cc | 3 +++ 1 file changed, 3 insertions(+) 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); -- cgit v1.2.3 From a1344ec06ead35a3b7933ee93b5757eeff2e5d4a Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Wed, 1 Jan 2020 16:24:30 +0100 Subject: Added a test case --- tests/arch/xilinx/bug1605.ys | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 tests/arch/xilinx/bug1605.ys 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 < Date: Tue, 31 Dec 2019 22:54:56 -0800 Subject: attributes.count() -> get_bool_attribute() --- backends/aiger/xaiger.cc | 2 +- passes/techmap/abc9.cc | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index be900f0e7..77659b4d8 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -284,7 +284,7 @@ struct XAigerWriter toposort.node(cell->name); - if (inst_module->attributes.count("\\abc9_flop")) + if (inst_module->get_bool_attribute("\\abc9_flop")) flop_boxes.push_back(cell); continue; } diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 3c53a5223..d6c8260b2 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -533,7 +533,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip } RTLIL::Module* box_module = design->module(mapped_cell->type); - auto abc9_flop = box_module && box_module->attributes.count("\\abc9_flop"); + auto abc9_flop = box_module && box_module->get_bool_attribute("\\abc9_flop"); for (auto &conn : mapped_cell->connections()) { RTLIL::SigSpec newsig; for (auto c : conn.second.chunks()) { @@ -988,7 +988,7 @@ struct Abc9Pass : public Pass { for (auto cell : all_cells) { auto inst_module = design->module(cell->type); - if (!inst_module || !inst_module->attributes.count("\\abc9_flop") + if (!inst_module || !inst_module->get_bool_attribute("\\abc9_flop") || cell->get_bool_attribute("\\abc9_keep")) continue; -- cgit v1.2.3 From c40b1aae42c91f200194f7f5f2caa512787ed5a3 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 1 Jan 2020 08:34:43 -0800 Subject: Restore abc9 -keepff --- README.md | 3 -- passes/techmap/abc9.cc | 79 ++++++++++++++++++------------------ techlibs/xilinx/abc9_map.v | 88 ++--------------------------------------- techlibs/xilinx/synth_xilinx.cc | 4 +- 4 files changed, 46 insertions(+), 128 deletions(-) diff --git a/README.md b/README.md index c04e2b9ec..aab1c7d6b 100644 --- a/README.md +++ b/README.md @@ -381,9 +381,6 @@ Verilog Attributes and non-standard features - The module attribute ``abc9_flop`` is a boolean marking the module as a whitebox that describes the synchronous behaviour of a flip-flop. -- The cell attribute ``abc9_keep`` is a boolean indicating that this black/ - white box should be preserved through `abc9` mapping. - - 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/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index d6c8260b2..a02b8d73b 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -249,7 +249,7 @@ struct abc9_output_filter }; void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string script_file, std::string exe_file, - bool cleanup, vector lut_costs, std::string delay_target, std::string /*lutin_shared*/, bool fast_mode, + bool cleanup, vector lut_costs, bool keepff, std::string delay_target, std::string /*lutin_shared*/, bool fast_mode, const std::vector &/*cells*/, bool show_tempdir, std::string box_file, std::string lut_file, std::string wire_delay, bool nomfs ) @@ -425,19 +425,12 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip module->remove(cell); continue; } + RTLIL::Module* box_module = design->module(cell->type); auto jt = abc9_box.find(cell->type); - if (jt == abc9_box.end()) { - RTLIL::Module* box_module = design->module(cell->type); + if (jt == abc9_box.end()) jt = abc9_box.insert(std::make_pair(cell->type, box_module && box_module->attributes.count(ID(abc9_box_id)))).first; - } if (jt->second) { - auto kt = cell->attributes.find("\\abc9_keep"); - bool abc9_keep = false; - if (kt != cell->attributes.end()) { - abc9_keep = kt->second.as_bool(); - cell->attributes.erase(kt); - } - if (!abc9_keep) + if (!keepff || !box_module->get_bool_attribute("\\abc9_flop")) boxes.emplace_back(cell); } } @@ -802,6 +795,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(" -keepff\n"); + log(" set the \"keep\" attribute on flip-flop output wires. (and thus preserve\n"); + log(" them, for example for equivalence checking.)\n"); + log("\n"); log(" -nocleanup\n"); log(" when this option is used, the temporary files created by this pass\n"); log(" are not removed. this is useful for debugging.\n"); @@ -840,7 +837,7 @@ struct Abc9Pass : public Pass { #endif std::string script_file, clk_str, box_file, lut_file; std::string delay_target, lutin_shared = "-S 1", wire_delay; - bool fast_mode = false, cleanup = true; + bool fast_mode = false, keepff = false, cleanup = true; bool show_tempdir = false; bool nomfs = false; vector lut_costs; @@ -931,6 +928,10 @@ struct Abc9Pass : public Pass { fast_mode = true; continue; } + if (arg == "-keepff") { + keepff = true; + continue; + } if (arg == "-nocleanup") { cleanup = false; continue; @@ -986,36 +987,36 @@ struct Abc9Pass : public Pass { const std::vector all_cells = module->selected_cells(); - for (auto cell : all_cells) { - auto inst_module = design->module(cell->type); - if (!inst_module || !inst_module->get_bool_attribute("\\abc9_flop") - || cell->get_bool_attribute("\\abc9_keep")) - continue; + if (!keepff) + for (auto cell : all_cells) { + auto inst_module = design->module(cell->type); + if (!inst_module || !inst_module->get_bool_attribute("\\abc9_flop")) + continue; - Wire *abc9_clock_wire = module->wire(stringf("%s.$abc9_clock", cell->name.c_str())); - if (abc9_clock_wire == NULL) - log_error("'%s$abc9_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.$abc9_init", cell->name.c_str())); - if (abc9_init_wire == NULL) - log_error("'%s.$abc9_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.$abc9_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); - } + Wire *abc9_clock_wire = module->wire(stringf("%s.$abc9_clock", cell->name.c_str())); + if (abc9_clock_wire == NULL) + log_error("'%s$abc9_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.$abc9_init", cell->name.c_str())); + if (abc9_init_wire == NULL) + log_error("'%s.$abc9_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.$abc9_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); + } design->selected_active_module = module->name.str(); - abc9_module(design, module, script_file, exe_file, cleanup, lut_costs, + abc9_module(design, module, script_file, exe_file, cleanup, lut_costs, keepff, delay_target, lutin_shared, fast_mode, all_cells, show_tempdir, box_file, lut_file, wire_delay, nomfs); design->selected_active_module.clear(); diff --git a/techlibs/xilinx/abc9_map.v b/techlibs/xilinx/abc9_map.v index 6d93e508f..1b58c34c0 100644 --- a/techlibs/xilinx/abc9_map.v +++ b/techlibs/xilinx/abc9_map.v @@ -21,7 +21,8 @@ // 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. @@ -83,7 +84,6 @@ module FDRE (output Q, input C, CE, D, R); parameter [0:0] IS_C_INVERTED = 1'b0; parameter [0:0] IS_D_INVERTED = 1'b0; parameter [0:0] IS_R_INVERTED = 1'b0; -`ifdef DFF_MODE wire QQ, $Q; generate if (INIT == 1'b1) begin assign Q = ~QQ; @@ -114,21 +114,9 @@ module FDRE (output Q, input C, CE, D, R); wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, IS_C_INVERTED}; wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = QQ; -`else - (* abc9_keep *) - FDRE #( - .INIT(INIT), - .IS_C_INVERTED(IS_C_INVERTED), - .IS_D_INVERTED(IS_D_INVERTED), - .IS_R_INVERTED(IS_R_INVERTED) - ) _TECHMAP_REPLACE_ ( - .D(D), .Q(Q), .C(C), .CE(CE), .R(R) - ); -`endif endmodule module FDRE_1 (output Q, input C, CE, D, R); parameter [0:0] INIT = 1'b0; -`ifdef DFF_MODE wire QQ, $Q; generate if (INIT == 1'b1) begin assign Q = ~QQ; @@ -153,14 +141,6 @@ module FDRE_1 (output Q, input C, CE, D, R); wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */}; wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = QQ; -`else - (* abc9_keep *) - FDRE_1 #( - .INIT(INIT) - ) _TECHMAP_REPLACE_ ( - .D(D), .Q(Q), .C(C), .CE(CE), .R(R) - ); -`endif endmodule module FDSE (output Q, input C, CE, D, S); @@ -168,7 +148,6 @@ module FDSE (output Q, input C, CE, D, S); parameter [0:0] IS_C_INVERTED = 1'b0; parameter [0:0] IS_D_INVERTED = 1'b0; parameter [0:0] IS_S_INVERTED = 1'b0; -`ifdef DFF_MODE wire QQ, $Q; generate if (INIT == 1'b1) begin assign Q = ~QQ; @@ -198,21 +177,9 @@ module FDSE (output Q, input C, CE, D, S); wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, IS_C_INVERTED}; wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = QQ; -`else - (* abc9_keep *) - FDSE #( - .INIT(INIT), - .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) - ); -`endif endmodule module FDSE_1 (output Q, input C, CE, D, S); parameter [0:0] INIT = 1'b1; -`ifdef DFF_MODE wire QQ, $Q; generate if (INIT == 1'b1) begin assign Q = ~QQ; @@ -236,14 +203,6 @@ module FDSE_1 (output Q, input C, CE, D, S); wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */}; wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = QQ; -`else - (* abc9_keep *) - FDSE_1 #( - .INIT(INIT) - ) _TECHMAP_REPLACE_ ( - .D(D), .Q(Q), .C(C), .CE(CE), .S(S) - ); -`endif endmodule module FDCE (output Q, input C, CE, D, CLR); @@ -251,7 +210,6 @@ module FDCE (output Q, input C, CE, D, CLR); parameter [0:0] IS_C_INVERTED = 1'b0; parameter [0:0] IS_D_INVERTED = 1'b0; parameter [0:0] IS_CLR_INVERTED = 1'b0; -`ifdef DFF_MODE wire QQ, $Q, $abc9_currQ; generate if (INIT == 1'b1) begin assign Q = ~QQ; @@ -295,21 +253,9 @@ module FDCE (output Q, input C, CE, D, CLR); wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, IS_C_INVERTED}; wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ; -`else - (* abc9_keep *) - FDCE #( - .INIT(INIT), - .IS_C_INVERTED(IS_C_INVERTED), - .IS_D_INVERTED(IS_D_INVERTED), - .IS_CLR_INVERTED(IS_CLR_INVERTED) - ) _TECHMAP_REPLACE_ ( - .D(D), .Q(Q), .C(C), .CE(CE), .CLR(CLR) - ); -`endif endmodule module FDCE_1 (output Q, input C, CE, D, CLR); parameter [0:0] INIT = 1'b0; -`ifdef DFF_MODE wire QQ, $Q, $abc9_currQ; generate if (INIT == 1'b1) begin assign Q = ~QQ; @@ -345,14 +291,6 @@ module FDCE_1 (output Q, input C, CE, D, CLR); wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */}; wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ; -`else - (* abc9_keep *) - FDCE_1 #( - .INIT(INIT) - ) _TECHMAP_REPLACE_ ( - .D(D), .Q(Q), .C(C), .CE(CE), .CLR(CLR) - ); -`endif endmodule module FDPE (output Q, input C, CE, D, PRE); @@ -360,7 +298,6 @@ module FDPE (output Q, input C, CE, D, PRE); parameter [0:0] IS_C_INVERTED = 1'b0; parameter [0:0] IS_D_INVERTED = 1'b0; parameter [0:0] IS_PRE_INVERTED = 1'b0; -`ifdef DFF_MODE wire QQ, $Q, $abc9_currQ; generate if (INIT == 1'b1) begin assign Q = ~QQ; @@ -402,21 +339,9 @@ module FDPE (output Q, input C, CE, D, PRE); wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, IS_C_INVERTED}; wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ; -`else - (* abc9_keep *) - FDPE #( - .INIT(INIT), - .IS_C_INVERTED(IS_C_INVERTED), - .IS_D_INVERTED(IS_D_INVERTED), - .IS_PRE_INVERTED(IS_PRE_INVERTED), - ) _TECHMAP_REPLACE_ ( - .D(D), .Q(Q), .C(C), .CE(CE), .PRE(PRE) - ); -`endif endmodule module FDPE_1 (output Q, input C, CE, D, PRE); parameter [0:0] INIT = 1'b1; -`ifdef DFF_MODE wire QQ, $Q, $abc9_currQ; generate if (INIT == 1'b1) begin assign Q = ~QQ; @@ -452,15 +377,8 @@ module FDPE_1 (output Q, input C, CE, D, PRE); wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */}; wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ; -`else - (* abc9_keep *) - FDPE_1 #( - .INIT(INIT) - ) _TECHMAP_REPLACE_ ( - .D(D), .Q(Q), .C(C), .CE(CE), .PRE(PRE) - ); -`endif endmodule +`endif // Attach a (combinatorial) black-box onto the output // of thes LUTRAM primitives to capture their diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index f2a9ae982..10aa7be5f 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -108,7 +108,7 @@ struct SynthXilinxPass : public ScriptPass log(" flatten design before synthesis\n"); log("\n"); log(" -dff\n"); - log(" run 'abc9' with -dff option\n"); + log(" enable sequential synthesis with 'abc9'\n"); log("\n"); log(" -retime\n"); log(" run 'abc' with -dff option\n"); @@ -559,6 +559,8 @@ 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 += " -keepff"; run("abc9" + abc9_opts); run("techmap -map +/xilinx/abc9_unmap.v"); } -- cgit v1.2.3 From 6dc63e84ef680465d500bf35da64fade626498b6 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 1 Jan 2020 08:34:57 -0800 Subject: Cleanup abc9, update doc for -keepff option --- passes/techmap/abc9.cc | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index a02b8d73b..c3c8e0dbc 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -250,7 +250,7 @@ struct abc9_output_filter void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string script_file, std::string exe_file, bool cleanup, vector lut_costs, bool keepff, std::string delay_target, std::string /*lutin_shared*/, bool fast_mode, - const std::vector &/*cells*/, bool show_tempdir, std::string box_file, std::string lut_file, + bool show_tempdir, std::string box_file, std::string lut_file, std::string wire_delay, bool nomfs ) { @@ -796,8 +796,8 @@ struct Abc9Pass : public Pass { log(" 2, 3, .. inputs.\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(" do not represent (* abc9_flop *) modules as boxes (and thus do not perform\n"); + log(" any form of sequential synthesis).\n"); log("\n"); log(" -nocleanup\n"); log(" when this option is used, the temporary files created by this pass\n"); @@ -985,10 +985,9 @@ struct Abc9Pass : public Pass { typedef SigSpec clkdomain_t; dict clk_to_mergeability; - const std::vector all_cells = module->selected_cells(); if (!keepff) - for (auto cell : all_cells) { + for (auto cell : module->selected_cells()) { auto inst_module = design->module(cell->type); if (!inst_module || !inst_module->get_bool_attribute("\\abc9_flop")) continue; @@ -1017,7 +1016,7 @@ struct Abc9Pass : public Pass { design->selected_active_module = module->name.str(); abc9_module(design, module, script_file, exe_file, cleanup, lut_costs, keepff, - delay_target, lutin_shared, fast_mode, all_cells, show_tempdir, + delay_target, lutin_shared, fast_mode, show_tempdir, box_file, lut_file, wire_delay, nomfs); design->selected_active_module.clear(); } -- cgit v1.2.3 From 11577b46fcfa6c9aef4c3ed83e508ab07bc722c7 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 1 Jan 2020 08:38:23 -0800 Subject: Get rid of (* abc9_keep *) in write_xaiger too --- backends/aiger/xaiger.cc | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 77659b4d8..9c6152dff 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -250,7 +250,12 @@ struct XAigerWriter RTLIL::Module* inst_module = module->design->module(cell->type); if (inst_module) { - bool abc9_box = inst_module->attributes.count("\\abc9_box_id") && !cell->get_bool_attribute("\\abc9_keep"); + bool abc9_box = inst_module->attributes.count("\\abc9_box_id"); + bool abc9_flop = inst_module->get_bool_attribute("\\abc9_flop"); + // The lack of an abc9_mergeability attribute indicates that + // we do want to keep this flop, so do not treat it as a box + if (abc9_flop && !cell->attributes.count("\\abc9_mergeability")) + abc9_box = false; for (const auto &conn : cell->connections()) { auto port_wire = inst_module->wire(conn.first); @@ -279,15 +284,15 @@ struct XAigerWriter } } - if (abc9_box) { - abc9_box_seen = true; + if (abc9_box) { + abc9_box_seen = true; - toposort.node(cell->name); + toposort.node(cell->name); - if (inst_module->get_bool_attribute("\\abc9_flop")) - flop_boxes.push_back(cell); - continue; - } + if (abc9_flop) + flop_boxes.push_back(cell); + continue; + } } bool cell_known = inst_module || cell->known(); @@ -322,11 +327,12 @@ struct XAigerWriter SigBit d; if (r.second) { for (const auto &conn : cell->connections()) { - const SigSpec &rhs = conn.second; - if (!rhs.is_bit()) + if (!conn.second.is_bit()) continue; - if (!ff_bits.count(rhs)) + d = conn.second; + if (!ff_bits.count(d)) continue; + r.first->second.first = conn.first; Module *inst_module = module->design->module(cell->type); Wire *wire = inst_module->wire(conn.first); @@ -337,7 +343,6 @@ struct XAigerWriter log_error("Attribute 'abc9_arrival' on port '%s' of module '%s' is not an integer.\n", log_id(wire), log_id(cell->type)); r.first->second.second = jt->second.as_int(); } - d = rhs; log_assert(d == sigmap(d)); break; } @@ -399,8 +404,7 @@ struct XAigerWriter log_assert(cell); RTLIL::Module* box_module = module->design->module(cell->type); - if (!box_module || !box_module->attributes.count("\\abc9_box_id") - || cell->get_bool_attribute("\\abc9_keep")) + if (!box_module || !box_module->attributes.count("\\abc9_box_id")) continue; bool blackbox = box_module->get_blackbox_attribute(true /* ignore_wb */); @@ -434,7 +438,6 @@ struct XAigerWriter 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()) { - log_assert(carry_out != IdString()); r.first->second.push_back(carry_in); r.first->second.push_back(carry_out); } -- cgit v1.2.3 From 0e95756e960f809aaa4596ba44330e7bd6fd0309 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 1 Jan 2020 08:39:00 -0800 Subject: Clamp -46ps for FDPE* too --- techlibs/xilinx/abc9_xc7.box | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/techlibs/xilinx/abc9_xc7.box b/techlibs/xilinx/abc9_xc7.box index 43c39544e..1dff88509 100644 --- a/techlibs/xilinx/abc9_xc7.box +++ b/techlibs/xilinx/abc9_xc7.box @@ -114,14 +114,14 @@ FDCE_1 1105 1 5 1 FDPE 1106 1 5 1 #C CE D PRE $abc9_currQ #0 109 -46 764 0 -0 109 -46 764 0 # Q (-46ps Tsu clamped to 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 -46 764 0 # Q (-46ps Tsu clamped to 0) +0 109 0 764 0 # Q (-46ps Tsu clamped to 0) # Box 2000 : $__ABC9_LUT6 # (private cell to emulate async behaviour of LUTRAMs) -- cgit v1.2.3 From 3deec51ddcb8690901f7d99958ad71bccd19084f Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 1 Jan 2020 08:43:16 -0800 Subject: Fix anlogic async flop mapping --- techlibs/anlogic/cells_map.v | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) 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"; -- cgit v1.2.3 From 52fe1e0c44d572b8e1f8881dc0a1e91f7fa93c9c Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 1 Jan 2020 09:05:46 -0800 Subject: Revert insertion of 'reg', leave note behind --- tests/arch/ice40/rom.v | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/arch/ice40/rom.v b/tests/arch/ice40/rom.v index c4c677c1e..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 reg [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) -- cgit v1.2.3 From db04161eca76d4db7a01641429d2da6a3a8d3239 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 1 Jan 2020 17:30:26 -0800 Subject: Rework abc9's DSP48E1 model --- techlibs/xilinx/abc9_map.v | 335 +++------- techlibs/xilinx/abc9_model.v | 155 +---- techlibs/xilinx/abc9_unmap.v | 194 +----- techlibs/xilinx/abc9_xc7.box | 1399 +++++++++--------------------------------- techlibs/xilinx/cells_sim.v | 79 +++ 5 files changed, 506 insertions(+), 1656 deletions(-) diff --git a/techlibs/xilinx/abc9_map.v b/techlibs/xilinx/abc9_map.v index 7b9427b2f..e3e736e8f 100644 --- a/techlibs/xilinx/abc9_map.v +++ b/techlibs/xilinx/abc9_map.v @@ -282,244 +282,113 @@ module DSP48E1 ( parameter [4:0] IS_INMODE_INVERTED = 5'b0; parameter [6:0] IS_OPMODE_INVERTED = 7'b0; - parameter _TECHMAP_CELLTYPE_ = ""; - localparam techmap_guard = (_TECHMAP_CELLTYPE_ != ""); + wire [47:0] $P, $PCOUT; -`define DSP48E1_INST(__CELL__) """ -__CELL__ #( - .ACASCREG(ACASCREG), - .ADREG(ADREG), - .ALUMODEREG(ALUMODEREG), - .AREG(AREG), - .AUTORESET_PATDET(AUTORESET_PATDET), - .A_INPUT(A_INPUT), - .BCASCREG(BCASCREG), - .BREG(BREG), - .B_INPUT(B_INPUT), - .CARRYINREG(CARRYINREG), - .CARRYINSELREG(CARRYINSELREG), - .CREG(CREG), - .DREG(DREG), - .INMODEREG(INMODEREG), - .MREG(MREG), - .OPMODEREG(OPMODEREG), - .PREG(PREG), - .SEL_MASK(SEL_MASK), - .SEL_PATTERN(SEL_PATTERN), - .USE_DPORT(USE_DPORT), - .USE_MULT(USE_MULT), - .USE_PATTERN_DETECT(USE_PATTERN_DETECT), - .USE_SIMD(USE_SIMD), - .MASK(MASK), - .PATTERN(PATTERN), - .IS_ALUMODE_INVERTED(IS_ALUMODE_INVERTED), - .IS_CARRYIN_INVERTED(IS_CARRYIN_INVERTED), - .IS_CLK_INVERTED(IS_CLK_INVERTED), - .IS_INMODE_INVERTED(IS_INMODE_INVERTED), - .IS_OPMODE_INVERTED(IS_OPMODE_INVERTED) - ) _TECHMAP_REPLACE_ ( - .ACOUT(ACOUT), - .BCOUT(BCOUT), - .CARRYCASCOUT(CARRYCASCOUT), - .CARRYOUT(CARRYOUT), - .MULTSIGNOUT(MULTSIGNOUT), - .OVERFLOW(OVERFLOW), - .P(oP), - .PATTERNBDETECT(PATTERNBDETECT), - .PATTERNDETECT(PATTERNDETECT), - .PCOUT(oPCOUT), - .UNDERFLOW(UNDERFLOW), - .A(iA), - .ACIN(ACIN), - .ALUMODE(ALUMODE), - .B(iB), - .BCIN(BCIN), - .C(iC), - .CARRYCASCIN(CARRYCASCIN), - .CARRYIN(CARRYIN), - .CARRYINSEL(CARRYINSEL), - .CEA1(CEA1), - .CEA2(CEA2), - .CEAD(CEAD), - .CEALUMODE(CEALUMODE), - .CEB1(CEB1), - .CEB2(CEB2), - .CEC(CEC), - .CECARRYIN(CECARRYIN), - .CECTRL(CECTRL), - .CED(CED), - .CEINMODE(CEINMODE), - .CEM(CEM), - .CEP(CEP), - .CLK(CLK), - .D(iD), - .INMODE(INMODE), - .MULTSIGNIN(MULTSIGNIN), - .OPMODE(OPMODE), - .PCIN(PCIN), - .RSTA(RSTA), - .RSTALLCARRYIN(RSTALLCARRYIN), - .RSTALUMODE(RSTALUMODE), - .RSTB(RSTB), - .RSTC(RSTC), - .RSTCTRL(RSTCTRL), - .RSTD(RSTD), - .RSTINMODE(RSTINMODE), - .RSTM(RSTM), - .RSTP(RSTP) - ); -""" - - wire [29:0] iA; - wire [17:0] iB; - wire [47:0] iC; - wire [24:0] iD; - - wire pA, pB, pC, pD, pAD, pM, pP; - wire [47:0] oP, mP; - wire [47:0] oPCOUT, mPCOUT; + DSP48E1 #( + .ACASCREG(ACASCREG), + .ADREG(ADREG), + .ALUMODEREG(ALUMODEREG), + .AREG(AREG), + .AUTORESET_PATDET(AUTORESET_PATDET), + .A_INPUT(A_INPUT), + .BCASCREG(BCASCREG), + .BREG(BREG), + .B_INPUT(B_INPUT), + .CARRYINREG(CARRYINREG), + .CARRYINSELREG(CARRYINSELREG), + .CREG(CREG), + .DREG(DREG), + .INMODEREG(INMODEREG), + .MREG(MREG), + .OPMODEREG(OPMODEREG), + .PREG(PREG), + .SEL_MASK(SEL_MASK), + .SEL_PATTERN(SEL_PATTERN), + .USE_DPORT(USE_DPORT), + .USE_MULT(USE_MULT), + .USE_PATTERN_DETECT(USE_PATTERN_DETECT), + .USE_SIMD(USE_SIMD), + .MASK(MASK), + .PATTERN(PATTERN), + .IS_ALUMODE_INVERTED(IS_ALUMODE_INVERTED), + .IS_CARRYIN_INVERTED(IS_CARRYIN_INVERTED), + .IS_CLK_INVERTED(IS_CLK_INVERTED), + .IS_INMODE_INVERTED(IS_INMODE_INVERTED), + .IS_OPMODE_INVERTED(IS_OPMODE_INVERTED) + ) _TECHMAP_REPLACE_ ( + .ACOUT(ACOUT), + .BCOUT(BCOUT), + .CARRYCASCOUT(CARRYCASCOUT), + .CARRYOUT(CARRYOUT), + .MULTSIGNOUT(MULTSIGNOUT), + .OVERFLOW(OVERFLOW), + .P($P), + .PATTERNBDETECT(PATTERNBDETECT), + .PATTERNDETECT(PATTERNDETECT), + .PCOUT($PCOUT), + .UNDERFLOW(UNDERFLOW), + .A(A), + .ACIN(ACIN), + .ALUMODE(ALUMODE), + .B(B), + .BCIN(BCIN), + .C(C), + .CARRYCASCIN(CARRYCASCIN), + .CARRYIN(CARRYIN), + .CARRYINSEL(CARRYINSEL), + .CEA1(CEA1), + .CEA2(CEA2), + .CEAD(CEAD), + .CEALUMODE(CEALUMODE), + .CEB1(CEB1), + .CEB2(CEB2), + .CEC(CEC), + .CECARRYIN(CECARRYIN), + .CECTRL(CECTRL), + .CED(CED), + .CEINMODE(CEINMODE), + .CEM(CEM), + .CEP(CEP), + .CLK(CLK), + .D(D), + .INMODE(INMODE), + .MULTSIGNIN(MULTSIGNIN), + .OPMODE(OPMODE), + .PCIN(PCIN), + .RSTA(RSTA), + .RSTALLCARRYIN(RSTALLCARRYIN), + .RSTALUMODE(RSTALUMODE), + .RSTB(RSTB), + .RSTC(RSTC), + .RSTCTRL(RSTCTRL), + .RSTD(RSTD), + .RSTINMODE(RSTINMODE), + .RSTM(RSTM), + .RSTP(RSTP) + ); generate - if (USE_MULT == "MULTIPLY" && USE_DPORT == "FALSE") begin - // Disconnect the A-input if MREG is enabled, since - // combinatorial path is broken - 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)); - 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)); - if (CREG == 0 && PREG == 0) - assign iC = C, pC = 1'bx; - else - \$__ABC9_REG #(.WIDTH(48)) rC (.I(C), .O(iC), .Q(pC)); - if (DREG == 0) - assign iD = D; - else if (techmap_guard) - $error("Invalid DSP48E1 configuration: DREG enabled but USE_DPORT == \"FALSE\""); - assign pD = 1'bx; - if (ADREG == 1 && techmap_guard) - $error("Invalid DSP48E1 configuration: ADREG enabled but USE_DPORT == \"FALSE\""); - assign pAD = 1'bx; - if (PREG == 0) begin - if (MREG == 1) - \$__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)); - end + wire [29:0] $A; + wire [17:0] $B; + wire [47:0] $C; + wire [24:0] $D; - if (MREG == 0 && PREG == 0) - assign mP = oP, mPCOUT = oPCOUT; - else - assign mP = 1'bx, mPCOUT = 1'bx; - \$__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 ( - .Aq(pA), .Bq(pB), .Cq(pC), .Dq(pD), .ADq(pAD), .I(oPCOUT), .Mq(pM), .P(mPCOUT), .Pq(pP), .O(PCOUT) - ); + if (PREG != 0) + assign P = $P, PCOUT = $PCOUT; + else begin + if (AREG == 0) assign $A = A; + if (BREG == 0) assign $B = B; + if (CREG == 0) assign $C = C; + if (DREG == 0) assign $D = D; - `DSP48E1_INST(\$__ABC9_DSP48E1_MULT ) - end - else if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE") begin - // Disconnect the A-input if MREG is enabled, since - // combinatorial path is broken - 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)); - 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)); - if (CREG == 0 && PREG == 0) - assign iC = C, pC = 1'bx; - else - \$__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)); - if (PREG == 0) begin - if (MREG == 1) begin - assign pAD = 1'bx; - \$__ABC9_REG rM (.Q(pM)); - end else begin - if (ADREG == 1) - \$__ABC9_REG rAD (.Q(pAD)); - else - assign pAD = 1'bx; - assign pM = 1'bx; - end - assign pP = 1'bx; - end else begin - assign pAD = 1'bx, pM = 1'bx; - \$__ABC9_REG rP (.Q(pP)); + if (USE_MULT == "MULTIPLY" && USE_DPORT == "FALSE") + $__ABC9_DSP48E1_MULT dsp_comb(.$A($A), .$B($B), .$C($C), .$D($D), .$P($P), .$PCIN(PCIN), .$PCOUT($PCOUT), .P(P), .PCOUT(PCOUT)); + else if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE") + $__ABC9_DSP48E1_MULT_DPORT dsp_comb(.$A($A), .$B($B), .$C($C), .$D($D), .$P($P), .$PCIN(PCIN), .$PCOUT($PCOUT), .P(P), .PCOUT(PCOUT)); + else if (USE_MULT == "NONE" && USE_DPORT == "FALSE") + $__ABC9_DSP48E1 dsp_comb(.$A($A), .$B($B), .$C($C), .$D($D), .$P($P), .$PCIN(PCIN), .$PCOUT($PCOUT), .P(P), .PCOUT(PCOUT)); + else + $error("Invalid DSP48E1 configuration"); 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 ( - .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 ( - .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 ) - end - else if (USE_MULT == "NONE" && USE_DPORT == "FALSE") begin - // Disconnect the A-input if MREG is enabled, since - // combinatorial path is broken - if (AREG == 0 && PREG == 0) - assign iA = A, pA = 1'bx; - else - \$__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)); - if (CREG == 0 && PREG == 0) - assign iC = C, pC = 1'bx; - else - \$__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; - if (ADREG == 1 && techmap_guard) - $error("Invalid DSP48E1 configuration: ADREG enabled but USE_DPORT == \"FALSE\""); - assign pAD = 1'bx; - if (MREG == 1 && techmap_guard) - $error("Invalid DSP48E1 configuration: MREG enabled but USE_MULT == \"NONE\""); - assign pM = 1'bx; - if (PREG == 1) - \$__ABC9_REG rP (.Q(pP)); - else - assign pP = 1'bx; - - if (MREG == 0 && PREG == 0) - assign mP = oP, mPCOUT = oPCOUT; - else - assign mP = 1'bx, mPCOUT = 1'bx; - \$__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 ( - .Aq(pA), .Bq(pB), .Cq(pC), .Dq(pD), .ADq(pAD), .I(oPCOUT), .Mq(pM), .P(mPCOUT), .Pq(pP), .O(PCOUT) - ); - - `DSP48E1_INST(\$__ABC9_DSP48E1 ) - end - else - $error("Invalid DSP48E1 configuration"); endgenerate - `undef DSP48E1_INST endmodule diff --git a/techlibs/xilinx/abc9_model.v b/techlibs/xilinx/abc9_model.v index 8c8e1556c..18d59dcd6 100644 --- a/techlibs/xilinx/abc9_model.v +++ b/techlibs/xilinx/abc9_model.v @@ -44,147 +44,22 @@ endmodule module \$__ABC9_LUT7 (input A, input [6:0] S, output Y); endmodule - -// Modules used to model the comb/seq behaviour of DSP48E1 -// With abc9_map.v responsible for splicing the below modules -// between the combinatorial DSP48E1 box (e.g. disconnecting -// A when AREG, MREG or PREG is enabled and splicing in the -// "$__ABC9_DSP48E1_REG" blackbox as "REG" in the diagram below) -// this acts to first disables the combinatorial path (as there -// is no connectivity through REG), and secondly, since this is -// blackbox a new PI will be introduced with an arrival time of -// zero. -// Note: Since these "$__ABC9_DSP48E1_REG" modules are of a -// sequential nature, they are not passed as a box to ABC and -// (desirably) represented as PO/PIs. -// -// At the DSP output, we place a blackbox mux ("M" in the diagram -// below) to capture the fact that the critical-path could come -// from any one of its inputs. -// In contrast to "REG", the "$__ABC9_DSP48E1_*_MUX" modules are -// combinatorial blackboxes that do get passed to ABC. -// The propagation delay through this box (specified in the box -// file) captures the arrival time of the register (i.e. -// propagation from AREG to P after clock edge), or zero delay -// for the combinatorial path from the DSP. -// -// Doing so should means that ABC is able to analyse the -// worst-case delay through to P, regardless of if it was -// through any combinatorial paths (e.g. B, below) or an -// internal register (A2REG). -// However, the true value of being as complete as this is -// questionable since if AREG=1 and BREG=0 (as below) -// then the worse-case path would very likely be through B -// and very unlikely to be through AREG.Q...? -// -// In graphical form: -// -// +-----+ -// +------>> REG >>----+ -// | +-----+ | -// | | -// | +---------+ | __ -// A >>-+X X-| | +--| \ -// | DSP48E1 |P | M |--->> P -// | AREG=1 |-------|__/ -// B >>------| | -// +---------+ -// -`define ABC9_DSP48E1_MUX(__NAME__) """ -module __NAME__ (input Aq, ADq, Bq, Cq, Dq, input [47:0] I, input Mq, input [47:0] P, input Pq, output [47:0] O); -endmodule -""" -(* abc9_box_id=2100 *) `ABC9_DSP48E1_MUX(\$__ABC9_DSP48E1_MULT_P_MUX ) -(* abc9_box_id=2101 *) `ABC9_DSP48E1_MUX(\$__ABC9_DSP48E1_MULT_PCOUT_MUX ) -(* abc9_box_id=2102 *) `ABC9_DSP48E1_MUX(\$__ABC9_DSP48E1_MULT_DPORT_P_MUX ) -(* abc9_box_id=2103 *) `ABC9_DSP48E1_MUX(\$__ABC9_DSP48E1_MULT_DPORT_PCOUT_MUX ) -(* abc9_box_id=2104 *) `ABC9_DSP48E1_MUX(\$__ABC9_DSP48E1_P_MUX ) -(* abc9_box_id=2105 *) `ABC9_DSP48E1_MUX(\$__ABC9_DSP48E1_PCOUT_MUX ) - +// Boxes used to represent the comb behaviour of various modes +// of DSP48E1 `define ABC9_DSP48E1(__NAME__) """ module __NAME__ ( - output [29:0] ACOUT, - output [17:0] BCOUT, - output reg CARRYCASCOUT, - output reg [3:0] CARRYOUT, - output reg MULTSIGNOUT, - output OVERFLOW, - output reg signed [47:0] P, - output PATTERNBDETECT, - output PATTERNDETECT, - output [47:0] PCOUT, - output UNDERFLOW, - input signed [29:0] A, - input [29:0] ACIN, - input [3:0] ALUMODE, - input signed [17:0] B, - input [17:0] BCIN, - input [47:0] C, - input CARRYCASCIN, - input CARRYIN, - input [2:0] CARRYINSEL, - input CEA1, - input CEA2, - input CEAD, - input CEALUMODE, - input CEB1, - input CEB2, - input CEC, - input CECARRYIN, - input CECTRL, - input CED, - input CEINMODE, - input CEM, - input CEP, - input CLK, - input [24:0] D, - input [4:0] INMODE, - input MULTSIGNIN, - input [6:0] OPMODE, - input [47:0] PCIN, - input RSTA, - input RSTALLCARRYIN, - input RSTALUMODE, - input RSTB, - input RSTC, - input RSTCTRL, - input RSTD, - input RSTINMODE, - input RSTM, - input RSTP -); - parameter integer ACASCREG = 1; - parameter integer ADREG = 1; - parameter integer ALUMODEREG = 1; - parameter integer AREG = 1; - parameter AUTORESET_PATDET = "NO_RESET"; - parameter A_INPUT = "DIRECT"; - parameter integer BCASCREG = 1; - parameter integer BREG = 1; - parameter B_INPUT = "DIRECT"; - parameter integer CARRYINREG = 1; - parameter integer CARRYINSELREG = 1; - parameter integer CREG = 1; - parameter integer DREG = 1; - parameter integer INMODEREG = 1; - parameter integer MREG = 1; - parameter integer OPMODEREG = 1; - parameter integer PREG = 1; - parameter SEL_MASK = "MASK"; - parameter SEL_PATTERN = "PATTERN"; - parameter USE_DPORT = "FALSE"; - parameter USE_MULT = "MULTIPLY"; - parameter USE_PATTERN_DETECT = "NO_PATDET"; - parameter USE_SIMD = "ONE48"; - parameter [47:0] MASK = 48'h3FFFFFFFFFFF; - parameter [47:0] PATTERN = 48'h000000000000; - parameter [3:0] IS_ALUMODE_INVERTED = 4'b0; - parameter [0:0] IS_CARRYIN_INVERTED = 1'b0; - parameter [0:0] IS_CLK_INVERTED = 1'b0; - parameter [4:0] IS_INMODE_INVERTED = 5'b0; - parameter [6:0] IS_OPMODE_INVERTED = 7'b0; + input [29:0] $A, + input [17:0] $B, + input [47:0] $C, + input [24:0] $D, + input [47:0] $P, + input [47:0] $PCIN, + input [47:0] $PCOUT, + output [47:0] P, + output [47:0] PCOUT); endmodule """ -(* abc9_box_id=3000 *) `ABC9_DSP48E1(\$__ABC9_DSP48E1_MULT ) -(* abc9_box_id=3001 *) `ABC9_DSP48E1(\$__ABC9_DSP48E1_MULT_DPORT ) -(* abc9_box_id=3002 *) `ABC9_DSP48E1(\$__ABC9_DSP48E1 ) +(* abc9_box_id=3000 *) `ABC9_DSP48E1($__ABC9_DSP48E1_MULT) +(* abc9_box_id=3001 *) `ABC9_DSP48E1($__ABC9_DSP48E1_MULT_DPORT) +(* abc9_box_id=3002 *) `ABC9_DSP48E1($__ABC9_DSP48E1) +`undef ABC9_DSP48E1 diff --git a/techlibs/xilinx/abc9_unmap.v b/techlibs/xilinx/abc9_unmap.v index ad6469702..64135e9a7 100644 --- a/techlibs/xilinx/abc9_unmap.v +++ b/techlibs/xilinx/abc9_unmap.v @@ -20,192 +20,24 @@ // ============================================================================ -module \$__ABC9_LUT6 (input A, input [5:0] S, output Y); +module $__ABC9_LUT6(input A, input [5:0] S, output Y); assign Y = A; endmodule -module \$__ABC9_LUT7 (input A, input [6:0] S, output Y); +module $__ABC9_LUT7(input A, input [6:0] S, output Y); assign Y = A; endmodule -module \$__ABC9_REG (input [WIDTH-1:0] I, output [WIDTH-1:0] O, output Q); - parameter WIDTH = 1; - assign O = I; -endmodule -(* techmap_celltype = "$__ABC9_DSP48E1_MULT_P_MUX $__ABC9_DSP48E1_MULT_PCOUT_MUX $__ABC9_DSP48E1_MULT_DPORT_P_MUX $__ABC9_DSP48E1_MULT_DPORT_PCOUT_MUX $__ABC9_DSP48E1_P_MUX $__ABC9_DSP48E1_PCOUT_MUX" *) -module \$__ABC9_DSP48E1_MUX ( - input Aq, Bq, Cq, Dq, ADq, - input [47:0] I, - input Mq, - input [47:0] P, - input Pq, - output [47:0] O -); - assign O = I; -endmodule - (* techmap_celltype = "$__ABC9_DSP48E1_MULT $__ABC9_DSP48E1_MULT_DPORT $__ABC9_DSP48E1" *) -module \$__ABC9_DSP48E1 ( - (* techmap_autopurge *) output [29:0] ACOUT, - (* techmap_autopurge *) output [17:0] BCOUT, - (* techmap_autopurge *) output reg CARRYCASCOUT, - (* techmap_autopurge *) output reg [3:0] CARRYOUT, - (* techmap_autopurge *) output reg MULTSIGNOUT, - (* techmap_autopurge *) output OVERFLOW, - (* techmap_autopurge *) output reg signed [47:0] P, - (* techmap_autopurge *) output PATTERNBDETECT, - (* techmap_autopurge *) output PATTERNDETECT, - (* techmap_autopurge *) output [47:0] PCOUT, - (* techmap_autopurge *) output UNDERFLOW, - (* techmap_autopurge *) input signed [29:0] A, - (* techmap_autopurge *) input [29:0] ACIN, - (* techmap_autopurge *) input [3:0] ALUMODE, - (* techmap_autopurge *) input signed [17:0] B, - (* techmap_autopurge *) input [17:0] BCIN, - (* techmap_autopurge *) input [47:0] C, - (* techmap_autopurge *) input CARRYCASCIN, - (* techmap_autopurge *) input CARRYIN, - (* techmap_autopurge *) input [2:0] CARRYINSEL, - (* techmap_autopurge *) input CEA1, - (* techmap_autopurge *) input CEA2, - (* techmap_autopurge *) input CEAD, - (* techmap_autopurge *) input CEALUMODE, - (* techmap_autopurge *) input CEB1, - (* techmap_autopurge *) input CEB2, - (* techmap_autopurge *) input CEC, - (* techmap_autopurge *) input CECARRYIN, - (* techmap_autopurge *) input CECTRL, - (* techmap_autopurge *) input CED, - (* techmap_autopurge *) input CEINMODE, - (* techmap_autopurge *) input CEM, - (* techmap_autopurge *) input CEP, - (* techmap_autopurge *) input CLK, - (* techmap_autopurge *) input [24:0] D, - (* techmap_autopurge *) input [4:0] INMODE, - (* techmap_autopurge *) input MULTSIGNIN, - (* techmap_autopurge *) input [6:0] OPMODE, - (* techmap_autopurge *) input [47:0] PCIN, - (* techmap_autopurge *) input RSTA, - (* techmap_autopurge *) input RSTALLCARRYIN, - (* techmap_autopurge *) input RSTALUMODE, - (* techmap_autopurge *) input RSTB, - (* techmap_autopurge *) input RSTC, - (* techmap_autopurge *) input RSTCTRL, - (* techmap_autopurge *) input RSTD, - (* techmap_autopurge *) input RSTINMODE, - (* techmap_autopurge *) input RSTM, - (* techmap_autopurge *) input RSTP +module $ABC9_DSP48E1( + input [29:0] $A, + input [17:0] $B, + input [47:0] $C, + input [24:0] $D, + input [47:0] $P, + input [47:0] $PCIN, + input [47:0] $PCOUT, + output [47:0] P, + output [47:0] PCOUT ); - parameter integer ACASCREG = 1; - parameter integer ADREG = 1; - parameter integer ALUMODEREG = 1; - parameter integer AREG = 1; - parameter AUTORESET_PATDET = "NO_RESET"; - parameter A_INPUT = "DIRECT"; - parameter integer BCASCREG = 1; - parameter integer BREG = 1; - parameter B_INPUT = "DIRECT"; - parameter integer CARRYINREG = 1; - parameter integer CARRYINSELREG = 1; - parameter integer CREG = 1; - parameter integer DREG = 1; - parameter integer INMODEREG = 1; - parameter integer MREG = 1; - parameter integer OPMODEREG = 1; - parameter integer PREG = 1; - parameter SEL_MASK = "MASK"; - parameter SEL_PATTERN = "PATTERN"; - parameter USE_DPORT = "FALSE"; - parameter USE_MULT = "MULTIPLY"; - parameter USE_PATTERN_DETECT = "NO_PATDET"; - parameter USE_SIMD = "ONE48"; - parameter [47:0] MASK = 48'h3FFFFFFFFFFF; - parameter [47:0] PATTERN = 48'h000000000000; - parameter [3:0] IS_ALUMODE_INVERTED = 4'b0; - parameter [0:0] IS_CARRYIN_INVERTED = 1'b0; - parameter [0:0] IS_CLK_INVERTED = 1'b0; - parameter [4:0] IS_INMODE_INVERTED = 5'b0; - parameter [6:0] IS_OPMODE_INVERTED = 7'b0; - - DSP48E1 #( - .ACASCREG(ACASCREG), - .ADREG(ADREG), - .ALUMODEREG(ALUMODEREG), - .AREG(AREG), - .AUTORESET_PATDET(AUTORESET_PATDET), - .A_INPUT(A_INPUT), - .BCASCREG(BCASCREG), - .BREG(BREG), - .B_INPUT(B_INPUT), - .CARRYINREG(CARRYINREG), - .CARRYINSELREG(CARRYINSELREG), - .CREG(CREG), - .DREG(DREG), - .INMODEREG(INMODEREG), - .MREG(MREG), - .OPMODEREG(OPMODEREG), - .PREG(PREG), - .SEL_MASK(SEL_MASK), - .SEL_PATTERN(SEL_PATTERN), - .USE_DPORT(USE_DPORT), - .USE_MULT(USE_MULT), - .USE_PATTERN_DETECT(USE_PATTERN_DETECT), - .USE_SIMD(USE_SIMD), - .MASK(MASK), - .PATTERN(PATTERN), - .IS_ALUMODE_INVERTED(IS_ALUMODE_INVERTED), - .IS_CARRYIN_INVERTED(IS_CARRYIN_INVERTED), - .IS_CLK_INVERTED(IS_CLK_INVERTED), - .IS_INMODE_INVERTED(IS_INMODE_INVERTED), - .IS_OPMODE_INVERTED(IS_OPMODE_INVERTED) - ) _TECHMAP_REPLACE_ ( - .ACOUT(ACOUT), - .BCOUT(BCOUT), - .CARRYCASCOUT(CARRYCASCOUT), - .CARRYOUT(CARRYOUT), - .MULTSIGNOUT(MULTSIGNOUT), - .OVERFLOW(OVERFLOW), - .P(P), - .PATTERNBDETECT(PATTERNBDETECT), - .PATTERNDETECT(PATTERNDETECT), - .PCOUT(PCOUT), - .UNDERFLOW(UNDERFLOW), - .A(A), - .ACIN(ACIN), - .ALUMODE(ALUMODE), - .B(B), - .BCIN(BCIN), - .C(C), - .CARRYCASCIN(CARRYCASCIN), - .CARRYIN(CARRYIN), - .CARRYINSEL(CARRYINSEL), - .CEA1(CEA1), - .CEA2(CEA2), - .CEAD(CEAD), - .CEALUMODE(CEALUMODE), - .CEB1(CEB1), - .CEB2(CEB2), - .CEC(CEC), - .CECARRYIN(CECARRYIN), - .CECTRL(CECTRL), - .CED(CED), - .CEINMODE(CEINMODE), - .CEM(CEM), - .CEP(CEP), - .CLK(CLK), - .D(D), - .INMODE(INMODE), - .MULTSIGNIN(MULTSIGNIN), - .OPMODE(OPMODE), - .PCIN(PCIN), - .RSTA(RSTA), - .RSTALLCARRYIN(RSTALLCARRYIN), - .RSTALUMODE(RSTALUMODE), - .RSTB(RSTB), - .RSTC(RSTC), - .RSTCTRL(RSTCTRL), - .RSTD(RSTD), - .RSTINMODE(RSTINMODE), - .RSTM(RSTM), - .RSTP(RSTP) - ); + assign P = $P, PCOUT = $PCOUT; endmodule diff --git a/techlibs/xilinx/abc9_xc7.box b/techlibs/xilinx/abc9_xc7.box index 774388d49..9fb1cc0ef 100644 --- a/techlibs/xilinx/abc9_xc7.box +++ b/techlibs/xilinx/abc9_xc7.box @@ -60,1106 +60,301 @@ $__ABC9_LUT6 2000 0 7 1 $__ABC9_LUT7 2001 0 8 1 0 1047 1036 877 812 643 532 478 -# Boxes used to represent the comb/seq behaviour of DSP48E1 -# With abc9_map.v responsible for disconnecting inputs to -# the combinatorial DSP48E1 model by a register (e.g. -# disconnecting A when AREG, MREG or PREG is enabled) -# this mux captures the existence of a replacement path -# between AREG/BREG/CREG/etc. and P/PCOUT. -# Since the Aq/ADq/Bq/etc. inputs are assumed to arrive at -# 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 +# Boxes used to represent the comb behaviour of various modes +# of DSP48E1 +$__ABC9_DSP48E1_MULT 3000 0 265 96 +#A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11 A12 A13 A14 A15 A16 A17 A18 A19 A20 A21 A22 A23 A24 A25 A26 A27 A28 A29 B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 B10 B11 B12 B13 B14 B15 B16 B17 C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 C10 C11 C12 C13 C14 C15 C16 C17 C18 C19 C20 C21 C22 C23 C24 C25 C26 C27 C28 C29 C30 C31 C32 C33 C34 C35 C36 C37 C38 C39 C40 C41 C42 C43 C44 C45 C46 C47 D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 D10 D11 D12 D13 D14 D15 D16 D17 D18 D19 D20 D21 D22 D23 D24 P0 P1 P2 P3 P4 P5 P6 P7 P8 P9 P10 P11 P12 P13 P14 P15 P16 P17 P18 P19 P20 P21 P22 P23 P24 P25 P26 P27 P28 P29 P30 P31 P32 P33 P34 P35 P36 P37 P38 P39 P40 P41 P42 P43 P44 P45 P46 P47 PCIN0 PCIN1 PCIN2 PCIN3 PCIN4 PCIN5 PCIN6 PCIN7 PCIN8 PCIN9 PCIN10 PCIN11 PCIN12 PCIN13 PCIN14 PCIN15 PCIN16 PCIN17 PCIN18 PCIN19 PCIN20 PCIN21 PCIN22 PCIN23 PCIN24 PCIN25 PCIN26 PCIN27 PCIN28 PCIN29 PCIN30 PCIN31 PCIN32 PCIN33 PCIN34 PCIN35 PCIN36 PCIN37 PCIN38 PCIN39 PCIN40 PCIN41 PCIN42 PCIN43 PCIN44 PCIN45 PCIN46 PCIN47 PCOUT0 PCOUT1 PCOUT2 PCOUT3 PCOUT4 PCOUT5 PCOUT6 PCOUT7 PCOUT8 PCOUT9 PCOUT10 PCOUT11 PCOUT12 PCOUT13 PCOUT14 PCOUT15 PCOUT16 PCOUT17 PCOUT18 PCOUT19 PCOUT20 PCOUT21 PCOUT22 PCOUT23 PCOUT24 PCOUT25 PCOUT26 PCOUT27 PCOUT28 PCOUT29 PCOUT30 PCOUT31 PCOUT32 PCOUT33 PCOUT34 PCOUT35 PCOUT36 PCOUT37 PCOUT38 PCOUT39 PCOUT40 PCOUT41 PCOUT42 PCOUT43 PCOUT44 PCOUT45 PCOUT46 PCOUT47 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P0 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P1 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P2 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P3 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P4 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P5 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P6 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P7 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P8 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P9 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P10 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P11 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P12 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P13 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P14 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P15 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P16 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P17 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P18 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P19 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P20 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P21 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P22 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P23 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P24 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P25 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P26 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P27 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P28 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P29 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P30 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P31 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P32 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P33 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P34 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P35 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P36 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P37 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P38 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P39 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P40 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P41 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P42 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P43 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P44 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P45 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P46 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P47 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT0 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT1 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT2 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT3 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT4 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT5 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT6 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT7 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT8 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT9 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT10 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT11 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT12 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT13 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT14 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT15 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT16 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT17 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT18 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT19 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT20 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT21 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT22 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT23 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT24 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT25 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT26 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT27 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT28 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT29 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT30 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT31 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT32 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT33 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT34 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT35 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT36 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT37 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT38 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT39 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT40 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT41 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT42 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT43 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT44 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT45 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT46 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT47 -$__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 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 - - 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 - - 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 - - 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 - - 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 - - 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 - - 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 - - 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 - - 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 - - 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 - - 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 - - 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 - - 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 - - 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 - - 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 - - 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 - - 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 - - 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 - - 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -$__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 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 - - 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 - - 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 - - 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 - - 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 - - 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 - - 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 - - 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 - - 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 - - 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 - - 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 - - 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 - - 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 - - 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 - - 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 - - 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 - - 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 - - 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 - - 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 - - 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 - - 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 - - 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 - - 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 - - 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 - - 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 - - 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 - - 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 - - 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 - - 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 - - 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 - - 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 - - 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 - - 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 - - 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 - - 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 - - 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 - - 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 - - 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 - - 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 - - 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 - - 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 - - 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 - - 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 3717 - - 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -$__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 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 - - 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 - - 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 - - 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 - - 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 - - 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 - - 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 - - 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 - - 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 - - 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 - - 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 - - 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 - - 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 - - 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 - - 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 - - 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 - - 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 - - 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 - - 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 - - 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +$__ABC9_DSP48E1_MULT_DPORT 3001 0 265 96 +#A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11 A12 A13 A14 A15 A16 A17 A18 A19 A20 A21 A22 A23 A24 A25 A26 A27 A28 A29 B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 B10 B11 B12 B13 B14 B15 B16 B17 C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 C10 C11 C12 C13 C14 C15 C16 C17 C18 C19 C20 C21 C22 C23 C24 C25 C26 C27 C28 C29 C30 C31 C32 C33 C34 C35 C36 C37 C38 C39 C40 C41 C42 C43 C44 C45 C46 C47 D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 D10 D11 D12 D13 D14 D15 D16 D17 D18 D19 D20 D21 D22 D23 D24 P0 P1 P2 P3 P4 P5 P6 P7 P8 P9 P10 P11 P12 P13 P14 P15 P16 P17 P18 P19 P20 P21 P22 P23 P24 P25 P26 P27 P28 P29 P30 P31 P32 P33 P34 P35 P36 P37 P38 P39 P40 P41 P42 P43 P44 P45 P46 P47 PCIN0 PCIN1 PCIN2 PCIN3 PCIN4 PCIN5 PCIN6 PCIN7 PCIN8 PCIN9 PCIN10 PCIN11 PCIN12 PCIN13 PCIN14 PCIN15 PCIN16 PCIN17 PCIN18 PCIN19 PCIN20 PCIN21 PCIN22 PCIN23 PCIN24 PCIN25 PCIN26 PCIN27 PCIN28 PCIN29 PCIN30 PCIN31 PCIN32 PCIN33 PCIN34 PCIN35 PCIN36 PCIN37 PCIN38 PCIN39 PCIN40 PCIN41 PCIN42 PCIN43 PCIN44 PCIN45 PCIN46 PCIN47 PCOUT0 PCOUT1 PCOUT2 PCOUT3 PCOUT4 PCOUT5 PCOUT6 PCOUT7 PCOUT8 PCOUT9 PCOUT10 PCOUT11 PCOUT12 PCOUT13 PCOUT14 PCOUT15 PCOUT16 PCOUT17 PCOUT18 PCOUT19 PCOUT20 PCOUT21 PCOUT22 PCOUT23 PCOUT24 PCOUT25 PCOUT26 PCOUT27 PCOUT28 PCOUT29 PCOUT30 PCOUT31 PCOUT32 PCOUT33 PCOUT34 PCOUT35 PCOUT36 PCOUT37 PCOUT38 PCOUT39 PCOUT40 PCOUT41 PCOUT42 PCOUT43 PCOUT44 PCOUT45 PCOUT46 PCOUT47 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P0 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P1 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P2 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P3 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P4 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P5 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P6 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P7 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P8 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P9 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P10 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P11 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P12 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P13 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P14 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P15 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P16 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P17 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P18 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P19 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P20 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P21 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P22 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P23 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P24 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P25 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P26 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P27 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P28 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P29 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P30 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P31 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P32 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P33 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P34 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P35 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P36 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P37 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P38 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P39 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P40 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P41 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P42 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P43 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P44 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P45 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P46 +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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P47 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT0 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT1 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT2 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT3 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT4 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT5 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT6 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT7 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT8 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT9 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT10 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT11 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT12 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT13 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT14 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT15 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT16 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT17 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT18 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT19 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT20 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT21 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT22 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT23 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT24 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT25 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT26 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT27 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT28 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT29 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT30 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT31 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT32 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT33 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT34 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT35 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT36 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT37 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT38 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT39 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT40 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT41 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT42 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT43 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT44 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT45 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT46 +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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT47 + +$__ABC9_DSP48E1 3002 0 265 96 +#A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11 A12 A13 A14 A15 A16 A17 A18 A19 A20 A21 A22 A23 A24 A25 A26 A27 A28 A29 B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 B10 B11 B12 B13 B14 B15 B16 B17 C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 C10 C11 C12 C13 C14 C15 C16 C17 C18 C19 C20 C21 C22 C23 C24 C25 C26 C27 C28 C29 C30 C31 C32 C33 C34 C35 C36 C37 C38 C39 C40 C41 C42 C43 C44 C45 C46 C47 D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 D10 D11 D12 D13 D14 D15 D16 D17 D18 D19 D20 D21 D22 D23 D24 P0 P1 P2 P3 P4 P5 P6 P7 P8 P9 P10 P11 P12 P13 P14 P15 P16 P17 P18 P19 P20 P21 P22 P23 P24 P25 P26 P27 P28 P29 P30 P31 P32 P33 P34 P35 P36 P37 P38 P39 P40 P41 P42 P43 P44 P45 P46 P47 PCIN0 PCIN1 PCIN2 PCIN3 PCIN4 PCIN5 PCIN6 PCIN7 PCIN8 PCIN9 PCIN10 PCIN11 PCIN12 PCIN13 PCIN14 PCIN15 PCIN16 PCIN17 PCIN18 PCIN19 PCIN20 PCIN21 PCIN22 PCIN23 PCIN24 PCIN25 PCIN26 PCIN27 PCIN28 PCIN29 PCIN30 PCIN31 PCIN32 PCIN33 PCIN34 PCIN35 PCIN36 PCIN37 PCIN38 PCIN39 PCIN40 PCIN41 PCIN42 PCIN43 PCIN44 PCIN45 PCIN46 PCIN47 PCOUT0 PCOUT1 PCOUT2 PCOUT3 PCOUT4 PCOUT5 PCOUT6 PCOUT7 PCOUT8 PCOUT9 PCOUT10 PCOUT11 PCOUT12 PCOUT13 PCOUT14 PCOUT15 PCOUT16 PCOUT17 PCOUT18 PCOUT19 PCOUT20 PCOUT21 PCOUT22 PCOUT23 PCOUT24 PCOUT25 PCOUT26 PCOUT27 PCOUT28 PCOUT29 PCOUT30 PCOUT31 PCOUT32 PCOUT33 PCOUT34 PCOUT35 PCOUT36 PCOUT37 PCOUT38 PCOUT39 PCOUT40 PCOUT41 PCOUT42 PCOUT43 PCOUT44 PCOUT45 PCOUT46 PCOUT47 +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 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P0 +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 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P1 +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 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P2 +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 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P3 +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 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P4 +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 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P5 +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 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P6 +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 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P7 +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 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P8 +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 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P9 +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 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P10 +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 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P11 +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 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P12 +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 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P13 +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 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P14 +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 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P15 +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 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P16 +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 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P17 +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 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P18 +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 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P19 +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 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P20 +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 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P21 +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 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P22 +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 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P23 +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 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P24 +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 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P25 +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 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P26 +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 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P27 +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 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P28 +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 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P29 +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 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P30 +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 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P31 +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 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P32 +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 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P33 +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 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P34 +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 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P35 +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 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P36 +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 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P37 +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 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P38 +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 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P39 +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 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P40 +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 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P41 +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 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P42 +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 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P43 +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 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P44 +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 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P45 +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 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P46 +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 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P47 +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 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT0 +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 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT1 +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 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT2 +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 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT3 +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 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT4 +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 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT5 +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 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT6 +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 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT7 +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 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT8 +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 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT9 +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 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT10 +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 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT11 +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 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT12 +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 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT13 +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 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT14 +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 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT15 +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 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT16 +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 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT17 +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 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT18 +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 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT19 +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 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT20 +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 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT21 +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 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT22 +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 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT23 +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 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT24 +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 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT25 +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 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT26 +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 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT27 +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 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT28 +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 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT29 +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 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT30 +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 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT31 +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 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT32 +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 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT33 +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 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT34 +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 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT35 +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 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT36 +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 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT37 +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 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT38 +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 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT39 +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 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT40 +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 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT41 +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 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT42 +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 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT43 +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 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT44 +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 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT45 +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 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT46 +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 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT47 diff --git a/techlibs/xilinx/cells_sim.v b/techlibs/xilinx/cells_sim.v index 72e684af5..d705451fe 100644 --- a/techlibs/xilinx/cells_sim.v +++ b/techlibs/xilinx/cells_sim.v @@ -2160,9 +2160,15 @@ module DSP48E1 ( output reg [3:0] CARRYOUT, output reg MULTSIGNOUT, output OVERFLOW, +`ifndef __ICARUS__ + (* abc9_arrival = \DSP48E1.P_arrival (USE_MULT, USE_DPORT, AREG, ADREG, BREG, CREG, DREG, MREG, PREG) *) +`endif output reg signed [47:0] P, output reg PATTERNBDETECT, output reg PATTERNDETECT, +`ifndef __ICARUS__ + (* abc9_arrival = \DSP48E1.PCOUT_arrival (USE_MULT, USE_DPORT, AREG, ADREG, BREG, CREG, DREG, MREG, PREG) *) +`endif output [47:0] PCOUT, output UNDERFLOW, input signed [29:0] A, @@ -2235,6 +2241,79 @@ module DSP48E1 ( parameter [4:0] IS_INMODE_INVERTED = 5'b0; parameter [6:0] IS_OPMODE_INVERTED = 7'b0; + function \DSP48E1.P_arrival ; + input USE_MULT, USE_DPORT; + input AREG, ADREG, BREG, CREG, DREG, MREG, PREG; + begin + \DSP48E1.P_arrival = 0; + if (USE_MULT == "MULTIPLY" && USE_DPORT == "FALSE") begin + if (PREG != 0) \DSP48E1.P_arrival = 329; + // Worse-case from CREG and MREG + else if (CREG != 0) \DSP48E1.P_arrival = 1687; + else if (MREG != 0) \DSP48E1.P_arrival = 1671; + // Worse-case from AREG and BREG + else if (AREG != 0) \DSP48E1.P_arrival = 2952; + else if (BREG != 0) \DSP48E1.P_arrival = 2813; + end + else if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE") begin + if (PREG != 0) \DSP48E1.P_arrival = 329; + // Worse-case from CREG and MREG + else if (CREG != 0) \DSP48E1.P_arrival = 1687; + else if (MREG != 0) \DSP48E1.P_arrival = 1671; + // Worse-case from AREG, ADREG, BREG, DREG + else if (AREG != 0) \DSP48E1.P_arrival = 3935; + else if (DREG != 0) \DSP48E1.P_arrival = 3908; + else if (ADREG != 0) \DSP48E1.P_arrival = 2958; + else if (BREG != 0) \DSP48E1.P_arrival = 2813; + end + else if (USE_MULT == "NONE" && USE_DPORT == "FALSE") begin + if (PREG != 0) \DSP48E1.P_arrival = 329; + // Worse-case from AREG, BREG, CREG + else if (CREG != 0) \DSP48E1.P_arrival = 1687; + else if (AREG != 0) \DSP48E1.P_arrival = 1632; + else if (BREG != 0) \DSP48E1.P_arrival = 1616; + end + //else + // $error("Invalid DSP48E1 configuration"); + end + endfunction + function \DSP48E1.PCOUT_arrival ; + input USE_MULT, USE_DPORT; + input AREG, ADREG, BREG, CREG, DREG, MREG, PREG; + begin + \DSP48E1.PCOUT_arrival = 0; + if (USE_MULT == "MULTIPLY" && USE_DPORT == "FALSE") begin + if (PREG != 0) \DSP48E1.PCOUT_arrival = 435; + // Worse-case from CREG and MREG + else if (CREG != 0) \DSP48E1.PCOUT_arrival = 1835; + else if (MREG != 0) \DSP48E1.PCOUT_arrival = 1819; + // Worse-case from AREG and BREG + else if (AREG != 0) \DSP48E1.PCOUT_arrival = 3098; + else if (BREG != 0) \DSP48E1.PCOUT_arrival = 2960; + end + else if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE") begin + if (PREG != 0) \DSP48E1.PCOUT_arrival = 435; + // Worse-case from CREG and MREG + else if (CREG != 0) \DSP48E1.PCOUT_arrival = 1835; + else if (MREG != 0) \DSP48E1.PCOUT_arrival = 1819; + // Worse-case from AREG, ADREG, BREG, DREG + else if (AREG != 0) \DSP48E1.PCOUT_arrival = 4083; + else if (DREG != 0) \DSP48E1.PCOUT_arrival = 4056; + else if (BREG != 0) \DSP48E1.PCOUT_arrival = 2960; + else if (ADREG != 0) \DSP48E1.PCOUT_arrival = 2859; + end + else if (USE_MULT == "NONE" && USE_DPORT == "FALSE") begin + if (PREG != 0) \DSP48E1.PCOUT_arrival = 435; + // Worse-case from AREG, BREG, CREG + else if (CREG != 0) \DSP48E1.PCOUT_arrival = 1835; + else if (AREG != 0) \DSP48E1.PCOUT_arrival = 1780; + else if (BREG != 0) \DSP48E1.PCOUT_arrival = 1765; + end + //else + // $error("Invalid DSP48E1 configuration"); + end + endfunction + initial begin `ifdef __ICARUS__ if (AUTORESET_PATDET != "NO_RESET") $fatal(1, "Unsupported AUTORESET_PATDET value"); -- cgit v1.2.3 From 3d98a9627312c283715a691995466568a33ce7a2 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 1 Jan 2020 17:33:10 -0800 Subject: ifdef __ICARUS__ -> ifndef YOSYS --- techlibs/xilinx/cells_sim.v | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/techlibs/xilinx/cells_sim.v b/techlibs/xilinx/cells_sim.v index 72e684af5..c27b0f02b 100644 --- a/techlibs/xilinx/cells_sim.v +++ b/techlibs/xilinx/cells_sim.v @@ -2236,7 +2236,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"); @@ -2399,12 +2399,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 @@ -2416,7 +2416,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 @@ -2430,13 +2430,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 -- cgit v1.2.3 From d0d3ab8f676cd355d74cb7b7f71fc5bfca0719a2 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 1 Jan 2020 17:33:47 -0800 Subject: ifndef __ICARUS__ -> ifdef YOSYS --- techlibs/xilinx/cells_sim.v | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/techlibs/xilinx/cells_sim.v b/techlibs/xilinx/cells_sim.v index d705451fe..2947fe692 100644 --- a/techlibs/xilinx/cells_sim.v +++ b/techlibs/xilinx/cells_sim.v @@ -2160,13 +2160,13 @@ module DSP48E1 ( output reg [3:0] CARRYOUT, output reg MULTSIGNOUT, output OVERFLOW, -`ifndef __ICARUS__ +`ifdef YOSYS (* abc9_arrival = \DSP48E1.P_arrival (USE_MULT, USE_DPORT, AREG, ADREG, BREG, CREG, DREG, MREG, PREG) *) `endif output reg signed [47:0] P, output reg PATTERNBDETECT, output reg PATTERNDETECT, -`ifndef __ICARUS__ +`ifdef YOSYS (* abc9_arrival = \DSP48E1.PCOUT_arrival (USE_MULT, USE_DPORT, AREG, ADREG, BREG, CREG, DREG, MREG, PREG) *) `endif output [47:0] PCOUT, -- cgit v1.2.3 From 3edb2e708b09c7c9ead2aeb11e2be3cae88f8ee5 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 2 Jan 2020 18:58:45 +0100 Subject: Always create $shl, $shr, $sshl, $sshr cells with unsigned B inputs Signed-off-by: Clifford Wolf --- kernel/rtlil.cc | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) 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); \ -- cgit v1.2.3 From 8e507bd80785db9fa6723eada4214a5a06516cae Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 2 Jan 2020 12:36:54 -0800 Subject: abc9 -keepff -> -dff; refactor dff operations --- backends/aiger/xaiger.cc | 136 ++++++++++++++-------------------------- passes/techmap/abc9.cc | 49 +++++++++------ techlibs/xilinx/abc9_map.v | 110 ++++++++++++++++---------------- techlibs/xilinx/synth_xilinx.cc | 6 +- 4 files changed, 135 insertions(+), 166 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 9c6152dff..053f9d835 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -82,7 +82,7 @@ struct XAigerWriter dict not_map, alias_map; dict> and_map; vector ci_bits, co_bits; - dict> ff_bits; + dict ff_bits; dict arrival_times; vector> aig_gates; @@ -204,7 +204,6 @@ struct XAigerWriter dict> bit_drivers, bit_users; TopoSort toposort; bool abc9_box_seen = false; - std::vector flop_boxes; for (auto cell : module->selected_cells()) { if (cell->type == "$_NOT_") @@ -236,14 +235,17 @@ struct XAigerWriter continue; } - if (cell->type == "$__ABC9_FF_") + 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 = ff_bits.insert(std::make_pair(D, std::make_tuple(Q, 0, 2))); + auto r YS_ATTRIBUTE(unused) = ff_bits.insert(std::make_pair(D, cell)); log_assert(r.second); continue; } @@ -252,14 +254,25 @@ struct XAigerWriter if (inst_module) { bool abc9_box = inst_module->attributes.count("\\abc9_box_id"); bool abc9_flop = inst_module->get_bool_attribute("\\abc9_flop"); - // The lack of an abc9_mergeability attribute indicates that - // we do want to keep this flop, so do not treat it as a box - if (abc9_flop && !cell->attributes.count("\\abc9_mergeability")) + if (abc9_box && cell->get_bool_attribute("\\abc9_keep")) abc9_box = false; for (const auto &conn : cell->connections()) { auto port_wire = inst_module->wire(conn.first); + if (abc9_box) { + // Ignore inout for the sake of topographical ordering + if (port_wire->port_input && !port_wire->port_output) + for (auto bit : sigmap(conn.second)) + bit_users[bit].insert(cell->name); + if (port_wire->port_output) + for (auto bit : sigmap(conn.second)) + bit_drivers[bit].insert(cell->name); + + if (!abc9_flop) + continue; + } + if (port_wire->port_output) { int arrival = 0; auto it = port_wire->attributes.find("\\abc9_arrival"); @@ -272,25 +285,11 @@ struct XAigerWriter for (auto bit : sigmap(conn.second)) arrival_times[bit] = arrival; } - - if (abc9_box) { - // Ignore inout for the sake of topographical ordering - if (port_wire->port_input && !port_wire->port_output) - for (auto bit : sigmap(conn.second)) - bit_users[bit].insert(cell->name); - if (port_wire->port_output) - for (auto bit : sigmap(conn.second)) - bit_drivers[bit].insert(cell->name); - } } if (abc9_box) { abc9_box_seen = true; - toposort.node(cell->name); - - if (abc9_flop) - flop_boxes.push_back(cell); continue; } } @@ -321,61 +320,6 @@ struct XAigerWriter } if (abc9_box_seen) { - dict> flop_q; - for (auto cell : flop_boxes) { - auto r = flop_q.insert(std::make_pair(cell->type, std::make_pair(IdString(), 0))); - SigBit d; - if (r.second) { - for (const auto &conn : cell->connections()) { - if (!conn.second.is_bit()) - continue; - d = conn.second; - if (!ff_bits.count(d)) - continue; - - r.first->second.first = conn.first; - Module *inst_module = module->design->module(cell->type); - Wire *wire = inst_module->wire(conn.first); - log_assert(wire); - auto jt = wire->attributes.find("\\abc9_arrival"); - if (jt != wire->attributes.end()) { - if (jt->second.flags != 0) - log_error("Attribute 'abc9_arrival' on port '%s' of module '%s' is not an integer.\n", log_id(wire), log_id(cell->type)); - r.first->second.second = jt->second.as_int(); - } - log_assert(d == sigmap(d)); - break; - } - } - else - d = cell->getPort(r.first->second.first); - - auto &rhs = ff_bits.at(d); - - auto it = cell->attributes.find(ID(abc9_mergeability)); - log_assert(it != cell->attributes.end()); - std::get<1>(rhs) = it->second.as_int(); - cell->attributes.erase(it); - - it = cell->attributes.find(ID(abc9_init)); - log_assert(it != cell->attributes.end()); - log_assert(GetSize(it->second) == 1); - if (it->second[0] == State::S1) - std::get<2>(rhs) = 1; - else if (it->second[0] == State::S0) - std::get<2>(rhs) = 0; - else { - log_assert(it->second[0] == State::Sx); - std::get<2>(rhs) = 0; - } - cell->attributes.erase(it); - - const SigBit &q = std::get<0>(rhs); - auto arrival = r.first->second.second; - if (arrival) - arrival_times[q] = arrival; - } - for (auto &it : bit_users) if (bit_drivers.count(it.first)) for (auto driver_cell : bit_drivers.at(it.first)) @@ -501,11 +445,11 @@ struct XAigerWriter } } - // Connect .$abc9_currQ (inserted by abc9_map.v) as an input to the flop box + // Connect .abc9_ff.Q (inserted by abc9_map.v) as the last input to the flop box if (box_module->get_bool_attribute("\\abc9_flop")) { - SigSpec rhs = module->wire(stringf("%s.$abc9_currQ", cell->name.c_str())); + SigSpec rhs = module->wire(stringf("%s.abc9_ff.Q", cell->name.c_str())); if (rhs.empty()) - log_error("'%s.$abc9_currQ' is not a wire present in module '%s'.\n", log_id(cell), log_id(module)); + 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); @@ -553,7 +497,8 @@ struct XAigerWriter } for (const auto &i : ff_bits) { - const SigBit &q = std::get<0>(i.second); + const Cell *cell = i.second; + const SigBit &q = sigmap(cell->getPort("\\Q")); aig_m++, aig_i++; log_assert(!aig_map.count(q)); aig_map[q] = 2*aig_m; @@ -742,7 +687,7 @@ struct XAigerWriter } // For flops only, create an extra 1-bit input that drives a new wire - // called ".$abc9_currQ" that is used below + // called ".abc9_ff.Q" that is used below if (box_module->get_bool_attribute("\\abc9_flop")) { log_assert(holes_cell); @@ -754,7 +699,8 @@ struct XAigerWriter holes_wire->port_id = port_id++; holes_module->ports.push_back(holes_wire->name); } - Wire *w = holes_module->addWire(stringf("%s.$abc9_currQ", cell->name.c_str())); + Wire *w = holes_module->addWire(stringf("%s.abc9_ff.Q", cell->name.c_str())); + log_assert(w); holes_module->connect(w, holes_wire); } @@ -774,13 +720,25 @@ struct XAigerWriter write_s_buffer(ff_bits.size()); for (const auto &i : ff_bits) { - const SigBit &q = std::get<0>(i.second); - int mergeability = std::get<1>(i.second); + 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); - int init = std::get<2>(i.second); - write_s_buffer(init); - write_i_buffer(arrival_times.at(q, 0)); + + 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); } @@ -833,9 +791,9 @@ struct XAigerWriter log_assert(pos != std::string::npos); IdString driver = Q.wire->name.substr(0, pos); // And drive the signal that was previously driven by "DFF.Q" (typically - // used to implement clock-enable functionality) with the ".$abc9_currQ" + // used to implement clock-enable functionality) with the ".abc9_ff.Q" // wire (which itself is driven an input port) we inserted above - Wire *currQ = holes_module->wire(stringf("%s.$abc9_currQ", driver.c_str())); + Wire *currQ = holes_module->wire(stringf("%s.abc9_ff.Q", driver.c_str())); log_assert(currQ); holes_module->connect(Q, currQ); continue; diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index c3c8e0dbc..6aa0b6f95 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -249,7 +249,7 @@ struct abc9_output_filter }; void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string script_file, std::string exe_file, - bool cleanup, vector lut_costs, bool keepff, std::string delay_target, std::string /*lutin_shared*/, bool fast_mode, + bool cleanup, vector lut_costs, bool dff, 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 ) @@ -347,7 +347,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip 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 */); + AigerReader reader(design, ifs, ID($__abc9__), "" /* clk_name */, /*buffer.c_str()*/ "" /* map_filename */, true /* wideports */); reader.parse_xaiger(); } ifs.close(); @@ -430,7 +430,13 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip if (jt == abc9_box.end()) jt = abc9_box.insert(std::make_pair(cell->type, box_module && box_module->attributes.count(ID(abc9_box_id)))).first; if (jt->second) { - if (!keepff || !box_module->get_bool_attribute("\\abc9_flop")) + if (box_module->get_bool_attribute("\\abc9_flop")) { + if (dff) + boxes.emplace_back(cell); + else + box_module->set_bool_attribute("\\abc9_keep", false); + } + else boxes.emplace_back(cell); } } @@ -795,9 +801,9 @@ 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(" -keepff\n"); - log(" do not represent (* abc9_flop *) modules as boxes (and thus do not perform\n"); - log(" any form of sequential synthesis).\n"); + log(" -dff\n"); + log(" also pass $_ABC9_FF_ cells through ABC. modules with many clock domains\n"); + log(" 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"); @@ -837,7 +843,7 @@ struct Abc9Pass : public Pass { #endif std::string script_file, clk_str, box_file, lut_file; std::string delay_target, lutin_shared = "-S 1", wire_delay; - bool fast_mode = false, keepff = false, cleanup = true; + bool fast_mode = false, dff = false, cleanup = true; bool show_tempdir = false; bool nomfs = false; vector lut_costs; @@ -928,8 +934,8 @@ struct Abc9Pass : public Pass { fast_mode = true; continue; } - if (arg == "-keepff") { - keepff = true; + if (arg == "-dff") { + dff = true; continue; } if (arg == "-nocleanup") { @@ -985,16 +991,14 @@ struct Abc9Pass : public Pass { typedef SigSpec clkdomain_t; dict clk_to_mergeability; - - if (!keepff) + if (dff) for (auto cell : module->selected_cells()) { - auto inst_module = design->module(cell->type); - if (!inst_module || !inst_module->get_bool_attribute("\\abc9_flop")) + if (cell->type != "$__ABC9_FF_") continue; - Wire *abc9_clock_wire = module->wire(stringf("%s.$abc9_clock", cell->name.c_str())); + Wire *abc9_clock_wire = module->wire(stringf("%s.clock", cell->name.c_str())); if (abc9_clock_wire == NULL) - log_error("'%s$abc9_clock' is not a wire present in module '%s'.\n", cell->name.c_str(), log_id(module)); + 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); @@ -1003,19 +1007,26 @@ struct Abc9Pass : public Pass { 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.$abc9_init", cell->name.c_str())); + Wire *abc9_init_wire = module->wire(stringf("%s.init", cell->name.c_str())); if (abc9_init_wire == NULL) - log_error("'%s.$abc9_init' is not a wire present in module '%s'.\n", cell->name.c_str(), log_id(module)); + 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.$abc9_init' is not a constant wire present in module '%s'.\n", cell->name.c_str(), log_id(module)); + 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); } + else + for (auto cell : module->selected_cells()) { + auto inst_module = design->module(cell->type); + if (!inst_module || !inst_module->get_bool_attribute("\\abc9_flop")) + continue; + cell->set_bool_attribute("\\abc9_keep"); + } design->selected_active_module = module->name.str(); - abc9_module(design, module, script_file, exe_file, cleanup, lut_costs, keepff, + abc9_module(design, module, script_file, exe_file, cleanup, lut_costs, dff, delay_target, lutin_shared, fast_mode, show_tempdir, box_file, lut_file, wire_delay, nomfs); design->selected_active_module.clear(); diff --git a/techlibs/xilinx/abc9_map.v b/techlibs/xilinx/abc9_map.v index 1b58c34c0..1d37952f5 100644 --- a/techlibs/xilinx/abc9_map.v +++ b/techlibs/xilinx/abc9_map.v @@ -51,29 +51,29 @@ // || || // || /\/\/\/\ || // D -->>-----< > || -// R -->>-----< Comb. > || +----------+ -// CE -->>-----< logic >--->>-- $Q --|$__ABC_FF_|--+-->> Q -// $abc9_currQ +-->>-----< > || +----------+ | -// | || \/\/\/\/ || | -// | || || | -// | ++==================++ | -// | | -// +----------------------------------------------+ +// 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 _TECHMAP_REPLACE_.$abc9_clock wire to capture its clock +// (c) a special _TECHMAP_REPLACE_.abc9_ff.clock wire to capture its clock // domain and polarity (used when partitioning the module so that `abc9' only // performs sequential synthesis (with reachability analysis) correctly on // one domain at a time) and also used to infer the optional delay target // from the (* abc9_clock_period = %d *) attribute attached to any wire // within -// (d) a special _TECHMAP_REPLACE_.$abc9_init wire to encode the flop's initial +// (d) a special _TECHMAP_REPLACE_.abc9_ff.init wire to encode the flop's initial // state -// (e) a special _TECHMAP_REPLACE_.$abc9_currQ wire that will be used for feedback +// (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 // // In order to perform sequential synthesis, `abc9' also requires that @@ -108,12 +108,12 @@ module FDRE (output Q, input C, CE, D, R); ); end endgenerate - $__ABC9_FF_ abc_dff (.D($Q), .Q(QQ)); + $__ABC9_FF_ abc9_ff (.D($Q), .Q(QQ)); // Special signals - wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, IS_C_INVERTED}; - wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; - wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = QQ; + 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; @@ -135,12 +135,12 @@ module FDRE_1 (output Q, input C, CE, D, R); ); end endgenerate - $__ABC9_FF_ abc_dff (.D($Q), .Q(QQ)); + $__ABC9_FF_ abc9_ff (.D($Q), .Q(QQ)); // Special signals - wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */}; - wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; - wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = QQ; + 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); @@ -171,12 +171,12 @@ module FDSE (output Q, input C, CE, D, S); .D(D), .Q($Q), .C(C), .CE(CE), .S(S) ); end endgenerate - $__ABC9_FF_ abc_dff (.D($Q), .Q(QQ)); + $__ABC9_FF_ abc9_ff (.D($Q), .Q(QQ)); // Special signals - wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, IS_C_INVERTED}; - wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; - wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = QQ; + 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; @@ -197,12 +197,12 @@ module FDSE_1 (output Q, input C, CE, D, S); .D(D), .Q($Q), .C(C), .CE(CE), .S(S) ); end endgenerate - $__ABC9_FF_ abc_dff (.D($Q), .Q(QQ)); + $__ABC9_FF_ abc9_ff (.D($Q), .Q(QQ)); // Special signals - wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */}; - wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; - wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = QQ; + 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); @@ -210,7 +210,7 @@ module FDCE (output Q, input C, CE, D, CLR); 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, $abc9_currQ; + wire QQ, $Q, $QQ; generate if (INIT == 1'b1) begin assign Q = ~QQ; FDPE #( @@ -227,7 +227,7 @@ module FDCE (output Q, input C, CE, D, CLR); // $__ABC9_ASYNC1 below ); // Since this is an async flop, async behaviour is dealt with here - $__ABC9_ASYNC1 abc_async (.A($abc9_currQ), .S(CLR ^ IS_CLR_INVERTED), .Y(QQ)); + $__ABC9_ASYNC1 abc_async (.A($QQ), .S(CLR ^ IS_CLR_INVERTED), .Y(QQ)); end else begin assign Q = QQ; @@ -245,18 +245,18 @@ module FDCE (output Q, input C, CE, D, CLR); // $__ABC9_ASYNC0 below ); // Since this is an async flop, async behaviour is dealt with here - $__ABC9_ASYNC0 abc_async (.A($abc9_currQ), .S(CLR ^ IS_CLR_INVERTED), .Y(QQ)); + $__ABC9_ASYNC0 abc_async (.A($QQ), .S(CLR ^ IS_CLR_INVERTED), .Y(QQ)); end endgenerate - $__ABC9_FF_ abc_dff (.D($Q), .Q($abc9_currQ)); + $__ABC9_FF_ abc9_ff (.D($Q), .Q($QQ)); // Special signals - wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, IS_C_INVERTED}; - wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; - wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ; + 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, $abc9_currQ; + wire QQ, $Q, $QQ; generate if (INIT == 1'b1) begin assign Q = ~QQ; FDPE_1 #( @@ -269,7 +269,7 @@ module FDCE_1 (output Q, input C, CE, D, CLR); // behaviour is captured by // $__ABC9_ASYNC1 below ); - $__ABC9_ASYNC1 abc_async (.A($abc9_currQ), .S(CLR), .Y(QQ)); + $__ABC9_ASYNC1 abc_async (.A($QQ), .S(CLR), .Y(QQ)); end else begin assign Q = QQ; @@ -283,14 +283,14 @@ module FDCE_1 (output Q, input C, CE, D, CLR); // behaviour is captured by // $__ABC9_ASYNC0 below ); - $__ABC9_ASYNC0 abc_async (.A($abc9_currQ), .S(CLR), .Y(QQ)); + $__ABC9_ASYNC0 abc_async (.A($QQ), .S(CLR), .Y(QQ)); end endgenerate - $__ABC9_FF_ abc_dff (.D($Q), .Q($abc9_currQ)); + $__ABC9_FF_ abc9_ff (.D($Q), .Q($QQ)); // Special signals - wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */}; - wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; - wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ; + 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); @@ -298,7 +298,7 @@ module FDPE (output Q, input C, CE, D, PRE); 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, $abc9_currQ; + wire QQ, $Q, $QQ; generate if (INIT == 1'b1) begin assign Q = ~QQ; FDCE #( @@ -314,7 +314,7 @@ module FDPE (output Q, input C, CE, D, PRE); // behaviour is captured by // $__ABC9_ASYNC0 below ); - $__ABC9_ASYNC0 abc_async (.A($abc9_currQ), .S(PRE ^ IS_PRE_INVERTED), .Y(QQ)); + $__ABC9_ASYNC0 abc_async (.A($QQ), .S(PRE ^ IS_PRE_INVERTED), .Y(QQ)); end else begin assign Q = QQ; @@ -331,18 +331,18 @@ module FDPE (output Q, input C, CE, D, PRE); // behaviour is captured by // $__ABC9_ASYNC1 below ); - $__ABC9_ASYNC1 abc_async (.A($abc9_currQ), .S(PRE ^ IS_PRE_INVERTED), .Y(QQ)); + $__ABC9_ASYNC1 abc_async (.A($QQ), .S(PRE ^ IS_PRE_INVERTED), .Y(QQ)); end endgenerate - $__ABC9_FF_ abc_dff (.D($Q), .Q($abc9_currQ)); + $__ABC9_FF_ abc9_ff (.D($Q), .Q($QQ)); // Special signals - wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, IS_C_INVERTED}; - wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; - wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ; + 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, $abc9_currQ; + wire QQ, $Q, $QQ; generate if (INIT == 1'b1) begin assign Q = ~QQ; FDCE_1 #( @@ -355,7 +355,7 @@ module FDPE_1 (output Q, input C, CE, D, PRE); // behaviour is captured by // $__ABC9_ASYNC0 below ); - $__ABC9_ASYNC0 abc_async (.A($abc9_currQ), .S(PRE), .Y(QQ)); + $__ABC9_ASYNC0 abc_async (.A($QQ), .S(PRE), .Y(QQ)); end else begin assign Q = QQ; @@ -369,14 +369,14 @@ module FDPE_1 (output Q, input C, CE, D, PRE); // behaviour is captured by // $__ABC9_ASYNC1 below ); - $__ABC9_ASYNC1 abc_async (.A($abc9_currQ), .S(PRE), .Y(QQ)); + $__ABC9_ASYNC1 abc_async (.A($QQ), .S(PRE), .Y(QQ)); end endgenerate - $__ABC9_FF_ abc_dff (.D($Q), .Q($abc9_currQ)); + $__ABC9_FF_ abc9_ff (.D($Q), .Q($QQ)); // Special signals - wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */}; - wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; - wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ; + 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 diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index 10aa7be5f..af9f21756 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -108,7 +108,7 @@ struct SynthXilinxPass : public ScriptPass log(" flatten design before synthesis\n"); log("\n"); log(" -dff\n"); - log(" enable sequential synthesis with 'abc9'\n"); + log(" run 'abc9' with -dff option\n"); log("\n"); log(" -retime\n"); log(" run 'abc' with -dff option\n"); @@ -559,8 +559,8 @@ 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 += " -keepff"; + if (dff_mode) + abc9_opts += " -dff"; run("abc9" + abc9_opts); run("techmap -map +/xilinx/abc9_unmap.v"); } -- cgit v1.2.3 From ec1756c0941fac02614c25307b17bb41fe36f468 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 2 Jan 2020 12:39:52 -0800 Subject: Update comments --- techlibs/xilinx/abc9_map.v | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/techlibs/xilinx/abc9_map.v b/techlibs/xilinx/abc9_map.v index 1d37952f5..af58e217c 100644 --- a/techlibs/xilinx/abc9_map.v +++ b/techlibs/xilinx/abc9_map.v @@ -65,19 +65,14 @@ // 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 _TECHMAP_REPLACE_.abc9_ff.clock wire to capture its clock -// domain and polarity (used when partitioning the module so that `abc9' only -// performs sequential synthesis (with reachability analysis) correctly on -// one domain at a time) and also used to infer the optional delay target -// from the (* abc9_clock_period = %d *) attribute attached to any wire -// within -// (d) a special _TECHMAP_REPLACE_.abc9_ff.init wire to encode the flop's initial -// state +// (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 -// -// In order to perform sequential synthesis, `abc9' also requires that -// the initial value of all flops be zero. module FDRE (output Q, input C, CE, D, R); parameter [0:0] INIT = 1'b0; -- cgit v1.2.3 From ca42af56a49a7ab3a55adab22f139d34ddb147b9 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 2 Jan 2020 12:41:57 -0800 Subject: Update doc --- passes/techmap/abc9.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 6aa0b6f95..d39aa7638 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -802,8 +802,8 @@ struct Abc9Pass : public Pass { log(" 2, 3, .. inputs.\n"); log("\n"); log(" -dff\n"); - log(" also pass $_ABC9_FF_ cells through ABC. modules with many clock domains\n"); - log(" are marked as such and automatically partitioned by ABC.\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"); @@ -825,8 +825,8 @@ 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 an XAIGER file with write_xaiger and then load that into ABC externally\n"); - log("if 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"); -- cgit v1.2.3 From 345e98f87105316da9797e01bdbdd3932269cfdf Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 2 Jan 2020 12:42:28 -0800 Subject: Add 'abc9 -dff' to CHANGELOG --- CHANGELOG | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG b/CHANGELOG index fc0cdc92e..481ba266e 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -57,6 +57,7 @@ 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 -- cgit v1.2.3 From a051801b72c7d526a1c04cf2635ae8d7fe43a135 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 2 Jan 2020 12:53:26 -0800 Subject: synth_xilinx -dff to work with abc too --- techlibs/xilinx/synth_xilinx.cc | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index e2a625f9b..51d2cbbd2 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -108,10 +108,11 @@ struct SynthXilinxPass : public ScriptPass log(" flatten design before synthesis\n"); log("\n"); log(" -dff\n"); - log(" run 'abc9' with -dff option\n"); + log(" run 'abc'/'abc9' with -dff option\n"); log("\n"); log(" -retime\n"); - log(" run 'abc' with '-dff -D 1' options\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"); @@ -195,6 +196,7 @@ struct SynthXilinxPass : public ScriptPass continue; } if (args[argidx] == "-retime") { + dff_mode = true; retime = true; continue; } @@ -542,7 +544,7 @@ 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, " @@ -565,10 +567,16 @@ struct SynthXilinxPass : public ScriptPass 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 -D 1" : "")); + abc_opts += " -luts 2:2,3,6:5"; else - run("abc -luts 2:2,3,6:5,10,20" + string(retime ? " -dff -D 1" : "")); + 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"); @@ -581,7 +589,7 @@ struct SynthXilinxPass : public ScriptPass 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, "(option without '-abc9')"); + run("techmap " + techmap_args, "(only if '-abc9')"); run("xilinx_dffopt"); } -- cgit v1.2.3 From 50b68777d3a79e283ab22388e686f615e520524d Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 2 Jan 2020 13:28:37 -0800 Subject: Drive $[ABCD] explicitly --- techlibs/xilinx/abc9_map.v | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/techlibs/xilinx/abc9_map.v b/techlibs/xilinx/abc9_map.v index e3e736e8f..cbe2a8cef 100644 --- a/techlibs/xilinx/abc9_map.v +++ b/techlibs/xilinx/abc9_map.v @@ -373,22 +373,28 @@ module DSP48E1 ( wire [47:0] $C; wire [24:0] $D; - if (PREG != 0) - assign P = $P, PCOUT = $PCOUT; - else begin - if (AREG == 0) assign $A = A; - if (BREG == 0) assign $B = B; - if (CREG == 0) assign $C = C; - if (DREG == 0) assign $D = D; + if (PREG == 0) begin + if (MREG == 0 && AREG == 0) assign $A = A; + else assign $A = 30'bx; + if (MREG == 0 && BREG == 0) assign $B = B; + else assign $B = 18'bx; + if (MREG == 0 && DREG == 0) assign $D = D; + else assign $D = 25'bx; - if (USE_MULT == "MULTIPLY" && USE_DPORT == "FALSE") - $__ABC9_DSP48E1_MULT dsp_comb(.$A($A), .$B($B), .$C($C), .$D($D), .$P($P), .$PCIN(PCIN), .$PCOUT($PCOUT), .P(P), .PCOUT(PCOUT)); - else if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE") - $__ABC9_DSP48E1_MULT_DPORT dsp_comb(.$A($A), .$B($B), .$C($C), .$D($D), .$P($P), .$PCIN(PCIN), .$PCOUT($PCOUT), .P(P), .PCOUT(PCOUT)); - else if (USE_MULT == "NONE" && USE_DPORT == "FALSE") - $__ABC9_DSP48E1 dsp_comb(.$A($A), .$B($B), .$C($C), .$D($D), .$P($P), .$PCIN(PCIN), .$PCOUT($PCOUT), .P(P), .PCOUT(PCOUT)); - else - $error("Invalid DSP48E1 configuration"); + if (CREG == 0) assign $C = C; + else assign $C = 48'bx; end + else begin + assign $A = 30'bx, $B = 18'bx, $C = 48'bx, $D = 25'bx; + end + + if (USE_MULT == "MULTIPLY" && USE_DPORT == "FALSE") + $__ABC9_DSP48E1_MULT dsp_comb(.$A($A), .$B($B), .$C($C), .$D($D), .$P($P), .$PCIN(PCIN), .$PCOUT($PCOUT), .P(P), .PCOUT(PCOUT)); + else if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE") + $__ABC9_DSP48E1_MULT_DPORT dsp_comb(.$A($A), .$B($B), .$C($C), .$D($D), .$P($P), .$PCIN(PCIN), .$PCOUT($PCOUT), .P(P), .PCOUT(PCOUT)); + else if (USE_MULT == "NONE" && USE_DPORT == "FALSE") + $__ABC9_DSP48E1 dsp_comb(.$A($A), .$B($B), .$C($C), .$D($D), .$P($P), .$PCIN(PCIN), .$PCOUT($PCOUT), .P(P), .PCOUT(PCOUT)); + else + $error("Invalid DSP48E1 configuration"); endgenerate endmodule -- cgit v1.2.3 From 6e866030c286d70f6ccff805e58b1fdd9a1a322b Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 2 Jan 2020 14:38:59 -0800 Subject: Combine tests to check multiple clock domains --- tests/arch/xilinx/abc9_dff.ys | 43 ++++++++++--------------------------------- 1 file changed, 10 insertions(+), 33 deletions(-) diff --git a/tests/arch/xilinx/abc9_dff.ys b/tests/arch/xilinx/abc9_dff.ys index 6611b4f18..b457cefce 100644 --- a/tests/arch/xilinx/abc9_dff.ys +++ b/tests/arch/xilinx/abc9_dff.ys @@ -1,55 +1,32 @@ read_verilog < Date: Thu, 2 Jan 2020 15:32:58 -0800 Subject: write_xaiger: get rid of external_bits dict --- backends/aiger/xaiger.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 053f9d835..2b456bb9a 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -78,7 +78,7 @@ struct XAigerWriter Module *module; SigMap sigmap; - pool input_bits, output_bits, external_bits; + pool input_bits, output_bits; dict not_map, alias_map; dict> and_map; vector ci_bits, co_bits; -- cgit v1.2.3 From 222e5e58ad1ae8845797a2afb63cdcb8c2396401 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 2 Jan 2020 15:58:45 -0800 Subject: Cleanup --- passes/techmap/abc9.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index a7e748ce7..8e17460e1 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -190,11 +190,10 @@ struct Abc9Pass : public ScriptPass run("flatten -wb @abc9_holes"); run("techmap @abc9_holes"); run("aigmap @abc9_holes"); - run("select -list @abc9_holes"); if (dff_mode) run("abc9_ops -prep_dff"); run("opt -purge @abc9_holes"); - run("setattr -mod -set whitebox 1 @abc9_holes"); + run("wbflip @abc9_holes"); auto selected_modules = active_design->selected_modules(); active_design->selection_stack.emplace_back(false); -- cgit v1.2.3 From 7fe268fcdb17d28dbb187d4c5c3b53e648c190ca Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 2 Jan 2020 16:00:26 -0800 Subject: Move scc operations out of inner loop --- passes/techmap/abc9.cc | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 8e17460e1..df59ff857 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -189,6 +189,8 @@ struct Abc9Pass : public ScriptPass run("select -set abc9_holes A:abc9_holes"); run("flatten -wb @abc9_holes"); run("techmap @abc9_holes"); + run("scc -set_attr abc9_scc_id {}"); + run("abc9_ops -break_scc"); run("aigmap @abc9_holes"); if (dff_mode) run("abc9_ops -prep_dff"); @@ -207,8 +209,6 @@ struct Abc9Pass : public ScriptPass continue; } - log_push(); - active_design->selection().select(mod); std::string tempdir_name = "/tmp/yosys-abc-XXXXXX"; @@ -216,14 +216,10 @@ struct Abc9Pass : public ScriptPass tempdir_name[0] = tempdir_name[4] = '_'; tempdir_name = make_temp_dir(tempdir_name); - run("scc -set_attr abc9_scc_id {}"); - run("abc9_ops -break_scc"); - run("aigmap"); run(stringf("write_xaiger -map %s/input.sym %s/input.xaig", tempdir_name.c_str(), tempdir_name.c_str()), "write_xaiger -map /input.sym /input.xaig"); run(stringf("%s -tempdir %s", map_cmd.str().c_str(), tempdir_name.c_str()), "abc9_map [options] -tempdir "); - run("abc9_ops -unbreak_scc"); if (cleanup) { @@ -232,11 +228,11 @@ struct Abc9Pass : public ScriptPass } active_design->selection().selected_modules.clear(); - - log_pop(); } active_design->selection_stack.pop_back(); + + run("abc9_ops -unbreak_scc"); } } Abc9Pass; -- cgit v1.2.3 From 32695e5032fcaa932a67f63946ae5e2a1edc8d65 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 2 Jan 2020 16:06:39 -0800 Subject: scc command to ignore blackboxes --- passes/cmds/scc.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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()) { -- cgit v1.2.3 From 4eaf41505256fc6f20065b3e5a64d74e607b15e7 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 2 Jan 2020 16:13:44 -0800 Subject: aigmap everything --- passes/techmap/abc9.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index df59ff857..e7fcb9165 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -191,7 +191,7 @@ struct Abc9Pass : public ScriptPass run("techmap @abc9_holes"); run("scc -set_attr abc9_scc_id {}"); run("abc9_ops -break_scc"); - run("aigmap @abc9_holes"); + run("aigmap"); if (dff_mode) run("abc9_ops -prep_dff"); run("opt -purge @abc9_holes"); -- cgit v1.2.3 From a050f9c80887f9962c326566c1f351c991e0c8b0 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 2 Jan 2020 16:14:04 -0800 Subject: Remove a few log_{push,pop}() --- passes/techmap/abc9_map.cc | 7 ------- passes/techmap/abc9_ops.cc | 1 - 2 files changed, 8 deletions(-) diff --git a/passes/techmap/abc9_map.cc b/passes/techmap/abc9_map.cc index 9b56f04a8..171289c6d 100644 --- a/passes/techmap/abc9_map.cc +++ b/passes/techmap/abc9_map.cc @@ -266,8 +266,6 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip fprintf(f, "%s\n", abc9_script.c_str()); fclose(f); - log_push(); - 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"), @@ -645,8 +643,6 @@ clone_lut: //{ // log("Don't call ABC as there is nothing to map.\n"); //} - - log_pop(); } struct Abc9MapPass : public Pass { @@ -759,7 +755,6 @@ struct Abc9MapPass : public Pass { void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE { log_header(design, "Executing ABC9_MAP pass (technology mapping using ABC9).\n"); - log_push(); #ifdef ABCEXTERNAL std::string exe_file = ABCEXTERNAL; @@ -913,8 +908,6 @@ struct Abc9MapPass : public Pass { delay_target, lutin_shared, fast_mode, all_cells, show_tempdir, box_file, lut_file, wire_delay, nomfs, tempdir_name); } - - log_pop(); } } Abc9MapPass; diff --git a/passes/techmap/abc9_ops.cc b/passes/techmap/abc9_ops.cc index dcb8a8a78..a4059bd4d 100644 --- a/passes/techmap/abc9_ops.cc +++ b/passes/techmap/abc9_ops.cc @@ -436,7 +436,6 @@ struct Abc9OpsPass : public Pass { void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE { log_header(design, "Executing ABC9_OPS pass (helper functions for ABC9).\n"); - log_push(); bool break_scc_mode = false; bool unbreak_scc_mode = false; -- cgit v1.2.3 From bac1e65a9cecf9a53292f28554f857e4dd3ff4dd Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 2 Jan 2020 17:21:54 -0800 Subject: Fix spacing --- techlibs/xilinx/abc9_xc7.box | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/techlibs/xilinx/abc9_xc7.box b/techlibs/xilinx/abc9_xc7.box index 1dff88509..a68da745f 100644 --- a/techlibs/xilinx/abc9_xc7.box +++ b/techlibs/xilinx/abc9_xc7.box @@ -58,7 +58,7 @@ $__ABC9_ASYNC0 1000 1 2 1 # Box 1001 : $__ABC9_ASYNC1 # (private cell to emulate async behaviour of FDP*) # name ID w/b ins outs -$__ABC9_ASYNC1 1001 1 2 1 +$__ABC9_ASYNC1 1001 1 2 1 #A S 0 764 # Y -- cgit v1.2.3 From dedea5a58d00b97180a9e0a2645f1018add00a36 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 2 Jan 2020 17:25:14 -0800 Subject: Cleanup --- backends/aiger/xaiger.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 2b456bb9a..faa722398 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -473,7 +473,7 @@ struct XAigerWriter } for (auto bit : input_bits) - undriven_bits.erase(sigmap(bit)); + undriven_bits.erase(bit); for (auto bit : output_bits) unused_bits.erase(sigmap(bit)); for (auto bit : unused_bits) @@ -700,7 +700,6 @@ struct XAigerWriter holes_module->ports.push_back(holes_wire->name); } Wire *w = holes_module->addWire(stringf("%s.abc9_ff.Q", cell->name.c_str())); - log_assert(w); holes_module->connect(w, holes_wire); } -- cgit v1.2.3 From b2ad781b0764971d4b27e231a6d773cb77dd9504 Mon Sep 17 00:00:00 2001 From: "N. Engelhardt" Date: Fri, 3 Jan 2020 14:11:41 +0100 Subject: share codepath for scratchpad argument handling with command arguments --- passes/techmap/abc9.cc | 124 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 84 insertions(+), 40 deletions(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index dd73d53a9..913b299d2 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -332,10 +332,6 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri abc9_script += script_file[i]; } else abc9_script += stringf("source %s", script_file.c_str()); - } else if (design->scratchpad.count("abc9.script")) { - abc9_script += design->scratchpad_get_string("abc9.script"); - } else if (design->scratchpad.count("abc9.scriptfile")) { - abc9_script += stringf("source %s", design->scratchpad_get_string("abc9.scriptfile").c_str()); } else if (!lut_costs.empty() || !lut_file.empty()) { //bool all_luts_cost_same = true; //for (int this_cost : lut_costs) @@ -956,6 +952,42 @@ struct Abc9Pass : public Pass { #endif #endif + // get arguments from scratchpad first, then override by command arguments + std::string lut_arg, luts_arg; + if (design->scratchpad.count("abc9.script")) { + script_file = design->scratchpad_get_string("abc9.script"); + } + if (design->scratchpad.count("abc9.D")) { + delay_target = "-D " + design->scratchpad_get_string("abc9.D"); + } + if (design->scratchpad.count("abc9.lut")) { + lut_arg = design->scratchpad_get_string("abc9.lut"); + } + if (design->scratchpad.count("abc9.luts")) { + luts_arg = design->scratchpad_get_string("abc9.luts"); + } + if (design->scratchpad.count("abc9.fast")) { + fast_mode = design->scratchpad_get_bool("abc9.fast", false /* default value if not bool-like */); + } + if (design->scratchpad.count("abc9.nocleanup")) { + cleanup = !design->scratchpad_get_bool("abc9.nocleanup", false /* default value if not bool-like */); + } + if (design->scratchpad.count("abc9.showtmp")) { + show_tempdir = design->scratchpad_get_bool("abc9.showtmp", false /* default value if not bool-like */); + } + if (design->scratchpad.count("abc9.markgroups")) { + markgroups = design->scratchpad_get_bool("abc9.markgroups", false /* default value if not bool-like */); + } + if (design->scratchpad.count("abc9.box")) { + box_file = design->scratchpad_get_string("abc9.box"); + } + if (design->scratchpad.count("abc9.W")) { + wire_delay = "-W " + design->scratchpad_get_string("abc9.W"); + } + if (design->scratchpad.count("abc9.nomfs")) { + nomfs = design->scratchpad_get_bool("abc9.nomfs", false /* default value if not bool-like */); + } + size_t argidx; char pwd [PATH_MAX]; if (!getcwd(pwd, sizeof(pwd))) { @@ -984,45 +1016,11 @@ struct Abc9Pass : public Pass { // 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; - } + lut_arg = args[++argidx]; 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"); - } + luts_arg = args[++argidx]; continue; } if (arg == "-fast") { @@ -1070,6 +1068,52 @@ struct Abc9Pass : public Pass { } extra_args(args, argidx, design); + rewrite_filename(script_file); + if (!script_file.empty() && !is_absolute_path(script_file) && script_file[0] != '+') + script_file = std::string(pwd) + "/" + script_file; + + // handle -lut / -luts args + if (!lut_arg.empty()) { + string arg = lut_arg; + 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 (!luts_arg.empty()) { + lut_costs.clear(); + for (auto &tok : split_tokens(luts_arg, ",")) { + 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"); + } + } + // ABC expects a box file for XAIG if (box_file.empty()) box_file = "+/dummy.box"; -- cgit v1.2.3 From e62eb02c1dd3074e58c9be64b8bb3b13b8d9a1ea Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 3 Jan 2020 12:30:22 -0800 Subject: Restore write_xaiger's holes_mode since port_id order causes QoR regressions inside abc9 --- backends/aiger/xaiger.cc | 46 +++++++++++++++++++--------------------------- 1 file changed, 19 insertions(+), 27 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index faa722398..1f1b9dffe 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -137,7 +137,7 @@ struct XAigerWriter return a; } - XAigerWriter(Module *module) : module(module), sigmap(module) + XAigerWriter(Module *module, bool holes_mode=false) : module(module), sigmap(module) { pool undriven_bits; pool unused_bits; @@ -157,12 +157,8 @@ struct XAigerWriter 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 (auto wire : module->wires()) for (int i = 0; i < GetSize(wire); i++) { SigBit wirebit(wire, i); @@ -176,6 +172,9 @@ struct XAigerWriter continue; } + undriven_bits.insert(bit); + unused_bits.insert(bit); + if (wire->port_input) input_bits.insert(bit); @@ -185,19 +184,6 @@ struct XAigerWriter output_bits.insert(wirebit); } } - } - - for (auto wire : module->wires()) - 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); - } - } // TODO: Speed up toposort -- ultimately we care about // box ordering, but not individual AIG cells @@ -485,12 +471,20 @@ struct XAigerWriter undriven_bits.erase(bit); } + if (holes_mode) { + struct sort_by_port_id { + bool operator()(const RTLIL::SigBit& a, const RTLIL::SigBit& b) const { + return a.wire->port_id < b.wire->port_id; + } + }; + input_bits.sort(sort_by_port_id()); + output_bits.sort(sort_by_port_id()); + } + aig_map[State::S0] = 0; aig_map[State::S1] = 1; - // pool<> iterates in LIFO order... - for (int i = input_bits.size()-1; i >= 0; i--) { - const auto &bit = *input_bits.element(i); + for (const auto &bit : input_bits) { aig_m++, aig_i++; log_assert(!aig_map.count(bit)); aig_map[bit] = 2*aig_m; @@ -515,9 +509,7 @@ struct XAigerWriter aig_outputs.push_back(bit2aig(bit)); } - // pool<> iterates in LIFO order... - for (int i = output_bits.size()-1; i >= 0; i--) { - const auto &bit = *output_bits.element(i); + for (const auto &bit : output_bits) { ordered_outputs[bit] = aig_o++; aig_outputs.push_back(bit2aig(bit)); } @@ -816,7 +808,7 @@ struct XAigerWriter Pass::call(holes_design, "opt -purge"); std::stringstream a_buffer; - XAigerWriter writer(holes_module); + XAigerWriter writer(holes_module, true /* holes_mode */); writer.write_aiger(a_buffer, false /*ascii_mode*/); delete holes_design; -- cgit v1.2.3 From e1f494ab1db523f90cf1e386ba133b1550dcb300 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 3 Jan 2020 13:08:52 -0800 Subject: WIP --- backends/aiger/xaiger.cc | 164 ++++++++++++++++++++++++++++++++++++++++------- passes/techmap/abc9.cc | 14 ++-- 2 files changed, 148 insertions(+), 30 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 42a26cbf9..02ab47ac0 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -619,26 +619,90 @@ struct XAigerWriter // write_o_buffer(0); if (!box_list.empty() || !ff_bits.empty()) { + RTLIL::Module *holes_module = module->design->addModule("$__holes__"); + log_assert(holes_module); + + dict cell_cache; + + int port_id = 1; int box_count = 0; for (auto cell : box_list) { RTLIL::Module* orig_box_module = module->design->module(cell->type); log_assert(orig_box_module); IdString derived_name = orig_box_module->derive(module->design, cell->parameters); RTLIL::Module* box_module = module->design->module(derived_name); + if (box_module->has_processes()) + Pass::call_on_module(module->design, box_module, "proc"); + + auto r = cell_cache.insert(std::make_pair(derived_name, nullptr)); + Cell *holes_cell = r.first->second; + if (r.second && box_module->get_bool_attribute("\\whitebox")) { + holes_cell = holes_module->addCell(cell->name, cell->type); + holes_cell->parameters = cell->parameters; + r.first->second = holes_cell; + } int box_inputs = 0, box_outputs = 0; for (auto port_name : box_ports.at(cell->type)) { RTLIL::Wire *w = box_module->wire(port_name); log_assert(w); + RTLIL::Wire *holes_wire; + RTLIL::SigSpec port_sig; + if (w->port_input) - box_inputs += GetSize(w); - if (w->port_output) + for (int i = 0; i < GetSize(w); i++) { + box_inputs++; + holes_wire = holes_module->wire(stringf("\\i%d", box_inputs)); + if (!holes_wire) { + holes_wire = holes_module->addWire(stringf("\\i%d", box_inputs)); + holes_wire->port_input = true; + holes_wire->port_id = port_id++; + holes_module->ports.push_back(holes_wire->name); + } + if (holes_cell) + port_sig.append(holes_wire); + } + if (w->port_output) { box_outputs += GetSize(w); + for (int i = 0; i < GetSize(w); i++) { + if (GetSize(w) == 1) + holes_wire = holes_module->addWire(stringf("$abc%s.%s", cell->name.c_str(), log_id(w->name))); + else + holes_wire = holes_module->addWire(stringf("$abc%s.%s[%d]", cell->name.c_str(), log_id(w->name), i)); + holes_wire->port_output = true; + holes_wire->port_id = port_id++; + holes_module->ports.push_back(holes_wire->name); + if (holes_cell) + port_sig.append(holes_wire); + else + holes_module->connect(holes_wire, State::S0); + } + } + if (!port_sig.empty()) { + if (r.second) + holes_cell->setPort(w->name, port_sig); + else + holes_module->connect(holes_cell->getPort(w->name), port_sig); + } } - // For flops only, create an extra 1-bit input for abc9_ff.Q - if (box_module->get_bool_attribute("\\abc9_flop")) + // For flops only, create an extra 1-bit input that drives a new wire + // called ".abc9_ff.Q" that is used below + if (box_module->get_bool_attribute("\\abc9_flop")) { + log_assert(holes_cell); + box_inputs++; + Wire *holes_wire = holes_module->wire(stringf("\\i%d", box_inputs)); + if (!holes_wire) { + holes_wire = holes_module->addWire(stringf("\\i%d", box_inputs)); + holes_wire->port_input = true; + holes_wire->port_id = port_id++; + holes_module->ports.push_back(holes_wire->name); + } + Wire *w = holes_module->addWire(stringf("%s.abc9_ff.Q", cell->name.c_str())); + log_assert(w); + holes_module->connect(w, holes_wire); + } write_h_buffer(box_inputs); write_h_buffer(box_outputs); @@ -690,27 +754,81 @@ struct XAigerWriter f.write(reinterpret_cast(&buffer_size_be), sizeof(buffer_size_be)); f.write(buffer_str.data(), buffer_str.size()); - RTLIL::Module *holes_module = module->design->module(stringf("%s$holes", module->name.c_str())); - log_assert(holes_module); - - for (auto cell : holes_module->cells()) - if (!cell->type.in("$_NOT_", "$_AND_")) - log_error("Whitebox contents cannot be represented as AIG. Please verify whiteboxes are synthesisable.\n"); - - module->design->selection_stack.emplace_back(false); - module->design->selection().select(holes_module); - - std::stringstream a_buffer; - XAigerWriter writer(holes_module); - writer.write_aiger(a_buffer, false /*ascii_mode*/); + if (holes_module) { + log_push(); + + // NB: fixup_ports() will sort ports by name + //holes_module->fixup_ports(); + holes_module->check(); + + // Cannot techmap/aigmap/check all lib_whitebox-es outside of write_xaiger + // since boxes may contain parameters in which case `flatten` would have + // created a new $paramod ... + Pass::call_on_module(holes_module->design, holes_module, "flatten -wb; techmap; aigmap"); + + dict replace; + for (auto it = holes_module->cells_.begin(); it != holes_module->cells_.end(); ) { + auto cell = it->second; + if (cell->type.in("$_DFF_N_", "$_DFF_NN0_", "$_DFF_NN1_", "$_DFF_NP0_", "$_DFF_NP1_", + "$_DFF_P_", "$_DFF_PN0_", "$_DFF_PN1", "$_DFF_PP0_", "$_DFF_PP1_")) { + SigBit D = cell->getPort("\\D"); + SigBit Q = cell->getPort("\\Q"); + // Remove the DFF cell from what needs to be a combinatorial box + it = holes_module->cells_.erase(it); + Wire *port; + if (GetSize(Q.wire) == 1) + port = holes_module->wire(stringf("$abc%s", Q.wire->name.c_str())); + else + port = holes_module->wire(stringf("$abc%s[%d]", Q.wire->name.c_str(), Q.offset)); + log_assert(port); + // Prepare to replace "assign = DFF.Q;" with "assign = DFF.D;" + // in order to extract the combinatorial control logic that feeds the box + // (i.e. clock enable, synchronous reset, etc.) + replace.insert(std::make_pair(SigSig(port,Q), SigSig(port,D))); + // Since `flatten` above would have created wires named ".Q", + // extract the pre-techmap cell name + auto pos = Q.wire->name.str().rfind("."); + log_assert(pos != std::string::npos); + IdString driver = Q.wire->name.substr(0, pos); + // And drive the signal that was previously driven by "DFF.Q" (typically + // used to implement clock-enable functionality) with the ".abc9_ff.Q" + // wire (which itself is driven an input port) we inserted above + Wire *currQ = holes_module->wire(stringf("%s.abc9_ff.Q", driver.c_str())); + log_assert(currQ); + holes_module->connect(Q, currQ); + continue; + } + else if (!cell->type.in("$_NOT_", "$_AND_")) + log_error("Whitebox contents cannot be represented as AIG. Please verify whiteboxes are synthesisable.\n"); + ++it; + } - module->design->selection_stack.pop_back(); + for (auto &conn : holes_module->connections_) { + auto it = replace.find(conn); + if (it != replace.end()) + conn = it->second; + } - f << "a"; - buffer_str = a_buffer.str(); - buffer_size_be = to_big_endian(buffer_str.size()); - f.write(reinterpret_cast(&buffer_size_be), sizeof(buffer_size_be)); - f.write(buffer_str.data(), buffer_str.size()); + // Move into a new (temporary) design so that "clean" will only + // operate (and run checks on) this one module + RTLIL::Design *holes_design = new RTLIL::Design; + module->design->modules_.erase(holes_module->name); + holes_design->add(holes_module); + Pass::call(holes_design, "opt -purge"); + + std::stringstream a_buffer; + XAigerWriter writer(holes_module); + writer.write_aiger(a_buffer, false /*ascii_mode*/); + delete holes_design; + + f << "a"; + std::string buffer_str = a_buffer.str(); + int32_t buffer_size_be = to_big_endian(buffer_str.size()); + f.write(reinterpret_cast(&buffer_size_be), sizeof(buffer_size_be)); + f.write(buffer_str.data(), buffer_str.size()); + + log_pop(); + } } f << "h"; diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index e7fcb9165..6dd4de2e0 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -185,17 +185,17 @@ struct Abc9Pass : public ScriptPass void script() YS_OVERRIDE { - run("abc9_ops -prep_holes"); - run("select -set abc9_holes A:abc9_holes"); - run("flatten -wb @abc9_holes"); - run("techmap @abc9_holes"); run("scc -set_attr abc9_scc_id {}"); - run("abc9_ops -break_scc"); + run("abc9_ops -break_scc"/*" -prep_holes"*/); +// run("select -set abc9_holes A:abc9_holes"); +// run("dump @abc9_holes"); +// run("flatten -wb @abc9_holes"); +// run("techmap @abc9_holes"); run("aigmap"); if (dff_mode) run("abc9_ops -prep_dff"); - run("opt -purge @abc9_holes"); - run("wbflip @abc9_holes"); +// run("opt -purge @abc9_holes"); +// run("wbflip @abc9_holes"); auto selected_modules = active_design->selected_modules(); active_design->selection_stack.emplace_back(false); -- cgit v1.2.3 From bb70915fb8adcd7ede7719174dea3bc9c04e613e Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 3 Jan 2020 13:21:56 -0800 Subject: WIP --- backends/aiger/xaiger.cc | 75 +++++----------------------------------------- passes/techmap/abc9.cc | 6 +++- passes/techmap/abc9_ops.cc | 48 +++++++++++++++++++++-------- 3 files changed, 48 insertions(+), 81 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 02ab47ac0..7e7a3a17e 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -619,90 +619,30 @@ struct XAigerWriter // write_o_buffer(0); if (!box_list.empty() || !ff_bits.empty()) { - RTLIL::Module *holes_module = module->design->addModule("$__holes__"); + RTLIL::Module *holes_module = module->design->module(stringf("%s$holes", module->name.c_str())); log_assert(holes_module); dict cell_cache; - int port_id = 1; int box_count = 0; for (auto cell : box_list) { - RTLIL::Module* orig_box_module = module->design->module(cell->type); - log_assert(orig_box_module); - IdString derived_name = orig_box_module->derive(module->design, cell->parameters); - RTLIL::Module* box_module = module->design->module(derived_name); - if (box_module->has_processes()) - Pass::call_on_module(module->design, box_module, "proc"); - - auto r = cell_cache.insert(std::make_pair(derived_name, nullptr)); - Cell *holes_cell = r.first->second; - if (r.second && box_module->get_bool_attribute("\\whitebox")) { - holes_cell = holes_module->addCell(cell->name, cell->type); - holes_cell->parameters = cell->parameters; - r.first->second = holes_cell; - } + RTLIL::Module* box_module = module->design->module(cell->type); + log_assert(box_module); int box_inputs = 0, box_outputs = 0; - for (auto port_name : box_ports.at(cell->type)) { + for (auto port_name : box_module->ports) { RTLIL::Wire *w = box_module->wire(port_name); log_assert(w); - RTLIL::Wire *holes_wire; - RTLIL::SigSpec port_sig; - if (w->port_input) - for (int i = 0; i < GetSize(w); i++) { - box_inputs++; - holes_wire = holes_module->wire(stringf("\\i%d", box_inputs)); - if (!holes_wire) { - holes_wire = holes_module->addWire(stringf("\\i%d", box_inputs)); - holes_wire->port_input = true; - holes_wire->port_id = port_id++; - holes_module->ports.push_back(holes_wire->name); - } - if (holes_cell) - port_sig.append(holes_wire); - } - if (w->port_output) { + box_inputs += GetSize(w); + if (w->port_output) box_outputs += GetSize(w); - for (int i = 0; i < GetSize(w); i++) { - if (GetSize(w) == 1) - holes_wire = holes_module->addWire(stringf("$abc%s.%s", cell->name.c_str(), log_id(w->name))); - else - holes_wire = holes_module->addWire(stringf("$abc%s.%s[%d]", cell->name.c_str(), log_id(w->name), i)); - holes_wire->port_output = true; - holes_wire->port_id = port_id++; - holes_module->ports.push_back(holes_wire->name); - if (holes_cell) - port_sig.append(holes_wire); - else - holes_module->connect(holes_wire, State::S0); - } - } - if (!port_sig.empty()) { - if (r.second) - holes_cell->setPort(w->name, port_sig); - else - holes_module->connect(holes_cell->getPort(w->name), port_sig); - } } // For flops only, create an extra 1-bit input that drives a new wire // called ".abc9_ff.Q" that is used below - if (box_module->get_bool_attribute("\\abc9_flop")) { - log_assert(holes_cell); - + if (box_module->get_bool_attribute("\\abc9_flop")) box_inputs++; - Wire *holes_wire = holes_module->wire(stringf("\\i%d", box_inputs)); - if (!holes_wire) { - holes_wire = holes_module->addWire(stringf("\\i%d", box_inputs)); - holes_wire->port_input = true; - holes_wire->port_id = port_id++; - holes_module->ports.push_back(holes_wire->name); - } - Wire *w = holes_module->addWire(stringf("%s.abc9_ff.Q", cell->name.c_str())); - log_assert(w); - holes_module->connect(w, holes_wire); - } write_h_buffer(box_inputs); write_h_buffer(box_outputs); @@ -764,6 +704,7 @@ struct XAigerWriter // Cannot techmap/aigmap/check all lib_whitebox-es outside of write_xaiger // since boxes may contain parameters in which case `flatten` would have // created a new $paramod ... + Pass::call_on_module(holes_module->design, holes_module, "wbflip"); Pass::call_on_module(holes_module->design, holes_module, "flatten -wb; techmap; aigmap"); dict replace; diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 6dd4de2e0..25fe3fbc8 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -195,7 +195,11 @@ struct Abc9Pass : public ScriptPass if (dff_mode) run("abc9_ops -prep_dff"); // run("opt -purge @abc9_holes"); -// run("wbflip @abc9_holes"); + + run("abc9_ops -prep_holes"); + + run("select -set abc9_holes A:abc9_holes"); + run("wbflip @abc9_holes"); auto selected_modules = active_design->selected_modules(); active_design->selection_stack.emplace_back(false); diff --git a/passes/techmap/abc9_ops.cc b/passes/techmap/abc9_ops.cc index a4059bd4d..c671553e2 100644 --- a/passes/techmap/abc9_ops.cc +++ b/passes/techmap/abc9_ops.cc @@ -288,8 +288,6 @@ void prep_holes(RTLIL::Module *module) // 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) for (const auto &port_name : box_module->ports) { RTLIL::Wire* w = box_module->wire(port_name); log_assert(w); @@ -333,6 +331,7 @@ void prep_holes(RTLIL::Module *module) holes_module->set_bool_attribute("\\abc9_holes"); dict cell_cache; + dict> box_ports; int port_id = 1; for (auto cell : box_list) { @@ -350,24 +349,47 @@ void prep_holes(RTLIL::Module *module) holes_cell = holes_module->addCell(cell->name, cell->type); holes_cell->parameters = cell->parameters; r.first->second = holes_cell; + } - // Since Module::derive() will create a new module, there - // is a chance that the ports will be alphabetically ordered - // again, which is a problem when carry-chains are involved. - // Inherit the port ordering from the original module here... - // (and set the port_id below, when iterating through those) - log_assert(GetSize(box_module->ports) == GetSize(orig_box_module->ports)); - box_module->ports = orig_box_module->ports; + 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); + } } // NB: Assume box_module->ports are sorted alphabetically // (as RTLIL::Module::fixup_ports() would do) - int box_port_id = 1; - for (const auto &port_name : box_module->ports) { + for (const auto &port_name : box_ports.at(cell->type)) { RTLIL::Wire *w = box_module->wire(port_name); log_assert(w); - if (r.second) - w->port_id = box_port_id++; RTLIL::Wire *holes_wire; RTLIL::SigSpec port_sig; if (w->port_input) -- cgit v1.2.3 From 559f3379e852f304a0255afcc37714b9d0da59d9 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 3 Jan 2020 14:37:58 -0800 Subject: Preserve topo ordering from -prep_holes to write_xaiger --- backends/aiger/xaiger.cc | 236 +++++++++++++++------------------------------ passes/techmap/abc9.cc | 6 +- passes/techmap/abc9_ops.cc | 1 + 3 files changed, 79 insertions(+), 164 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 7e7a3a17e..ff3de65cc 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -78,7 +78,7 @@ struct XAigerWriter Module *module; SigMap sigmap; - pool input_bits, output_bits, external_bits; + pool input_bits, output_bits; dict not_map, alias_map; dict> and_map; vector ci_bits, co_bits; @@ -199,12 +199,6 @@ struct XAigerWriter } } - // TODO: Speed up toposort -- ultimately we care about - // box ordering, but not individual AIG cells - dict> bit_drivers, bit_users; - TopoSort toposort; - bool abc9_box_seen = false; - for (auto cell : module->selected_cells()) { if (cell->type == "$_NOT_") { @@ -213,9 +207,6 @@ struct XAigerWriter unused_bits.erase(A); undriven_bits.erase(Y); not_map[Y] = A; - toposort.node(cell->name); - bit_users[A].insert(cell->name); - bit_drivers[Y].insert(cell->name); continue; } @@ -228,10 +219,6 @@ struct XAigerWriter unused_bits.erase(B); undriven_bits.erase(Y); and_map[Y] = make_pair(A, B); - toposort.node(cell->name); - bit_users[A].insert(cell->name); - bit_users[B].insert(cell->name); - bit_drivers[Y].insert(cell->name); continue; } @@ -257,22 +244,17 @@ struct XAigerWriter if (abc9_box && cell->get_bool_attribute("\\abc9_keep")) abc9_box = false; + if (abc9_box) { + int abc9_box_order = cell->attributes.at("\\abc9_box_order").as_int(); + if (GetSize(box_list) <= abc9_box_order) + box_list.resize(abc9_box_order+1); + box_list[abc9_box_order] = cell; + if (!abc9_flop) + continue; + } + for (const auto &conn : cell->connections()) { auto port_wire = inst_module->wire(conn.first); - - if (abc9_box) { - // Ignore inout for the sake of topographical ordering - if (port_wire->port_input && !port_wire->port_output) - for (auto bit : sigmap(conn.second)) - bit_users[bit].insert(cell->name); - if (port_wire->port_output) - for (auto bit : sigmap(conn.second)) - bit_drivers[bit].insert(cell->name); - - if (!abc9_flop) - continue; - } - if (port_wire->port_output) { int arrival = 0; auto it = port_wire->attributes.find("\\abc9_arrival"); @@ -286,12 +268,6 @@ struct XAigerWriter arrival_times[bit] = arrival; } } - - if (abc9_box) { - abc9_box_seen = true; - toposort.node(cell->name); - continue; - } } bool cell_known = inst_module || cell->known(); @@ -319,138 +295,56 @@ struct XAigerWriter //log_warning("Unsupported cell type: %s (%s)\n", log_id(cell->type), log_id(cell)); } - if (abc9_box_seen) { - for (auto &it : bit_users) - if (bit_drivers.count(it.first)) - for (auto driver_cell : bit_drivers.at(it.first)) - for (auto user_cell : it.second) - toposort.edge(driver_cell, user_cell); - -#if 0 - toposort.analyze_loops = true; -#endif - bool no_loops YS_ATTRIBUTE(unused) = toposort.sort(); -#if 0 - unsigned i = 0; - for (auto &it : toposort.loops) { - log(" loop %d\n", i++); - for (auto cell_name : it) { - auto cell = module->cell(cell_name); - log_assert(cell); - log("\t%s (%s @ %s)\n", log_id(cell), log_id(cell->type), cell->get_src_attribute().c_str()); - } - } -#endif - log_assert(no_loops); - - for (auto cell_name : toposort.sorted) { - RTLIL::Cell *cell = module->cell(cell_name); - log_assert(cell); - - RTLIL::Module* box_module = module->design->module(cell->type); - if (!box_module || !box_module->attributes.count("\\abc9_box_id")) - continue; - - bool blackbox = box_module->get_blackbox_attribute(true /* ignore_wb */); - - auto r = box_ports.insert(cell->type); - if (r.second) { - // Make carry in the last PI, and carry out the last PO - // since ABC requires it this way - IdString carry_in, carry_out; - for (const auto &port_name : box_module->ports) { - auto w = box_module->wire(port_name); - log_assert(w); - if (w->get_bool_attribute("\\abc9_carry")) { - if (w->port_input) { - if (carry_in != IdString()) - log_error("Module '%s' contains more than one 'abc9_carry' input port.\n", log_id(box_module)); - carry_in = port_name; - } - if (w->port_output) { - if (carry_out != IdString()) - log_error("Module '%s' contains more than one 'abc9_carry' output port.\n", log_id(box_module)); - carry_out = port_name; - } - } - else - r.first->second.push_back(port_name); - } + for (auto cell : box_list) { + log_assert(cell); - if (carry_in != IdString() && carry_out == IdString()) - log_error("Module '%s' contains an 'abc9_carry' input port but no output port.\n", log_id(box_module)); - if (carry_in == IdString() && carry_out != IdString()) - log_error("Module '%s' contains an 'abc9_carry' output port but no input port.\n", log_id(box_module)); - if (carry_in != IdString()) { - r.first->second.push_back(carry_in); - r.first->second.push_back(carry_out); - } - } + RTLIL::Module* box_module = module->design->module(cell->type); + log_assert(box_module); + log_assert(box_module->attributes.count("\\abc9_box_id")); - // Fully pad all unused input connections of this box cell with S0 - // Fully pad all undriven output connections of this box cell with anonymous wires - for (auto port_name : r.first->second) { + auto r = box_ports.insert(cell->type); + if (r.second) { + // Make carry in the last PI, and carry out the last PO + // since ABC requires it this way + IdString carry_in, carry_out; + for (const auto &port_name : box_module->ports) { auto w = box_module->wire(port_name); log_assert(w); - auto it = cell->connections_.find(port_name); - if (w->port_input) { - RTLIL::SigSpec rhs; - if (it != cell->connections_.end()) { - if (GetSize(it->second) < GetSize(w)) - it->second.append(RTLIL::SigSpec(State::S0, GetSize(w)-GetSize(it->second))); - rhs = it->second; - } - else { - rhs = RTLIL::SigSpec(State::S0, GetSize(w)); - cell->setPort(port_name, rhs); + if (w->get_bool_attribute("\\abc9_carry")) { + if (w->port_input) { + if (carry_in != IdString()) + log_error("Module '%s' contains more than one 'abc9_carry' input port.\n", log_id(box_module)); + carry_in = port_name; } - - for (auto b : rhs) { - SigBit I = sigmap(b); - if (b == RTLIL::Sx) - b = State::S0; - else if (I != b) { - if (I == RTLIL::Sx) - alias_map[b] = State::S0; - else - alias_map[b] = I; - } - co_bits.emplace_back(b); - unused_bits.erase(I); + if (w->port_output) { + if (carry_out != IdString()) + log_error("Module '%s' contains more than one 'abc9_carry' output port.\n", log_id(box_module)); + carry_out = port_name; } } - if (w->port_output) { - RTLIL::SigSpec rhs; - auto it = cell->connections_.find(w->name); - if (it != cell->connections_.end()) { - if (GetSize(it->second) < GetSize(w)) - it->second.append(module->addWire(NEW_ID, GetSize(w)-GetSize(it->second))); - rhs = it->second; - } - else { - Wire *wire = module->addWire(NEW_ID, GetSize(w)); - if (blackbox) - wire->set_bool_attribute(ID(abc9_padding)); - rhs = wire; - cell->setPort(port_name, rhs); - } + else + r.first->second.push_back(port_name); + } - for (const auto &b : rhs.bits()) { - SigBit O = sigmap(b); - if (O != b) - alias_map[O] = b; - ci_bits.emplace_back(b); - undriven_bits.erase(O); - } - } + if (carry_in != IdString() && carry_out == IdString()) + log_error("Module '%s' contains an 'abc9_carry' input port but no output port.\n", log_id(box_module)); + if (carry_in == IdString() && carry_out != IdString()) + log_error("Module '%s' contains an 'abc9_carry' output port but no input port.\n", log_id(box_module)); + if (carry_in != IdString()) { + r.first->second.push_back(carry_in); + r.first->second.push_back(carry_out); } + } - // Connect .abc9_ff.Q (inserted by abc9_map.v) as the last input to the flop box - if (box_module->get_bool_attribute("\\abc9_flop")) { - SigSpec rhs = module->wire(stringf("%s.abc9_ff.Q", cell->name.c_str())); - if (rhs.empty()) - log_error("'%s.abc9_ff.Q' is not a wire present in module '%s'.\n", log_id(cell), log_id(module)); + bool blackbox = box_module->get_blackbox_attribute(true /* ignore_wb */); + // Fully pad all unused input connections of this box cell with S0 + // Fully pad all undriven output connections of this box cell with anonymous wires + for (auto port_name : r.first->second) { + auto w = box_module->wire(port_name); + log_assert(w); + auto rhs = cell->getPort(port_name); + if (w->port_input) for (auto b : rhs) { SigBit I = sigmap(b); if (b == RTLIL::Sx) @@ -464,12 +358,36 @@ struct XAigerWriter co_bits.emplace_back(b); unused_bits.erase(I); } - } - - box_list.emplace_back(cell); + if (w->port_output) + for (const auto &b : rhs.bits()) { + SigBit O = sigmap(b); + if (O != b) + alias_map[O] = b; + ci_bits.emplace_back(b); + undriven_bits.erase(O); + } } - // TODO: Free memory from toposort, bit_drivers, bit_users + // Connect .abc9_ff.Q (inserted by abc9_map.v) as the last input to the flop box + if (box_module->get_bool_attribute("\\abc9_flop")) { + SigSpec rhs = module->wire(stringf("%s.abc9_ff.Q", cell->name.c_str())); + if (rhs.empty()) + log_error("'%s.abc9_ff.Q' is not a wire present in module '%s'.\n", log_id(cell), log_id(module)); + + for (auto b : rhs) { + SigBit I = sigmap(b); + if (b == RTLIL::Sx) + b = State::S0; + else if (I != b) { + if (I == RTLIL::Sx) + alias_map[b] = State::S0; + else + alias_map[b] = I; + } + co_bits.emplace_back(b); + unused_bits.erase(I); + } + } } for (auto bit : input_bits) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 25fe3fbc8..af37ecb5c 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -187,17 +187,13 @@ struct Abc9Pass : public ScriptPass { run("scc -set_attr abc9_scc_id {}"); run("abc9_ops -break_scc"/*" -prep_holes"*/); -// run("select -set abc9_holes A:abc9_holes"); -// run("dump @abc9_holes"); // run("flatten -wb @abc9_holes"); // run("techmap @abc9_holes"); run("aigmap"); + run("abc9_ops -prep_holes"); if (dff_mode) run("abc9_ops -prep_dff"); // run("opt -purge @abc9_holes"); - - run("abc9_ops -prep_holes"); - run("select -set abc9_holes A:abc9_holes"); run("wbflip @abc9_holes"); diff --git a/passes/techmap/abc9_ops.cc b/passes/techmap/abc9_ops.cc index c671553e2..bcf622dba 100644 --- a/passes/techmap/abc9_ops.cc +++ b/passes/techmap/abc9_ops.cc @@ -322,6 +322,7 @@ void prep_holes(RTLIL::Module *module) } } + cell->attributes["\\abc9_box_order"] = box_list.size(); box_list.emplace_back(cell); } log_assert(!box_list.empty()); -- cgit v1.2.3 From a819656972dd44c479422fa688874926d6239a95 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 3 Jan 2020 14:59:55 -0800 Subject: WIP --- backends/aiger/xaiger.cc | 56 ---------------------------------------------- passes/techmap/abc9.cc | 12 +++++----- passes/techmap/abc9_ops.cc | 2 -- 3 files changed, 7 insertions(+), 63 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index ff3de65cc..e9b4f07bf 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -336,8 +336,6 @@ struct XAigerWriter } } - bool blackbox = box_module->get_blackbox_attribute(true /* ignore_wb */); - // Fully pad all unused input connections of this box cell with S0 // Fully pad all undriven output connections of this box cell with anonymous wires for (auto port_name : r.first->second) { @@ -615,65 +613,11 @@ struct XAigerWriter if (holes_module) { log_push(); - // NB: fixup_ports() will sort ports by name - //holes_module->fixup_ports(); - holes_module->check(); - - // Cannot techmap/aigmap/check all lib_whitebox-es outside of write_xaiger - // since boxes may contain parameters in which case `flatten` would have - // created a new $paramod ... - Pass::call_on_module(holes_module->design, holes_module, "wbflip"); - Pass::call_on_module(holes_module->design, holes_module, "flatten -wb; techmap; aigmap"); - - dict replace; - for (auto it = holes_module->cells_.begin(); it != holes_module->cells_.end(); ) { - auto cell = it->second; - if (cell->type.in("$_DFF_N_", "$_DFF_NN0_", "$_DFF_NN1_", "$_DFF_NP0_", "$_DFF_NP1_", - "$_DFF_P_", "$_DFF_PN0_", "$_DFF_PN1", "$_DFF_PP0_", "$_DFF_PP1_")) { - SigBit D = cell->getPort("\\D"); - SigBit Q = cell->getPort("\\Q"); - // Remove the DFF cell from what needs to be a combinatorial box - it = holes_module->cells_.erase(it); - Wire *port; - if (GetSize(Q.wire) == 1) - port = holes_module->wire(stringf("$abc%s", Q.wire->name.c_str())); - else - port = holes_module->wire(stringf("$abc%s[%d]", Q.wire->name.c_str(), Q.offset)); - log_assert(port); - // Prepare to replace "assign = DFF.Q;" with "assign = DFF.D;" - // in order to extract the combinatorial control logic that feeds the box - // (i.e. clock enable, synchronous reset, etc.) - replace.insert(std::make_pair(SigSig(port,Q), SigSig(port,D))); - // Since `flatten` above would have created wires named ".Q", - // extract the pre-techmap cell name - auto pos = Q.wire->name.str().rfind("."); - log_assert(pos != std::string::npos); - IdString driver = Q.wire->name.substr(0, pos); - // And drive the signal that was previously driven by "DFF.Q" (typically - // used to implement clock-enable functionality) with the ".abc9_ff.Q" - // wire (which itself is driven an input port) we inserted above - Wire *currQ = holes_module->wire(stringf("%s.abc9_ff.Q", driver.c_str())); - log_assert(currQ); - holes_module->connect(Q, currQ); - continue; - } - else if (!cell->type.in("$_NOT_", "$_AND_")) - log_error("Whitebox contents cannot be represented as AIG. Please verify whiteboxes are synthesisable.\n"); - ++it; - } - - for (auto &conn : holes_module->connections_) { - auto it = replace.find(conn); - if (it != replace.end()) - conn = it->second; - } - // Move into a new (temporary) design so that "clean" will only // operate (and run checks on) this one module RTLIL::Design *holes_design = new RTLIL::Design; module->design->modules_.erase(holes_module->name); holes_design->add(holes_module); - Pass::call(holes_design, "opt -purge"); std::stringstream a_buffer; XAigerWriter writer(holes_module); diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index af37ecb5c..da56f42ea 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -186,15 +186,17 @@ struct Abc9Pass : public ScriptPass void script() YS_OVERRIDE { run("scc -set_attr abc9_scc_id {}"); - run("abc9_ops -break_scc"/*" -prep_holes"*/); -// run("flatten -wb @abc9_holes"); -// run("techmap @abc9_holes"); + run("abc9_ops -break_scc"); run("aigmap"); + run("abc9_ops -prep_holes"); + run("select -set abc9_holes A:abc9_holes"); + run("flatten -wb @abc9_holes"); + run("techmap @abc9_holes"); + run("aigmap @abc9_holes"); if (dff_mode) run("abc9_ops -prep_dff"); -// run("opt -purge @abc9_holes"); - run("select -set abc9_holes A:abc9_holes"); + run("opt -purge @abc9_holes"); run("wbflip @abc9_holes"); auto selected_modules = active_design->selected_modules(); diff --git a/passes/techmap/abc9_ops.cc b/passes/techmap/abc9_ops.cc index bcf622dba..632f2bc8a 100644 --- a/passes/techmap/abc9_ops.cc +++ b/passes/techmap/abc9_ops.cc @@ -386,8 +386,6 @@ void prep_holes(RTLIL::Module *module) } } - // NB: Assume box_module->ports are sorted alphabetically - // (as RTLIL::Module::fixup_ports() would do) for (const auto &port_name : box_ports.at(cell->type)) { RTLIL::Wire *w = box_module->wire(port_name); log_assert(w); -- cgit v1.2.3 From 930f03e8830ed8a8023ff88207b97e757ae8496c Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 3 Jan 2020 15:38:18 -0800 Subject: Call -prep_holes before aigmap; fix topo ordering --- backends/aiger/xaiger.cc | 9 +------- passes/techmap/abc9.cc | 7 ++---- passes/techmap/abc9_ops.cc | 55 +++++++++++++--------------------------------- 3 files changed, 18 insertions(+), 53 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index e9b4f07bf..7ef744d04 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -199,7 +199,7 @@ struct XAigerWriter } } - for (auto cell : module->selected_cells()) { + for (auto cell : module->cells()) { if (cell->type == "$_NOT_") { SigBit A = sigmap(cell->getPort("\\A").as_bit()); @@ -613,16 +613,9 @@ struct XAigerWriter if (holes_module) { log_push(); - // Move into a new (temporary) design so that "clean" will only - // operate (and run checks on) this one module - RTLIL::Design *holes_design = new RTLIL::Design; - module->design->modules_.erase(holes_module->name); - holes_design->add(holes_module); - std::stringstream a_buffer; XAigerWriter writer(holes_module); writer.write_aiger(a_buffer, false /*ascii_mode*/); - delete holes_design; f << "a"; std::string buffer_str = a_buffer.str(); diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index da56f42ea..0da815870 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -186,14 +186,11 @@ struct Abc9Pass : public ScriptPass void script() YS_OVERRIDE { run("scc -set_attr abc9_scc_id {}"); - run("abc9_ops -break_scc"); - run("aigmap"); - - run("abc9_ops -prep_holes"); + run("abc9_ops -break_scc -prep_holes"); run("select -set abc9_holes A:abc9_holes"); run("flatten -wb @abc9_holes"); run("techmap @abc9_holes"); - run("aigmap @abc9_holes"); + run("aigmap"); if (dff_mode) run("abc9_ops -prep_dff"); run("opt -purge @abc9_holes"); diff --git a/passes/techmap/abc9_ops.cc b/passes/techmap/abc9_ops.cc index 632f2bc8a..2f07de8d4 100644 --- a/passes/techmap/abc9_ops.cc +++ b/passes/techmap/abc9_ops.cc @@ -21,6 +21,7 @@ #include "kernel/register.h" #include "kernel/sigtools.h" #include "kernel/utils.h" +#include "kernel/celltypes.h" USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN @@ -194,58 +195,32 @@ void prep_holes(RTLIL::Module *module) SigMap sigmap(module); - // TODO: Speed up toposort -- ultimately we care about - // box ordering, but not individual AIG cells dict> bit_drivers, bit_users; TopoSort toposort; bool abc9_box_seen = false; for (auto cell : module->selected_cells()) { - if (cell->type == "$_NOT_") - { - SigBit A = sigmap(cell->getPort("\\A").as_bit()); - SigBit Y = sigmap(cell->getPort("\\Y").as_bit()); - toposort.node(cell->name); - bit_users[A].insert(cell->name); - bit_drivers[Y].insert(cell->name); - continue; - } - - if (cell->type == "$_AND_") - { - SigBit A = sigmap(cell->getPort("\\A").as_bit()); - SigBit B = sigmap(cell->getPort("\\B").as_bit()); - SigBit Y = sigmap(cell->getPort("\\Y").as_bit()); - toposort.node(cell->name); - bit_users[A].insert(cell->name); - bit_users[B].insert(cell->name); - bit_drivers[Y].insert(cell->name); - continue; - } - if (cell->type == "$__ABC9_FF_") continue; - RTLIL::Module* inst_module = design->module(cell->type); - if (inst_module) { - if (!inst_module->attributes.count("\\abc9_box_id") || cell->get_bool_attribute("\\abc9_keep")) - continue; + auto inst_module = module->design->module(cell->type); + bool abc9_box = inst_module && inst_module->attributes.count("\\abc9_box_id") && !cell->get_bool_attribute("\\abc9_keep"); + abc9_box_seen = abc9_box_seen || abc9_box; - for (const auto &conn : cell->connections()) { - auto port_wire = inst_module->wire(conn.first); - // Ignore inout for the sake of topographical ordering - if (port_wire->port_input && !port_wire->port_output) - for (auto bit : sigmap(conn.second)) - bit_users[bit].insert(cell->name); - if (port_wire->port_output) - for (auto bit : sigmap(conn.second)) - bit_drivers[bit].insert(cell->name); - } + if (!abc9_box && !yosys_celltypes.cell_known(cell->type)) + continue; - abc9_box_seen = true; + for (auto conn : cell->connections()) { + if (cell->input(conn.first)) + for (auto bit : sigmap(conn.second)) + bit_users[bit].insert(cell->name); - toposort.node(cell->name); + if (cell->output(conn.first)) + for (auto bit : sigmap(conn.second)) + bit_drivers[bit].insert(cell->name); } + + toposort.node(cell->name); } if (!abc9_box_seen) -- cgit v1.2.3 From 6556a1347ab56b022a599835071c6b3059787462 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Sat, 4 Jan 2020 09:17:01 -0800 Subject: Fix when -dff not given --- backends/aiger/xaiger.cc | 24 ++++++------- passes/techmap/abc9.cc | 5 ++- passes/techmap/abc9_map.cc | 18 ++-------- passes/techmap/abc9_ops.cc | 85 +++++++++++++++++++++++----------------------- 4 files changed, 59 insertions(+), 73 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 7ef744d04..32b218a22 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -239,17 +239,13 @@ struct XAigerWriter RTLIL::Module* inst_module = module->design->module(cell->type); if (inst_module) { - bool abc9_box = inst_module->attributes.count("\\abc9_box_id"); - bool abc9_flop = inst_module->get_bool_attribute("\\abc9_flop"); - if (abc9_box && cell->get_bool_attribute("\\abc9_keep")) - abc9_box = false; - - if (abc9_box) { - int abc9_box_order = cell->attributes.at("\\abc9_box_order").as_int(); - if (GetSize(box_list) <= abc9_box_order) - box_list.resize(abc9_box_order+1); - box_list[abc9_box_order] = cell; - if (!abc9_flop) + auto it = cell->attributes.find("\\abc9_box_seq"); + if (it != cell->attributes.end()) { + int abc9_box_seq = it->second.as_int(); + if (GetSize(box_list) <= abc9_box_seq) + box_list.resize(abc9_box_seq+1); + box_list[abc9_box_seq] = cell; + if (!inst_module->get_bool_attribute("\\abc9_flop")) continue; } @@ -542,6 +538,8 @@ struct XAigerWriter int box_count = 0; for (auto cell : box_list) { + log_assert(cell); + RTLIL::Module* box_module = module->design->module(cell->type); log_assert(box_module); @@ -611,7 +609,7 @@ struct XAigerWriter f.write(buffer_str.data(), buffer_str.size()); if (holes_module) { - log_push(); + log_module(holes_module); std::stringstream a_buffer; XAigerWriter writer(holes_module); @@ -622,8 +620,6 @@ struct XAigerWriter int32_t buffer_size_be = to_big_endian(buffer_str.size()); f.write(reinterpret_cast(&buffer_size_be), sizeof(buffer_size_be)); f.write(buffer_str.data(), buffer_str.size()); - - log_pop(); } } diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 0da815870..d51ed3352 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -186,7 +186,10 @@ struct Abc9Pass : public ScriptPass void script() YS_OVERRIDE { run("scc -set_attr abc9_scc_id {}"); - run("abc9_ops -break_scc -prep_holes"); + if (help_mode) + run("abc9_ops -break_scc -prep_holes [-dff]", "(option for -dff)"); + else + run("abc9_ops -break_scc -prep_holes" + std::string(dff_mode ? " -dff" : ""), "(option for -dff)"); run("select -set abc9_holes A:abc9_holes"); run("flatten -wb @abc9_holes"); run("techmap @abc9_holes"); diff --git a/passes/techmap/abc9_map.cc b/passes/techmap/abc9_map.cc index 171289c6d..d007dbcc2 100644 --- a/passes/techmap/abc9_map.cc +++ b/passes/techmap/abc9_map.cc @@ -355,28 +355,14 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip if (markgroups) remap_wire->attributes[ID(abcgroup)] = map_autoidx; } - dict abc9_box; vector boxes; for (auto cell : cells) { if (cell->type.in(ID($_AND_), ID($_NOT_), ID($__ABC9_FF_))) { 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) { - auto kt = cell->attributes.find("\\abc9_keep"); - bool abc9_keep = false; - if (kt != cell->attributes.end()) { - abc9_keep = kt->second.as_bool(); - cell->attributes.erase(kt); - } - if (!abc9_keep) - boxes.emplace_back(cell); - } + if (cell->attributes.erase("\\abc9_box_seq")) + boxes.emplace_back(cell); } dict> bit_drivers, bit_users; diff --git a/passes/techmap/abc9_ops.cc b/passes/techmap/abc9_ops.cc index 2f07de8d4..ab5aa9f8d 100644 --- a/passes/techmap/abc9_ops.cc +++ b/passes/techmap/abc9_ops.cc @@ -109,39 +109,31 @@ void prep_dff(RTLIL::Module *module) typedef SigSpec clkdomain_t; dict clk_to_mergeability; - //if (dff_mode) - for (auto cell : module->selected_cells()) { - if (cell->type != "$__ABC9_FF_") - continue; + 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); - } - //else - // for (auto cell : module->selected_cells()) { - // auto inst_module = design->module(cell->type); - // if (!inst_module || !inst_module->get_bool_attribute("\\abc9_flop")) - // continue; - // cell->set_bool_attribute("\\abc9_keep"); - // } + 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) { @@ -188,7 +180,7 @@ void prep_dff(RTLIL::Module *module) } } -void prep_holes(RTLIL::Module *module) +void prep_holes(RTLIL::Module *module, bool dff) { auto design = module->design; log_assert(design); @@ -204,10 +196,15 @@ void prep_holes(RTLIL::Module *module) continue; auto inst_module = module->design->module(cell->type); - bool abc9_box = inst_module && inst_module->attributes.count("\\abc9_box_id") && !cell->get_bool_attribute("\\abc9_keep"); - abc9_box_seen = abc9_box_seen || abc9_box; - - if (!abc9_box && !yosys_celltypes.cell_known(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()) { @@ -215,7 +212,7 @@ void prep_holes(RTLIL::Module *module) for (auto bit : sigmap(conn.second)) bit_users[bit].insert(cell->name); - if (cell->output(conn.first)) + if (cell->output(conn.first) && !abc9_flop) for (auto bit : sigmap(conn.second)) bit_drivers[bit].insert(cell->name); } @@ -255,8 +252,7 @@ void prep_holes(RTLIL::Module *module) log_assert(cell); RTLIL::Module* box_module = design->module(cell->type); - if (!box_module || !box_module->attributes.count("\\abc9_box_id") - || cell->get_bool_attribute("\\abc9_keep")) + if (!box_module || !box_module->attributes.count("\\abc9_box_id")) continue; bool blackbox = box_module->get_blackbox_attribute(true /* ignore_wb */); @@ -297,7 +293,7 @@ void prep_holes(RTLIL::Module *module) } } - cell->attributes["\\abc9_box_order"] = box_list.size(); + cell->attributes["\\abc9_box_seq"] = box_list.size(); box_list.emplace_back(cell); } log_assert(!box_list.empty()); @@ -437,6 +433,7 @@ struct Abc9OpsPass : public Pass { 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++) { @@ -457,6 +454,10 @@ struct Abc9OpsPass : public Pass { prep_holes_mode = true; continue; } + if (arg == "-dff") { + dff_mode = true; + continue; + } break; } extra_args(args, argidx, design); @@ -479,7 +480,7 @@ struct Abc9OpsPass : public Pass { if (prep_dff_mode) prep_dff(mod); if (prep_holes_mode) - prep_holes(mod); + prep_holes(mod, dff_mode); } } } Abc9OpsPass; -- cgit v1.2.3 From 8293a3fe749701c7df425acd81e24a2a34f5032e Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Sat, 4 Jan 2020 09:30:48 -0800 Subject: Cleanup --- passes/techmap/abc9_map.cc | 46 ++++++++++++++++------------------------------ 1 file changed, 16 insertions(+), 30 deletions(-) diff --git a/passes/techmap/abc9_map.cc b/passes/techmap/abc9_map.cc index d007dbcc2..b3642ab22 100644 --- a/passes/techmap/abc9_map.cc +++ b/passes/techmap/abc9_map.cc @@ -198,7 +198,7 @@ struct abc9_output_filter void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string script_file, std::string exe_file, vector lut_costs, std::string delay_target, std::string /*lutin_shared*/, bool fast_mode, - const std::vector &cells, bool show_tempdir, std::string box_file, std::string lut_file, + bool show_tempdir, std::string box_file, std::string lut_file, std::string wire_delay, bool nomfs, std::string tempdir_name ) { @@ -355,15 +355,11 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip if (markgroups) remap_wire->attributes[ID(abcgroup)] = map_autoidx; } - vector boxes; - for (auto cell : cells) { - if (cell->type.in(ID($_AND_), ID($_NOT_), ID($__ABC9_FF_))) { - module->remove(cell); - continue; - } - if (cell->attributes.erase("\\abc9_box_seq")) - boxes.emplace_back(cell); - } + 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> bit_drivers, bit_users; TopoSort toposort; @@ -455,9 +451,18 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip cell->attributes = mapped_cell->attributes; } + auto abc9_box = cell->attributes.erase("\\abc9_box_seq"); + if (abc9_box) { + module->swap_names(cell, existing_cell); + module->remove(existing_cell); + } 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()) { + // Skip entire box ports composed entirely of padding only + if (abc9_box && conn.second.is_wire() && conn.second.as_wire()->get_bool_attribute(ID(abc9_padding))) + continue; + RTLIL::SigSpec newsig; for (auto c : conn.second.chunks()) { if (c.width == 0) @@ -483,23 +488,6 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip } } - 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()) { @@ -888,10 +876,8 @@ struct Abc9MapPass : public Pass { continue; } - const std::vector all_cells = mod->selected_cells(); - abc9_module(design, mod, script_file, exe_file, lut_costs, - delay_target, lutin_shared, fast_mode, all_cells, show_tempdir, + delay_target, lutin_shared, fast_mode, show_tempdir, box_file, lut_file, wire_delay, nomfs, tempdir_name); } } -- cgit v1.2.3 From c5d28f5d6b20a42e6f3a4b1a4e3be341a352e5e3 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Sat, 4 Jan 2020 19:00:44 +0100 Subject: Valid to have attribute starting with SB_CARRY. --- techlibs/ice40/ice40_opt.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/techlibs/ice40/ice40_opt.cc b/techlibs/ice40/ice40_opt.cc index 371ceb623..9bee0444b 100644 --- a/techlibs/ice40/ice40_opt.cc +++ b/techlibs/ice40/ice40_opt.cc @@ -128,6 +128,8 @@ static void run_ice40_opts(Module *module) new_attr.insert(std::make_pair(a.first, a.second)); else if (a.first.in(ID(SB_LUT4.name), ID::keep, ID(module_not_derived))) continue; + else if (a.first.begins_with("\\SB_CARRY.\\")) + continue; else log_abort(); cell->attributes = std::move(new_attr); -- cgit v1.2.3 From b76b02358439cd04ed5cad5cb889e8b43c801ac1 Mon Sep 17 00:00:00 2001 From: Cassie Jones Date: Sun, 5 Jan 2020 03:19:02 -0500 Subject: Add --version and -version as aliases for -V The flag --version is commonly accepted by command line tools. The code for the version flags added here matches the pattern used for the help flag aliases, for consistency. Fixes #1612 --- kernel/driver.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/kernel/driver.cc b/kernel/driver.cc index 70a97c4b9..56899dcc4 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -317,6 +317,12 @@ int main(int argc, char **argv) exit(0); } + if (argc == 2 && (!strcmp(argv[1], "-V") || !strcmp(argv[1], "-version") || !strcmp(argv[1], "--version"))) + { + printf("%s\n", yosys_version_str); + exit(0); + } + int opt; while ((opt = getopt(argc, argv, "MXAQTVSgm:f:Hh:b:o:p:l:L:qv:tds:c:W:w:e:D:P:E:")) != -1) { -- cgit v1.2.3 From b5f60e055d07579a2d4f23fc053ca030f103f377 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Sun, 5 Jan 2020 10:20:24 -0800 Subject: write_xaiger to pad, not abc9_ops -prep_holes --- backends/aiger/xaiger.cc | 26 ++++++++++++++++---------- passes/techmap/abc9_map.cc | 13 ++++--------- passes/techmap/abc9_ops.cc | 39 --------------------------------------- 3 files changed, 20 insertions(+), 58 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 32b218a22..5aea70f3b 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -332,13 +332,14 @@ struct XAigerWriter } } - // Fully pad all unused input connections of this box cell with S0 - // Fully pad all undriven output connections of this box cell with anonymous wires for (auto port_name : r.first->second) { auto w = box_module->wire(port_name); log_assert(w); - auto rhs = cell->getPort(port_name); - if (w->port_input) + + SigSpec rhs = cell->connections_.at(port_name, SigSpec()); + if (w->port_input) { + // Add padding to fill entire port + rhs.append(SigSpec(State::Sx, GetSize(w)-GetSize(rhs))); for (auto b : rhs) { SigBit I = sigmap(b); if (b == RTLIL::Sx) @@ -352,14 +353,18 @@ struct XAigerWriter co_bits.emplace_back(b); unused_bits.erase(I); } - if (w->port_output) - for (const auto &b : rhs.bits()) { + } + if (w->port_output) { + // Add padding to fill entire port + rhs.append(SigSpec(State::Sx, GetSize(w)-GetSize(rhs))); + for (const auto &b : rhs) { SigBit O = sigmap(b); if (O != b) alias_map[O] = b; ci_bits.emplace_back(b); undriven_bits.erase(O); } + } } // Connect .abc9_ff.Q (inserted by abc9_map.v) as the last input to the flop box @@ -418,8 +423,11 @@ struct XAigerWriter for (auto &bit : ci_bits) { aig_m++, aig_i++; - log_assert(!aig_map.count(bit)); - aig_map[bit] = 2*aig_m; + // State::Sx if padding + if (bit != State::Sx) { + log_assert(!aig_map.count(bit)); + aig_map[bit] = 2*aig_m; + } } for (auto bit : co_bits) { @@ -609,8 +617,6 @@ struct XAigerWriter f.write(buffer_str.data(), buffer_str.size()); if (holes_module) { - log_module(holes_module); - std::stringstream a_buffer; XAigerWriter writer(holes_module); writer.write_aiger(a_buffer, false /*ascii_mode*/); diff --git a/passes/techmap/abc9_map.cc b/passes/techmap/abc9_map.cc index b3642ab22..e061cadeb 100644 --- a/passes/techmap/abc9_map.cc +++ b/passes/techmap/abc9_map.cc @@ -445,24 +445,19 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip 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; } - auto abc9_box = cell->attributes.erase("\\abc9_box_seq"); - if (abc9_box) { - module->swap_names(cell, existing_cell); - module->remove(existing_cell); - } 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()) { - // Skip entire box ports composed entirely of padding only - if (abc9_box && conn.second.is_wire() && conn.second.as_wire()->get_bool_attribute(ID(abc9_padding))) - continue; - RTLIL::SigSpec newsig; for (auto c : conn.second.chunks()) { if (c.width == 0) diff --git a/passes/techmap/abc9_ops.cc b/passes/techmap/abc9_ops.cc index ab5aa9f8d..730431ebf 100644 --- a/passes/techmap/abc9_ops.cc +++ b/passes/techmap/abc9_ops.cc @@ -254,45 +254,6 @@ void prep_holes(RTLIL::Module *module, bool dff) RTLIL::Module* box_module = design->module(cell->type); if (!box_module || !box_module->attributes.count("\\abc9_box_id")) continue; - - bool blackbox = box_module->get_blackbox_attribute(true /* ignore_wb */); - - // Fully pad all unused input connections of this box cell with S0 - // Fully pad all undriven output connections of this box cell with anonymous wires - for (const auto &port_name : box_module->ports) { - RTLIL::Wire* 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->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); - } - } - } - cell->attributes["\\abc9_box_seq"] = box_list.size(); box_list.emplace_back(cell); } -- cgit v1.2.3 From b376548fb99b231182a27090ecbfc6482a2aff7a Mon Sep 17 00:00:00 2001 From: "N. Engelhardt" Date: Mon, 6 Jan 2020 10:46:10 +0100 Subject: inherit default values when checking scratchpad for arguments --- passes/techmap/abc9.cc | 37 ++++++++++--------------------------- 1 file changed, 10 insertions(+), 27 deletions(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 913b299d2..17caf6c7a 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -954,39 +954,22 @@ struct Abc9Pass : public Pass { // get arguments from scratchpad first, then override by command arguments std::string lut_arg, luts_arg; - if (design->scratchpad.count("abc9.script")) { - script_file = design->scratchpad_get_string("abc9.script"); - } + exe_file = design->scratchpad_get_string("abc9.exe", exe_file /* inherit default value if not set */); + script_file = design->scratchpad_get_string("abc9.script", script_file); if (design->scratchpad.count("abc9.D")) { delay_target = "-D " + design->scratchpad_get_string("abc9.D"); } - if (design->scratchpad.count("abc9.lut")) { - lut_arg = design->scratchpad_get_string("abc9.lut"); - } - if (design->scratchpad.count("abc9.luts")) { - luts_arg = design->scratchpad_get_string("abc9.luts"); - } - if (design->scratchpad.count("abc9.fast")) { - fast_mode = design->scratchpad_get_bool("abc9.fast", false /* default value if not bool-like */); - } - if (design->scratchpad.count("abc9.nocleanup")) { - cleanup = !design->scratchpad_get_bool("abc9.nocleanup", false /* default value if not bool-like */); - } - if (design->scratchpad.count("abc9.showtmp")) { - show_tempdir = design->scratchpad_get_bool("abc9.showtmp", false /* default value if not bool-like */); - } - if (design->scratchpad.count("abc9.markgroups")) { - markgroups = design->scratchpad_get_bool("abc9.markgroups", false /* default value if not bool-like */); - } - if (design->scratchpad.count("abc9.box")) { - box_file = design->scratchpad_get_string("abc9.box"); - } + lut_arg = design->scratchpad_get_string("abc9.lut", lut_arg); + luts_arg = design->scratchpad_get_string("abc9.luts", luts_arg); + fast_mode = design->scratchpad_get_bool("abc9.fast", fast_mode); + cleanup = !design->scratchpad_get_bool("abc9.nocleanup", !cleanup); + show_tempdir = design->scratchpad_get_bool("abc9.showtmp", show_tempdir); + markgroups = design->scratchpad_get_bool("abc9.markgroups", markgroups); + box_file = design->scratchpad_get_string("abc9.box", box_file); if (design->scratchpad.count("abc9.W")) { wire_delay = "-W " + design->scratchpad_get_string("abc9.W"); } - if (design->scratchpad.count("abc9.nomfs")) { - nomfs = design->scratchpad_get_bool("abc9.nomfs", false /* default value if not bool-like */); - } + nomfs = design->scratchpad_get_bool("abc9.nomfs", nomfs); size_t argidx; char pwd [PATH_MAX]; -- cgit v1.2.3 From 7764b62d239cb5393cf2386ca047dca3efe518fc Mon Sep 17 00:00:00 2001 From: "N. Engelhardt" Date: Mon, 6 Jan 2020 10:46:44 +0100 Subject: check scratchpad for arguments in abc pass too --- passes/techmap/abc.cc | 371 +++++++++++++++++++++++++++++--------------------- 1 file changed, 214 insertions(+), 157 deletions(-) diff --git a/passes/techmap/abc.cc b/passes/techmap/abc.cc index 50bae5e85..28a1c01b1 100644 --- a/passes/techmap/abc.cc +++ b/passes/techmap/abc.cc @@ -732,8 +732,6 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin abc_script += script_file[i]; } else abc_script += stringf("source %s", script_file.c_str()); - } else if (design->scratchpad.count("abc.script")) { - abc_script += design->scratchpad_get_string("abc.script"); } else if (!lut_costs.empty()) { bool all_luts_cost_same = true; for (int this_cost : lut_costs) @@ -1516,7 +1514,47 @@ struct AbcPass : public Pass { #endif #endif - size_t argidx; + // get arguments from scratchpad first, then override by command arguments + std::string lut_arg, luts_arg, g_arg; + exe_file = design->scratchpad_get_string("abc.exe", exe_file /* inherit default value if not set */); + script_file = design->scratchpad_get_string("abc.script", script_file); + liberty_file = design->scratchpad_get_string("abc.liberty", liberty_file); + constr_file = design->scratchpad_get_string("abc.constr", constr_file); + if (design->scratchpad.count("abc.D")) { + delay_target = "-D " + design->scratchpad_get_string("abc.D"); + } + if (design->scratchpad.count("abc.I")) { + sop_inputs = "-I " + design->scratchpad_get_string("abc.I"); + } + if (design->scratchpad.count("abc.P")) { + sop_products = "-P " + design->scratchpad_get_string("abc.P"); + } + if (design->scratchpad.count("abc.S")) { + lutin_shared = "-S " + design->scratchpad_get_string("abc.S"); + } + lut_arg = design->scratchpad_get_string("abc.lut", lut_arg); + luts_arg = design->scratchpad_get_string("abc.luts", luts_arg); + sop_mode = design->scratchpad_get_bool("abc.sop", sop_mode); + map_mux4 = design->scratchpad_get_bool("abc.mux4", map_mux4); + map_mux8 = design->scratchpad_get_bool("abc.mux8", map_mux8); + map_mux16 = design->scratchpad_get_bool("abc.mux16", map_mux16); + abc_dress = design->scratchpad_get_bool("abc.dress", abc_dress); + g_arg = design->scratchpad_get_string("abc.g", g_arg); + + fast_mode = design->scratchpad_get_bool("abc.fast", fast_mode); + dff_mode = design->scratchpad_get_bool("abc.dff", dff_mode); + if (design->scratchpad.count("abc.clk")) { + clk_str = design->scratchpad_get_string("abc.clk"); + dff_mode = true; + } + keepff = design->scratchpad_get_bool("abc.keepff", keepff); + cleanup = !design->scratchpad_get_bool("abc.nocleanup", !cleanup); + keepff = design->scratchpad_get_bool("abc.keepff", keepff); + show_tempdir = design->scratchpad_get_bool("abc.showtmp", show_tempdir); + markgroups = design->scratchpad_get_bool("abc.markgroups", markgroups); + + size_t argidx, g_argidx; + bool g_arg_from_cmd = false; char pwd [PATH_MAX]; if (!getcwd(pwd, sizeof(pwd))) { log_cmd_error("getcwd failed: %s\n", strerror(errno)); @@ -1530,23 +1568,14 @@ struct AbcPass : public Pass { } 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 == "-liberty" && argidx+1 < args.size()) { liberty_file = args[++argidx]; - rewrite_filename(liberty_file); - if (!liberty_file.empty() && !is_absolute_path(liberty_file)) - liberty_file = std::string(pwd) + "/" + liberty_file; continue; } if (arg == "-constr" && argidx+1 < args.size()) { - rewrite_filename(constr_file); constr_file = args[++argidx]; - if (!constr_file.empty() && !is_absolute_path(constr_file)) - constr_file = std::string(pwd) + "/" + constr_file; continue; } if (arg == "-D" && argidx+1 < args.size()) { @@ -1566,37 +1595,11 @@ struct AbcPass : public Pass { continue; } if (arg == "-lut" && argidx+1 < args.size()) { - string arg = args[++argidx]; - 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)); + lut_arg = args[++argidx]; 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) < std::atoi(parts.at(0).c_str())) - lut_costs.push_back(atoi(parts.at(1).c_str())); - else - log_cmd_error("Invalid -luts syntax.\n"); - } + luts_arg = args[++argidx]; continue; } if (arg == "-sop") { @@ -1620,123 +1623,9 @@ struct AbcPass : public Pass { continue; } if (arg == "-g" && argidx+1 < args.size()) { - for (auto g : split_tokens(args[++argidx], ",")) { - vector gate_list; - bool remove_gates = false; - if (GetSize(g) > 0 && g[0] == '-') { - remove_gates = true; - g = g.substr(1); - } - if (g == "AND") goto ok_gate; - if (g == "NAND") goto ok_gate; - if (g == "OR") goto ok_gate; - if (g == "NOR") goto ok_gate; - if (g == "XOR") goto ok_gate; - if (g == "XNOR") goto ok_gate; - if (g == "ANDNOT") goto ok_gate; - if (g == "ORNOT") goto ok_gate; - if (g == "MUX") goto ok_gate; - if (g == "NMUX") goto ok_gate; - if (g == "AOI3") goto ok_gate; - if (g == "OAI3") goto ok_gate; - if (g == "AOI4") goto ok_gate; - if (g == "OAI4") goto ok_gate; - if (g == "simple") { - gate_list.push_back("AND"); - gate_list.push_back("OR"); - gate_list.push_back("XOR"); - gate_list.push_back("MUX"); - goto ok_alias; - } - if (g == "cmos2") { - if (!remove_gates) - cmos_cost = true; - gate_list.push_back("NAND"); - gate_list.push_back("NOR"); - goto ok_alias; - } - if (g == "cmos3") { - if (!remove_gates) - cmos_cost = true; - gate_list.push_back("NAND"); - gate_list.push_back("NOR"); - gate_list.push_back("AOI3"); - gate_list.push_back("OAI3"); - goto ok_alias; - } - if (g == "cmos4") { - if (!remove_gates) - cmos_cost = true; - gate_list.push_back("NAND"); - gate_list.push_back("NOR"); - gate_list.push_back("AOI3"); - gate_list.push_back("OAI3"); - gate_list.push_back("AOI4"); - gate_list.push_back("OAI4"); - goto ok_alias; - } - if (g == "cmos") { - if (!remove_gates) - cmos_cost = true; - gate_list.push_back("NAND"); - gate_list.push_back("NOR"); - gate_list.push_back("AOI3"); - gate_list.push_back("OAI3"); - gate_list.push_back("AOI4"); - gate_list.push_back("OAI4"); - gate_list.push_back("NMUX"); - gate_list.push_back("MUX"); - gate_list.push_back("XOR"); - gate_list.push_back("XNOR"); - goto ok_alias; - } - if (g == "gates") { - gate_list.push_back("AND"); - gate_list.push_back("NAND"); - gate_list.push_back("OR"); - gate_list.push_back("NOR"); - gate_list.push_back("XOR"); - gate_list.push_back("XNOR"); - gate_list.push_back("ANDNOT"); - gate_list.push_back("ORNOT"); - goto ok_alias; - } - if (g == "aig") { - gate_list.push_back("AND"); - gate_list.push_back("NAND"); - gate_list.push_back("OR"); - gate_list.push_back("NOR"); - gate_list.push_back("ANDNOT"); - gate_list.push_back("ORNOT"); - goto ok_alias; - } - if (g == "all") { - gate_list.push_back("AND"); - gate_list.push_back("NAND"); - gate_list.push_back("OR"); - gate_list.push_back("NOR"); - gate_list.push_back("XOR"); - gate_list.push_back("XNOR"); - gate_list.push_back("ANDNOT"); - gate_list.push_back("ORNOT"); - gate_list.push_back("AOI3"); - gate_list.push_back("OAI3"); - gate_list.push_back("AOI4"); - gate_list.push_back("OAI4"); - gate_list.push_back("MUX"); - gate_list.push_back("NMUX"); - } - cmd_error(args, argidx, stringf("Unsupported gate type: %s", g.c_str())); - ok_gate: - gate_list.push_back(g); - ok_alias: - for (auto gate : gate_list) { - if (remove_gates) - enabled_gates.erase(gate); - else - enabled_gates.insert(gate); - } - } + g_arg = args[++argidx]; + g_argidx = argidx; + g_arg_from_cmd = true; continue; } if (arg == "-fast") { @@ -1772,6 +1661,174 @@ struct AbcPass : public Pass { } extra_args(args, argidx, design); + rewrite_filename(script_file); + if (!script_file.empty() && !is_absolute_path(script_file) && script_file[0] != '+') + script_file = std::string(pwd) + "/" + script_file; + rewrite_filename(liberty_file); + if (!liberty_file.empty() && !is_absolute_path(liberty_file)) + liberty_file = std::string(pwd) + "/" + liberty_file; + rewrite_filename(constr_file); + if (!constr_file.empty() && !is_absolute_path(constr_file)) + constr_file = std::string(pwd) + "/" + constr_file; + + // handle -lut argument + if (!lut_arg.empty()) { + size_t pos = lut_arg.find_first_of(':'); + int lut_mode = 0, lut_mode2 = 0; + if (pos != string::npos) { + lut_mode = atoi(lut_arg.substr(0, pos).c_str()); + lut_mode2 = atoi(lut_arg.substr(pos+1).c_str()); + } else { + lut_mode = atoi(lut_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)); + } + //handle -luts argument + if (!luts_arg.empty()){ + lut_costs.clear(); + for (auto &tok : split_tokens(luts_arg, ",")) { + 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) < std::atoi(parts.at(0).c_str())) + lut_costs.push_back(atoi(parts.at(1).c_str())); + else + log_cmd_error("Invalid -luts syntax.\n"); + } + } + + // handle -g argument + if (!g_arg.empty()){ + for (auto g : split_tokens(g_arg, ",")) { + vector gate_list; + bool remove_gates = false; + if (GetSize(g) > 0 && g[0] == '-') { + remove_gates = true; + g = g.substr(1); + } + if (g == "AND") goto ok_gate; + if (g == "NAND") goto ok_gate; + if (g == "OR") goto ok_gate; + if (g == "NOR") goto ok_gate; + if (g == "XOR") goto ok_gate; + if (g == "XNOR") goto ok_gate; + if (g == "ANDNOT") goto ok_gate; + if (g == "ORNOT") goto ok_gate; + if (g == "MUX") goto ok_gate; + if (g == "NMUX") goto ok_gate; + if (g == "AOI3") goto ok_gate; + if (g == "OAI3") goto ok_gate; + if (g == "AOI4") goto ok_gate; + if (g == "OAI4") goto ok_gate; + if (g == "simple") { + gate_list.push_back("AND"); + gate_list.push_back("OR"); + gate_list.push_back("XOR"); + gate_list.push_back("MUX"); + goto ok_alias; + } + if (g == "cmos2") { + if (!remove_gates) + cmos_cost = true; + gate_list.push_back("NAND"); + gate_list.push_back("NOR"); + goto ok_alias; + } + if (g == "cmos3") { + if (!remove_gates) + cmos_cost = true; + gate_list.push_back("NAND"); + gate_list.push_back("NOR"); + gate_list.push_back("AOI3"); + gate_list.push_back("OAI3"); + goto ok_alias; + } + if (g == "cmos4") { + if (!remove_gates) + cmos_cost = true; + gate_list.push_back("NAND"); + gate_list.push_back("NOR"); + gate_list.push_back("AOI3"); + gate_list.push_back("OAI3"); + gate_list.push_back("AOI4"); + gate_list.push_back("OAI4"); + goto ok_alias; + } + if (g == "cmos") { + if (!remove_gates) + cmos_cost = true; + gate_list.push_back("NAND"); + gate_list.push_back("NOR"); + gate_list.push_back("AOI3"); + gate_list.push_back("OAI3"); + gate_list.push_back("AOI4"); + gate_list.push_back("OAI4"); + gate_list.push_back("NMUX"); + gate_list.push_back("MUX"); + gate_list.push_back("XOR"); + gate_list.push_back("XNOR"); + goto ok_alias; + } + if (g == "gates") { + gate_list.push_back("AND"); + gate_list.push_back("NAND"); + gate_list.push_back("OR"); + gate_list.push_back("NOR"); + gate_list.push_back("XOR"); + gate_list.push_back("XNOR"); + gate_list.push_back("ANDNOT"); + gate_list.push_back("ORNOT"); + goto ok_alias; + } + if (g == "aig") { + gate_list.push_back("AND"); + gate_list.push_back("NAND"); + gate_list.push_back("OR"); + gate_list.push_back("NOR"); + gate_list.push_back("ANDNOT"); + gate_list.push_back("ORNOT"); + goto ok_alias; + } + if (g == "all") { + gate_list.push_back("AND"); + gate_list.push_back("NAND"); + gate_list.push_back("OR"); + gate_list.push_back("NOR"); + gate_list.push_back("XOR"); + gate_list.push_back("XNOR"); + gate_list.push_back("ANDNOT"); + gate_list.push_back("ORNOT"); + gate_list.push_back("AOI3"); + gate_list.push_back("OAI3"); + gate_list.push_back("AOI4"); + gate_list.push_back("OAI4"); + gate_list.push_back("MUX"); + gate_list.push_back("NMUX"); + } + if (g_arg_from_cmd) + cmd_error(args, g_argidx, stringf("Unsupported gate type: %s", g.c_str())); + else + log_cmd_error("Unsupported gate type: %s", g.c_str()); + ok_gate: + gate_list.push_back(g); + ok_alias: + for (auto gate : gate_list) { + if (remove_gates) + enabled_gates.erase(gate); + else + enabled_gates.insert(gate); + } + } + } + if (!lut_costs.empty() && !liberty_file.empty()) log_cmd_error("Got -lut and -liberty! These two options are exclusive.\n"); if (!constr_file.empty() && liberty_file.empty()) -- cgit v1.2.3 From ffd38cb5ea7a6b7d93a49c90bf603131f6c760af Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 6 Jan 2020 09:03:18 -0800 Subject: Reword (* abc9_flop *) description --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index aab1c7d6b..77e9410da 100644 --- a/README.md +++ b/README.md @@ -376,10 +376,11 @@ Verilog Attributes and non-standard features - The port attribute ``abc9_arrival`` specifies an integer (for output ports only) to be used as the arrival time of this sequential port. It can be used, for example, to specify the clk-to-Q delay of a flip-flop for consideration - during techmapping. + during `abc9` techmapping. - The module attribute ``abc9_flop`` is a boolean marking the module as a - whitebox that describes the synchronous behaviour of a flip-flop. + flip-flop. This allows `abc9` to analyse its contents in order to perform + sequential synthesis. - The frontend sets attributes ``always_comb``, ``always_latch`` and ``always_ff`` on processes derived from SystemVerilog style always blocks -- cgit v1.2.3 From c89186b363056060838c79621889075aa1484194 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 6 Jan 2020 09:27:35 -0800 Subject: Revert ABCREV --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index d7319796b..a85f6350c 100644 --- a/Makefile +++ b/Makefile @@ -128,7 +128,7 @@ bumpversion: # is just a symlink to your actual ABC working directory, as 'make mrproper' # will remove the 'abc' directory and you do not want to accidentally # delete your work on ABC.. -ABCREV = f6dc4a5 +ABCREV = 623b5e8 ABCPULL = 1 ABCURL ?= https://github.com/berkeley-abc/abc ABCMKARGS = CC="$(CXX)" CXX="$(CXX)" ABC_USE_LIBSTDCXX=1 -- cgit v1.2.3 From f576721a37b49152990eaba3e2eff23b2c10c2e6 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 6 Jan 2020 09:46:02 -0800 Subject: Add abc9.dff scratchpad option --- passes/techmap/abc9.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index df37f7257..a5f593873 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -871,6 +871,7 @@ struct Abc9Pass : public Pass { lut_arg = design->scratchpad_get_string("abc9.lut", lut_arg); luts_arg = design->scratchpad_get_string("abc9.luts", luts_arg); fast_mode = design->scratchpad_get_bool("abc9.fast", fast_mode); + dff_mode = design->scratchpad_get_bool("abc9.dff", dff_mode); cleanup = !design->scratchpad_get_bool("abc9.nocleanup", !cleanup); show_tempdir = design->scratchpad_get_bool("abc9.showtmp", show_tempdir); markgroups = design->scratchpad_get_bool("abc9.markgroups", markgroups); -- cgit v1.2.3 From fcc1c14adc44ae1772dc2c41f577e39063d03144 Mon Sep 17 00:00:00 2001 From: "N. Engelhardt" Date: Mon, 6 Jan 2020 19:10:13 +0100 Subject: error if multiple -g options are given for abc --- passes/techmap/abc.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/passes/techmap/abc.cc b/passes/techmap/abc.cc index 28a1c01b1..581652a41 100644 --- a/passes/techmap/abc.cc +++ b/passes/techmap/abc.cc @@ -1623,6 +1623,8 @@ struct AbcPass : public Pass { continue; } if (arg == "-g" && argidx+1 < args.size()) { + if (g_arg_from_cmd) + log_cmd_error("Can only use -g once. Please combine."); g_arg = args[++argidx]; g_argidx = argidx; g_arg_from_cmd = true; -- cgit v1.2.3 From 19ec54f956924b93070d2970b51aa1d8dbe16b73 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 6 Jan 2020 10:18:59 -0800 Subject: write_aiger: make more robust --- backends/aiger/aiger.cc | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/backends/aiger/aiger.cc b/backends/aiger/aiger.cc index 44718baae..a51e3648c 100644 --- a/backends/aiger/aiger.cc +++ b/backends/aiger/aiger.cc @@ -787,6 +787,14 @@ struct AigerBackend : public Backend { if (top_module == nullptr) log_error("Can't find top module in current design!\n"); + if (!design->selected_whole_module(top_module)) + log_cmd_error("Can't handle partially selected module %s!\n", log_id(top_module)); + + if (!top_module->processes.empty()) + log_error("Found unmapped processes in module %s: unmapped processes are not supported in AIGER backend!\n", log_id(top_module)); + if (!top_module->memories.empty()) + log_error("Found unmapped memories in module %s: unmapped memories are not supported in AIGER backend!\n", log_id(top_module)); + AigerWriter writer(top_module, zinit_mode, imode, omode, bmode, lmode); writer.write_aiger(*f, ascii_mode, miter_mode, symbols_mode); -- cgit v1.2.3 From 886c5c58834ccdb5f54dfbcb7d09908dc102e20a Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 6 Jan 2020 10:23:04 -0800 Subject: write_xaiger: make more robust, update doc --- backends/aiger/xaiger.cc | 43 ++++++++++++++----------------------------- 1 file changed, 14 insertions(+), 29 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 1f1b9dffe..05e9678ee 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -847,17 +847,13 @@ struct XAigerWriter module->design->scratchpad_set_int("write_xaiger.num_outputs", output_bits.size()); } - void write_map(std::ostream &f, bool verbose_map) + void write_map(std::ostream &f) { dict input_lines; dict output_lines; - dict wire_lines; for (auto wire : module->wires()) { - //if (!verbose_map && wire->name[0] == '$') - // continue; - SigSpec sig = sigmap(wire); for (int i = 0; i < GetSize(wire); i++) @@ -875,14 +871,6 @@ struct XAigerWriter output_lines[o] += stringf("output %d %d %s %d\n", o - GetSize(co_bits), i, log_id(wire), init); continue; } - - if (verbose_map) { - if (aig_map.count(sig[i]) == 0) - continue; - - int a = aig_map.at(sig[i]); - wire_lines[a] += stringf("wire %d %d %s\n", a, i, log_id(wire)); - } } } @@ -899,10 +887,6 @@ struct XAigerWriter for (auto &it : output_lines) f << it.second; log_assert(output_lines.size() == output_bits.size()); - - wire_lines.sort(); - for (auto &it : wire_lines) - f << it.second; } }; @@ -914,8 +898,10 @@ struct XAigerBackend : public Backend { log("\n"); log(" write_xaiger [options] [filename]\n"); log("\n"); - log("Write the current design to an XAIGER file. The design must be flattened and\n"); - log("all unsupported cells will be converted into psuedo-inputs and pseudo-outputs.\n"); + log("Write the top module (according to the (* top *) attribute or if only one module\n"); + log("is currently selected) to an XAIGER file. Any non $_NOT_, $_AND_, $_ABC9_FF_, or"); + log("non (* abc9_box_id *) cells will be converted into psuedo-inputs and\n"); + log("pseudo-outputs.\n"); log("\n"); log(" -ascii\n"); log(" write ASCII version of AIGER format\n"); @@ -923,14 +909,10 @@ struct XAigerBackend : public Backend { log(" -map \n"); log(" write an extra file with port and box symbols\n"); log("\n"); - log(" -vmap \n"); - log(" like -map, but more verbose\n"); - log("\n"); } void execute(std::ostream *&f, std::string filename, std::vector args, RTLIL::Design *design) YS_OVERRIDE { bool ascii_mode = false; - bool verbose_map = false; std::string map_filename; log_header(design, "Executing XAIGER backend.\n"); @@ -946,11 +928,6 @@ struct XAigerBackend : public Backend { map_filename = args[++argidx]; continue; } - if (map_filename.empty() && args[argidx] == "-vmap" && argidx+1 < args.size()) { - map_filename = args[++argidx]; - verbose_map = true; - continue; - } break; } extra_args(f, filename, args, argidx, !ascii_mode); @@ -960,6 +937,14 @@ struct XAigerBackend : public Backend { if (top_module == nullptr) log_error("Can't find top module in current design!\n"); + if (!design->selected_whole_module(top_module)) + log_cmd_error("Can't handle partially selected module %s!\n", log_id(top_module)); + + if (!top_module->processes.empty()) + log_error("Found unmapped processes in module %s: unmapped processes are not supported in XAIGER backend!\n", log_id(top_module)); + if (!top_module->memories.empty()) + log_error("Found unmapped memories in module %s: unmapped memories are not supported in XAIGER backend!\n", log_id(top_module)); + XAigerWriter writer(top_module); writer.write_aiger(*f, ascii_mode); @@ -968,7 +953,7 @@ struct XAigerBackend : public Backend { mapf.open(map_filename.c_str(), std::ofstream::trunc); if (mapf.fail()) log_error("Can't open file `%s' for writing: %s\n", map_filename.c_str(), strerror(errno)); - writer.write_map(mapf, verbose_map); + writer.write_map(mapf); } } } XAigerBackend; -- cgit v1.2.3 From 1cf974ff400b50c09387cc0674b3404a18b4aa6d Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 6 Jan 2020 10:26:49 -0800 Subject: abc9: cleanup --- passes/techmap/abc9.cc | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index a5f593873..05607c7fe 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -249,7 +249,7 @@ struct abc9_output_filter }; void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string script_file, std::string exe_file, - bool cleanup, vector lut_costs, bool dff, std::string delay_target, std::string /*lutin_shared*/, bool fast_mode, + bool cleanup, vector lut_costs, bool dff_mode, 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 ) @@ -420,7 +420,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip dict abc9_box; vector boxes; - for (auto cell : module->selected_cells()) { + for (auto cell : module->cells()) { if (cell->type.in(ID($_AND_), ID($_NOT_), ID($__ABC9_FF_))) { module->remove(cell); continue; @@ -431,7 +431,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip jt = abc9_box.insert(std::make_pair(cell->type, box_module && box_module->attributes.count(ID(abc9_box_id)))).first; if (jt->second) { if (box_module->get_bool_attribute("\\abc9_flop")) { - if (dff) + if (dff_mode) boxes.emplace_back(cell); else box_module->set_bool_attribute("\\abc9_keep", false); @@ -843,7 +843,7 @@ struct Abc9Pass : public Pass { #endif std::string script_file, clk_str, box_file, lut_file; std::string delay_target, lutin_shared = "-S 1", wire_delay; - bool fast_mode = false, dff = false, cleanup = true; + bool fast_mode = false, dff_mode = false, cleanup = true; bool show_tempdir = false; bool nomfs = false; vector lut_costs; @@ -921,7 +921,7 @@ struct Abc9Pass : public Pass { continue; } if (arg == "-dff") { - dff = true; + dff_mode = true; continue; } if (arg == "-nocleanup") { @@ -1010,21 +1010,22 @@ struct Abc9Pass : public Pass { CellTypes ct(design); for (auto module : design->selected_modules()) { - if (module->attributes.count(ID(abc9_box_id))) - continue; - if (module->processes.size() > 0) { log("Skipping module %s as it contains processes.\n", log_id(module)); continue; } + log_assert(!module->attributes.count(ID(abc9_box_id))); + + if (!design->selected_whole_module(module)) + log_cmd_error("Can't handle partially selected module %s!\n", log_id(module)); assign_map.set(module); typedef SigSpec clkdomain_t; dict clk_to_mergeability; - if (dff) - for (auto cell : module->selected_cells()) { + if (dff_mode) + for (auto cell : module->cells()) { if (cell->type != "$__ABC9_FF_") continue; @@ -1050,7 +1051,7 @@ struct Abc9Pass : public Pass { log_assert(r2.second); } else - for (auto cell : module->selected_cells()) { + for (auto cell : module->cells()) { auto inst_module = design->module(cell->type); if (!inst_module || !inst_module->get_bool_attribute("\\abc9_flop")) continue; @@ -1058,7 +1059,7 @@ struct Abc9Pass : public Pass { } design->selected_active_module = module->name.str(); - abc9_module(design, module, script_file, exe_file, cleanup, lut_costs, dff, + abc9_module(design, module, script_file, exe_file, cleanup, lut_costs, dff_mode, delay_target, lutin_shared, fast_mode, show_tempdir, box_file, lut_file, wire_delay, nomfs); design->selected_active_module.clear(); -- cgit v1.2.3 From 275e937fc16635edfd38c18ea9eb9f7cbbdd32c9 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 6 Jan 2020 10:43:21 -0800 Subject: abc9: remove -markgroups option, since operates on fully selected mod --- passes/techmap/abc9.cc | 23 +---------------------- 1 file changed, 1 insertion(+), 22 deletions(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 05607c7fe..1806b2d53 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -63,7 +63,6 @@ extern "C" int Abc_RealMain(int argc, char *argv[]); USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN -bool markgroups; int map_autoidx; inline std::string remap_name(RTLIL::IdString abc9_name) @@ -412,12 +411,6 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip 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; - } - dict abc9_box; vector boxes; for (auto cell : module->cells()) { @@ -496,7 +489,6 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip } else log_abort(); - if (cell && markgroups) cell->attributes[ID(abcgroup)] = map_autoidx; continue; } cell_stats[mapped_cell->type]++; @@ -509,7 +501,6 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip 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; } @@ -521,7 +512,6 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip 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; @@ -743,7 +733,7 @@ struct Abc9Pass : public Pass { log(" abc9 [options] [selection]\n"); log("\n"); log("This pass uses the ABC tool [1] for technology mapping of yosys's internal gate\n"); - log("library to a target architecture.\n"); + log("library to a target architecture. Only fully-selected modules are supported.\n"); log("\n"); log(" -exe \n"); #ifdef ABCEXTERNAL @@ -813,11 +803,6 @@ struct Abc9Pass : public Pass { log(" print the temp dir name in log. usually this is suppressed so that the\n"); log(" command output is identical across runs.\n"); log("\n"); - log(" -markgroups\n"); - log(" set a 'abcgroup' attribute on all objects created by ABC. The value of\n"); - log(" this attribute is a unique integer for each ABC process started. This\n"); - log(" is useful for debugging the partitioning of clock domains.\n"); - log("\n"); log(" -box \n"); log(" pass this file with box library to ABC. Use with -lut.\n"); log("\n"); @@ -847,7 +832,6 @@ struct Abc9Pass : public Pass { bool show_tempdir = false; bool nomfs = false; vector lut_costs; - markgroups = false; #if 0 cleanup = false; @@ -874,7 +858,6 @@ struct Abc9Pass : public Pass { dff_mode = design->scratchpad_get_bool("abc9.dff", dff_mode); cleanup = !design->scratchpad_get_bool("abc9.nocleanup", !cleanup); show_tempdir = design->scratchpad_get_bool("abc9.showtmp", show_tempdir); - markgroups = design->scratchpad_get_bool("abc9.markgroups", markgroups); box_file = design->scratchpad_get_string("abc9.box", box_file); if (design->scratchpad.count("abc9.W")) { wire_delay = "-W " + design->scratchpad_get_string("abc9.W"); @@ -932,10 +915,6 @@ struct Abc9Pass : public Pass { show_tempdir = true; continue; } - if (arg == "-markgroups") { - markgroups = true; - continue; - } if (arg == "-box" && argidx+1 < args.size()) { box_file = args[++argidx]; continue; -- cgit v1.2.3 From 7738d608e3f88695248dd49f923492e643b428dd Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 6 Jan 2020 11:14:05 -0800 Subject: Bump ABCREV for upstream fix --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index a85f6350c..d7319796b 100644 --- a/Makefile +++ b/Makefile @@ -128,7 +128,7 @@ bumpversion: # is just a symlink to your actual ABC working directory, as 'make mrproper' # will remove the 'abc' directory and you do not want to accidentally # delete your work on ABC.. -ABCREV = 623b5e8 +ABCREV = f6dc4a5 ABCPULL = 1 ABCURL ?= https://github.com/berkeley-abc/abc ABCMKARGS = CC="$(CXX)" CXX="$(CXX)" ABC_USE_LIBSTDCXX=1 -- cgit v1.2.3 From 27c150bfcc222512a0f3816e72ee20285acad9b4 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 6 Jan 2020 11:39:08 -0800 Subject: Fix return value of arrival time functions, fix word --- techlibs/xilinx/cells_sim.v | 32 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/techlibs/xilinx/cells_sim.v b/techlibs/xilinx/cells_sim.v index 7bfc36aa3..5e4529fd6 100644 --- a/techlibs/xilinx/cells_sim.v +++ b/techlibs/xilinx/cells_sim.v @@ -2161,13 +2161,13 @@ module DSP48E1 ( output reg MULTSIGNOUT, output OVERFLOW, `ifdef YOSYS - (* abc9_arrival = \DSP48E1.P_arrival (USE_MULT, USE_DPORT, AREG, ADREG, BREG, CREG, DREG, MREG, PREG) *) + (* abc9_arrival = \DSP48E1.P_arrival () *) `endif output reg signed [47:0] P, output reg PATTERNBDETECT, output reg PATTERNDETECT, `ifdef YOSYS - (* abc9_arrival = \DSP48E1.PCOUT_arrival (USE_MULT, USE_DPORT, AREG, ADREG, BREG, CREG, DREG, MREG, PREG) *) + (* abc9_arrival = \DSP48E1.PCOUT_arrival () *) `endif output [47:0] PCOUT, output UNDERFLOW, @@ -2241,26 +2241,24 @@ module DSP48E1 ( parameter [4:0] IS_INMODE_INVERTED = 5'b0; parameter [6:0] IS_OPMODE_INVERTED = 7'b0; - function \DSP48E1.P_arrival ; - input USE_MULT, USE_DPORT; - input AREG, ADREG, BREG, CREG, DREG, MREG, PREG; + function integer \DSP48E1.P_arrival ; begin \DSP48E1.P_arrival = 0; if (USE_MULT == "MULTIPLY" && USE_DPORT == "FALSE") begin if (PREG != 0) \DSP48E1.P_arrival = 329; - // Worse-case from CREG and MREG + // Worst-case from CREG and MREG else if (CREG != 0) \DSP48E1.P_arrival = 1687; else if (MREG != 0) \DSP48E1.P_arrival = 1671; - // Worse-case from AREG and BREG + // Worst-case from AREG and BREG else if (AREG != 0) \DSP48E1.P_arrival = 2952; else if (BREG != 0) \DSP48E1.P_arrival = 2813; end else if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE") begin if (PREG != 0) \DSP48E1.P_arrival = 329; - // Worse-case from CREG and MREG + // Worst-case from CREG and MREG else if (CREG != 0) \DSP48E1.P_arrival = 1687; else if (MREG != 0) \DSP48E1.P_arrival = 1671; - // Worse-case from AREG, ADREG, BREG, DREG + // Worst-case from AREG, ADREG, BREG, DREG else if (AREG != 0) \DSP48E1.P_arrival = 3935; else if (DREG != 0) \DSP48E1.P_arrival = 3908; else if (ADREG != 0) \DSP48E1.P_arrival = 2958; @@ -2268,7 +2266,7 @@ module DSP48E1 ( end else if (USE_MULT == "NONE" && USE_DPORT == "FALSE") begin if (PREG != 0) \DSP48E1.P_arrival = 329; - // Worse-case from AREG, BREG, CREG + // Worst-case from AREG, BREG, CREG else if (CREG != 0) \DSP48E1.P_arrival = 1687; else if (AREG != 0) \DSP48E1.P_arrival = 1632; else if (BREG != 0) \DSP48E1.P_arrival = 1616; @@ -2277,26 +2275,24 @@ module DSP48E1 ( // $error("Invalid DSP48E1 configuration"); end endfunction - function \DSP48E1.PCOUT_arrival ; - input USE_MULT, USE_DPORT; - input AREG, ADREG, BREG, CREG, DREG, MREG, PREG; + function integer \DSP48E1.PCOUT_arrival ; begin \DSP48E1.PCOUT_arrival = 0; if (USE_MULT == "MULTIPLY" && USE_DPORT == "FALSE") begin if (PREG != 0) \DSP48E1.PCOUT_arrival = 435; - // Worse-case from CREG and MREG + // Worst-case from CREG and MREG else if (CREG != 0) \DSP48E1.PCOUT_arrival = 1835; else if (MREG != 0) \DSP48E1.PCOUT_arrival = 1819; - // Worse-case from AREG and BREG + // Worst-case from AREG and BREG else if (AREG != 0) \DSP48E1.PCOUT_arrival = 3098; else if (BREG != 0) \DSP48E1.PCOUT_arrival = 2960; end else if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE") begin if (PREG != 0) \DSP48E1.PCOUT_arrival = 435; - // Worse-case from CREG and MREG + // Worst-case from CREG and MREG else if (CREG != 0) \DSP48E1.PCOUT_arrival = 1835; else if (MREG != 0) \DSP48E1.PCOUT_arrival = 1819; - // Worse-case from AREG, ADREG, BREG, DREG + // Worst-case from AREG, ADREG, BREG, DREG else if (AREG != 0) \DSP48E1.PCOUT_arrival = 4083; else if (DREG != 0) \DSP48E1.PCOUT_arrival = 4056; else if (BREG != 0) \DSP48E1.PCOUT_arrival = 2960; @@ -2304,7 +2300,7 @@ module DSP48E1 ( end else if (USE_MULT == "NONE" && USE_DPORT == "FALSE") begin if (PREG != 0) \DSP48E1.PCOUT_arrival = 435; - // Worse-case from AREG, BREG, CREG + // Worst-case from AREG, BREG, CREG else if (CREG != 0) \DSP48E1.PCOUT_arrival = 1835; else if (AREG != 0) \DSP48E1.PCOUT_arrival = 1780; else if (BREG != 0) \DSP48E1.PCOUT_arrival = 1765; -- cgit v1.2.3 From d152fe961ffb3d7ed0493cde5c21f88fe78644e1 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 6 Jan 2020 11:50:55 -0800 Subject: Fixes --- passes/techmap/abc9.cc | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 1806b2d53..3c781ca44 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -413,11 +413,13 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip dict abc9_box; vector boxes; - for (auto cell : module->cells()) { + for (auto it = module->cells_.begin(); it != module->cells_.end(); ) { + auto cell = it->second; if (cell->type.in(ID($_AND_), ID($_NOT_), ID($__ABC9_FF_))) { - module->remove(cell); + it = module->cells_.erase(it); continue; } + ++it; RTLIL::Module* box_module = design->module(cell->type); auto jt = abc9_box.find(cell->type); if (jt == abc9_box.end()) @@ -996,7 +998,7 @@ struct Abc9Pass : public Pass { log_assert(!module->attributes.count(ID(abc9_box_id))); if (!design->selected_whole_module(module)) - log_cmd_error("Can't handle partially selected module %s!\n", log_id(module)); + log_error("Can't handle partially selected module %s!\n", log_id(module)); assign_map.set(module); -- cgit v1.2.3 From 64ace4b0dc5c8dd24132bc8046b2bacc163f9164 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 6 Jan 2020 11:53:48 -0800 Subject: Fixes --- passes/techmap/abc9.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 3c781ca44..f82511407 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -411,6 +411,9 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip if (mapped_mod == NULL) log_error("ABC output file does not contain a module `$__abc9__'.\n"); + for (auto w : mapped_mod->wires()) + module->addWire(remap_name(w->name), GetSize(w)); + dict abc9_box; vector boxes; for (auto it = module->cells_.begin(); it != module->cells_.end(); ) { -- cgit v1.2.3 From 28bf712372c494043c7adc0de904925a9199c939 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 6 Jan 2020 11:55:56 -0800 Subject: Wrap arrival functions inside `YOSYS too --- techlibs/xilinx/cells_sim.v | 2 ++ 1 file changed, 2 insertions(+) diff --git a/techlibs/xilinx/cells_sim.v b/techlibs/xilinx/cells_sim.v index 5e4529fd6..1cd4d2f30 100644 --- a/techlibs/xilinx/cells_sim.v +++ b/techlibs/xilinx/cells_sim.v @@ -2241,6 +2241,7 @@ module DSP48E1 ( parameter [4:0] IS_INMODE_INVERTED = 5'b0; parameter [6:0] IS_OPMODE_INVERTED = 7'b0; +`ifdef YOSYS function integer \DSP48E1.P_arrival ; begin \DSP48E1.P_arrival = 0; @@ -2309,6 +2310,7 @@ module DSP48E1 ( // $error("Invalid DSP48E1 configuration"); end endfunction +`endif initial begin `ifndef YOSYS -- cgit v1.2.3 From 6728a62d92bc710002cdb2d7270ffac49e09e0d1 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 6 Jan 2020 12:21:50 -0800 Subject: abc9: uncomment nothing to map message --- passes/techmap/abc9.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index f82511407..8cb34e523 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -715,10 +715,10 @@ clone_lut: design->remove(mapped_mod); } - //else - //{ - // log("Don't call ABC as there is nothing to map.\n"); - //} + else + { + log("Don't call ABC as there is nothing to map.\n"); + } if (cleanup) { -- cgit v1.2.3 From 36ae2e52e49ee510a0bec45e7faa4ed60fdc760d Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 6 Jan 2020 12:28:58 -0800 Subject: Fix bad merge --- passes/techmap/abc9.cc | 21 ++------- passes/techmap/abc9_map.cc | 107 ++++++++++++++++++++++++++++----------------- 2 files changed, 69 insertions(+), 59 deletions(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index d54891167..94eea2983 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -146,23 +146,8 @@ struct Abc9Pass : public ScriptPass clear_flags(); // get arguments from scratchpad first, then override by command arguments - std::string lut_arg, luts_arg; - exe_file = design->scratchpad_get_string("abc9.exe", exe_file /* inherit default value if not set */); - script_file = design->scratchpad_get_string("abc9.script", script_file); - if (design->scratchpad.count("abc9.D")) { - delay_target = "-D " + design->scratchpad_get_string("abc9.D"); - } - lut_arg = design->scratchpad_get_string("abc9.lut", lut_arg); - luts_arg = design->scratchpad_get_string("abc9.luts", luts_arg); - fast_mode = design->scratchpad_get_bool("abc9.fast", fast_mode); dff_mode = design->scratchpad_get_bool("abc9.dff", dff_mode); cleanup = !design->scratchpad_get_bool("abc9.nocleanup", !cleanup); - show_tempdir = design->scratchpad_get_bool("abc9.showtmp", show_tempdir); - box_file = design->scratchpad_get_string("abc9.box", box_file); - if (design->scratchpad.count("abc9.W")) { - wire_delay = "-W " + design->scratchpad_get_string("abc9.W"); - } - nomfs = design->scratchpad_get_bool("abc9.nomfs", nomfs); size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) { @@ -224,10 +209,10 @@ struct Abc9Pass : public ScriptPass log("Skipping module %s as it contains processes.\n", log_id(mod)); continue; } - log_assert(!module->attributes.count(ID(abc9_box_id))); + log_assert(!mod->attributes.count(ID(abc9_box_id))); - if (!design->selected_whole_module(module)) - log_error("Can't handle partially selected module %s!\n", log_id(module)); + if (!active_design->selected_whole_module(mod)) + log_error("Can't handle partially selected module %s!\n", log_id(mod)); active_design->selection().select(mod); diff --git a/passes/techmap/abc9_map.cc b/passes/techmap/abc9_map.cc index 0877906ca..e6e4e3e72 100644 --- a/passes/techmap/abc9_map.cc +++ b/passes/techmap/abc9_map.cc @@ -348,7 +348,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip if (mapped_mod == NULL) log_error("ABC output file does not contain a module `$__abc9__'.\n"); - for (auto wire : mapped_mod->wires()) + for (auto w : mapped_mod->wires()) module->addWire(remap_name(w->name), GetSize(w)); for (auto it = module->cells_.begin(); it != module->cells_.end(); ) @@ -727,6 +727,22 @@ struct Abc9MapPass : public Pass { #endif #endif + std::string lut_arg, luts_arg; + exe_file = design->scratchpad_get_string("abc9.exe", exe_file /* inherit default value if not set */); + script_file = design->scratchpad_get_string("abc9.script", script_file); + if (design->scratchpad.count("abc9.D")) { + delay_target = "-D " + design->scratchpad_get_string("abc9.D"); + } + lut_arg = design->scratchpad_get_string("abc9.lut", lut_arg); + luts_arg = design->scratchpad_get_string("abc9.luts", luts_arg); + fast_mode = design->scratchpad_get_bool("abc9.fast", fast_mode); + show_tempdir = design->scratchpad_get_bool("abc9.showtmp", show_tempdir); + box_file = design->scratchpad_get_string("abc9.box", box_file); + if (design->scratchpad.count("abc9.W")) { + wire_delay = "-W " + design->scratchpad_get_string("abc9.W"); + } + nomfs = design->scratchpad_get_bool("abc9.nomfs", nomfs); + size_t argidx; char pwd [PATH_MAX]; if (!getcwd(pwd, sizeof(pwd))) { @@ -741,9 +757,6 @@ struct Abc9MapPass : public Pass { } 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()) { @@ -755,45 +768,11 @@ struct Abc9MapPass : public Pass { // 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; - } + lut_arg = args[++argidx]; 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"); - } + lut_arg = args[++argidx]; continue; } if (arg == "-fast") { @@ -824,6 +803,52 @@ struct Abc9MapPass : public Pass { } extra_args(args, argidx, design); + rewrite_filename(script_file); + if (!script_file.empty() && !is_absolute_path(script_file) && script_file[0] != '+') + script_file = std::string(pwd) + "/" + script_file; + + // handle -lut / -luts args + if (!lut_arg.empty()) { + string arg = lut_arg; + 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 (!luts_arg.empty()) { + lut_costs.clear(); + for (auto &tok : split_tokens(luts_arg, ",")) { + 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"); + } + } + // ABC expects a box file for XAIG if (box_file.empty()) box_file = "+/dummy.box"; @@ -844,7 +869,7 @@ struct Abc9MapPass : public Pass { } if (!design->selected_whole_module(mod)) - log_error("Can't handle partially selected module %s!\n", log_id(module)); + log_error("Can't handle partially selected module %s!\n", log_id(mod)); abc9_module(design, mod, script_file, exe_file, lut_costs, delay_target, lutin_shared, fast_mode, show_tempdir, -- cgit v1.2.3 From 4f13ab823fcfc52c91013eb45f0c3886ed8bcc40 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 6 Jan 2020 12:29:13 -0800 Subject: Revert "scc command to ignore blackboxes" This reverts commit 32695e5032fcaa932a67f63946ae5e2a1edc8d65. --- passes/cmds/scc.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/passes/cmds/scc.cc b/passes/cmds/scc.cc index dd26f8258..99f4fbae8 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 : design->modules()) - if (!mod->get_blackbox_attribute() && design->selected(mod)) + for (auto &mod_it : design->modules_) + if (design->selected(mod_it.second)) { - SccWorker worker(design, mod, nofeedbackMode, allCellTypes, maxDepth); + SccWorker worker(design, mod_it.second, nofeedbackMode, allCellTypes, maxDepth); if (!setAttr.empty()) { -- cgit v1.2.3 From b70e87137d6409b7b05d5d032617ee5d7048a86d Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 6 Jan 2020 12:36:11 -0800 Subject: scc to use design->selected_modules() which avoids black/white-boxes --- passes/cmds/scc.cc | 51 +++++++++++++++++++++++++-------------------------- 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/passes/cmds/scc.cc b/passes/cmds/scc.cc index 99f4fbae8..ad0554bae 100644 --- a/passes/cmds/scc.cc +++ b/passes/cmds/scc.cc @@ -301,42 +301,41 @@ struct SccPass : public Pass { RTLIL::Selection newSelection(false); int scc_counter = 0; - for (auto &mod_it : design->modules_) - if (design->selected(mod_it.second)) - { - SccWorker worker(design, mod_it.second, nofeedbackMode, allCellTypes, maxDepth); + for (auto mod : design->selected_modules()) + { + SccWorker worker(design, mod, nofeedbackMode, allCellTypes, maxDepth); - if (!setAttr.empty()) + if (!setAttr.empty()) + { + for (const auto &cells : worker.sccList) { - for (const auto &cells : worker.sccList) + for (auto attr : setAttr) { - for (auto attr : setAttr) - { - IdString attr_name(RTLIL::escape_id(attr.first)); - string attr_valstr = attr.second; - string index = stringf("%d", scc_counter); - - for (size_t pos = 0; (pos = attr_valstr.find("{}", pos)) != string::npos; pos += index.size()) - attr_valstr.replace(pos, 2, index); + IdString attr_name(RTLIL::escape_id(attr.first)); + string attr_valstr = attr.second; + string index = stringf("%d", scc_counter); - Const attr_value(attr_valstr); + for (size_t pos = 0; (pos = attr_valstr.find("{}", pos)) != string::npos; pos += index.size()) + attr_valstr.replace(pos, 2, index); - for (auto cell : cells) - cell->attributes[attr_name] = attr_value; - } + Const attr_value(attr_valstr); - scc_counter++; + for (auto cell : cells) + cell->attributes[attr_name] = attr_value; } - } - else - { - scc_counter += GetSize(worker.sccList); - } - if (selectMode) - worker.select(newSelection); + scc_counter++; + } + } + else + { + scc_counter += GetSize(worker.sccList); } + if (selectMode) + worker.select(newSelection); + } + if (expect >= 0) { if (scc_counter == expect) log("Found and expected %d SCCs.\n", scc_counter); -- cgit v1.2.3 From 83616e7866138a91d0b4f60b02e32877c1a34ac1 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 6 Jan 2020 12:43:29 -0800 Subject: read_aiger: add -xaiger option --- frontends/aiger/aigerparse.cc | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc index f030933ec..d6efdaafe 100644 --- a/frontends/aiger/aigerparse.cc +++ b/frontends/aiger/aigerparse.cc @@ -1000,18 +1000,21 @@ struct AigerFrontend : public Frontend { log("Load module from an AIGER file into the current design.\n"); log("\n"); log(" -module_name \n"); - log(" Name of module to be created (default: )\n"); + log(" name of module to be created (default: )\n"); log("\n"); log(" -clk_name \n"); - log(" If specified, AIGER latches to be transformed into $_DFF_P_ cells\n"); - log(" clocked by wire of this name. Otherwise, $_FF_ cells will be used.\n"); + log(" if specified, AIGER latches to be transformed into $_DFF_P_ cells\n"); + log(" clocked by wire of this name. otherwise, $_FF_ cells will be used\n"); log("\n"); log(" -map \n"); log(" read file with port and latch symbols\n"); log("\n"); log(" -wideports\n"); - log(" Merge ports that match the pattern 'name[int]' into a single\n"); - log(" multi-bit port 'name'.\n"); + log(" merge ports that match the pattern 'name[int]' into a single\n"); + log(" multi-bit port 'name'\n"); + log("\n"); + log(" -xaiger\n"); + log(" read XAIGER extensions\n"); log("\n"); } void execute(std::istream *&f, std::string filename, std::vector args, RTLIL::Design *design) YS_OVERRIDE @@ -1021,7 +1024,7 @@ struct AigerFrontend : public Frontend { RTLIL::IdString clk_name = "\\clk"; RTLIL::IdString module_name; std::string map_filename; - bool wideports = false; + bool wideports = false, xaiger = false; size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) { @@ -1042,6 +1045,10 @@ struct AigerFrontend : public Frontend { wideports = true; continue; } + if (arg == "-xaiger") { + xaiger = true; + continue; + } break; } extra_args(f, filename, args, argidx, true); @@ -1061,7 +1068,10 @@ struct AigerFrontend : public Frontend { } AigerReader reader(design, *f, module_name, clk_name, map_filename, wideports); - reader.parse_aiger(); + if (xaiger) + reader.parse_xaiger(); + else + reader.parse_aiger(); } } AigerFrontend; -- cgit v1.2.3 From 2bf442ca011a1495c7c0960e9ea4452fa7e934b5 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 6 Jan 2020 13:02:04 -0800 Subject: Cleanup --- passes/techmap/abc9.cc | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 94eea2983..c7db4f557 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -202,20 +202,17 @@ struct Abc9Pass : public ScriptPass active_design->selection_stack.emplace_back(false); for (auto mod : selected_modules) { - if (mod->get_blackbox_attribute()) - continue; - if (mod->processes.size() > 0) { log("Skipping module %s as it contains processes.\n", log_id(mod)); continue; } log_assert(!mod->attributes.count(ID(abc9_box_id))); + active_design->selection().select(mod); + if (!active_design->selected_whole_module(mod)) log_error("Can't handle partially selected module %s!\n", log_id(mod)); - active_design->selection().select(mod); - std::string tempdir_name = "/tmp/yosys-abc-XXXXXX"; if (!cleanup) tempdir_name[0] = tempdir_name[4] = '_'; -- cgit v1.2.3 From aa58472a292c2cd3c0f2ba669c9dcfd608d8dc5f Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 6 Jan 2020 13:34:45 -0800 Subject: Revert "write_xaiger to pad, not abc9_ops -prep_holes" This reverts commit b5f60e055d07579a2d4f23fc053ca030f103f377. --- backends/aiger/xaiger.cc | 26 ++++++++++---------------- passes/techmap/abc9_map.cc | 13 +++++++++---- passes/techmap/abc9_ops.cc | 39 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 20 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index c01adde3d..a9680525d 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -318,14 +318,13 @@ struct XAigerWriter } } + // Fully pad all unused input connections of this box cell with S0 + // Fully pad all undriven output connections of this box cell with anonymous wires for (auto port_name : r.first->second) { auto w = box_module->wire(port_name); log_assert(w); - - SigSpec rhs = cell->connections_.at(port_name, SigSpec()); - if (w->port_input) { - // Add padding to fill entire port - rhs.append(SigSpec(State::Sx, GetSize(w)-GetSize(rhs))); + auto rhs = cell->getPort(port_name); + if (w->port_input) for (auto b : rhs) { SigBit I = sigmap(b); if (b == RTLIL::Sx) @@ -339,18 +338,14 @@ struct XAigerWriter co_bits.emplace_back(b); unused_bits.erase(I); } - } - if (w->port_output) { - // Add padding to fill entire port - rhs.append(SigSpec(State::Sx, GetSize(w)-GetSize(rhs))); - for (const auto &b : rhs) { + if (w->port_output) + for (const auto &b : rhs.bits()) { SigBit O = sigmap(b); if (O != b) alias_map[O] = b; ci_bits.emplace_back(b); undriven_bits.erase(O); } - } } // Connect .abc9_ff.Q (inserted by abc9_map.v) as the last input to the flop box @@ -417,11 +412,8 @@ struct XAigerWriter for (auto &bit : ci_bits) { aig_m++, aig_i++; - // State::Sx if padding - if (bit != State::Sx) { - log_assert(!aig_map.count(bit)); - aig_map[bit] = 2*aig_m; - } + log_assert(!aig_map.count(bit)); + aig_map[bit] = 2*aig_m; } for (auto bit : co_bits) { @@ -609,6 +601,8 @@ struct XAigerWriter f.write(buffer_str.data(), buffer_str.size()); if (holes_module) { + log_module(holes_module); + std::stringstream a_buffer; XAigerWriter writer(holes_module, true /* holes_mode */); writer.write_aiger(a_buffer, false /*ascii_mode*/); diff --git a/passes/techmap/abc9_map.cc b/passes/techmap/abc9_map.cc index e6e4e3e72..c01feedb6 100644 --- a/passes/techmap/abc9_map.cc +++ b/passes/techmap/abc9_map.cc @@ -438,19 +438,24 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip 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; } + auto abc9_box = cell->attributes.erase("\\abc9_box_seq"); + if (abc9_box) { + module->swap_names(cell, existing_cell); + module->remove(existing_cell); + } 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()) { + // Skip entire box ports composed entirely of padding only + if (abc9_box && conn.second.is_wire() && conn.second.as_wire()->get_bool_attribute(ID(abc9_padding))) + continue; + RTLIL::SigSpec newsig; for (auto c : conn.second.chunks()) { if (c.width == 0) diff --git a/passes/techmap/abc9_ops.cc b/passes/techmap/abc9_ops.cc index 730431ebf..ab5aa9f8d 100644 --- a/passes/techmap/abc9_ops.cc +++ b/passes/techmap/abc9_ops.cc @@ -254,6 +254,45 @@ void prep_holes(RTLIL::Module *module, bool dff) RTLIL::Module* box_module = design->module(cell->type); if (!box_module || !box_module->attributes.count("\\abc9_box_id")) continue; + + bool blackbox = box_module->get_blackbox_attribute(true /* ignore_wb */); + + // Fully pad all unused input connections of this box cell with S0 + // Fully pad all undriven output connections of this box cell with anonymous wires + for (const auto &port_name : box_module->ports) { + RTLIL::Wire* 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->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); + } + } + } + cell->attributes["\\abc9_box_seq"] = box_list.size(); box_list.emplace_back(cell); } -- cgit v1.2.3 From 8d0cc654a4c6cad925d20557cf299e00e27d5726 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 6 Jan 2020 15:14:38 -0800 Subject: Stray log_module --- backends/aiger/xaiger.cc | 2 -- 1 file changed, 2 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index a9680525d..beaed696d 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -601,8 +601,6 @@ struct XAigerWriter f.write(buffer_str.data(), buffer_str.size()); if (holes_module) { - log_module(holes_module); - std::stringstream a_buffer; XAigerWriter writer(holes_module, true /* holes_mode */); writer.write_aiger(a_buffer, false /*ascii_mode*/); -- cgit v1.2.3 From 46ed507b93aa744bf03ea79a2950a2cb66c250da Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 6 Jan 2020 15:14:54 -0800 Subject: abc9_map: drop padding in box connections --- passes/techmap/abc9_map.cc | 67 ++++++++++++++++++++++++---------------------- 1 file changed, 35 insertions(+), 32 deletions(-) diff --git a/passes/techmap/abc9_map.cc b/passes/techmap/abc9_map.cc index c01feedb6..4ed3419f0 100644 --- a/passes/techmap/abc9_map.cc +++ b/passes/techmap/abc9_map.cc @@ -435,29 +435,11 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip cell = module->addCell(remap_name(mapped_cell->name), mapped_cell->type); } - if (existing_cell) { - cell->parameters = existing_cell->parameters; - cell->attributes = existing_cell->attributes; - } - else { - cell->parameters = mapped_cell->parameters; - cell->attributes = mapped_cell->attributes; - } - - auto abc9_box = cell->attributes.erase("\\abc9_box_seq"); - if (abc9_box) { - module->swap_names(cell, existing_cell); - module->remove(existing_cell); - } 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()) { - // Skip entire box ports composed entirely of padding only - if (abc9_box && conn.second.is_wire() && conn.second.as_wire()->get_bool_attribute(ID(abc9_padding))) - continue; - + for (auto &mapped_conn : mapped_cell->connections()) { RTLIL::SigSpec newsig; - for (auto c : conn.second.chunks()) { + for (auto c : mapped_conn.second.chunks()) { if (c.width == 0) continue; //log_assert(c.width == 1); @@ -465,19 +447,40 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip 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); + if (existing_cell) { + auto it = existing_cell->connections_.find(mapped_conn.first); + if (it == existing_cell->connections_.end()) + continue; + log_assert(GetSize(newsig) >= GetSize(it->second)); + newsig = newsig.extract(0, GetSize(it->second)); } + cell->setPort(mapped_conn.first, newsig); + + if (abc9_flop) + continue; + + if (cell->input(mapped_conn.first)) { + for (auto i : newsig) + bit2sinks[i].push_back(cell); + for (auto i : mapped_conn.second) + bit_users[i].insert(mapped_cell->name); + } + if (cell->output(mapped_conn.first)) + for (auto i : mapped_conn.second) + bit_drivers[i].insert(mapped_cell->name); + } + + 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; } } -- cgit v1.2.3 From cf3a13746d27fee141700e2c6ea40d528267190f Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 6 Jan 2020 15:52:59 -0800 Subject: Add abc9_ops -reintegrate; moved out from now abc9_exe --- passes/techmap/Makefile.inc | 2 +- passes/techmap/abc9.cc | 20 +- passes/techmap/abc9_exe.cc | 557 +++++++++++++++++++++++++++ passes/techmap/abc9_map.cc | 889 -------------------------------------------- passes/techmap/abc9_ops.cc | 286 +++++++++++++- 5 files changed, 854 insertions(+), 900 deletions(-) create mode 100644 passes/techmap/abc9_exe.cc delete mode 100644 passes/techmap/abc9_map.cc diff --git a/passes/techmap/Makefile.inc b/passes/techmap/Makefile.inc index 734d6c10f..369c9de64 100644 --- a/passes/techmap/Makefile.inc +++ b/passes/techmap/Makefile.inc @@ -8,7 +8,7 @@ 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_exe.o OBJS += passes/techmap/abc9_ops.o ifneq ($(ABCEXTERNAL),) passes/techmap/abc.o: CXXFLAGS += -DABCEXTERNAL='"$(ABCEXTERNAL)"' diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index c7db4f557..7c261e220 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -129,13 +129,13 @@ struct Abc9Pass : public ScriptPass log("\n"); } - std::stringstream map_cmd; + std::stringstream exe_cmd; bool dff_mode, cleanup; void clear_flags() YS_OVERRIDE { - map_cmd.str(""); - map_cmd << "abc9_map"; + exe_cmd.str(""); + exe_cmd << "abc9_exe"; dff_mode = false; cleanup = true; } @@ -156,13 +156,13 @@ struct Abc9Pass : public ScriptPass /* arg == "-S" || */ arg == "-lut" || arg == "-luts" || arg == "-box" || arg == "-W") && argidx+1 < args.size()) { - map_cmd << " " << arg << " " << args[++argidx]; + exe_cmd << " " << arg << " " << args[++argidx]; continue; } if (arg == "-fast" || /* arg == "-dff" || */ /* arg == "-nocleanup" || */ arg == "-showtmp" || arg == "-nomfs") { - map_cmd << " " << arg; + exe_cmd << " " << arg; continue; } if (arg == "-dff") { @@ -219,9 +219,13 @@ struct Abc9Pass : public ScriptPass tempdir_name = make_temp_dir(tempdir_name); run(stringf("write_xaiger -map %s/input.sym %s/input.xaig", tempdir_name.c_str(), tempdir_name.c_str()), - "write_xaiger -map /input.sym /input.xaig"); - run(stringf("%s -tempdir %s", map_cmd.str().c_str(), tempdir_name.c_str()), - "abc9_map [options] -tempdir "); + "write_xaiger -map /input.sym /input.xaig"); + run(stringf("%s -cwd %s", exe_cmd.str().c_str(), tempdir_name.c_str()), + "abc9_exe [options] -cwd "); + + run(stringf("read_aiger -xaiger -wideports -module_name %s$abc9 -map %s/input.sym %s/output.aig", log_id(mod->name), tempdir_name.c_str(), tempdir_name.c_str()), + "read_aiger -xaiger -wideports -module_name $abc9 -map /input.sym /output.aig"); + run("abc9_ops -reintegrate"); if (cleanup) { diff --git a/passes/techmap/abc9_exe.cc b/passes/techmap/abc9_exe.cc new file mode 100644 index 000000000..36d7faf1b --- /dev/null +++ b/passes/techmap/abc9_exe.cc @@ -0,0 +1,557 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 Clifford Wolf + * 2019 Eddie Hung + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +// [[CITE]] ABC +// Berkeley Logic Synthesis and Verification Group, ABC: A System for Sequential Synthesis and Verification +// http://www.eecs.berkeley.edu/~alanmi/abc/ + +#if 0 +// Based on &flow3 - better QoR but more experimental +#define ABC_COMMAND_LUT "&st; &ps -l; &sweep -v; &scorr; " \ + "&st; &if {W}; &save; &st; &syn2; &if {W} -v; &save; &load; "\ + "&st; &if -g -K 6; &dch -f; &if {W} -v; &save; &load; "\ + "&st; &if -g -K 6; &synch2; &if {W} -v; &save; &load; "\ + "&mfs; &ps -l" +#else +#define ABC_COMMAND_LUT "&st; &scorr; &sweep; &dc2; &st; &dch -f; &ps; &if {W} {D} -v; &mfs; &ps -l" +#endif + + +#define ABC_FAST_COMMAND_LUT "&st; &if {W} {D}" + +#include "kernel/register.h" +#include "kernel/log.h" + +#ifndef _WIN32 +# include +# include +#endif + +#ifdef YOSYS_LINK_ABC +extern "C" int Abc_RealMain(int argc, char *argv[]); +#endif + +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + +std::string add_echos_to_abc9_cmd(std::string str) +{ + std::string new_str, token; + for (size_t i = 0; i < str.size(); i++) { + token += str[i]; + if (str[i] == ';') { + while (i+1 < str.size() && str[i+1] == ' ') + i++; + new_str += "echo + " + token + " " + token + " "; + token.clear(); + } + } + + if (!token.empty()) { + if (!new_str.empty()) + new_str += "echo + " + token + "; "; + new_str += token; + } + + return new_str; +} + +std::string fold_abc9_cmd(std::string str) +{ + std::string token, new_str = " "; + int char_counter = 10; + + for (size_t i = 0; i <= str.size(); i++) { + if (i < str.size()) + token += str[i]; + if (i == str.size() || str[i] == ';') { + if (char_counter + token.size() > 75) + new_str += "\n ", char_counter = 14; + new_str += token, char_counter += token.size(); + token.clear(); + } + } + + return new_str; +} + +std::string replace_tempdir(std::string text, std::string tempdir_name, bool show_tempdir) +{ + if (show_tempdir) + return text; + + while (1) { + size_t pos = text.find(tempdir_name); + if (pos == std::string::npos) + break; + text = text.substr(0, pos) + "" + text.substr(pos + GetSize(tempdir_name)); + } + + std::string selfdir_name = proc_self_dirname(); + if (selfdir_name != "/") { + while (1) { + size_t pos = text.find(selfdir_name); + if (pos == std::string::npos) + break; + text = text.substr(0, pos) + "/" + text.substr(pos + GetSize(selfdir_name)); + } + } + + return text; +} + +struct abc9_output_filter +{ + bool got_cr; + int escape_seq_state; + std::string linebuf; + std::string tempdir_name; + bool show_tempdir; + + abc9_output_filter(std::string tempdir_name, bool show_tempdir) : tempdir_name(tempdir_name), show_tempdir(show_tempdir) + { + got_cr = false; + escape_seq_state = 0; + } + + void next_char(char ch) + { + if (escape_seq_state == 0 && ch == '\033') { + escape_seq_state = 1; + return; + } + if (escape_seq_state == 1) { + escape_seq_state = ch == '[' ? 2 : 0; + return; + } + if (escape_seq_state == 2) { + if ((ch < '0' || '9' < ch) && ch != ';') + escape_seq_state = 0; + return; + } + escape_seq_state = 0; + if (ch == '\r') { + got_cr = true; + return; + } + if (ch == '\n') { + log("ABC: %s\n", replace_tempdir(linebuf, tempdir_name, show_tempdir).c_str()); + got_cr = false, linebuf.clear(); + return; + } + if (got_cr) + got_cr = false, linebuf.clear(); + linebuf += ch; + } + + void next_line(const std::string &line) + { + //int pi, po; + //if (sscanf(line.c_str(), "Start-point = pi%d. End-point = po%d.", &pi, &po) == 2) { + // log("ABC: Start-point = pi%d (%s). End-point = po%d (%s).\n", + // pi, pi_map.count(pi) ? pi_map.at(pi).c_str() : "???", + // po, po_map.count(po) ? po_map.at(po).c_str() : "???"); + // return; + //} + + for (char ch : line) + next_char(ch); + } +}; + +void abc9_module(RTLIL::Design *design, std::string script_file, std::string exe_file, + vector 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 +) +{ + //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; + + 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); + } + else + { + log("Don't call ABC as there is nothing to map.\n"); + } +} + +struct Abc9ExePass : public Pass { + Abc9ExePass() : Pass("abc9_exe", "use ABC9 for technology mapping") { } + void help() YS_OVERRIDE + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" abc9_exe [options] [selection]\n"); + log("\n"); + log("This pass uses the ABC tool [1] for technology mapping of yosys's internal gate\n"); + log("library to a target architecture.\n"); + log("\n"); + log(" -exe \n"); +#ifdef ABCEXTERNAL + log(" use the specified command instead of \"" ABCEXTERNAL "\" to execute ABC.\n"); +#else + log(" use the specified command instead of \"/yosys-abc\" to execute ABC.\n"); +#endif + log(" This can e.g. be used to call a specific version of ABC or a wrapper.\n"); + log("\n"); + log(" -script \n"); + log(" use the specified ABC script file instead of the default script.\n"); + log("\n"); + log(" if starts with a plus sign (+), then the rest of the filename\n"); + log(" string is interpreted as the command string to be passed to ABC. The\n"); + log(" leading plus sign is removed and all commas (,) in the string are\n"); + log(" replaced with blanks before the string is passed to ABC.\n"); + log("\n"); + log(" if no -script parameter is given, the following scripts are used:\n"); + log("\n"); + log(" for -lut/-luts (only one LUT size):\n"); + log("%s\n", fold_abc9_cmd(ABC_COMMAND_LUT /*"; lutpack {S}"*/).c_str()); + log("\n"); + log(" for -lut/-luts (different LUT sizes):\n"); + log("%s\n", fold_abc9_cmd(ABC_COMMAND_LUT).c_str()); + log("\n"); + log(" -fast\n"); + log(" use different default scripts that are slightly faster (at the cost\n"); + log(" of output quality):\n"); + log("\n"); + log(" for -lut/-luts:\n"); + log("%s\n", fold_abc9_cmd(ABC_FAST_COMMAND_LUT).c_str()); + log("\n"); + log(" -D \n"); + log(" set delay target. the string {D} in the default scripts above is\n"); + log(" replaced by this option when used, and an empty string otherwise\n"); + log(" (indicating best possible delay).\n"); + log("\n"); +// log(" -S \n"); +// log(" maximum number of LUT inputs shared.\n"); +// log(" (replaces {S} in the default scripts above, default: -S 1)\n"); +// log("\n"); + log(" -lut \n"); + log(" generate netlist using luts of (max) the specified width.\n"); + log("\n"); + log(" -lut :\n"); + log(" generate netlist using luts of (max) the specified width . All\n"); + log(" luts with width <= have constant cost. for luts larger than \n"); + log(" the area cost doubles with each additional input bit. the delay cost\n"); + log(" is still constant for all lut widths.\n"); + log("\n"); + log(" -lut \n"); + log(" pass this file with lut library to ABC.\n"); + log("\n"); + log(" -luts ,,,:,..\n"); + log(" generate netlist using luts. Use the specified costs for luts with 1,\n"); + log(" 2, 3, .. inputs.\n"); + log("\n"); + log(" -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(" -box \n"); + log(" pass this file with box library to ABC. Use with -lut.\n"); + log("\n"); + log(" -cwd \n"); + log(" use this as the current working directory, inside which the 'input.xaig'\n"); + log(" file is expected. temporary files will be created in this directory, and\n"); + log(" the mapped result will be written to 'output.aig'.\n"); + log("\n"); + log("Note that this is a logic optimization pass within Yosys that is calling ABC\n"); + log("internally. This is not going to \"run ABC on your design\". It will instead run\n"); + log("ABC on logic snippets extracted from your design. You will not get any useful\n"); + log("output when passing an ABC script that writes a file. Instead write your full\n"); + log("design as BLIF file with write_blif and then load that into ABC externally if\n"); + log("you want to use ABC to convert your design into another format.\n"); + log("\n"); + log("[1] http://www.eecs.berkeley.edu/~alanmi/abc/\n"); + log("\n"); + } + void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE + { + log_header(design, "Executing ABC9_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 lut_costs; + +#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 + + std::string lut_arg, luts_arg; + exe_file = design->scratchpad_get_string("abc9.exe", exe_file /* inherit default value if not set */); + script_file = design->scratchpad_get_string("abc9.script", script_file); + if (design->scratchpad.count("abc9.D")) { + delay_target = "-D " + design->scratchpad_get_string("abc9.D"); + } + lut_arg = design->scratchpad_get_string("abc9.lut", lut_arg); + luts_arg = design->scratchpad_get_string("abc9.luts", luts_arg); + fast_mode = design->scratchpad_get_bool("abc9.fast", fast_mode); + show_tempdir = design->scratchpad_get_bool("abc9.showtmp", show_tempdir); + box_file = design->scratchpad_get_string("abc9.box", box_file); + if (design->scratchpad.count("abc9.W")) { + wire_delay = "-W " + design->scratchpad_get_string("abc9.W"); + } + nomfs = design->scratchpad_get_bool("abc9.nomfs", nomfs); + + size_t argidx; + 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]; + 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()) { + lut_arg = args[++argidx]; + continue; + } + if (arg == "-luts" && argidx+1 < args.size()) { + lut_arg = args[++argidx]; + continue; + } + if (arg == "-fast") { + fast_mode = true; + continue; + } + if (arg == "-showtmp") { + show_tempdir = 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 == "-cwd" && argidx+1 < args.size()) { + tempdir_name = args[++argidx]; + continue; + } + break; + } + extra_args(args, argidx, design); + + rewrite_filename(script_file); + if (!script_file.empty() && !is_absolute_path(script_file) && script_file[0] != '+') + script_file = std::string(pwd) + "/" + script_file; + + // handle -lut / -luts args + if (!lut_arg.empty()) { + string arg = lut_arg; + 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 (!luts_arg.empty()) { + lut_costs.clear(); + for (auto &tok : split_tokens(luts_arg, ",")) { + 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"); + } + } + + // 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_exe '-cwd' option is mandatory.\n"); + + + abc9_module(design, script_file, exe_file, lut_costs, + delay_target, lutin_shared, fast_mode, show_tempdir, + box_file, lut_file, wire_delay, nomfs, tempdir_name); + } +} Abc9ExePass; + +PRIVATE_NAMESPACE_END diff --git a/passes/techmap/abc9_map.cc b/passes/techmap/abc9_map.cc deleted file mode 100644 index 4ed3419f0..000000000 --- a/passes/techmap/abc9_map.cc +++ /dev/null @@ -1,889 +0,0 @@ -/* - * yosys -- Yosys Open SYnthesis Suite - * - * Copyright (C) 2012 Clifford Wolf - * 2019 Eddie Hung - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - */ - -// [[CITE]] ABC -// Berkeley Logic Synthesis and Verification Group, ABC: A System for Sequential Synthesis and Verification -// http://www.eecs.berkeley.edu/~alanmi/abc/ - -#if 0 -// Based on &flow3 - better QoR but more experimental -#define ABC_COMMAND_LUT "&st; &ps -l; &sweep -v; &scorr; " \ - "&st; &if {W}; &save; &st; &syn2; &if {W} -v; &save; &load; "\ - "&st; &if -g -K 6; &dch -f; &if {W} -v; &save; &load; "\ - "&st; &if -g -K 6; &synch2; &if {W} -v; &save; &load; "\ - "&mfs; &ps -l" -#else -#define ABC_COMMAND_LUT "&st; &scorr; &sweep; &dc2; &st; &dch -f; &ps; &if {W} {D} -v; &mfs; &ps -l" -#endif - - -#define ABC_FAST_COMMAND_LUT "&st; &if {W} {D}" - -#include "kernel/register.h" -#include "kernel/sigtools.h" -#include "kernel/celltypes.h" -#include "kernel/cost.h" -#include "kernel/log.h" -#include -#include -#include -#include -#include -#include - -#ifndef _WIN32 -# include -# include -#endif - -#include "frontends/aiger/aigerparse.h" -#include "kernel/utils.h" - -#ifdef YOSYS_LINK_ABC -extern "C" int Abc_RealMain(int argc, char *argv[]); -#endif - -USING_YOSYS_NAMESPACE -PRIVATE_NAMESPACE_BEGIN - -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) + "" + text.substr(pos + GetSize(tempdir_name)); - } - - std::string selfdir_name = proc_self_dirname(); - if (selfdir_name != "/") { - while (1) { - size_t pos = text.find(selfdir_name); - if (pos == std::string::npos) - break; - text = text.substr(0, pos) + "/" + text.substr(pos + GetSize(selfdir_name)); - } - } - - return text; -} - -struct abc9_output_filter -{ - bool got_cr; - int escape_seq_state; - std::string linebuf; - std::string tempdir_name; - bool show_tempdir; - - abc9_output_filter(std::string tempdir_name, bool show_tempdir) : tempdir_name(tempdir_name), show_tempdir(show_tempdir) - { - got_cr = false; - escape_seq_state = 0; - } - - void next_char(char ch) - { - if (escape_seq_state == 0 && ch == '\033') { - escape_seq_state = 1; - return; - } - if (escape_seq_state == 1) { - escape_seq_state = ch == '[' ? 2 : 0; - return; - } - if (escape_seq_state == 2) { - if ((ch < '0' || '9' < ch) && ch != ';') - escape_seq_state = 0; - return; - } - escape_seq_state = 0; - if (ch == '\r') { - got_cr = true; - return; - } - if (ch == '\n') { - log("ABC: %s\n", replace_tempdir(linebuf, tempdir_name, show_tempdir).c_str()); - got_cr = false, linebuf.clear(); - return; - } - if (got_cr) - got_cr = false, linebuf.clear(); - linebuf += ch; - } - - void next_line(const std::string &line) - { - //int pi, po; - //if (sscanf(line.c_str(), "Start-point = pi%d. End-point = po%d.", &pi, &po) == 2) { - // log("ABC: Start-point = pi%d (%s). End-point = po%d (%s).\n", - // pi, pi_map.count(pi) ? pi_map.at(pi).c_str() : "???", - // po, po_map.count(po) ? po_map.at(po).c_str() : "???"); - // return; - //} - - for (char ch : line) - next_char(ch); - } -}; - -void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string script_file, std::string exe_file, - vector 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 w : mapped_mod->wires()) - module->addWire(remap_name(w->name), GetSize(w)); - - 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> bit_drivers, bit_users; - TopoSort toposort; - dict not2drivers; - dict> bit2sinks; - - std::map 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(); - 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); - 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); - } - - RTLIL::Module* box_module = design->module(mapped_cell->type); - auto abc9_flop = box_module && box_module->attributes.count("\\abc9_flop"); - for (auto &mapped_conn : mapped_cell->connections()) { - RTLIL::SigSpec newsig; - for (auto c : mapped_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); - } - if (existing_cell) { - auto it = existing_cell->connections_.find(mapped_conn.first); - if (it == existing_cell->connections_.end()) - continue; - log_assert(GetSize(newsig) >= GetSize(it->second)); - newsig = newsig.extract(0, GetSize(it->second)); - } - cell->setPort(mapped_conn.first, newsig); - - if (abc9_flop) - continue; - - if (cell->input(mapped_conn.first)) { - for (auto i : newsig) - bit2sinks[i].push_back(cell); - for (auto i : mapped_conn.second) - bit_users[i].insert(mapped_cell->name); - } - if (cell->output(mapped_conn.first)) - for (auto i : mapped_conn.second) - bit_drivers[i].insert(mapped_cell->name); - } - - 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; - } - } - - // 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 \n"); -#ifdef ABCEXTERNAL - log(" use the specified command instead of \"" ABCEXTERNAL "\" to execute ABC.\n"); -#else - log(" use the specified command instead of \"/yosys-abc\" to execute ABC.\n"); -#endif - log(" This can e.g. be used to call a specific version of ABC or a wrapper.\n"); - log("\n"); - log(" -script \n"); - log(" use the specified ABC script file instead of the default script.\n"); - log("\n"); - log(" if starts with a plus sign (+), then the rest of the filename\n"); - log(" string is interpreted as the command string to be passed to ABC. The\n"); - log(" leading plus sign is removed and all commas (,) in the string are\n"); - log(" replaced with blanks before the string is passed to ABC.\n"); - log("\n"); - log(" if no -script parameter is given, the following scripts are used:\n"); - log("\n"); - log(" for -lut/-luts (only one LUT size):\n"); - log("%s\n", fold_abc9_cmd(ABC_COMMAND_LUT /*"; lutpack {S}"*/).c_str()); - log("\n"); - log(" for -lut/-luts (different LUT sizes):\n"); - log("%s\n", fold_abc9_cmd(ABC_COMMAND_LUT).c_str()); - log("\n"); - log(" -fast\n"); - log(" use different default scripts that are slightly faster (at the cost\n"); - log(" of output quality):\n"); - log("\n"); - log(" for -lut/-luts:\n"); - log("%s\n", fold_abc9_cmd(ABC_FAST_COMMAND_LUT).c_str()); - log("\n"); - log(" -D \n"); - log(" set delay target. the string {D} in the default scripts above is\n"); - log(" replaced by this option when used, and an empty string otherwise\n"); - log(" (indicating best possible delay).\n"); - log("\n"); -// log(" -S \n"); -// log(" maximum number of LUT inputs shared.\n"); -// log(" (replaces {S} in the default scripts above, default: -S 1)\n"); -// log("\n"); - log(" -lut \n"); - log(" generate netlist using luts of (max) the specified width.\n"); - log("\n"); - log(" -lut :\n"); - log(" generate netlist using luts of (max) the specified width . All\n"); - log(" luts with width <= have constant cost. for luts larger than \n"); - log(" the area cost doubles with each additional input bit. the delay cost\n"); - log(" is still constant for all lut widths.\n"); - log("\n"); - log(" -lut \n"); - log(" pass this file with lut library to ABC.\n"); - log("\n"); - log(" -luts ,,,:,..\n"); - log(" generate netlist using luts. Use the specified costs for luts with 1,\n"); - log(" 2, 3, .. inputs.\n"); - log("\n"); - log(" -dff\n"); - log(" also pass $_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(" -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(" -box \n"); - log(" pass this file with box library to ABC. Use with -lut.\n"); - log("\n"); - log(" -tempdir \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 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 lut_costs; - -#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 - - std::string lut_arg, luts_arg; - exe_file = design->scratchpad_get_string("abc9.exe", exe_file /* inherit default value if not set */); - script_file = design->scratchpad_get_string("abc9.script", script_file); - if (design->scratchpad.count("abc9.D")) { - delay_target = "-D " + design->scratchpad_get_string("abc9.D"); - } - lut_arg = design->scratchpad_get_string("abc9.lut", lut_arg); - luts_arg = design->scratchpad_get_string("abc9.luts", luts_arg); - fast_mode = design->scratchpad_get_bool("abc9.fast", fast_mode); - show_tempdir = design->scratchpad_get_bool("abc9.showtmp", show_tempdir); - box_file = design->scratchpad_get_string("abc9.box", box_file); - if (design->scratchpad.count("abc9.W")) { - wire_delay = "-W " + design->scratchpad_get_string("abc9.W"); - } - nomfs = design->scratchpad_get_bool("abc9.nomfs", nomfs); - - size_t argidx; - 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]; - 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()) { - lut_arg = args[++argidx]; - continue; - } - if (arg == "-luts" && argidx+1 < args.size()) { - lut_arg = args[++argidx]; - continue; - } - if (arg == "-fast") { - fast_mode = true; - continue; - } - if (arg == "-showtmp") { - show_tempdir = 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); - - rewrite_filename(script_file); - if (!script_file.empty() && !is_absolute_path(script_file) && script_file[0] != '+') - script_file = std::string(pwd) + "/" + script_file; - - // handle -lut / -luts args - if (!lut_arg.empty()) { - string arg = lut_arg; - 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 (!luts_arg.empty()) { - lut_costs.clear(); - for (auto &tok : split_tokens(luts_arg, ",")) { - 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"); - } - } - - // 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; - } - - if (!design->selected_whole_module(mod)) - log_error("Can't handle partially selected module %s!\n", log_id(mod)); - - 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 index ab5aa9f8d..c8d91a6ac 100644 --- a/passes/techmap/abc9_ops.cc +++ b/passes/techmap/abc9_ops.cc @@ -26,6 +26,13 @@ USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN +int map_autoidx; + +inline std::string remap_name(RTLIL::IdString abc9_name) +{ + return stringf("$abc$%d$%s", map_autoidx, abc9_name.c_str()+1); +} + void break_scc(RTLIL::Module *module) { // For every unique SCC found, (arbitrarily) find the first @@ -416,6 +423,276 @@ void prep_holes(RTLIL::Module *module, bool dff) } } +void reintegrate(RTLIL::Module *module) +{ + auto design = module->design; + log_assert(design); + + map_autoidx = autoidx++; + + RTLIL::Module *mapped_mod = design->module(stringf("%s$abc9", module->name.c_str())); + if (mapped_mod == NULL) + log_error("ABC output file does not contain a module `%s$abc'.\n", log_id(module)); + + for (auto w : mapped_mod->wires()) + module->addWire(remap_name(w->name), GetSize(w)); + + 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> bit_drivers, bit_users; + TopoSort toposort; + dict not2drivers; + dict> bit2sinks; + + std::map 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 { + 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; + } + 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); + 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); + } + + RTLIL::Module* box_module = design->module(mapped_cell->type); + auto abc9_flop = box_module && box_module->attributes.count("\\abc9_flop"); + for (auto &mapped_conn : mapped_cell->connections()) { + RTLIL::SigSpec newsig; + for (auto c : mapped_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); + } + if (existing_cell) { + auto it = existing_cell->connections_.find(mapped_conn.first); + if (it == existing_cell->connections_.end()) + continue; + log_assert(GetSize(newsig) >= GetSize(it->second)); + newsig = newsig.extract(0, GetSize(it->second)); + } + cell->setPort(mapped_conn.first, newsig); + + if (abc9_flop) + continue; + + if (cell->input(mapped_conn.first)) { + for (auto i : newsig) + bit2sinks[i].push_back(cell); + for (auto i : mapped_conn.second) + bit_users[i].insert(mapped_cell->name); + } + if (cell->output(mapped_conn.first)) + for (auto i : mapped_conn.second) + bit_drivers[i].insert(mapped_cell->name); + } + + 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; + } + } + + // 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); +} + struct Abc9OpsPass : public Pass { Abc9OpsPass() : Pass("abc9_ops", "helper functions for ABC9") { } void help() YS_OVERRIDE @@ -433,6 +710,7 @@ struct Abc9OpsPass : public Pass { bool unbreak_scc_mode = false; bool prep_dff_mode = false; bool prep_holes_mode = false; + bool reintegrate_mode = false; bool dff_mode = false; size_t argidx; @@ -454,6 +732,10 @@ struct Abc9OpsPass : public Pass { prep_holes_mode = true; continue; } + if (arg == "-reintegrate") { + reintegrate_mode = true; + continue; + } if (arg == "-dff") { dff_mode = true; continue; @@ -463,8 +745,6 @@ struct Abc9OpsPass : public Pass { 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; @@ -481,6 +761,8 @@ struct Abc9OpsPass : public Pass { prep_dff(mod); if (prep_holes_mode) prep_holes(mod, dff_mode); + if (reintegrate_mode) + reintegrate(mod); } } } Abc9OpsPass; -- cgit v1.2.3 From 3753760971fc9cec9c09d7000e03afd3bcafe6e3 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 6 Jan 2020 16:20:58 -0800 Subject: Bump ABCREV --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index d7319796b..6a8051b65 100644 --- a/Makefile +++ b/Makefile @@ -128,7 +128,7 @@ bumpversion: # is just a symlink to your actual ABC working directory, as 'make mrproper' # will remove the 'abc' directory and you do not want to accidentally # delete your work on ABC.. -ABCREV = f6dc4a5 +ABCREV = 1485e63 ABCPULL = 1 ABCURL ?= https://github.com/berkeley-abc/abc ABCMKARGS = CC="$(CXX)" CXX="$(CXX)" ABC_USE_LIBSTDCXX=1 -- cgit v1.2.3 From 53aa51dc923467bf7aed46e646640e7cee7b009d Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 6 Jan 2020 16:21:04 -0800 Subject: Re-enable &mfs for synth_{ecp5,xilinx} --- techlibs/ecp5/synth_ecp5.cc | 4 ++-- techlibs/xilinx/synth_xilinx.cc | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/techlibs/ecp5/synth_ecp5.cc b/techlibs/ecp5/synth_ecp5.cc index d616391b2..6583f43fd 100644 --- a/techlibs/ecp5/synth_ecp5.cc +++ b/techlibs/ecp5/synth_ecp5.cc @@ -323,9 +323,9 @@ struct SynthEcp5Pass : public ScriptPass if (abc9) { run("read_verilog -icells -lib +/ecp5/abc9_model.v"); if (nowidelut) - run("abc9 -lut +/ecp5/abc9_5g_nowide.lut -box +/ecp5/abc9_5g.box -W 200 -nomfs"); + run("abc9 -lut +/ecp5/abc9_5g_nowide.lut -box +/ecp5/abc9_5g.box -W 200"); else - run("abc9 -lut +/ecp5/abc9_5g.lut -box +/ecp5/abc9_5g.box -W 200 -nomfs"); + run("abc9 -lut +/ecp5/abc9_5g.lut -box +/ecp5/abc9_5g.box -W 200"); run("techmap -map +/ecp5/abc9_unmap.v"); } else { if (nowidelut) diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index b0c4795ee..e1748562e 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -541,7 +541,6 @@ struct SynthXilinxPass : public ScriptPass 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); - abc9_opts += " -nomfs"; if (nowidelut) abc9_opts += " -lut +/xilinx/abc9_xc7_nowide.lut"; else -- cgit v1.2.3 From 3df869cc7cb6bd0afc2850bdcd5ce0409a36d53c Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 6 Jan 2020 16:22:22 -0800 Subject: Add testcase from #1459 --- tests/arch/ecp5/bug1459.ys | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 tests/arch/ecp5/bug1459.ys diff --git a/tests/arch/ecp5/bug1459.ys b/tests/arch/ecp5/bug1459.ys new file mode 100644 index 000000000..1142ae0b5 --- /dev/null +++ b/tests/arch/ecp5/bug1459.ys @@ -0,0 +1,25 @@ +read_verilog < Date: Mon, 6 Jan 2020 16:45:29 -0800 Subject: Fix DSP48E1 sim --- techlibs/xilinx/cells_sim.v | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/techlibs/xilinx/cells_sim.v b/techlibs/xilinx/cells_sim.v index 1cd4d2f30..70ab1f293 100644 --- a/techlibs/xilinx/cells_sim.v +++ b/techlibs/xilinx/cells_sim.v @@ -2388,8 +2388,8 @@ module DSP48E1 ( if (CEB2) Br2 <= Br1; end end else if (BREG == 1) begin - //initial Br1 = 25'b0; - initial Br2 = 25'b0; + //initial Br1 = 18'b0; + initial Br2 = 18'b0; always @(posedge CLK) if (RSTB) begin Br1 <= 18'b0; @@ -2436,7 +2436,7 @@ module DSP48E1 ( endgenerate // A/D input selection and pre-adder - wire signed [29:0] Ar12_muxed = INMODEr[0] ? Ar1 : Ar2; + wire signed [24:0] Ar12_muxed = INMODEr[0] ? Ar1 : Ar2; wire signed [24:0] Ar12_gated = INMODEr[1] ? 25'b0 : Ar12_muxed; wire signed [24:0] Dr_gated = INMODEr[2] ? Dr : 25'b0; wire signed [24:0] AD_result = INMODEr[3] ? (Dr_gated - Ar12_gated) : (Dr_gated + Ar12_gated); -- cgit v1.2.3 From 5d9050a9551628f838ee419404cf1b1d3920a3ed Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 7 Jan 2020 08:00:32 -0800 Subject: abc_exe: move 'count_outputs' check to abc --- passes/techmap/abc9.cc | 27 ++++++++++------ passes/techmap/abc9_exe.cc | 77 +++++++++++++++++++--------------------------- 2 files changed, 50 insertions(+), 54 deletions(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 7c261e220..0a5454d99 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -219,16 +219,25 @@ struct Abc9Pass : public ScriptPass tempdir_name = make_temp_dir(tempdir_name); run(stringf("write_xaiger -map %s/input.sym %s/input.xaig", tempdir_name.c_str(), tempdir_name.c_str()), - "write_xaiger -map /input.sym /input.xaig"); - run(stringf("%s -cwd %s", exe_cmd.str().c_str(), tempdir_name.c_str()), - "abc9_exe [options] -cwd "); - - run(stringf("read_aiger -xaiger -wideports -module_name %s$abc9 -map %s/input.sym %s/output.aig", log_id(mod->name), tempdir_name.c_str(), tempdir_name.c_str()), - "read_aiger -xaiger -wideports -module_name $abc9 -map /input.sym /output.aig"); - run("abc9_ops -reintegrate"); + "write_xaiger -map /input.sym /input.xaig"); + + int num_outputs = active_design->scratchpad_get_int("write_xaiger.num_outputs"); + log("Extracted %d AND gates and %d wires to a netlist network with %d inputs and %d outputs.\n", + active_design->scratchpad_get_int("write_xaiger.num_ands"), + active_design->scratchpad_get_int("write_xaiger.num_wires"), + active_design->scratchpad_get_int("write_xaiger.num_inputs"), + num_outputs); + if (num_outputs) { + run(stringf("%s -cwd %s", exe_cmd.str().c_str(), tempdir_name.c_str()), + "abc9_exe [options] -cwd "); + run(stringf("read_aiger -xaiger -wideports -module_name %s$abc9 -map %s/input.sym %s/output.aig", log_id(mod->name), tempdir_name.c_str(), tempdir_name.c_str()), + "read_aiger -xaiger -wideports -module_name $abc9 -map /input.sym /output.aig"); + run("abc9_ops -reintegrate"); + } + else + log("Don't call ABC as there is nothing to map.\n"); - if (cleanup) - { + if (cleanup) { log("Removing temp directory.\n"); remove_directory(tempdir_name); } diff --git a/passes/techmap/abc9_exe.cc b/passes/techmap/abc9_exe.cc index 36d7faf1b..f7dafda96 100644 --- a/passes/techmap/abc9_exe.cc +++ b/passes/techmap/abc9_exe.cc @@ -244,56 +244,43 @@ void abc9_module(RTLIL::Design *design, std::string script_file, std::string exe 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; - - 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); - } + std::string buffer; + + 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()); + 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)); + 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]); + // 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); - } - else - { - log("Don't call ABC as there is nothing to map.\n"); - } + if (ret != 0) + log_error("ABC: execution of command \"%s\" failed: return code %d.\n", buffer.c_str(), ret); } struct Abc9ExePass : public Pass { -- cgit v1.2.3 From b57f692a9e5b2fe9b9f63f329f29d933347a2c40 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 7 Jan 2020 09:32:34 -0800 Subject: read_aiger: consistency between ascii and binary --- frontends/aiger/aigerparse.cc | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc index d6efdaafe..f937ae1f0 100644 --- a/frontends/aiger/aigerparse.cc +++ b/frontends/aiger/aigerparse.cc @@ -496,13 +496,14 @@ void AigerReader::parse_aiger_ascii() unsigned l1, l2, l3; // Parse inputs + int digits = ceil(log10(I)); for (unsigned i = 1; i <= I; ++i, ++line_count) { if (!(f >> l1)) log_error("Line %u cannot be interpreted as an input!\n", line_count); log_debug2("%d is an input\n", l1); - log_assert(!(l1 & 1)); // Inputs can't be inverted - RTLIL::Wire *wire = createWireIfNotExists(module, l1); + RTLIL::Wire *wire = module->addWire(stringf("$i%0*d", digits, l1)); wire->port_input = true; + module->connect(createWireIfNotExists(module, l1 << 1), wire); inputs.push_back(wire); } @@ -552,25 +553,18 @@ void AigerReader::parse_aiger_ascii() } // 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 // Parse bad properties for (unsigned i = 0; i < B; ++i, ++line_count) { -- cgit v1.2.3 From 6e12ba218be1beaa6da712ebf96ff08593793967 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 7 Jan 2020 09:32:58 -0800 Subject: Fix tabs and cleanup --- passes/techmap/abc9_ops.cc | 76 +++++++++++++++++++++++----------------------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/passes/techmap/abc9_ops.cc b/passes/techmap/abc9_ops.cc index c8d91a6ac..69239c93d 100644 --- a/passes/techmap/abc9_ops.cc +++ b/passes/techmap/abc9_ops.cc @@ -521,49 +521,49 @@ void reintegrate(RTLIL::Module *module) RTLIL::Module* box_module = design->module(mapped_cell->type); auto abc9_flop = box_module && box_module->attributes.count("\\abc9_flop"); for (auto &mapped_conn : mapped_cell->connections()) { - RTLIL::SigSpec newsig; - for (auto c : mapped_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); - } - if (existing_cell) { - auto it = existing_cell->connections_.find(mapped_conn.first); - if (it == existing_cell->connections_.end()) - continue; - log_assert(GetSize(newsig) >= GetSize(it->second)); - newsig = newsig.extract(0, GetSize(it->second)); - } - cell->setPort(mapped_conn.first, newsig); - - if (abc9_flop) - continue; + RTLIL::SigSpec newsig; + for (auto c : mapped_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); + } + if (existing_cell) { + auto it = existing_cell->connections_.find(mapped_conn.first); + if (it == existing_cell->connections_.end()) + continue; + log_assert(GetSize(newsig) >= GetSize(it->second)); + newsig = newsig.extract(0, GetSize(it->second)); + } + cell->setPort(mapped_conn.first, newsig); - if (cell->input(mapped_conn.first)) { - for (auto i : newsig) - bit2sinks[i].push_back(cell); - for (auto i : mapped_conn.second) - bit_users[i].insert(mapped_cell->name); - } - if (cell->output(mapped_conn.first)) - for (auto i : mapped_conn.second) - bit_drivers[i].insert(mapped_cell->name); + if (abc9_flop) + continue; + + if (cell->input(mapped_conn.first)) { + for (auto i : newsig) + bit2sinks[i].push_back(cell); + for (auto i : mapped_conn.second) + bit_users[i].insert(mapped_cell->name); + } + if (cell->output(mapped_conn.first)) + for (auto i : mapped_conn.second) + bit_drivers[i].insert(mapped_cell->name); } 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); - } + 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; + cell->parameters = mapped_cell->parameters; + cell->attributes = mapped_cell->attributes; } } @@ -595,7 +595,7 @@ void reintegrate(RTLIL::Module *module) 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)); + RTLIL::SigSpec signal(wire, 0, GetSize(remap_wire)); log_assert(GetSize(signal) >= GetSize(remap_wire)); RTLIL::SigSig conn; -- cgit v1.2.3 From 61a2a60595f60acd4d46344e4c974153bbdfe8e3 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 7 Jan 2020 09:48:11 -0800 Subject: read_aiger: do not process box connections, work standalone --- frontends/aiger/aigerparse.cc | 161 ++++++++++++------------------------------ 1 file changed, 46 insertions(+), 115 deletions(-) diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc index f937ae1f0..355429646 100644 --- a/frontends/aiger/aigerparse.cc +++ b/frontends/aiger/aigerparse.cc @@ -382,21 +382,6 @@ void AigerReader::parse_xaiger() if (f.peek() == '\n') f.get(); - dict box_lookup; - for (auto m : design->modules()) { - auto it = m->attributes.find(ID(abc9_box_id)); - if (it == m->attributes.end()) - continue; - if (m->name.begins_with("$paramod")) - continue; - auto id = it->second.as_int(); - auto r = box_lookup.insert(std::make_pair(id, m->name)); - if (!r.second) - log_error("Module '%s' has the same abc9_box_id = %d value as '%s'.\n", - log_id(m), id, log_id(r.first->second)); - log_assert(r.second); - } - // Parse footer (symbol table, comments, etc.) std::string s; for (int c = f.get(); c != EOF; c = f.get()) { @@ -467,11 +452,14 @@ void AigerReader::parse_xaiger() 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 boxInputs = parse_xaiger_literal(f); + uint32_t boxOutputs = parse_xaiger_literal(f); 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)); + RTLIL::Cell* cell = module->addCell(stringf("$box%u", oldBoxNum), stringf("$__boxid%u", boxUniqueId)); + cell->setPort("\\i", SigSpec(State::S0, boxInputs)); + cell->setPort("\\o", SigSpec(State::S0, boxOutputs)); boxes.emplace_back(cell); } } @@ -501,7 +489,8 @@ void AigerReader::parse_aiger_ascii() if (!(f >> l1)) log_error("Line %u cannot be interpreted as an input!\n", line_count); log_debug2("%d is an input\n", l1); - RTLIL::Wire *wire = module->addWire(stringf("$i%0*d", digits, l1)); + log_assert(!(l1 & 1)); // Inputs can't be inverted + RTLIL::Wire *wire = module->addWire(stringf("$i%0*d", digits, i)); wire->port_input = true; module->connect(createWireIfNotExists(module, l1 << 1), wire); inputs.push_back(wire); @@ -576,6 +565,8 @@ void AigerReader::parse_aiger_ascii() wire->port_output = true; bad_properties.push_back(wire); } + if (B > 0) + std::getline(f, line); // Ignore up to start of next line // TODO: Parse invariant constraints for (unsigned i = 0; i < C; ++i, ++line_count) @@ -729,84 +720,46 @@ void AigerReader::parse_aiger_binary() void AigerReader::post_process() { - dict> box_ports; - unsigned ci_count = 0, co_count = 0, flop_count = 0; + unsigned ci_count = 0, co_count = 0; for (auto cell : boxes) { - RTLIL::Module* box_module = design->module(cell->type); - log_assert(box_module); - - 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; - } - 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); - } + for (auto &bit : cell->connections_.at("\\i")) { + log_assert(bit == State::S0); + log_assert(co_count < outputs.size()); + bit = outputs[co_count++]; + log_assert(bit.wire && GetSize(bit.wire) == 1); + log_assert(bit.wire->port_output); + bit.wire->port_output = false; } - - for (auto port_name : box_ports.at(cell->type)) { - RTLIL::Wire* port = box_module->wire(port_name); - log_assert(port); - RTLIL::SigSpec rhs; - for (int i = 0; i < GetSize(port); i++) { - RTLIL::Wire* wire = nullptr; - if (port->port_input) { - log_assert(co_count < outputs.size()); - wire = outputs[co_count++]; - log_assert(wire); - log_assert(wire->port_output); - wire->port_output = false; - } - if (port->port_output) { - log_assert((piNum + ci_count) < inputs.size()); - wire = inputs[piNum + ci_count++]; - log_assert(wire); - log_assert(wire->port_input); - wire->port_input = false; - } - rhs.append(wire); - } - cell->setPort(port_name, rhs); + for (auto &bit : cell->connections_.at("\\o")) { + log_assert(bit == State::S0); + log_assert((piNum + ci_count) < inputs.size()); + bit = inputs[piNum + ci_count++]; + log_assert(bit.wire && GetSize(bit.wire) == 1); + log_assert(bit.wire->port_input); + bit.wire->port_input = false; } + } - 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; - } + for (uint32_t i = 0; i < flopNum; i++) { + 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 + i]; + log_assert(d); + log_assert(d->port_output); + d->port_output = false; + + RTLIL::Wire *q = inputs[piNum - flopNum + i]; + 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); } dict wideports_cache; @@ -856,10 +809,6 @@ void AigerReader::post_process() RTLIL::Wire* wire = outputs[variable + co_count]; log_assert(wire); log_assert(wire->port_output); - if (escaped_s == "$__dummy__") { - wire->port_output = false; - continue; - } log_debug("Renaming output %s", log_id(wire)); if (index == 0) { @@ -897,26 +846,8 @@ void AigerReader::post_process() } else if (type == "box") { RTLIL::Cell* cell = module->cell(stringf("$box%d", variable)); - if (cell) { // ABC could have optimised this box away + if (cell) // ABC could have optimised this box away module->rename(cell, escaped_s); - for (const auto &i : cell->connections()) { - RTLIL::IdString port_name = i.first; - RTLIL::SigSpec rhs = i.second; - int index = 0; - for (auto bit : rhs.bits()) { - RTLIL::Wire* wire = bit.wire; - RTLIL::IdString escaped_s = RTLIL::escape_id(stringf("%s.%s", log_id(cell), log_id(port_name))); - if (index == 0) - module->rename(wire, escaped_s); - else if (index > 0) { - module->rename(wire, stringf("%s[%d]", escaped_s.c_str(), index)); - if (wideports) - wideports_cache[escaped_s] = std::max(wideports_cache[escaped_s], index); - } - index++; - } - } - } } else log_error("Symbol type '%s' not recognised.\n", type.c_str()); -- cgit v1.2.3 From dc3b21c1c050416aae443231729c8f4e4faf93ab Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 7 Jan 2020 09:48:57 -0800 Subject: abc9_ops -reintegrate: process box connections --- passes/techmap/abc9_ops.cc | 161 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 134 insertions(+), 27 deletions(-) diff --git a/passes/techmap/abc9_ops.cc b/passes/techmap/abc9_ops.cc index 69239c93d..721a33f09 100644 --- a/passes/techmap/abc9_ops.cc +++ b/passes/techmap/abc9_ops.cc @@ -437,6 +437,57 @@ void reintegrate(RTLIL::Module *module) for (auto w : mapped_mod->wires()) module->addWire(remap_name(w->name), GetSize(w)); + dict box_lookup; + dict> box_ports; + + 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(stringf("$__boxid%d", 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); + + auto r2 = box_ports.insert(m->name); + 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 : m->ports) { + auto w = m->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(m)); + 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(m)); + 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(m)); + if (carry_in == IdString() && carry_out != IdString()) + log_error("Module '%s' contains an 'abc9_carry' output port but no input port.\n", log_id(m)); + if (carry_in != IdString()) { + r2.first->second.push_back(carry_in); + r2.first->second.push_back(carry_out); + } + } + } + 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); @@ -515,42 +566,98 @@ void reintegrate(RTLIL::Module *module) else { existing_cell = module->cell(mapped_cell->name); log_assert(existing_cell); + + if (mapped_cell->type.begins_with("$__boxid")) { + auto type = box_lookup.at(mapped_cell->type, IdString()); + if (type == IdString()) + log_error("No module with abc9_box_id = %s found.\n", mapped_cell->type.c_str() + strlen("$__boxid")); + mapped_cell->type = type; + } cell = module->addCell(remap_name(mapped_cell->name), mapped_cell->type); } - RTLIL::Module* box_module = design->module(mapped_cell->type); - auto abc9_flop = box_module && box_module->attributes.count("\\abc9_flop"); - for (auto &mapped_conn : mapped_cell->connections()) { - RTLIL::SigSpec newsig; - for (auto c : mapped_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); + if (existing_cell) { + auto it = mapped_cell->connections_.find("\\i"); + log_assert(it != mapped_cell->connections_.end()); + SigSpec inputs = std::move(it->second); + mapped_cell->connections_.erase(it); + it = mapped_cell->connections_.find("\\o"); + log_assert(it != mapped_cell->connections_.end()); + SigSpec outputs = std::move(it->second); + mapped_cell->connections_.erase(it); + + RTLIL::Module* box_module = design->module(mapped_cell->type); + auto abc9_flop = box_module->attributes.count("\\abc9_flop"); + if (!abc9_flop) { + for (const auto &i : inputs) + bit_users[i].insert(mapped_cell->name); + for (const auto &i : outputs) + bit_drivers[i].insert(mapped_cell->name); } - if (existing_cell) { - auto it = existing_cell->connections_.find(mapped_conn.first); + + int input_count = 0, output_count = 0; + for (const auto &port_name : box_ports.at(cell->type)) { + RTLIL::Wire *w = box_module->wire(port_name); + log_assert(w); + + SigSpec sig; + if (w->port_input) { + sig = inputs.extract(input_count, GetSize(w)); + input_count += GetSize(w); + } + if (w->port_output) { + sig = outputs.extract(output_count, GetSize(w)); + output_count += GetSize(w); + } + + SigSpec newsig; + for (auto c : sig.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); + } + + auto it = existing_cell->connections_.find(port_name); if (it == existing_cell->connections_.end()) continue; - log_assert(GetSize(newsig) >= GetSize(it->second)); - newsig = newsig.extract(0, GetSize(it->second)); - } - cell->setPort(mapped_conn.first, newsig); + if (GetSize(newsig) > GetSize(it->second)) + newsig = newsig.extract(0, GetSize(it->second)); + else + log_assert(GetSize(newsig) == GetSize(it->second)); - if (abc9_flop) - continue; + cell->setPort(port_name, newsig); - if (cell->input(mapped_conn.first)) { - for (auto i : newsig) - bit2sinks[i].push_back(cell); - for (auto i : mapped_conn.second) - bit_users[i].insert(mapped_cell->name); + if (w->port_input && !abc9_flop) + for (const auto &i : newsig) + bit2sinks[i].push_back(cell); + } + } + else { + for (auto &mapped_conn : mapped_cell->connections()) { + RTLIL::SigSpec newsig; + for (auto c : mapped_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(mapped_conn.first, newsig); + + if (cell->input(mapped_conn.first)) { + for (auto i : newsig) + bit2sinks[i].push_back(cell); + for (auto i : mapped_conn.second) + bit_users[i].insert(mapped_cell->name); + } + if (cell->output(mapped_conn.first)) + for (auto i : mapped_conn.second) + bit_drivers[i].insert(mapped_cell->name); } - if (cell->output(mapped_conn.first)) - for (auto i : mapped_conn.second) - bit_drivers[i].insert(mapped_cell->name); } if (existing_cell) { -- cgit v1.2.3 From 738af17a26587f6f9438bfa2452e65a5911e58e8 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 7 Jan 2020 11:21:45 -0800 Subject: read_aiger: default -clk_name to be empty --- frontends/aiger/aigerparse.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc index f030933ec..d7367479b 100644 --- a/frontends/aiger/aigerparse.cc +++ b/frontends/aiger/aigerparse.cc @@ -1018,7 +1018,7 @@ struct AigerFrontend : public Frontend { { log_header(design, "Executing AIGER frontend.\n"); - RTLIL::IdString clk_name = "\\clk"; + RTLIL::IdString clk_name; RTLIL::IdString module_name; std::string map_filename; bool wideports = false; -- cgit v1.2.3 From baba33fbd391d31187695a8d0d9937249a472b2e Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 7 Jan 2020 11:22:48 -0800 Subject: read_aiger: cope with latches and POs with same name --- frontends/aiger/aigerparse.cc | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc index d7367479b..04530e562 100644 --- a/frontends/aiger/aigerparse.cc +++ b/frontends/aiger/aigerparse.cc @@ -271,14 +271,23 @@ end_of_header: if ((c == 'i' && l1 > inputs.size()) || (c == 'l' && l1 > latches.size()) || (c == 'o' && l1 > outputs.size())) log_error("Line %u has invalid symbol position!\n", line_count); + RTLIL::IdString escaped_s = stringf("\\%s", s.c_str()); RTLIL::Wire* wire; if (c == 'i') wire = inputs[l1]; else if (c == 'l') wire = latches[l1]; - else if (c == 'o') wire = outputs[l1]; + else if (c == 'o') { + wire = module->wire(escaped_s); + if (wire) { + // Could have been renamed by a latch + module->swap_names(wire, outputs[l1]); + goto next; + } + wire = outputs[l1]; + } else if (c == 'b') wire = bad_properties[l1]; else log_abort(); - module->rename(wire, stringf("\\%s", s.c_str())); + module->rename(wire, escaped_s); } else if (c == 'j' || c == 'f') { // TODO @@ -293,6 +302,7 @@ end_of_header: } else log_error("Line %u: cannot interpret first character '%c'!\n", line_count, c); +next: std::getline(f, line); // Ignore up to start of next line } -- cgit v1.2.3 From b94cf0c1266f6f3daea809323f0bba0dc5d69e1a Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 7 Jan 2020 11:43:28 -0800 Subject: read_aiger: connect identical signals together --- frontends/aiger/aigerparse.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc index 04530e562..f7b9146ce 100644 --- a/frontends/aiger/aigerparse.cc +++ b/frontends/aiger/aigerparse.cc @@ -280,6 +280,7 @@ end_of_header: if (wire) { // Could have been renamed by a latch module->swap_names(wire, outputs[l1]); + module->connect(outputs[l1], wire); goto next; } wire = outputs[l1]; -- cgit v1.2.3 From 7c878bf39741ca8889425932063918d837b8ac9b Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 7 Jan 2020 11:44:03 -0800 Subject: tests/aiger: write Yosys output --- tests/aiger/run-test.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/aiger/run-test.sh b/tests/aiger/run-test.sh index deaf48a3d..8e932b091 100755 --- a/tests/aiger/run-test.sh +++ b/tests/aiger/run-test.sh @@ -33,7 +33,7 @@ design -import gold -as gold design -import gate -as gate miter -equiv -flatten -make_assert -make_outputs gold gate miter sat -verify -prove-asserts -show-ports -seq 16 miter -" +" -l ${aag}.log done for aig in *.aig; do @@ -50,5 +50,5 @@ design -import gold -as gold design -import gate -as gate miter -equiv -flatten -make_assert -make_outputs gold gate miter sat -verify -prove-asserts -show-ports -seq 16 miter -" +" -l ${aig}.log done -- cgit v1.2.3 From 0d3f10d3cc55e83ae6a39881227feb843769d6b1 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 7 Jan 2020 11:44:20 -0800 Subject: Add testcases --- tests/aiger/symbols.aag | 9 +++++++++ tests/aiger/symbols.aig | 8 ++++++++ 2 files changed, 17 insertions(+) create mode 100644 tests/aiger/symbols.aag create mode 100644 tests/aiger/symbols.aig diff --git a/tests/aiger/symbols.aag b/tests/aiger/symbols.aag new file mode 100644 index 000000000..93f8989f2 --- /dev/null +++ b/tests/aiger/symbols.aag @@ -0,0 +1,9 @@ +aag 2 1 1 1 0 +2 +4 2 1 +4 +i0 d +l0 q +o0 q +c +Generated by Yosys 0.9+932 (git sha1 baba33fb, clang 9.0.0-2 -fPIC -Os) diff --git a/tests/aiger/symbols.aig b/tests/aiger/symbols.aig new file mode 100644 index 000000000..a7922ab46 --- /dev/null +++ b/tests/aiger/symbols.aig @@ -0,0 +1,8 @@ +aig 2 1 1 1 0 +2 1 +4 +i0 d +l0 q +o0 q +c +Generated by Yosys 0.9+932 (git sha1 baba33fb, clang 9.0.0-2 -fPIC -Os) -- cgit v1.2.3 From 9c5ceb5b4f7aea169c8d9ffd2411c6f4eb3e49d5 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 7 Jan 2020 11:44:03 -0800 Subject: tests/aiger: write Yosys output --- tests/aiger/run-test.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/aiger/run-test.sh b/tests/aiger/run-test.sh index deaf48a3d..8e932b091 100755 --- a/tests/aiger/run-test.sh +++ b/tests/aiger/run-test.sh @@ -33,7 +33,7 @@ design -import gold -as gold design -import gate -as gate miter -equiv -flatten -make_assert -make_outputs gold gate miter sat -verify -prove-asserts -show-ports -seq 16 miter -" +" -l ${aag}.log done for aig in *.aig; do @@ -50,5 +50,5 @@ design -import gold -as gold design -import gate -as gate miter -equiv -flatten -make_assert -make_outputs gold gate miter sat -verify -prove-asserts -show-ports -seq 16 miter -" +" -l ${aig}.log done -- cgit v1.2.3 From 8f5388ea5b88d4e848b1110fed2abf7544440185 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 7 Jan 2020 11:59:57 -0800 Subject: read_aiger fixes --- frontends/aiger/aigerparse.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc index 355429646..b18049df1 100644 --- a/frontends/aiger/aigerparse.cc +++ b/frontends/aiger/aigerparse.cc @@ -490,9 +490,9 @@ void AigerReader::parse_aiger_ascii() log_error("Line %u cannot be interpreted as an input!\n", line_count); log_debug2("%d is an input\n", l1); log_assert(!(l1 & 1)); // Inputs can't be inverted - RTLIL::Wire *wire = module->addWire(stringf("$i%0*d", digits, i)); + RTLIL::Wire *wire = module->addWire(stringf("$i%0*d", digits, l1 >> 1)); wire->port_input = true; - module->connect(createWireIfNotExists(module, l1 << 1), wire); + module->connect(createWireIfNotExists(module, l1), wire); inputs.push_back(wire); } @@ -553,7 +553,7 @@ void AigerReader::parse_aiger_ascii() module->connect(wire, createWireIfNotExists(module, l1)); outputs.push_back(wire); } - std::getline(f, line); // Ignore up to start of next line + //std::getline(f, line); // Ignore up to start of next line // Parse bad properties for (unsigned i = 0; i < B; ++i, ++line_count) { @@ -565,8 +565,8 @@ void AigerReader::parse_aiger_ascii() wire->port_output = true; bad_properties.push_back(wire); } - if (B > 0) - std::getline(f, line); // Ignore up to start of next line + //if (B > 0) + // std::getline(f, line); // Ignore up to start of next line // TODO: Parse invariant constraints for (unsigned i = 0; i < C; ++i, ++line_count) -- cgit v1.2.3 From 2ac36031d4da8d2e99d89f16cb69871c9e3c59aa Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 7 Jan 2020 13:30:31 -0800 Subject: read_aiger: consistency between ascii and binary; also name latches --- frontends/aiger/aigerparse.cc | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc index f7b9146ce..8a114b18c 100644 --- a/frontends/aiger/aigerparse.cc +++ b/frontends/aiger/aigerparse.cc @@ -507,13 +507,15 @@ void AigerReader::parse_aiger_ascii() unsigned l1, l2, l3; // Parse inputs + int digits = ceil(log10(I)); for (unsigned i = 1; i <= I; ++i, ++line_count) { if (!(f >> l1)) log_error("Line %u cannot be interpreted as an input!\n", line_count); log_debug2("%d is an input\n", l1); log_assert(!(l1 & 1)); // Inputs can't be inverted - RTLIL::Wire *wire = createWireIfNotExists(module, l1); + RTLIL::Wire *wire = module->addWire(stringf("$i%0*d", digits, l1 >> 1)); wire->port_input = true; + module->connect(createWireIfNotExists(module, l1), wire); inputs.push_back(wire); } @@ -527,12 +529,14 @@ void AigerReader::parse_aiger_ascii() clk_wire->port_input = true; clk_wire->port_output = false; } + digits = ceil(log10(L)); for (unsigned i = 0; i < L; ++i, ++line_count) { if (!(f >> l1 >> l2)) log_error("Line %u cannot be interpreted as a latch!\n", line_count); log_debug2("%d %d is a latch\n", l1, l2); log_assert(!(l1 & 1)); - RTLIL::Wire *q_wire = createWireIfNotExists(module, l1); + RTLIL::Wire *q_wire = module->addWire(stringf("$l%0*d", digits, l1 >> 1)); + module->connect(createWireIfNotExists(module, l1), q_wire); RTLIL::Wire *d_wire = createWireIfNotExists(module, l2); if (clk_wire) @@ -655,12 +659,14 @@ void AigerReader::parse_aiger_binary() clk_wire->port_input = true; clk_wire->port_output = false; } + digits = ceil(log10(L)); l1 = (I+1) * 2; for (unsigned i = 0; i < L; ++i, ++line_count, l1 += 2) { if (!(f >> l2)) log_error("Line %u cannot be interpreted as a latch!\n", line_count); log_debug("%d %d is a latch\n", l1, l2); - RTLIL::Wire *q_wire = createWireIfNotExists(module, l1); + RTLIL::Wire *q_wire = module->addWire(stringf("$l%0*d", digits, l1 >> 1)); + module->connect(createWireIfNotExists(module, l1), q_wire); RTLIL::Wire *d_wire = createWireIfNotExists(module, l2); if (clk_wire) -- cgit v1.2.3 From 66b0f3c406fca11d789b26d85dd27660eacee26c Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 7 Jan 2020 15:40:37 -0800 Subject: Bump ABCREV for upstream fix --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index d7319796b..fd95219ee 100644 --- a/Makefile +++ b/Makefile @@ -128,7 +128,7 @@ bumpversion: # is just a symlink to your actual ABC working directory, as 'make mrproper' # will remove the 'abc' directory and you do not want to accidentally # delete your work on ABC.. -ABCREV = f6dc4a5 +ABCREV = 144c5be ABCPULL = 1 ABCURL ?= https://github.com/berkeley-abc/abc ABCMKARGS = CC="$(CXX)" CXX="$(CXX)" ABC_USE_LIBSTDCXX=1 -- cgit v1.2.3 From 102f1397284980705efe3eb03cc3d3cd859e94ff Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 6 Jan 2020 12:36:11 -0800 Subject: scc to use design->selected_modules() which avoids black/white-boxes --- passes/cmds/scc.cc | 51 +++++++++++++++++++++++++-------------------------- 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/passes/cmds/scc.cc b/passes/cmds/scc.cc index 99f4fbae8..ad0554bae 100644 --- a/passes/cmds/scc.cc +++ b/passes/cmds/scc.cc @@ -301,42 +301,41 @@ struct SccPass : public Pass { RTLIL::Selection newSelection(false); int scc_counter = 0; - for (auto &mod_it : design->modules_) - if (design->selected(mod_it.second)) - { - SccWorker worker(design, mod_it.second, nofeedbackMode, allCellTypes, maxDepth); + for (auto mod : design->selected_modules()) + { + SccWorker worker(design, mod, nofeedbackMode, allCellTypes, maxDepth); - if (!setAttr.empty()) + if (!setAttr.empty()) + { + for (const auto &cells : worker.sccList) { - for (const auto &cells : worker.sccList) + for (auto attr : setAttr) { - for (auto attr : setAttr) - { - IdString attr_name(RTLIL::escape_id(attr.first)); - string attr_valstr = attr.second; - string index = stringf("%d", scc_counter); - - for (size_t pos = 0; (pos = attr_valstr.find("{}", pos)) != string::npos; pos += index.size()) - attr_valstr.replace(pos, 2, index); + IdString attr_name(RTLIL::escape_id(attr.first)); + string attr_valstr = attr.second; + string index = stringf("%d", scc_counter); - Const attr_value(attr_valstr); + for (size_t pos = 0; (pos = attr_valstr.find("{}", pos)) != string::npos; pos += index.size()) + attr_valstr.replace(pos, 2, index); - for (auto cell : cells) - cell->attributes[attr_name] = attr_value; - } + Const attr_value(attr_valstr); - scc_counter++; + for (auto cell : cells) + cell->attributes[attr_name] = attr_value; } - } - else - { - scc_counter += GetSize(worker.sccList); - } - if (selectMode) - worker.select(newSelection); + scc_counter++; + } + } + else + { + scc_counter += GetSize(worker.sccList); } + if (selectMode) + worker.select(newSelection); + } + if (expect >= 0) { if (scc_counter == expect) log("Found and expected %d SCCs.\n", scc_counter); -- cgit v1.2.3 From 6e3e81402520b854eb5879964adc3434fefd3f51 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 7 Jan 2020 15:59:18 -0800 Subject: Fix abc9_xc7.box comments --- techlibs/xilinx/abc9_xc7.box | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/techlibs/xilinx/abc9_xc7.box b/techlibs/xilinx/abc9_xc7.box index 64170546c..13f4f0e61 100644 --- a/techlibs/xilinx/abc9_xc7.box +++ b/techlibs/xilinx/abc9_xc7.box @@ -132,15 +132,16 @@ $__ABC9_LUT6 2000 0 7 1 0 642 631 472 407 238 127 # Y # Box 2001 : $__ABC9_LUT6 -# (private cell to emulate async behaviour of LUITRAMs) +# (private cell to emulate async behaviour of LUTRAMs) # name ID w/b ins outs -$__ABC9_LUT7 2001 0 8 1 +$__ABC9_LUT7 2001 0 8 1 #A S0 S1 S2 S3 S4 S5 S6 0 1047 1036 877 812 643 532 478 # Y -# Boxes used to represent the comb behaviour of various modes -# of DSP48E1 -$__ABC9_DSP48E1_MULT 3000 0 265 96 +# Box 3000 : $__ABC9_DSP48E1_MULT +# (private cell to emulate comb behaviour of a DSP48E1 mode) +# name ID w/b ins outs +$__ABC9_DSP48E1_MULT 3000 0 265 96 #A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11 A12 A13 A14 A15 A16 A17 A18 A19 A20 A21 A22 A23 A24 A25 A26 A27 A28 A29 B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 B10 B11 B12 B13 B14 B15 B16 B17 C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 C10 C11 C12 C13 C14 C15 C16 C17 C18 C19 C20 C21 C22 C23 C24 C25 C26 C27 C28 C29 C30 C31 C32 C33 C34 C35 C36 C37 C38 C39 C40 C41 C42 C43 C44 C45 C46 C47 D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 D10 D11 D12 D13 D14 D15 D16 D17 D18 D19 D20 D21 D22 D23 D24 P0 P1 P2 P3 P4 P5 P6 P7 P8 P9 P10 P11 P12 P13 P14 P15 P16 P17 P18 P19 P20 P21 P22 P23 P24 P25 P26 P27 P28 P29 P30 P31 P32 P33 P34 P35 P36 P37 P38 P39 P40 P41 P42 P43 P44 P45 P46 P47 PCIN0 PCIN1 PCIN2 PCIN3 PCIN4 PCIN5 PCIN6 PCIN7 PCIN8 PCIN9 PCIN10 PCIN11 PCIN12 PCIN13 PCIN14 PCIN15 PCIN16 PCIN17 PCIN18 PCIN19 PCIN20 PCIN21 PCIN22 PCIN23 PCIN24 PCIN25 PCIN26 PCIN27 PCIN28 PCIN29 PCIN30 PCIN31 PCIN32 PCIN33 PCIN34 PCIN35 PCIN36 PCIN37 PCIN38 PCIN39 PCIN40 PCIN41 PCIN42 PCIN43 PCIN44 PCIN45 PCIN46 PCIN47 PCOUT0 PCOUT1 PCOUT2 PCOUT3 PCOUT4 PCOUT5 PCOUT6 PCOUT7 PCOUT8 PCOUT9 PCOUT10 PCOUT11 PCOUT12 PCOUT13 PCOUT14 PCOUT15 PCOUT16 PCOUT17 PCOUT18 PCOUT19 PCOUT20 PCOUT21 PCOUT22 PCOUT23 PCOUT24 PCOUT25 PCOUT26 PCOUT27 PCOUT28 PCOUT29 PCOUT30 PCOUT31 PCOUT32 PCOUT33 PCOUT34 PCOUT35 PCOUT36 PCOUT37 PCOUT38 PCOUT39 PCOUT40 PCOUT41 PCOUT42 PCOUT43 PCOUT44 PCOUT45 PCOUT46 PCOUT47 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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P0 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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P1 @@ -239,7 +240,10 @@ $__ABC9_DSP48E1_MULT 3000 0 265 96 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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT46 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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT47 -$__ABC9_DSP48E1_MULT_DPORT 3001 0 265 96 +# Box 3001 : $__ABC9_DSP48E1_MULT_DPORT +# (private cell to emulate comb behaviour of a DSP48E1 mode) +# name ID w/b ins outs +$__ABC9_DSP48E1_MULT_DPORT 3001 0 265 96 #A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11 A12 A13 A14 A15 A16 A17 A18 A19 A20 A21 A22 A23 A24 A25 A26 A27 A28 A29 B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 B10 B11 B12 B13 B14 B15 B16 B17 C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 C10 C11 C12 C13 C14 C15 C16 C17 C18 C19 C20 C21 C22 C23 C24 C25 C26 C27 C28 C29 C30 C31 C32 C33 C34 C35 C36 C37 C38 C39 C40 C41 C42 C43 C44 C45 C46 C47 D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 D10 D11 D12 D13 D14 D15 D16 D17 D18 D19 D20 D21 D22 D23 D24 P0 P1 P2 P3 P4 P5 P6 P7 P8 P9 P10 P11 P12 P13 P14 P15 P16 P17 P18 P19 P20 P21 P22 P23 P24 P25 P26 P27 P28 P29 P30 P31 P32 P33 P34 P35 P36 P37 P38 P39 P40 P41 P42 P43 P44 P45 P46 P47 PCIN0 PCIN1 PCIN2 PCIN3 PCIN4 PCIN5 PCIN6 PCIN7 PCIN8 PCIN9 PCIN10 PCIN11 PCIN12 PCIN13 PCIN14 PCIN15 PCIN16 PCIN17 PCIN18 PCIN19 PCIN20 PCIN21 PCIN22 PCIN23 PCIN24 PCIN25 PCIN26 PCIN27 PCIN28 PCIN29 PCIN30 PCIN31 PCIN32 PCIN33 PCIN34 PCIN35 PCIN36 PCIN37 PCIN38 PCIN39 PCIN40 PCIN41 PCIN42 PCIN43 PCIN44 PCIN45 PCIN46 PCIN47 PCOUT0 PCOUT1 PCOUT2 PCOUT3 PCOUT4 PCOUT5 PCOUT6 PCOUT7 PCOUT8 PCOUT9 PCOUT10 PCOUT11 PCOUT12 PCOUT13 PCOUT14 PCOUT15 PCOUT16 PCOUT17 PCOUT18 PCOUT19 PCOUT20 PCOUT21 PCOUT22 PCOUT23 PCOUT24 PCOUT25 PCOUT26 PCOUT27 PCOUT28 PCOUT29 PCOUT30 PCOUT31 PCOUT32 PCOUT33 PCOUT34 PCOUT35 PCOUT36 PCOUT37 PCOUT38 PCOUT39 PCOUT40 PCOUT41 PCOUT42 PCOUT43 PCOUT44 PCOUT45 PCOUT46 PCOUT47 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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P0 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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P1 @@ -338,7 +342,10 @@ $__ABC9_DSP48E1_MULT_DPORT 3001 0 265 96 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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT46 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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT47 -$__ABC9_DSP48E1 3002 0 265 96 +# Box 3002 : $__ABC9_DSP48E1 +# (private cell to emulate comb behaviour of a DSP48E1 mode) +# name ID w/b ins outs +$__ABC9_DSP48E1 3002 0 265 96 #A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11 A12 A13 A14 A15 A16 A17 A18 A19 A20 A21 A22 A23 A24 A25 A26 A27 A28 A29 B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 B10 B11 B12 B13 B14 B15 B16 B17 C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 C10 C11 C12 C13 C14 C15 C16 C17 C18 C19 C20 C21 C22 C23 C24 C25 C26 C27 C28 C29 C30 C31 C32 C33 C34 C35 C36 C37 C38 C39 C40 C41 C42 C43 C44 C45 C46 C47 D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 D10 D11 D12 D13 D14 D15 D16 D17 D18 D19 D20 D21 D22 D23 D24 P0 P1 P2 P3 P4 P5 P6 P7 P8 P9 P10 P11 P12 P13 P14 P15 P16 P17 P18 P19 P20 P21 P22 P23 P24 P25 P26 P27 P28 P29 P30 P31 P32 P33 P34 P35 P36 P37 P38 P39 P40 P41 P42 P43 P44 P45 P46 P47 PCIN0 PCIN1 PCIN2 PCIN3 PCIN4 PCIN5 PCIN6 PCIN7 PCIN8 PCIN9 PCIN10 PCIN11 PCIN12 PCIN13 PCIN14 PCIN15 PCIN16 PCIN17 PCIN18 PCIN19 PCIN20 PCIN21 PCIN22 PCIN23 PCIN24 PCIN25 PCIN26 PCIN27 PCIN28 PCIN29 PCIN30 PCIN31 PCIN32 PCIN33 PCIN34 PCIN35 PCIN36 PCIN37 PCIN38 PCIN39 PCIN40 PCIN41 PCIN42 PCIN43 PCIN44 PCIN45 PCIN46 PCIN47 PCOUT0 PCOUT1 PCOUT2 PCOUT3 PCOUT4 PCOUT5 PCOUT6 PCOUT7 PCOUT8 PCOUT9 PCOUT10 PCOUT11 PCOUT12 PCOUT13 PCOUT14 PCOUT15 PCOUT16 PCOUT17 PCOUT18 PCOUT19 PCOUT20 PCOUT21 PCOUT22 PCOUT23 PCOUT24 PCOUT25 PCOUT26 PCOUT27 PCOUT28 PCOUT29 PCOUT30 PCOUT31 PCOUT32 PCOUT33 PCOUT34 PCOUT35 PCOUT36 PCOUT37 PCOUT38 PCOUT39 PCOUT40 PCOUT41 PCOUT42 PCOUT43 PCOUT44 PCOUT45 PCOUT46 PCOUT47 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 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P0 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 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P1 -- cgit v1.2.3 From 823a08e0d8272e8d48584eecc2d8dc57bdb98a6e Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 7 Jan 2020 15:59:18 -0800 Subject: Fix abc9_xc7.box comments --- techlibs/xilinx/abc9_xc7.box | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/techlibs/xilinx/abc9_xc7.box b/techlibs/xilinx/abc9_xc7.box index 64170546c..13f4f0e61 100644 --- a/techlibs/xilinx/abc9_xc7.box +++ b/techlibs/xilinx/abc9_xc7.box @@ -132,15 +132,16 @@ $__ABC9_LUT6 2000 0 7 1 0 642 631 472 407 238 127 # Y # Box 2001 : $__ABC9_LUT6 -# (private cell to emulate async behaviour of LUITRAMs) +# (private cell to emulate async behaviour of LUTRAMs) # name ID w/b ins outs -$__ABC9_LUT7 2001 0 8 1 +$__ABC9_LUT7 2001 0 8 1 #A S0 S1 S2 S3 S4 S5 S6 0 1047 1036 877 812 643 532 478 # Y -# Boxes used to represent the comb behaviour of various modes -# of DSP48E1 -$__ABC9_DSP48E1_MULT 3000 0 265 96 +# Box 3000 : $__ABC9_DSP48E1_MULT +# (private cell to emulate comb behaviour of a DSP48E1 mode) +# name ID w/b ins outs +$__ABC9_DSP48E1_MULT 3000 0 265 96 #A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11 A12 A13 A14 A15 A16 A17 A18 A19 A20 A21 A22 A23 A24 A25 A26 A27 A28 A29 B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 B10 B11 B12 B13 B14 B15 B16 B17 C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 C10 C11 C12 C13 C14 C15 C16 C17 C18 C19 C20 C21 C22 C23 C24 C25 C26 C27 C28 C29 C30 C31 C32 C33 C34 C35 C36 C37 C38 C39 C40 C41 C42 C43 C44 C45 C46 C47 D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 D10 D11 D12 D13 D14 D15 D16 D17 D18 D19 D20 D21 D22 D23 D24 P0 P1 P2 P3 P4 P5 P6 P7 P8 P9 P10 P11 P12 P13 P14 P15 P16 P17 P18 P19 P20 P21 P22 P23 P24 P25 P26 P27 P28 P29 P30 P31 P32 P33 P34 P35 P36 P37 P38 P39 P40 P41 P42 P43 P44 P45 P46 P47 PCIN0 PCIN1 PCIN2 PCIN3 PCIN4 PCIN5 PCIN6 PCIN7 PCIN8 PCIN9 PCIN10 PCIN11 PCIN12 PCIN13 PCIN14 PCIN15 PCIN16 PCIN17 PCIN18 PCIN19 PCIN20 PCIN21 PCIN22 PCIN23 PCIN24 PCIN25 PCIN26 PCIN27 PCIN28 PCIN29 PCIN30 PCIN31 PCIN32 PCIN33 PCIN34 PCIN35 PCIN36 PCIN37 PCIN38 PCIN39 PCIN40 PCIN41 PCIN42 PCIN43 PCIN44 PCIN45 PCIN46 PCIN47 PCOUT0 PCOUT1 PCOUT2 PCOUT3 PCOUT4 PCOUT5 PCOUT6 PCOUT7 PCOUT8 PCOUT9 PCOUT10 PCOUT11 PCOUT12 PCOUT13 PCOUT14 PCOUT15 PCOUT16 PCOUT17 PCOUT18 PCOUT19 PCOUT20 PCOUT21 PCOUT22 PCOUT23 PCOUT24 PCOUT25 PCOUT26 PCOUT27 PCOUT28 PCOUT29 PCOUT30 PCOUT31 PCOUT32 PCOUT33 PCOUT34 PCOUT35 PCOUT36 PCOUT37 PCOUT38 PCOUT39 PCOUT40 PCOUT41 PCOUT42 PCOUT43 PCOUT44 PCOUT45 PCOUT46 PCOUT47 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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P0 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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P1 @@ -239,7 +240,10 @@ $__ABC9_DSP48E1_MULT 3000 0 265 96 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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT46 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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT47 -$__ABC9_DSP48E1_MULT_DPORT 3001 0 265 96 +# Box 3001 : $__ABC9_DSP48E1_MULT_DPORT +# (private cell to emulate comb behaviour of a DSP48E1 mode) +# name ID w/b ins outs +$__ABC9_DSP48E1_MULT_DPORT 3001 0 265 96 #A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11 A12 A13 A14 A15 A16 A17 A18 A19 A20 A21 A22 A23 A24 A25 A26 A27 A28 A29 B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 B10 B11 B12 B13 B14 B15 B16 B17 C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 C10 C11 C12 C13 C14 C15 C16 C17 C18 C19 C20 C21 C22 C23 C24 C25 C26 C27 C28 C29 C30 C31 C32 C33 C34 C35 C36 C37 C38 C39 C40 C41 C42 C43 C44 C45 C46 C47 D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 D10 D11 D12 D13 D14 D15 D16 D17 D18 D19 D20 D21 D22 D23 D24 P0 P1 P2 P3 P4 P5 P6 P7 P8 P9 P10 P11 P12 P13 P14 P15 P16 P17 P18 P19 P20 P21 P22 P23 P24 P25 P26 P27 P28 P29 P30 P31 P32 P33 P34 P35 P36 P37 P38 P39 P40 P41 P42 P43 P44 P45 P46 P47 PCIN0 PCIN1 PCIN2 PCIN3 PCIN4 PCIN5 PCIN6 PCIN7 PCIN8 PCIN9 PCIN10 PCIN11 PCIN12 PCIN13 PCIN14 PCIN15 PCIN16 PCIN17 PCIN18 PCIN19 PCIN20 PCIN21 PCIN22 PCIN23 PCIN24 PCIN25 PCIN26 PCIN27 PCIN28 PCIN29 PCIN30 PCIN31 PCIN32 PCIN33 PCIN34 PCIN35 PCIN36 PCIN37 PCIN38 PCIN39 PCIN40 PCIN41 PCIN42 PCIN43 PCIN44 PCIN45 PCIN46 PCIN47 PCOUT0 PCOUT1 PCOUT2 PCOUT3 PCOUT4 PCOUT5 PCOUT6 PCOUT7 PCOUT8 PCOUT9 PCOUT10 PCOUT11 PCOUT12 PCOUT13 PCOUT14 PCOUT15 PCOUT16 PCOUT17 PCOUT18 PCOUT19 PCOUT20 PCOUT21 PCOUT22 PCOUT23 PCOUT24 PCOUT25 PCOUT26 PCOUT27 PCOUT28 PCOUT29 PCOUT30 PCOUT31 PCOUT32 PCOUT33 PCOUT34 PCOUT35 PCOUT36 PCOUT37 PCOUT38 PCOUT39 PCOUT40 PCOUT41 PCOUT42 PCOUT43 PCOUT44 PCOUT45 PCOUT46 PCOUT47 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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P0 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 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P1 @@ -338,7 +342,10 @@ $__ABC9_DSP48E1_MULT_DPORT 3001 0 265 96 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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT46 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 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT47 -$__ABC9_DSP48E1 3002 0 265 96 +# Box 3002 : $__ABC9_DSP48E1 +# (private cell to emulate comb behaviour of a DSP48E1 mode) +# name ID w/b ins outs +$__ABC9_DSP48E1 3002 0 265 96 #A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11 A12 A13 A14 A15 A16 A17 A18 A19 A20 A21 A22 A23 A24 A25 A26 A27 A28 A29 B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 B10 B11 B12 B13 B14 B15 B16 B17 C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 C10 C11 C12 C13 C14 C15 C16 C17 C18 C19 C20 C21 C22 C23 C24 C25 C26 C27 C28 C29 C30 C31 C32 C33 C34 C35 C36 C37 C38 C39 C40 C41 C42 C43 C44 C45 C46 C47 D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 D10 D11 D12 D13 D14 D15 D16 D17 D18 D19 D20 D21 D22 D23 D24 P0 P1 P2 P3 P4 P5 P6 P7 P8 P9 P10 P11 P12 P13 P14 P15 P16 P17 P18 P19 P20 P21 P22 P23 P24 P25 P26 P27 P28 P29 P30 P31 P32 P33 P34 P35 P36 P37 P38 P39 P40 P41 P42 P43 P44 P45 P46 P47 PCIN0 PCIN1 PCIN2 PCIN3 PCIN4 PCIN5 PCIN6 PCIN7 PCIN8 PCIN9 PCIN10 PCIN11 PCIN12 PCIN13 PCIN14 PCIN15 PCIN16 PCIN17 PCIN18 PCIN19 PCIN20 PCIN21 PCIN22 PCIN23 PCIN24 PCIN25 PCIN26 PCIN27 PCIN28 PCIN29 PCIN30 PCIN31 PCIN32 PCIN33 PCIN34 PCIN35 PCIN36 PCIN37 PCIN38 PCIN39 PCIN40 PCIN41 PCIN42 PCIN43 PCIN44 PCIN45 PCIN46 PCIN47 PCOUT0 PCOUT1 PCOUT2 PCOUT3 PCOUT4 PCOUT5 PCOUT6 PCOUT7 PCOUT8 PCOUT9 PCOUT10 PCOUT11 PCOUT12 PCOUT13 PCOUT14 PCOUT15 PCOUT16 PCOUT17 PCOUT18 PCOUT19 PCOUT20 PCOUT21 PCOUT22 PCOUT23 PCOUT24 PCOUT25 PCOUT26 PCOUT27 PCOUT28 PCOUT29 PCOUT30 PCOUT31 PCOUT32 PCOUT33 PCOUT34 PCOUT35 PCOUT36 PCOUT37 PCOUT38 PCOUT39 PCOUT40 PCOUT41 PCOUT42 PCOUT43 PCOUT44 PCOUT45 PCOUT46 PCOUT47 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 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P0 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 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P1 -- cgit v1.2.3 From 8a47e6ddfdb49ec172f783621a64b3a8906ff5d6 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 8 Jan 2020 10:00:50 -0800 Subject: Fix abc9 help, add labels --- passes/techmap/abc9.cc | 129 +++++++++++++++++++++++++++---------------------- 1 file changed, 71 insertions(+), 58 deletions(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 0a5454d99..f6627602b 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -184,70 +184,83 @@ struct Abc9Pass : public ScriptPass void script() YS_OVERRIDE { - run("scc -set_attr abc9_scc_id {}"); - if (help_mode) - run("abc9_ops -break_scc -prep_holes [-dff]", "(option for -dff)"); - else - run("abc9_ops -break_scc -prep_holes" + std::string(dff_mode ? " -dff" : ""), "(option for -dff)"); - run("select -set abc9_holes A:abc9_holes"); - run("flatten -wb @abc9_holes"); - run("techmap @abc9_holes"); - run("aigmap"); - if (dff_mode) - run("abc9_ops -prep_dff"); - run("opt -purge @abc9_holes"); - run("wbflip @abc9_holes"); - - auto selected_modules = active_design->selected_modules(); - active_design->selection_stack.emplace_back(false); - - for (auto mod : selected_modules) { - if (mod->processes.size() > 0) { - log("Skipping module %s as it contains processes.\n", log_id(mod)); - continue; - } - log_assert(!mod->attributes.count(ID(abc9_box_id))); - - active_design->selection().select(mod); - - if (!active_design->selected_whole_module(mod)) - log_error("Can't handle partially selected module %s!\n", log_id(mod)); - - std::string tempdir_name = "/tmp/yosys-abc-XXXXXX"; - if (!cleanup) - tempdir_name[0] = tempdir_name[4] = '_'; - tempdir_name = make_temp_dir(tempdir_name); - - run(stringf("write_xaiger -map %s/input.sym %s/input.xaig", tempdir_name.c_str(), tempdir_name.c_str()), - "write_xaiger -map /input.sym /input.xaig"); - - int num_outputs = active_design->scratchpad_get_int("write_xaiger.num_outputs"); - log("Extracted %d AND gates and %d wires to a netlist network with %d inputs and %d outputs.\n", - active_design->scratchpad_get_int("write_xaiger.num_ands"), - active_design->scratchpad_get_int("write_xaiger.num_wires"), - active_design->scratchpad_get_int("write_xaiger.num_inputs"), - num_outputs); - if (num_outputs) { - run(stringf("%s -cwd %s", exe_cmd.str().c_str(), tempdir_name.c_str()), - "abc9_exe [options] -cwd "); - run(stringf("read_aiger -xaiger -wideports -module_name %s$abc9 -map %s/input.sym %s/output.aig", log_id(mod->name), tempdir_name.c_str(), tempdir_name.c_str()), - "read_aiger -xaiger -wideports -module_name $abc9 -map /input.sym /output.aig"); - run("abc9_ops -reintegrate"); - } + if (check_label("pre")) { + run("scc -set_attr abc9_scc_id {}"); + if (help_mode) + run("abc9_ops -break_scc -prep_holes [-dff]", "(option for -dff)"); else - log("Don't call ABC as there is nothing to map.\n"); + run("abc9_ops -break_scc -prep_holes" + std::string(dff_mode ? " -dff" : ""), "(option for -dff)"); + run("select -set abc9_holes A:abc9_holes"); + run("flatten -wb @abc9_holes"); + run("techmap @abc9_holes"); + run("aigmap"); + if (dff_mode || help_mode) + run("abc9_ops -prep_dff", "(only if -dff)"); + run("opt -purge @abc9_holes"); + run("wbflip @abc9_holes"); + } - if (cleanup) { - log("Removing temp directory.\n"); - remove_directory(tempdir_name); + if (check_label("map")) { + if (help_mode) { + run("foreach module in selection"); + run(" write_xaiger -map /input.sym /input.xaig"); + run(" abc9_exe [options] -cwd "); + run(" read_aiger -xaiger -wideports -module_name $abc9 -map /input.sym /output.aig"); + run(" abc9_ops -reintegrate"); } + else { + auto selected_modules = active_design->selected_modules(); + active_design->selection_stack.emplace_back(false); - active_design->selection().selected_modules.clear(); - } + for (auto mod : selected_modules) { + if (mod->processes.size() > 0) { + log("Skipping module %s as it contains processes.\n", log_id(mod)); + continue; + } + log_assert(!mod->attributes.count(ID(abc9_box_id))); + + active_design->selection().select(mod); + + if (!active_design->selected_whole_module(mod)) + log_error("Can't handle partially selected module %s!\n", log_id(mod)); - active_design->selection_stack.pop_back(); + std::string tempdir_name = "/tmp/yosys-abc-XXXXXX"; + if (!cleanup) + tempdir_name[0] = tempdir_name[4] = '_'; + tempdir_name = make_temp_dir(tempdir_name); + + run(stringf("write_xaiger -map %s/input.sym %s/input.xaig", tempdir_name.c_str(), tempdir_name.c_str())); + + int num_outputs = active_design->scratchpad_get_int("write_xaiger.num_outputs"); + log("Extracted %d AND gates and %d wires to a netlist network with %d inputs and %d outputs.\n", + active_design->scratchpad_get_int("write_xaiger.num_ands"), + active_design->scratchpad_get_int("write_xaiger.num_wires"), + active_design->scratchpad_get_int("write_xaiger.num_inputs"), + num_outputs); + if (num_outputs) { + run(stringf("%s -cwd %s", exe_cmd.str().c_str(), tempdir_name.c_str()), + "abc9_exe [options] -cwd "); + run(stringf("read_aiger -xaiger -wideports -module_name %s$abc9 -map %s/input.sym %s/output.aig", log_id(mod->name), tempdir_name.c_str(), tempdir_name.c_str()), + "read_aiger -xaiger -wideports -module_name $abc9 -map /input.sym /output.aig"); + run("abc9_ops -reintegrate"); + } + else + log("Don't call ABC as there is nothing to map.\n"); + + if (cleanup) { + log("Removing temp directory.\n"); + remove_directory(tempdir_name); + } + + active_design->selection().selected_modules.clear(); + } + + active_design->selection_stack.pop_back(); + } + } - run("abc9_ops -unbreak_scc"); + if (check_label("post")) + run("abc9_ops -unbreak_scc"); } } Abc9Pass; -- cgit v1.2.3 From 88f14b8bca811a3945aa642ccd50d22ffa0adcbd Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 8 Jan 2020 10:02:45 -0800 Subject: Cleanup --- passes/techmap/abc9.cc | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index f6627602b..ba5f97626 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -204,7 +204,7 @@ struct Abc9Pass : public ScriptPass if (help_mode) { run("foreach module in selection"); run(" write_xaiger -map /input.sym /input.xaig"); - run(" abc9_exe [options] -cwd "); + run(" abc9_exe -cwd [options]"); run(" read_aiger -xaiger -wideports -module_name $abc9 -map /input.sym /output.aig"); run(" abc9_ops -reintegrate"); } @@ -238,10 +238,8 @@ struct Abc9Pass : public ScriptPass active_design->scratchpad_get_int("write_xaiger.num_inputs"), num_outputs); if (num_outputs) { - run(stringf("%s -cwd %s", exe_cmd.str().c_str(), tempdir_name.c_str()), - "abc9_exe [options] -cwd "); - run(stringf("read_aiger -xaiger -wideports -module_name %s$abc9 -map %s/input.sym %s/output.aig", log_id(mod->name), tempdir_name.c_str(), tempdir_name.c_str()), - "read_aiger -xaiger -wideports -module_name $abc9 -map /input.sym /output.aig"); + run(stringf("%s -cwd %s", exe_cmd.str().c_str(), tempdir_name.c_str())); + run(stringf("read_aiger -xaiger -wideports -module_name %s$abc9 -map %s/input.sym %s/output.aig", log_id(mod->name), tempdir_name.c_str(), tempdir_name.c_str())); run("abc9_ops -reintegrate"); } else -- cgit v1.2.3 From a63e2508fcca395e795029d5c57c59acc63a9959 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 7 Jan 2020 12:52:03 -0800 Subject: Add RTLIL::constpad, init by yosys_setup(); use for abc9 --- kernel/rtlil.cc | 1 + kernel/rtlil.h | 2 ++ kernel/yosys.cc | 9 +++++++++ passes/cmds/scratchpad.cc | 25 ++++++++++++++++++------- passes/techmap/abc9.cc | 34 +++++++++------------------------- 5 files changed, 39 insertions(+), 32 deletions(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index ab4f4f377..f286d139f 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -46,6 +46,7 @@ IdString RTLIL::ID::Y; IdString RTLIL::ID::keep; IdString RTLIL::ID::whitebox; IdString RTLIL::ID::blackbox; +dict RTLIL::constpad; RTLIL::Const::Const() { diff --git a/kernel/rtlil.h b/kernel/rtlil.h index e5b24cc02..6251d265d 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -377,6 +377,8 @@ namespace RTLIL extern IdString blackbox; }; + extern dict constpad; + static inline std::string escape_id(std::string str) { if (str.size() > 0 && str[0] != '\\' && str[0] != '$') return "\\" + str; diff --git a/kernel/yosys.cc b/kernel/yosys.cc index 5018a4888..6c8427c19 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -524,6 +524,15 @@ void yosys_setup() PyRun_SimpleString("import sys"); #endif + RTLIL::constpad["abc9.script.default"] = "&scorr; &sweep; &dc2; &dch -f; &ps; &if {C} {W} {D} -v; &mfs"; + RTLIL::constpad["abc9.script.default.area"] = "&scorr; &sweep; &dc2; &dch -f; &ps; &if {C} {W} {D} -a -v; &mfs"; + RTLIL::constpad["abc9.script.default.fast"] = "&if {W} {D}"; + RTLIL::constpad["abc9.script.flow3"] = "&scorr; &sweep;" \ + "&if {C} {W} {D}; &save; &st; &syn2; &if {C} {W} {D} -v; &save; &load; "\ + "&st; &if {C} -g -K 6; &dch -f; &if {C} {W} {D} -v; &save; &load; "\ + "&st; &if {C} -g -K 6; &synch2; &if {C} {W} {D} -v; &save; &load; "\ + "&mfs"; + Pass::init_register(); yosys_design = new RTLIL::Design; yosys_celltypes.setup(); diff --git a/passes/cmds/scratchpad.cc b/passes/cmds/scratchpad.cc index 7ec55b78e..34ec0863a 100644 --- a/passes/cmds/scratchpad.cc +++ b/passes/cmds/scratchpad.cc @@ -70,8 +70,10 @@ struct ScratchpadPass : public Pass { { if (args[argidx] == "-get" && argidx+1 < args.size()) { string identifier = args[++argidx]; - if (design->scratchpad.count(identifier)){ + if (design->scratchpad.count(identifier)) { log("%s\n", design->scratchpad_get_string(identifier).c_str()); + } else if (RTLIL::constpad.count(identifier)) { + log("%s\n", RTLIL::constpad.at(identifier).c_str()); } else { log("\"%s\" not set\n", identifier.c_str()); } @@ -79,6 +81,8 @@ struct ScratchpadPass : public Pass { } if (args[argidx] == "-set" && argidx+2 < args.size()) { string identifier = args[++argidx]; + if (RTLIL::constpad.count(identifier)) + log_error("scratchpad entry \"%s\" is a global constant\n", identifier.c_str()); string value = args[++argidx]; if (value.front() == '\"' && value.back() == '\"') value = value.substr(1, value.size() - 2); design->scratchpad_set_string(identifier, value); @@ -92,8 +96,15 @@ struct ScratchpadPass : public Pass { if (args[argidx] == "-copy" && argidx+2 < args.size()) { string identifier_from = args[++argidx]; string identifier_to = args[++argidx]; - if (design->scratchpad.count(identifier_from) == 0) log_error("\"%s\" not set\n", identifier_from.c_str()); - string value = design->scratchpad_get_string(identifier_from); + string value; + if (design->scratchpad.count(identifier_from)) + value = design->scratchpad_get_string(identifier_from); + else if (RTLIL::constpad.count(identifier_from)) + value = RTLIL::constpad.at(identifier_from); + else + log_error("\"%s\" not set\n", identifier_from.c_str()); + if (RTLIL::constpad.count(identifier_to)) + log_error("scratchpad entry \"%s\" is a global constant\n", identifier_to.c_str()); design->scratchpad_set_string(identifier_to, value); continue; } @@ -102,10 +113,10 @@ struct ScratchpadPass : public Pass { string expected = args[++argidx]; if (expected.front() == '\"' && expected.back() == '\"') expected = expected.substr(1, expected.size() - 2); if (design->scratchpad.count(identifier) == 0) - log_error("Assertion failed: scratchpad entry '%s' is not defined\n", identifier.c_str()); + log_error("scratchpad entry '%s' is not defined\n", identifier.c_str()); string value = design->scratchpad_get_string(identifier); if (value != expected) { - log_error("Assertion failed: scratchpad entry '%s' is set to '%s' instead of the asserted '%s'\n", + log_error("scratchpad entry '%s' is set to '%s' instead of the asserted '%s'\n", identifier.c_str(), value.c_str(), expected.c_str()); } continue; @@ -113,13 +124,13 @@ struct ScratchpadPass : public Pass { if (args[argidx] == "-assert-set" && argidx+1 < args.size()) { string identifier = args[++argidx]; if (design->scratchpad.count(identifier) == 0) - log_error("Assertion failed: scratchpad entry '%s' is not defined\n", identifier.c_str()); + log_error("scratchpad entry '%s' is not defined\n", identifier.c_str()); continue; } if (args[argidx] == "-assert-unset" && argidx+1 < args.size()) { string identifier = args[++argidx]; if (design->scratchpad.count(identifier) > 0) - log_error("Assertion failed: scratchpad entry '%s' is defined\n", identifier.c_str()); + log_error("scratchpad entry '%s' is defined\n", identifier.c_str()); continue; } break; diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 8cb34e523..486b9313b 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -22,20 +22,6 @@ // 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" @@ -292,7 +278,8 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip } 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; + abc9_script += fast_mode ? RTLIL::constpad.at("abc9.script.default.fast") + : RTLIL::constpad.at("abc9.script.default"); } else log_abort(); @@ -305,11 +292,14 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip 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); + for (size_t pos = abc9_script.find("{C}"); pos != std::string::npos; pos = abc9_script.find("{C}", pos)) + abc9_script = abc9_script.substr(0, pos) + design->scratchpad_get_string("abc9.if.C", "") + 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 += stringf("&ps -l; &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++) @@ -758,18 +748,15 @@ struct Abc9Pass : public Pass { 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).c_str()); - log("\n"); - log(" for -lut/-luts (different LUT sizes):\n"); - log("%s\n", fold_abc9_cmd(ABC_COMMAND_LUT).c_str()); + log(" for -lut/-luts:\n"); + log("%s\n", fold_abc9_cmd(RTLIL::constpad.at("abc9.script.default")).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("%s\n", fold_abc9_cmd(RTLIL::constpad.at("abc9.script.default.fast")).c_str()); log("\n"); log(" -D \n"); log(" set delay target. the string {D} in the default scripts above is\n"); @@ -883,9 +870,6 @@ struct Abc9Pass : public Pass { } 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()) { -- cgit v1.2.3 From e230fd8afef6483d546cb38616e63b05d4d9b42a Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 7 Jan 2020 13:08:59 -0800 Subject: Fix {C} substitution --- passes/techmap/abc9.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 486b9313b..d03c24fdb 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -292,8 +292,11 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip 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); + std::string C; + if (design->scratchpad.count("abc9.if.C")) + C = "-C " + design->scratchpad_get_string("abc9.if.C"); for (size_t pos = abc9_script.find("{C}"); pos != std::string::npos; pos = abc9_script.find("{C}", pos)) - abc9_script = abc9_script.substr(0, pos) + design->scratchpad_get_string("abc9.if.C", "") + abc9_script.substr(pos+3); + abc9_script = abc9_script.substr(0, pos) + C + 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)) -- cgit v1.2.3 From 050f03f15b01855d9c3bd6e98c4c47ebab607d57 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 8 Jan 2020 10:55:44 -0800 Subject: abc9: add time as last script command --- passes/techmap/abc9.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index d03c24fdb..652ccafaf 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -302,7 +302,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip 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("&ps -l; &write -n %s/output.aig", tempdir_name.c_str()); + abc9_script += stringf("&ps -l; &write -n %s/output.aig; time", tempdir_name.c_str()); abc9_script = add_echos_to_abc9_cmd(abc9_script); for (size_t i = 0; i+1 < abc9_script.size(); i++) -- cgit v1.2.3 From 0696b7bc9e4bd86eadd0e0b92696392cc5dc6172 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 8 Jan 2020 12:11:55 -0800 Subject: abc9: if -script value is a file, then source it, otherwise commands --- passes/techmap/abc9.cc | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 652ccafaf..5bcbb1611 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -267,16 +267,21 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip 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 + if (check_file_exists(script_file)) abc9_script += stringf("source %s", script_file.c_str()); + else { + 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 += script_file; + } } else if (!lut_costs.empty() || !lut_file.empty()) { abc9_script += fast_mode ? RTLIL::constpad.at("abc9.script.default.fast") : RTLIL::constpad.at("abc9.script.default"); @@ -302,7 +307,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip 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("&ps -l; &write -n %s/output.aig; time", tempdir_name.c_str()); + abc9_script += stringf("; &ps -l; &write -n %s/output.aig; time", tempdir_name.c_str()); abc9_script = add_echos_to_abc9_cmd(abc9_script); for (size_t i = 0; i+1 < abc9_script.size(); i++) @@ -924,7 +929,7 @@ struct Abc9Pass : public Pass { extra_args(args, argidx, design); rewrite_filename(script_file); - if (!script_file.empty() && !is_absolute_path(script_file) && script_file[0] != '+') + if (!script_file.empty() && !is_absolute_path(script_file) && check_file_exists(script_file)) script_file = std::string(pwd) + "/" + script_file; // handle -lut / -luts args -- cgit v1.2.3 From 589ffead5cca63a55506eb3b291ffd025f0f9c0f Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 8 Jan 2020 12:13:06 -0800 Subject: scratchpad entry abc9.if.R to &if -R --- passes/techmap/abc9.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 5bcbb1611..3fdcc0e5c 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -303,6 +303,12 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip for (size_t pos = abc9_script.find("{C}"); pos != std::string::npos; pos = abc9_script.find("{C}", pos)) abc9_script = abc9_script.substr(0, pos) + C + abc9_script.substr(pos+3); + std::string R; + if (design->scratchpad.count("abc9.if.R")) + C = "-C " + design->scratchpad_get_string("abc9.if.R"); + for (size_t pos = abc9_script.find("{R}"); pos != std::string::npos; pos = abc9_script.find("{R}", pos)) + abc9_script = abc9_script.substr(0, pos) + C + 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")); -- cgit v1.2.3 From fbd9636e08b9a4ac5e58161ca6a6b5308cd795cb Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 8 Jan 2020 12:15:01 -0800 Subject: Add abc9.if.script.flow{,2} to constpad --- kernel/yosys.cc | 38 ++++++++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/kernel/yosys.cc b/kernel/yosys.cc index 6c8427c19..cd6955c3f 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -524,13 +524,39 @@ void yosys_setup() PyRun_SimpleString("import sys"); #endif - RTLIL::constpad["abc9.script.default"] = "&scorr; &sweep; &dc2; &dch -f; &ps; &if {C} {W} {D} -v; &mfs"; - RTLIL::constpad["abc9.script.default.area"] = "&scorr; &sweep; &dc2; &dch -f; &ps; &if {C} {W} {D} -a -v; &mfs"; - RTLIL::constpad["abc9.script.default.fast"] = "&if {W} {D}"; + RTLIL::constpad["abc9.script.default"] = "&scorr; &sweep; &dc2; &dch -f; &ps; &if {C} {W} {D} {R} -v; &mfs"; + RTLIL::constpad["abc9.script.default.area"] = "&scorr; &sweep; &dc2; &dch -f; &ps; &if {C} {W} {D} {R} -a -v; &mfs"; + RTLIL::constpad["abc9.script.default.fast"] = "&if {C} {W} {D} {R}"; + // Based on ABC's &flow + RTLIL::constpad["abc9.script.flow"] = "&scorr; &sweep;" \ + /* Round 1 */ \ + "&unmap; &if {C} {W} {D} {R}; &mfs;" \ + "&st; &dsdb;" \ + "&unmap; &if {C} {W} {D} {R}; &mfs;" \ + "&st; &syn2 -m -R 10; &dsdb;" \ + "&blut -a -K 6;" \ + "&unmap; &if {C} {W} {D} {R}; &mfs;" \ + /* Round 2 */ \ + "&st; &sopb;" \ + "&unmap; &if {C} {W} {D} {R}; &mfs;" \ + "&st; &dsdb;" \ + "&unmap; &if {C} {W} {D} {R}; &mfs;" \ + "&st; &syn2 -m -R 10; &dsdb;" \ + "&blut -a -K 6;" \ + "&unmap; &if {C} {W} {D} {R} -v; &mfs"; + // Based on ABC's &flow2 + RTLIL::constpad["abc9.script.flow2"] = "&scorr; &sweep;" \ + /* Comm1 */ "&synch2 -K 6 -C 500; &if -m {C} {W} {D} {R} -v; &mfs "/*"-W 4 -M 500 -C 7000"*/"; &save;"\ + /* Comm2 */ "&dch -C 500; &if -m {C} {W} {D} {R} -v; &mfs "/*"-W 4 -M 500 -C 7000"*/"; &save;"\ + "&load; &st; &sopb -R 10 -C 4; " \ + /* Comm3 */ "&synch2 -K 6 -C 500; &if -m "/*"-E 5"*/" {C} {W} {D} {R} -v; &mfs "/*"-W 4 -M 500 -C 7000"*/"; &save;"\ + /* Comm2 */ "&dch -C 500; &if -m {C} {W} {D} {R} -v; &mfs "/*"-W 4 -M 500 -C 7000"*/"; &save; "\ + "&load"; + // Based on ABC's &flow3 RTLIL::constpad["abc9.script.flow3"] = "&scorr; &sweep;" \ - "&if {C} {W} {D}; &save; &st; &syn2; &if {C} {W} {D} -v; &save; &load; "\ - "&st; &if {C} -g -K 6; &dch -f; &if {C} {W} {D} -v; &save; &load; "\ - "&st; &if {C} -g -K 6; &synch2; &if {C} {W} {D} -v; &save; &load; "\ + "&if {C} {W} {D}; &save; &st; &syn2; &if {C} {W} {D} {R} -v; &save; &load;"\ + "&st; &if {C} -g -K 6; &dch -f; &if {C} {W} {D} {R} -v; &save; &load;"\ + "&st; &if {C} -g -K 6; &synch2; &if {C} {W} {D} {R} -v; &save; &load;"\ "&mfs"; Pass::init_register(); -- cgit v1.2.3 From 5f7349f26d814b8bf32a0e532b6f0fbacedcae90 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 8 Jan 2020 15:40:37 -0800 Subject: write_xaiger: holes PIs only if whitebox --- backends/aiger/xaiger.cc | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 05e9678ee..4cbf49baf 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -626,9 +626,10 @@ struct XAigerWriter if (box_module->has_processes()) Pass::call_on_module(module->design, box_module, "proc"); + bool whitebox = box_module->get_bool_attribute("\\whitebox"); 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")) { + if (r.second && whitebox) { holes_cell = holes_module->addCell(cell->name, cell->type); holes_cell->parameters = cell->parameters; r.first->second = holes_cell; @@ -641,19 +642,23 @@ struct XAigerWriter 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 (w->port_input) { + if (whitebox) + 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 (holes_cell) - port_sig.append(holes_wire); - } + else + box_inputs += GetSize(w); + } if (w->port_output) { box_outputs += GetSize(w); for (int i = 0; i < GetSize(w); i++) { -- cgit v1.2.3 From 7532416cd7a8c3fb41592c6677a30e0dad53813c Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 8 Jan 2020 18:27:09 -0800 Subject: write_xaiger: cleanup holes generation --- backends/aiger/xaiger.cc | 169 +++++++++++++++++++++++++---------------------- 1 file changed, 89 insertions(+), 80 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 4cbf49baf..b6a7dbac2 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -407,7 +407,7 @@ struct XAigerWriter } if (w->port_output) { RTLIL::SigSpec rhs; - auto it = cell->connections_.find(w->name); + auto it = cell->connections_.find(port_name); if (it != cell->connections_.end()) { if (GetSize(it->second) < GetSize(w)) it->second.append(module->addWire(NEW_ID, GetSize(w)-GetSize(it->second))); @@ -614,7 +614,7 @@ struct XAigerWriter RTLIL::Module *holes_module = module->design->addModule("$__holes__"); log_assert(holes_module); - dict cell_cache; + dict> cell_cache; int port_id = 1; int box_count = 0; @@ -623,86 +623,94 @@ struct XAigerWriter log_assert(orig_box_module); IdString derived_name = orig_box_module->derive(module->design, cell->parameters); RTLIL::Module* box_module = module->design->module(derived_name); - if (box_module->has_processes()) - Pass::call_on_module(module->design, box_module, "proc"); - - bool whitebox = box_module->get_bool_attribute("\\whitebox"); - auto r = cell_cache.insert(std::make_pair(derived_name, nullptr)); - Cell *holes_cell = r.first->second; - if (r.second && whitebox) { - holes_cell = holes_module->addCell(cell->name, cell->type); - holes_cell->parameters = cell->parameters; - r.first->second = holes_cell; - } - int box_inputs = 0, box_outputs = 0; - for (auto port_name : box_ports.at(cell->type)) { - RTLIL::Wire *w = box_module->wire(port_name); - log_assert(w); - RTLIL::Wire *holes_wire; - RTLIL::SigSpec port_sig; - - if (w->port_input) { - if (whitebox) - 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); + auto r = cell_cache.insert(derived_name); + auto &v = r.first->second; + if (r.second) { + if (box_module->has_processes()) + Pass::call_on_module(module->design, box_module, "proc"); + + int box_inputs = 0, box_outputs = 0; + if (box_module->get_bool_attribute("\\whitebox")) { + auto holes_cell = holes_module->addCell(cell->name, derived_name); + for (auto port_name : box_ports.at(cell->type)) { + RTLIL::Wire *w = box_module->wire(port_name); + log_assert(w); + log_assert(!w->port_input || !w->port_output); + auto &conn = holes_cell->connections_[port_name]; + if (w->port_input) { + for (int i = 0; i < GetSize(w); i++) { + box_inputs++; + RTLIL::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); + } + conn.append(holes_wire); } - if (holes_cell) - port_sig.append(holes_wire); } - else - box_inputs += GetSize(w); - } - if (w->port_output) { - box_outputs += GetSize(w); - for (int i = 0; i < GetSize(w); i++) { - if (GetSize(w) == 1) - holes_wire = holes_module->addWire(stringf("$abc%s.%s", cell->name.c_str(), log_id(w->name))); - else - holes_wire = holes_module->addWire(stringf("$abc%s.%s[%d]", cell->name.c_str(), log_id(w->name), i)); - holes_wire->port_output = true; - holes_wire->port_id = port_id++; - holes_module->ports.push_back(holes_wire->name); - if (holes_cell) - port_sig.append(holes_wire); - else - holes_module->connect(holes_wire, State::S0); + else if (w->port_output) { + box_outputs += GetSize(w); + conn = holes_module->addWire(stringf("%s.%s", derived_name.c_str(), log_id(port_name)), GetSize(w)); + } } + + // For flops only, create an extra 1-bit input that drives a new wire + // called ".abc9_ff.Q" that is used below + if (box_module->get_bool_attribute("\\abc9_flop")) { + box_inputs++; + 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 *Q = holes_module->addWire(stringf("%s.abc9_ff.Q", cell->name.c_str())); + holes_module->connect(Q, holes_wire); + } + + std::get<0>(v) = holes_cell; } - 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); + else { + for (auto port_name : box_ports.at(cell->type)) { + RTLIL::Wire *w = box_module->wire(port_name); + log_assert(w); + log_assert(!w->port_input || !w->port_output); + if (w->port_input) + box_inputs += GetSize(w); + else if (w->port_output) + box_outputs += GetSize(w); + } + log_assert(std::get<0>(v) == nullptr); } + + std::get<1>(v) = box_inputs; + std::get<2>(v) = box_outputs; + std::get<3>(v) = box_module->attributes.at("\\abc9_box_id").as_int(); } - // For flops only, create an extra 1-bit input that drives a new wire - // called ".abc9_ff.Q" that is used below - if (box_module->get_bool_attribute("\\abc9_flop")) { - log_assert(holes_cell); - - box_inputs++; - Wire *holes_wire = holes_module->wire(stringf("\\i%d", box_inputs)); - if (!holes_wire) { - holes_wire = holes_module->addWire(stringf("\\i%d", box_inputs)); - holes_wire->port_input = true; - holes_wire->port_id = port_id++; - holes_module->ports.push_back(holes_wire->name); - } - Wire *w = holes_module->addWire(stringf("%s.abc9_ff.Q", cell->name.c_str())); - holes_module->connect(w, holes_wire); + auto holes_cell = std::get<0>(v); + for (auto port_name : box_ports.at(cell->type)) { + RTLIL::Wire *w = box_module->wire(port_name); + log_assert(w); + if (!w->port_output) + continue; + Wire *holes_wire = holes_module->addWire(stringf("$abc%s.%s", cell->name.c_str(), log_id(port_name)), GetSize(w)); + holes_wire->port_output = true; + holes_wire->port_id = port_id++; + holes_module->ports.push_back(holes_wire->name); + if (holes_cell) // whitebox + holes_module->connect(holes_wire, holes_cell->getPort(port_name)); + else // blackbox + holes_module->connect(holes_wire, Const(State::S0, GetSize(w))); } - write_h_buffer(box_inputs); - write_h_buffer(box_outputs); - write_h_buffer(box_module->attributes.at("\\abc9_box_id").as_int()); + write_h_buffer(std::get<1>(v)); + write_h_buffer(std::get<2>(v)); + write_h_buffer(std::get<3>(v)); write_h_buffer(box_count++); } @@ -762,14 +770,14 @@ struct XAigerWriter // created a new $paramod ... Pass::call_on_module(holes_module->design, holes_module, "flatten -wb; techmap; aigmap"); - dict replace; + dict replace; for (auto it = holes_module->cells_.begin(); it != holes_module->cells_.end(); ) { auto cell = it->second; if (cell->type.in("$_DFF_N_", "$_DFF_NN0_", "$_DFF_NN1_", "$_DFF_NP0_", "$_DFF_NP1_", "$_DFF_P_", "$_DFF_PN0_", "$_DFF_PN1", "$_DFF_PP0_", "$_DFF_PP1_")) { SigBit D = cell->getPort("\\D"); SigBit Q = cell->getPort("\\Q"); - // Remove the DFF cell from what needs to be a combinatorial box + // 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) @@ -777,10 +785,10 @@ struct XAigerWriter else port = holes_module->wire(stringf("$abc%s[%d]", Q.wire->name.c_str(), Q.offset)); log_assert(port); - // Prepare to replace "assign = DFF.Q;" with "assign = DFF.D;" - // in order to extract the combinatorial control logic that feeds the box + // Prepare to replace "assign = $_DFF_*.Q;" with "assign = $_DFF_*.D;" + // in order to extract just 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))); + replace.insert(std::make_pair(Q,D)); // Since `flatten` above would have created wires named ".Q", // extract the pre-techmap cell name auto pos = Q.wire->name.str().rfind("."); @@ -788,7 +796,7 @@ struct XAigerWriter IdString driver = Q.wire->name.substr(0, pos); // And drive the signal that was previously driven by "DFF.Q" (typically // used to implement clock-enable functionality) with the ".abc9_ff.Q" - // wire (which itself is driven an input port) we inserted above + // wire (which itself is driven by 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); @@ -799,10 +807,11 @@ struct XAigerWriter ++it; } + SigMap holes_sigmap(holes_module); for (auto &conn : holes_module->connections_) { - auto it = replace.find(conn); + auto it = replace.find(sigmap(conn.second)); if (it != replace.end()) - conn = it->second; + conn.second = it->second; } // Move into a new (temporary) design so that "clean" will only -- cgit v1.2.3 From 943ea4bf9ea34960bfce517450a8a466d1c54ed3 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 9 Jan 2020 08:55:36 -0800 Subject: read_aiger: do not double-count outputs for flops --- frontends/aiger/aigerparse.cc | 6 ------ 1 file changed, 6 deletions(-) diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc index bded2bfee..ae16a9e9b 100644 --- a/frontends/aiger/aigerparse.cc +++ b/frontends/aiger/aigerparse.cc @@ -756,12 +756,6 @@ void AigerReader::post_process() } for (uint32_t i = 0; i < flopNum; i++) { - 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 + i]; log_assert(d); log_assert(d->port_output); -- cgit v1.2.3 From d979648b7af4eb5fab042ac55ff2fb40e0c17a89 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 9 Jan 2020 10:02:19 -0800 Subject: read_aiger: more accurate debug message --- frontends/aiger/aigerparse.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc index ae16a9e9b..b4304a581 100644 --- a/frontends/aiger/aigerparse.cc +++ b/frontends/aiger/aigerparse.cc @@ -797,6 +797,7 @@ void AigerReader::post_process() wire->port_input = false; module->connect(wire, existing); } + log_debug(" -> %s\n", log_id(escaped_s)); } else if (index > 0) { std::string indexed_name = stringf("%s[%d]", escaped_s.c_str(), index); @@ -810,8 +811,8 @@ void AigerReader::post_process() module->connect(wire, existing); wire->port_input = false; } + log_debug(" -> %s\n", log_id(indexed_name)); } - log_debug(" -> %s\n", log_id(wire)); } else if (type == "output") { log_assert(static_cast(variable + co_count) < outputs.size()); @@ -833,6 +834,7 @@ void AigerReader::post_process() module->connect(wire, existing); wire = existing; } + log_debug(" -> %s\n", log_id(escaped_s)); } else if (index > 0) { std::string indexed_name = stringf("%s[%d]", escaped_s.c_str(), index); @@ -846,8 +848,8 @@ void AigerReader::post_process() module->connect(wire, existing); wire->port_output = false; } + log_debug(" -> %s\n", log_id(indexed_name)); } - log_debug(" -> %s\n", log_id(wire)); int init; mf >> init; if (init < 2) -- cgit v1.2.3 From 4e396ee7a39682cb859aa64a89b40a149cb4148b Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 9 Jan 2020 11:21:03 -0800 Subject: abc9_ops: fix reintegration by removing optimised-away boxes --- passes/techmap/abc9_ops.cc | 106 +++++++++++++++++++++------------------------ 1 file changed, 50 insertions(+), 56 deletions(-) diff --git a/passes/techmap/abc9_ops.cc b/passes/techmap/abc9_ops.cc index 721a33f09..7c7208711 100644 --- a/passes/techmap/abc9_ops.cc +++ b/passes/techmap/abc9_ops.cc @@ -488,11 +488,13 @@ void reintegrate(RTLIL::Module *module) } } - 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; + std::vector boxes; + for (auto cell : module->cells().to_vector()) { + if (cell->type.in(ID($_AND_), ID($_NOT_), ID($__ABC9_FF_))) + module->remove(cell); + else if (cell->attributes.erase("\\abc9_box_seq")) + boxes.emplace_back(cell); + } dict> bit_drivers, bit_users; TopoSort toposort; @@ -504,7 +506,6 @@ void reintegrate(RTLIL::Module *module) { 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); @@ -536,7 +537,7 @@ void reintegrate(RTLIL::Module *module) 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::Cell *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")); @@ -548,10 +549,9 @@ void reintegrate(RTLIL::Module *module) } continue; } - cell_stats[mapped_cell->type]++; - RTLIL::Cell *existing_cell = nullptr; if (mapped_cell->type.in(ID($lut), ID($__ABC9_FF_))) { + // Convert buffer into direct connection if (mapped_cell->type == ID($lut) && GetSize(mapped_cell->getPort(ID::A)) == 1 && mapped_cell->getParam(ID(LUT)) == RTLIL::Const::from_string("01")) { @@ -561,22 +561,48 @@ void reintegrate(RTLIL::Module *module) log_abort(); continue; } - cell = module->addCell(remap_name(mapped_cell->name), mapped_cell->type); + RTLIL::Cell *cell = module->addCell(remap_name(mapped_cell->name), mapped_cell->type); + cell->parameters = mapped_cell->parameters; + cell->attributes = mapped_cell->attributes; + + for (auto &mapped_conn : mapped_cell->connections()) { + RTLIL::SigSpec newsig; + for (auto c : mapped_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(mapped_conn.first, newsig); + + if (cell->input(mapped_conn.first)) { + for (auto i : newsig) + bit2sinks[i].push_back(cell); + for (auto i : mapped_conn.second) + bit_users[i].insert(mapped_cell->name); + } + if (cell->output(mapped_conn.first)) + for (auto i : mapped_conn.second) + bit_drivers[i].insert(mapped_cell->name); + } } else { - existing_cell = module->cell(mapped_cell->name); + RTLIL::Cell *existing_cell = module->cell(mapped_cell->name); log_assert(existing_cell); + log_assert(mapped_cell->type.begins_with("$__boxid")); - if (mapped_cell->type.begins_with("$__boxid")) { - auto type = box_lookup.at(mapped_cell->type, IdString()); - if (type == IdString()) - log_error("No module with abc9_box_id = %s found.\n", mapped_cell->type.c_str() + strlen("$__boxid")); - mapped_cell->type = type; - } - cell = module->addCell(remap_name(mapped_cell->name), mapped_cell->type); - } + auto type = box_lookup.at(mapped_cell->type, IdString()); + if (type == IdString()) + log_error("No module with abc9_box_id = %s found.\n", mapped_cell->type.c_str() + strlen("$__boxid")); + mapped_cell->type = type; + + RTLIL::Cell *cell = module->addCell(remap_name(mapped_cell->name), mapped_cell->type); + cell->parameters = existing_cell->parameters; + cell->attributes = existing_cell->attributes; + module->swap_names(cell, existing_cell); - if (existing_cell) { auto it = mapped_cell->connections_.find("\\i"); log_assert(it != mapped_cell->connections_.end()); SigSpec inputs = std::move(it->second); @@ -635,45 +661,13 @@ void reintegrate(RTLIL::Module *module) bit2sinks[i].push_back(cell); } } - else { - for (auto &mapped_conn : mapped_cell->connections()) { - RTLIL::SigSpec newsig; - for (auto c : mapped_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(mapped_conn.first, newsig); - - if (cell->input(mapped_conn.first)) { - for (auto i : newsig) - bit2sinks[i].push_back(cell); - for (auto i : mapped_conn.second) - bit_users[i].insert(mapped_cell->name); - } - if (cell->output(mapped_conn.first)) - for (auto i : mapped_conn.second) - bit_drivers[i].insert(mapped_cell->name); - } - } - 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; - } + cell_stats[mapped_cell->type]++; } + for (auto cell : boxes) + module->remove(cell); + // Copy connections (and rename) from mapped_mod to module for (auto conn : mapped_mod->connections()) { if (!conn.first.is_fully_const()) { -- cgit v1.2.3 From 3fa374a69886c3a7ef8d52a2bbb67ea740e130dd Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 9 Jan 2020 21:22:54 +0100 Subject: Add fminit pass Signed-off-by: Clifford Wolf --- passes/sat/Makefile.inc | 1 + passes/sat/fminit.cc | 197 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 198 insertions(+) create mode 100644 passes/sat/fminit.cc diff --git a/passes/sat/Makefile.inc b/passes/sat/Makefile.inc index fc3ac879e..4bb4b0edc 100644 --- a/passes/sat/Makefile.inc +++ b/passes/sat/Makefile.inc @@ -12,4 +12,5 @@ OBJS += passes/sat/supercover.o OBJS += passes/sat/fmcombine.o OBJS += passes/sat/mutate.o OBJS += passes/sat/cutpoint.o +OBJS += passes/sat/fminit.o diff --git a/passes/sat/fminit.cc b/passes/sat/fminit.cc new file mode 100644 index 000000000..f3f00b382 --- /dev/null +++ b/passes/sat/fminit.cc @@ -0,0 +1,197 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 Clifford Wolf + * + * 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/yosys.h" +#include "kernel/sigtools.h" + +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + +struct FminitPass : public Pass { + FminitPass() : Pass("fminit", "set init values/sequences for formal") { } + void help() YS_OVERRIDE + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" fminit [options] \n"); + log("\n"); + log("This pass creates init constraints (for example for reset sequences) in a formal\n"); + log("model.\n"); + log("\n"); + log(" -seq \n"); + log(" Set sequence using comma-separated list of values, use 'z for\n"); + log(" unconstrained bits. The last value is used for the remainder of the\n"); + log(" trace.\n"); + log("\n"); + log(" -set \n"); + log(" Add constant value constraint\n"); + log("\n"); + log(" -posedge \n"); + log(" -negedge \n"); + log(" Set clock for init sequences\n"); + log("\n"); + } + void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE + { + vector>> initdata; + vector> setdata; + string clocksignal; + bool clockedge; + + log_header(design, "Executing FMINIT pass.\n"); + + size_t argidx; + for (argidx = 1; argidx < args.size(); argidx++) + { + // if (args[argidx] == "-o" && argidx+1 < args.size()) { + // filename = args[++argidx]; + // continue; + // } + if (args[argidx] == "-seq" && argidx+2 < args.size()) { + string lhs = args[++argidx]; + string rhs = args[++argidx]; + initdata.push_back(make_pair(lhs, split_tokens(rhs, ","))); + continue; + } + if (args[argidx] == "-set" && argidx+2 < args.size()) { + string lhs = args[++argidx]; + string rhs = args[++argidx]; + setdata.push_back(make_pair(lhs, rhs)); + continue; + } + if (args[argidx] == "-posedge" && argidx+1 < args.size()) { + clocksignal = args[++argidx]; + clockedge = true; + continue; + } + if (args[argidx] == "-negedge" && argidx+1 < args.size()) { + clocksignal = args[++argidx]; + clockedge = true; + continue; + } + break; + } + extra_args(args, argidx, design); + + Module *module = nullptr; + + for (auto mod : design->selected_modules()) { + if (module != nullptr) + log_error("'fminit' requires exactly one module to be selected.\n"); + module = mod; + } + + if (module == nullptr) + log_error("'fminit' requires exactly one module to be selected.\n"); + + SigSpec clksig; + if (!clocksignal.empty()) { + if (!SigSpec::parse(clksig, module, clocksignal)) + log_error("Error parsing expression '%s'.\n", clocksignal.c_str()); + } + + for (auto &it : setdata) + { + SigSpec lhs, rhs; + + if (!SigSpec::parse(lhs, module, it.first)) + log_error("Error parsing expression '%s'.\n", it.first.c_str()); + + if (!SigSpec::parse_rhs(lhs, rhs, module, it.second)) + log_error("Error parsing expression '%s'.\n", it.second.c_str()); + + SigSpec final_lhs, final_rhs; + + for (int i = 0; i < GetSize(rhs); i++) + if (rhs[i] != State::Sz) { + final_lhs.append(lhs[i]); + final_rhs.append(rhs[i]); + } + + if (!final_lhs.empty()) { + SigSpec eq = module->Eq(NEW_ID, final_lhs, final_rhs); + module->addAssume(NEW_ID, eq, State::S1); + } + } + + vector ctrlsig; + vector ctrlsig_latched; + + for (auto &it : initdata) + { + SigSpec lhs, rhs; + + if (!SigSpec::parse(lhs, module, it.first)) + log_error("Error parsing expression '%s'.\n", it.first.c_str()); + + for (int i = 0; i < GetSize(it.second); i++) + { + if (i >= GetSize(ctrlsig)) + { + SigSpec insig = i > 0 ? ctrlsig.at(i-1) : State::S0; + + Wire *outwire = module->addWire(NEW_ID); + outwire->attributes[ID(init)] = i > 0 ? State::S0 : State::S1; + + if (clksig.empty()) + module->addFf(NEW_ID, insig, outwire); + else + module->addDff(NEW_ID, clksig, insig, outwire, clockedge); + + ctrlsig.push_back(outwire); + ctrlsig_latched.push_back(SigSpec()); + } + + if (i+1 == GetSize(it.second) && ctrlsig_latched[i].empty()) + { + Wire *ffwire = module->addWire(NEW_ID); + ffwire->attributes[ID(init)] = State::S0; + SigSpec outsig = module->Or(NEW_ID, ffwire, ctrlsig[i]); + + if (clksig.empty()) + module->addFf(NEW_ID, outsig, ffwire); + else + module->addDff(NEW_ID, clksig, outsig, ffwire, clockedge); + + ctrlsig_latched[i] = outsig; + } + + SigSpec ctrl = i+1 == GetSize(it.second) ? ctrlsig_latched[i] : ctrlsig[i]; + + SigSpec final_lhs, final_rhs; + + if (!SigSpec::parse_rhs(lhs, rhs, module, it.second[i])) + log_error("Error parsing expression '%s'.\n", it.second[i].c_str()); + + for (int i = 0; i < GetSize(rhs); i++) + if (rhs[i] != State::Sz) { + final_lhs.append(lhs[i]); + final_rhs.append(rhs[i]); + } + + if (!final_lhs.empty()) { + SigSpec eq = module->Eq(NEW_ID, final_lhs, final_rhs); + module->addAssume(NEW_ID, eq, ctrl); + } + } + } + } +} FminitPass; + +PRIVATE_NAMESPACE_END -- cgit v1.2.3 From cd92a974f4cf8d4db74d504c38e51ce043e02403 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 9 Jan 2020 21:36:34 +0100 Subject: Add Pass::on_register() and Pass::on_shutdown() Signed-off-by: Clifford Wolf --- kernel/register.cc | 15 +++++++++++++++ kernel/register.h | 3 +++ kernel/yosys.cc | 3 ++- 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/kernel/register.cc b/kernel/register.cc index 37f2e5e1b..5d0fb3c8c 100644 --- a/kernel/register.cc +++ b/kernel/register.cc @@ -114,20 +114,35 @@ void Pass::run_register() void Pass::init_register() { + vector added_passes; while (first_queued_pass) { + added_passes.push_back(first_queued_pass); first_queued_pass->run_register(); first_queued_pass = first_queued_pass->next_queued_pass; } + for (auto added_pass : added_passes) + added_pass->on_register(); } void Pass::done_register() { + for (auto &it : pass_register) + it.second->on_shutdown(); + frontend_register.clear(); pass_register.clear(); backend_register.clear(); log_assert(first_queued_pass == NULL); } +void Pass::on_register() +{ +} + +void Pass::on_shutdown() +{ +} + Pass::~Pass() { } diff --git a/kernel/register.h b/kernel/register.h index 85d552f0d..821faff3e 100644 --- a/kernel/register.h +++ b/kernel/register.h @@ -62,6 +62,9 @@ struct Pass virtual void run_register(); static void init_register(); static void done_register(); + + virtual void on_register(); + virtual void on_shutdown(); }; struct ScriptPass : Pass diff --git a/kernel/yosys.cc b/kernel/yosys.cc index 5018a4888..8190d8902 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -544,6 +544,8 @@ void yosys_shutdown() already_shutdown = true; log_pop(); + Pass::done_register(); + delete yosys_design; yosys_design = NULL; @@ -553,7 +555,6 @@ void yosys_shutdown() log_errfile = NULL; log_files.clear(); - Pass::done_register(); yosys_celltypes.clear(); #ifdef YOSYS_ENABLE_TCL -- cgit v1.2.3 From ccc83d99bafc74f7ec62111bf61d962ca0a0771d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 9 Jan 2020 21:37:28 +0100 Subject: Bump version Signed-off-by: Clifford Wolf --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index fd95219ee..374d42f6f 100644 --- a/Makefile +++ b/Makefile @@ -115,7 +115,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+932 +YOSYS_VER := 0.9+1706 GIT_REV := $(shell cd $(YOSYS_SRC) && git rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o -- cgit v1.2.3 From 67c9c41f7e566f5604a3e38e7ad402d6b5c80fd8 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 9 Jan 2020 17:10:54 -0800 Subject: Move abc9.* constpad entries to Abc9Pass::on_register() --- kernel/yosys.cc | 35 ----------------------------------- passes/techmap/abc9.cc | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 35 deletions(-) diff --git a/kernel/yosys.cc b/kernel/yosys.cc index 6956cbdc3..8190d8902 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -524,41 +524,6 @@ void yosys_setup() PyRun_SimpleString("import sys"); #endif - RTLIL::constpad["abc9.script.default"] = "&scorr; &sweep; &dc2; &dch -f; &ps; &if {C} {W} {D} {R} -v; &mfs"; - RTLIL::constpad["abc9.script.default.area"] = "&scorr; &sweep; &dc2; &dch -f; &ps; &if {C} {W} {D} {R} -a -v; &mfs"; - RTLIL::constpad["abc9.script.default.fast"] = "&if {C} {W} {D} {R}"; - // Based on ABC's &flow - RTLIL::constpad["abc9.script.flow"] = "&scorr; &sweep;" \ - /* Round 1 */ \ - "&unmap; &if {C} {W} {D} {R}; &mfs;" \ - "&st; &dsdb;" \ - "&unmap; &if {C} {W} {D} {R}; &mfs;" \ - "&st; &syn2 -m -R 10; &dsdb;" \ - "&blut -a -K 6;" \ - "&unmap; &if {C} {W} {D} {R}; &mfs;" \ - /* Round 2 */ \ - "&st; &sopb;" \ - "&unmap; &if {C} {W} {D} {R}; &mfs;" \ - "&st; &dsdb;" \ - "&unmap; &if {C} {W} {D} {R}; &mfs;" \ - "&st; &syn2 -m -R 10; &dsdb;" \ - "&blut -a -K 6;" \ - "&unmap; &if {C} {W} {D} {R} -v; &mfs"; - // Based on ABC's &flow2 - RTLIL::constpad["abc9.script.flow2"] = "&scorr; &sweep;" \ - /* Comm1 */ "&synch2 -K 6 -C 500; &if -m {C} {W} {D} {R} -v; &mfs "/*"-W 4 -M 500 -C 7000"*/"; &save;"\ - /* Comm2 */ "&dch -C 500; &if -m {C} {W} {D} {R} -v; &mfs "/*"-W 4 -M 500 -C 7000"*/"; &save;"\ - "&load; &st; &sopb -R 10 -C 4; " \ - /* Comm3 */ "&synch2 -K 6 -C 500; &if -m "/*"-E 5"*/" {C} {W} {D} {R} -v; &mfs "/*"-W 4 -M 500 -C 7000"*/"; &save;"\ - /* Comm2 */ "&dch -C 500; &if -m {C} {W} {D} {R} -v; &mfs "/*"-W 4 -M 500 -C 7000"*/"; &save; "\ - "&load"; - // Based on ABC's &flow3 - RTLIL::constpad["abc9.script.flow3"] = "&scorr; &sweep;" \ - "&if {C} {W} {D}; &save; &st; &syn2; &if {C} {W} {D} {R} -v; &save; &load;"\ - "&st; &if {C} -g -K 6; &dch -f; &if {C} {W} {D} {R} -v; &save; &load;"\ - "&st; &if {C} -g -K 6; &synch2; &if {C} {W} {D} {R} -v; &save; &load;"\ - "&mfs"; - Pass::init_register(); yosys_design = new RTLIL::Design; yosys_celltypes.setup(); diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 3fdcc0e5c..3f05494c7 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -735,6 +735,43 @@ clone_lut: struct Abc9Pass : public Pass { Abc9Pass() : Pass("abc9", "use ABC9 for technology mapping") { } + void on_register() YS_OVERRIDE + { + RTLIL::constpad["abc9.script.default"] = "&scorr; &sweep; &dc2; &dch -f; &ps; &if {C} {W} {D} {R} -v; &mfs"; + RTLIL::constpad["abc9.script.default.area"] = "&scorr; &sweep; &dc2; &dch -f; &ps; &if {C} {W} {D} {R} -a -v; &mfs"; + RTLIL::constpad["abc9.script.default.fast"] = "&if {C} {W} {D} {R}"; + // Based on ABC's &flow + RTLIL::constpad["abc9.script.flow"] = "&scorr; &sweep;" \ + /* Round 1 */ \ + "&unmap; &if {C} {W} {D} {R}; &mfs;" \ + "&st; &dsdb;" \ + "&unmap; &if {C} {W} {D} {R}; &mfs;" \ + "&st; &syn2 -m -R 10; &dsdb;" \ + "&blut -a -K 6;" \ + "&unmap; &if {C} {W} {D} {R}; &mfs;" \ + /* Round 2 */ \ + "&st; &sopb;" \ + "&unmap; &if {C} {W} {D} {R}; &mfs;" \ + "&st; &dsdb;" \ + "&unmap; &if {C} {W} {D} {R}; &mfs;" \ + "&st; &syn2 -m -R 10; &dsdb;" \ + "&blut -a -K 6;" \ + "&unmap; &if {C} {W} {D} {R} -v; &mfs"; + // Based on ABC's &flow2 + RTLIL::constpad["abc9.script.flow2"] = "&scorr; &sweep;" \ + /* Comm1 */ "&synch2 -K 6 -C 500; &if -m {C} {W} {D} {R} -v; &mfs "/*"-W 4 -M 500 -C 7000"*/"; &save;"\ + /* Comm2 */ "&dch -C 500; &if -m {C} {W} {D} {R} -v; &mfs "/*"-W 4 -M 500 -C 7000"*/"; &save;"\ + "&load; &st; &sopb -R 10 -C 4; " \ + /* Comm3 */ "&synch2 -K 6 -C 500; &if -m "/*"-E 5"*/" {C} {W} {D} {R} -v; &mfs "/*"-W 4 -M 500 -C 7000"*/"; &save;"\ + /* Comm2 */ "&dch -C 500; &if -m {C} {W} {D} {R} -v; &mfs "/*"-W 4 -M 500 -C 7000"*/"; &save; "\ + "&load"; + // Based on ABC's &flow3 + RTLIL::constpad["abc9.script.flow3"] = "&scorr; &sweep;" \ + "&if {C} {W} {D}; &save; &st; &syn2; &if {C} {W} {D} {R} -v; &save; &load;"\ + "&st; &if {C} -g -K 6; &dch -f; &if {C} {W} {D} {R} -v; &save; &load;"\ + "&st; &if {C} -g -K 6; &synch2; &if {C} {W} {D} {R} -v; &save; &load;"\ + "&mfs"; + } void help() YS_OVERRIDE { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| -- cgit v1.2.3 From ef3e84aac97565caff1f7d9bbce459d1592318ad Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 9 Jan 2020 17:11:09 -0800 Subject: Revert "abc9: if -script value is a file, then source it, otherwise commands" This reverts commit 0696b7bc9e4bd86eadd0e0b92696392cc5dc6172. --- passes/techmap/abc9.cc | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 3f05494c7..e8988f699 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -267,21 +267,16 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip abc9_script += stringf("&read %s/input.xaig; &ps; ", tempdir_name.c_str()); if (!script_file.empty()) { - if (check_file_exists(script_file)) + 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 (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 += script_file; - } } else if (!lut_costs.empty() || !lut_file.empty()) { abc9_script += fast_mode ? RTLIL::constpad.at("abc9.script.default.fast") : RTLIL::constpad.at("abc9.script.default"); @@ -313,7 +308,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip 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("; &ps -l; &write -n %s/output.aig; time", tempdir_name.c_str()); + abc9_script += stringf("&ps -l; &write -n %s/output.aig; time", tempdir_name.c_str()); abc9_script = add_echos_to_abc9_cmd(abc9_script); for (size_t i = 0; i+1 < abc9_script.size(); i++) @@ -972,7 +967,7 @@ struct Abc9Pass : public Pass { extra_args(args, argidx, design); rewrite_filename(script_file); - if (!script_file.empty() && !is_absolute_path(script_file) && check_file_exists(script_file)) + if (!script_file.empty() && !is_absolute_path(script_file) && script_file[0] != '+') script_file = std::string(pwd) + "/" + script_file; // handle -lut / -luts args -- cgit v1.2.3 From ca70f9650336b4e58a13ab119e098f6494549f27 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 9 Jan 2020 17:17:47 -0800 Subject: abc9.script.* constpad entries to start with '+' --- passes/techmap/abc9.cc | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index e8988f699..7039d4dd8 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -278,8 +278,8 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip } else abc9_script += stringf("source %s", script_file.c_str()); } else if (!lut_costs.empty() || !lut_file.empty()) { - abc9_script += fast_mode ? RTLIL::constpad.at("abc9.script.default.fast") - : RTLIL::constpad.at("abc9.script.default"); + abc9_script += fast_mode ? RTLIL::constpad.at("abc9.script.default.fast").substr(1,std::string::npos) + : RTLIL::constpad.at("abc9.script.default").substr(1,std::string::npos); } else log_abort(); @@ -732,11 +732,11 @@ struct Abc9Pass : public Pass { Abc9Pass() : Pass("abc9", "use ABC9 for technology mapping") { } void on_register() YS_OVERRIDE { - RTLIL::constpad["abc9.script.default"] = "&scorr; &sweep; &dc2; &dch -f; &ps; &if {C} {W} {D} {R} -v; &mfs"; - RTLIL::constpad["abc9.script.default.area"] = "&scorr; &sweep; &dc2; &dch -f; &ps; &if {C} {W} {D} {R} -a -v; &mfs"; - RTLIL::constpad["abc9.script.default.fast"] = "&if {C} {W} {D} {R}"; + RTLIL::constpad["abc9.script.default"] = "+&scorr; &sweep; &dc2; &dch -f; &ps; &if {C} {W} {D} {R} -v; &mfs"; + RTLIL::constpad["abc9.script.default.area"] = "+&scorr; &sweep; &dc2; &dch -f; &ps; &if {C} {W} {D} {R} -a -v; &mfs"; + RTLIL::constpad["abc9.script.default.fast"] = "+&if {C} {W} {D} {R}"; // Based on ABC's &flow - RTLIL::constpad["abc9.script.flow"] = "&scorr; &sweep;" \ + RTLIL::constpad["abc9.script.flow"] = "+&scorr; &sweep;" \ /* Round 1 */ \ "&unmap; &if {C} {W} {D} {R}; &mfs;" \ "&st; &dsdb;" \ @@ -753,7 +753,7 @@ struct Abc9Pass : public Pass { "&blut -a -K 6;" \ "&unmap; &if {C} {W} {D} {R} -v; &mfs"; // Based on ABC's &flow2 - RTLIL::constpad["abc9.script.flow2"] = "&scorr; &sweep;" \ + RTLIL::constpad["abc9.script.flow2"] = "+&scorr; &sweep;" \ /* Comm1 */ "&synch2 -K 6 -C 500; &if -m {C} {W} {D} {R} -v; &mfs "/*"-W 4 -M 500 -C 7000"*/"; &save;"\ /* Comm2 */ "&dch -C 500; &if -m {C} {W} {D} {R} -v; &mfs "/*"-W 4 -M 500 -C 7000"*/"; &save;"\ "&load; &st; &sopb -R 10 -C 4; " \ @@ -761,7 +761,7 @@ struct Abc9Pass : public Pass { /* Comm2 */ "&dch -C 500; &if -m {C} {W} {D} {R} -v; &mfs "/*"-W 4 -M 500 -C 7000"*/"; &save; "\ "&load"; // Based on ABC's &flow3 - RTLIL::constpad["abc9.script.flow3"] = "&scorr; &sweep;" \ + RTLIL::constpad["abc9.script.flow3"] = "+&scorr; &sweep;" \ "&if {C} {W} {D}; &save; &st; &syn2; &if {C} {W} {D} {R} -v; &save; &load;"\ "&st; &if {C} -g -K 6; &dch -f; &if {C} {W} {D} {R} -v; &save; &load;"\ "&st; &if {C} -g -K 6; &synch2; &if {C} {W} {D} {R} -v; &save; &load;"\ -- cgit v1.2.3 From 32946a402de068ba052e0af9564959cf746fbf91 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 9 Jan 2020 17:35:13 -0800 Subject: abc9: start post-fix with semicolon --- passes/techmap/abc9.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 7039d4dd8..fb0c547a3 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -308,7 +308,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip 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("&ps -l; &write -n %s/output.aig; time", tempdir_name.c_str()); + abc9_script += stringf("; &ps -l; &write -n %s/output.aig; time", tempdir_name.c_str()); abc9_script = add_echos_to_abc9_cmd(abc9_script); for (size_t i = 0; i+1 < abc9_script.size(); i++) -- cgit v1.2.3 From 8b6309747b302f11046be029d5f224ba891d0461 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 9 Jan 2020 17:49:56 -0800 Subject: Add '-v' to &if for abc9.script.default.fast --- passes/techmap/abc9.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index fb0c547a3..aed662fc5 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -734,7 +734,7 @@ struct Abc9Pass : public Pass { { RTLIL::constpad["abc9.script.default"] = "+&scorr; &sweep; &dc2; &dch -f; &ps; &if {C} {W} {D} {R} -v; &mfs"; RTLIL::constpad["abc9.script.default.area"] = "+&scorr; &sweep; &dc2; &dch -f; &ps; &if {C} {W} {D} {R} -a -v; &mfs"; - RTLIL::constpad["abc9.script.default.fast"] = "+&if {C} {W} {D} {R}"; + RTLIL::constpad["abc9.script.default.fast"] = "+&if {C} {W} {D} {R} -v"; // Based on ABC's &flow RTLIL::constpad["abc9.script.flow"] = "+&scorr; &sweep;" \ /* Round 1 */ \ -- cgit v1.2.3 From e378902f939c24cb8f6cbff29c3f508a4655f3ab Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 9 Jan 2020 18:16:58 -0800 Subject: Tune abc9.script.flow --- passes/techmap/abc9.cc | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index aed662fc5..b828404bc 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -737,21 +737,29 @@ struct Abc9Pass : public Pass { RTLIL::constpad["abc9.script.default.fast"] = "+&if {C} {W} {D} {R} -v"; // Based on ABC's &flow RTLIL::constpad["abc9.script.flow"] = "+&scorr; &sweep;" \ + "&dch -C 500;" \ /* Round 1 */ \ - "&unmap; &if {C} {W} {D} {R}; &mfs;" \ + /* Map 1 */ "&unmap; &if {C} {W} {D} {R} -v; &save; &load; &mfs;" \ "&st; &dsdb;" \ - "&unmap; &if {C} {W} {D} {R}; &mfs;" \ + /* Map 2 */ "&unmap; &if {C} {W} {D} {R} -v; &save; &load; &mfs;" \ "&st; &syn2 -m -R 10; &dsdb;" \ "&blut -a -K 6;" \ - "&unmap; &if {C} {W} {D} {R}; &mfs;" \ + /* Map 3 */ "&unmap; &if {C} {W} {D} {R} -v; &save; &load; &mfs;" \ /* Round 2 */ \ "&st; &sopb;" \ - "&unmap; &if {C} {W} {D} {R}; &mfs;" \ + /* Map 1 */ "&unmap; &if {C} {W} {D} {R} -v; &save; &load; &mfs;" \ "&st; &dsdb;" \ - "&unmap; &if {C} {W} {D} {R}; &mfs;" \ + /* Map 2 */ "&unmap; &if {C} {W} {D} {R} -v; &save; &load; &mfs;" \ "&st; &syn2 -m -R 10; &dsdb;" \ "&blut -a -K 6;" \ - "&unmap; &if {C} {W} {D} {R} -v; &mfs"; + /* Map 3 */ "&unmap; &if {C} {W} {D} {R} -v; &save; &load; &mfs;" \ + /* Round 3 */ \ + /* Map 1 */ "&unmap; &if {C} {W} {D} {R} -v; &save; &load; &mfs;" \ + "&st; &dsdb;" \ + /* Map 2 */ "&unmap; &if {C} {W} {D} {R} -v; &save; &load; &mfs;" \ + "&st; &syn2 -m -R 10; &dsdb;" \ + "&blut -a -K 6;" \ + /* Map 3 */ "&unmap; &if {C} {W} {D} {R} -v; &save; &load; &mfs;"; // Based on ABC's &flow2 RTLIL::constpad["abc9.script.flow2"] = "+&scorr; &sweep;" \ /* Comm1 */ "&synch2 -K 6 -C 500; &if -m {C} {W} {D} {R} -v; &mfs "/*"-W 4 -M 500 -C 7000"*/"; &save;"\ -- cgit v1.2.3 From a10016ccc57638aa837acd76fc93f296eda83b32 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 9 Jan 2020 18:17:06 -0800 Subject: Add abc9 sanity test --- tests/techmap/abc9.ys | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 tests/techmap/abc9.ys diff --git a/tests/techmap/abc9.ys b/tests/techmap/abc9.ys new file mode 100644 index 000000000..20f263da8 --- /dev/null +++ b/tests/techmap/abc9.ys @@ -0,0 +1,40 @@ +read_verilog < Date: Fri, 10 Jan 2020 12:33:58 +0100 Subject: Export wire properties as well in EDIF --- backends/edif/edif.cc | 64 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 38 insertions(+), 26 deletions(-) diff --git a/backends/edif/edif.cc b/backends/edif/edif.cc index 6d9469538..1bfd4a335 100644 --- a/backends/edif/edif.cc +++ b/backends/edif/edif.cc @@ -300,13 +300,33 @@ struct EdifBackend : public Backend { *f << stringf(" (library DESIGN\n"); *f << stringf(" (edifLevel 0)\n"); *f << stringf(" (technology (numberDefinition))\n"); + + auto add_prop = [&](IdString name, Const val) { + if ((val.flags & RTLIL::CONST_FLAG_STRING) != 0) + *f << stringf("\n (property %s (string \"%s\"))", EDIF_DEF(name), val.decode_string().c_str()); + else if (val.bits.size() <= 32 && RTLIL::SigSpec(val).is_fully_def()) + *f << stringf("\n (property %s (integer %u))", EDIF_DEF(name), val.as_int()); + else { + std::string hex_string = ""; + for (size_t i = 0; i < val.bits.size(); i += 4) { + int digit_value = 0; + if (i+0 < val.bits.size() && val.bits.at(i+0) == RTLIL::State::S1) digit_value |= 1; + if (i+1 < val.bits.size() && val.bits.at(i+1) == RTLIL::State::S1) digit_value |= 2; + if (i+2 < val.bits.size() && val.bits.at(i+2) == RTLIL::State::S1) digit_value |= 4; + if (i+3 < val.bits.size() && val.bits.at(i+3) == RTLIL::State::S1) digit_value |= 8; + char digit_str[2] = { "0123456789abcdef"[digit_value], 0 }; + hex_string = std::string(digit_str) + hex_string; + } + *f << stringf("\n (property %s (string \"%d'h%s\"))", EDIF_DEF(name), GetSize(val.bits), hex_string.c_str()); + } + }; for (auto module : sorted_modules) { if (module->get_blackbox_attribute()) continue; SigMap sigmap(module); - std::map> net_join_db; + std::map> net_join_db; *f << stringf(" (cell %s\n", EDIF_DEF(module->name)); *f << stringf(" (cellType GENERIC)\n"); @@ -323,14 +343,23 @@ struct EdifBackend : public Backend { else if (!wire->port_input) dir = "OUTPUT"; if (wire->width == 1) { - *f << stringf(" (port %s (direction %s))\n", EDIF_DEF(wire->name), dir); + *f << stringf(" (port %s (direction %s)", EDIF_DEF(wire->name), dir); + if (attr_properties) + for (auto &p : wire->attributes) + add_prop(p.first, p.second); + *f << ")\n"; RTLIL::SigSpec sig = sigmap(RTLIL::SigSpec(wire)); net_join_db[sig].insert(stringf("(portRef %s)", EDIF_REF(wire->name))); } else { int b[2]; b[wire->upto ? 0 : 1] = wire->start_offset; b[wire->upto ? 1 : 0] = wire->start_offset + GetSize(wire) - 1; - *f << stringf(" (port (array %s %d) (direction %s))\n", EDIF_DEFR(wire->name, port_rename, b[0], b[1]), wire->width, dir); + *f << stringf(" (port (array %s %d) (direction %s)", EDIF_DEFR(wire->name, port_rename, b[0], b[1]), wire->width, dir); + if (attr_properties) + for (auto &p : wire->attributes) + add_prop(p.first, p.second); + + *f << ")\n"; for (int i = 0; i < wire->width; i++) { RTLIL::SigSpec sig = sigmap(RTLIL::SigSpec(wire, i)); net_join_db[sig].insert(stringf("(portRef (member %s %d))", EDIF_REF(wire->name), GetSize(wire)-i-1)); @@ -348,27 +377,6 @@ struct EdifBackend : public Backend { *f << stringf(" (instance %s\n", EDIF_DEF(cell->name)); *f << stringf(" (viewRef VIEW_NETLIST (cellRef %s%s))", EDIF_REF(cell->type), lib_cell_ports.count(cell->type) > 0 ? " (libraryRef LIB)" : ""); - - auto add_prop = [&](IdString name, Const val) { - if ((val.flags & RTLIL::CONST_FLAG_STRING) != 0) - *f << stringf("\n (property %s (string \"%s\"))", EDIF_DEF(name), val.decode_string().c_str()); - else if (val.bits.size() <= 32 && RTLIL::SigSpec(val).is_fully_def()) - *f << stringf("\n (property %s (integer %u))", EDIF_DEF(name), val.as_int()); - else { - std::string hex_string = ""; - for (size_t i = 0; i < val.bits.size(); i += 4) { - int digit_value = 0; - if (i+0 < val.bits.size() && val.bits.at(i+0) == RTLIL::State::S1) digit_value |= 1; - if (i+1 < val.bits.size() && val.bits.at(i+1) == RTLIL::State::S1) digit_value |= 2; - if (i+2 < val.bits.size() && val.bits.at(i+2) == RTLIL::State::S1) digit_value |= 4; - if (i+3 < val.bits.size() && val.bits.at(i+3) == RTLIL::State::S1) digit_value |= 8; - char digit_str[2] = { "0123456789abcdef"[digit_value], 0 }; - hex_string = std::string(digit_str) + hex_string; - } - *f << stringf("\n (property %s (string \"%d'h%s\"))", EDIF_DEF(name), GetSize(val.bits), hex_string.c_str()); - } - }; - for (auto &p : cell->parameters) add_prop(p.first, p.second); if (attr_properties) @@ -431,8 +439,12 @@ struct EdifBackend : public Backend { *f << stringf(" (portRef %c (instanceRef GND))\n", gndvccy ? 'Y' : 'G'); if (sig == RTLIL::State::S1) *f << stringf(" (portRef %c (instanceRef VCC))\n", gndvccy ? 'Y' : 'P'); - } - *f << stringf(" ))\n"); + } + *f << stringf(" )"); + if (attr_properties && sig.wire != NULL) + for (auto &p : sig.wire->attributes) + add_prop(p.first, p.second); + *f << stringf("\n )\n"); } *f << stringf(" )\n"); *f << stringf(" )\n"); -- cgit v1.2.3 From 992b507537d6c0e5804859100e05a7a78adb21eb Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Fri, 10 Jan 2020 12:34:21 +0100 Subject: Use CARRY4 for abc1 as well, preventing issues with Vivado --- techlibs/xilinx/synth_xilinx.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index 51d2cbbd2..7ff09a437 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -515,7 +515,7 @@ struct SynthXilinxPass : public ScriptPass techmap_args += " -map +/xilinx/arith_map.v"; if (vpr) techmap_args += " -D _EXPLICIT_CARRY"; - else if (abc9) + else techmap_args += " -D _CLB_CARRY"; } run("techmap " + techmap_args); -- cgit v1.2.3 From 6888799c7545ff07b8c057e1b7382ddd2a2c1b8e Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Fri, 10 Jan 2020 12:38:03 +0100 Subject: remove whitespace --- backends/edif/edif.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backends/edif/edif.cc b/backends/edif/edif.cc index 1bfd4a335..6735d670f 100644 --- a/backends/edif/edif.cc +++ b/backends/edif/edif.cc @@ -326,7 +326,7 @@ struct EdifBackend : public Backend { continue; SigMap sigmap(module); - std::map> net_join_db; + std::map> net_join_db; *f << stringf(" (cell %s\n", EDIF_DEF(module->name)); *f << stringf(" (cellType GENERIC)\n"); -- cgit v1.2.3 From af852a0ea8d7a5671f24afce8118aa7a04dab129 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Fri, 10 Jan 2020 14:48:01 +0100 Subject: Fix tests --- tests/arch/xilinx/add_sub.ys | 8 ++++---- tests/arch/xilinx/counter.ys | 7 +++---- tests/arch/xilinx/fsm.ys | 8 ++++---- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/tests/arch/xilinx/add_sub.ys b/tests/arch/xilinx/add_sub.ys index 313948cc5..70cfe81a3 100644 --- a/tests/arch/xilinx/add_sub.ys +++ b/tests/arch/xilinx/add_sub.ys @@ -4,8 +4,8 @@ proc 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 -select -assert-count 6 t:MUXCY -select -assert-count 8 t:XORCY -select -assert-none t:LUT2 t:MUXCY t:XORCY %% t:* %D +stat +select -assert-count 16 t:LUT2 +select -assert-count 2 t:CARRY4 +select -assert-none t:LUT2 t:CARRY4 %% t:* %D diff --git a/tests/arch/xilinx/counter.ys b/tests/arch/xilinx/counter.ys index 11c29922e..064519ce7 100644 --- a/tests/arch/xilinx/counter.ys +++ b/tests/arch/xilinx/counter.ys @@ -5,10 +5,9 @@ flatten 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 - +stat select -assert-count 1 t:BUFG select -assert-count 8 t:FDCE select -assert-count 1 t:INV -select -assert-count 7 t:MUXCY -select -assert-count 8 t:XORCY -select -assert-none t:BUFG t:FDCE t:INV t:MUXCY t:XORCY %% t:* %D +select -assert-count 2 t:CARRY4 +select -assert-none t:BUFG t:FDCE t:INV t:CARRY4 %% t:* %D diff --git a/tests/arch/xilinx/fsm.ys b/tests/arch/xilinx/fsm.ys index 3235d5af3..3cef84388 100644 --- a/tests/arch/xilinx/fsm.ys +++ b/tests/arch/xilinx/fsm.ys @@ -9,11 +9,11 @@ sat -verify -prove-asserts -show-public -set-at 1 in_reset 1 -seq 20 -prove-skip design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd fsm # Constrain all select calls below inside the top module - +stat select -assert-count 1 t:BUFG select -assert-count 4 t:FDRE select -assert-count 1 t:FDSE select -assert-count 1 t:LUT2 -select -assert-count 3 t:LUT5 -select -assert-count 1 t:LUT6 -select -assert-none t:BUFG t:FDRE t:FDSE t:LUT2 t:LUT5 t:LUT6 %% t:* %D +select -assert-count 2 t:LUT3 +select -assert-count 4 t:LUT5 +select -assert-none t:BUFG t:FDRE t:FDSE t:LUT2 t:LUT3 t:LUT5 %% t:* %D -- cgit v1.2.3 From ccfe1e5909ba6093e49ebdfaa1aac6c4aa267036 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Fri, 10 Jan 2020 15:20:50 +0100 Subject: this one is fine --- tests/arch/xilinx/fsm.ys | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/arch/xilinx/fsm.ys b/tests/arch/xilinx/fsm.ys index 3cef84388..a464fcfdb 100644 --- a/tests/arch/xilinx/fsm.ys +++ b/tests/arch/xilinx/fsm.ys @@ -14,6 +14,6 @@ select -assert-count 1 t:BUFG select -assert-count 4 t:FDRE select -assert-count 1 t:FDSE select -assert-count 1 t:LUT2 -select -assert-count 2 t:LUT3 -select -assert-count 4 t:LUT5 -select -assert-none t:BUFG t:FDRE t:FDSE t:LUT2 t:LUT3 t:LUT5 %% t:* %D +select -assert-count 3 t:LUT5 +select -assert-count 1 t:LUT6 +select -assert-none t:BUFG t:FDRE t:FDSE t:LUT2 t:LUT5 t:LUT6 %% t:* %D -- cgit v1.2.3 From d1f8371481b787b3cc6948a7165b7c191e4b4c64 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 10 Jan 2020 10:00:09 -0800 Subject: abc9: fix typos --- passes/techmap/abc9.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index b828404bc..22f5a1f3a 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -300,9 +300,9 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip std::string R; if (design->scratchpad.count("abc9.if.R")) - C = "-C " + design->scratchpad_get_string("abc9.if.R"); + R = "-R " + design->scratchpad_get_string("abc9.if.R"); for (size_t pos = abc9_script.find("{R}"); pos != std::string::npos; pos = abc9_script.find("{R}", pos)) - abc9_script = abc9_script.substr(0, pos) + C + abc9_script.substr(pos+3); + abc9_script = abc9_script.substr(0, pos) + R + 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)) @@ -803,14 +803,14 @@ struct Abc9Pass : public Pass { log(" if no -script parameter is given, the following scripts are used:\n"); log("\n"); log(" for -lut/-luts:\n"); - log("%s\n", fold_abc9_cmd(RTLIL::constpad.at("abc9.script.default")).c_str()); + log("%s\n", fold_abc9_cmd(RTLIL::constpad.at("abc9.script.default")).c_str()+1); 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(RTLIL::constpad.at("abc9.script.default.fast")).c_str()); + log("%s\n", fold_abc9_cmd(RTLIL::constpad.at("abc9.script.default.fast")).c_str()+1); log("\n"); log(" -D \n"); log(" set delay target. the string {D} in the default scripts above is\n"); -- cgit v1.2.3 From 1f7893bd8c8d88f2a84b9bcba67acf43cee0430f Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 10 Jan 2020 10:46:06 -0800 Subject: abc9: fix memory leak --- passes/techmap/abc9.cc | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 8cb34e523..3fc6ed2c2 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -416,13 +416,11 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip dict abc9_box; vector boxes; - for (auto it = module->cells_.begin(); it != module->cells_.end(); ) { - auto cell = it->second; + for (auto cell : module->cells().to_vector()) { if (cell->type.in(ID($_AND_), ID($_NOT_), ID($__ABC9_FF_))) { - it = module->cells_.erase(it); + module->remove(cell); continue; } - ++it; RTLIL::Module* box_module = design->module(cell->type); auto jt = abc9_box.find(cell->type); if (jt == abc9_box.end()) -- cgit v1.2.3 From 291530c59f639609bc7534e561f28c9fb4081e19 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 10 Jan 2020 15:04:13 -0800 Subject: abc9: add abc9.verify and abc9.debug options --- passes/techmap/abc9.cc | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 22f5a1f3a..3ce435dd0 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -308,7 +308,14 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip 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("; &ps -l; &write -n %s/output.aig; time", tempdir_name.c_str()); + abc9_script += stringf("; &ps -l; &write -n %s/output.aig;", tempdir_name.c_str()); + if (design->scratchpad_get_bool("abc9.debug")) { + if (dff_mode) + abc9_script += "verify -s;"; + else + abc9_script += "verify;"; + } + abc9_script += "time"; abc9_script = add_echos_to_abc9_cmd(abc9_script); for (size_t i = 0; i+1 < abc9_script.size(); i++) @@ -910,6 +917,11 @@ struct Abc9Pass : public Pass { } nomfs = design->scratchpad_get_bool("abc9.nomfs", nomfs); + if (design->scratchpad_get_bool("abc9.debug")) { + cleanup = false; + show_tempdir = true; + } + size_t argidx; char pwd [PATH_MAX]; if (!getcwd(pwd, sizeof(pwd))) { -- cgit v1.2.3 From 7d94e18100a6fe61805e94e754b199826571e7ef Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 10 Jan 2020 15:07:46 -0800 Subject: synth_xilinx: synth_xilinx.abc9.xc7.W to replace XC7_WIRE_DELAY macro --- techlibs/xilinx/synth_xilinx.cc | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index 51d2cbbd2..5867f5d1c 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -26,13 +26,16 @@ USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN -#define XC7_WIRE_DELAY 300 // Number with which ABC will map a 6-input gate - // to one LUT6 (instead of a LUT5 + LUT2) - struct SynthXilinxPass : public ScriptPass { SynthXilinxPass() : ScriptPass("synth_xilinx", "synthesis for Xilinx FPGAs") { } + void on_register() YS_OVERRIDE + { + RTLIL::constpad["synth_xilinx.abc9.xc7.W"] = "300"; // Number with which ABC will map a 6-input gate + // to one LUT6 (instead of a LUT5 + LUT2) + } + void help() YS_OVERRIDE { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| @@ -555,7 +558,11 @@ struct SynthXilinxPass : public ScriptPass 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); + auto k = stringf("synth_xilinx.abc9.%s.W", family.c_str()); + if (active_design->scratchpad.count(k)) + abc9_opts += stringf(" -W %s", active_design->scratchpad_get_string(k).c_str()); + else + abc9_opts += stringf(" -W %s", RTLIL::constpad.at(k).c_str()); abc9_opts += " -nomfs"; if (nowidelut) abc9_opts += " -lut +/xilinx/abc9_xc7_nowide.lut"; -- cgit v1.2.3 From ed2aeb498eb7bbe028ece4adf96b94bacd0b3ef0 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 10 Jan 2020 15:09:42 -0800 Subject: Copy-pasta --- passes/techmap/abc9.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 3ce435dd0..387d9b644 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -309,7 +309,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip abc9_script = abc9_script.erase(pos, strlen("&mfs")); abc9_script += stringf("; &ps -l; &write -n %s/output.aig;", tempdir_name.c_str()); - if (design->scratchpad_get_bool("abc9.debug")) { + if (design->scratchpad_get_bool("abc9.verify")) { if (dff_mode) abc9_script += "verify -s;"; else -- cgit v1.2.3 From 9005bb97ff35513a510344108db203c5f5193ec6 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Sat, 11 Jan 2020 07:59:18 -0800 Subject: Bump ABCREV for upstream fix --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index fd95219ee..9140cac0f 100644 --- a/Makefile +++ b/Makefile @@ -128,7 +128,7 @@ bumpversion: # is just a symlink to your actual ABC working directory, as 'make mrproper' # will remove the 'abc' directory and you do not want to accidentally # delete your work on ABC.. -ABCREV = 144c5be +ABCREV = 71f2b40 ABCPULL = 1 ABCURL ?= https://github.com/berkeley-abc/abc ABCMKARGS = CC="$(CXX)" CXX="$(CXX)" ABC_USE_LIBSTDCXX=1 -- cgit v1.2.3 From 45d9caf3f9771a3f6289b745ff2bb631e6e16f06 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Sat, 11 Jan 2020 08:08:35 -0800 Subject: abc9: remove -nomfs option --- passes/techmap/abc9.cc | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 3fc6ed2c2..471c11a80 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -250,7 +250,7 @@ struct abc9_output_filter void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string script_file, std::string exe_file, bool cleanup, vector lut_costs, bool dff_mode, 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 wire_delay ) { map_autoidx = autoidx++; @@ -305,10 +305,6 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip 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); @@ -833,7 +829,6 @@ struct Abc9Pass : public Pass { std::string delay_target, lutin_shared = "-S 1", wire_delay; bool fast_mode = false, dff_mode = false, cleanup = true; bool show_tempdir = false; - bool nomfs = false; vector lut_costs; #if 0 @@ -865,7 +860,6 @@ struct Abc9Pass : public Pass { if (design->scratchpad.count("abc9.W")) { wire_delay = "-W " + design->scratchpad_get_string("abc9.W"); } - nomfs = design->scratchpad_get_bool("abc9.nomfs", nomfs); size_t argidx; char pwd [PATH_MAX]; @@ -926,10 +920,6 @@ struct Abc9Pass : public Pass { wire_delay = "-W " + args[++argidx]; continue; } - if (arg == "-nomfs") { - nomfs = true; - continue; - } break; } extra_args(args, argidx, design); @@ -1043,7 +1033,7 @@ struct Abc9Pass : public Pass { design->selected_active_module = module->name.str(); abc9_module(design, module, script_file, exe_file, cleanup, lut_costs, dff_mode, delay_target, lutin_shared, fast_mode, show_tempdir, - box_file, lut_file, wire_delay, nomfs); + box_file, lut_file, wire_delay); design->selected_active_module.clear(); } -- cgit v1.2.3 From 784fec93c901caa6f9d980388356d120b0cdfea9 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Sat, 11 Jan 2020 08:42:58 -0800 Subject: abc9: cleanup --- passes/techmap/abc9.cc | 20 +++++-------------- passes/techmap/abc9_exe.cc | 15 +++++---------- passes/techmap/abc9_ops.cc | 48 +++++++++++++++++++++++++++------------------- 3 files changed, 38 insertions(+), 45 deletions(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index f6627602b..2af0676b1 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -26,9 +26,6 @@ USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN -#define XC7_WIRE_DELAY 300 // Number with which ABC will map a 6-input gate - // to one LUT6 (instead of a LUT5 + LUT2) - struct Abc9Pass : public ScriptPass { Abc9Pass() : ScriptPass("abc9", "use ABC9 for technology mapping") { } @@ -39,8 +36,9 @@ struct Abc9Pass : public ScriptPass log("\n"); log(" abc9 [options] [selection]\n"); log("\n"); - log("This pass uses the ABC tool [1] for technology mapping of yosys's internal gate\n"); - log("library to a target architecture. Only fully-selected modules are supported.\n"); + log("This script pass performs a sequence of commands to facilitate the use of the ABC\n"); + log("tool [1] for technology mapping of the current design to a target FPGA\n"); + log("architecture. Only fully-selected modules are supported.\n"); log("\n"); log(" -exe \n"); #ifdef ABCEXTERNAL @@ -59,21 +57,13 @@ struct Abc9Pass : public ScriptPass log(" replaced with blanks before the string is passed to ABC.\n"); log("\n"); log(" if no -script parameter is given, the following scripts are used:\n"); - log("\n"); - log(" for -lut/-luts (only one LUT size):\n"); - // FIXME - //log("%s\n", fold_abc9_cmd(ABC_COMMAND_LUT /*"; lutpack {S}"*/).c_str()); - log("\n"); - log(" for -lut/-luts (different LUT sizes):\n"); - // FIXME + //FIXME: //log("%s\n", fold_abc9_cmd(ABC_COMMAND_LUT).c_str()); log("\n"); log(" -fast\n"); log(" use different default scripts that are slightly faster (at the cost\n"); log(" of output quality):\n"); - log("\n"); - log(" for -lut/-luts:\n"); - // FIXME + //FIXME: //log("%s\n", fold_abc9_cmd(ABC_FAST_COMMAND_LUT).c_str()); log("\n"); log(" -D \n"); diff --git a/passes/techmap/abc9_exe.cc b/passes/techmap/abc9_exe.cc index f7dafda96..3108765a1 100644 --- a/passes/techmap/abc9_exe.cc +++ b/passes/techmap/abc9_exe.cc @@ -289,10 +289,12 @@ struct Abc9ExePass : public Pass { { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); - log(" abc9_exe [options] [selection]\n"); + log(" abc9_exe [options]\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("This pass uses the ABC tool [1] for technology mapping of the top module\n"); + log("(according to the (* top *) attribute or if only one module is currently selected)\n"); + log("to a target FPGA architecture.\n"); log("\n"); log(" -exe \n"); #ifdef ABCEXTERNAL @@ -311,18 +313,11 @@ struct Abc9ExePass : public Pass { log(" replaced with blanks before the string is passed to ABC.\n"); log("\n"); log(" if no -script parameter is given, the following scripts are used:\n"); - log("\n"); - log(" for -lut/-luts (only one LUT size):\n"); - log("%s\n", fold_abc9_cmd(ABC_COMMAND_LUT /*"; lutpack {S}"*/).c_str()); - log("\n"); - log(" for -lut/-luts (different LUT sizes):\n"); log("%s\n", fold_abc9_cmd(ABC_COMMAND_LUT).c_str()); log("\n"); log(" -fast\n"); log(" use different default scripts that are slightly faster (at the cost\n"); log(" of output quality):\n"); - log("\n"); - log(" for -lut/-luts:\n"); log("%s\n", fold_abc9_cmd(ABC_FAST_COMMAND_LUT).c_str()); log("\n"); log(" -D \n"); diff --git a/passes/techmap/abc9_ops.cc b/passes/techmap/abc9_ops.cc index 7c7208711..6f089447e 100644 --- a/passes/techmap/abc9_ops.cc +++ b/passes/techmap/abc9_ops.cc @@ -40,7 +40,7 @@ void break_scc(RTLIL::Module *module) // its output ports into a new PO, and drive its previous // sinks with a new PI pool ids_seen; - for (auto cell : module->selected_cells()) { + for (auto cell : module->cells()) { auto it = cell->attributes.find(ID(abc9_scc_id)); if (it == cell->attributes.end()) continue; @@ -116,7 +116,7 @@ void prep_dff(RTLIL::Module *module) typedef SigSpec clkdomain_t; dict clk_to_mergeability; - for (auto cell : module->selected_cells()) { + for (auto cell : module->cells()) { if (cell->type != "$__ABC9_FF_") continue; @@ -179,11 +179,8 @@ void prep_dff(RTLIL::Module *module) ++it; } - for (auto &conn : holes_module->connections_) { - auto it = replace.find(conn); - if (it != replace.end()) - conn = it->second; - } + for (auto &conn : holes_module->connections_) + conn = replace.at(conn, conn); } } @@ -198,7 +195,7 @@ void prep_holes(RTLIL::Module *module, bool dff) TopoSort toposort; bool abc9_box_seen = false; - for (auto cell : module->selected_cells()) { + for (auto cell : module->cells()) { if (cell->type == "$__ABC9_FF_") continue; @@ -236,21 +233,23 @@ void prep_holes(RTLIL::Module *module, bool dff) for (auto user_cell : it.second) toposort.edge(driver_cell, user_cell); -#if 0 - toposort.analyze_loops = true; -#endif + if (ys_debug(1)) + toposort.analyze_loops = true; + 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()); + + if (ys_debug(1)) { + 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 box_list; @@ -845,6 +844,12 @@ struct Abc9OpsPass : public Pass { } extra_args(args, argidx, design); + if (!(break_scc_mode || unbreak_scc_mode || prep_dff_mode || reintegrate_mode)) + log_cmd_error("At least one of -{,un}break_scc, -prep_{dff,holes}, -reintegrate must be specified.\n"); + + if (dff_mode && !prep_holes_mode) + log_cmd_error("'-dff' option is only relevant for -prep_holes.\n"); + for (auto mod : design->selected_modules()) { if (mod->get_bool_attribute("\\abc9_holes")) continue; @@ -854,6 +859,9 @@ struct Abc9OpsPass : public Pass { continue; } + if (!design->selected_whole_module(mod)) + log_error("Can't handle partially selected module %s!\n", log_id(mod)); + if (break_scc_mode) break_scc(mod); if (unbreak_scc_mode) -- cgit v1.2.3 From 1ccee4b95e1e7a2edf55c989d6acc7d6f63762ba Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Sat, 11 Jan 2020 11:49:57 -0800 Subject: write_xaiger: sort holes by offset as well as port_id --- backends/aiger/xaiger.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index b6a7dbac2..7ee5058ae 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -474,7 +474,8 @@ struct XAigerWriter 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; + return a.wire->port_id < b.wire->port_id || + (a.wire->port_id == b.wire->port_id && a.offset < b.offset); } }; input_bits.sort(sort_by_port_id()); -- cgit v1.2.3 From c8206823141aa54b6151c57548fdb73211157451 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Sat, 11 Jan 2020 12:11:35 -0800 Subject: abc9: fix help message, found by @nakengelhardt --- passes/techmap/abc9.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 387d9b644..ec80e098f 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -810,14 +810,14 @@ struct Abc9Pass : public Pass { log(" if no -script parameter is given, the following scripts are used:\n"); log("\n"); log(" for -lut/-luts:\n"); - log("%s\n", fold_abc9_cmd(RTLIL::constpad.at("abc9.script.default")).c_str()+1); + log("%s\n", fold_abc9_cmd(RTLIL::constpad.at("abc9.script.default").substr(1,std::string::npos)).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(RTLIL::constpad.at("abc9.script.default.fast")).c_str()+1); + log("%s\n", fold_abc9_cmd(RTLIL::constpad.at("abc9.script.default.fast").substr(1,std::string::npos)).c_str()); log("\n"); log(" -D \n"); log(" set delay target. the string {D} in the default scripts above is\n"); -- cgit v1.2.3 From 556ed0e18ac00e4ec19e127f33ccf3550be78186 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Sat, 11 Jan 2020 17:05:30 -0800 Subject: MIssed this merge conflict --- passes/techmap/abc9.cc | 4 ---- 1 file changed, 4 deletions(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index bd4e506ac..8a6195741 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -304,10 +304,6 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip for (size_t pos = abc9_script.find("{R}"); pos != std::string::npos; pos = abc9_script.find("{R}", pos)) abc9_script = abc9_script.substr(0, pos) + R + 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("; &ps -l; &write -n %s/output.aig;", tempdir_name.c_str()); if (design->scratchpad_get_bool("abc9.verify")) { if (dff_mode) -- cgit v1.2.3 From 58ab9f6021bc5b90956d97759ef0f3bc8c7e209e Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Sat, 11 Jan 2020 17:25:32 -0800 Subject: write_xaiger: create holes_sigmap before modifications --- backends/aiger/xaiger.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 7ee5058ae..a6c87159d 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -771,6 +771,8 @@ struct XAigerWriter // created a new $paramod ... Pass::call_on_module(holes_module->design, holes_module, "flatten -wb; techmap; aigmap"); + SigMap holes_sigmap(holes_module); + dict replace; for (auto it = holes_module->cells_.begin(); it != holes_module->cells_.end(); ) { auto cell = it->second; @@ -808,7 +810,6 @@ struct XAigerWriter ++it; } - SigMap holes_sigmap(holes_module); for (auto &conn : holes_module->connections_) { auto it = replace.find(sigmap(conn.second)); if (it != replace.end()) -- cgit v1.2.3 From 295e241c074ae275e832fdde9fae6fd897170ac8 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Sat, 11 Jan 2020 17:28:24 -0800 Subject: cleanup --- backends/aiger/xaiger.cc | 2 +- passes/techmap/abc9.cc | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 212e1e561..93e0ebc8c 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -93,7 +93,6 @@ struct XAigerWriter dict ordered_outputs; vector box_list; - dict> box_ports; int mkgate(int a0, int a1) { @@ -277,6 +276,7 @@ struct XAigerWriter //log_warning("Unsupported cell type: %s (%s)\n", log_id(cell->type), log_id(cell)); } + dict> box_ports; for (auto cell : box_list) { log_assert(cell); diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 30b62dc79..5d6d8904c 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -182,12 +182,10 @@ struct Abc9Pass : public ScriptPass run("abc9_ops -break_scc -prep_holes" + std::string(dff_mode ? " -dff" : ""), "(option for -dff)"); run("select -set abc9_holes A:abc9_holes"); run("flatten -wb @abc9_holes"); -run("dump @abc9_holes"); run("techmap @abc9_holes"); if (dff_mode || help_mode) run("abc9_ops -prep_dff", "(only if -dff)"); run("opt -purge @abc9_holes"); -run("dump @abc9_holes"); run("aigmap"); run("wbflip @abc9_holes"); } -- cgit v1.2.3 From 35e49fde4dfa67030a3e80d0bdf700c97258ed45 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Sat, 11 Jan 2020 18:57:25 -0800 Subject: Another conflict --- techlibs/xilinx/synth_xilinx.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index 5867f5d1c..d916093dc 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -563,7 +563,6 @@ struct SynthXilinxPass : public ScriptPass abc9_opts += stringf(" -W %s", active_design->scratchpad_get_string(k).c_str()); else abc9_opts += stringf(" -W %s", RTLIL::constpad.at(k).c_str()); - abc9_opts += " -nomfs"; if (nowidelut) abc9_opts += " -lut +/xilinx/abc9_xc7_nowide.lut"; else -- cgit v1.2.3 From c0b55deb0bb189d1b6343b5d209f7fc4ac251596 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Sun, 12 Jan 2020 11:26:05 -0800 Subject: synth_ice40: -abc2 to always use `abc` even if `-abc9` --- techlibs/ice40/synth_ice40.cc | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/techlibs/ice40/synth_ice40.cc b/techlibs/ice40/synth_ice40.cc index 463c2063a..121bcff1f 100644 --- a/techlibs/ice40/synth_ice40.cc +++ b/techlibs/ice40/synth_ice40.cc @@ -102,8 +102,8 @@ struct SynthIce40Pass : public ScriptPass log("\n"); } - string top_opt, blif_file, edif_file, json_file, abc, device_opt; - bool nocarry, nodffe, nobram, dsp, flatten, retime, noabc, abc2, vpr; + string top_opt, blif_file, edif_file, json_file, device_opt; + bool nocarry, nodffe, nobram, dsp, flatten, retime, noabc, abc2, vpr, abc9; int min_ce_use; void clear_flags() YS_OVERRIDE @@ -122,7 +122,7 @@ struct SynthIce40Pass : public ScriptPass noabc = false; abc2 = false; vpr = false; - abc = "abc"; + abc9 = false; device_opt = "hx"; } @@ -207,7 +207,7 @@ struct SynthIce40Pass : public ScriptPass continue; } if (args[argidx] == "-abc9") { - abc = "abc9"; + abc9 = true; continue; } if (args[argidx] == "-device" && argidx+1 < args.size()) { @@ -223,7 +223,7 @@ struct SynthIce40Pass : public ScriptPass if (device_opt != "hx" && device_opt != "lp" && device_opt !="u") log_cmd_error("Invalid or no device specified: '%s'\n", device_opt.c_str()); - if (abc == "abc9" && retime) + if (abc9 && retime) log_cmd_error("-retime option not currently compatible with -abc9!\n"); log_header(design, "Executing SYNTH_ICE40 pass.\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 -D 1", "(only if -retime)"); + run("abc -dff -D 1", "(only if -retime)"); run("ice40_opt"); } @@ -340,7 +340,7 @@ struct SynthIce40Pass : public ScriptPass if (check_label("map_luts")) { if (abc2 || help_mode) { - run(abc, " (only if -abc2)"); + run("abc", " (only if -abc2)"); run("ice40_opt", "(only if -abc2)"); } run("techmap -map +/ice40/latches_map.v"); @@ -349,7 +349,7 @@ struct SynthIce40Pass : public ScriptPass run("techmap -map +/gate2lut.v -D LUT_WIDTH=4", "(only if -noabc)"); } if (!noabc) { - if (abc == "abc9") { + if (abc9) { run("read_verilog -icells -lib +/ice40/abc9_model.v"); int wire_delay; if (device_opt == "lp") @@ -358,10 +358,10 @@ struct SynthIce40Pass : public ScriptPass wire_delay = 750; else wire_delay = 250; - run(abc + stringf(" -W %d -lut +/ice40/abc9_%s.lut -box +/ice40/abc9_%s.box", wire_delay, device_opt.c_str(), device_opt.c_str()), "(skip if -noabc)"); + run(stringf("abc9 -W %d -lut +/ice40/abc9_%s.lut -box +/ice40/abc9_%s.box", wire_delay, device_opt.c_str(), device_opt.c_str())); } else - run(abc + " -dress -lut 4", "(skip if -noabc)"); + run("abc -dress -lut 4", "(skip if -noabc)"); } run("ice40_wrapcarry -unwrap"); run("techmap -D NO_LUT -map +/ice40/cells_map.v"); -- cgit v1.2.3 From ae619ba87a58ee530549206eee7f5ea1ad8e1072 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Sun, 12 Jan 2020 15:21:26 -0800 Subject: Add #1626 testcase --- tests/arch/ice40/bug1626.ys | 217 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 217 insertions(+) create mode 100644 tests/arch/ice40/bug1626.ys diff --git a/tests/arch/ice40/bug1626.ys b/tests/arch/ice40/bug1626.ys new file mode 100644 index 000000000..27b6fb5e8 --- /dev/null +++ b/tests/arch/ice40/bug1626.ys @@ -0,0 +1,217 @@ +read_ilang < Date: Mon, 13 Jan 2020 14:49:31 +0100 Subject: edif: Just ignore connections to 'z Connecting a const 'z to a net should be equivalent to not connecting it at all, so let's just ignore such connections on output. --- backends/edif/edif.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/backends/edif/edif.cc b/backends/edif/edif.cc index 6d9469538..e9beace83 100644 --- a/backends/edif/edif.cc +++ b/backends/edif/edif.cc @@ -404,6 +404,8 @@ struct EdifBackend : public Backend { for (auto &ref : it.second) log_warning("Exporting x-bit on %s as zero bit.\n", ref.c_str()); sig = RTLIL::State::S0; + } else if (sig == RTLIL::State::Sz) { + continue; } else { for (auto &ref : it.second) log_error("Don't know how to handle %s on %s.\n", log_signal(sig), ref.c_str()); -- cgit v1.2.3 From 808b388e34f3cededd450de35555476874cf2799 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 13 Jan 2020 09:43:57 -0800 Subject: abc9: log which module is being operated on --- passes/techmap/abc9.cc | 4 +++- passes/techmap/abc9_exe.cc | 4 ---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 2ded1c162..2e3df773e 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -276,9 +276,11 @@ struct Abc9Pass : public ScriptPass run(stringf("write_xaiger -map %s/input.sym %s/input.xaig", tempdir_name.c_str(), tempdir_name.c_str())); int num_outputs = active_design->scratchpad_get_int("write_xaiger.num_outputs"); - log("Extracted %d AND gates and %d wires to a netlist network with %d inputs and %d outputs.\n", + + log("Extracted %d AND gates and %d wires from module `%s' to a netlist network with %d inputs and %d outputs.\n", active_design->scratchpad_get_int("write_xaiger.num_ands"), active_design->scratchpad_get_int("write_xaiger.num_wires"), + log_id(mod), active_design->scratchpad_get_int("write_xaiger.num_inputs"), num_outputs); if (num_outputs) { diff --git a/passes/techmap/abc9_exe.cc b/passes/techmap/abc9_exe.cc index c1687ef97..a2acfac91 100644 --- a/passes/techmap/abc9_exe.cc +++ b/passes/techmap/abc9_exe.cc @@ -168,10 +168,6 @@ void abc9_module(RTLIL::Design *design, std::string script_file, std::string exe std::string wire_delay, std::string tempdir_name ) { - //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()) -- cgit v1.2.3 From 0d2c06ee47a5008ba79d14d52f72d9b08ac2c7fc Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 13 Jan 2020 09:50:50 -0800 Subject: write_xaiger: cache arrival times --- backends/aiger/xaiger.cc | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 93e0ebc8c..0c08645d0 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -184,6 +184,7 @@ struct XAigerWriter } } + dict> arrival_cache; for (auto cell : module->cells()) { if (cell->type == "$_NOT_") { @@ -230,24 +231,29 @@ struct XAigerWriter if (GetSize(box_list) <= abc9_box_seq) box_list.resize(abc9_box_seq+1); box_list[abc9_box_seq] = cell; + // Only flop boxes may have arrival times if (!inst_module->get_bool_attribute("\\abc9_flop")) continue; } + auto &cell_arrivals = arrival_cache[cell->type]; for (const auto &conn : cell->connections()) { - auto port_wire = inst_module->wire(conn.first); - if (port_wire->port_output) { - int arrival = 0; - auto it = port_wire->attributes.find("\\abc9_arrival"); - if (it != port_wire->attributes.end()) { - if (it->second.flags != 0) - log_error("Attribute 'abc9_arrival' on port '%s' of module '%s' is not an integer.\n", log_id(port_wire), log_id(cell->type)); - arrival = it->second.as_int(); + auto r = cell_arrivals.insert(conn.first); + auto &arrival = r.first->second; + if (r.second) { + auto port_wire = inst_module->wire(conn.first); + if (port_wire->port_output) { + auto it = port_wire->attributes.find("\\abc9_arrival"); + if (it != port_wire->attributes.end()) { + if (it->second.flags != 0) + log_error("Attribute 'abc9_arrival' on port '%s' of module '%s' is not an integer.\n", log_id(port_wire), log_id(cell->type)); + arrival = it->second.as_int(); + } } - if (arrival) - for (auto bit : sigmap(conn.second)) - arrival_times[bit] = arrival; } + if (arrival) + for (auto bit : sigmap(conn.second)) + arrival_times[bit] = arrival; } } -- cgit v1.2.3 From 766e16b525d5ab23e451be1e4183cf82560dc8da Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 13 Jan 2020 17:34:37 -0800 Subject: read_aiger: make $and/$not/$lut the prefix not suffix --- frontends/aiger/aigerparse.cc | 10 +++++----- passes/techmap/abc9.cc | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc index 8a114b18c..6a1b64a21 100644 --- a/frontends/aiger/aigerparse.cc +++ b/frontends/aiger/aigerparse.cc @@ -346,7 +346,7 @@ 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("$not$%d", variable), wire_inv, wire); return wire; } @@ -445,10 +445,10 @@ void AigerReader::parse_xaiger() log_assert(o.wire == nullptr); lut_mask[gray] = o.data; } - RTLIL::Cell *output_cell = module->cell(stringf("$%d$and", rootNodeID)); + RTLIL::Cell *output_cell = module->cell(stringf("$and$%d", rootNodeID)); log_assert(output_cell); module->remove(output_cell); - module->addLut(stringf("$%d$lut", rootNodeID), input_sig, output_sig, std::move(lut_mask)); + module->addLut(stringf("$lut$%d", rootNodeID), input_sig, output_sig, std::move(lut_mask)); } } else if (c == 'r') { @@ -620,7 +620,7 @@ void AigerReader::parse_aiger_ascii() RTLIL::Wire *o_wire = createWireIfNotExists(module, l1); RTLIL::Wire *i1_wire = createWireIfNotExists(module, l2); RTLIL::Wire *i2_wire = createWireIfNotExists(module, l3); - module->addAndGate(o_wire->name.str() + "$and", i1_wire, i2_wire, o_wire); + module->addAndGate("$and" + o_wire->name.str(), i1_wire, i2_wire, o_wire); } std::getline(f, line); // Ignore up to start of next line } @@ -746,7 +746,7 @@ void AigerReader::parse_aiger_binary() RTLIL::Wire *o_wire = createWireIfNotExists(module, l1); RTLIL::Wire *i1_wire = createWireIfNotExists(module, l2); RTLIL::Wire *i2_wire = createWireIfNotExists(module, l3); - module->addAndGate(o_wire->name.str() + "$and", i1_wire, i2_wire, o_wire); + module->addAndGate("$and" + o_wire->name.str(), i1_wire, i2_wire, o_wire); } } diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 8a6195741..1f6cdaa22 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -348,7 +348,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip 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 */); + AigerReader reader(design, ifs, ID($__abc9__), "" /* clk_name */, buffer.c_str() /* map_filename */, true /* wideports */); reader.parse_xaiger(); } ifs.close(); @@ -472,16 +472,16 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip // (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()); + driver_name = stringf("$lut%s", a_bit.wire->name.c_str()); else - driver_name = stringf("%s[%d]$lut", a_bit.wire->name.c_str(), a_bit.offset); + driver_name = stringf("$lut%s[%d]", 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())), + cell = module->addLut(remap_name(stringf("$lut%s", 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")); -- cgit v1.2.3 From 9ec948f3965eef214bee3af778b67fdd6ee86929 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 13 Jan 2020 19:07:55 -0800 Subject: write_xaiger: add support and test for (* keep *) on wires --- backends/aiger/xaiger.cc | 24 +++++++++++++++++------- tests/techmap/abc9.ys | 13 +++++++++++++ 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 0c08645d0..2a0f5c7e4 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -156,7 +156,6 @@ struct XAigerWriter if (wire->get_bool_attribute(ID::keep)) sigmap.add(wire); - for (auto wire : module->wires()) for (int i = 0; i < GetSize(wire); i++) { @@ -174,10 +173,11 @@ struct XAigerWriter undriven_bits.insert(bit); unused_bits.insert(bit); - if (wire->port_input) + bool keep = wire->get_bool_attribute(ID::keep); + if (wire->port_input || keep) input_bits.insert(bit); - if (wire->port_output) { + if (wire->port_output || keep) { if (bit != wirebit) alias_map[wirebit] = bit; output_bits.insert(wirebit); @@ -209,9 +209,9 @@ struct XAigerWriter } if (cell->type == "$__ABC9_FF_" && - // The presence of an abc9_mergeability attribute indicates - // that we do want to pass this flop to ABC - cell->attributes.count("\\abc9_mergeability")) + // The presence of an abc9_mergeability attribute indicates + // that we do want to pass this flop to ABC + cell->attributes.count("\\abc9_mergeability")) { SigBit D = sigmap(cell->getPort("\\D").as_bit()); SigBit Q = sigmap(cell->getPort("\\Q").as_bit()); @@ -430,7 +430,17 @@ struct XAigerWriter for (const auto &bit : output_bits) { ordered_outputs[bit] = aig_o++; - aig_outputs.push_back(bit2aig(bit)); + int aig; + if (input_bits.count(bit)) { + auto it = aig_map.find(bit); + int input_aig = it->second; + aig_map.erase(it); + aig = bit2aig(bit); + aig_map.at(bit) = input_aig; + } + else + aig = bit2aig(bit); + aig_outputs.push_back(aig); } for (auto &i : ff_bits) { diff --git a/tests/techmap/abc9.ys b/tests/techmap/abc9.ys index 20f263da8..46b6f08d2 100644 --- a/tests/techmap/abc9.ys +++ b/tests/techmap/abc9.ys @@ -38,3 +38,16 @@ abc9 -lut 4 design -load gold scratchpad -copy abc9.script.flow3 abc9.script abc9 -lut 4 + +design -reset +read_verilog < Date: Mon, 13 Jan 2020 19:21:11 -0800 Subject: abc9: respect (* keep *) on cells --- backends/aiger/xaiger.cc | 130 ++++++++++++++++++++++++--------------------- passes/techmap/abc9_ops.cc | 2 + tests/techmap/abc9.ys | 15 ++++++ 3 files changed, 86 insertions(+), 61 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 2a0f5c7e4..ed0e48e01 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -186,74 +186,76 @@ struct XAigerWriter dict> arrival_cache; for (auto cell : module->cells()) { - if (cell->type == "$_NOT_") - { - SigBit A = sigmap(cell->getPort("\\A").as_bit()); - SigBit Y = sigmap(cell->getPort("\\Y").as_bit()); - unused_bits.erase(A); - undriven_bits.erase(Y); - not_map[Y] = A; - continue; - } - - if (cell->type == "$_AND_") - { - SigBit A = sigmap(cell->getPort("\\A").as_bit()); - SigBit B = sigmap(cell->getPort("\\B").as_bit()); - SigBit Y = sigmap(cell->getPort("\\Y").as_bit()); - unused_bits.erase(A); - unused_bits.erase(B); - undriven_bits.erase(Y); - and_map[Y] = make_pair(A, B); - continue; - } + RTLIL::Module* inst_module = module->design->module(cell->type); + if (!cell->has_keep_attr()) { + if (cell->type == "$_NOT_") + { + SigBit A = sigmap(cell->getPort("\\A").as_bit()); + SigBit Y = sigmap(cell->getPort("\\Y").as_bit()); + unused_bits.erase(A); + undriven_bits.erase(Y); + not_map[Y] = A; + continue; + } - if (cell->type == "$__ABC9_FF_" && - // The presence of an abc9_mergeability attribute indicates - // that we do want to pass this flop to ABC - cell->attributes.count("\\abc9_mergeability")) - { - SigBit D = sigmap(cell->getPort("\\D").as_bit()); - SigBit Q = sigmap(cell->getPort("\\Q").as_bit()); - unused_bits.erase(D); - undriven_bits.erase(Q); - alias_map[Q] = D; - auto r YS_ATTRIBUTE(unused) = ff_bits.insert(std::make_pair(D, cell)); - log_assert(r.second); - continue; - } + if (cell->type == "$_AND_") + { + SigBit A = sigmap(cell->getPort("\\A").as_bit()); + SigBit B = sigmap(cell->getPort("\\B").as_bit()); + SigBit Y = sigmap(cell->getPort("\\Y").as_bit()); + unused_bits.erase(A); + unused_bits.erase(B); + undriven_bits.erase(Y); + and_map[Y] = make_pair(A, B); + continue; + } - RTLIL::Module* inst_module = module->design->module(cell->type); - if (inst_module) { - auto it = cell->attributes.find("\\abc9_box_seq"); - if (it != cell->attributes.end()) { - int abc9_box_seq = it->second.as_int(); - if (GetSize(box_list) <= abc9_box_seq) - box_list.resize(abc9_box_seq+1); - box_list[abc9_box_seq] = cell; - // Only flop boxes may have arrival times - if (!inst_module->get_bool_attribute("\\abc9_flop")) - continue; + if (cell->type == "$__ABC9_FF_" && + // The presence of an abc9_mergeability attribute indicates + // that we do want to pass this flop to ABC + cell->attributes.count("\\abc9_mergeability")) + { + SigBit D = sigmap(cell->getPort("\\D").as_bit()); + SigBit Q = sigmap(cell->getPort("\\Q").as_bit()); + unused_bits.erase(D); + undriven_bits.erase(Q); + alias_map[Q] = D; + auto r YS_ATTRIBUTE(unused) = ff_bits.insert(std::make_pair(D, cell)); + log_assert(r.second); + continue; } - auto &cell_arrivals = arrival_cache[cell->type]; - for (const auto &conn : cell->connections()) { - auto r = cell_arrivals.insert(conn.first); - auto &arrival = r.first->second; - if (r.second) { - auto port_wire = inst_module->wire(conn.first); - if (port_wire->port_output) { - auto it = port_wire->attributes.find("\\abc9_arrival"); - if (it != port_wire->attributes.end()) { - if (it->second.flags != 0) - log_error("Attribute 'abc9_arrival' on port '%s' of module '%s' is not an integer.\n", log_id(port_wire), log_id(cell->type)); - arrival = it->second.as_int(); + if (inst_module) { + auto it = cell->attributes.find("\\abc9_box_seq"); + if (it != cell->attributes.end()) { + int abc9_box_seq = it->second.as_int(); + if (GetSize(box_list) <= abc9_box_seq) + box_list.resize(abc9_box_seq+1); + box_list[abc9_box_seq] = cell; + // Only flop boxes may have arrival times + if (!inst_module->get_bool_attribute("\\abc9_flop")) + continue; + } + + auto &cell_arrivals = arrival_cache[cell->type]; + for (const auto &conn : cell->connections()) { + auto r = cell_arrivals.insert(conn.first); + auto &arrival = r.first->second; + if (r.second) { + auto port_wire = inst_module->wire(conn.first); + if (port_wire->port_output) { + auto it = port_wire->attributes.find("\\abc9_arrival"); + if (it != port_wire->attributes.end()) { + if (it->second.flags != 0) + log_error("Attribute 'abc9_arrival' on port '%s' of module '%s' is not an integer.\n", log_id(port_wire), log_id(cell->type)); + arrival = it->second.as_int(); + } } } + if (arrival) + for (auto bit : sigmap(conn.second)) + arrival_times[bit] = arrival; } - if (arrival) - for (auto bit : sigmap(conn.second)) - arrival_times[bit] = arrival; } } @@ -270,6 +272,9 @@ struct XAigerWriter for (auto b : c.second) { Wire *w = b.wire; if (!w) continue; + // Do not add as PO if bit is already a PI + if (input_bits.count(b)) + continue; if (!w->port_output || !cell_known) { SigBit I = sigmap(b); if (I != b) @@ -431,6 +436,9 @@ struct XAigerWriter for (const auto &bit : output_bits) { ordered_outputs[bit] = aig_o++; int aig; + // For inout/keep bits only, the output bit + // should be driven by logic, not the PI, + // so temporarily swap that out if (input_bits.count(bit)) { auto it = aig_map.find(bit); int input_aig = it->second; diff --git a/passes/techmap/abc9_ops.cc b/passes/techmap/abc9_ops.cc index cc22fd474..9cc58c99d 100644 --- a/passes/techmap/abc9_ops.cc +++ b/passes/techmap/abc9_ops.cc @@ -489,6 +489,8 @@ void reintegrate(RTLIL::Module *module) std::vector boxes; for (auto cell : module->cells().to_vector()) { + if (cell->has_keep_attr()) + continue; if (cell->type.in(ID($_AND_), ID($_NOT_), ID($__ABC9_FF_))) module->remove(cell); else if (cell->attributes.erase("\\abc9_box_seq")) diff --git a/tests/techmap/abc9.ys b/tests/techmap/abc9.ys index 46b6f08d2..d5a63e1cb 100644 --- a/tests/techmap/abc9.ys +++ b/tests/techmap/abc9.ys @@ -51,3 +51,18 @@ simplemap equiv_opt -assert abc9 -lut 4 design -load postopt select -assert-count 2 t:$lut + +design -reset +read_verilog -icells < Date: Mon, 13 Jan 2020 19:22:23 -0800 Subject: abc9: add -run option --- passes/techmap/abc9.cc | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 2e3df773e..2627ab9ca 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -91,6 +91,11 @@ struct Abc9Pass : public ScriptPass log("tool [1] for technology mapping of the current design to a target FPGA\n"); log("architecture. Only fully-selected modules are supported.\n"); log("\n"); + log(" -run :\n"); + log(" only run the commands between the labels (see below). an empty\n"); + log(" from label is synonymous to 'begin', and empty to label is\n"); + log(" synonymous to the end of the command list.\n"); + log("\n"); log(" -exe \n"); #ifdef ABCEXTERNAL log(" use the specified command instead of \"" ABCEXTERNAL "\" to execute ABC.\n"); @@ -210,13 +215,21 @@ struct Abc9Pass : public ScriptPass } if (arg == "-dff") { dff_mode = true; - exe_cmd << " " << arg; + exe_cmd << " " << arg; continue; } if (arg == "-nocleanup") { cleanup = false; continue; } + if (arg == "-run" && argidx+1 < args.size()) { + size_t pos = args[argidx+1].find(':'); + if (pos == std::string::npos) + break; + run_from = args[++argidx].substr(0, pos); + run_to = args[argidx].substr(pos+1); + continue; + } break; } extra_args(args, argidx, design); -- cgit v1.2.3 From 565d349dc9963c9cde887c0632e8451f01997b1c Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 13 Jan 2020 21:27:53 -0800 Subject: Add #1630 testcase --- tests/arch/ecp5/bug1630.il.gz | Bin 0 -> 8527 bytes tests/arch/ecp5/bug1630.ys | 2 ++ 2 files changed, 2 insertions(+) create mode 100644 tests/arch/ecp5/bug1630.il.gz create mode 100644 tests/arch/ecp5/bug1630.ys diff --git a/tests/arch/ecp5/bug1630.il.gz b/tests/arch/ecp5/bug1630.il.gz new file mode 100644 index 000000000..37bcf2be2 Binary files /dev/null and b/tests/arch/ecp5/bug1630.il.gz differ diff --git a/tests/arch/ecp5/bug1630.ys b/tests/arch/ecp5/bug1630.ys new file mode 100644 index 000000000..b419fb9bb --- /dev/null +++ b/tests/arch/ecp5/bug1630.ys @@ -0,0 +1,2 @@ +read_ilang bug1630.il.gz +abc9 -lut +/ecp5/abc9_5g.lut -- cgit v1.2.3 From ee95fa959acc3a796836c9df970d6739d6cf0ade Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 13 Jan 2020 21:28:27 -0800 Subject: read_aiger: uniquify wires with $aiger prefix --- frontends/aiger/aigerparse.cc | 19 ++++++++++--------- frontends/aiger/aigerparse.h | 3 +++ 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc index 6a1b64a21..859dd5314 100644 --- a/frontends/aiger/aigerparse.cc +++ b/frontends/aiger/aigerparse.cc @@ -206,7 +206,7 @@ eval_end: }; AigerReader::AigerReader(RTLIL::Design *design, std::istream &f, RTLIL::IdString module_name, RTLIL::IdString clk_name, std::string map_filename, bool wideports) - : design(design), f(f), clk_name(clk_name), map_filename(map_filename), wideports(wideports) + : design(design), f(f), clk_name(clk_name), map_filename(map_filename), wideports(wideports), aiger_autoidx(autoidx++) { module = new RTLIL::Module; module->name = module_name; @@ -323,18 +323,18 @@ static uint32_t parse_xaiger_literal(std::istream &f) return from_big_endian(l); } -static RTLIL::Wire* createWireIfNotExists(RTLIL::Module *module, unsigned literal) +RTLIL::Wire* AigerReader::createWireIfNotExists(RTLIL::Module *module, unsigned literal) { 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("$aiger%d$%d%s", aiger_autoidx, 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("$aiger%d$%d", aiger_autoidx, variable)); RTLIL::Wire *wire_inv = module->wire(wire_inv_name); if (wire_inv) { if (module->cell(wire_inv_name)) return wire; @@ -346,7 +346,7 @@ 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("$not$%d", variable), wire_inv, wire); + module->addNotGate(stringf("$not$aiger%d$%d", aiger_autoidx, variable), wire_inv, wire); return wire; } @@ -422,13 +422,14 @@ void AigerReader::parse_xaiger() 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)); + RTLIL::Wire *output_sig = module->wire(stringf("$aiger%d$%d", aiger_autoidx, rootNodeID)); + log_assert(output_sig); 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)); + RTLIL::Wire *wire = module->wire(stringf("$aiger%d$%d", aiger_autoidx, nodeID)); log_assert(wire); input_sig.append(wire); } @@ -445,10 +446,10 @@ void AigerReader::parse_xaiger() log_assert(o.wire == nullptr); lut_mask[gray] = o.data; } - RTLIL::Cell *output_cell = module->cell(stringf("$and$%d", rootNodeID)); + RTLIL::Cell *output_cell = module->cell(stringf("$and$aiger%d$%d", aiger_autoidx, rootNodeID)); log_assert(output_cell); module->remove(output_cell); - module->addLut(stringf("$lut$%d", rootNodeID), input_sig, output_sig, std::move(lut_mask)); + module->addLut(stringf("$lut$aiger%d$%d", aiger_autoidx, rootNodeID), input_sig, output_sig, std::move(lut_mask)); } } else if (c == 'r') { diff --git a/frontends/aiger/aigerparse.h b/frontends/aiger/aigerparse.h index de3c3efbc..722f1e472 100644 --- a/frontends/aiger/aigerparse.h +++ b/frontends/aiger/aigerparse.h @@ -33,6 +33,7 @@ struct AigerReader RTLIL::Module *module; std::string map_filename; bool wideports; + const int aiger_autoidx; unsigned M, I, L, O, A; unsigned B, C, J, F; // Optional in AIGER 1.9 @@ -51,6 +52,8 @@ struct AigerReader void parse_aiger_ascii(); void parse_aiger_binary(); void post_process(); + + RTLIL::Wire* createWireIfNotExists(RTLIL::Module *module, unsigned literal); }; YOSYS_NAMESPACE_END -- cgit v1.2.3 From 2c65e1abacc4401c4fd3e9b48f52c4de120bc511 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 13 Jan 2020 21:45:27 -0800 Subject: abc9: break SCC by setting (* keep *) on output wires --- backends/aiger/xaiger.cc | 23 +++++++++++++++-------- frontends/aiger/aigerparse.cc | 4 +++- passes/techmap/abc9.cc | 2 +- passes/techmap/abc9_ops.cc | 29 ++++------------------------- 4 files changed, 23 insertions(+), 35 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index ed0e48e01..8651f3a01 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -436,15 +436,22 @@ struct XAigerWriter for (const auto &bit : output_bits) { ordered_outputs[bit] = aig_o++; int aig; - // For inout/keep bits only, the output bit - // should be driven by logic, not the PI, - // so temporarily swap that out + // Unlike bit2aig() which checks aig_map first, for + // inout/keep bits, since aig_map will point to + // the PI, first attempt to find the NOT/AND driver + // before resorting to an aig_map lookup (which + // could be another PO) if (input_bits.count(bit)) { - auto it = aig_map.find(bit); - int input_aig = it->second; - aig_map.erase(it); - aig = bit2aig(bit); - aig_map.at(bit) = input_aig; + if (not_map.count(bit)) { + aig = bit2aig(not_map.at(bit)) ^ 1; + } else if (and_map.count(bit)) { + auto args = and_map.at(bit); + int a0 = bit2aig(args.first); + int a1 = bit2aig(args.second); + aig = mkgate(a0, a1); + } + else + aig = aig_map.at(bit); } else aig = bit2aig(bit); diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc index b4304a581..f4decaf25 100644 --- a/frontends/aiger/aigerparse.cc +++ b/frontends/aiger/aigerparse.cc @@ -831,6 +831,7 @@ void AigerReader::post_process() } else { wire->port_output = false; + existing->port_output = true; module->connect(wire, existing); wire = existing; } @@ -845,8 +846,9 @@ void AigerReader::post_process() wideports_cache[escaped_s] = std::max(wideports_cache[escaped_s], index); } else { - module->connect(wire, existing); wire->port_output = false; + existing->port_output = true; + module->connect(wire, existing); } log_debug(" -> %s\n", log_id(indexed_name)); } diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 2627ab9ca..dad40be63 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -298,7 +298,7 @@ struct Abc9Pass : public ScriptPass num_outputs); if (num_outputs) { run(stringf("%s -cwd %s", exe_cmd.str().c_str(), tempdir_name.c_str())); - run(stringf("read_aiger -xaiger -wideports -module_name %s$abc9 -map %s/input.sym %s/output.aig", log_id(mod->name), tempdir_name.c_str(), tempdir_name.c_str())); + run(stringf("read_aiger -xaiger -wideports -module_name %s$abc9 -map %s/input.sym %s/output.aig", log_id(mod), tempdir_name.c_str(), tempdir_name.c_str())); run("abc9_ops -reintegrate"); } else diff --git a/passes/techmap/abc9_ops.cc b/passes/techmap/abc9_ops.cc index 9cc58c99d..4da10d94b 100644 --- a/passes/techmap/abc9_ops.cc +++ b/passes/techmap/abc9_ops.cc @@ -53,30 +53,7 @@ void break_scc(RTLIL::Module *module) 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); - } + w->set_bool_attribute(ID::keep); } } } @@ -586,7 +563,9 @@ void reintegrate(RTLIL::Module *module) } if (cell->output(mapped_conn.first)) for (auto i : mapped_conn.second) - bit_drivers[i].insert(mapped_cell->name); + // Ignore inouts for topo ordering + if (i.wire && !(i.wire->port_input && i.wire->port_output)) + bit_drivers[i].insert(mapped_cell->name); } } else { -- cgit v1.2.3 From eb7dd7d3741983fafe62b13c4a2d6a21ced06133 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 13 Jan 2020 23:23:21 -0800 Subject: write_xaiger: fix case of PI and CI and (* keep *) --- backends/aiger/xaiger.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 8651f3a01..822ba4dec 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -356,6 +356,11 @@ struct XAigerWriter alias_map[O] = b; ci_bits.emplace_back(b); undriven_bits.erase(O); + // If PI and CI, then must be a (* keep *) wire + if (input_bits.erase(O)) { + log_assert(output_bits.count(O)); + log_assert(O.wire->get_bool_attribute(ID::keep)); + } } } -- cgit v1.2.3 From b678b15c6d0d14580ca18e89f86926eabf8fead0 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 13 Jan 2020 23:33:37 -0800 Subject: abc9_ops: ignore inouts of all cell outputs for topo ordering --- passes/techmap/abc9_ops.cc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/passes/techmap/abc9_ops.cc b/passes/techmap/abc9_ops.cc index 4da10d94b..d7ebfdf3f 100644 --- a/passes/techmap/abc9_ops.cc +++ b/passes/techmap/abc9_ops.cc @@ -488,7 +488,9 @@ void reintegrate(RTLIL::Module *module) 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); + // Ignore inouts for topo ordering + if (y_bit.wire && !(y_bit.wire->port_input && y_bit.wire->port_output)) + bit_drivers[y_bit].insert(mapped_cell->name); if (!a_bit.wire) { mapped_cell->setPort(ID::Y, module->addWire(NEW_ID)); @@ -598,7 +600,9 @@ void reintegrate(RTLIL::Module *module) for (const auto &i : inputs) bit_users[i].insert(mapped_cell->name); for (const auto &i : outputs) - bit_drivers[i].insert(mapped_cell->name); + // Ignore inouts for topo ordering + if (i.wire && !(i.wire->port_input && i.wire->port_output)) + bit_drivers[i].insert(mapped_cell->name); } int input_count = 0, output_count = 0; -- cgit v1.2.3 From 531fddf797a79b46df3e462112ca68ff50e6a18e Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 13 Jan 2020 23:42:27 -0800 Subject: abc9_ops: -break_scc -> -mark_scc using (* keep *), remove -unbreak_scc --- passes/techmap/abc9.cc | 7 ++---- passes/techmap/abc9_ops.cc | 59 ++++++++++++++-------------------------------- 2 files changed, 20 insertions(+), 46 deletions(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index dad40be63..c7fe05795 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -244,9 +244,9 @@ struct Abc9Pass : public ScriptPass if (check_label("pre")) { run("scc -set_attr abc9_scc_id {}"); if (help_mode) - run("abc9_ops -break_scc -prep_holes [-dff]", "(option for -dff)"); + run("abc9_ops -mark_scc -prep_holes [-dff]", "(option for -dff)"); else - run("abc9_ops -break_scc -prep_holes" + std::string(dff_mode ? " -dff" : ""), "(option for -dff)"); + run("abc9_ops -mark_scc -prep_holes" + std::string(dff_mode ? " -dff" : ""), "(option for -dff)"); run("select -set abc9_holes A:abc9_holes"); run("flatten -wb @abc9_holes"); run("techmap @abc9_holes"); @@ -315,9 +315,6 @@ struct Abc9Pass : public ScriptPass active_design->selection_stack.pop_back(); } } - - if (check_label("post")) - run("abc9_ops -unbreak_scc"); } } Abc9Pass; diff --git a/passes/techmap/abc9_ops.cc b/passes/techmap/abc9_ops.cc index d7ebfdf3f..c7236486f 100644 --- a/passes/techmap/abc9_ops.cc +++ b/passes/techmap/abc9_ops.cc @@ -33,7 +33,7 @@ inline std::string remap_name(RTLIL::IdString abc9_name) return stringf("$abc$%d$%s", map_autoidx, abc9_name.c_str()+1); } -void break_scc(RTLIL::Module *module) +void mark_scc(RTLIL::Module *module) { // For every unique SCC found, (arbitrarily) find the first // cell in the component, and convert all wires driven by @@ -44,7 +44,8 @@ void break_scc(RTLIL::Module *module) auto it = cell->attributes.find(ID(abc9_scc_id)); if (it == cell->attributes.end()) continue; - auto r = ids_seen.insert(it->second); + auto id = it->second; + auto r = ids_seen.insert(id); cell->attributes.erase(it); if (!r.second) continue; @@ -54,6 +55,7 @@ void break_scc(RTLIL::Module *module) SigBit b = c.second.as_bit(); Wire *w = b.wire; w->set_bool_attribute(ID::keep); + w->attributes[ID(abc9_scc_id)] = id.as_int(); } } } @@ -61,28 +63,6 @@ void break_scc(RTLIL::Module *module) 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; @@ -676,21 +656,25 @@ void reintegrate(RTLIL::Module *module) // Stitch in mapped_mod's inputs/outputs into module for (auto port : mapped_mod->ports) { - RTLIL::Wire *w = mapped_mod->wire(port); + RTLIL::Wire *mapped_wire = mapped_mod->wire(port); RTLIL::Wire *wire = module->wire(port); log_assert(wire); + if (wire->attributes.erase(ID(abc9_scc_id))) { + auto r YS_ATTRIBUTE(unused) = wire->attributes.erase(ID::keep); + log_assert(r); + } RTLIL::Wire *remap_wire = module->wire(remap_name(port)); RTLIL::SigSpec signal(wire, 0, GetSize(remap_wire)); log_assert(GetSize(signal) >= GetSize(remap_wire)); RTLIL::SigSig conn; - if (w->port_output) { + if (mapped_wire->port_output) { conn.first = signal; conn.second = remap_wire; out_wires++; module->connect(conn); } - else if (w->port_input) { + else if (mapped_wire->port_input) { conn.first = remap_wire; conn.second = signal; in_wires++; @@ -791,8 +775,7 @@ struct Abc9OpsPass : public Pass { { log_header(design, "Executing ABC9_OPS pass (helper functions for ABC9).\n"); - bool break_scc_mode = false; - bool unbreak_scc_mode = false; + bool mark_scc_mode = false; bool prep_dff_mode = false; bool prep_holes_mode = false; bool reintegrate_mode = false; @@ -801,12 +784,8 @@ struct Abc9OpsPass : public Pass { 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; + if (arg == "-mark_scc") { + mark_scc_mode = true; continue; } if (arg == "-prep_dff") { @@ -829,8 +808,8 @@ struct Abc9OpsPass : public Pass { } extra_args(args, argidx, design); - if (!(break_scc_mode || unbreak_scc_mode || prep_dff_mode || reintegrate_mode)) - log_cmd_error("At least one of -{,un}break_scc, -prep_{dff,holes}, -reintegrate must be specified.\n"); + if (!(mark_scc_mode || prep_dff_mode || reintegrate_mode)) + log_cmd_error("At least one of -mark_scc, -prep_{dff,holes}, -reintegrate must be specified.\n"); if (dff_mode && !prep_holes_mode) log_cmd_error("'-dff' option is only relevant for -prep_holes.\n"); @@ -847,10 +826,8 @@ struct Abc9OpsPass : public Pass { if (!design->selected_whole_module(mod)) log_error("Can't handle partially selected module %s!\n", log_id(mod)); - if (break_scc_mode) - break_scc(mod); - if (unbreak_scc_mode) - unbreak_scc(mod); + if (mark_scc_mode) + mark_scc(mod); if (prep_dff_mode) prep_dff(mod); if (prep_holes_mode) -- cgit v1.2.3 From f63f76c372e8003f60565ee109d38ae1797d7e89 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 14 Jan 2020 09:01:53 -0800 Subject: read_aiger: also rename "$0" --- frontends/aiger/aigerparse.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc index 859dd5314..f6b2a639d 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(stringf("$aiger%d$0", aiger_autoidx)); if (n0) module->connect(n0, State::S0); @@ -383,7 +383,7 @@ void AigerReader::parse_xaiger() else log_abort(); - RTLIL::Wire* n0 = module->wire("$0"); + RTLIL::Wire* n0 = module->wire(stringf("$aiger%d$0", aiger_autoidx)); if (n0) module->connect(n0, State::S0); -- cgit v1.2.3 From 00964e999d5bc1825ff664e1514efcacb6d2e23f Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 14 Jan 2020 10:13:03 -0800 Subject: autoname: add testcase with $-prefix-ed port --- tests/various/autoname.ys | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 tests/various/autoname.ys diff --git a/tests/various/autoname.ys b/tests/various/autoname.ys new file mode 100644 index 000000000..830962e81 --- /dev/null +++ b/tests/various/autoname.ys @@ -0,0 +1,19 @@ +read_ilang < Date: Tue, 14 Jan 2020 10:13:29 -0800 Subject: autoname: do not autoname ports --- passes/cmds/autoname.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/cmds/autoname.cc b/passes/cmds/autoname.cc index 4614a8153..50632201e 100644 --- a/passes/cmds/autoname.cc +++ b/passes/cmds/autoname.cc @@ -56,7 +56,7 @@ int autoname_worker(Module *module) for (auto &conn : cell->connections()) { string suffix = stringf("_%s", log_id(conn.first)); for (auto bit : conn.second) - if (bit.wire != nullptr && bit.wire->name[0] == '$') { + if (bit.wire != nullptr && bit.wire->name[0] == '$' && !bit.wire->port_id) { IdString new_name(cell->name.str() + suffix); int score = wire_score.at(bit.wire); if (cell->output(conn.first)) score = 0; -- cgit v1.2.3 From a901a5fb44f146415ff45f9fed3f89ca3786b0da Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 14 Jan 2020 11:25:23 -0800 Subject: print_stats footer to return peak memory, option for including children --- kernel/driver.cc | 40 ++++++++++++---------------------------- 1 file changed, 12 insertions(+), 28 deletions(-) diff --git a/kernel/driver.cc b/kernel/driver.cc index 70a97c4b9..cf676a591 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -564,39 +564,23 @@ int main(int argc, char **argv) #ifdef _WIN32 log("End of script. Logfile hash: %s\n", hash.c_str()); #else - std::string meminfo; std::string stats_divider = ", "; -# if defined(__linux__) - std::ifstream statm; - statm.open(stringf("/proc/%lld/statm", (long long)getpid())); - if (statm.is_open()) { - int sz_total, sz_resident; - statm >> sz_total >> sz_resident; - meminfo = stringf(", MEM: %.2f MB total, %.2f MB resident", - sz_total * (getpagesize() / 1024.0 / 1024.0), - sz_resident * (getpagesize() / 1024.0 / 1024.0)); - stats_divider = "\n"; - } -# elif defined(__FreeBSD__) - pid_t pid = getpid(); - int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, (int)pid}; - struct kinfo_proc kip; - size_t kip_len = sizeof(kip); - if (sysctl(mib, 4, &kip, &kip_len, NULL, 0) == 0) { - vm_size_t sz_total = kip.ki_size; - segsz_t sz_resident = kip.ki_rssize; - meminfo = stringf(", MEM: %.2f MB total, %.2f MB resident", - (int)sz_total / 1024.0 / 1024.0, - (int)sz_resident * (getpagesize() / 1024.0 / 1024.0)); - stats_divider = "\n"; - } -# endif struct rusage ru_buffer; getrusage(RUSAGE_SELF, &ru_buffer); - log("End of script. Logfile hash: %s%sCPU: user %.2fs system %.2fs%s\n", hash.c_str(), + if (yosys_design->scratchpad_get_bool("print_stats.include_children")) { + struct rusage ru_buffer_children; + getrusage(RUSAGE_CHILDREN, &ru_buffer_children); + ru_buffer.ru_utime.tv_sec += ru_buffer_children.ru_utime.tv_sec; + ru_buffer.ru_utime.tv_usec += ru_buffer_children.ru_utime.tv_usec; + ru_buffer.ru_stime.tv_sec += ru_buffer_children.ru_stime.tv_sec; + ru_buffer.ru_stime.tv_usec += ru_buffer_children.ru_stime.tv_usec; + ru_buffer.ru_maxrss = std::max(ru_buffer.ru_maxrss, ru_buffer_children.ru_maxrss); + } + log("End of script. Logfile hash: %s%sCPU: user %.2fs system %.2fs, MEM: %.2f MB peak\n", hash.c_str(), stats_divider.c_str(), ru_buffer.ru_utime.tv_sec + 1e-6 * ru_buffer.ru_utime.tv_usec, - ru_buffer.ru_stime.tv_sec + 1e-6 * ru_buffer.ru_stime.tv_usec, meminfo.c_str()); + ru_buffer.ru_stime.tv_sec + 1e-6 * ru_buffer.ru_stime.tv_usec, + ru_buffer.ru_maxrss / 1024.0); #endif log("%s\n", yosys_version_str); -- cgit v1.2.3 From 36d1a2c60ff8179d9cfbdb1ae0ca5dd5d883991a Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 14 Jan 2020 11:34:40 -0800 Subject: synth_xilinx: fix default W value for non-xc7 --- techlibs/xilinx/synth_xilinx.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index d916093dc..b86484e71 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -562,7 +562,7 @@ struct SynthXilinxPass : public ScriptPass if (active_design->scratchpad.count(k)) abc9_opts += stringf(" -W %s", active_design->scratchpad_get_string(k).c_str()); else - abc9_opts += stringf(" -W %s", RTLIL::constpad.at(k).c_str()); + abc9_opts += stringf(" -W %s", RTLIL::constpad.at(k, RTLIL::constpad.at("synth_xilinx.abc9.xc7.W")).c_str()); if (nowidelut) abc9_opts += " -lut +/xilinx/abc9_xc7_nowide.lut"; else -- cgit v1.2.3 From ade57058f70590bb8353eda32d9b961a31c61fbc Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 14 Jan 2020 11:38:48 -0800 Subject: As before, only display MEM if Linux or FreeBSD --- kernel/driver.cc | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/kernel/driver.cc b/kernel/driver.cc index cf676a591..f0d495b46 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -564,6 +564,7 @@ int main(int argc, char **argv) #ifdef _WIN32 log("End of script. Logfile hash: %s\n", hash.c_str()); #else + std::string meminfo; std::string stats_divider = ", "; struct rusage ru_buffer; @@ -577,10 +578,13 @@ int main(int argc, char **argv) ru_buffer.ru_stime.tv_usec += ru_buffer_children.ru_stime.tv_usec; ru_buffer.ru_maxrss = std::max(ru_buffer.ru_maxrss, ru_buffer_children.ru_maxrss); } - log("End of script. Logfile hash: %s%sCPU: user %.2fs system %.2fs, MEM: %.2f MB peak\n", hash.c_str(), - stats_divider.c_str(), ru_buffer.ru_utime.tv_sec + 1e-6 * ru_buffer.ru_utime.tv_usec, - ru_buffer.ru_stime.tv_sec + 1e-6 * ru_buffer.ru_stime.tv_usec, +# if defined(__linux__) || defined(__FreeBSD__) + meminfo = stringf(", MEM: %.2f MB peak", ru_buffer.ru_maxrss / 1024.0); +#endif + log("End of script. Logfile hash: %s%sCPU: user %.2fs system %.2fs%s\n", hash.c_str(), + stats_divider.c_str(), ru_buffer.ru_utime.tv_sec + 1e-6 * ru_buffer.ru_utime.tv_usec, + ru_buffer.ru_stime.tv_sec + 1e-6 * ru_buffer.ru_stime.tv_usec, meminfo.c_str()); #endif log("%s\n", yosys_version_str); -- cgit v1.2.3 From d21262ee0439df761b054d46752c2c3d52e6f373 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 14 Jan 2020 12:22:21 -0800 Subject: Adding (* techmap_autopurge *) to FD* in abc9_map.v --- techlibs/xilinx/abc9_map.v | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/techlibs/xilinx/abc9_map.v b/techlibs/xilinx/abc9_map.v index 0652064cb..7dc027176 100644 --- a/techlibs/xilinx/abc9_map.v +++ b/techlibs/xilinx/abc9_map.v @@ -74,7 +74,7 @@ // (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); +module FDRE (output Q, (* techmap_autopurge *) 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; @@ -110,7 +110,7 @@ module FDRE (output Q, input C, CE, D, R); 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); +module FDRE_1 (output Q, (* techmap_autopurge *) input C, CE, D, R); parameter [0:0] INIT = 1'b0; wire QQ, $Q; generate if (INIT == 1'b1) begin @@ -138,7 +138,7 @@ module FDRE_1 (output Q, input C, CE, D, R); wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = QQ; endmodule -module FDSE (output Q, input C, CE, D, S); +module FDSE (output Q, (* techmap_autopurge *) 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; @@ -173,7 +173,7 @@ module FDSE (output Q, input C, CE, D, S); 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); +module FDSE_1 (output Q, (* techmap_autopurge *) input C, CE, D, S); parameter [0:0] INIT = 1'b1; wire QQ, $Q; generate if (INIT == 1'b1) begin @@ -200,7 +200,7 @@ module FDSE_1 (output Q, input C, CE, D, S); wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = QQ; endmodule -module FDCE (output Q, input C, CE, D, CLR); +module FDCE (output Q, (* techmap_autopurge *) input C, CE, D, CLR); parameter [0:0] INIT = 1'b0; parameter [0:0] IS_C_INVERTED = 1'b0; parameter [0:0] IS_D_INVERTED = 1'b0; @@ -249,7 +249,7 @@ module FDCE (output Q, input C, CE, D, CLR); 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); +module FDCE_1 (output Q, (* techmap_autopurge *) input C, CE, D, CLR); parameter [0:0] INIT = 1'b0; wire QQ, $Q, $QQ; generate if (INIT == 1'b1) begin @@ -288,7 +288,7 @@ module FDCE_1 (output Q, input C, CE, D, CLR); wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = $QQ; endmodule -module FDPE (output Q, input C, CE, D, PRE); +module FDPE (output Q, (* techmap_autopurge *) 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; @@ -335,7 +335,7 @@ module FDPE (output Q, input C, CE, D, PRE); 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); +module FDPE_1 (output Q, (* techmap_autopurge *) input C, CE, D, PRE); parameter [0:0] INIT = 1'b1; wire QQ, $Q, $QQ; generate if (INIT == 1'b1) begin -- cgit v1.2.3 From 468386d67d902722562e9a0412a76fca79ec4fa2 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 14 Jan 2020 12:25:45 -0800 Subject: abc9_ops: -prep_holes -> -prep_xaiger, move padding to write_xaiger --- backends/aiger/xaiger.cc | 9 ++- passes/techmap/abc9.cc | 4 +- passes/techmap/abc9_ops.cc | 173 +++++++++++++++++++-------------------------- 3 files changed, 79 insertions(+), 107 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 822ba4dec..2d908e33b 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -329,12 +329,11 @@ struct XAigerWriter } } - // Fully pad all unused input connections of this box cell with S0 - // Fully pad all undriven output connections of this box cell with anonymous wires for (auto port_name : r.first->second) { auto w = box_module->wire(port_name); log_assert(w); - auto rhs = cell->getPort(port_name); + auto rhs = cell->connections_.at(port_name, SigSpec()); + rhs.append(Const(State::Sx, GetSize(w)-GetSize(rhs))); if (w->port_input) for (auto b : rhs) { SigBit I = sigmap(b); @@ -429,6 +428,10 @@ struct XAigerWriter for (auto &bit : ci_bits) { aig_m++, aig_i++; + // 1'bx may exist here due to a box output + // that has been padded to its full width + if (bit == State::Sx) + continue; log_assert(!aig_map.count(bit)); aig_map[bit] = 2*aig_m; } diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index c7fe05795..6a296bfe7 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -244,9 +244,9 @@ struct Abc9Pass : public ScriptPass if (check_label("pre")) { run("scc -set_attr abc9_scc_id {}"); if (help_mode) - run("abc9_ops -mark_scc -prep_holes [-dff]", "(option for -dff)"); + run("abc9_ops -mark_scc -prep_xaiger [-dff]", "(option for -dff)"); else - run("abc9_ops -mark_scc -prep_holes" + std::string(dff_mode ? " -dff" : ""), "(option for -dff)"); + run("abc9_ops -mark_scc -prep_xaiger" + std::string(dff_mode ? " -dff" : ""), "(option for -dff)"); run("select -set abc9_holes A:abc9_holes"); run("flatten -wb @abc9_holes"); run("techmap @abc9_holes"); diff --git a/passes/techmap/abc9_ops.cc b/passes/techmap/abc9_ops.cc index cc82a72cf..405f3e267 100644 --- a/passes/techmap/abc9_ops.cc +++ b/passes/techmap/abc9_ops.cc @@ -143,7 +143,7 @@ void prep_dff(RTLIL::Module *module) } } -void prep_holes(RTLIL::Module *module, bool dff) +void prep_xaiger(RTLIL::Module *module, bool dff) { auto design = module->design; log_assert(design); @@ -152,7 +152,7 @@ void prep_holes(RTLIL::Module *module, bool dff) dict> bit_drivers, bit_users; TopoSort toposort; - bool abc9_box_seen = false; + dict> box_ports; for (auto cell : module->cells()) { if (cell->type == "$__ABC9_FF_") @@ -165,7 +165,40 @@ void prep_holes(RTLIL::Module *module, bool dff) abc9_flop = inst_module->get_bool_attribute("\\abc9_flop"); if (abc9_flop && !dff) continue; - abc9_box_seen = abc9_box; + + 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 : inst_module->ports) { + auto w = inst_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(inst_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(inst_module)); + carry_out = port_name; + } + } + else + r.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(inst_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(inst_module)); + if (carry_in != IdString()) { + r.first->second.push_back(carry_in); + r.first->second.push_back(carry_out); + } + } } else if (!yosys_celltypes.cell_known(cell->type)) continue; @@ -183,7 +216,7 @@ void prep_holes(RTLIL::Module *module, bool dff) toposort.node(cell->name); } - if (!abc9_box_seen) + if (box_ports.empty()) return; for (auto &it : bit_users) @@ -211,7 +244,13 @@ void prep_holes(RTLIL::Module *module, bool dff) log_assert(no_loops); - vector box_list; + 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 cell_cache; + + int port_id = 1, box_count = 0; for (auto cell_name : toposort.sorted) { RTLIL::Cell *cell = module->cell(cell_name); log_assert(cell); @@ -220,62 +259,10 @@ void prep_holes(RTLIL::Module *module, bool dff) if (!box_module || !box_module->attributes.count("\\abc9_box_id")) continue; - bool blackbox = box_module->get_blackbox_attribute(true /* ignore_wb */); - - // Fully pad all unused input connections of this box cell with S0 - // Fully pad all undriven output connections of this box cell with anonymous wires - for (const auto &port_name : box_module->ports) { - RTLIL::Wire* 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->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); - } - } - } - - 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"); + cell->attributes["\\abc9_box_seq"] = box_count++; - dict cell_cache; - dict> 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); + IdString derived_name = box_module->derive(design, cell->parameters); + box_module = design->module(derived_name); auto r = cell_cache.insert(derived_name); auto &holes_cell = r.first->second; @@ -283,40 +270,6 @@ void prep_holes(RTLIL::Module *module, bool dff) if (box_module->has_processes()) Pass::call_on_module(design, box_module, "proc"); - 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); - } - } - if (box_module->get_bool_attribute("\\whitebox")) { holes_cell = holes_module->addCell(cell->name, derived_name); @@ -770,6 +723,22 @@ struct Abc9OpsPass : public Pass { log("\n"); log(" abc9_ops [options] [selection]\n"); log("\n"); + log("This pass contains a set of supporting operations for use during ABC technology\n"); + log("mapping, and is expected to be called in conjunction with other operations from\n"); + log("the `abc9' script pass. Only fully-selected modules are supported.\n"); + log("\n"); + log(" -mark_scc\n"); + log(" for an arbitrarily chosen cell in each unique SCC of each selected module\n"); + log(" (tagged with an (* abc9_scc_id = *) attribute), temporarily mark all\n"); + log(" wires driven by this cell's outputs with a (* keep *) attribute in order\n"); + log(" to break the SCC. this temporary attribute will be removed on -reintegrate.\n"); + log("\n"); + log(" -prep_xaiger\n"); + log(" prepare the design for XAIGER output. this includes computing the\n"); + log(" topological ordering of ABC9 boxes, as well as preparing the\n"); + log(" '$holes' module that contains the logic behaviour of ABC9\n"); + log(" whiteboxes.\n"); + log("\n"); } void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE { @@ -777,7 +746,7 @@ struct Abc9OpsPass : public Pass { bool mark_scc_mode = false; bool prep_dff_mode = false; - bool prep_holes_mode = false; + bool prep_xaiger_mode = false; bool reintegrate_mode = false; bool dff_mode = false; @@ -792,8 +761,8 @@ struct Abc9OpsPass : public Pass { prep_dff_mode = true; continue; } - if (arg == "-prep_holes") { - prep_holes_mode = true; + if (arg == "-prep_xaiger") { + prep_xaiger_mode = true; continue; } if (arg == "-reintegrate") { @@ -809,10 +778,10 @@ struct Abc9OpsPass : public Pass { extra_args(args, argidx, design); if (!(mark_scc_mode || prep_dff_mode || reintegrate_mode)) - log_cmd_error("At least one of -mark_scc, -prep_{dff,holes}, -reintegrate must be specified.\n"); + log_cmd_error("At least one of -mark_scc, -prep_{xaiger,dff}, -reintegrate must be specified.\n"); - if (dff_mode && !prep_holes_mode) - log_cmd_error("'-dff' option is only relevant for -prep_holes.\n"); + if (dff_mode && !prep_xaiger_mode) + log_cmd_error("'-dff' option is only relevant for -prep_xaiger.\n"); for (auto mod : design->selected_modules()) { if (mod->get_bool_attribute("\\abc9_holes")) @@ -830,8 +799,8 @@ struct Abc9OpsPass : public Pass { mark_scc(mod); if (prep_dff_mode) prep_dff(mod); - if (prep_holes_mode) - prep_holes(mod, dff_mode); + if (prep_xaiger_mode) + prep_xaiger(mod, dff_mode); if (reintegrate_mode) reintegrate(mod); } -- cgit v1.2.3 From 654247abe9078566f93960a135ce08b0cfc96442 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 14 Jan 2020 12:40:36 -0800 Subject: abc9_ops/write_xaiger: update doc --- backends/aiger/xaiger.cc | 3 ++- passes/techmap/abc9_ops.cc | 13 +++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 2d908e33b..f9890a592 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -740,7 +740,8 @@ struct XAigerBackend : public Backend { log("Write the top module (according to the (* top *) attribute or if only one module\n"); log("is currently selected) to an XAIGER file. Any non $_NOT_, $_AND_, $_ABC9_FF_, or"); log("non (* abc9_box_id *) cells will be converted into psuedo-inputs and\n"); - log("pseudo-outputs.\n"); + log("pseudo-outputs. Whitebox contents will be taken from the '$holes'\n"); + log("module, if it exists.\n"); log("\n"); log(" -ascii\n"); log(" write ASCII version of AIGER format\n"); diff --git a/passes/techmap/abc9_ops.cc b/passes/techmap/abc9_ops.cc index 405f3e267..463941b0b 100644 --- a/passes/techmap/abc9_ops.cc +++ b/passes/techmap/abc9_ops.cc @@ -739,6 +739,19 @@ struct Abc9OpsPass : public Pass { log(" '$holes' module that contains the logic behaviour of ABC9\n"); log(" whiteboxes.\n"); log("\n"); + log(" -dff\n"); + log(" consider flop cells (those instantiating modules marked with (* abc9_flop *)\n"); + log(" during -prep_xaiger.\n"); + log("\n"); + log(" -prep_dff\n"); + log(" compute the clock domain and initial value of each flop in the design.\n"); + log(" process the '$holes' module to support clock-enable functionality.\n"); + log("\n"); + log(" -reintegrate\n"); + log(" for each selected module, re-intergrate the module '$abc9'\n"); + log(" by first recovering ABC9 boxes, and then stitching in the remaining primary\n"); + log(" inputs and outputs.\n"); + log("\n"); } void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE { -- cgit v1.2.3 From a5d2358a60084361902583f4fa024d2d53ce6c2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20Ko=C5=9Bcielnicki?= Date: Tue, 14 Jan 2020 22:48:40 +0100 Subject: fsm_detect: Add a cache to avoid excessive CPU usage for big mux networks. Fixes #1634. --- passes/fsm/fsm_detect.cc | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/passes/fsm/fsm_detect.cc b/passes/fsm/fsm_detect.cc index fb3896669..a1c8067b4 100644 --- a/passes/fsm/fsm_detect.cc +++ b/passes/fsm/fsm_detect.cc @@ -34,13 +34,20 @@ static SigSet sig2driver, sig2user; static std::set muxtree_cells; static SigPool sig_at_port; -static bool check_state_mux_tree(RTLIL::SigSpec old_sig, RTLIL::SigSpec sig, pool &recursion_monitor) +static bool check_state_mux_tree(RTLIL::SigSpec old_sig, RTLIL::SigSpec sig, pool &recursion_monitor, dict &mux_tree_cache) { + if (mux_tree_cache.find(sig) != mux_tree_cache.end()) + return mux_tree_cache.at(sig); + if (sig.is_fully_const() || old_sig == sig) { +ret_true: + mux_tree_cache[sig] = true; return true; } if (sig_at_port.check_any(assign_map(sig))) { +ret_false: + mux_tree_cache[sig] = false; return false; } @@ -49,13 +56,13 @@ static bool check_state_mux_tree(RTLIL::SigSpec old_sig, RTLIL::SigSpec sig, poo for (auto &cellport : cellport_list) { if ((cellport.first->type != "$mux" && cellport.first->type != "$pmux") || cellport.second != "\\Y") { - return false; + goto ret_false; } if (recursion_monitor.count(cellport.first)) { log_warning("logic loop in mux tree at signal %s in module %s.\n", log_signal(sig), RTLIL::id2cstr(module->name)); - return false; + goto ret_false; } recursion_monitor.insert(cellport.first); @@ -63,22 +70,22 @@ static bool check_state_mux_tree(RTLIL::SigSpec old_sig, RTLIL::SigSpec sig, poo RTLIL::SigSpec sig_a = assign_map(cellport.first->getPort("\\A")); RTLIL::SigSpec sig_b = assign_map(cellport.first->getPort("\\B")); - if (!check_state_mux_tree(old_sig, sig_a, recursion_monitor)) { + if (!check_state_mux_tree(old_sig, sig_a, recursion_monitor, mux_tree_cache)) { recursion_monitor.erase(cellport.first); - return false; + goto ret_false; } for (int i = 0; i < sig_b.size(); i += sig_a.size()) - if (!check_state_mux_tree(old_sig, sig_b.extract(i, sig_a.size()), recursion_monitor)) { + if (!check_state_mux_tree(old_sig, sig_b.extract(i, sig_a.size()), recursion_monitor, mux_tree_cache)) { recursion_monitor.erase(cellport.first); - return false; + goto ret_false; } recursion_monitor.erase(cellport.first); muxtree_cells.insert(cellport.first); } - return true; + goto ret_true; } static bool check_state_users(RTLIL::SigSpec sig) @@ -143,11 +150,12 @@ static void detect_fsm(RTLIL::Wire *wire) pool recursion_monitor; RTLIL::SigSpec sig_q = assign_map(cellport.first->getPort("\\Q")); RTLIL::SigSpec sig_d = assign_map(cellport.first->getPort("\\D")); + dict mux_tree_cache; if (sig_q != assign_map(wire)) continue; - looks_like_state_reg = check_state_mux_tree(sig_q, sig_d, recursion_monitor); + looks_like_state_reg = check_state_mux_tree(sig_q, sig_d, recursion_monitor, mux_tree_cache); looks_like_good_state_reg = check_state_users(sig_q); if (!looks_like_state_reg) -- cgit v1.2.3 From 4656f202c6f05d126c1acc79fca675e467c80840 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 14 Jan 2020 14:27:29 -0800 Subject: abc9_ops: -reintegrate to not trim box padding anymore --- backends/aiger/xaiger.cc | 2 +- passes/techmap/abc9_ops.cc | 9 --------- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index f9890a592..4f466d568 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -349,7 +349,7 @@ struct XAigerWriter unused_bits.erase(I); } if (w->port_output) - for (const auto &b : rhs.bits()) { + for (const auto &b : rhs) { SigBit O = sigmap(b); if (O != b) alias_map[O] = b; diff --git a/passes/techmap/abc9_ops.cc b/passes/techmap/abc9_ops.cc index 463941b0b..aa21ff283 100644 --- a/passes/techmap/abc9_ops.cc +++ b/passes/techmap/abc9_ops.cc @@ -562,15 +562,6 @@ void reintegrate(RTLIL::Module *module) c.wire = module->wires_.at(remap_name(c.wire->name)); newsig.append(c); } - - auto it = existing_cell->connections_.find(port_name); - if (it == existing_cell->connections_.end()) - continue; - if (GetSize(newsig) > GetSize(it->second)) - newsig = newsig.extract(0, GetSize(it->second)); - else - log_assert(GetSize(newsig) == GetSize(it->second)); - cell->setPort(port_name, newsig); if (w->port_input && !abc9_flop) -- cgit v1.2.3 From 1c41dc6b95c4c0261db96c15dd1b3cce8de6491f Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 14 Jan 2020 16:17:27 -0800 Subject: write_xaiger: do not export flop inputs as POs --- backends/aiger/xaiger.cc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 4f466d568..c3fc61e3b 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -226,6 +226,7 @@ struct XAigerWriter } if (inst_module) { + bool abc9_flop = inst_module->get_bool_attribute("\\abc9_flop"); auto it = cell->attributes.find("\\abc9_box_seq"); if (it != cell->attributes.end()) { int abc9_box_seq = it->second.as_int(); @@ -233,7 +234,7 @@ struct XAigerWriter box_list.resize(abc9_box_seq+1); box_list[abc9_box_seq] = cell; // Only flop boxes may have arrival times - if (!inst_module->get_bool_attribute("\\abc9_flop")) + if (!abc9_flop) continue; } @@ -256,6 +257,9 @@ struct XAigerWriter for (auto bit : sigmap(conn.second)) arrival_times[bit] = arrival; } + + if (abc9_flop) + continue; } } @@ -591,7 +595,7 @@ struct XAigerWriter // For flops only, create an extra 1-bit input that drives a new wire // called ".abc9_ff.Q" that is used below if (box_module->get_bool_attribute("\\abc9_flop")) - box_inputs++; + box_inputs++; std::get<0>(v) = box_inputs; std::get<1>(v) = box_outputs; -- cgit v1.2.3 From d6da9c0c0f3b59706f509b7fd96ea793491a2307 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 15 Jan 2020 11:25:20 -0800 Subject: write_xaiger: skip abc9_flop only if abc_box_seq present --- backends/aiger/xaiger.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index c3fc61e3b..a9b75ecc7 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -226,7 +226,7 @@ struct XAigerWriter } if (inst_module) { - bool abc9_flop = inst_module->get_bool_attribute("\\abc9_flop"); + bool abc9_flop = false; auto it = cell->attributes.find("\\abc9_box_seq"); if (it != cell->attributes.end()) { int abc9_box_seq = it->second.as_int(); @@ -234,6 +234,7 @@ struct XAigerWriter box_list.resize(abc9_box_seq+1); box_list[abc9_box_seq] = cell; // Only flop boxes may have arrival times + abc9_flop = inst_module->get_bool_attribute("\\abc9_flop"); if (!abc9_flop) continue; } -- cgit v1.2.3 From 05c8858a907f0f188f1687ede260c2e1a97efe38 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 15 Jan 2020 14:31:32 -0800 Subject: read_aiger: $lut prefix in front --- frontends/aiger/aigerparse.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc index f6b2a639d..a4b1e6fec 100644 --- a/frontends/aiger/aigerparse.cc +++ b/frontends/aiger/aigerparse.cc @@ -1001,9 +1001,9 @@ void AigerReader::post_process() if (cell->type != "$lut") continue; auto y_port = cell->getPort("\\Y").as_bit(); if (y_port.wire->width == 1) - module->rename(cell, stringf("%s$lut", y_port.wire->name.c_str())); + module->rename(cell, stringf("$lut%s", y_port.wire->name.c_str())); else - module->rename(cell, stringf("%s[%d]$lut", y_port.wire->name.c_str(), y_port.offset)); + module->rename(cell, stringf("$lut%s[%d]", y_port.wire->name.c_str(), y_port.offset)); } } -- cgit v1.2.3 From 5918ede9bd7568d5a5156f20fdc4ce215d4968f8 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 15 Jan 2020 14:36:05 -0800 Subject: abc9: aAdd test to check $_NOT_s are absorbed --- tests/techmap/abc9.ys | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/techmap/abc9.ys b/tests/techmap/abc9.ys index 20f263da8..62b5dfef6 100644 --- a/tests/techmap/abc9.ys +++ b/tests/techmap/abc9.ys @@ -38,3 +38,15 @@ abc9 -lut 4 design -load gold scratchpad -copy abc9.script.flow3 abc9.script abc9 -lut 4 + + +design -reset +read_verilog -icells < Date: Fri, 17 Jan 2020 11:14:19 -0800 Subject: +/xilinx/arith_map.v fix $lcu rule --- techlibs/xilinx/arith_map.v | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/techlibs/xilinx/arith_map.v b/techlibs/xilinx/arith_map.v index 5c848d4e6..c345a3da3 100644 --- a/techlibs/xilinx/arith_map.v +++ b/techlibs/xilinx/arith_map.v @@ -53,9 +53,9 @@ module _80_xilinx_lcu (P, G, CI, CO); ( .CYINIT(CI), .CI (1'd0), - .DI (G [(Y_WIDTH - 1):i*4]), - .S (S [(Y_WIDTH - 1):i*4]), - .CO (CO[(Y_WIDTH - 1):i*4]), + .DI (G [(WIDTH - 1):i*4]), + .S (S [(WIDTH - 1):i*4]), + .CO (CO[(WIDTH - 1):i*4]), ); // Another one end else begin @@ -63,9 +63,9 @@ module _80_xilinx_lcu (P, G, CI, CO); ( .CYINIT(1'd0), .CI (C [i*4 - 1]), - .DI (G [(Y_WIDTH - 1):i*4]), - .S (S [(Y_WIDTH - 1):i*4]), - .CO (CO[(Y_WIDTH - 1):i*4]), + .DI (G [(WIDTH - 1):i*4]), + .S (S [(WIDTH - 1):i*4]), + .CO (CO[(WIDTH - 1):i*4]), ); end -- cgit v1.2.3 From d4e188299ba729756ee689d14c81aab68a7ca1b7 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 17 Jan 2020 12:00:14 -0800 Subject: abc9: add some log_{push,pop}() as per @nakengelhardt --- passes/techmap/abc9.cc | 5 +++++ passes/techmap/alumacc.cc | 19 ++++++++++++++----- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 6a296bfe7..f4a89efff 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -235,8 +235,11 @@ struct Abc9Pass : public ScriptPass extra_args(args, argidx, design); log_header(design, "Executing ABC9 pass.\n"); + log_push(); run_script(design, run_from, run_to); + + log_pop(); } void script() YS_OVERRIDE @@ -276,6 +279,7 @@ struct Abc9Pass : public ScriptPass } log_assert(!mod->attributes.count(ID(abc9_box_id))); + log_push(); active_design->selection().select(mod); if (!active_design->selected_whole_module(mod)) @@ -310,6 +314,7 @@ struct Abc9Pass : public ScriptPass } active_design->selection().selected_modules.clear(); + log_pop(); } active_design->selection_stack.pop_back(); diff --git a/passes/techmap/alumacc.cc b/passes/techmap/alumacc.cc index 034731b87..cf2ac16c9 100644 --- a/passes/techmap/alumacc.cc +++ b/passes/techmap/alumacc.cc @@ -397,18 +397,21 @@ struct AlumaccWorker { log(" creating $alu model for %s (%s):", log_id(cell), log_id(cell->type)); - bool cmp_less = cell->type.in(ID($lt), ID($le)); - bool cmp_equal = cell->type.in(ID($le), ID($ge)); + bool cmp_less = false; //cell->type.in(ID($lt), ID($le)); + bool cmp_equal = false; //cell->type.in(ID($le), ID($ge)); bool is_signed = cell->getParam(ID(A_SIGNED)).as_bool(); RTLIL::SigSpec A = sigmap(cell->getPort(ID::A)); RTLIL::SigSpec B = sigmap(cell->getPort(ID::B)); RTLIL::SigSpec Y = sigmap(cell->getPort(ID::Y)); - if (B < A && GetSize(B)) { - cmp_less = !cmp_less; + if (cell->type.in(ID($lt), ID($ge))) std::swap(A, B); - } + + //if (B < A && GetSize(B)) { + // cmp_less = !cmp_less; + // std::swap(A, B); + //} alunode_t *n = nullptr; @@ -432,6 +435,12 @@ struct AlumaccWorker log(" merged with %s.\n", log_id(n->cells.front())); } + if (cell->type.in(ID($le), ID($ge))) { + SigSpec YY = module->addWire(NEW_ID, GetSize(Y)); + module->addNot(NEW_ID, YY, Y); + Y = YY; + } + n->cells.push_back(cell); n->cmp.push_back(std::make_tuple(cmp_less, !cmp_less, cmp_equal, false, Y)); } -- cgit v1.2.3 From 5c589244df2ec4fc5fde0bcdc69dee727f4b8e79 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 17 Jan 2020 12:02:46 -0800 Subject: Deprecate `_CLB_CARRY from +/xilinx/arith_map.v since #1623 --- techlibs/xilinx/arith_map.v | 199 +++++++++++++++++----------------------- techlibs/xilinx/synth_xilinx.cc | 2 - 2 files changed, 82 insertions(+), 119 deletions(-) diff --git a/techlibs/xilinx/arith_map.v b/techlibs/xilinx/arith_map.v index c345a3da3..40c378d16 100644 --- a/techlibs/xilinx/arith_map.v +++ b/techlibs/xilinx/arith_map.v @@ -33,7 +33,21 @@ module _80_xilinx_lcu (P, G, CI, CO); genvar i; -`ifdef _CLB_CARRY +`ifdef _EXPLICIT_CARRY + + wire [WIDTH-1:0] C = {CO, CI}; + wire [WIDTH-1:0] S = P & ~G; + + generate for (i = 0; i < WIDTH; i = i + 1) begin:slice + MUXCY muxcy ( + .CI(C[i]), + .DI(G[i]), + .S(S[i]), + .O(CO[i]) + ); + end endgenerate + +`else localparam CARRY4_COUNT = (WIDTH + 3) / 4; localparam MAX_WIDTH = CARRY4_COUNT * 4; @@ -97,34 +111,6 @@ module _80_xilinx_lcu (P, G, CI, CO); end end endgenerate - -`elsif _EXPLICIT_CARRY - - wire [WIDTH-1:0] C = {CO, CI}; - wire [WIDTH-1:0] S = P & ~G; - - generate for (i = 0; i < WIDTH; i = i + 1) begin:slice - MUXCY muxcy ( - .CI(C[i]), - .DI(G[i]), - .S(S[i]), - .O(CO[i]) - ); - end endgenerate - -`else - - wire [WIDTH-1:0] C = {CO, CI}; - wire [WIDTH-1:0] S = P & ~G; - - generate for (i = 0; i < WIDTH; i = i + 1) begin:slice - MUXCY muxcy ( - .CI(C[i]), - .DI(G[i]), - .S(S[i]), - .O(CO[i]) - ); - end endgenerate `endif endmodule @@ -161,79 +147,7 @@ module _80_xilinx_alu (A, B, CI, BI, X, Y, CO); genvar i; -`ifdef _CLB_CARRY - - localparam CARRY4_COUNT = (Y_WIDTH + 3) / 4; - localparam MAX_WIDTH = CARRY4_COUNT * 4; - localparam PAD_WIDTH = MAX_WIDTH - Y_WIDTH; - - wire [MAX_WIDTH-1:0] S = {{PAD_WIDTH{1'b0}}, AA ^ BB}; - wire [MAX_WIDTH-1:0] DI = {{PAD_WIDTH{1'b0}}, AA & BB}; - - wire [MAX_WIDTH-1:0] C = CO; - - genvar i; - generate for (i = 0; i < CARRY4_COUNT; i = i + 1) begin:slice - - // Partially occupied CARRY4 - if ((i+1)*4 > Y_WIDTH) begin - - // First one - if (i == 0) begin - CARRY4 carry4_1st_part - ( - .CYINIT(CI), - .CI (1'd0), - .DI (DI[(Y_WIDTH - 1):i*4]), - .S (S [(Y_WIDTH - 1):i*4]), - .O (Y [(Y_WIDTH - 1):i*4]), - .CO (CO[(Y_WIDTH - 1):i*4]) - ); - // Another one - end else begin - CARRY4 carry4_part - ( - .CYINIT(1'd0), - .CI (C [i*4 - 1]), - .DI (DI[(Y_WIDTH - 1):i*4]), - .S (S [(Y_WIDTH - 1):i*4]), - .O (Y [(Y_WIDTH - 1):i*4]), - .CO (CO[(Y_WIDTH - 1):i*4]) - ); - end - - // Fully occupied CARRY4 - end else begin - - // First one - if (i == 0) begin - CARRY4 carry4_1st_full - ( - .CYINIT(CI), - .CI (1'd0), - .DI (DI[((i+1)*4 - 1):i*4]), - .S (S [((i+1)*4 - 1):i*4]), - .O (Y [((i+1)*4 - 1):i*4]), - .CO (CO[((i+1)*4 - 1):i*4]) - ); - // Another one - end else begin - CARRY4 carry4_full - ( - .CYINIT(1'd0), - .CI (C [i*4 - 1]), - .DI (DI[((i+1)*4 - 1):i*4]), - .S (S [((i+1)*4 - 1):i*4]), - .O (Y [((i+1)*4 - 1):i*4]), - .CO (CO[((i+1)*4 - 1):i*4]) - ); - end - - end - - end endgenerate - -`elsif _EXPLICIT_CARRY +`ifdef _EXPLICIT_CARRY wire [Y_WIDTH-1:0] S = AA ^ BB; wire [Y_WIDTH-1:0] DI = AA & BB; @@ -333,23 +247,74 @@ module _80_xilinx_alu (A, B, CI, BI, X, Y, CO); `else - wire [Y_WIDTH-1:0] S = AA ^ BB; - wire [Y_WIDTH-1:0] DI = AA & BB; + localparam CARRY4_COUNT = (Y_WIDTH + 3) / 4; + localparam MAX_WIDTH = CARRY4_COUNT * 4; + localparam PAD_WIDTH = MAX_WIDTH - Y_WIDTH; - wire [Y_WIDTH-1:0] C = {CO, CI}; + wire [MAX_WIDTH-1:0] S = {{PAD_WIDTH{1'b0}}, AA ^ BB}; + wire [MAX_WIDTH-1:0] DI = {{PAD_WIDTH{1'b0}}, AA & BB}; + + wire [MAX_WIDTH-1:0] C = CO; + + genvar i; + generate for (i = 0; i < CARRY4_COUNT; i = i + 1) begin:slice + + // Partially occupied CARRY4 + if ((i+1)*4 > Y_WIDTH) begin + + // First one + if (i == 0) begin + CARRY4 carry4_1st_part + ( + .CYINIT(CI), + .CI (1'd0), + .DI (DI[(Y_WIDTH - 1):i*4]), + .S (S [(Y_WIDTH - 1):i*4]), + .O (Y [(Y_WIDTH - 1):i*4]), + .CO (CO[(Y_WIDTH - 1):i*4]) + ); + // Another one + end else begin + CARRY4 carry4_part + ( + .CYINIT(1'd0), + .CI (C [i*4 - 1]), + .DI (DI[(Y_WIDTH - 1):i*4]), + .S (S [(Y_WIDTH - 1):i*4]), + .O (Y [(Y_WIDTH - 1):i*4]), + .CO (CO[(Y_WIDTH - 1):i*4]) + ); + end + + // Fully occupied CARRY4 + end else begin + + // First one + if (i == 0) begin + CARRY4 carry4_1st_full + ( + .CYINIT(CI), + .CI (1'd0), + .DI (DI[((i+1)*4 - 1):i*4]), + .S (S [((i+1)*4 - 1):i*4]), + .O (Y [((i+1)*4 - 1):i*4]), + .CO (CO[((i+1)*4 - 1):i*4]) + ); + // Another one + end else begin + CARRY4 carry4_full + ( + .CYINIT(1'd0), + .CI (C [i*4 - 1]), + .DI (DI[((i+1)*4 - 1):i*4]), + .S (S [((i+1)*4 - 1):i*4]), + .O (Y [((i+1)*4 - 1):i*4]), + .CO (CO[((i+1)*4 - 1):i*4]) + ); + end + + end - generate for (i = 0; i < Y_WIDTH; i = i + 1) begin:slice - MUXCY muxcy ( - .CI(C[i]), - .DI(DI[i]), - .S(S[i]), - .O(CO[i]) - ); - XORCY xorcy ( - .CI(C[i]), - .LI(S[i]), - .O(Y[i]) - ); end endgenerate `endif diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index 3dc05cd10..5c3b5179d 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -518,8 +518,6 @@ struct SynthXilinxPass : public ScriptPass techmap_args += " -map +/xilinx/arith_map.v"; if (vpr) techmap_args += " -D _EXPLICIT_CARRY"; - else - techmap_args += " -D _CLB_CARRY"; } run("techmap " + techmap_args); run("opt -fast"); -- cgit v1.2.3 From 6692e5d558e7c7277153b7a3bd1623af0e57405d Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 17 Jan 2020 15:28:02 -0800 Subject: ice40_dsp: tolerant of fanout-less outputs, as well as all-zero inputs --- passes/pmgen/ice40_dsp.pmg | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/passes/pmgen/ice40_dsp.pmg b/passes/pmgen/ice40_dsp.pmg index 6b6d2b56f..9514e65d9 100644 --- a/passes/pmgen/ice40_dsp.pmg +++ b/passes/pmgen/ice40_dsp.pmg @@ -57,6 +57,9 @@ code sigA sigB sigH sigH.append(O[i]); } log_assert(nusers(O.extract_end(i)) <= 1); + + if (sigH.empty()) + reject; endcode code argQ ffA ffAholdmux ffArstmux ffAholdpol ffArstpol sigA clock clock_pol @@ -328,6 +331,8 @@ arg argD argQ clock clock_pol code dff = nullptr; + if (argQ.empty()) + reject; for (auto c : argQ.chunks()) { if (!c.wire) reject; -- cgit v1.2.3 From 4985318263a8113563c9c62c60a9d4d6ee0a4f4e Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 17 Jan 2020 15:37:52 -0800 Subject: ice40_dsp: add default values for parameters --- passes/pmgen/ice40_dsp.cc | 8 ++++---- passes/pmgen/ice40_dsp.pmg | 14 +++++++------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/passes/pmgen/ice40_dsp.cc b/passes/pmgen/ice40_dsp.cc index f60e67158..202a43f0c 100644 --- a/passes/pmgen/ice40_dsp.cc +++ b/passes/pmgen/ice40_dsp.cc @@ -73,11 +73,11 @@ void create_ice40_dsp(ice40_dsp_pm &pm) // SB_MAC16 Input Interface SigSpec A = st.sigA; - A.extend_u0(16, st.mul->getParam(ID(A_SIGNED)).as_bool()); + A.extend_u0(16, st.mul->connections_.at(ID(A_SIGNED), State::S0).as_bool()); log_assert(GetSize(A) == 16); SigSpec B = st.sigB; - B.extend_u0(16, st.mul->getParam(ID(B_SIGNED)).as_bool()); + B.extend_u0(16, st.mul->connections_.at(ID(B_SIGNED), State::S0).as_bool()); log_assert(GetSize(B) == 16); SigSpec CD = st.sigCD; @@ -248,8 +248,8 @@ void create_ice40_dsp(ice40_dsp_pm &pm) cell->setParam(ID(BOTADDSUB_CARRYSELECT), Const(0, 2)); cell->setParam(ID(MODE_8x8), State::S0); - cell->setParam(ID(A_SIGNED), st.mul->getParam(ID(A_SIGNED)).as_bool()); - cell->setParam(ID(B_SIGNED), st.mul->getParam(ID(B_SIGNED)).as_bool()); + cell->setParam(ID(A_SIGNED), st.mul->parameters.at(ID(A_SIGNED), State::S0).as_bool()); + cell->setParam(ID(B_SIGNED), st.mul->parameters.at(ID(B_SIGNED), State::S0).as_bool()); if (st.ffO) { if (st.o_lo) diff --git a/passes/pmgen/ice40_dsp.pmg b/passes/pmgen/ice40_dsp.pmg index 9514e65d9..fca307453 100644 --- a/passes/pmgen/ice40_dsp.pmg +++ b/passes/pmgen/ice40_dsp.pmg @@ -63,7 +63,7 @@ code sigA sigB sigH endcode code argQ ffA ffAholdmux ffArstmux ffAholdpol ffArstpol sigA clock clock_pol - if (mul->type != \SB_MAC16 || !param(mul, \A_REG).as_bool()) { + if (mul->type != \SB_MAC16 || !param(mul, \A_REG, State::S0).as_bool()) { argQ = sigA; subpattern(in_dffe); if (dff) { @@ -84,7 +84,7 @@ code argQ ffA ffAholdmux ffArstmux ffAholdpol ffArstpol sigA clock clock_pol endcode code argQ ffB ffBholdmux ffBrstmux ffBholdpol ffBrstpol sigB clock clock_pol - if (mul->type != \SB_MAC16 || !param(mul, \B_REG).as_bool()) { + if (mul->type != \SB_MAC16 || !param(mul, \B_REG, State::S0).as_bool()) { argQ = sigB; subpattern(in_dffe); if (dff) { @@ -107,7 +107,7 @@ endcode code argD ffFJKG sigH clock clock_pol if (nusers(sigH) == 2 && (mul->type != \SB_MAC16 || - (!param(mul, \TOP_8x8_MULT_REG).as_bool() && !param(mul, \BOT_8x8_MULT_REG).as_bool() && !param(mul, \PIPELINE_16x16_MULT_REG1).as_bool() && !param(mul, \PIPELINE_16x16_MULT_REG1).as_bool()))) { + (!param(mul, \TOP_8x8_MULT_REG, State::S0).as_bool() && !param(mul, \BOT_8x8_MULT_REG, State::S0).as_bool() && !param(mul, \PIPELINE_16x16_MULT_REG1, State::S0).as_bool() && !param(mul, \PIPELINE_16x16_MULT_REG1, State::S0).as_bool()))) { argD = sigH; subpattern(out_dffe); if (dff) { @@ -146,7 +146,7 @@ endcode code argD ffH sigH sigO clock clock_pol if (ffFJKG && nusers(sigH) == 2 && - (mul->type != \SB_MAC16 || !param(mul, \PIPELINE_16x16_MULT_REG2).as_bool())) { + (mul->type != \SB_MAC16 || !param(mul, \PIPELINE_16x16_MULT_REG2, State::S0).as_bool())) { argD = sigH; subpattern(out_dffe); if (dff) { @@ -177,7 +177,7 @@ reject_ffH: ; endcode match add - if mul->type != \SB_MAC16 || (param(mul, \TOPOUTPUT_SELECT).as_int() == 3 && param(mul, \BOTOUTPUT_SELECT).as_int() == 3) + if mul->type != \SB_MAC16 || (param(mul, \TOPOUTPUT_SELECT, State::S0).as_int() == 3 && param(mul, \BOTOUTPUT_SELECT, State::S0).as_int() == 3) select add->type.in($add) choice AB {\A, \B} @@ -203,7 +203,7 @@ code sigCD sigO cd_signed if ((actual_acc_width > actual_mul_width) && (natural_mul_width > actual_mul_width)) reject; // If accumulator, check adder width and signedness - if (sigCD == sigH && (actual_acc_width != actual_mul_width) && (param(mul, \A_SIGNED).as_bool() != param(add, \A_SIGNED).as_bool())) + if (sigCD == sigH && (actual_acc_width != actual_mul_width) && (param(mul, \A_SIGNED, State::S0).as_bool() != param(add, \A_SIGNED).as_bool())) reject; sigO = port(add, \Y); @@ -278,7 +278,7 @@ endcode code argQ ffCD ffCDholdmux ffCDholdpol ffCDrstpol sigCD clock clock_pol if (!sigCD.empty() && sigCD != sigO && - (mul->type != \SB_MAC16 || (!param(mul, \C_REG).as_bool() && !param(mul, \D_REG).as_bool()))) { + (mul->type != \SB_MAC16 || (!param(mul, \C_REG, State::S0).as_bool() && !param(mul, \D_REG, State::S0).as_bool()))) { argQ = sigCD; subpattern(in_dffe); if (dff) { -- cgit v1.2.3 From ad6c49fff12e27d99c1fc15850857e5129dd76ee Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 17 Jan 2020 15:38:26 -0800 Subject: ice40_dsp: add test --- tests/arch/ice40/ice40_dsp.ys | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 tests/arch/ice40/ice40_dsp.ys diff --git a/tests/arch/ice40/ice40_dsp.ys b/tests/arch/ice40/ice40_dsp.ys new file mode 100644 index 000000000..250273859 --- /dev/null +++ b/tests/arch/ice40/ice40_dsp.ys @@ -0,0 +1,11 @@ +read_verilog < Date: Fri, 17 Jan 2020 15:41:55 -0800 Subject: synth_ice40: call wreduce before mul2dsp --- techlibs/ice40/synth_ice40.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/techlibs/ice40/synth_ice40.cc b/techlibs/ice40/synth_ice40.cc index 121bcff1f..d92e40726 100644 --- a/techlibs/ice40/synth_ice40.cc +++ b/techlibs/ice40/synth_ice40.cc @@ -273,7 +273,8 @@ struct SynthIce40Pass : public ScriptPass run("opt_expr"); run("opt_clean"); if (help_mode || dsp) { - run("memory_dff"); + run("memory_dff"); // ice40_dsp will merge registers, reserve memory port registers first + run("wreduce t:$mul"); run("techmap -map +/mul2dsp.v -map +/ice40/dsp_map.v -D DSP_A_MAXWIDTH=16 -D DSP_B_MAXWIDTH=16 " "-D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 -D DSP_Y_MINWIDTH=11 " "-D DSP_NAME=$__MUL16X16", "(if -dsp)"); -- cgit v1.2.3 From 5507c328fff7b534abcba4186b2e5b1e26c4ad5e Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 17 Jan 2020 15:57:52 -0800 Subject: Add #1644 testcase --- tests/arch/ice40/bug1644.il.gz | Bin 0 -> 25669 bytes tests/arch/ice40/bug1644.ys | 2 ++ 2 files changed, 2 insertions(+) create mode 100644 tests/arch/ice40/bug1644.il.gz create mode 100644 tests/arch/ice40/bug1644.ys diff --git a/tests/arch/ice40/bug1644.il.gz b/tests/arch/ice40/bug1644.il.gz new file mode 100644 index 000000000..363c510ef Binary files /dev/null and b/tests/arch/ice40/bug1644.il.gz differ diff --git a/tests/arch/ice40/bug1644.ys b/tests/arch/ice40/bug1644.ys new file mode 100644 index 000000000..5950f0e3c --- /dev/null +++ b/tests/arch/ice40/bug1644.ys @@ -0,0 +1,2 @@ +read_ilang bug1644.il.gz +synth_ice40 -top top -dsp -json adc_dac_pass_through.json -run :map_bram -- cgit v1.2.3 From ee500b6d8e7a6cd10a8187a3fc69b46f3d155a91 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 17 Jan 2020 16:05:10 -0800 Subject: xilinx_dsp: add parameter defaults --- passes/pmgen/xilinx_dsp.pmg | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/passes/pmgen/xilinx_dsp.pmg b/passes/pmgen/xilinx_dsp.pmg index 5d3b9c2eb..b9a4b0864 100644 --- a/passes/pmgen/xilinx_dsp.pmg +++ b/passes/pmgen/xilinx_dsp.pmg @@ -120,7 +120,7 @@ endcode // reset functionality, using a subpattern discussed above) // If matched, treat 'A' input as input of ADREG code argQ ffAD ffADcemux ffADrstmux ffADcepol ffADrstpol sigA clock - if (param(dsp, \ADREG).as_int() == 0) { + if (param(dsp, \ADREG, 1).as_int() == 0) { argQ = sigA; subpattern(in_dffe); if (dff) { @@ -176,7 +176,7 @@ code argQ ffAD ffADcemux ffADrstmux ffADcepol ffADrstpol sigA clock ffA2 ffA2cem // Only search for ffA2 if there was a pre-adder // (otherwise ffA2 would have been matched as ffAD) if (preAdd) { - if (param(dsp, \AREG).as_int() == 0) { + if (param(dsp, \AREG, 1).as_int() == 0) { argQ = sigA; subpattern(in_dffe); if (dff) { @@ -237,7 +237,7 @@ endcode // (5) Match 'B' input for B2REG // If B2REG, then match 'B' input for B1REG code argQ ffB2 ffB2cemux ffB2rstmux ffB2cepol ffBrstpol sigB clock ffB1 ffB1cemux ffB1rstmux ffB1cepol - if (param(dsp, \BREG).as_int() == 0) { + if (param(dsp, \BREG, 1).as_int() == 0) { argQ = sigB; subpattern(in_dffe); if (dff) { @@ -287,7 +287,7 @@ endcode // (6) Match 'D' input for DREG code argQ ffD ffDcemux ffDrstmux ffDcepol ffDrstpol sigD clock - if (param(dsp, \DREG).as_int() == 0) { + if (param(dsp, \DREG, 1).as_int() == 0) { argQ = sigD; subpattern(in_dffe); if (dff) { @@ -308,7 +308,7 @@ endcode // (7) Match 'P' output that exclusively drives an MREG code argD ffM ffMcemux ffMrstmux ffMcepol ffMrstpol sigM sigP clock - if (param(dsp, \MREG).as_int() == 0 && nusers(sigM) == 2) { + if (param(dsp, \MREG, 1).as_int() == 0 && nusers(sigM) == 2) { argD = sigM; subpattern(out_dffe); if (dff) { @@ -335,7 +335,7 @@ endcode // recognised in xilinx_dsp.cc). match postAdd // Ensure that Z mux is not already used - if port(dsp, \OPMODE, SigSpec()).extract(4,3).is_fully_zero() + if port(dsp, \OPMODE, SigSpec(0, 7)).extract(4,3).is_fully_zero() select postAdd->type.in($add) select GetSize(port(postAdd, \Y)) <= 48 @@ -363,7 +363,7 @@ endcode // (9) Match 'P' output that exclusively drives a PREG code argD ffP ffPcemux ffPrstmux ffPcepol ffPrstpol sigP clock - if (param(dsp, \PREG).as_int() == 0) { + if (param(dsp, \PREG, 1).as_int() == 0) { int users = 2; // If ffMcemux and no postAdd new-value net must have three users: ffMcemux, ffM and ffPcemux if (ffMcemux && !postAdd) users++; -- cgit v1.2.3 From e17f3f8c63603746ad3aa33e9900d91e9b86db39 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 17 Jan 2020 16:06:20 -0800 Subject: Consistency --- passes/pmgen/ice40_dsp.pmg | 8 +++++--- passes/pmgen/xilinx_dsp.pmg | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/passes/pmgen/ice40_dsp.pmg b/passes/pmgen/ice40_dsp.pmg index fca307453..9d649cb98 100644 --- a/passes/pmgen/ice40_dsp.pmg +++ b/passes/pmgen/ice40_dsp.pmg @@ -56,10 +56,12 @@ code sigA sigB sigH break; sigH.append(O[i]); } - log_assert(nusers(O.extract_end(i)) <= 1); - - if (sigH.empty()) + // This sigM could have no users if downstream sinks (e.g. $add) is + // narrower than $mul result, for example + if (i == 0) reject; + + log_assert(nusers(O.extract_end(i)) <= 1); endcode code argQ ffA ffAholdmux ffArstmux ffAholdpol ffArstpol sigA clock clock_pol diff --git a/passes/pmgen/xilinx_dsp.pmg b/passes/pmgen/xilinx_dsp.pmg index b9a4b0864..20925c0dc 100644 --- a/passes/pmgen/xilinx_dsp.pmg +++ b/passes/pmgen/xilinx_dsp.pmg @@ -460,7 +460,7 @@ arg argD argQ clock code dff = nullptr; - if (GetSize(argQ) == 0) + if (argQ.empty() == 0) reject; for (const auto &c : argQ.chunks()) { // Abandon matches when 'Q' is a constant -- cgit v1.2.3 From db68e4c2a7a39eda46863fba8b8c8313a831f606 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 17 Jan 2020 16:08:04 -0800 Subject: ice40_dsp: fix typo --- passes/pmgen/ice40_dsp.cc | 4 ++-- tests/arch/xilinx/xilinx_dsp.ys | 11 +++++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) create mode 100644 tests/arch/xilinx/xilinx_dsp.ys diff --git a/passes/pmgen/ice40_dsp.cc b/passes/pmgen/ice40_dsp.cc index 202a43f0c..c364cd91a 100644 --- a/passes/pmgen/ice40_dsp.cc +++ b/passes/pmgen/ice40_dsp.cc @@ -73,11 +73,11 @@ void create_ice40_dsp(ice40_dsp_pm &pm) // SB_MAC16 Input Interface SigSpec A = st.sigA; - A.extend_u0(16, st.mul->connections_.at(ID(A_SIGNED), State::S0).as_bool()); + A.extend_u0(16, st.mul->parameters.at(ID(A_SIGNED), State::S0).as_bool()); log_assert(GetSize(A) == 16); SigSpec B = st.sigB; - B.extend_u0(16, st.mul->connections_.at(ID(B_SIGNED), State::S0).as_bool()); + B.extend_u0(16, st.mul->parameters.at(ID(B_SIGNED), State::S0).as_bool()); log_assert(GetSize(B) == 16); SigSpec CD = st.sigCD; diff --git a/tests/arch/xilinx/xilinx_dsp.ys b/tests/arch/xilinx/xilinx_dsp.ys new file mode 100644 index 000000000..3b9f52930 --- /dev/null +++ b/tests/arch/xilinx/xilinx_dsp.ys @@ -0,0 +1,11 @@ +read_verilog < Date: Fri, 17 Jan 2020 17:07:03 -0800 Subject: xilinx_dsp: another typo; move xilinx specific test --- passes/pmgen/xilinx_dsp.pmg | 2 +- tests/arch/xilinx/bug1462.ys | 11 +++++++++++ tests/various/bug1462.ys | 11 ----------- 3 files changed, 12 insertions(+), 12 deletions(-) create mode 100644 tests/arch/xilinx/bug1462.ys delete mode 100644 tests/various/bug1462.ys diff --git a/passes/pmgen/xilinx_dsp.pmg b/passes/pmgen/xilinx_dsp.pmg index 20925c0dc..af47ab111 100644 --- a/passes/pmgen/xilinx_dsp.pmg +++ b/passes/pmgen/xilinx_dsp.pmg @@ -460,7 +460,7 @@ arg argD argQ clock code dff = nullptr; - if (argQ.empty() == 0) + if (argQ.empty()) reject; for (const auto &c : argQ.chunks()) { // Abandon matches when 'Q' is a constant diff --git a/tests/arch/xilinx/bug1462.ys b/tests/arch/xilinx/bug1462.ys new file mode 100644 index 000000000..15cab5121 --- /dev/null +++ b/tests/arch/xilinx/bug1462.ys @@ -0,0 +1,11 @@ +read_verilog << EOF +module top(...); +input wire [31:0] A; +output wire [31:0] P; + +assign P = A * 32'h12300000; + +endmodule +EOF + +synth_xilinx diff --git a/tests/various/bug1462.ys b/tests/various/bug1462.ys deleted file mode 100644 index 15cab5121..000000000 --- a/tests/various/bug1462.ys +++ /dev/null @@ -1,11 +0,0 @@ -read_verilog << EOF -module top(...); -input wire [31:0] A; -output wire [31:0] P; - -assign P = A * 32'h12300000; - -endmodule -EOF - -synth_xilinx -- cgit v1.2.3 From cd8f55a91100b8dcf8b4775803cbacf70f5a998c Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 21 Jan 2020 09:43:04 -0800 Subject: write_xaiger: fix for (* keep *) on flop output --- backends/aiger/xaiger.cc | 6 +++--- tests/various/abc9.ys | 15 +++++++++++++++ 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index a9b75ecc7..b72dd6890 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -222,6 +222,8 @@ struct XAigerWriter alias_map[Q] = D; auto r YS_ATTRIBUTE(unused) = ff_bits.insert(std::make_pair(D, cell)); log_assert(r.second); + if (input_bits.erase(Q)) + log_assert(Q.wire->attributes.count(ID::keep)); continue; } @@ -568,9 +570,6 @@ struct XAigerWriter // write_o_buffer(0); if (!box_list.empty() || !ff_bits.empty()) { - RTLIL::Module *holes_module = module->design->module(stringf("%s$holes", module->name.c_str())); - log_assert(holes_module); - dict> cell_cache; int box_count = 0; @@ -653,6 +652,7 @@ struct XAigerWriter f.write(reinterpret_cast(&buffer_size_be), sizeof(buffer_size_be)); f.write(buffer_str.data(), buffer_str.size()); + RTLIL::Module *holes_module = module->design->module(stringf("%s$holes", module->name.c_str())); if (holes_module) { std::stringstream a_buffer; XAigerWriter writer(holes_module, true /* holes_mode */); diff --git a/tests/various/abc9.ys b/tests/various/abc9.ys index 81d0afd1b..0c7695089 100644 --- a/tests/various/abc9.ys +++ b/tests/various/abc9.ys @@ -14,6 +14,7 @@ design -import gate -as gate miter -equiv -flatten -make_assert -make_outputs gold gate miter sat -verify -prove-asserts -show-ports miter + design -load read hierarchy -top abc9_test028 proc @@ -23,6 +24,7 @@ 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 @@ -38,3 +40,16 @@ design -import gate -as gate miter -equiv -flatten -make_assert -make_outputs gold gate miter sat -seq 10 -verify -prove-asserts -show-ports miter + + +design -reset +read_verilog -icells < Date: Tue, 21 Jan 2020 11:16:50 -0800 Subject: read_aiger: ignore constant inputs on LUTs --- frontends/aiger/aigerparse.cc | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc index b5c861936..52bcfa0b6 100644 --- a/frontends/aiger/aigerparse.cc +++ b/frontends/aiger/aigerparse.cc @@ -414,6 +414,10 @@ void AigerReader::parse_xaiger() for (unsigned j = 0; j < cutLeavesM; ++j) { nodeID = parse_xaiger_literal(f); log_debug2("\t%u\n", nodeID); + if (nodeID < 2) { + log_debug("\tLUT '$lut$aiger%d$%d' input %d is constant!\n", aiger_autoidx, rootNodeID, cutLeavesM); + continue; + } RTLIL::Wire *wire = module->wire(stringf("$aiger%d$%d", aiger_autoidx, nodeID)); log_assert(wire); input_sig.append(wire); @@ -421,10 +425,10 @@ void AigerReader::parse_xaiger() // 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) { + RTLIL::Const lut_mask(RTLIL::State::Sx, 1 << GetSize(input_sig)); + for (int j = 0; j < GetSize(lut_mask); ++j) { int gray = j ^ (j >> 1); - ce.set_incremental(input_sig, RTLIL::Const{gray, static_cast(cutLeavesM)}); + ce.set_incremental(input_sig, RTLIL::Const{gray, GetSize(input_sig)}); RTLIL::SigBit o(output_sig); bool success YS_ATTRIBUTE(unused) = ce.eval(o); log_assert(success); -- cgit v1.2.3 From cd093c00f84b44662a09d469c2b0d8ba6ecf6f6e Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 21 Jan 2020 11:56:01 -0800 Subject: read_aiger: discard LUT inputs with nodeID == 0; not < 2 --- frontends/aiger/aigerparse.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc index 52bcfa0b6..e7478c316 100644 --- a/frontends/aiger/aigerparse.cc +++ b/frontends/aiger/aigerparse.cc @@ -414,7 +414,7 @@ void AigerReader::parse_xaiger() for (unsigned j = 0; j < cutLeavesM; ++j) { nodeID = parse_xaiger_literal(f); log_debug2("\t%u\n", nodeID); - if (nodeID < 2) { + if (nodeID == 0) { log_debug("\tLUT '$lut$aiger%d$%d' input %d is constant!\n", aiger_autoidx, rootNodeID, cutLeavesM); continue; } -- cgit v1.2.3 From 3b44b53e946780ac25581f236be7c836fa6927bf Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 22 Jan 2020 09:36:54 -0800 Subject: abc9: fix scratchpad entry abc9.verify --- passes/techmap/abc9.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 1f6cdaa22..b0e2c7697 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -304,14 +304,14 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip for (size_t pos = abc9_script.find("{R}"); pos != std::string::npos; pos = abc9_script.find("{R}", pos)) abc9_script = abc9_script.substr(0, pos) + R + abc9_script.substr(pos+3); - abc9_script += stringf("; &ps -l; &write -n %s/output.aig;", tempdir_name.c_str()); + abc9_script += stringf("; &ps -l; &write -n %s/output.aig", tempdir_name.c_str()); if (design->scratchpad_get_bool("abc9.verify")) { if (dff_mode) - abc9_script += "verify -s;"; + abc9_script += "; &verify -s"; else - abc9_script += "verify;"; + abc9_script += "; &verify"; } - abc9_script += "time"; + abc9_script += "; time"; abc9_script = add_echos_to_abc9_cmd(abc9_script); for (size_t i = 0; i+1 < abc9_script.size(); i++) -- cgit v1.2.3 From a94b41011d5ec9514739c52b963e0bd96890973f Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 22 Jan 2020 10:08:48 -0800 Subject: abc9: error out if flip-flop init is 1'b1 for '-dff' Due to ABC sequential synthesis restriction --- passes/techmap/abc9.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index b0e2c7697..2568a6cd1 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -1069,6 +1069,8 @@ struct Abc9Pass : public Pass { 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)); + if (abc9_init == State::S1) + log_error("'%s.init' in module '%s' has value 1'b1 which is not supported by 'abc9 -dff'.\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); } -- cgit v1.2.3 From 73526a6f103c927dd0d1504281659a87e7943688 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 22 Jan 2020 14:21:25 -0800 Subject: read_aiger: also parse abc9_mergeability --- frontends/aiger/aigerparse.cc | 7 +++++-- frontends/aiger/aigerparse.h | 1 + 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc index e7478c316..b9c648afd 100644 --- a/frontends/aiger/aigerparse.cc +++ b/frontends/aiger/aigerparse.cc @@ -442,11 +442,13 @@ void AigerReader::parse_xaiger() } } else if (c == 'r') { - uint32_t dataSize YS_ATTRIBUTE(unused) = parse_xaiger_literal(f); + uint32_t dataSize = parse_xaiger_literal(f); flopNum = parse_xaiger_literal(f); log_debug("flopNum = %u\n", flopNum); log_assert(dataSize == (flopNum+1) * sizeof(uint32_t)); - f.ignore(flopNum * sizeof(uint32_t)); + mergeability.reserve(flopNum); + for (unsigned i = 0; i < flopNum; i++) + mergeability.emplace_back(parse_xaiger_literal(f)); } else if (c == 'n') { parse_xaiger_literal(f); @@ -774,6 +776,7 @@ void AigerReader::post_process() auto ff = module->addCell(NEW_ID, "$__ABC9_FF_"); ff->setPort("\\D", d); ff->setPort("\\Q", q); + ff->attributes["\\abc9_mergeability"] = mergeability[i]; } dict wideports_cache; diff --git a/frontends/aiger/aigerparse.h b/frontends/aiger/aigerparse.h index 722f1e472..46ac81212 100644 --- a/frontends/aiger/aigerparse.h +++ b/frontends/aiger/aigerparse.h @@ -45,6 +45,7 @@ struct AigerReader std::vector outputs; std::vector bad_properties; std::vector boxes; + std::vector mergeability; AigerReader(RTLIL::Design *design, std::istream &f, RTLIL::IdString module_name, RTLIL::IdString clk_name, std::string map_filename, bool wideports); void parse_aiger(); -- cgit v1.2.3 From da134701cd86e3958490b97fd6d840ce24586080 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 22 Jan 2020 14:22:03 -0800 Subject: Fix $__ABC9_ASYNC1 to output 1'b1 not 1'b0 --- techlibs/xilinx/abc9_model.v | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/techlibs/xilinx/abc9_model.v b/techlibs/xilinx/abc9_model.v index 204fa883f..15d12c89f 100644 --- a/techlibs/xilinx/abc9_model.v +++ b/techlibs/xilinx/abc9_model.v @@ -42,7 +42,7 @@ 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; + assign Y = S ? 1'b1 : A; endmodule // Box to emulate comb/seq behaviour of RAM{32,64} and SRL{16,32} -- cgit v1.2.3 From af0e7637a28f08978bc4dfb77089261f9fe18a5d Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 22 Jan 2020 20:54:03 -0800 Subject: alumacc: undo accidental commit --- passes/techmap/alumacc.cc | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/passes/techmap/alumacc.cc b/passes/techmap/alumacc.cc index cf2ac16c9..034731b87 100644 --- a/passes/techmap/alumacc.cc +++ b/passes/techmap/alumacc.cc @@ -397,21 +397,18 @@ struct AlumaccWorker { log(" creating $alu model for %s (%s):", log_id(cell), log_id(cell->type)); - bool cmp_less = false; //cell->type.in(ID($lt), ID($le)); - bool cmp_equal = false; //cell->type.in(ID($le), ID($ge)); + bool cmp_less = cell->type.in(ID($lt), ID($le)); + bool cmp_equal = cell->type.in(ID($le), ID($ge)); bool is_signed = cell->getParam(ID(A_SIGNED)).as_bool(); RTLIL::SigSpec A = sigmap(cell->getPort(ID::A)); RTLIL::SigSpec B = sigmap(cell->getPort(ID::B)); RTLIL::SigSpec Y = sigmap(cell->getPort(ID::Y)); - if (cell->type.in(ID($lt), ID($ge))) + if (B < A && GetSize(B)) { + cmp_less = !cmp_less; std::swap(A, B); - - //if (B < A && GetSize(B)) { - // cmp_less = !cmp_less; - // std::swap(A, B); - //} + } alunode_t *n = nullptr; @@ -435,12 +432,6 @@ struct AlumaccWorker log(" merged with %s.\n", log_id(n->cells.front())); } - if (cell->type.in(ID($le), ID($ge))) { - SigSpec YY = module->addWire(NEW_ID, GetSize(Y)); - module->addNot(NEW_ID, YY, Y); - Y = YY; - } - n->cells.push_back(cell); n->cmp.push_back(std::make_tuple(cmp_less, !cmp_less, cmp_equal, false, Y)); } -- cgit v1.2.3 From 1d4314d88853feb1fa6af13fe56274d53d81d853 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 23 Jan 2020 14:58:56 -0800 Subject: abc9_ops -prep_dff: insert async s/r mux in holes when replacing $_DFF_* --- passes/techmap/abc9_ops.cc | 68 +++++++++++++++++++++++++--------------------- 1 file changed, 37 insertions(+), 31 deletions(-) diff --git a/passes/techmap/abc9_ops.cc b/passes/techmap/abc9_ops.cc index 5091ac0f2..750f36ceb 100644 --- a/passes/techmap/abc9_ops.cc +++ b/passes/techmap/abc9_ops.cc @@ -106,38 +106,44 @@ void prep_dff(RTLIL::Module *module) SigMap sigmap(holes_module); dict replace; - for (auto it = holes_module->cells_.begin(); it != holes_module->cells_.end(); ) { - auto cell = it->second; - if (cell->type.in("$_DFF_N_", "$_DFF_NN0_", "$_DFF_NN1_", "$_DFF_NP0_", "$_DFF_NP1_", - "$_DFF_P_", "$_DFF_PN0_", "$_DFF_PN1", "$_DFF_PP0_", "$_DFF_PP1_")) { - SigBit D = cell->getPort("\\D"); - SigBit Q = cell->getPort("\\Q"); - // Remove the $_DFF_* cell from what needs to be a combinatorial box - it = holes_module->cells_.erase(it); - Wire *port; - if (GetSize(Q.wire) == 1) - port = holes_module->wire(stringf("$abc%s", Q.wire->name.c_str())); - else - port = holes_module->wire(stringf("$abc%s[%d]", Q.wire->name.c_str(), Q.offset)); - log_assert(port); - // Prepare to replace "assign = $_DFF_*.Q;" with "assign = $_DFF_*.D;" - // in order to extract just the combinatorial control logic that feeds the box - // (i.e. clock enable, synchronous reset, etc.) - replace.insert(std::make_pair(Q,D)); - // Since `flatten` above would have created wires named ".Q", - // extract the pre-techmap cell name - auto pos = Q.wire->name.str().rfind("."); - log_assert(pos != std::string::npos); - IdString driver = Q.wire->name.substr(0, pos); - // And drive the signal that was previously driven by "DFF.Q" (typically - // used to implement clock-enable functionality) with the ".$abc9_currQ" - // wire (which itself is driven an by 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); - } + for (auto cell : holes_module->cells().to_vector()) { + if (!cell->type.in("$_DFF_N_", "$_DFF_NN0_", "$_DFF_NN1_", "$_DFF_NP0_", "$_DFF_NP1_", + "$_DFF_P_", "$_DFF_PN0_", "$_DFF_PN1", "$_DFF_PP0_", "$_DFF_PP1_")) + continue; + SigBit D = cell->getPort("\\D"); + SigBit Q = cell->getPort("\\Q"); + // Emulate async control embedded inside $_DFF_* cell with mux in front of D + if (cell->type.in("$_DFF_NN0_", "$_DFF_PN0_")) + D = holes_module->MuxGate(NEW_ID, State::S0, D, cell->getPort("\\R")); + else if (cell->type.in("$_DFF_NN1_", "$_DFF_PN1_")) + D = holes_module->MuxGate(NEW_ID, State::S1, D, cell->getPort("\\R")); + else if (cell->type.in("$_DFF_NP0_", "$_DFF_PP0_")) + D = holes_module->MuxGate(NEW_ID, D, State::S0, cell->getPort("\\R")); + else if (cell->type.in("$_DFF_NP1_", "$_DFF_PP1_")) + D = holes_module->MuxGate(NEW_ID, D, State::S1, cell->getPort("\\R")); + // Remove the $_DFF_* cell from what needs to be a combinatorial box + holes_module->remove(cell); + Wire *port; + if (GetSize(Q.wire) == 1) + port = holes_module->wire(stringf("$abc%s", Q.wire->name.c_str())); else - ++it; + port = holes_module->wire(stringf("$abc%s[%d]", Q.wire->name.c_str(), Q.offset)); + log_assert(port); + // Prepare to replace "assign = $_DFF_*.Q;" with "assign = $_DFF_*.D;" + // in order to extract just the combinatorial control logic that feeds the box + // (i.e. clock enable, synchronous reset, etc.) + replace.insert(std::make_pair(Q,D)); + // Since `flatten` above would have created wires named ".Q", + // extract the pre-techmap cell name + auto pos = Q.wire->name.str().rfind("."); + log_assert(pos != std::string::npos); + IdString driver = Q.wire->name.substr(0, pos); + // And drive the signal that was previously driven by "DFF.Q" (typically + // used to implement clock-enable functionality) with the ".$abc9_currQ" + // wire (which itself is driven an by 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); } for (auto &conn : holes_module->connections_) -- cgit v1.2.3 From 48aec34e0dbb6918e38ef2b80cdbbd8bb992d0f5 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 23 Jan 2020 18:53:14 -0800 Subject: abc_box_id -> abc9_box_id in test --- tests/simple_abc9/abc9.v | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/simple_abc9/abc9.v b/tests/simple_abc9/abc9.v index 8afd0ce96..ee01ab5dc 100644 --- a/tests/simple_abc9/abc9.v +++ b/tests/simple_abc9/abc9.v @@ -213,7 +213,7 @@ module arbiter (clk, rst, request, acknowledge, grant, grant_valid, grant_encode input rst; endmodule -(* abc_box_id=1 *) +(* abc9_box_id=1 *) module MUXF8(input I0, I1, S, output O); endmodule -- cgit v1.2.3 From f180dba753c9f4bfb3b89575b0d224c73a1e8897 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 23 Jan 2020 18:56:06 -0800 Subject: abc9_ops: -prep_xaiger to skip (* keep *) cells --- passes/techmap/abc9_ops.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/passes/techmap/abc9_ops.cc b/passes/techmap/abc9_ops.cc index 750f36ceb..40622ece7 100644 --- a/passes/techmap/abc9_ops.cc +++ b/passes/techmap/abc9_ops.cc @@ -165,6 +165,8 @@ void prep_xaiger(RTLIL::Module *module, bool dff) for (auto cell : module->cells()) { if (cell->type == "$__ABC9_FF_") continue; + if (cell->has_keep_attr()) + continue; auto inst_module = module->design->module(cell->type); bool abc9_box = inst_module && inst_module->attributes.count("\\abc9_box_id"); -- cgit v1.2.3 From 11e50c0e9ecec6439d44064a0e1a016dc2b3188b Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 23 Jan 2020 18:56:25 -0800 Subject: Test for (* keep *)-ed abc9_box_id --- tests/simple_abc9/abc9.v | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/simple_abc9/abc9.v b/tests/simple_abc9/abc9.v index ee01ab5dc..52ccb3e1d 100644 --- a/tests/simple_abc9/abc9.v +++ b/tests/simple_abc9/abc9.v @@ -291,3 +291,19 @@ 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 + +module abc9_test036(input A, B, S, output [1:0] O); + (* keep *) + MUXF8 m ( + .I0(I0), + .I1(I1), + .O(O[0]), + .S(S) + ); + MUXF8 m2 ( + .I0(I0), + .I1(I1), + .O(O[1]), + .S(S) + ); +endmodule -- cgit v1.2.3 From 7858cf20a9fa3cec6993bcda39f84974d2793429 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 22 Jan 2020 14:22:03 -0800 Subject: Fix $__ABC9_ASYNC1 to output 1'b1 not 1'b0 --- techlibs/xilinx/abc9_model.v | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/techlibs/xilinx/abc9_model.v b/techlibs/xilinx/abc9_model.v index 204fa883f..15d12c89f 100644 --- a/techlibs/xilinx/abc9_model.v +++ b/techlibs/xilinx/abc9_model.v @@ -42,7 +42,7 @@ 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; + assign Y = S ? 1'b1 : A; endmodule // Box to emulate comb/seq behaviour of RAM{32,64} and SRL{16,32} -- cgit v1.2.3 From 245873d42d7975b6c303c2d04b75f3cafc6c5697 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 23 Jan 2020 19:08:51 -0800 Subject: abc9: warning message if no modules selected --- passes/techmap/abc9.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index f4a89efff..2aeda16d6 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -234,6 +234,12 @@ struct Abc9Pass : public ScriptPass } extra_args(args, argidx, design); + log_assert(design); + if (design->selected_modules().empty()) { + log_warning("No modules selected for ABC9 techmapping.\n"); + return; + } + log_header(design, "Executing ABC9 pass.\n"); log_push(); -- cgit v1.2.3 From e471b330ac6107c63f80baaba4fee7782e2dc396 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 23 Jan 2020 18:53:14 -0800 Subject: abc_box_id -> abc9_box_id in test --- tests/simple_abc9/abc9.v | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/simple_abc9/abc9.v b/tests/simple_abc9/abc9.v index 8afd0ce96..ee01ab5dc 100644 --- a/tests/simple_abc9/abc9.v +++ b/tests/simple_abc9/abc9.v @@ -213,7 +213,7 @@ module arbiter (clk, rst, request, acknowledge, grant, grant_valid, grant_encode input rst; endmodule -(* abc_box_id=1 *) +(* abc9_box_id=1 *) module MUXF8(input I0, I1, S, output O); endmodule -- cgit v1.2.3 From dca1c806eca0219fb609acfd111fbf9073c6908f Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 23 Jan 2020 19:55:11 -0800 Subject: simple_abc9 tests to discard whitebox before write for sim --- tests/simple_abc9/abc9.v | 2 +- tests/simple_abc9/run-test.sh | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/simple_abc9/abc9.v b/tests/simple_abc9/abc9.v index 52ccb3e1d..e5837d480 100644 --- a/tests/simple_abc9/abc9.v +++ b/tests/simple_abc9/abc9.v @@ -213,7 +213,7 @@ module arbiter (clk, rst, request, acknowledge, grant, grant_valid, grant_encode input rst; endmodule -(* abc9_box_id=1 *) +(* abc9_box_id=1, whitebox *) module MUXF8(input I0, I1, S, output O); endmodule diff --git a/tests/simple_abc9/run-test.sh b/tests/simple_abc9/run-test.sh index bc921daa9..32d7a80ca 100755 --- a/tests/simple_abc9/run-test.sh +++ b/tests/simple_abc9/run-test.sh @@ -28,4 +28,5 @@ exec ${MAKE:-make} -f ../tools/autotest.mk $seed *.v *.sv EXTRA_FLAGS="-n 300 -p abc9 -lut 4 -box ../abc.box; \ clean; \ check -assert; \ - select -assert-none t:${DOLLAR}_NOT_ t:${DOLLAR}_AND_ %%'" + select -assert-none t:${DOLLAR}_NOT_ t:${DOLLAR}_AND_ %%; \ + setattr -mod -unset whitebox'" -- cgit v1.2.3 From 2d795fb8c0546ed2b65ee75ffdfd769c48b1164c Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 23 Jan 2020 19:55:11 -0800 Subject: simple_abc9 tests to discard whitebox before write for sim --- tests/simple_abc9/abc9.v | 2 +- tests/simple_abc9/run-test.sh | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/simple_abc9/abc9.v b/tests/simple_abc9/abc9.v index ee01ab5dc..4dc5ad689 100644 --- a/tests/simple_abc9/abc9.v +++ b/tests/simple_abc9/abc9.v @@ -213,7 +213,7 @@ module arbiter (clk, rst, request, acknowledge, grant, grant_valid, grant_encode input rst; endmodule -(* abc9_box_id=1 *) +(* abc9_box_id=1, whitebox *) module MUXF8(input I0, I1, S, output O); endmodule diff --git a/tests/simple_abc9/run-test.sh b/tests/simple_abc9/run-test.sh index bc921daa9..32d7a80ca 100755 --- a/tests/simple_abc9/run-test.sh +++ b/tests/simple_abc9/run-test.sh @@ -28,4 +28,5 @@ exec ${MAKE:-make} -f ../tools/autotest.mk $seed *.v *.sv EXTRA_FLAGS="-n 300 -p abc9 -lut 4 -box ../abc.box; \ clean; \ check -assert; \ - select -assert-none t:${DOLLAR}_NOT_ t:${DOLLAR}_AND_ %%'" + select -assert-none t:${DOLLAR}_NOT_ t:${DOLLAR}_AND_ %%; \ + setattr -mod -unset whitebox'" -- cgit v1.2.3 From dbf351390e68a9d7c453e893de8fa9d09eb24f62 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 23 Jan 2020 22:45:34 -0800 Subject: abc9: -reintegrate recover type from existing cell, check against boxid --- passes/techmap/abc9_ops.cc | 49 ++++++++++++++++++---------------------------- 1 file changed, 19 insertions(+), 30 deletions(-) diff --git a/passes/techmap/abc9_ops.cc b/passes/techmap/abc9_ops.cc index 40622ece7..d238ce0ad 100644 --- a/passes/techmap/abc9_ops.cc +++ b/passes/techmap/abc9_ops.cc @@ -356,24 +356,14 @@ void reintegrate(RTLIL::Module *module) for (auto w : mapped_mod->wires()) module->addWire(remap_name(w->name), GetSize(w)); - dict box_lookup; dict> box_ports; for (auto m : design->modules()) { - auto it = m->attributes.find(ID(abc9_box_id)); - if (it == m->attributes.end()) + if (!m->attributes.count(ID(abc9_box_id))) continue; - if (m->name.begins_with("$paramod")) - continue; - auto id = it->second.as_int(); - auto r = box_lookup.insert(std::make_pair(stringf("$__boxid%d", 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); - auto r2 = box_ports.insert(m->name); - if (r2.second) { + auto r = box_ports.insert(m->name); + 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; @@ -393,7 +383,7 @@ void reintegrate(RTLIL::Module *module) } } else - r2.first->second.push_back(port_name); + r.first->second.push_back(port_name); } if (carry_in != IdString() && carry_out == IdString()) @@ -401,8 +391,8 @@ void reintegrate(RTLIL::Module *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(m)); if (carry_in != IdString()) { - r2.first->second.push_back(carry_in); - r2.first->second.push_back(carry_out); + r.first->second.push_back(carry_in); + r.first->second.push_back(carry_out); } } } @@ -516,28 +506,27 @@ void reintegrate(RTLIL::Module *module) else { RTLIL::Cell *existing_cell = module->cell(mapped_cell->name); log_assert(existing_cell); - log_assert(mapped_cell->type.begins_with("$__boxid")); - auto type = box_lookup.at(mapped_cell->type, IdString()); - if (type == IdString()) - log_error("No module with abc9_box_id = %s found.\n", mapped_cell->type.c_str() + strlen("$__boxid")); - mapped_cell->type = type; + RTLIL::Module* box_module = design->module(existing_cell->type); + auto it = box_module->attributes.find(ID(abc9_box_id)); + log_assert(it != box_module->attributes.end()); + log_assert(mapped_cell->type == stringf("$__boxid%d", it->second.as_int())); + mapped_cell->type = existing_cell->type; RTLIL::Cell *cell = module->addCell(remap_name(mapped_cell->name), mapped_cell->type); cell->parameters = existing_cell->parameters; cell->attributes = existing_cell->attributes; module->swap_names(cell, existing_cell); - auto it = mapped_cell->connections_.find("\\i"); - log_assert(it != mapped_cell->connections_.end()); - SigSpec inputs = std::move(it->second); - mapped_cell->connections_.erase(it); - it = mapped_cell->connections_.find("\\o"); - log_assert(it != mapped_cell->connections_.end()); - SigSpec outputs = std::move(it->second); - mapped_cell->connections_.erase(it); + auto jt = mapped_cell->connections_.find("\\i"); + log_assert(jt != mapped_cell->connections_.end()); + SigSpec inputs = std::move(jt->second); + mapped_cell->connections_.erase(jt); + jt = mapped_cell->connections_.find("\\o"); + log_assert(jt != mapped_cell->connections_.end()); + SigSpec outputs = std::move(jt->second); + mapped_cell->connections_.erase(jt); - RTLIL::Module* box_module = design->module(mapped_cell->type); auto abc9_flop = box_module->attributes.count("\\abc9_flop"); if (!abc9_flop) { for (const auto &i : inputs) -- cgit v1.2.3 From b1787615514f84c83c27d08011427e90c9bd0f4a Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 24 Jan 2020 11:59:48 -0800 Subject: ice40: reduce ABC9 internal fanout warnings with a param for CI->I3 --- passes/pmgen/ice40_wrapcarry.cc | 15 ++++++++++++--- techlibs/ice40/abc9_model.v | 4 +++- techlibs/ice40/abc9_u.box | 3 +-- techlibs/ice40/arith_map.v | 5 +++-- techlibs/ice40/ice40_opt.cc | 4 +++- tests/arch/ice40/ice40_opt.ys | 27 ++++----------------------- 6 files changed, 26 insertions(+), 32 deletions(-) diff --git a/passes/pmgen/ice40_wrapcarry.cc b/passes/pmgen/ice40_wrapcarry.cc index 6e154147f..d458dce46 100644 --- a/passes/pmgen/ice40_wrapcarry.cc +++ b/passes/pmgen/ice40_wrapcarry.cc @@ -42,11 +42,19 @@ void create_ice40_wrapcarry(ice40_wrapcarry_pm &pm) cell->setPort("\\A", st.carry->getPort("\\I0")); cell->setPort("\\B", st.carry->getPort("\\I1")); - cell->setPort("\\CI", st.carry->getPort("\\CI")); + auto CI = st.carry->getPort("\\CI"); + cell->setPort("\\CI", CI); cell->setPort("\\CO", st.carry->getPort("\\CO")); cell->setPort("\\I0", st.lut->getPort("\\I0")); - cell->setPort("\\I3", st.lut->getPort("\\I3")); + auto I3 = st.lut->getPort("\\I3"); + if (pm.sigmap(CI) == pm.sigmap(I3)) { + cell->setParam("\\I3_IS_CI", State::S1); + I3 = State::Sx; + } + else + cell->setParam("\\I3_IS_CI", State::S0); + cell->setPort("\\I3", I3); cell->setPort("\\O", st.lut->getPort("\\O")); cell->setParam("\\LUT", st.lut->getParam("\\LUT_INIT")); @@ -118,7 +126,8 @@ struct Ice40WrapCarryPass : public Pass { auto lut = module->addCell(lut_name, ID($lut)); lut->setParam(ID(WIDTH), 4); lut->setParam(ID(LUT), cell->getParam(ID(LUT))); - lut->setPort(ID(A), {cell->getPort(ID(I0)), cell->getPort(ID(A)), cell->getPort(ID(B)), cell->getPort(ID(I3)) }); + auto I3 = cell->getPort(cell->getParam(ID(I3_IS_CI)).as_bool() ? ID(CI) : ID(I3)); + lut->setPort(ID(A), {cell->getPort(ID(I0)), cell->getPort(ID(A)), cell->getPort(ID(B)), I3 }); lut->setPort(ID(Y), cell->getPort(ID(O))); Const src; diff --git a/techlibs/ice40/abc9_model.v b/techlibs/ice40/abc9_model.v index 26cf6cc22..a5e5f4372 100644 --- a/techlibs/ice40/abc9_model.v +++ b/techlibs/ice40/abc9_model.v @@ -9,6 +9,8 @@ module \$__ICE40_CARRY_WRAPPER ( input I0, I3 ); parameter LUT = 0; + parameter I3_IS_CI = 0; + wire I3_OR_CI = I3_IS_CI ? CI : I3; SB_CARRY carry ( .I0(A), .I1(B), @@ -21,7 +23,7 @@ module \$__ICE40_CARRY_WRAPPER ( .I0(I0), .I1(A), .I2(B), - .I3(I3), + .I3(I3_OR_CI), .O(O) ); endmodule diff --git a/techlibs/ice40/abc9_u.box b/techlibs/ice40/abc9_u.box index 48a51463e..3d4b93834 100644 --- a/techlibs/ice40/abc9_u.box +++ b/techlibs/ice40/abc9_u.box @@ -6,13 +6,12 @@ # 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 +#A B I0 I3 CI 1231 1205 1285 874 874 # O 675 609 - - 278 # CO diff --git a/techlibs/ice40/arith_map.v b/techlibs/ice40/arith_map.v index 00a07247b..ed4140e44 100644 --- a/techlibs/ice40/arith_map.v +++ b/techlibs/ice40/arith_map.v @@ -49,13 +49,14 @@ module _80_ice40_alu (A, B, CI, BI, X, Y, CO); // A[1]: 1100 1100 1100 1100 // A[2]: 1111 0000 1111 0000 // A[3]: 1111 1111 0000 0000 - .LUT(16'b 0110_1001_1001_0110) + .LUT(16'b 0110_1001_1001_0110), + .I3_IS_CI(1'b1) ) carry ( .A(AA[i]), .B(BB[i]), .CI(C[i]), .I0(1'b0), - .I3(C[i]), + .I3(1'bx), .CO(CO[i]), .O(Y[i]) ); diff --git a/techlibs/ice40/ice40_opt.cc b/techlibs/ice40/ice40_opt.cc index 9bee0444b..df10a2842 100644 --- a/techlibs/ice40/ice40_opt.cc +++ b/techlibs/ice40/ice40_opt.cc @@ -139,7 +139,8 @@ static void run_ice40_opts(Module *module) log("Optimized $__ICE40_CARRY_WRAPPER cell back to logic (without SB_CARRY) %s.%s: CO=%s\n", log_id(module), log_id(cell), log_signal(replacement_output)); cell->type = "$lut"; - cell->setPort("\\A", { cell->getPort("\\I0"), inbit[0], inbit[1], cell->getPort("\\I3") }); + auto I3 = cell->getPort(cell->getParam(ID(I3_IS_CI)).as_bool() ? ID(CI) : ID(I3)); + cell->setPort("\\A", { cell->getPort("\\I0"), inbit[0], inbit[1], I3 }); cell->setPort("\\Y", cell->getPort("\\O")); cell->unsetPort("\\B"); cell->unsetPort("\\CI"); @@ -148,6 +149,7 @@ static void run_ice40_opts(Module *module) cell->unsetPort("\\CO"); cell->unsetPort("\\O"); cell->setParam("\\WIDTH", 4); + cell->unsetParam("\\I3_IS_CI"); } continue; } diff --git a/tests/arch/ice40/ice40_opt.ys b/tests/arch/ice40/ice40_opt.ys index 5186d4800..011d98fef 100644 --- a/tests/arch/ice40/ice40_opt.ys +++ b/tests/arch/ice40/ice40_opt.ys @@ -1,23 +1,3 @@ -read_verilog -icells -formal < Date: Fri, 24 Jan 2020 12:16:05 -0800 Subject: ice40: add SB_SPRAM256KA arrival time --- techlibs/ice40/cells_sim.v | 1 + 1 file changed, 1 insertion(+) diff --git a/techlibs/ice40/cells_sim.v b/techlibs/ice40/cells_sim.v index 7d1b37fd6..50eab5dde 100644 --- a/techlibs/ice40/cells_sim.v +++ b/techlibs/ice40/cells_sim.v @@ -1126,6 +1126,7 @@ module SB_SPRAM256KA ( input [15:0] DATAIN, input [3:0] MASKWREN, input WREN, CHIPSELECT, CLOCK, STANDBY, SLEEP, POWEROFF, + `ABC9_ARRIVAL_U(1821) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13207 output reg [15:0] DATAOUT ); `ifndef BLACKBOX -- cgit v1.2.3 From c7fbe13db5144cf87c56d3f7a620a295029606b3 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 24 Jan 2020 13:11:43 -0800 Subject: read_aiger: set abc9_box_seq attr --- frontends/aiger/aigerparse.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc index b9c648afd..418fd722c 100644 --- a/frontends/aiger/aigerparse.cc +++ b/frontends/aiger/aigerparse.cc @@ -478,6 +478,7 @@ void AigerReader::parse_xaiger() RTLIL::Cell* cell = module->addCell(stringf("$box%u", oldBoxNum), stringf("$__boxid%u", boxUniqueId)); cell->setPort("\\i", SigSpec(State::S0, boxInputs)); cell->setPort("\\o", SigSpec(State::S0, boxOutputs)); + cell->attributes["\\abc9_box_seq"] = oldBoxNum; boxes.emplace_back(cell); } } -- cgit v1.2.3 From 485f31f6818e21974fac9030aa3976bb6107dfaa Mon Sep 17 00:00:00 2001 From: Claire Wolf Date: Mon, 27 Jan 2020 17:48:56 +0100 Subject: Improve yosys-smtbmc "solver not found" handling Signed-off-by: Claire Wolf --- backends/smt2/smtio.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/backends/smt2/smtio.py b/backends/smt2/smtio.py index 1df996aa7..34bf7ef38 100644 --- a/backends/smt2/smtio.py +++ b/backends/smt2/smtio.py @@ -304,7 +304,11 @@ class SmtIo: def p_open(self): assert self.p is None - self.p = subprocess.Popen(self.popen_vargs, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + try: + self.p = subprocess.Popen(self.popen_vargs, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + except FileNotFoundError: + print("%s SMT Solver '%s' not found in path." % (self.timestamp(), self.popen_vargs[0]), flush=True) + sys.exit(1) running_solvers[self.p_index] = self.p self.p_running = True self.p_next = None -- cgit v1.2.3 From 9009b76a69b9e867f69295a8e555305925e83aeb Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 27 Jan 2020 11:18:21 -0800 Subject: abc9_ops: add comments --- passes/techmap/abc9_ops.cc | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/passes/techmap/abc9_ops.cc b/passes/techmap/abc9_ops.cc index d238ce0ad..9ad29a8f6 100644 --- a/passes/techmap/abc9_ops.cc +++ b/passes/techmap/abc9_ops.cc @@ -213,6 +213,7 @@ void prep_xaiger(RTLIL::Module *module, bool dff) else if (!yosys_celltypes.cell_known(cell->type)) continue; + // TODO: Speed up toposort -- we care about box ordering only for (auto conn : cell->connections()) { if (cell->input(conn.first)) for (auto bit : sigmap(conn.second)) @@ -222,7 +223,6 @@ void prep_xaiger(RTLIL::Module *module, bool dff) for (auto bit : sigmap(conn.second)) bit_drivers[bit].insert(cell->name); } - toposort.node(cell->name); } @@ -415,6 +415,7 @@ void reintegrate(RTLIL::Module *module) std::map cell_stats; for (auto mapped_cell : mapped_mod->cells()) { + // TODO: Speed up toposort -- we care about NOT ordering only toposort.node(mapped_cell->name); if (mapped_cell->type == ID($_NOT_)) { @@ -625,6 +626,17 @@ void reintegrate(RTLIL::Module *module) } } + // ABC9 will return $_NOT_ gates in its mapping (since they are + // treated as being "free"), in particular driving primary + // outputs (real primary outputs, or cells treated as blackboxes) + // or driving box inputs. + // Instead of just mapping those $_NOT_ gates into 2-input $lut-s + // at an area and delay cost, see if it is possible to push + // this $_NOT_ into the driving LUT, or into all sink LUTs. + // When this is not possible, (i.e. this signal drives two primary + // outputs, only one of which is complemented) and when the driver + // is a LUT, then clone the LUT so that it can be inverted without + // increasing depth/delay. for (auto &it : bit_users) if (bit_drivers.count(it.first)) for (auto driver_cell : bit_drivers.at(it.first)) -- cgit v1.2.3 From ce6a690d27f3ce3b637f1d9be42b1efd744500d2 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 21 Jan 2020 12:29:07 -0800 Subject: xilinx/ice40/ecp5: undo permuting LUT masks in lut_map Now done in read_aiger --- frontends/aiger/aigerparse.cc | 6 +- techlibs/ecp5/cells_map.v | 132 ++++++++++++++++++------------------------ techlibs/ice40/cells_map.v | 13 ++--- techlibs/xilinx/lut_map.v | 99 ++++++++++++------------------- 4 files changed, 102 insertions(+), 148 deletions(-) diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc index 418fd722c..f92a11c6d 100644 --- a/frontends/aiger/aigerparse.cc +++ b/frontends/aiger/aigerparse.cc @@ -410,7 +410,7 @@ void AigerReader::parse_xaiger() RTLIL::Wire *output_sig = module->wire(stringf("$aiger%d$%d", aiger_autoidx, rootNodeID)); log_assert(output_sig); uint32_t nodeID; - RTLIL::SigSpec input_sig; + std::vector input_bits; for (unsigned j = 0; j < cutLeavesM; ++j) { nodeID = parse_xaiger_literal(f); log_debug2("\t%u\n", nodeID); @@ -420,8 +420,10 @@ void AigerReader::parse_xaiger() } RTLIL::Wire *wire = module->wire(stringf("$aiger%d$%d", aiger_autoidx, nodeID)); log_assert(wire); - input_sig.append(wire); + input_bits.push_back(wire); } + // Reverse input order as fastest input is returned first + RTLIL::SigSpec input_sig(std::vector(input_bits.rbegin(), input_bits.rend())); // 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()); diff --git a/techlibs/ecp5/cells_map.v b/techlibs/ecp5/cells_map.v index 10e89a3e0..c031703a9 100644 --- a/techlibs/ecp5/cells_map.v +++ b/techlibs/ecp5/cells_map.v @@ -73,102 +73,80 @@ module \$lut (A, Y); input [WIDTH-1:0] A; output Y; - // Need to swap input ordering, and fix init accordingly, - // to match ABC's expectation of LUT inputs in non-decreasing - // delay order - localparam P_WIDTH = WIDTH < 4 ? 4 : WIDTH; - function [P_WIDTH-1:0] permute_index; - input [P_WIDTH-1:0] i; - integer j; - begin - permute_index = 0; - for (j = 0; j < P_WIDTH; j = j + 1) - permute_index[P_WIDTH-1 - j] = i[j]; - end - endfunction - - function [2**P_WIDTH-1:0] permute_init; - integer i; - begin - permute_init = 0; - for (i = 0; i < 2**P_WIDTH; i = i + 1) - permute_init[i] = LUT[permute_index(i)]; - end - endfunction - - parameter [2**P_WIDTH-1:0] P_LUT = permute_init(); - generate if (WIDTH == 1) begin - LUT4 #(.INIT(P_LUT)) _TECHMAP_REPLACE_ (.Z(Y), + localparam [15:0] INIT = {{8{LUT[1]}}, {8{LUT[0]}}}; + LUT4 #(.INIT(INIT)) _TECHMAP_REPLACE_ (.Z(Y), .A(1'b0), .B(1'b0), .C(1'b0), .D(A[0])); end else if (WIDTH == 2) begin - LUT4 #(.INIT(P_LUT)) _TECHMAP_REPLACE_ (.Z(Y), - .A(1'b0), .B(1'b0), .C(A[1]), .D(A[0])); + localparam [15:0] INIT = {{4{LUT[3]}}, {4{LUT[2]}}, {4{LUT[1]}}, {4{LUT[0]}}}; + LUT4 #(.INIT(INIT)) _TECHMAP_REPLACE_ (.Z(Y), + .A(1'b0), .B(1'b0), .C(A[0]), .D(A[1])); end else if (WIDTH == 3) begin - LUT4 #(.INIT(P_LUT)) _TECHMAP_REPLACE_ (.Z(Y), - .A(1'b0), .B(A[2]), .C(A[1]), .D(A[0])); + localparam [15:0] INIT = {{2{LUT[7]}}, {2{LUT[6]}}, {2{LUT[5]}}, {2{LUT[4]}}, {2{LUT[3]}}, {2{LUT[2]}}, {2{LUT[1]}}, {2{LUT[0]}}}; + LUT4 #(.INIT(INIT)) _TECHMAP_REPLACE_ (.Z(Y), + .A(1'b0), .B(A[0]), .C(A[1]), .D(A[2])); end else if (WIDTH == 4) begin - LUT4 #(.INIT(P_LUT)) _TECHMAP_REPLACE_ (.Z(Y), - .A(A[3]), .B(A[2]), .C(A[1]), .D(A[0])); + LUT4 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.Z(Y), + .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3])); `ifndef NO_PFUMUX end else if (WIDTH == 5) begin wire f0, f1; - LUT4 #(.INIT(P_LUT[15: 0])) lut0 (.Z(f0), - .A(A[4]), .B(A[3]), .C(A[2]), .D(A[1])); - LUT4 #(.INIT(P_LUT[31:16])) lut1 (.Z(f1), - .A(A[4]), .B(A[3]), .C(A[2]), .D(A[1])); - PFUMX mux5(.ALUT(f1), .BLUT(f0), .C0(A[0]), .Z(Y)); + LUT4 #(.INIT(LUT[15: 0])) lut0 (.Z(f0), + .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3])); + LUT4 #(.INIT(LUT[31:16])) lut1 (.Z(f1), + .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3])); + PFUMX mux5(.ALUT(f1), .BLUT(f0), .C0(A[4]), .Z(Y)); end else if (WIDTH == 6) begin wire f0, f1, f2, f3, g0, g1; - LUT4 #(.INIT(P_LUT[15: 0])) lut0 (.Z(f0), - .A(A[5]), .B(A[4]), .C(A[3]), .D(A[2])); - LUT4 #(.INIT(P_LUT[31:16])) lut1 (.Z(f1), - .A(A[5]), .B(A[4]), .C(A[3]), .D(A[2])); - - LUT4 #(.INIT(P_LUT[47:32])) lut2 (.Z(f2), - .A(A[5]), .B(A[4]), .C(A[3]), .D(A[2])); - LUT4 #(.INIT(P_LUT[63:48])) lut3 (.Z(f3), - .A(A[5]), .B(A[4]), .C(A[3]), .D(A[2])); - - PFUMX mux50(.ALUT(f1), .BLUT(f0), .C0(A[1]), .Z(g0)); - PFUMX mux51(.ALUT(f3), .BLUT(f2), .C0(A[1]), .Z(g1)); - L6MUX21 mux6 (.D0(g0), .D1(g1), .SD(A[0]), .Z(Y)); + LUT4 #(.INIT(LUT[15: 0])) lut0 (.Z(f0), + .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3])); + LUT4 #(.INIT(LUT[31:16])) lut1 (.Z(f1), + .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3])); + + LUT4 #(.INIT(LUT[47:32])) lut2 (.Z(f2), + .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3])); + LUT4 #(.INIT(LUT[63:48])) lut3 (.Z(f3), + .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3])); + + PFUMX mux50(.ALUT(f1), .BLUT(f0), .C0(A[4]), .Z(g0)); + PFUMX mux51(.ALUT(f3), .BLUT(f2), .C0(A[4]), .Z(g1)); + L6MUX21 mux6 (.D0(g0), .D1(g1), .SD(A[5]), .Z(Y)); end else if (WIDTH == 7) begin wire f0, f1, f2, f3, f4, f5, f6, f7, g0, g1, g2, g3, h0, h1; - LUT4 #(.INIT(P_LUT[15: 0])) lut0 (.Z(f0), - .A(A[6]), .B(A[5]), .C(A[4]), .D(A[3])); - LUT4 #(.INIT(P_LUT[31:16])) lut1 (.Z(f1), - .A(A[6]), .B(A[5]), .C(A[4]), .D(A[3])); - - LUT4 #(.INIT(P_LUT[47:32])) lut2 (.Z(f2), - .A(A[6]), .B(A[5]), .C(A[4]), .D(A[3])); - LUT4 #(.INIT(P_LUT[63:48])) lut3 (.Z(f3), - .A(A[6]), .B(A[5]), .C(A[4]), .D(A[3])); - - LUT4 #(.INIT(P_LUT[79:64])) lut4 (.Z(f4), - .A(A[6]), .B(A[5]), .C(A[4]), .D(A[3])); - LUT4 #(.INIT(P_LUT[95:80])) lut5 (.Z(f5), - .A(A[6]), .B(A[5]), .C(A[4]), .D(A[3])); - - LUT4 #(.INIT(P_LUT[111: 96])) lut6 (.Z(f6), - .A(A[6]), .B(A[5]), .C(A[4]), .D(A[3])); - LUT4 #(.INIT(P_LUT[127:112])) lut7 (.Z(f7), - .A(A[6]), .B(A[5]), .C(A[4]), .D(A[3])); - - PFUMX mux50(.ALUT(f1), .BLUT(f0), .C0(A[2]), .Z(g0)); - PFUMX mux51(.ALUT(f3), .BLUT(f2), .C0(A[2]), .Z(g1)); - PFUMX mux52(.ALUT(f5), .BLUT(f4), .C0(A[2]), .Z(g2)); - PFUMX mux53(.ALUT(f7), .BLUT(f6), .C0(A[2]), .Z(g3)); - L6MUX21 mux60 (.D0(g0), .D1(g1), .SD(A[1]), .Z(h0)); - L6MUX21 mux61 (.D0(g2), .D1(g3), .SD(A[1]), .Z(h1)); - L6MUX21 mux7 (.D0(h0), .D1(h1), .SD(A[0]), .Z(Y)); + LUT4 #(.INIT(LUT[15: 0])) lut0 (.Z(f0), + .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3])); + LUT4 #(.INIT(LUT[31:16])) lut1 (.Z(f1), + .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3])); + + LUT4 #(.INIT(LUT[47:32])) lut2 (.Z(f2), + .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3])); + LUT4 #(.INIT(LUT[63:48])) lut3 (.Z(f3), + .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3])); + + LUT4 #(.INIT(LUT[79:64])) lut4 (.Z(f4), + .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3])); + LUT4 #(.INIT(LUT[95:80])) lut5 (.Z(f5), + .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3])); + + LUT4 #(.INIT(LUT[111: 96])) lut6 (.Z(f6), + .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3])); + LUT4 #(.INIT(LUT[127:112])) lut7 (.Z(f7), + .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3])); + + PFUMX mux50(.ALUT(f1), .BLUT(f0), .C0(A[4]), .Z(g0)); + PFUMX mux51(.ALUT(f3), .BLUT(f2), .C0(A[4]), .Z(g1)); + PFUMX mux52(.ALUT(f5), .BLUT(f4), .C0(A[4]), .Z(g2)); + PFUMX mux53(.ALUT(f7), .BLUT(f6), .C0(A[4]), .Z(g3)); + L6MUX21 mux60 (.D0(g0), .D1(g1), .SD(A[5]), .Z(h0)); + L6MUX21 mux61 (.D0(g2), .D1(g3), .SD(A[5]), .Z(h1)); + L6MUX21 mux7 (.D0(h0), .D1(h1), .SD(A[6]), .Z(Y)); `endif end else begin wire _TECHMAP_FAIL_ = 1; diff --git a/techlibs/ice40/cells_map.v b/techlibs/ice40/cells_map.v index 759549e30..d5362eb83 100644 --- a/techlibs/ice40/cells_map.v +++ b/techlibs/ice40/cells_map.v @@ -42,19 +42,18 @@ module \$lut (A, Y); .I0(1'b0), .I1(1'b0), .I2(1'b0), .I3(A[0])); end else if (WIDTH == 2) begin - localparam [15:0] INIT = {{4{LUT[3]}}, {4{LUT[1]}}, {4{LUT[2]}}, {4{LUT[0]}}}; + localparam [15:0] INIT = {{4{LUT[3]}}, {4{LUT[2]}}, {4{LUT[1]}}, {4{LUT[0]}}}; SB_LUT4 #(.LUT_INIT(INIT)) _TECHMAP_REPLACE_ (.O(Y), - .I0(1'b0), .I1(1'b0), .I2(A[1]), .I3(A[0])); + .I0(1'b0), .I1(1'b0), .I2(A[0]), .I3(A[1])); end else if (WIDTH == 3) begin - localparam [15:0] INIT = {{2{LUT[7]}}, {2{LUT[3]}}, {2{LUT[5]}}, {2{LUT[1]}}, {2{LUT[6]}}, {2{LUT[2]}}, {2{LUT[4]}}, {2{LUT[0]}}}; + localparam [15:0] INIT = {{2{LUT[7]}}, {2{LUT[6]}}, {2{LUT[5]}}, {2{LUT[4]}}, {2{LUT[3]}}, {2{LUT[2]}}, {2{LUT[1]}}, {2{LUT[0]}}}; SB_LUT4 #(.LUT_INIT(INIT)) _TECHMAP_REPLACE_ (.O(Y), - .I0(1'b0), .I1(A[2]), .I2(A[1]), .I3(A[0])); + .I0(1'b0), .I1(A[0]), .I2(A[1]), .I3(A[2])); end else if (WIDTH == 4) begin - localparam [15:0] INIT = {LUT[15], LUT[7], LUT[11], LUT[3], LUT[13], LUT[5], LUT[9], LUT[1], LUT[14], LUT[6], LUT[10], LUT[2], LUT[12], LUT[4], LUT[8], LUT[0]}; - SB_LUT4 #(.LUT_INIT(INIT)) _TECHMAP_REPLACE_ (.O(Y), - .I0(A[3]), .I1(A[2]), .I2(A[1]), .I3(A[0])); + SB_LUT4 #(.LUT_INIT(LUT)) _TECHMAP_REPLACE_ (.O(Y), + .I0(A[0]), .I1(A[1]), .I2(A[2]), .I3(A[3])); end else begin wire _TECHMAP_FAIL_ = 1; end diff --git a/techlibs/xilinx/lut_map.v b/techlibs/xilinx/lut_map.v index 62d501632..718ec42f1 100644 --- a/techlibs/xilinx/lut_map.v +++ b/techlibs/xilinx/lut_map.v @@ -29,90 +29,65 @@ module \$lut (A, Y); input [WIDTH-1:0] A; output Y; - // Need to swap input ordering, and fix init accordingly, - // to match ABC's expectation of LUT inputs in non-decreasing - // delay order - function [WIDTH-1:0] permute_index; - input [WIDTH-1:0] i; - integer j; - begin - permute_index = 0; - for (j = 0; j < WIDTH; j = j + 1) - permute_index[WIDTH-1 - j] = i[j]; - end - endfunction - - function [2**WIDTH-1:0] permute_init; - input [2**WIDTH-1:0] orig; - integer i; - begin - permute_init = 0; - for (i = 0; i < 2**WIDTH; i = i + 1) - permute_init[i] = orig[permute_index(i)]; - end - endfunction - - parameter [2**WIDTH-1:0] P_LUT = permute_init(LUT); - generate if (WIDTH == 1) begin - if (P_LUT == 2'b01) begin + if (LUT == 2'b01) begin INV _TECHMAP_REPLACE_ (.O(Y), .I(A[0])); end else begin - LUT1 #(.INIT(P_LUT)) _TECHMAP_REPLACE_ (.O(Y), + LUT1 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.O(Y), .I0(A[0])); end end else if (WIDTH == 2) begin - LUT2 #(.INIT(P_LUT)) _TECHMAP_REPLACE_ (.O(Y), - .I0(A[1]), .I1(A[0])); + LUT2 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.O(Y), + .I0(A[0]), .I1(A[1])); end else if (WIDTH == 3) begin - LUT3 #(.INIT(P_LUT)) _TECHMAP_REPLACE_ (.O(Y), - .I0(A[2]), .I1(A[1]), .I2(A[0])); + LUT3 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.O(Y), + .I0(A[0]), .I1(A[1]), .I2(A[2])); end else if (WIDTH == 4) begin - LUT4 #(.INIT(P_LUT)) _TECHMAP_REPLACE_ (.O(Y), - .I0(A[3]), .I1(A[2]), .I2(A[1]), - .I3(A[0])); + LUT4 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.O(Y), + .I0(A[0]), .I1(A[1]), .I2(A[2]), + .I3(A[3])); end else if (WIDTH == 5) begin - LUT5 #(.INIT(P_LUT)) _TECHMAP_REPLACE_ (.O(Y), - .I0(A[4]), .I1(A[3]), .I2(A[2]), - .I3(A[1]), .I4(A[0])); + LUT5 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.O(Y), + .I0(A[0]), .I1(A[1]), .I2(A[2]), + .I3(A[3]), .I4(A[4])); end else if (WIDTH == 6) begin - LUT6 #(.INIT(P_LUT)) _TECHMAP_REPLACE_ (.O(Y), - .I0(A[5]), .I1(A[4]), .I2(A[3]), - .I3(A[2]), .I4(A[1]), .I5(A[0])); + LUT6 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.O(Y), + .I0(A[0]), .I1(A[1]), .I2(A[2]), + .I3(A[3]), .I4(A[4]), .I5(A[5])); end else if (WIDTH == 7) begin wire T0, T1; - LUT6 #(.INIT(P_LUT[63:0])) fpga_lut_0 (.O(T0), - .I0(A[6]), .I1(A[5]), .I2(A[4]), - .I3(A[3]), .I4(A[2]), .I5(A[1])); - LUT6 #(.INIT(P_LUT[127:64])) fpga_lut_1 (.O(T1), - .I0(A[6]), .I1(A[5]), .I2(A[4]), - .I3(A[3]), .I4(A[2]), .I5(A[1])); - MUXF7 fpga_mux_0 (.O(Y), .I0(T0), .I1(T1), .S(A[0])); + LUT6 #(.INIT(LUT[63:0])) fpga_lut_0 (.O(T0), + .I0(A[0]), .I1(A[1]), .I2(A[2]), + .I3(A[3]), .I4(A[4]), .I5(A[5])); + LUT6 #(.INIT(LUT[127:64])) fpga_lut_1 (.O(T1), + .I0(A[0]), .I1(A[1]), .I2(A[2]), + .I3(A[3]), .I4(A[4]), .I5(A[5])); + MUXF7 fpga_mux_0 (.O(Y), .I0(T0), .I1(T1), .S(A[6])); end else if (WIDTH == 8) begin wire T0, T1, T2, T3, T4, T5; - LUT6 #(.INIT(P_LUT[63:0])) fpga_lut_0 (.O(T0), - .I0(A[7]), .I1(A[6]), .I2(A[5]), - .I3(A[4]), .I4(A[3]), .I5(A[2])); - LUT6 #(.INIT(P_LUT[127:64])) fpga_lut_1 (.O(T1), - .I0(A[7]), .I1(A[6]), .I2(A[5]), - .I3(A[4]), .I4(A[3]), .I5(A[2])); - LUT6 #(.INIT(P_LUT[191:128])) fpga_lut_2 (.O(T2), - .I0(A[7]), .I1(A[6]), .I2(A[5]), - .I3(A[4]), .I4(A[3]), .I5(A[2])); - LUT6 #(.INIT(P_LUT[255:192])) fpga_lut_3 (.O(T3), - .I0(A[7]), .I1(A[6]), .I2(A[5]), - .I3(A[4]), .I4(A[3]), .I5(A[2])); - MUXF7 fpga_mux_0 (.O(T4), .I0(T0), .I1(T1), .S(A[1])); - MUXF7 fpga_mux_1 (.O(T5), .I0(T2), .I1(T3), .S(A[1])); - MUXF8 fpga_mux_2 (.O(Y), .I0(T4), .I1(T5), .S(A[0])); + LUT6 #(.INIT(LUT[63:0])) fpga_lut_0 (.O(T0), + .I0(A[0]), .I1(A[1]), .I2(A[2]), + .I3(A[3]), .I4(A[4]), .I5(A[5])); + LUT6 #(.INIT(LUT[127:64])) fpga_lut_1 (.O(T1), + .I0(A[0]), .I1(A[1]), .I2(A[2]), + .I3(A[3]), .I4(A[4]), .I5(A[5])); + LUT6 #(.INIT(LUT[191:128])) fpga_lut_2 (.O(T2), + .I0(A[0]), .I1(A[1]), .I2(A[2]), + .I3(A[3]), .I4(A[4]), .I5(A[5])); + LUT6 #(.INIT(LUT[255:192])) fpga_lut_3 (.O(T3), + .I0(A[0]), .I1(A[1]), .I2(A[2]), + .I3(A[3]), .I4(A[4]), .I5(A[5])); + MUXF7 fpga_mux_0 (.O(T4), .I0(T0), .I1(T1), .S(A[6])); + MUXF7 fpga_mux_1 (.O(T5), .I0(T2), .I1(T3), .S(A[6])); + MUXF8 fpga_mux_2 (.O(Y), .I0(T4), .I1(T5), .S(A[7])); end else begin wire _TECHMAP_FAIL_ = 1; end -- cgit v1.2.3 From cfb0366a18b0f3cab254636fdf534a3de76af8d5 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 27 Jan 2020 13:56:16 -0800 Subject: Import tests from #1628 --- techlibs/ice40/ice40_opt.cc | 4 +-- tests/arch/ice40/bug1597.ys | 72 +++++++++++++++++++++++++++++++++++++++++++ tests/arch/ice40/ice40_opt.ys | 30 ++++++++++++++++++ 3 files changed, 104 insertions(+), 2 deletions(-) create mode 100644 tests/arch/ice40/bug1597.ys diff --git a/techlibs/ice40/ice40_opt.cc b/techlibs/ice40/ice40_opt.cc index df10a2842..940a11063 100644 --- a/techlibs/ice40/ice40_opt.cc +++ b/techlibs/ice40/ice40_opt.cc @@ -139,8 +139,8 @@ static void run_ice40_opts(Module *module) log("Optimized $__ICE40_CARRY_WRAPPER cell back to logic (without SB_CARRY) %s.%s: CO=%s\n", log_id(module), log_id(cell), log_signal(replacement_output)); cell->type = "$lut"; - auto I3 = cell->getPort(cell->getParam(ID(I3_IS_CI)).as_bool() ? ID(CI) : ID(I3)); - cell->setPort("\\A", { cell->getPort("\\I0"), inbit[0], inbit[1], I3 }); + auto I3 = get_bit_or_zero(cell->getPort(cell->getParam(ID(I3_IS_CI)).as_bool() ? ID(CI) : ID(I3))); + cell->setPort("\\A", { get_bit_or_zero(cell->getPort("\\I0")), inbit[0], inbit[1], I3 }); cell->setPort("\\Y", cell->getPort("\\O")); cell->unsetPort("\\B"); cell->unsetPort("\\CI"); diff --git a/tests/arch/ice40/bug1597.ys b/tests/arch/ice40/bug1597.ys new file mode 100644 index 000000000..b7983cfa4 --- /dev/null +++ b/tests/arch/ice40/bug1597.ys @@ -0,0 +1,72 @@ +read_verilog < Date: Mon, 27 Jan 2020 14:02:13 -0800 Subject: Fix $lut input ordering -- SigSpec(std::initializer_list<>) is backwards Just like Verilog... --- passes/pmgen/ice40_wrapcarry.cc | 2 +- techlibs/ice40/ice40_opt.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/passes/pmgen/ice40_wrapcarry.cc b/passes/pmgen/ice40_wrapcarry.cc index d458dce46..0053c8872 100644 --- a/passes/pmgen/ice40_wrapcarry.cc +++ b/passes/pmgen/ice40_wrapcarry.cc @@ -127,7 +127,7 @@ struct Ice40WrapCarryPass : public Pass { lut->setParam(ID(WIDTH), 4); lut->setParam(ID(LUT), cell->getParam(ID(LUT))); auto I3 = cell->getPort(cell->getParam(ID(I3_IS_CI)).as_bool() ? ID(CI) : ID(I3)); - lut->setPort(ID(A), {cell->getPort(ID(I0)), cell->getPort(ID(A)), cell->getPort(ID(B)), I3 }); + lut->setPort(ID(A), { I3, cell->getPort(ID(B)), cell->getPort(ID(A)), cell->getPort(ID(I0)) }); lut->setPort(ID(Y), cell->getPort(ID(O))); Const src; diff --git a/techlibs/ice40/ice40_opt.cc b/techlibs/ice40/ice40_opt.cc index 940a11063..925ab31bb 100644 --- a/techlibs/ice40/ice40_opt.cc +++ b/techlibs/ice40/ice40_opt.cc @@ -140,7 +140,7 @@ static void run_ice40_opts(Module *module) log_id(module), log_id(cell), log_signal(replacement_output)); cell->type = "$lut"; auto I3 = get_bit_or_zero(cell->getPort(cell->getParam(ID(I3_IS_CI)).as_bool() ? ID(CI) : ID(I3))); - cell->setPort("\\A", { get_bit_or_zero(cell->getPort("\\I0")), inbit[0], inbit[1], I3 }); + cell->setPort("\\A", { I3, inbit[1], inbit[0], get_bit_or_zero(cell->getPort("\\I0")) }); cell->setPort("\\Y", cell->getPort("\\O")); cell->unsetPort("\\B"); cell->unsetPort("\\CI"); -- cgit v1.2.3 From 409e5324333d881dadd64fa211b9a6aa86ce36e9 Mon Sep 17 00:00:00 2001 From: Pepijn de Vos Date: Tue, 26 Nov 2019 12:56:06 +0100 Subject: redirect fuser stderr to /dev/null --- passes/cmds/show.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/cmds/show.cc b/passes/cmds/show.cc index a3e969ef1..eeef24bde 100644 --- a/passes/cmds/show.cc +++ b/passes/cmds/show.cc @@ -873,7 +873,7 @@ struct ShowPass : public Pass { #ifdef __APPLE__ std::string cmd = stringf("ps -fu %d | grep -q '[ ]%s' || xdot '%s' &", getuid(), dot_file.c_str(), dot_file.c_str()); #else - std::string cmd = stringf("{ test -f '%s.pid' && fuser -s '%s.pid'; } || ( echo $$ >&3; exec xdot '%s'; ) 3> '%s.pid' &", dot_file.c_str(), dot_file.c_str(), dot_file.c_str(), dot_file.c_str()); + std::string cmd = stringf("{ test -f '%s.pid' && fuser -s '%s.pid' 2> /dev/null; } || ( echo $$ >&3; exec xdot '%s'; ) 3> '%s.pid' &", dot_file.c_str(), dot_file.c_str(), dot_file.c_str(), dot_file.c_str()); #endif log("Exec: %s\n", cmd.c_str()); if (run_command(cmd) != 0) -- cgit v1.2.3 From 245b8c4ab64c5c3bd7b9f71f94316a76a2576fd1 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 28 Jan 2020 10:17:47 -0800 Subject: Fix unresolved conflict from #1573 --- techlibs/xilinx/synth_xilinx.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index 5ba8c0e10..3c5599e4e 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -318,7 +318,7 @@ struct SynthXilinxPass : public ScriptPass run("flatten", "(with '-flatten')"); active_design->scratchpad_unset("tribuf.added_something"); run("tribuf -logic"); - if (!do_iopad && active_design->scratchpad_get_bool("tribuf.added_something")) + if (noiopad && active_design->scratchpad_get_bool("tribuf.added_something")) log_error("Tristate buffers are unsupported without the '-iopad' option.\n"); run("deminout"); run("opt_expr"); -- cgit v1.2.3 From 6d27d4372730cb94306a4f314482459f9d527d7c Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 28 Jan 2020 10:37:16 -0800 Subject: Add and use SigSpec::reverse() --- frontends/aiger/aigerparse.cc | 6 +++--- kernel/rtlil.h | 2 ++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc index f92a11c6d..a42569301 100644 --- a/frontends/aiger/aigerparse.cc +++ b/frontends/aiger/aigerparse.cc @@ -410,7 +410,7 @@ void AigerReader::parse_xaiger() RTLIL::Wire *output_sig = module->wire(stringf("$aiger%d$%d", aiger_autoidx, rootNodeID)); log_assert(output_sig); uint32_t nodeID; - std::vector input_bits; + RTLIL::SigSpec input_sig; for (unsigned j = 0; j < cutLeavesM; ++j) { nodeID = parse_xaiger_literal(f); log_debug2("\t%u\n", nodeID); @@ -420,10 +420,10 @@ void AigerReader::parse_xaiger() } RTLIL::Wire *wire = module->wire(stringf("$aiger%d$%d", aiger_autoidx, nodeID)); log_assert(wire); - input_bits.push_back(wire); + input_sig.append(wire); } // Reverse input order as fastest input is returned first - RTLIL::SigSpec input_sig(std::vector(input_bits.rbegin(), input_bits.rend())); + input_sig.reverse(); // 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()); diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 6251d265d..58c5d9674 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -851,6 +851,8 @@ public: RTLIL::SigSpec repeat(int num) const; + void reverse() { inline_unpack(); std::reverse(bits_.begin(), bits_.end()); } + bool operator <(const RTLIL::SigSpec &other) const; bool operator ==(const RTLIL::SigSpec &other) const; inline bool operator !=(const RTLIL::SigSpec &other) const { return !(*this == other); } -- cgit v1.2.3