diff --git a/.github/ci/build_gowin.sh b/.github/ci/build_gowin.sh deleted file mode 100644 index 430cd2b046..0000000000 --- a/.github/ci/build_gowin.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/bash - -function get_dependencies { - pip3 install apycula==${APYCULA_REVISION} -} - -function build_nextpnr { - mkdir build - pushd build - cmake .. -DARCH=gowin -DWERROR=on -DBUILD_GUI=on -DUSE_IPO=off - make nextpnr-gowin -j`nproc` - popd -} - -function run_tests { - : -} - -function run_archcheck { - pushd build - ./nextpnr-gowin --device GW1N-UV4LQ144C6/I5 --test - popd -} diff --git a/.github/workflows/arch_ci.yml b/.github/workflows/arch_ci.yml index d428fc8027..c5be6100c2 100644 --- a/.github/workflows/arch_ci.yml +++ b/.github/workflows/arch_ci.yml @@ -9,7 +9,7 @@ jobs: strategy: fail-fast: false matrix: - arch: [mistral, ice40, ecp5, generic, nexus, machxo2, gowin, himbaechel] + arch: [mistral, ice40, ecp5, generic, nexus, machxo2, himbaechel] runs-on: ubuntu-latest env: DEPS_PATH: ${{ github.workspace }}/deps diff --git a/.gitignore b/.gitignore index 087c35ac5e..d034171621 100644 --- a/.gitignore +++ b/.gitignore @@ -5,7 +5,6 @@ /nextpnr-ecp5* /nextpnr-nexus* /nextpnr-fpga_interchange* -/nextpnr-gowin* /nextpnr-machxo2* /nextpnr-himbaechel* .cache diff --git a/CMakeLists.txt b/CMakeLists.txt index 5b4604a4a5..764ae24416 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -108,9 +108,9 @@ endif() set(PROGRAM_PREFIX "" CACHE STRING "Name prefix for executables") # List of families to build -set(FAMILIES generic ice40 ecp5 nexus gowin fpga_interchange machxo2 mistral himbaechel) +set(FAMILIES generic ice40 ecp5 nexus fpga_interchange machxo2 mistral himbaechel) set(STABLE_FAMILIES generic ice40 ecp5) -set(EXPERIMENTAL_FAMILIES nexus gowin fpga_interchange machxo2 mistral himbaechel) +set(EXPERIMENTAL_FAMILIES nexus fpga_interchange machxo2 mistral himbaechel) set(ARCH "" CACHE STRING "Architecture family for nextpnr build") set_property(CACHE ARCH PROPERTY STRINGS ${FAMILIES}) diff --git a/gowin/CMakeLists.txt b/gowin/CMakeLists.txt deleted file mode 100644 index 92ff1c0859..0000000000 --- a/gowin/CMakeLists.txt +++ /dev/null @@ -1,53 +0,0 @@ -cmake_minimum_required(VERSION 3.5) -project(chipdb-gowin NONE) - -set(ALL_GOWIN_DEVICES GW1N-1 GW1NZ-1 GW1N-4 GW1N-9 GW1N-9C GW1NS-2 GW1NS-4 GW2A-18) -set(GOWIN_DEVICES ${ALL_GOWIN_DEVICES} CACHE STRING - "Include support for these Gowin devices (available: ${ALL_GOWIN_DEVICES})") -message(STATUS "Enabled Gowin devices: ${GOWIN_DEVICES}") - -find_program (GOWIN_BBA_EXECUTABLE gowin_bba) -message(STATUS "gowin_bba executable: ${GOWIN_BBA_EXECUTABLE}") - -if(DEFINED GOWIN_CHIPDB) - add_custom_target(chipdb-gowin-bbas ALL) -else() - # shared among all families - set(SERIALIZE_CHIPDBS TRUE CACHE BOOL - "Serialize device data preprocessing to minimize memory use") - - set(all_device_bbas) - file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/chipdb) - foreach(device ${GOWIN_DEVICES}) - if(NOT device IN_LIST ALL_GOWIN_DEVICES) - message(FATAL_ERROR "Device ${device} is not a supported Gowin device") - endif() - - set(device_bba chipdb/chipdb-${device}.bba) - add_custom_command( - OUTPUT ${device_bba} - COMMAND ${GOWIN_BBA_EXECUTABLE} -d ${device} -i ${CMAKE_CURRENT_SOURCE_DIR}/constids.inc -o ${device_bba}.new - # atomically update - COMMAND ${CMAKE_COMMAND} -E rename ${device_bba}.new ${device_bba} - DEPENDS - ${GOWIN_BBA_EXECUTABLE} - ${PREVIOUS_CHIPDB_TARGET} - ${CMAKE_CURRENT_SOURCE_DIR}/constids.inc - VERBATIM) - list(APPEND all_device_bbas ${device_bba}) - if(SERIALIZE_CHIPDBS) - set(PREVIOUS_CHIPDB_TARGET ${CMAKE_CURRENT_BINARY_DIR}/${device_bba}) - endif() - endforeach() - - add_custom_target(chipdb-gowin-bbas ALL DEPENDS ${all_device_bbas}) - - get_directory_property(has_parent PARENT_DIRECTORY) - if(has_parent) - set(GOWIN_CHIPDB ${CMAKE_CURRENT_BINARY_DIR}/chipdb PARENT_SCOPE) - # serialize chipdb build across multiple architectures - set(PREVIOUS_CHIPDB_TARGET chipdb-gowin-bbas PARENT_SCOPE) - else() - message(STATUS "Build nextpnr with -DGOWIN_CHIPDB=${CMAKE_CURRENT_BINARY_DIR}/chipdb") - endif() -endif() diff --git a/gowin/arch.cc b/gowin/arch.cc deleted file mode 100644 index b69c6afc96..0000000000 --- a/gowin/arch.cc +++ /dev/null @@ -1,2655 +0,0 @@ -/* - * nextpnr -- Next Generation Place and Route - * - * Copyright (C) 2018 Claire Xenia Wolf - * Copyright (C) 2020 Pepijn de Vos - * - * 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 -#include -#include -#include -#include -#include "design_utils.h" -#include "embed.h" -#include "gfx.h" -#include "nextpnr.h" -#include "placer1.h" -#include "placer_heap.h" -#include "router1.h" -#include "router2.h" -#include "util.h" - -NEXTPNR_NAMESPACE_BEGIN - -const PairPOD *pairLookup(const PairPOD *list, const size_t len, const int dest); - -// GUI -void Arch::fixClockSpineDecals(void) -{ - for (auto sp : clockSpinesCache) { - // row: (#of spine cells, wire_id) - dict> rows; - IdString min_x, max_x; - min_x = max_x = *sp.second.begin(); - for (auto wire : sp.second) { - WireInfo &wi = wire_info(wire); - std::pair &row = rows[wi.y]; - ++row.first; - row.second = wire; - if (wi.x < wire_info(min_x).x) { - min_x = wire; - } else { - if (wi.x > wire_info(max_x).x) { - max_x = wire; - } - } - } - // central mux row owns the global decal - int mux_row = -1; - for (auto row : rows) { - if (row.second.first == 1) { - mux_row = row.first; - break; - } - } - // if there is no separate central mux than all decals are the same - if (mux_row == -1) { - mux_row = rows.begin()->first; - WireInfo &wi = wire_info(rows.at(mux_row).second); - GraphicElement &el_active = decal_graphics.at(wi.decalxy_active.decal).at(0); - GraphicElement &el_inactive = decal_graphics.at(wi.decalxy_inactive.decal).at(0); - el_active.y1 -= wi.y; - el_active.y2 -= wi.y; - el_inactive.y1 -= wi.y; - el_inactive.y2 -= wi.y; - el_active.x1 += wire_info(min_x).x; - el_active.x2 += wire_info(max_x).x; - el_inactive.x1 += wire_info(min_x).x; - el_inactive.x2 += wire_info(max_x).x; - } else { - // change the global decal - WireInfo &wi = wire_info(rows.at(mux_row).second); - // clear spine decals - float y = 0.; - for (auto wire : sp.second) { - if (wire == wi.name) { - continue; - } - wire_info(wire).decalxy_active = DecalXY(); - wire_info(wire).decalxy_inactive = DecalXY(); - y = wire_info(wire).y; - } - GraphicElement &el_active = decal_graphics.at(wi.decalxy_active.decal).at(0); - GraphicElement &el_inactive = decal_graphics.at(wi.decalxy_inactive.decal).at(0); - el_active.y1 -= y; - el_active.y2 -= y; - el_inactive.y1 -= y; - el_inactive.y2 -= y; - el_active.x1 += wire_info(min_x).x; - el_active.x2 += wire_info(max_x).x; - el_inactive.x1 += wire_info(min_x).x; - el_inactive.x2 += wire_info(max_x).x; - } - refreshUi(); - } -} - -void Arch::updateClockSpinesCache(IdString spine_id, IdString wire_id) -{ - std::vector &sp = clockSpinesCache[spine_id]; - if (std::find(sp.begin(), sp.end(), wire_id) == sp.end()) { - sp.push_back(wire_id); - } -} - -DecalXY Arch::getBelDecal(BelId bel) const -{ - CellInfo *ci = getBoundBelCell(bel); - if (ci == nullptr) { - return bels.at(bel).decalxy_inactive; - } else { - // LUT + used/unused DFF - if (bels.at(bel).type == id_SLICE) { - DecalXY decalxy = bels.at(bel).decalxy_active; - if (!ci->params.at(id_FF_USED).as_bool()) { - decalxy.decal = id_DECAL_LUT_UNUSED_DFF_ACTIVE; - if (ci->params.count(id_ALU_MODE) != 0) { - decalxy.decal = id_DECAL_ALU_ACTIVE; - } - } - return decalxy; - } - } - return bels.at(bel).decalxy_active; -} - -DecalXY Arch::getGroupDecal(GroupId grp) const { return groups.at(grp).decalxy; } - -DecalXY Arch::getPipDecal(PipId pip) const -{ - if (getBoundPipNet(pip) == nullptr) { - return pips.at(pip).decalxy_inactive; - } - return pips.at(pip).decalxy_active; -} - -DecalXY Arch::getWireDecal(WireId wire) const -{ - static std::vector clk_wires = {id_GB00, id_GB10, id_GB20, id_GB30, id_GB40, id_GB50, id_GB60, id_GB70}; - static std::vector pip_dst = {id_CLK0, id_CLK1, id_CLK2, id_EW10, id_EW20, id_SN10, id_SN20}; - if (getBoundWireNet(wire) == nullptr) { - if (std::find(clk_wires.begin(), clk_wires.end(), wires.at(wire).type) != clk_wires.end()) { - for (auto dst : pip_dst) { - // check if pip is used - char pip_name[20]; - snprintf(pip_name, sizeof(pip_name), "%s_%s", wire.c_str(this), dst.c_str(this)); - if (pips.count(id(pip_name)) != 0) { - if (getBoundPipNet(id(pip_name)) != nullptr) { - return wires.at(wire).decalxy_active; - } - } - } - } else { - // spines - if (clockSpinesCache.count(wires.at(wire).type) != 0) { - std::vector const &sp = clockSpinesCache.at(wires.at(wire).type); - for (auto w : sp) { - if (getBoundWireNet(w) != nullptr) { - return wires.at(wire).decalxy_active; - } - } - } - } - return wires.at(wire).decalxy_inactive; - } - return wires.at(wire).decalxy_active; -} - -bool Arch::allocate_longwire(NetInfo *ni, int lw_idx) -{ - NPNR_ASSERT(ni != nullptr); - if (ni->driver.cell == nullptr) { - return false; - } - if (ni->name == id("$PACKER_VCC_NET") || ni->name == id("$PACKER_GND_NET")) { - return false; - } - // So far only for OBUF - switch (ni->driver.cell->type.index) { - case ID_ODDR: /* fall-through*/ - case ID_ODDRC: /* fall-through*/ - case ID_IOBUF: /* fall-through*/ - case ID_TBUF: - return false; - case ID_OBUF: - if (getCtx()->debug) { - log_info("Long wire for IO %s\n", nameOf(ni)); - } - ni = ni->driver.cell->ports.at(id_I).net; - return allocate_longwire(ni, lw_idx); - break; - default: - break; - } - - if (getCtx()->debug) { - log_info("Requested index:%d\n", lw_idx); - } - if (avail_longwires == 0 || (lw_idx != -1 && (avail_longwires & (1 << lw_idx)) == 0)) { - return false; - } - int longwire = lw_idx; - if (lw_idx == -1) { - for (longwire = 7; longwire >= 0; --longwire) { - if (avail_longwires & (1 << longwire)) { - break; - } - } - } - avail_longwires &= ~(1 << longwire); - - // BUFS cell - CellInfo *bufs; - char buf[40]; - snprintf(buf, sizeof(buf), "$PACKER_BUFS%d", longwire); - std::unique_ptr new_cell = create_generic_cell(getCtx(), id_BUFS, buf); - bufs = new_cell.get(); - cells[bufs->name] = std::move(new_cell); - if (lw_idx != -1) { - bufs->cluster = bufs->name; - bufs->constr_z = lw_idx + BelZ::bufs_0_z; - bufs->constr_abs_z = true; - bufs->constr_children.clear(); - } - - // old driver -> bufs LW input net - auto net = std::make_unique(idf("$PACKER_BUFS_%c", longwire + 'A')); - NetInfo *bufs_net = net.get(); - nets[net->name] = std::move(net); - - // split the net - CellInfo *driver_cell = ni->driver.cell; - IdString driver_port = ni->driver.port; - driver_cell->disconnectPort(driver_port); - - bufs->connectPort(id_O, ni); - bufs->connectPort(id_I, bufs_net); - driver_cell->connectPort(driver_port, bufs_net); - - if (getCtx()->debug) { - log_info("Long wire %d was allocated\n", longwire); - } - return true; -} - -void Arch::auto_longwires() {} - -void Arch::fix_longwire_bels() -{ - // After routing, it is clear which wires and in which bus SS00 and SS40 are used and - // in which quadrant they are routed. Here we write it in the attributes. - for (auto &cell : cells) { - CellInfo *ci = cell.second.get(); - if (ci->type != id_BUFS) { - continue; - } - const NetInfo *ni = ci->getPort(id_O); - if (ni == nullptr) { - continue; - } - // bus wire is one of the wires - // value does not matter, but the L/R parameter itself - for (auto &wire : ni->wires) { - WireId w = wires[wire.first].type; - switch (w.hash()) { - case ID_LWSPINETL0: - case ID_LWSPINETL1: - case ID_LWSPINETL2: - case ID_LWSPINETL3: - case ID_LWSPINETL4: - case ID_LWSPINETL5: - case ID_LWSPINETL6: - case ID_LWSPINETL7: - case ID_LWSPINEBL0: - case ID_LWSPINEBL1: - case ID_LWSPINEBL2: - case ID_LWSPINEBL3: - case ID_LWSPINEBL4: - case ID_LWSPINEBL5: - case ID_LWSPINEBL6: - case ID_LWSPINEBL7: - ci->setParam(id("L"), Property(w.str(this))); - break; - case ID_LWSPINETR0: - case ID_LWSPINETR1: - case ID_LWSPINETR2: - case ID_LWSPINETR3: - case ID_LWSPINETR4: - case ID_LWSPINETR5: - case ID_LWSPINETR6: - case ID_LWSPINETR7: - case ID_LWSPINEBR0: - case ID_LWSPINEBR1: - case ID_LWSPINEBR2: - case ID_LWSPINEBR3: - case ID_LWSPINEBR4: - case ID_LWSPINEBR5: - case ID_LWSPINEBR6: - case ID_LWSPINEBR7: - ci->setParam(id("R"), Property(w.str(this))); - break; - default: - break; - } - } - } -} - -WireInfo &Arch::wire_info(IdString wire) -{ - auto w = wires.find(wire); - if (w == wires.end()) - NPNR_ASSERT_FALSE_STR("no wire named " + wire.str(this)); - return w->second; -} - -PipInfo &Arch::pip_info(IdString pip) -{ - auto p = pips.find(pip); - if (p == pips.end()) - NPNR_ASSERT_FALSE_STR("no pip named " + pip.str(this)); - return p->second; -} - -BelInfo &Arch::bel_info(IdString bel) -{ - auto b = bels.find(bel); - if (b == bels.end()) - NPNR_ASSERT_FALSE_STR("no bel named " + bel.str(this)); - return b->second; -} - -NetInfo &Arch::net_info(IdString net) -{ - auto b = nets.find(net); - if (b == nets.end()) - NPNR_ASSERT_FALSE_STR("no net named " + net.str(this)); - return *b->second; -} - -void Arch::addWire(IdString name, IdString type, int x, int y) -{ - NPNR_ASSERT(!wires.count(name)); - WireInfo &wi = wires[name]; - wi.name = name; - wi.type = type; - wi.x = x; - wi.y = y; - - wire_ids.push_back(name); - - // Needed to ensure empty tile bel locations - if (int(bels_by_tile.size()) <= x) - bels_by_tile.resize(x + 1); - if (int(bels_by_tile[x].size()) <= y) - bels_by_tile[x].resize(y + 1); - if (int(tileBelDimZ.size()) <= x) - tileBelDimZ.resize(x + 1); - if (int(tileBelDimZ[x].size()) <= y) - tileBelDimZ[x].resize(y + 1); -} - -void Arch::addPip(IdString name, IdString type, IdString srcWire, IdString dstWire, DelayQuad delay, Loc loc) -{ - NPNR_ASSERT(pips.count(name) == 0); - PipInfo &pi = pips[name]; - pi.name = name; - pi.type = type; - pi.srcWire = srcWire; - pi.dstWire = dstWire; - pi.delay = delay; - pi.loc = loc; - - wire_info(srcWire).downhill.push_back(name); - wire_info(dstWire).uphill.push_back(name); - pip_ids.push_back(name); - - if (int(tilePipDimZ.size()) <= loc.x) - tilePipDimZ.resize(loc.x + 1); - - if (int(tilePipDimZ[loc.x].size()) <= loc.y) - tilePipDimZ[loc.x].resize(loc.y + 1); - - // Needed to ensure empty tile bel locations - if (int(bels_by_tile.size()) <= loc.x) - bels_by_tile.resize(loc.x + 1); - if (int(bels_by_tile[loc.x].size()) <= loc.y) - bels_by_tile[loc.x].resize(loc.y + 1); - if (int(tileBelDimZ.size()) <= loc.x) - tileBelDimZ.resize(loc.x + 1); - if (int(tileBelDimZ[loc.x].size()) <= loc.y) - tileBelDimZ[loc.x].resize(loc.y + 1); - - gridDimX = std::max(gridDimX, loc.x + 1); - gridDimY = std::max(gridDimY, loc.y + 1); - tilePipDimZ[loc.x][loc.y] = std::max(tilePipDimZ[loc.x][loc.y], loc.z + 1); -} - -void Arch::addGroup(IdString name) -{ - NPNR_ASSERT(groups.count(name) == 0); - GroupInfo &gi = groups[name]; - gi.name = name; -} - -void Arch::addBel(IdString name, IdString type, Loc loc, bool gb) -{ - NPNR_ASSERT(bels.count(name) == 0); - NPNR_ASSERT(bel_by_loc.count(loc) == 0); - BelInfo &bi = bels[name]; - bi.name = name; - bi.type = type; - bi.x = loc.x; - bi.y = loc.y; - bi.z = loc.z; - bi.gb = gb; - - bel_ids.push_back(name); - bel_by_loc[loc] = name; - - if (int(bels_by_tile.size()) <= loc.x) - bels_by_tile.resize(loc.x + 1); - - if (int(bels_by_tile[loc.x].size()) <= loc.y) - bels_by_tile[loc.x].resize(loc.y + 1); - - bels_by_tile[loc.x][loc.y].push_back(name); - - if (int(tileBelDimZ.size()) <= loc.x) - tileBelDimZ.resize(loc.x + 1); - - if (int(tileBelDimZ[loc.x].size()) <= loc.y) - tileBelDimZ[loc.x].resize(loc.y + 1); - - gridDimX = std::max(gridDimX, loc.x + 1); - gridDimY = std::max(gridDimY, loc.y + 1); - tileBelDimZ[loc.x][loc.y] = std::max(tileBelDimZ[loc.x][loc.y], loc.z + 1); -} - -void Arch::addBelInput(IdString bel, IdString name, IdString wire) -{ - NPNR_ASSERT(bel_info(bel).pins.count(name) == 0); - PinInfo &pi = bel_info(bel).pins[name]; - pi.name = name; - pi.wire = wire; - pi.type = PORT_IN; - - wire_info(wire).downhill_bel_pins.push_back(BelPin{bel, name}); - wire_info(wire).bel_pins.push_back(BelPin{bel, name}); -} - -void Arch::addBelOutput(IdString bel, IdString name, IdString wire) -{ - NPNR_ASSERT(bel_info(bel).pins.count(name) == 0); - PinInfo &pi = bel_info(bel).pins[name]; - pi.name = name; - pi.wire = wire; - pi.type = PORT_OUT; - - wire_info(wire).uphill_bel_pin = BelPin{bel, name}; - wire_info(wire).bel_pins.push_back(BelPin{bel, name}); -} - -void Arch::addBelInout(IdString bel, IdString name, IdString wire) -{ - NPNR_ASSERT(bel_info(bel).pins.count(name) == 0); - PinInfo &pi = bel_info(bel).pins[name]; - pi.name = name; - pi.wire = wire; - pi.type = PORT_INOUT; - - wire_info(wire).downhill_bel_pins.push_back(BelPin{bel, name}); - wire_info(wire).bel_pins.push_back(BelPin{bel, name}); -} - -void Arch::addGroupBel(IdString group, IdString bel) { groups[group].bels.push_back(bel); } - -void Arch::addGroupWire(IdString group, IdString wire) { groups[group].wires.push_back(wire); } - -void Arch::addGroupPip(IdString group, IdString pip) { groups[group].pips.push_back(pip); } - -void Arch::addGroupGroup(IdString group, IdString grp) { groups[group].groups.push_back(grp); } - -void Arch::addDecalGraphic(DecalId decal, const GraphicElement &graphic) -{ - decal_graphics[decal].push_back(graphic); - refreshUi(); -} - -void Arch::setWireDecal(WireId wire, DecalXY active, DecalXY inactive) -{ - wire_info(wire).decalxy_active = active; - wire_info(wire).decalxy_inactive = inactive; - refreshUiWire(wire); -} - -void Arch::setPipDecal(PipId pip, DecalXY active, DecalXY inactive) -{ - pip_info(pip).decalxy_active = active; - pip_info(pip).decalxy_inactive = inactive; - refreshUiPip(pip); -} - -void Arch::setBelDecal(BelId bel, DecalXY active, DecalXY inactive) -{ - bel_info(bel).decalxy_active = active; - bel_info(bel).decalxy_inactive = inactive; - refreshUiBel(bel); -} - -void Arch::setDefaultDecals(void) -{ -#ifndef NO_GUI - for (BelId bel : getBels()) { - gfxSetBelDefaultDecal(this, bel_info(bel)); - } - for (PipId pip : getPips()) { - gfxSetPipDefaultDecal(this, pip_info(pip)); - } - for (WireId wire : getWires()) { - gfxSetWireDefaultDecal(this, wire_info(wire)); - } - fixClockSpineDecals(); -#endif -} - -void Arch::setGroupDecal(GroupId group, DecalXY decalxy) -{ - groups[group].decalxy = decalxy; - refreshUiGroup(group); -} - -void Arch::setWireAttr(IdString wire, IdString key, const std::string &value) { wire_info(wire).attrs[key] = value; } - -void Arch::setPipAttr(IdString pip, IdString key, const std::string &value) { pip_info(pip).attrs[key] = value; } - -void Arch::setBelAttr(IdString bel, IdString key, const std::string &value) { bel_info(bel).attrs[key] = value; } - -void Arch::setDelayScaling(double scale, double offset) -{ - args.delayScale = scale; - args.delayOffset = offset; -} - -void Arch::addCellTimingClass(IdString cell, IdString port, TimingPortClass cls) -{ - cellTiming[cell].portClasses[port] = cls; -} - -void Arch::addCellTimingClock(IdString cell, IdString port) { cellTiming[cell].portClasses[port] = TMG_CLOCK_INPUT; } - -void Arch::addCellTimingDelay(IdString cell, IdString fromPort, IdString toPort, DelayQuad delay) -{ - if (get_or_default(cellTiming[cell].portClasses, fromPort, TMG_IGNORE) == TMG_IGNORE) - cellTiming[cell].portClasses[fromPort] = TMG_COMB_INPUT; - if (get_or_default(cellTiming[cell].portClasses, toPort, TMG_IGNORE) == TMG_IGNORE) - cellTiming[cell].portClasses[toPort] = TMG_COMB_OUTPUT; - cellTiming[cell].combDelays[CellDelayKey{fromPort, toPort}] = delay; -} - -void Arch::addCellTimingSetupHold(IdString cell, IdString port, IdString clock, DelayPair setup, DelayPair hold) -{ - TimingClockingInfo ci; - ci.clock_port = clock; - ci.edge = RISING_EDGE; - ci.setup = setup; - ci.hold = hold; - cellTiming[cell].clockingInfo[port].push_back(ci); - cellTiming[cell].portClasses[port] = TMG_REGISTER_INPUT; -} - -void Arch::addCellTimingClockToOut(IdString cell, IdString port, IdString clock, DelayQuad clktoq) -{ - TimingClockingInfo ci; - ci.clock_port = clock; - ci.edge = RISING_EDGE; - ci.clockToQ = clktoq; - cellTiming[cell].clockingInfo[port].push_back(ci); - cellTiming[cell].portClasses[port] = TMG_REGISTER_OUTPUT; -} - -// --------------------------------------------------------------- - -IdString Arch::apply_local_aliases(int row, int col, const DatabasePOD *db, IdString &wire) -{ - const TilePOD *tile = db->grid[row * db->cols + col].get(); - auto local_alias = pairLookup(tile->aliases.get(), tile->num_aliases, wire.index); - IdString res_wire = IdString(); - if (local_alias != nullptr) { - wire = IdString(local_alias->src_id); - res_wire = idf("R%dC%d_%s", row + 1, col + 1, wire.c_str(this)); - } - return res_wire; -} - -// TODO represent wires more intelligently. -IdString Arch::wireToGlobal(int &row, int &col, const DatabasePOD *db, IdString &wire) -{ - const std::string &wirename = wire.str(this); - if (wirename == "VCC" || wirename == "VSS") { - row = 0; - col = 0; - return wire; - } - if (!isdigit(wirename[1]) || !isdigit(wirename[2]) || !isdigit(wirename[3])) { - IdString res_wire = apply_local_aliases(row, col, db, wire); - if (res_wire == IdString()) { - return idf("R%dC%d_%s", row + 1, col + 1, wirename.c_str()); - } - return res_wire; - } - char direction = wirename[0]; - int num = std::stoi(wirename.substr(1, 2)); - int segment = std::stoi(wirename.substr(3, 1)); - switch (direction) { - case 'N': - row += segment; - break; - case 'S': - row -= segment; - break; - case 'E': - col -= segment; - break; - case 'W': - col += segment; - break; - default: - return idf("R%dC%d_%s", row + 1, col + 1, wirename.c_str()); - break; - } - // wires wrap around the edges - // assumes 0-based indexes - if (row < 0) { - row = -1 - row; - direction = 'N'; - } else if (col < 0) { - col = -1 - col; - direction = 'W'; - } else if (row >= db->rows) { - row = 2 * db->rows - 1 - row; - direction = 'S'; - } else if (col >= db->cols) { - col = 2 * db->cols - 1 - col; - direction = 'E'; - } - wire = idf("%c%d0", direction, num); - // local aliases - IdString res_wire = apply_local_aliases(row, col, db, wire); - if (res_wire == IdString()) { - res_wire = idf("R%dC%d_%c%d", row + 1, col + 1, direction, num); - } - return res_wire; -} - -const PairPOD *pairLookup(const PairPOD *list, const size_t len, const int dest) -{ - for (size_t i = 0; i < len; i++) { - const PairPOD *pair = &list[i]; - if (pair->dest_id == dest) { - return pair; - } - } - return nullptr; -} - -const PinPOD *pinLookup(const PinPOD *list, const size_t len, const int idx) -{ - for (size_t i = 0; i < len; i++) { - const PinPOD *pin = &list[i]; - if (pin->index_id == idx) { - return pin; - } - } - return nullptr; -} - -bool aliasCompare(GlobalAliasPOD i, GlobalAliasPOD j) -{ - return (i.dest_row < j.dest_row) || (i.dest_row == j.dest_row && i.dest_col < j.dest_col) || - (i.dest_row == j.dest_row && i.dest_col == j.dest_col && i.dest_id < j.dest_id); -} - -bool timingCompare(TimingPOD i, TimingPOD j) { return i.name_id < j.name_id; } - -template const T *genericLookup(const T *first, int len, const T val, C compare) -{ - auto res = std::lower_bound(first, first + len, val, compare); - if (res - first != len && !compare(val, *res)) { - return res; - } else { - return nullptr; - } -} - -template const T *timingLookup(const T *first, int len, const T val, C compare) -{ - for (int i = 0; i < len; ++i) { - auto res = &first[i]; - if (!(compare(*res, val) || compare(val, *res))) { - return res; - } - } - return nullptr; -} - -DelayQuad delayLookup(const TimingPOD *first, int len, IdString name) -{ - TimingPOD needle; - needle.name_id = name.index; - const TimingPOD *timing = timingLookup(first, len, needle, timingCompare); - DelayQuad delay; - if (timing != nullptr) { - delay.fall.max_delay = std::max(timing->ff, timing->rf) / 1000.; - delay.fall.min_delay = std::min(timing->ff, timing->rf) / 1000.; - delay.rise.max_delay = std::max(timing->rr, timing->fr) / 1000.; - delay.rise.min_delay = std::min(timing->rr, timing->fr) / 1000.; - } else { - delay = DelayQuad(0); - } - return delay; -} - -DelayQuad Arch::getWireTypeDelay(IdString wire) -{ - IdString len; - IdString glbsrc; - switch (wire.index) { - case ID_X01: - case ID_X02: - case ID_X03: - case ID_X04: - case ID_X05: - case ID_X06: - case ID_X07: - case ID_X08: - case ID_I0: - case ID_I1: - len = id_X0; - break; - case ID_N100: - case ID_N130: - case ID_S100: - case ID_S130: - case ID_E100: - case ID_E130: - case ID_W100: - case ID_W130: - case ID_E110: - case ID_W110: - case ID_E120: - case ID_W120: - case ID_S110: - case ID_N110: - case ID_S120: - case ID_N120: - case ID_SN10: - case ID_SN20: - case ID_EW10: - case ID_EW20: - case ID_I01: - len = id_FX1; - break; - case ID_N200: - case ID_N210: - case ID_N220: - case ID_N230: - case ID_N240: - case ID_N250: - case ID_N260: - case ID_N270: - case ID_S200: - case ID_S210: - case ID_S220: - case ID_S230: - case ID_S240: - case ID_S250: - case ID_S260: - case ID_S270: - case ID_E200: - case ID_E210: - case ID_E220: - case ID_E230: - case ID_E240: - case ID_E250: - case ID_E260: - case ID_E270: - case ID_W200: - case ID_W210: - case ID_W220: - case ID_W230: - case ID_W240: - case ID_W250: - case ID_W260: - case ID_W270: - len = id_X2; - break; - case ID_N800: - case ID_N810: - case ID_N820: - case ID_N830: - case ID_S800: - case ID_S810: - case ID_S820: - case ID_S830: - case ID_E800: - case ID_E810: - case ID_E820: - case ID_E830: - case ID_W800: - case ID_W810: - case ID_W820: - case ID_W830: - len = id_X8; - break; - case ID_LT02: - case ID_LT13: - glbsrc = id_SPINE_TAP_SCLK_0; - break; - case ID_LT01: - case ID_LT04: - glbsrc = id_SPINE_TAP_SCLK_1; - break; - case ID_LBO0: - case ID_LBO1: - glbsrc = id_TAP_BRANCH_SCLK; - break; - case ID_LB01: - case ID_LB11: - case ID_LB21: - case ID_LB31: - case ID_LB41: - case ID_LB51: - case ID_LB61: - case ID_LB71: - glbsrc = id_BRANCH_SCLK; - break; - case ID_GT00: - case ID_GT10: - glbsrc = id_SPINE_TAP_PCLK; - break; - case ID_GBO0: - case ID_GBO1: - glbsrc = id_TAP_BRANCH_PCLK; - break; - case ID_GB00: - case ID_GB10: - case ID_GB20: - case ID_GB30: - case ID_GB40: - case ID_GB50: - case ID_GB60: - case ID_GB70: - glbsrc = id_BRANCH_PCLK; - break; - default: - if (wire.str(this).rfind("LWSPINE", 0) == 0) { - glbsrc = IdString(ID_CENT_SPINE_SCLK); - } else if (wire.str(this).rfind("SPINE", 0) == 0) { - glbsrc = IdString(ID_CENT_SPINE_PCLK); - } else if (wire.str(this).rfind("UNK", 0) == 0) { - glbsrc = IdString(ID_PIO_CENT_PCLK); - } - break; - } - if (len != IdString()) { - return delayLookup(speed->wire.timings.get(), speed->wire.num_timings, len); - } else if (glbsrc != IdString()) { - return delayLookup(speed->glbsrc.timings.get(), speed->glbsrc.num_timings, glbsrc); - } else { - return DelayQuad(0); - } -} - -static Loc getLoc(std::smatch match, int maxX, int maxY) -{ - int col = std::stoi(match[2]); - int row = 1; // Top - std::string side = match[1].str(); - if (side == "R") { - row = col; - col = maxX; - } else if (side == "B") { - row = maxY; - } else if (side == "L") { - row = col; - col = 1; - } - int z = match[3].str()[0] - 'A'; - return Loc(col - 1, row - 1, z); -} - -void Arch::read_cst(std::istream &in) -{ - // If two locations are specified separated by commas (for differential I/O buffers), - // only the first location is actually recognized and used. - // And pin A will be Positive and pin B will be Negative in any case. - std::regex iobre = std::regex("IO_LOC +\"([^\"]+)\" +([^ ,;]+)(, *[^ ;]+)? *;.*[\\s\\S]*"); - std::regex portre = std::regex("IO_PORT +\"([^\"]+)\" +([^;]+;).*[\\s\\S]*"); - std::regex port_attrre = std::regex("([^ =;]+=[^ =;]+) *([^;]*;)"); - std::regex iobelre = std::regex("IO([TRBL])([0-9]+)\\[?([A-Z])\\]?"); - std::regex inslocre = - std::regex("INS_LOC +\"([^\"]+)\" +R([0-9]+)C([0-9]+)\\[([0-9])\\]\\[([AB])\\] *;.*[\\s\\S]*"); - std::regex clockre = std::regex("CLOCK_LOC +\"([^\"]+)\" +BUF([GS])(\\[([0-7])\\])?[^;]*;.*[\\s\\S]*"); - std::smatch match, match_attr, match_pinloc; - std::string line, pinline; - enum - { - ioloc, - ioport, - insloc, - clock - } cst_type; - - settings.erase(id_cst); - while (!in.eof()) { - std::getline(in, line); - cst_type = ioloc; - if (!std::regex_match(line, match, iobre)) { - if (std::regex_match(line, match, portre)) { - cst_type = ioport; - } else { - if (std::regex_match(line, match, clockre)) { - cst_type = clock; - } else { - if (std::regex_match(line, match, inslocre)) { - cst_type = insloc; - } else { - if ((!line.empty()) && (line.rfind("//", 0) == std::string::npos)) { - log_warning("Invalid constraint: %s\n", line.c_str()); - } - continue; - } - } - } - } - - IdString net = id(match[1]); - auto it = cells.find(net); - if (cst_type != clock && it == cells.end()) { - log_info("Cell %s not found\n", net.c_str(this)); - continue; - } - switch (cst_type) { - case clock: { // CLOCK name BUFG|S=# - std::string which_clock = match[2]; - std::string lw = match[4]; - int lw_idx = -1; - if (lw.length() > 0) { - lw_idx = atoi(lw.c_str()); - log_info("lw_idx:%d\n", lw_idx); - } - if (which_clock.at(0) == 'S') { - auto ni = nets.find(net); - if (ni == nets.end()) { - log_info("Net %s not found\n", net.c_str(this)); - continue; - } - if (!allocate_longwire(ni->second.get(), lw_idx)) { - log_info("Can't use the long wires. The %s network will use normal routing.\n", net.c_str(this)); - } - } else { - log_info("BUFG isn't supported\n"); - continue; - } - } break; - case ioloc: { // IO_LOC name pin - IdString pinname = id(match[2]); - pinline = match[2]; - const PinPOD *belname = pinLookup(package->pins.get(), package->num_pins, pinname.index); - if (belname != nullptr) { - std::string bel = IdString(belname->loc_id).str(this); - it->second->setAttr(IdString(ID_BEL), bel); - } else { - if (std::regex_match(pinline, match_pinloc, iobelre)) { - // may be it's IOx#[AB] style? - Loc loc = getLoc(match_pinloc, getGridDimX(), getGridDimY()); - BelId bel = getBelByLocation(loc); - if (bel == BelId()) { - log_error("Pin %s not found (TRBL style). \n", pinline.c_str()); - } - std::string belname = getCtx()->nameOfBel(bel); - it->second->setAttr(IdString(ID_BEL), belname); - } else { - log_error("Pin %s not found (pin# style)\n", pinname.c_str(this)); - } - } - } break; - case insloc: { // INS_LOC - int slice = std::stoi(match[4].str()) * 2; - if (match[5].str() == "B") { - ++slice; - } - std::string belname = std::string("R") + match[2].str() + "C" + match[3].str() + stringf("_SLICE%d", slice); - it->second->setAttr(IdString(ID_BEL), belname); - } break; - default: { // IO_PORT attr=value - std::string attr_val = match[2]; - while (std::regex_match(attr_val, match_attr, port_attrre)) { - std::string attr = "&"; - attr += match_attr[1]; - boost::algorithm::to_upper(attr); - it->second->setAttr(id(attr), 1); - attr_val = match_attr[2]; - } - } - } - } - settings[id_cst] = 1; -} - -// Add all MUXes for the cell -void Arch::addMuxBels(const DatabasePOD *db, int row, int col) -{ - IdString belname, bel_id; - char buf[40]; - int z; - - // make all wide luts with these parameters - struct - { - char type; // MUX type 5,6,7,8 - char bel_idx; // just bel name suffix - char in_prefix[2]; // input from F or OF - char in_idx[2]; // input from bel with idx - } const mux_names[] = {{'5', '0', "", {'0', '1'}}, {'6', '0', "O", {'2', '0'}}, {'5', '1', "", {'2', '3'}}, - {'7', '0', "O", {'5', '1'}}, {'5', '2', "", {'4', '5'}}, {'6', '1', "O", {'6', '4'}}, - {'5', '3', "", {'6', '7'}}, {'8', '0', "O", {'3', '3'}}}; - - // 4 MUX2_LUT5, 2 MUX2_LUT6, 1 MUX2_LUT7, 1 MUX2_LUT8 - for (int j = 0; j < 8; ++j) { - z = j + BelZ::mux_0_z; - - int grow = row + 1; - int gcol = col + 1; - - // no MUX2_LUT8 in the last column - if (j == 7 && col == getGridDimX() - 2) { - continue; - } - - // bel - snprintf(buf, 40, "R%dC%d_MUX2_LUT%c%c", grow, gcol, mux_names[j].type, mux_names[j].bel_idx); - belname = id(buf); - snprintf(buf, 40, "MUX2_LUT%c", mux_names[j].type); - bel_id = id(buf); - addBel(belname, bel_id, Loc(col, row, z), false); - - // dummy wires - snprintf(buf, 40, "I0MUX%d", j); - IdString id_wire_i0 = id(buf); - IdString wire_i0_name = wireToGlobal(row, col, db, id_wire_i0); - addWire(wire_i0_name, id_wire_i0, col, row); - - snprintf(buf, 40, "I1MUX%d", j); - IdString id_wire_i1 = id(buf); - IdString wire_i1_name = wireToGlobal(row, col, db, id_wire_i1); - addWire(wire_i1_name, id_wire_i1, col, row); - - // dummy right pip - DelayQuad delay = getWireTypeDelay(id_I0); - snprintf(buf, 40, "%sF%c", mux_names[j].in_prefix, mux_names[j].in_idx[1]); - IdString id_src_F = id(buf); - IdString src_F = wireToGlobal(row, col, db, id_src_F); - snprintf(buf, 40, "R%dC%d_%s_DUMMY_%s", grow, gcol, id_src_F.c_str(this), id_wire_i1.c_str(this)); - addPip(id(buf), id_wire_i1, src_F, wire_i1_name, delay, Loc(col, row, 0)); - - // dummy left pip - snprintf(buf, 40, "%sF%c", mux_names[j].in_prefix, mux_names[j].in_idx[0]); - id_src_F = id(buf); - // LUT8's I0 is wired to the right cell - int src_col = col; - if (j == 7) { - ++src_col; - delay = getWireTypeDelay(id_I01); - } - src_F = wireToGlobal(row, src_col, db, id_src_F); - snprintf(buf, 40, "R%dC%d_%s_DUMMY_%s", grow, gcol, id_src_F.c_str(this), id_wire_i0.c_str(this)); - addPip(id(buf), id_wire_i0, src_F, wire_i0_name, delay, Loc(col, row, 0)); - - // the MUX ports - snprintf(buf, 40, "R%dC%d_OF%d", grow, gcol, j); - addBelOutput(belname, id_OF, id(buf)); - snprintf(buf, 40, "R%dC%d_SEL%d", grow, gcol, j); - addBelInput(belname, id_SEL, id(buf)); - snprintf(buf, 40, "R%dC%d_I0MUX%d", grow, gcol, j); - addBelInput(belname, id_I0, id(buf)); - snprintf(buf, 40, "R%dC%d_I1MUX%d", grow, gcol, j); - addBelInput(belname, id_I1, id(buf)); - } -} - -void Arch::add_pllvr_ports(DatabasePOD const *db, BelsPOD const *bel, IdString belname, int row, int col) -{ - IdString portname; - - for (int pid : - {ID_CLKIN, ID_CLKFB, ID_FBDSEL0, ID_FBDSEL1, ID_FBDSEL2, ID_FBDSEL3, ID_FBDSEL4, ID_FBDSEL5, ID_IDSEL0, - ID_IDSEL1, ID_IDSEL2, ID_IDSEL3, ID_IDSEL4, ID_IDSEL5, ID_ODSEL0, ID_ODSEL1, ID_ODSEL2, ID_ODSEL3, - ID_ODSEL4, ID_ODSEL5, ID_VREN, ID_PSDA0, ID_PSDA1, ID_PSDA2, ID_PSDA3, ID_DUTYDA0, ID_DUTYDA1, - ID_DUTYDA2, ID_DUTYDA3, ID_FDLY0, ID_FDLY1, ID_FDLY2, ID_FDLY3, ID_RESET, ID_RESET_P}) { - portname = IdString(pairLookup(bel->ports.get(), bel->num_ports, pid)->src_id); - IdString wire = idf("R%dC%d_%s", row + 1, col + 1, portname.c_str(this)); - if (!wires.count(wire)) { - GlobalAliasPOD alias; - alias.dest_col = col; - alias.dest_row = row; - alias.dest_id = portname.hash(); - auto alias_src = genericLookup(db->aliases.get(), db->num_aliases, alias, aliasCompare); - NPNR_ASSERT(alias_src != nullptr); - int srcrow = alias_src->src_row; - int srccol = alias_src->src_col; - IdString srcid = IdString(alias_src->src_id); - wire = wireToGlobal(srcrow, srccol, db, srcid); - if (!wires.count(wire)) { - addWire(wire, srcid, srccol, srcrow); - } - } - addBelInput(belname, IdString(pid), wire); - } - for (int pid : {ID_LOCK, ID_CLKOUT, ID_CLKOUTP, ID_CLKOUTD, ID_CLKOUTD3}) { - portname = IdString(pairLookup(bel->ports.get(), bel->num_ports, pid)->src_id); - addBelOutput(belname, IdString(pid), idf("R%dC%d_%s", row + 1, col + 1, portname.c_str(this))); - } -} - -void Arch::add_rpll_ports(DatabasePOD const *db, BelsPOD const *bel, IdString belname, int row, int col) -{ - IdString portname; - - for (int pid : - {ID_CLKIN, ID_CLKFB, ID_FBDSEL0, ID_FBDSEL1, ID_FBDSEL2, ID_FBDSEL3, ID_FBDSEL4, ID_FBDSEL5, ID_IDSEL0, - ID_IDSEL1, ID_IDSEL2, ID_IDSEL3, ID_IDSEL4, ID_IDSEL5, ID_ODSEL0, ID_ODSEL1, ID_ODSEL2, ID_ODSEL3, - ID_ODSEL4, ID_ODSEL5, ID_PSDA0, ID_PSDA1, ID_PSDA2, ID_PSDA3, ID_DUTYDA0, ID_DUTYDA1, ID_DUTYDA2, - ID_DUTYDA3, ID_FDLY0, ID_FDLY1, ID_FDLY2, ID_FDLY3, ID_RESET, ID_RESET_P}) { - const PairPOD *port = pairLookup(bel->ports.get(), bel->num_ports, pid); - // old base - if (port == nullptr) { - log_warning("When building nextpnr, obsolete old apicula bases were used. Probably not working properly " - "with PLL.\n"); - return; - } - portname = IdString(port->src_id); - IdString wire = idf("R%dC%d_%s", row + 1, col + 1, portname.c_str(this)); - if (!wires.count(wire)) { - GlobalAliasPOD alias; - alias.dest_col = col; - alias.dest_row = row; - alias.dest_id = portname.hash(); - auto alias_src = genericLookup(db->aliases.get(), db->num_aliases, alias, aliasCompare); - NPNR_ASSERT(alias_src != nullptr); - int srcrow = alias_src->src_row; - int srccol = alias_src->src_col; - IdString srcid = IdString(alias_src->src_id); - wire = wireToGlobal(srcrow, srccol, db, srcid); - if (!wires.count(wire)) { - addWire(wire, srcid, srccol, srcrow); - } - } - addBelInput(belname, IdString(pid), wire); - } - for (int pid : {ID_LOCK, ID_CLKOUT, ID_CLKOUTP, ID_CLKOUTD, ID_CLKOUTD3}) { - portname = IdString(pairLookup(bel->ports.get(), bel->num_ports, pid)->src_id); - IdString wire = idf("R%dC%d_%s", row + 1, col + 1, portname.c_str(this)); - if (!wires.count(wire)) { - GlobalAliasPOD alias; - alias.dest_col = col; - alias.dest_row = row; - alias.dest_id = portname.hash(); - auto alias_src = genericLookup(db->aliases.get(), db->num_aliases, alias, aliasCompare); - NPNR_ASSERT(alias_src != nullptr); - int srcrow = alias_src->src_row; - int srccol = alias_src->src_col; - IdString srcid = IdString(alias_src->src_id); - wire = wireToGlobal(srcrow, srccol, db, srcid); - if (!wires.count(wire)) { - addWire(wire, srcid, srccol, srcrow); - } - } - addBelOutput(belname, IdString(pid), wire); - } -} - -static bool skip_aux_oser16(std::string device, int row, int col) -{ - if (device == "GW1NSR-4C") { - switch (col) { - case 2: /* fall-through*/ - case 4: /* fall-through*/ - case 6: /* fall-through*/ - case 8: /* fall-through*/ - case 9: /* fall-through*/ - case 11: /* fall-through*/ - case 13: /* fall-through*/ - case 15: /* fall-through*/ - case 17: /* fall-through*/ - case 18: /* fall-through*/ - case 20: /* fall-through*/ - case 22: /* fall-through*/ - case 24: /* fall-through*/ - case 26: /* fall-through*/ - case 27: /* fall-through*/ - case 29: /* fall-through*/ - case 31: /* fall-through*/ - case 33: /* fall-through*/ - case 35: - return true; - default: - break; - } - } - if (device == "GW1NR-9" || device == "GW1NR-9C") { - switch (col) { - case 2: /* fall-through*/ - case 4: /* fall-through*/ - case 6: /* fall-through*/ - case 8: /* fall-through*/ - case 9: /* fall-through*/ - case 11: /* fall-through*/ - case 13: /* fall-through*/ - case 15: /* fall-through*/ - case 17: /* fall-through*/ - case 18: /* fall-through*/ - case 19: /* fall-through*/ - case 21: /* fall-through*/ - case 23: /* fall-through*/ - case 25: /* fall-through*/ - case 27: /* fall-through*/ - case 28: /* fall-through*/ - case 29: /* fall-through*/ - case 31: /* fall-through*/ - case 33: /* fall-through*/ - case 35: /* fall-through*/ - case 36: /* fall-through*/ - case 37: /* fall-through*/ - case 39: /* fall-through*/ - case 41: /* fall-through*/ - case 43: /* fall-through*/ - case 45: - return true; - default: - break; - } - } - return false; -} - -WireId Arch::get_make_port_wire(const DatabasePOD *db, const BelsPOD *bel, int row, int col, IdString port) -{ - IdString wirename = IdString(pairLookup(bel->ports.get(), bel->num_ports, port.hash())->src_id); - IdString wire = idf("R%dC%d_%s", row + 1, col + 1, wirename.c_str(this)); - if (!wires.count(wire)) { - GlobalAliasPOD alias; - alias.dest_col = col; - alias.dest_row = row; - alias.dest_id = port.hash(); - auto alias_src = genericLookup(db->aliases.get(), db->num_aliases, alias, aliasCompare); - NPNR_ASSERT(alias_src != nullptr); - int srcrow = alias_src->src_row; - int srccol = alias_src->src_col; - IdString srcid = IdString(alias_src->src_id); - wire = wireToGlobal(srcrow, srccol, db, srcid); - if (!wires.count(wire)) { - addWire(wire, srcid, srccol, srcrow); - } - } - return wire; -} - -Arch::Arch(ArchArgs args) : args(args) -{ - family = args.family; - - max_clock = 6; - if (family == "GW1NZ-1") { - max_clock = 3; - } - - // Load database - std::string chipdb = stringf("gowin/chipdb-%s.bin", family.c_str()); - auto db = reinterpret_cast(get_chipdb(chipdb)); - if (db == nullptr) { - log_error("Failed to load chipdb '%s'\n", chipdb.c_str()); - } - if (db->version != chipdb_version) { - log_error("Incorrect chipdb version %u is used. Version %u is required\n", db->version, chipdb_version); - } - if (db->family.get() != family) { - log_error("Database is for family '%s' but provided device is family '%s'.\n", db->family.get(), - family.c_str()); - } - // setup id strings - for (size_t i = 0; i < db->num_ids; i++) { - IdString::initialize_add(this, db->id_strs[i].get(), uint32_t(i) + db->num_constids); - } - - // Empty decal - addDecalGraphic(IdString(), GraphicElement()); - - if (args.gui) { -#ifndef NO_GUI - // decals - gfxCreateBelDecals(this); -#endif - } - - // setup package - IdString package_name; - IdString device_id; - IdString speed_id; - for (unsigned int i = 0; i < db->num_partnumbers; i++) { - auto partnumber = &db->partnumber_packages[i]; - // std::cout << IdString(partnumber->name_id).str(this) << IdString(partnumber->package_id).str(this) << - // std::endl; - if (IdString(partnumber->name_id) == id(args.partnumber)) { - package_name = IdString(partnumber->package_id); - device_id = IdString(partnumber->device_id); - speed_id = IdString(partnumber->speed_id); - break; - } - } - if (package_name == IdString()) { - log_error("Unsupported partnumber '%s'.\n", args.partnumber.c_str()); - } - - // setup timing info - speed = nullptr; - for (unsigned int i = 0; i < db->num_speeds; i++) { - const TimingClassPOD *tc = &db->speeds[i]; - // std::cout << IdString(tc->name_id).str(this) << std::endl; - if (IdString(tc->name_id) == speed_id) { - speed = tc->groups.get(); - break; - } - } - if (speed == nullptr) { - log_error("Unsupported speed grade '%s'.\n", speed_id.c_str(this)); - } - - const VariantPOD *variant = nullptr; - for (unsigned int i = 0; i < db->num_variants; i++) { - auto var = &db->variants[i]; - // std::cout << IdString(var->name_id).str(this) << std::endl; - if (IdString(var->name_id) == device_id) { - variant = var; - break; - } - } - if (variant == nullptr) { - log_error("Unsupported device grade '%s'.\n", device_id.c_str(this)); - } - - package = nullptr; - for (unsigned int i = 0; i < variant->num_packages; i++) { - auto pkg = &variant->packages[i]; - // std::cout << IdString(pkg->name_id).str(this) << std::endl; - if (IdString(pkg->name_id) == package_name) { - package = pkg; - break; - } - // for (int j=0; j < pkg->num_pins; j++) { - // auto pin = pkg->pins[j]; - // std::cout << IdString(pin.src_id).str(this) << " " << IdString(pin.dest_id).str(this) << std::endl; - // } - } - - if (package == nullptr) { - log_error("Unsupported package '%s'.\n", package_name.c_str(this)); - } - - // - log_info("Series:%s Device:%s Package:%s Speed:%s\n", family.c_str(), device_id.c_str(this), - package_name.c_str(this), speed_id.c_str(this)); - - device = device_id.str(this); - - // setup db - // add global VCC and GND bels - addBel(id_GND, id_GND, Loc(0, 0, BelZ::gnd_0_z), true); - addWire(id_VSS, id_VSS, 0, 0); - addBelOutput(id_GND, id_G, id_VSS); - addBel(id_VCC, id_VCC, Loc(0, 0, BelZ::vcc_0_z), true); - addWire(id_VCC, id_VCC, 0, 0); - addBelOutput(id_VCC, id_V, id_VCC); - char buf[32]; - // The reverse order of the enumeration simplifies the creation - // of MUX2_LUT8s: they need the existence of the wire on the right. - for (int i = db->rows * db->cols - 1; i >= 0; --i) { - IdString grpname; - int row = i / db->cols; - int col = i % db->cols; - const TilePOD *tile = db->grid[i].get(); - if (args.gui) { -#ifndef NO_GUI - // CRU decal - snprintf(buf, 32, "R%dC%d_CRU", row + 1, col + 1); - grpname = id(buf); - addGroup(grpname); - setGroupDecal(grpname, gfxGetCruGroupDecalXY(col, row)); -#endif - } - // setup wires - const PairPOD *pips[2] = {tile->pips.get(), tile->clock_pips.get()}; - unsigned int num_pips[2] = {tile->num_pips, tile->num_clock_pips}; - for (int p = 0; p < 2; p++) { - for (unsigned int j = 0; j < num_pips[p]; j++) { - const PairPOD pip = pips[p][j]; - int destrow = row; - int destcol = col; - IdString destid(pip.dest_id), gdestid(pip.dest_id); - IdString gdestname = wireToGlobal(destrow, destcol, db, gdestid); - if (!wires.count(gdestname)) - addWire(gdestname, destid, destcol, destrow); - int srcrow = row; - int srccol = col; - IdString srcid(pip.src_id), gsrcid(pip.src_id); - IdString gsrcname = wireToGlobal(srcrow, srccol, db, gsrcid); - if (!wires.count(gsrcname)) - addWire(gsrcname, srcid, srccol, srcrow); - } - } - for (unsigned int j = 0; j < tile->num_bels; j++) { - const BelsPOD *bel = &tile->bels[j]; - IdString belname; - IdString portname; - int z = 0; - bool dff = true; - switch (static_cast(bel->type_id)) { - case ID_PLLVR: - belname = idf("R%dC%d_PLLVR", row + 1, col + 1); - addBel(belname, id_PLLVR, Loc(col, row, BelZ::pllvr_z), false); - add_pllvr_ports(db, bel, belname, row, col); - break; - case ID_RPLLA: - belname = idf("R%dC%d_rPLL", row + 1, col + 1); - addBel(belname, id_rPLL, Loc(col, row, BelZ::pll_z), false); - add_rpll_ports(db, bel, belname, row, col); - break; - case ID_BUFS7: - z++; /* fall-through*/ - case ID_BUFS6: - z++; /* fall-through*/ - case ID_BUFS5: - z++; /* fall-through*/ - case ID_BUFS4: - z++; /* fall-through*/ - case ID_BUFS3: - z++; /* fall-through*/ - case ID_BUFS2: - z++; /* fall-through*/ - case ID_BUFS1: - z++; /* fall-through*/ - case ID_BUFS0: - snprintf(buf, 32, "R%dC%d_BUFS%d", row + 1, col + 1, z); - belname = id(buf); - addBel(belname, id_BUFS, Loc(col, row, BelZ::bufs_0_z + z), false); - portname = IdString(pairLookup(bel->ports.get(), bel->num_ports, ID_I)->src_id); - snprintf(buf, 32, "R%dC%d_%s", row + 1, col + 1, portname.c_str(this)); - addBelInput(belname, id_I, id(buf)); - portname = IdString(pairLookup(bel->ports.get(), bel->num_ports, ID_O)->src_id); - snprintf(buf, 32, "R%dC%d_%s", row + 1, col + 1, portname.c_str(this)); - addBelOutput(belname, id_O, id(buf)); - break; - case ID_GSR0: - snprintf(buf, 32, "R%dC%d_GSR0", row + 1, col + 1); - belname = id(buf); - addBel(belname, id_GSR, Loc(col, row, 0), false); - portname = IdString(pairLookup(bel->ports.get(), bel->num_ports, ID_GSRI)->src_id); - snprintf(buf, 32, "R%dC%d_%s", row + 1, col + 1, portname.c_str(this)); - addBelInput(belname, id_GSRI, id(buf)); - break; - case ID_OSC: /* fall-through*/ - case ID_OSCH: /* fall-through*/ - case ID_OSCW: - belname = idf("R%dC%d_%s", row + 1, col + 1, IdString(bel->type_id).c_str(this)); - addBel(belname, IdString(bel->type_id), Loc(col, row, BelZ::osc_z), false); - addBelOutput(belname, id_OSCOUT, get_make_port_wire(db, bel, row, col, id_OSCOUT)); - break; - case ID_OSCF: /* fall-through*/ - case ID_OSCZ: /* fall-through*/ - case ID_OSCO: - belname = idf("R%dC%d_%s", row + 1, col + 1, IdString(bel->type_id).c_str(this)); - addBel(belname, IdString(bel->type_id), Loc(col, row, BelZ::osc_z), false); - addBelOutput(belname, id_OSCOUT, get_make_port_wire(db, bel, row, col, id_OSCOUT)); - addBelInput(belname, id_OSCEN, get_make_port_wire(db, bel, row, col, id_OSCEN)); - break; - case ID_RAM16: - snprintf(buf, 32, "R%dC%d_RAMW", row + 1, col + 1); - belname = id(buf); - addBel(belname, id_RAMW, Loc(col, row, BelZ::lutram_0_z), false); - - snprintf(buf, 32, "R%dC%d_A%d", row + 1, col + 1, 4); - addBelInput(belname, id_A4, id(buf)); - snprintf(buf, 32, "R%dC%d_B%d", row + 1, col + 1, 4); - addBelInput(belname, id_B4, id(buf)); - snprintf(buf, 32, "R%dC%d_C%d", row + 1, col + 1, 4); - addBelInput(belname, id_C4, id(buf)); - snprintf(buf, 32, "R%dC%d_D%d", row + 1, col + 1, 4); - addBelInput(belname, id_D4, id(buf)); - - snprintf(buf, 32, "R%dC%d_A%d", row + 1, col + 1, 5); - addBelInput(belname, id_A5, id(buf)); - snprintf(buf, 32, "R%dC%d_B%d", row + 1, col + 1, 5); - addBelInput(belname, id_B5, id(buf)); - snprintf(buf, 32, "R%dC%d_C%d", row + 1, col + 1, 5); - addBelInput(belname, id_C5, id(buf)); - snprintf(buf, 32, "R%dC%d_D%d", row + 1, col + 1, 5); - addBelInput(belname, id_D5, id(buf)); - - snprintf(buf, 32, "R%dC%d_CLK%d", row + 1, col + 1, 2); - addBelInput(belname, id_CLK, id(buf)); - snprintf(buf, 32, "R%dC%d_LSR%d", row + 1, col + 1, 2); - addBelInput(belname, id_LSR, id(buf)); - snprintf(buf, 32, "R%dC%d_CE%d", row + 1, col + 1, 2); - addBelInput(belname, id_CE, id(buf)); - break; - // fall through the ++ - case ID_LUT7: - z++; - dff = false; /* fall-through*/ - case ID_LUT6: - z++; - dff = false; /* fall-through*/ - case ID_LUT5: - z++; /* fall-through*/ - case ID_LUT4: - z++; /* fall-through*/ - case ID_LUT3: - z++; /* fall-through*/ - case ID_LUT2: - z++; /* fall-through*/ - case ID_LUT1: - z++; /* fall-through*/ - case ID_LUT0: - // common LUT+DFF code - snprintf(buf, 32, "R%dC%d_SLICE%d", row + 1, col + 1, z); - belname = id(buf); - addBel(belname, id_SLICE, Loc(col, row, z), false); - snprintf(buf, 32, "R%dC%d_F%d", row + 1, col + 1, z); - addBelOutput(belname, id_F, id(buf)); - snprintf(buf, 32, "R%dC%d_A%d", row + 1, col + 1, z); - addBelInput(belname, id_A, id(buf)); - snprintf(buf, 32, "R%dC%d_B%d", row + 1, col + 1, z); - addBelInput(belname, id_B, id(buf)); - snprintf(buf, 32, "R%dC%d_C%d", row + 1, col + 1, z); - addBelInput(belname, id_C, id(buf)); - snprintf(buf, 32, "R%dC%d_D%d", row + 1, col + 1, z); - addBelInput(belname, id_D, id(buf)); - if (dff) { - snprintf(buf, 32, "R%dC%d_CLK%d", row + 1, col + 1, z / 2); - addBelInput(belname, id_CLK, id(buf)); - snprintf(buf, 32, "R%dC%d_LSR%d", row + 1, col + 1, z / 2); - addBelInput(belname, id_LSR, id(buf)); - snprintf(buf, 32, "R%dC%d_CE%d", row + 1, col + 1, z / 2); - addBelInput(belname, id_CE, id(buf)); - snprintf(buf, 32, "R%dC%d_Q%d", row + 1, col + 1, z); - addBelOutput(belname, id_Q, id(buf)); - } - if (z == 0) { - addMuxBels(db, row, col); - } - if (z % 2 == 0) { - snprintf(buf, 32, "R%dC%d_LUT_GRP%d", row + 1, col + 1, z); - grpname = id(buf); - if (args.gui) { -#ifndef NO_GUI - addGroup(grpname); - setGroupDecal(grpname, gfxGetLutGroupDecalXY(col, row, z >> 1)); -#endif - } - } - break; - case ID_IOBJ: - z++; /* fall-through*/ - case ID_IOBI: - z++; /* fall-through*/ - case ID_IOBH: - z++; /* fall-through*/ - case ID_IOBG: - z++; /* fall-through*/ - case ID_IOBF: - z++; /* fall-through*/ - case ID_IOBE: - z++; /* fall-through*/ - case ID_IOBD: - z++; /* fall-through*/ - case ID_IOBC: - z++; /* fall-through*/ - case ID_IOBB: - z++; /* fall-through*/ - case ID_IOBA: { - snprintf(buf, 32, "R%dC%d_IOB%c", row + 1, col + 1, 'A' + z); - belname = id(buf); - addBel(belname, id_IOB, Loc(col, row, z), false); - portname = IdString(pairLookup(bel->ports.get(), bel->num_ports, ID_O)->src_id); - snprintf(buf, 32, "R%dC%d_%s", row + 1, col + 1, portname.c_str(this)); - addBelOutput(belname, id_O, id(buf)); - portname = IdString(pairLookup(bel->ports.get(), bel->num_ports, ID_I)->src_id); - snprintf(buf, 32, "R%dC%d_%s", row + 1, col + 1, portname.c_str(this)); - addBelInput(belname, id_I, id(buf)); - portname = IdString(pairLookup(bel->ports.get(), bel->num_ports, ID_OE)->src_id); - snprintf(buf, 32, "R%dC%d_%s", row + 1, col + 1, portname.c_str(this)); - addBelInput(belname, id_OEN, id(buf)); - // GW1NR-9 quirk - const PairPOD *quirk_port = pairLookup(bel->ports.get(), bel->num_ports, ID_GW9_ALWAYS_LOW0); - if (quirk_port != nullptr) { - gw1n9_quirk = true; - portname = IdString(quirk_port->src_id); - snprintf(buf, 32, "R%dC%d_%s", row + 1, col + 1, portname.c_str(this)); - addBelInput(belname, id_GW9_ALWAYS_LOW0, id(buf)); - } - quirk_port = pairLookup(bel->ports.get(), bel->num_ports, ID_GW9_ALWAYS_LOW1); - if (quirk_port != nullptr) { - gw1n9_quirk = true; - portname = IdString(quirk_port->src_id); - snprintf(buf, 32, "R%dC%d_%s", row + 1, col + 1, portname.c_str(this)); - addBelInput(belname, id_GW9_ALWAYS_LOW1, id(buf)); - } - if (!z && device_id == id("GW1NR-9C")) { - addBelInput(belname, id_GW9C_ALWAYS_LOW0, idf("R%dC%d_C6", row + 1, col + 1)); - addBelInput(belname, id_GW9C_ALWAYS_LOW1, idf("R%dC%d_D6", row + 1, col + 1)); - } - } break; - // Simplified IO - case ID_IOBJS: - z++; /* fall-through*/ - case ID_IOBIS: - z++; /* fall-through*/ - case ID_IOBHS: - z++; /* fall-through*/ - case ID_IOBGS: - z++; /* fall-through*/ - case ID_IOBFS: - z++; /* fall-through*/ - case ID_IOBES: - z++; /* fall-through*/ - case ID_IOBDS: - z++; /* fall-through*/ - case ID_IOBCS: - z++; /* fall-through*/ - case ID_IOBBS: - z++; /* fall-through*/ - case ID_IOBAS: - snprintf(buf, 32, "R%dC%d_IOB%c", row + 1, col + 1, 'A' + z); - belname = id(buf); - addBel(belname, id_IOBS, Loc(col, row, z), false); - portname = IdString(pairLookup(bel->ports.get(), bel->num_ports, ID_O)->src_id); - snprintf(buf, 32, "R%dC%d_%s", row + 1, col + 1, portname.c_str(this)); - addBelOutput(belname, id_O, id(buf)); - portname = IdString(pairLookup(bel->ports.get(), bel->num_ports, ID_I)->src_id); - snprintf(buf, 32, "R%dC%d_%s", row + 1, col + 1, portname.c_str(this)); - addBelInput(belname, id_I, id(buf)); - portname = IdString(pairLookup(bel->ports.get(), bel->num_ports, ID_OE)->src_id); - snprintf(buf, 32, "R%dC%d_%s", row + 1, col + 1, portname.c_str(this)); - addBelInput(belname, id_OEN, id(buf)); - break; - - // IO logic - case ID_IOLOGICB: - z++; /* fall-through*/ - case ID_IOLOGICA: { - belname = idf("R%dC%d_IOLOGIC%c", row + 1, col + 1, 'A' + z); - addBel(belname, id_IOLOGIC, Loc(col, row, BelZ::iologic_z + z), false); - - IdString const iologic_in_ports[] = {id_TX, id_TX0, id_TX1, id_TX2, id_TX3, id_RESET, - id_CALIB, id_PCLK, id_D, id_D0, id_D1, id_D2, - id_D3, id_D4, id_D5, id_D6, id_D7, id_D8, - id_D9, id_CLK, id_CLEAR, id_DAADJ0, id_DAADJ1}; - for (IdString port : iologic_in_ports) { - const PairPOD *portid = pairLookup(bel->ports.get(), bel->num_ports, port.hash()); - if (portid != nullptr) { - portname = IdString(portid->src_id); - addBelInput(belname, port, idf("R%dC%d_%s", row + 1, col + 1, portname.c_str(this))); - } - } - IdString const iologic_out_ports[] = {id_Q, id_Q0, id_Q1, id_Q2, id_Q3, id_Q4, - id_Q5, id_Q6, id_Q7, id_Q8, id_Q9}; - for (IdString port : iologic_out_ports) { - portname = IdString(pairLookup(bel->ports.get(), bel->num_ports, port.hash())->src_id); - addBelOutput(belname, port, idf("R%dC%d_%s", row + 1, col + 1, portname.c_str(this))); - } - auto fclk = pairLookup(bel->ports.get(), bel->num_ports, ID_FCLK); - // XXX as long as there is no special processing of the pins - if (fclk != nullptr) { - portname = IdString(fclk->src_id); - IdString wire = idf("R%dC%d_%s", row + 1, col + 1, portname.c_str(this)); - if (!wires.count(wire)) { - GlobalAliasPOD alias; - alias.dest_col = col; - alias.dest_row = row; - alias.dest_id = portname.hash(); - auto alias_src = genericLookup(db->aliases.get(), db->num_aliases, alias, aliasCompare); - if (alias_src != nullptr) { - int srcrow = alias_src->src_row; - int srccol = alias_src->src_col; - IdString srcid = IdString(alias_src->src_id); - wire = wireToGlobal(srcrow, srccol, db, srcid); - if (!wires.count(wire)) { - addWire(wire, srcid, srccol, srcrow); - } - addBelInput(belname, id_FCLK, wire); - } - // XXX here we are creating an - // IOLOGIC with a missing FCLK input. This is so - // because bels with the same type can be placed in - // on the chip where there is no pin, so no - // IOLOGIC makes sense. But since each type is - // described only once in the database we can't really - // mark these special bel somehow. - // By creating an IOLOGIC without an FCLK input we - // create a routing error later, so that "bad" - // locations are handled. - } else { - addBelInput(belname, id_FCLK, idf("R%dC%d_%s", row + 1, col + 1, portname.c_str(this))); - } - } - } break; - case ID_OSER16: { - if (skip_aux_oser16(device, row, col)) { - break; - } - belname = idf("R%dC%d_OSER16", row + 1, col + 1); - addBel(belname, id_OSER16, Loc(col, row, BelZ::oser16_z), false); - - const IdString oser16_in_ports[] = {id_RESET, id_PCLK, id_D0, id_D1, id_D2, id_D3, - id_D4, id_D5, id_D6, id_D7, id_D8, id_D9, - id_D10, id_D11, id_D12, id_D13, id_D14, id_D15}; - for (IdString port : oser16_in_ports) { - portname = IdString(pairLookup(bel->ports.get(), bel->num_ports, port.hash())->src_id); - addBelInput(belname, port, idf("R%dC%d_%s", row + 1, col + 1, portname.c_str(this))); - } - portname = IdString(pairLookup(bel->ports.get(), bel->num_ports, id_Q0.hash())->src_id); - addBelOutput(belname, id_Q, idf("R%dC%d_%s", row + 1, col + 1, portname.c_str(this))); - auto fclk = pairLookup(bel->ports.get(), bel->num_ports, ID_FCLK); - // XXX as long as there is no special processing of the pins - if (fclk != nullptr) { - portname = IdString(fclk->src_id); - IdString wire = idf("R%dC%d_%s", row + 1, col + 1, portname.c_str(this)); - if (!wires.count(wire)) { - GlobalAliasPOD alias; - alias.dest_col = col; - alias.dest_row = row; - alias.dest_id = portname.hash(); - auto alias_src = genericLookup(db->aliases.get(), db->num_aliases, alias, aliasCompare); - if (alias_src != nullptr) { - int srcrow = alias_src->src_row; - int srccol = alias_src->src_col; - IdString srcid = IdString(alias_src->src_id); - wire = wireToGlobal(srcrow, srccol, db, srcid); - if (!wires.count(wire)) { - addWire(wire, srcid, srccol, srcrow); - } - addBelInput(belname, id_FCLK, wire); - } - } else { - addBelInput(belname, id_FCLK, idf("R%dC%d_%s", row + 1, col + 1, portname.c_str(this))); - } - } - } break; - case ID_IDES16: { - if (skip_aux_oser16(device, row, col)) { - break; - } - belname = idf("R%dC%d_IDES16", row + 1, col + 1); - addBel(belname, id_IDES16, Loc(col, row, BelZ::ides16_z), false); - - IdString const ides16_in_ports[] = {id_RESET, id_PCLK, id_CALIB, id_D}; - for (IdString port : ides16_in_ports) { - portname = IdString(pairLookup(bel->ports.get(), bel->num_ports, port.hash())->src_id); - addBelInput(belname, port, idf("R%dC%d_%s", row + 1, col + 1, portname.c_str(this))); - } - IdString const ides16_out_ports[] = {id_Q0, id_Q1, id_Q2, id_Q3, id_Q4, id_Q5, id_Q6, id_Q7, - id_Q8, id_Q9, id_Q10, id_Q11, id_Q12, id_Q13, id_Q14, id_Q15}; - for (IdString port : ides16_out_ports) { - portname = IdString(pairLookup(bel->ports.get(), bel->num_ports, port.hash())->src_id); - addBelOutput(belname, port, idf("R%dC%d_%s", row + 1, col + 1, portname.c_str(this))); - } - auto fclk = pairLookup(bel->ports.get(), bel->num_ports, ID_FCLK); - // XXX as long as there is no special processing of the pins - if (fclk != nullptr) { - portname = IdString(fclk->src_id); - IdString wire = idf("R%dC%d_%s", row + 1, col + 1, portname.c_str(this)); - if (!wires.count(wire)) { - GlobalAliasPOD alias; - alias.dest_col = col; - alias.dest_row = row; - alias.dest_id = portname.hash(); - auto alias_src = genericLookup(db->aliases.get(), db->num_aliases, alias, aliasCompare); - if (alias_src != nullptr) { - int srcrow = alias_src->src_row; - int srccol = alias_src->src_col; - IdString srcid = IdString(alias_src->src_id); - wire = wireToGlobal(srcrow, srccol, db, srcid); - if (!wires.count(wire)) { - addWire(wire, srcid, srccol, srcrow); - } - addBelInput(belname, id_FCLK, wire); - } - } else { - addBelInput(belname, id_FCLK, idf("R%dC%d_%s", row + 1, col + 1, portname.c_str(this))); - } - } - } break; - default: - break; - } - } - } - - // IO pin configs - for (unsigned int i = 0; i < package->num_pins; i++) { - const PinPOD *pin = &package->pins[i]; - if (pin->num_cfgs == 0) { - continue; - } - auto b = bels.find(IdString(pin->loc_id)); - if (b == bels.end()) { - // Not all pins are transmitted, e.g. MODE, DONE etc. - continue; - } - std::vector &cfgs = b->second.pin_cfgs; - for (unsigned int j = 0; j < pin->num_cfgs; ++j) { - cfgs.push_back(IdString(pin->cfgs[j])); - } - } - - // setup pips - for (int i = 0; i < db->rows * db->cols; i++) { - int row = i / db->cols; - int col = i % db->cols; - const TilePOD *tile = db->grid[i].get(); - const PairPOD *pips[2] = {tile->pips.get(), tile->clock_pips.get()}; - unsigned int num_pips[2] = {tile->num_pips, tile->num_clock_pips}; - for (int p = 0; p < 2; p++) { - for (unsigned int j = 0; j < num_pips[p]; j++) { - const PairPOD pip = pips[p][j]; - int destrow = row; - int destcol = col; - IdString destid(pip.dest_id), gdestid(pip.dest_id); - IdString gdestname = wireToGlobal(destrow, destcol, db, gdestid); - int srcrow = row; - int srccol = col; - IdString srcid(pip.src_id), gsrcid(pip.src_id); - IdString gsrcname = wireToGlobal(srcrow, srccol, db, gsrcid); - - snprintf(buf, 32, "R%dC%d_%s_%s", row + 1, col + 1, srcid.c_str(this), destid.c_str(this)); - IdString pipname = id(buf); - DelayQuad delay = getWireTypeDelay(destid); - // global alias - srcid = IdString(pip.src_id); - GlobalAliasPOD alias; - alias.dest_col = srccol; - alias.dest_row = srcrow; - alias.dest_id = srcid.index; - auto alias_src = genericLookup(db->aliases.get(), db->num_aliases, alias, aliasCompare); - if (alias_src != nullptr) { - srccol = alias_src->src_col; - srcrow = alias_src->src_row; - srcid = IdString(alias_src->src_id); - gsrcname = wireToGlobal(srcrow, srccol, db, srcid); - } - addPip(pipname, destid, gsrcname, gdestname, delay, Loc(col, row, j)); - } - } - } - if (args.gui) { - setDefaultDecals(); - } - - // Permissible combinations of modes in a single slice - dff_comp_mode[id_DFF] = id_DFF; - dff_comp_mode[id_DFFE] = id_DFFE; - dff_comp_mode[id_DFFS] = id_DFFR; - dff_comp_mode[id_DFFR] = id_DFFS; - dff_comp_mode[id_DFFSE] = id_DFFRE; - dff_comp_mode[id_DFFRE] = id_DFFSE; - dff_comp_mode[id_DFFP] = id_DFFC; - dff_comp_mode[id_DFFC] = id_DFFP; - dff_comp_mode[id_DFFPE] = id_DFFCE; - dff_comp_mode[id_DFFCE] = id_DFFPE; - dff_comp_mode[id_DFFNS] = id_DFFNR; - dff_comp_mode[id_DFFNR] = id_DFFNS; - dff_comp_mode[id_DFFNSE] = id_DFFNRE; - dff_comp_mode[id_DFFNRE] = id_DFFNSE; - dff_comp_mode[id_DFFNP] = id_DFFNC; - dff_comp_mode[id_DFFNC] = id_DFFNP; - dff_comp_mode[id_DFFNPE] = id_DFFNCE; - dff_comp_mode[id_DFFNCE] = id_DFFNPE; - - BaseArch::init_cell_types(); - BaseArch::init_bel_buckets(); -} - -void IdString::initialize_arch(const BaseCtx *ctx) -{ -#define X(t) initialize_add(ctx, #t, ID_##t); -#include "constids.inc" -#undef X -} - -// --------------------------------------------------------------- - -BelId Arch::getBelByName(IdStringList name) const -{ - if (bels.count(name[0])) - return name[0]; - return BelId(); -} - -IdStringList Arch::getBelName(BelId bel) const { return IdStringList(bel); } - -Loc Arch::getBelLocation(BelId bel) const -{ - auto &info = bels.at(bel); - return Loc(info.x, info.y, info.z); -} - -BelId Arch::getBelByLocation(Loc loc) const -{ - auto it = bel_by_loc.find(loc); - if (it != bel_by_loc.end()) - return it->second; - return BelId(); -} - -const std::vector &Arch::getBelsByTile(int x, int y) const { return bels_by_tile.at(x).at(y); } - -bool Arch::haveBelType(int x, int y, IdString bel_type) -{ - for (auto bel : getBelsByTile(x, y)) { - BelInfo bi = bel_info(bel); - if (bi.type == bel_type) { - return true; - } - } - return false; -} - -bool Arch::getBelGlobalBuf(BelId bel) const { return bels.at(bel).gb; } - -void Arch::bindBel(BelId bel, CellInfo *cell, PlaceStrength strength) -{ - bels.at(bel).bound_cell = cell; - cell->bel = bel; - cell->belStrength = strength; - refreshUiBel(bel); -} - -void Arch::unbindBel(BelId bel) -{ - bels.at(bel).bound_cell->bel = BelId(); - bels.at(bel).bound_cell->belStrength = STRENGTH_NONE; - bels.at(bel).bound_cell = nullptr; - refreshUiBel(bel); -} - -bool Arch::checkBelAvail(BelId bel) const { return bels.at(bel).bound_cell == nullptr; } - -CellInfo *Arch::getBoundBelCell(BelId bel) const { return bels.at(bel).bound_cell; } - -CellInfo *Arch::getConflictingBelCell(BelId bel) const { return bels.at(bel).bound_cell; } - -const std::vector &Arch::getBels() const { return bel_ids; } - -IdString Arch::getBelType(BelId bel) const { return bels.at(bel).type; } - -const std::map &Arch::getBelAttrs(BelId bel) const { return bels.at(bel).attrs; } - -WireId Arch::getBelPinWire(BelId bel, IdString pin) const -{ - const auto &bdata = bels.at(bel); - if (!bdata.pins.count(pin)) - log_error("bel '%s' has no pin '%s'\n", bel.c_str(this), pin.c_str(this)); - return bdata.pins.at(pin).wire; -} - -PortType Arch::getBelPinType(BelId bel, IdString pin) const { return bels.at(bel).pins.at(pin).type; } - -std::vector Arch::getBelPins(BelId bel) const -{ - std::vector ret; - for (auto &it : bels.at(bel).pins) - ret.push_back(it.first); - return ret; -} - -std::array Arch::getBelPinsForCellPin(const CellInfo *cell_info, IdString pin) const { return {pin}; } - -// --------------------------------------------------------------- - -WireId Arch::getWireByName(IdStringList name) const -{ - if (wires.count(name[0])) - return name[0]; - return WireId(); -} - -IdStringList Arch::getWireName(WireId wire) const { return IdStringList(wire); } - -IdString Arch::getWireType(WireId wire) const { return wires.at(wire).type; } - -const std::map &Arch::getWireAttrs(WireId wire) const { return wires.at(wire).attrs; } - -void Arch::bindWire(WireId wire, NetInfo *net, PlaceStrength strength) -{ - wires.at(wire).bound_net = net; - net->wires[wire].pip = PipId(); - net->wires[wire].strength = strength; - refreshUiWire(wire); -} - -void Arch::unbindWire(WireId wire) -{ - auto &net_wires = wires.at(wire).bound_net->wires; - - auto pip = net_wires.at(wire).pip; - if (pip != PipId()) { - pips.at(pip).bound_net = nullptr; - refreshUiPip(pip); - } - - net_wires.erase(wire); - wires.at(wire).bound_net = nullptr; - refreshUiWire(wire); -} - -bool Arch::checkWireAvail(WireId wire) const { return wires.at(wire).bound_net == nullptr; } - -NetInfo *Arch::getBoundWireNet(WireId wire) const { return wires.at(wire).bound_net; } - -NetInfo *Arch::getConflictingWireNet(WireId wire) const { return wires.at(wire).bound_net; } - -const std::vector &Arch::getWireBelPins(WireId wire) const { return wires.at(wire).bel_pins; } - -const std::vector &Arch::getWires() const { return wire_ids; } - -// --------------------------------------------------------------- - -PipId Arch::getPipByName(IdStringList name) const -{ - if (pips.count(name[0])) - return name[0]; - return PipId(); -} - -IdStringList Arch::getPipName(PipId pip) const { return IdStringList(pip); } - -IdString Arch::getPipType(PipId pip) const { return pips.at(pip).type; } - -const std::map &Arch::getPipAttrs(PipId pip) const { return pips.at(pip).attrs; } - -void Arch::bindPip(PipId pip, NetInfo *net, PlaceStrength strength) -{ - WireId wire = pips.at(pip).dstWire; - pips.at(pip).bound_net = net; - wires.at(wire).bound_net = net; - net->wires[wire].pip = pip; - net->wires[wire].strength = strength; - refreshUiPip(pip); - refreshUiWire(wire); -} - -void Arch::unbindPip(PipId pip) -{ - WireId wire = pips.at(pip).dstWire; - wires.at(wire).bound_net->wires.erase(wire); - pips.at(pip).bound_net = nullptr; - wires.at(wire).bound_net = nullptr; - refreshUiPip(pip); - refreshUiWire(wire); -} - -bool Arch::checkPipAvail(PipId pip) const { return pips.at(pip).bound_net == nullptr; } - -NetInfo *Arch::getBoundPipNet(PipId pip) const { return pips.at(pip).bound_net; } - -NetInfo *Arch::getConflictingPipNet(PipId pip) const { return pips.at(pip).bound_net; } - -WireId Arch::getConflictingPipWire(PipId pip) const { return pips.at(pip).bound_net ? pips.at(pip).dstWire : WireId(); } - -const std::vector &Arch::getPips() const { return pip_ids; } - -Loc Arch::getPipLocation(PipId pip) const { return pips.at(pip).loc; } - -WireId Arch::getPipSrcWire(PipId pip) const { return pips.at(pip).srcWire; } - -WireId Arch::getPipDstWire(PipId pip) const { return pips.at(pip).dstWire; } - -DelayQuad Arch::getPipDelay(PipId pip) const { return pips.at(pip).delay; } - -const std::vector &Arch::getPipsDownhill(WireId wire) const { return wires.at(wire).downhill; } - -const std::vector &Arch::getPipsUphill(WireId wire) const { return wires.at(wire).uphill; } - -// --------------------------------------------------------------- - -GroupId Arch::getGroupByName(IdStringList name) const { return name[0]; } - -IdStringList Arch::getGroupName(GroupId group) const { return IdStringList(group); } - -std::vector Arch::getGroups() const -{ - std::vector ret; - for (auto &it : groups) - ret.push_back(it.first); - return ret; -} - -const std::vector &Arch::getGroupBels(GroupId group) const { return groups.at(group).bels; } - -const std::vector &Arch::getGroupWires(GroupId group) const { return groups.at(group).wires; } - -const std::vector &Arch::getGroupPips(GroupId group) const { return groups.at(group).pips; } - -const std::vector &Arch::getGroupGroups(GroupId group) const { return groups.at(group).groups; } - -// --------------------------------------------------------------- - -delay_t Arch::estimateDelay(WireId src, WireId dst) const -{ - const WireInfo &s = wires.at(src); - const WireInfo &d = wires.at(dst); - int dx = abs(s.x - d.x); - int dy = abs(s.y - d.y); - return (dx + dy) * args.delayScale + args.delayOffset; -} - -delay_t Arch::predictDelay(BelId src_bel, IdString src_pin, BelId dst_bel, IdString dst_pin) const -{ - NPNR_UNUSED(src_pin); - NPNR_UNUSED(dst_pin); - auto driver_loc = getBelLocation(src_bel); - auto sink_loc = getBelLocation(dst_bel); - - int dx = abs(sink_loc.x - driver_loc.x); - int dy = abs(sink_loc.y - driver_loc.y); - return (dx + dy) * args.delayScale + args.delayOffset; -} - -BoundingBox Arch::getRouteBoundingBox(WireId src, WireId dst) const -{ - BoundingBox bb; - - int src_x = wires.at(src).x; - int src_y = wires.at(src).y; - int dst_x = wires.at(dst).x; - int dst_y = wires.at(dst).y; - - bb.x0 = src_x; - bb.y0 = src_y; - bb.x1 = src_x; - bb.y1 = src_y; - - auto extend = [&](int x, int y) { - bb.x0 = std::min(bb.x0, x); - bb.x1 = std::max(bb.x1, x); - bb.y0 = std::min(bb.y0, y); - bb.y1 = std::max(bb.y1, y); - }; - extend(dst_x, dst_y); - return bb; -} - -// --------------------------------------------------------------- - -bool Arch::place() -{ - std::string placer = str_or_default(settings, id_placer, defaultPlacer); - bool retVal; - if (placer == "heap") { - bool have_iobuf_or_constr = false; - for (auto &cell : cells) { - CellInfo *ci = cell.second.get(); - if (ci->type == id_IOB || ci->bel != BelId() || ci->attrs.count(id_BEL)) { - have_iobuf_or_constr = true; - break; - } - } - if (!have_iobuf_or_constr) { - log_warning("Unable to use HeAP due to a lack of IO buffers or constrained cells as anchors; reverting to " - "SA.\n"); - retVal = placer1(getCtx(), Placer1Cfg(getCtx())); - } else { - PlacerHeapCfg cfg(getCtx()); - cfg.ioBufTypes.insert(id_IOB); - cfg.beta = 0.5; - retVal = placer_heap(getCtx(), cfg); - } - getCtx()->settings[id_place] = 1; - archInfoToAttributes(); - } else if (placer == "sa") { - retVal = placer1(getCtx(), Placer1Cfg(getCtx())); - getCtx()->settings[id_place] = 1; - archInfoToAttributes(); - return retVal; - } else { - log_error("Gowin architecture does not support placer '%s'\n", placer.c_str()); - } - // debug placement - if (getCtx()->debug) { - for (auto &cell : getCtx()->cells) { - log_info("Placed: %s -> %s\n", cell.first.c_str(getCtx()), getCtx()->nameOfBel(cell.second->bel)); - } - } - return retVal; -} - -static bool is_spec_iob(const Context *ctx, const CellInfo *cell, IdString pin_name) -{ - if (!is_iob(ctx, cell)) { - return false; - } - std::vector const &cfgs = ctx->bels.at(cell->bel).pin_cfgs; - bool have_pin = std::find(cfgs.begin(), cfgs.end(), pin_name) != cfgs.end(); - return have_pin; -} - -static bool is_RPLL_T_IN_iob(const Context *ctx, const CellInfo *cell) -{ - return is_spec_iob(ctx, cell, ctx->id("RPLL_T_IN")); -} - -static bool is_LPLL_T_IN_iob(const Context *ctx, const CellInfo *cell) -{ - return is_spec_iob(ctx, cell, ctx->id("LPLL_T_IN")); -} - -static bool is_RPLL_T_FB_iob(const Context *ctx, const CellInfo *cell) -{ - return is_spec_iob(ctx, cell, ctx->id("RPLL_T_FB")); -} - -static bool is_LPLL_T_FB_iob(const Context *ctx, const CellInfo *cell) -{ - return is_spec_iob(ctx, cell, ctx->id("LPLL_T_FB")); -} - -bool Arch::is_GCLKT_iob(const CellInfo *cell) -{ - for (int i = 0; i < 6; ++i) { - if (is_spec_iob(getCtx(), cell, idf("GCLKT_%d", i))) { - return true; - } - } - return false; -} - -void Arch::bind_pll_to_bel(CellInfo *ci, PLL loc) -{ - BelId bel; - switch (ci->type.hash()) { - case ID_PLLVR: - bel = loc == PLL::left ? id("R1C28_PLLVR") : id("R1C37_PLLVR"); - break; - case ID_rPLL: - if (family == "GW1N-1" || family == "GW1NZ-1") { - if (loc == PLL::left) { - return; - } - bel = id("R1C18_rPLL"); - break; - } - if (family == "GW1NS-2") { - if (loc == PLL::left) { - return; - } - bel = id("R10C20_rPLL"); - break; - } - if (family == "GW1N-4") { - bel = loc == PLL::left ? id("R1C10_rPLL") : id("R1C28_rPLL"); - break; - } - if (family == "GW1NR-9C" || family == "GW1NR-9") { - bel = loc == PLL::left ? id("R10C1_rPLL") : id("R10C47_rPLL"); - break; - } - return; - default: - return; - } - if (checkBelAvail(bel) || ci->belStrength != STRENGTH_LOCKED) { - if (ci->bel == bel) { - unbindBel(bel); - } else { - if (!checkBelAvail(bel) && ci->belStrength != STRENGTH_LOCKED) { - CellInfo *other_ci = getBoundBelCell(bel); - unbindBel(bel); - BelId our_bel = ci->bel; - unbindBel(our_bel); - bindBel(our_bel, other_ci, STRENGTH_LOCKED); - } - } - ci->disconnectPort(id_CLKIN); - ci->setParam(id_INSEL, Property("CLKIN0")); - bindBel(bel, ci, STRENGTH_LOCKED); - } -} - -// If the PLL input can be connected using a direct wire, then do so, -// bypassing conventional routing. -void Arch::fix_pll_nets(Context *ctx) -{ - for (auto &cell : ctx->cells) { - CellInfo *ci = cell.second.get(); - if (ci->type != id_rPLL && ci->type != id_PLLVR) { - continue; - } - // *** CLKIN - do { - if (!port_used(ci, id_CLKIN)) { - ci->setParam(id_INSEL, Property("UNKNOWN")); - break; - } - NetInfo *net = ci->getPort(id_CLKIN); - if (net->name == id("$PACKER_VCC_NET") || net->name == id("$PACKER_GND_NET")) { - ci->setParam(id_INSEL, Property("UNKNOWN")); - break; - } - if (net_driven_by(ctx, net, is_RPLL_T_IN_iob, id_O) != nullptr) { - bind_pll_to_bel(ci, PLL::right); - break; - } - if (net_driven_by(ctx, net, is_LPLL_T_IN_iob, id_O) != nullptr) { - bind_pll_to_bel(ci, PLL::left); - break; - } - // XXX do special bels (HCLK etc) - // This is general routing through CLK0 pip - ci->setParam(id_INSEL, Property("CLKIN1")); - } while (0); - - do { - // *** CLKFB - if (str_or_default(ci->params, id_CLKFB_SEL, "internal") == "internal") { - ci->setParam(id_FBSEL, Property("CLKFB3")); - continue; - } - if (!port_used(ci, id_CLKFB)) { - ci->setParam(id_FBSEL, Property("UNKNOWN")); - continue; - } - NetInfo *net = ci->getPort(id_CLKFB); - if (net->name == id("$PACKER_VCC_NET") || net->name == id("$PACKER_GND_NET")) { - ci->setParam(id_FBSEL, Property("UNKNOWN")); - continue; - } - // XXX Redesign for chips other than N-1 and NS-4 - if (net_driven_by(ctx, net, is_RPLL_T_FB_iob, id_O) != nullptr) { - ci->disconnectPort(id_CLKFB); - ci->setParam(id_FBSEL, Property("CLKFB2")); - break; - } - if (net_driven_by(ctx, net, is_LPLL_T_FB_iob, id_O) != nullptr) { - ci->disconnectPort(id_CLKFB); - ci->setParam(id_FBSEL, Property("CLKFB2")); - break; - } - // XXX do special bels (HCLK etc) - // This is general routing through CLK2 pip - ci->setParam(id_FBSEL, Property("CLKFB0")); - } while (0); - } -} - -// mark with hclk is used -void Arch::mark_used_hclk(Context *ctx) -{ - pool aux_cells; - for (auto &cell : ctx->cells) { - CellInfo *ci = cell.second.get(); - if (ci->type != id_IOLOGIC) { - continue; - } - if (ci->attrs.count(id_IOLOGIC_FCLK)) { - continue; - } - // if it's an aux cell - if (ci->attrs.count(id_IOLOGIC_MASTER_CELL)) { - aux_cells.insert(ci->name); - continue; - } - ci->setAttr(id_IOLOGIC_FCLK, Property("UNKNOWN")); - - // *** FCLK - if (port_used(ci, id_FCLK)) { - NetInfo const *net = ci->getPort(id_FCLK); - for (auto const &user : net->users) { - if (user.cell != ci) { - continue; - } - if (user.port != id_FCLK) { - continue; - } - WireId dstWire = ctx->getNetinfoSinkWire(net, user, 0); - if (ctx->verbose) { - log_info(" Cell:%s, port:%s, wire:%s\n", user.cell->name.c_str(this), user.port.c_str(this), - dstWire.c_str(this)); - } - for (PipId pip : getPipsUphill(dstWire)) { - if (!checkPipAvail(pip)) { - WireId src_wire = getPipSrcWire(pip); - ci->setAttr(id_IOLOGIC_FCLK, Property(wire_info(src_wire).type.str(this))); - } - } - } - } - } - for (auto acell : aux_cells) { - IdString main_cell = ctx->id(ctx->cells.at(acell)->attrs.at(id_IOLOGIC_MASTER_CELL).as_string()); - Property &fclk = ctx->cells.at(main_cell)->attrs.at(id_IOLOGIC_FCLK); - ctx->cells.at(acell)->setAttr(id_IOLOGIC_FCLK, fclk); - } -} - -void Arch::pre_route(Context *ctx) -{ - fix_pll_nets(ctx); - if (bool_or_default(settings, id("arch.enable-globals"))) { - mark_gowin_globals(ctx); - } -} - -void Arch::post_route(Context *ctx) -{ - fix_longwire_bels(); - mark_used_hclk(ctx); -} - -bool Arch::route() -{ - std::string router = str_or_default(settings, id_router, defaultRouter); - Context *ctx = getCtx(); - - pre_route(ctx); - if (bool_or_default(settings, id("arch.enable-globals"))) { - route_gowin_globals(ctx); - } - - bool result; - if (router == "router1") { - result = router1(ctx, Router1Cfg(ctx)); - } else if (router == "router2") { - router2(ctx, Router2Cfg(ctx)); - result = true; - } else { - log_error("Gowin architecture does not support router '%s'\n", router.c_str()); - } - getCtx()->settings[id_route] = 1; - archInfoToAttributes(); - post_route(ctx); - return result; -} - -// --------------------------------------------------------------- -std::vector Arch::getDecalGraphics(DecalId decal) const -{ - if (!decal_graphics.count(decal)) { - // XXX - return std::vector(); - } - return decal_graphics.at(decal); -} - -// --------------------------------------------------------------- - -bool Arch::getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort, DelayQuad &delay) const -{ - if (!cellTiming.count(cell->name)) - return false; - const auto &tmg = cellTiming.at(cell->name); - auto fnd = tmg.combDelays.find(CellDelayKey{fromPort, toPort}); - if (fnd != tmg.combDelays.end()) { - delay = fnd->second; - return true; - } else { - return false; - } -} - -// Get the port class, also setting clockPort if applicable -TimingPortClass Arch::getPortTimingClass(const CellInfo *cell, IdString port, int &clockInfoCount) const -{ - if (!cellTiming.count(cell->name)) - return TMG_IGNORE; - const auto &tmg = cellTiming.at(cell->name); - if (tmg.clockingInfo.count(port)) - clockInfoCount = int(tmg.clockingInfo.at(port).size()); - else - clockInfoCount = 0; - return get_or_default(tmg.portClasses, port, TMG_IGNORE); -} - -TimingClockingInfo Arch::getPortClockingInfo(const CellInfo *cell, IdString port, int index) const -{ - NPNR_ASSERT(cellTiming.count(cell->name)); - const auto &tmg = cellTiming.at(cell->name); - NPNR_ASSERT(tmg.clockingInfo.count(port)); - return tmg.clockingInfo.at(port).at(index); -} - -bool Arch::isBelLocationValid(BelId bel, bool explain_invalid) const -{ - Loc loc = getBelLocation(bel); - - std::vector cells; - for (auto tbel : getBelsByTile(loc.x, loc.y)) { - CellInfo *bound = getBoundBelCell(tbel); - if (bound != nullptr) - cells.push_back(bound); - } - - return cellsCompatible(cells.data(), int(cells.size())); -} - -const std::string Arch::defaultPlacer = "heap"; - -const std::vector Arch::availablePlacers = {"sa", "heap"}; - -const std::string Arch::defaultRouter = "router1"; -const std::vector Arch::availableRouters = {"router1", "router2"}; - -void Arch::assignArchInfo() -{ - for (auto &cell : getCtx()->cells) { - IdString cname = cell.first; - CellInfo *ci = cell.second.get(); - DelayQuad delay = DelayQuad(0); - ci->is_slice = false; - switch (ci->type.index) { - case ID_SLICE: { - ci->is_slice = true; - ci->ff_used = ci->params.at(id_FF_USED).as_bool(); - ci->ff_type = id(ci->params.at(id_FF_TYPE).as_string()); - ci->slice_clk = ci->getPort(id_CLK); - ci->slice_ce = ci->getPort(id_CE); - ci->slice_lsr = ci->getPort(id_LSR); - - // add timing paths - addCellTimingClock(cname, id_CLK); - addCellTimingClass(cname, id_CE, TMG_REGISTER_INPUT); - addCellTimingClass(cname, id_LSR, TMG_REGISTER_INPUT); - IdString ports[4] = {id_A, id_B, id_C, id_D}; - for (int i = 0; i < 4; i++) { - DelayPair setup = - delayLookup(speed->dff.timings.get(), speed->dff.num_timings, id_clksetpos).delayPair(); - DelayPair hold = - delayLookup(speed->dff.timings.get(), speed->dff.num_timings, id_clkholdpos).delayPair(); - addCellTimingSetupHold(cname, ports[i], id_CLK, setup, hold); - } - DelayQuad clkout = delayLookup(speed->dff.timings.get(), speed->dff.num_timings, id_clk_qpos); - addCellTimingClockToOut(cname, id_Q, id_CLK, clkout); - IdString port_delay[4] = {id_a_f, id_b_f, id_c_f, id_d_f}; - for (int i = 0; i < 4; i++) { - DelayQuad delay = delayLookup(speed->lut.timings.get(), speed->lut.num_timings, port_delay[i]); - addCellTimingDelay(cname, ports[i], id_F, delay); - } - break; - } - case ID_MUX2_LUT8: - delay = delay + delayLookup(speed->lut.timings.get(), speed->lut.num_timings, id_fx_ofx1); - /* FALLTHRU */ - case ID_MUX2_LUT7: - delay = delay + delayLookup(speed->lut.timings.get(), speed->lut.num_timings, id_fx_ofx1); - /* FALLTHRU */ - case ID_MUX2_LUT6: - delay = delay + delayLookup(speed->lut.timings.get(), speed->lut.num_timings, id_fx_ofx1); - /* FALLTHRU */ - case ID_MUX2_LUT5: { - delay = delay + delayLookup(speed->lut.timings.get(), speed->lut.num_timings, id_fx_ofx1); - addCellTimingDelay(cname, id_I0, id_OF, delay); - addCellTimingDelay(cname, id_I1, id_OF, delay); - addCellTimingClass(cname, id_SEL, TMG_COMB_INPUT); - break; - } - case ID_IOB: - /* FALLTHRU */ - case ID_IOBS: - addCellTimingClass(cname, id_I, TMG_ENDPOINT); - addCellTimingClass(cname, id_O, TMG_STARTPOINT); - break; - case ID_BUFS: - addCellTimingClass(cname, id_I, TMG_ENDPOINT); - addCellTimingClass(cname, id_O, TMG_STARTPOINT); - break; - default: - break; - } - } -} - -bool Arch::cellsCompatible(const CellInfo **cells, int count) const -{ - const NetInfo *clk[4] = {nullptr, nullptr, nullptr, nullptr}; - const NetInfo *ce[4] = {nullptr, nullptr, nullptr, nullptr}; - const NetInfo *lsr[4] = {nullptr, nullptr, nullptr, nullptr}; - IdString mode[4] = {IdString(), IdString(), IdString(), IdString()}; - for (int i = 0; i < count; i++) { - const CellInfo *ci = cells[i]; - if (ci->is_slice) { - Loc loc = getBelLocation(ci->bel); - int cls = loc.z / 2; - if (loc.z >= 6 && ci->ff_used) // top slice have no ff - return false; - if (clk[cls] == nullptr) - clk[cls] = ci->slice_clk; - else if (clk[cls] != ci->slice_clk) - return false; - if (ce[cls] == nullptr) - ce[cls] = ci->slice_ce; - else if (ce[cls] != ci->slice_ce) - return false; - if (lsr[cls] == nullptr) - lsr[cls] = ci->slice_lsr; - else if (lsr[cls] != ci->slice_lsr) - return false; - if (mode[cls] == IdString()) - mode[cls] = ci->ff_type; - else if (mode[cls] != ci->ff_type) { - auto res = dff_comp_mode.find(mode[cls]); - if (res == dff_comp_mode.end() || res->second != ci->ff_type) - return false; - } - } - } - return true; -} - -void Arch::route_gowin_globals(Context *ctx) { globals_router.route_globals(ctx); } - -void Arch::mark_gowin_globals(Context *ctx) { globals_router.mark_globals(ctx); } -// --------------------------------------------------------------- -void Arch::pre_pack(Context *ctx) -{ - if (bool_or_default(settings, id("arch.enable-auto-longwires"))) { - auto_longwires(); - } -} - -void Arch::post_pack(Context *ctx) {} - -NEXTPNR_NAMESPACE_END diff --git a/gowin/arch.h b/gowin/arch.h deleted file mode 100644 index ee687c266d..0000000000 --- a/gowin/arch.h +++ /dev/null @@ -1,555 +0,0 @@ -/* - * nextpnr -- Next Generation Place and Route - * - * Copyright (C) 2018 Claire Xenia Wolf - * Copyright (C) 2020 Pepijn de Vos - * - * 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. - * - */ - -#ifndef GOWIN_ARCH_H -#define GOWIN_ARCH_H - -#include -#include -#include -#include - -#include "base_arch.h" -#include "idstring.h" -#include "nextpnr_namespaces.h" -#include "nextpnr_types.h" - -#include "globals.h" - -NEXTPNR_NAMESPACE_BEGIN - -template struct RelPtr -{ - int32_t offset; - - // void set(const T *ptr) { - // offset = reinterpret_cast(ptr) - - // reinterpret_cast(this); - // } - - const T *get() const { return reinterpret_cast(reinterpret_cast(this) + offset); } - - T *get_mut() const - { - return const_cast(reinterpret_cast(reinterpret_cast(this) + offset)); - } - - const T &operator[](std::size_t index) const { return get()[index]; } - - const T &operator*() const { return *(get()); } - - const T *operator->() const { return get(); } - - RelPtr(const RelPtr &) = delete; - RelPtr &operator=(const RelPtr &) = delete; -}; - -NPNR_PACKED_STRUCT(struct PairPOD { - uint16_t dest_id; - uint16_t src_id; -}); - -NPNR_PACKED_STRUCT(struct BelsPOD { - uint16_t type_id; - uint16_t num_ports; - RelPtr ports; -}); - -NPNR_PACKED_STRUCT(struct TilePOD /*TidePOD*/ { - uint32_t num_bels; - RelPtr bels; - uint32_t num_pips; - RelPtr pips; - uint32_t num_clock_pips; - RelPtr clock_pips; - uint32_t num_aliases; - RelPtr aliases; -}); - -NPNR_PACKED_STRUCT(struct GlobalAliasPOD { - uint16_t dest_row; - uint16_t dest_col; - uint16_t dest_id; - uint16_t src_row; - uint16_t src_col; - uint16_t src_id; -}); - -NPNR_PACKED_STRUCT(struct TimingPOD { - uint32_t name_id; - // input, output - uint32_t ff; - uint32_t fr; - uint32_t rf; - uint32_t rr; -}); - -NPNR_PACKED_STRUCT(struct TimingGroupPOD { - uint32_t name_id; - uint32_t num_timings; - RelPtr timings; -}); - -NPNR_PACKED_STRUCT(struct TimingGroupsPOD { - TimingGroupPOD lut; - TimingGroupPOD alu; - TimingGroupPOD sram; - TimingGroupPOD dff; - // TimingGroupPOD dl; - // TimingGroupPOD iddroddr; - // TimingGroupPOD pll; - // TimingGroupPOD dll; - TimingGroupPOD bram; - // TimingGroupPOD dsp; - TimingGroupPOD fanout; - TimingGroupPOD glbsrc; - TimingGroupPOD hclk; - TimingGroupPOD iodelay; - // TimingGroupPOD io; - // TimingGroupPOD iregoreg; - TimingGroupPOD wire; -}); - -NPNR_PACKED_STRUCT(struct TimingClassPOD { - uint32_t name_id; - uint32_t num_groups; - RelPtr groups; -}); - -NPNR_PACKED_STRUCT(struct PartnumberPOD { - uint32_t name_id; - uint32_t package_id; - uint32_t device_id; - uint32_t speed_id; -}); - -NPNR_PACKED_STRUCT(struct PinPOD { - uint16_t index_id; - uint16_t loc_id; - uint32_t num_cfgs; - RelPtr cfgs; -}); - -NPNR_PACKED_STRUCT(struct PackagePOD { - uint32_t name_id; - uint32_t num_pins; - RelPtr pins; -}); - -NPNR_PACKED_STRUCT(struct VariantPOD { - uint32_t name_id; - uint32_t num_packages; - RelPtr packages; -}); - -NPNR_PACKED_STRUCT(struct DatabasePOD { - RelPtr family; - uint32_t version; - uint16_t rows; - uint16_t cols; - RelPtr> grid; - uint32_t num_aliases; - RelPtr aliases; - uint32_t num_speeds; - RelPtr speeds; - uint32_t num_partnumbers; - RelPtr partnumber_packages; - uint32_t num_variants; - RelPtr variants; - uint16_t num_constids; - uint16_t num_ids; - RelPtr> id_strs; -}); - -struct ArchArgs -{ - std::string family; - std::string partnumber; - // y = mx + c relationship between distance and delay for interconnect - // delay estimates - double delayScale = 0.4, delayOffset = 0.4; - bool gui; -}; - -struct WireInfo; - -struct PipInfo -{ - IdString name, type; - std::map attrs; - NetInfo *bound_net; - WireId srcWire, dstWire; - DelayQuad delay; - DecalXY decalxy_active, decalxy_inactive; - Loc loc; -}; - -struct WireInfo -{ - IdString name, type; - std::map attrs; - NetInfo *bound_net; - std::vector downhill, uphill; - BelPin uphill_bel_pin; - std::vector downhill_bel_pins; - std::vector bel_pins; - DecalXY decalxy_active, decalxy_inactive; - int x, y; -}; - -struct PinInfo -{ - IdString name; - WireId wire; - PortType type; -}; - -struct BelInfo -{ - IdString name, type; - std::map attrs; - CellInfo *bound_cell; - dict pins; - std::vector pin_cfgs; - DecalXY decalxy_active, decalxy_inactive; - int x, y, z; - bool gb; -}; - -struct GroupInfo -{ - IdString name; - std::vector bels; - std::vector wires; - std::vector pips; - std::vector groups; - DecalXY decalxy; -}; - -struct CellDelayKey -{ - IdString from, to; - inline bool operator==(const CellDelayKey &other) const { return from == other.from && to == other.to; } - unsigned int hash() const { return mkhash(from.hash(), to.hash()); } -}; - -struct CellTiming -{ - dict portClasses; - dict combDelays; - dict> clockingInfo; -}; - -struct ArchRanges : BaseArchRanges -{ - using ArchArgsT = ArchArgs; - // Bels - using AllBelsRangeT = const std::vector &; - using TileBelsRangeT = const std::vector &; - using BelAttrsRangeT = const std::map &; - using BelPinsRangeT = std::vector; - using CellBelPinRangeT = std::array; - // Wires - using AllWiresRangeT = const std::vector &; - using DownhillPipRangeT = const std::vector &; - using UphillPipRangeT = const std::vector &; - using WireBelPinRangeT = const std::vector &; - using WireAttrsRangeT = const std::map &; - // Pips - using AllPipsRangeT = const std::vector &; - using PipAttrsRangeT = const std::map &; - // Groups - using AllGroupsRangeT = std::vector; - using GroupBelsRangeT = const std::vector &; - using GroupWiresRangeT = const std::vector &; - using GroupPipsRangeT = const std::vector &; - using GroupGroupsRangeT = const std::vector &; -}; - -enum class PLL // fixed PLL locations -{ - left, - right -}; - -struct Arch : BaseArch -{ - std::string family; - std::string device; - const PackagePOD *package; - const TimingGroupsPOD *speed; - - dict wires; - dict pips; - dict bels; - dict groups; - - // These functions include useful errors if not found - WireInfo &wire_info(IdString wire); - PipInfo &pip_info(IdString pip); - BelInfo &bel_info(IdString bel); - NetInfo &net_info(IdString net); - - std::vector bel_ids, wire_ids, pip_ids; - - dict bel_by_loc; - std::vector>> bels_by_tile; - - dict> decal_graphics; - - int gridDimX = 0, gridDimY = 0; - std::vector> tileBelDimZ; - std::vector> tilePipDimZ; - - dict cellTiming; - - void addWire(IdString name, IdString type, int x, int y); - void addPip(IdString name, IdString type, IdString srcWire, IdString dstWire, DelayQuad delay, Loc loc); - - void addBel(IdString name, IdString type, Loc loc, bool gb); - void addBelInput(IdString bel, IdString name, IdString wire); - void addBelOutput(IdString bel, IdString name, IdString wire); - void addBelInout(IdString bel, IdString name, IdString wire); - - void addGroup(IdString name); - void addGroupBel(IdString group, IdString bel); - void addGroupWire(IdString group, IdString wire); - void addGroupPip(IdString group, IdString pip); - void addGroupGroup(IdString group, IdString grp); - - void addDecalGraphic(DecalId decal, const GraphicElement &graphic); - void setWireDecal(WireId wire, DecalXY active, DecalXY inactive); - void setPipDecal(PipId pip, DecalXY active, DecalXY inactive); - void setBelDecal(BelId bel, DecalXY active, DecalXY inactive); - void setDefaultDecals(void); - void setGroupDecal(GroupId group, DecalXY decalxy); - std::vector getDecalGraphics(DecalId decal) const override; - DecalXY getBelDecal(BelId bel) const override; - DecalXY getGroupDecal(GroupId grp) const override; - DecalXY getPipDecal(PipId pip) const override; - DecalXY getWireDecal(WireId pip) const override; - - void setWireAttr(IdString wire, IdString key, const std::string &value); - void setPipAttr(IdString pip, IdString key, const std::string &value); - void setBelAttr(IdString bel, IdString key, const std::string &value); - - void setDelayScaling(double scale, double offset); - - void addCellTimingClock(IdString cell, IdString port); - void addCellTimingClass(IdString cell, IdString port, TimingPortClass cls); - void addCellTimingDelay(IdString cell, IdString fromPort, IdString toPort, DelayQuad delay); - void addCellTimingSetupHold(IdString cell, IdString port, IdString clock, DelayPair setup, DelayPair hold); - void addCellTimingClockToOut(IdString cell, IdString port, IdString clock, DelayQuad clktoq); - - IdString wireToGlobal(int &row, int &col, const DatabasePOD *db, IdString &wire); - DelayQuad getWireTypeDelay(IdString wire); - void read_cst(std::istream &in); - void addMuxBels(const DatabasePOD *db, int row, int col); - - // --------------------------------------------------------------- - // Common Arch API. Every arch must provide the following methods. - - ArchArgs args; - Arch(ArchArgs args); - - std::string getChipName() const override { return device; } - - ArchArgs archArgs() const override { return args; } - IdString archArgsToId(ArchArgs args) const override { return id_none; } - - int getGridDimX() const override { return gridDimX; } - int getGridDimY() const override { return gridDimY; } - int getTileBelDimZ(int x, int y) const override { return tileBelDimZ[x][y]; } - int getTilePipDimZ(int x, int y) const override { return tilePipDimZ[x][y]; } - char getNameDelimiter() const override - { - return ' '; /* use a non-existent delimiter as we aren't using IdStringLists yet */ - } - - BelId getBelByName(IdStringList name) const override; - IdStringList getBelName(BelId bel) const override; - Loc getBelLocation(BelId bel) const override; - BelId getBelByLocation(Loc loc) const override; - const std::vector &getBelsByTile(int x, int y) const override; - bool getBelGlobalBuf(BelId bel) const override; - void bindBel(BelId bel, CellInfo *cell, PlaceStrength strength) override; - void unbindBel(BelId bel) override; - bool checkBelAvail(BelId bel) const override; - CellInfo *getBoundBelCell(BelId bel) const override; - CellInfo *getConflictingBelCell(BelId bel) const override; - const std::vector &getBels() const override; - IdString getBelType(BelId bel) const override; - const std::map &getBelAttrs(BelId bel) const override; - WireId getBelPinWire(BelId bel, IdString pin) const override; - PortType getBelPinType(BelId bel, IdString pin) const override; - std::vector getBelPins(BelId bel) const override; - std::array getBelPinsForCellPin(const CellInfo *cell_info, IdString pin) const override; - // Placement validity checks - virtual bool isValidBelForCellType(IdString cell_type, BelId bel) const override - { - return cell_type == id_DUMMY_CELL || cell_type == this->getBelType(bel); - } - - WireId getWireByName(IdStringList name) const override; - IdStringList getWireName(WireId wire) const override; - IdString getWireType(WireId wire) const override; - const std::map &getWireAttrs(WireId wire) const override; - void bindWire(WireId wire, NetInfo *net, PlaceStrength strength) override; - void unbindWire(WireId wire) override; - bool checkWireAvail(WireId wire) const override; - NetInfo *getBoundWireNet(WireId wire) const override; - WireId getConflictingWireWire(WireId wire) const override { return wire; } - NetInfo *getConflictingWireNet(WireId wire) const override; - DelayQuad getWireDelay(WireId wire) const override { return DelayQuad(0); } - const std::vector &getWires() const override; - const std::vector &getWireBelPins(WireId wire) const override; - - PipId getPipByName(IdStringList name) const override; - IdStringList getPipName(PipId pip) const override; - IdString getPipType(PipId pip) const override; - const std::map &getPipAttrs(PipId pip) const override; - void bindPip(PipId pip, NetInfo *net, PlaceStrength strength) override; - void unbindPip(PipId pip) override; - bool checkPipAvail(PipId pip) const override; - NetInfo *getBoundPipNet(PipId pip) const override; - WireId getConflictingPipWire(PipId pip) const override; - NetInfo *getConflictingPipNet(PipId pip) const override; - const std::vector &getPips() const override; - Loc getPipLocation(PipId pip) const override; - WireId getPipSrcWire(PipId pip) const override; - WireId getPipDstWire(PipId pip) const override; - DelayQuad getPipDelay(PipId pip) const override; - const std::vector &getPipsDownhill(WireId wire) const override; - const std::vector &getPipsUphill(WireId wire) const override; - - GroupId getGroupByName(IdStringList name) const override; - IdStringList getGroupName(GroupId group) const override; - std::vector getGroups() const override; - const std::vector &getGroupBels(GroupId group) const override; - const std::vector &getGroupWires(GroupId group) const override; - const std::vector &getGroupPips(GroupId group) const override; - const std::vector &getGroupGroups(GroupId group) const override; - - delay_t estimateDelay(WireId src, WireId dst) const override; - delay_t predictDelay(BelId src_bel, IdString src_pin, BelId dst_bel, IdString dst_pin) const override; - delay_t getDelayEpsilon() const override { return 0.01; } - delay_t getRipupDelayPenalty() const override { return 0.4; } - float getDelayNS(delay_t v) const override { return v; } - - delay_t getDelayFromNS(float ns) const override { return ns; } - - uint32_t getDelayChecksum(delay_t v) const override { return 0; } - - BoundingBox getRouteBoundingBox(WireId src, WireId dst) const override; - - bool pack() override; - bool place() override; - bool route() override; - - bool getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort, DelayQuad &delay) const override; - // Get the port class, also setting clockInfoCount to the number of TimingClockingInfos associated with a port - TimingPortClass getPortTimingClass(const CellInfo *cell, IdString port, int &clockInfoCount) const override; - // Get the TimingClockingInfo of a port - TimingClockingInfo getPortClockingInfo(const CellInfo *cell, IdString port, int index) const override; - - bool isBelLocationValid(BelId bel, bool explain_invalid = false) const override; - - static const std::string defaultPlacer; - static const std::vector availablePlacers; - static const std::string defaultRouter; - static const std::vector availableRouters; - - // --------------------------------------------------------------- - // Internal usage - void assignArchInfo() override; - bool cellsCompatible(const CellInfo **cells, int count) const; - bool haveBelType(int x, int y, IdString bel_type); - bool allocate_longwire(NetInfo *ni, int lw_idx = -1); - void fix_longwire_bels(); - void pre_pack(Context *ctx); - void post_pack(Context *ctx); - void pre_route(Context *ctx); - void post_route(Context *ctx); - void auto_longwires(); - void add_pllvr_ports(DatabasePOD const *db, BelsPOD const *bel, IdString belname, int row, int col); - void add_rpll_ports(DatabasePOD const *db, BelsPOD const *bel, IdString belname, int row, int col); - void fix_pll_nets(Context *ctx); - bool is_GCLKT_iob(const CellInfo *cell); - void bind_pll_to_bel(CellInfo *ci, PLL loc); - - void mark_used_hclk(Context *ctx); - IdString apply_local_aliases(int row, int col, const DatabasePOD *db, IdString &wire); - - WireId get_make_port_wire(const DatabasePOD *db, const BelsPOD *bel, int row, int col, IdString port); - - GowinGlobalRouter globals_router; - void mark_gowin_globals(Context *ctx); - void route_gowin_globals(Context *ctx); - - // chip db version - unsigned int const chipdb_version = 2; - - std::vector cell_types; - - // clock spines cache - // spine_id : [wire_id, wire_id, ...] - dict> clockSpinesCache; - void updateClockSpinesCache(IdString spine_id, IdString wire_id); - void fixClockSpineDecals(void); - - // XXX GW1N-9C DDR quirk - bool ddr_has_extra_inputs = false; - // XXX GW1NR-9 iobuf quirk - bool gw1n9_quirk = false; - - // 8 Long wires - uint8_t avail_longwires = 0xff; - - // Permissible combinations of modes in a single slice - std::map dff_comp_mode; - - // max global clock wires - int max_clock; -}; - -// Bels Z range -namespace BelZ { -enum -{ - ioba_z = 0, // IOBA - iobb_z = 1, // IOBB - mux_0_z = 10, // start Z for the MUX2LUT5 bels - lutram_0_z = 30, // start Z for the LUTRAM bels - vcc_0_z = 277, // virtual VCC bel Z - gnd_0_z = 278, // virtual VSS bel Z - osc_z = 280, // Z for the oscillator bels - bufs_0_z = 281, // Z for long wire buffer bel - pll_z = 289, // PLL - pllvr_z = 290, // PLLVR - iologic_z = 291, // IOLOGIC - oser16_z = 293, // OSER16 - ides16_z = 294, // IDES16 - free_z = 295 // Must be the last, one can use z starting from this value, adjust accordingly. -}; -} - -NEXTPNR_NAMESPACE_END - -#endif /* GOWIN_ARCH_H */ diff --git a/gowin/arch_pybindings.cc b/gowin/arch_pybindings.cc deleted file mode 100644 index 193fff81b4..0000000000 --- a/gowin/arch_pybindings.cc +++ /dev/null @@ -1,160 +0,0 @@ -/* - * nextpnr -- Next Generation Place and Route - * - * Copyright (C) 2018 Claire Xenia Wolf - * Copyright (C) 2018 gatecat - * - * 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. - * - */ - -#ifndef NO_PYTHON - -#include "arch_pybindings.h" -#include "nextpnr.h" -#include "pybindings.h" -#include "pywrappers.h" - -using namespace pybind11::literals; - -NEXTPNR_NAMESPACE_BEGIN -namespace PythonConversion { -template <> struct string_converter -{ - const IdString &from_str(Context *ctx, std::string name) { NPNR_ASSERT_FALSE("unsupported"); } - - std::string to_str(Context *ctx, const IdString &id) { return id.str(ctx); } -}; -} // namespace PythonConversion - -void arch_wrap_python(py::module &m) -{ - using namespace PythonConversion; - - auto arch_cls = py::class_(m, "Arch").def(py::init()); - - auto dxy_cls = py::class_>(m, "DecalXY_"); - readwrite_wrapper, - conv_from_str>::def_wrap(dxy_cls, "decal"); - readwrite_wrapper, pass_through>::def_wrap( - dxy_cls, "x"); - readwrite_wrapper, pass_through>::def_wrap( - dxy_cls, "y"); - - auto ctx_cls = py::class_(m, "Context") - .def("checksum", &Context::checksum) - .def("pack", &Context::pack) - .def("place", &Context::place) - .def("route", &Context::route); - - py::class_(m, "BelPin").def_readwrite("bel", &BelPin::bel).def_readwrite("pin", &BelPin::pin); - - fn_wrapper_1a, - conv_from_str>::def_wrap(ctx_cls, "getBelType"); - fn_wrapper_1a, - conv_from_str>::def_wrap(ctx_cls, "checkBelAvail"); - fn_wrapper_1a, - conv_from_str>::def_wrap(ctx_cls, "getBelChecksum"); - fn_wrapper_3a_v, - addr_and_unwrap, pass_through>::def_wrap(ctx_cls, "bindBel"); - fn_wrapper_1a_v>::def_wrap( - ctx_cls, "unbindBel"); - fn_wrapper_1a, - conv_from_str>::def_wrap(ctx_cls, "getBoundBelCell"); - fn_wrapper_1a, conv_from_str>::def_wrap(ctx_cls, "getConflictingBelCell"); - fn_wrapper_0a &>>::def_wrap(ctx_cls, "getBels"); - - fn_wrapper_2a, - conv_from_str, conv_from_str>::def_wrap(ctx_cls, "getBelPinWire"); - fn_wrapper_1a &>, conv_from_str>::def_wrap(ctx_cls, - "getWireBelPins"); - - fn_wrapper_1a, - conv_from_str>::def_wrap(ctx_cls, "getWireChecksum"); - fn_wrapper_3a_v, - addr_and_unwrap, pass_through>::def_wrap(ctx_cls, "bindWire"); - fn_wrapper_1a_v>::def_wrap( - ctx_cls, "unbindWire"); - fn_wrapper_1a, - conv_from_str>::def_wrap(ctx_cls, "checkWireAvail"); - fn_wrapper_1a, - conv_from_str>::def_wrap(ctx_cls, "getBoundWireNet"); - fn_wrapper_1a, conv_from_str>::def_wrap(ctx_cls, "getConflictingWireNet"); - - fn_wrapper_0a &>>::def_wrap(ctx_cls, "getWires"); - - fn_wrapper_0a &>>::def_wrap(ctx_cls, "getPips"); - fn_wrapper_1a, - conv_from_str>::def_wrap(ctx_cls, "getPipChecksum"); - fn_wrapper_3a_v, - addr_and_unwrap, pass_through>::def_wrap(ctx_cls, "bindPip"); - fn_wrapper_1a_v>::def_wrap( - ctx_cls, "unbindPip"); - fn_wrapper_1a, - conv_from_str>::def_wrap(ctx_cls, "checkPipAvail"); - fn_wrapper_1a, - conv_from_str>::def_wrap(ctx_cls, "getBoundPipNet"); - fn_wrapper_1a, conv_from_str>::def_wrap(ctx_cls, "getConflictingPipNet"); - - fn_wrapper_1a &>, conv_from_str>::def_wrap(ctx_cls, - "getPipsDownhill"); - fn_wrapper_1a &>, conv_from_str>::def_wrap(ctx_cls, "getPipsUphill"); - - fn_wrapper_1a, - conv_from_str>::def_wrap(ctx_cls, "getPipSrcWire"); - fn_wrapper_1a, - conv_from_str>::def_wrap(ctx_cls, "getPipDstWire"); - fn_wrapper_1a, - conv_from_str>::def_wrap(ctx_cls, "getPipDelay"); - - fn_wrapper_1a, - pass_through>::def_wrap(ctx_cls, "getDelayFromNS"); - - fn_wrapper_0a>::def_wrap( - ctx_cls, "getChipName"); - fn_wrapper_0a>::def_wrap(ctx_cls, - "archId"); - - fn_wrapper_3a, - conv_from_str, pass_through, pass_through>::def_wrap(ctx_cls, "DecalXY"); - - typedef dict> CellMap; - typedef dict> NetMap; - typedef dict HierarchyMap; - - readonly_wrapper>::def_wrap(ctx_cls, - "cells"); - readonly_wrapper>::def_wrap(ctx_cls, - "nets"); - - fn_wrapper_2a_v, - pass_through>::def_wrap(ctx_cls, "addClock"); - - WRAP_MAP_UPTR(m, CellMap, "IdCellMap"); - WRAP_MAP_UPTR(m, NetMap, "IdNetMap"); - WRAP_MAP(m, HierarchyMap, wrap_context, "HierarchyMap"); - WRAP_VECTOR(m, const std::vector, conv_to_str); -} - -NEXTPNR_NAMESPACE_END - -#endif diff --git a/gowin/arch_pybindings.h b/gowin/arch_pybindings.h deleted file mode 100644 index 9a5735408c..0000000000 --- a/gowin/arch_pybindings.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * nextpnr -- Next Generation Place and Route - * - * Copyright (C) 2018 Claire Xenia Wolf - * Copyright (C) 2018 gatecat - * - * 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. - * - */ -#ifndef ARCH_PYBINDINGS_H -#define ARCH_PYBINDINGS_H -#ifndef NO_PYTHON - -#include "nextpnr.h" -#include "pybindings.h" - -NEXTPNR_NAMESPACE_BEGIN - -NEXTPNR_NAMESPACE_END -#endif -#endif diff --git a/gowin/archdefs.h b/gowin/archdefs.h deleted file mode 100644 index c4d2ecdb53..0000000000 --- a/gowin/archdefs.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * nextpnr -- Next Generation Place and Route - * - * Copyright (C) 2018 Claire Xenia Wolf - * Copyright (C) 2020 Pepijn de Vos - * - * 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. - * - */ - -#ifndef GOWIN_ARCHDEFS_H -#define GOWIN_ARCHDEFS_H - -#include "base_clusterinfo.h" -#include "idstring.h" -#include "nextpnr_namespaces.h" - -NEXTPNR_NAMESPACE_BEGIN - -typedef float delay_t; - -#ifndef Q_MOC_RUN -enum ConstIds -{ - ID_NONE -#define X(t) , ID_##t -#include "constids.inc" -#undef X -}; - -#define X(t) static constexpr auto id_##t = IdString(ID_##t); -#include "constids.inc" -#undef X -#endif - -typedef IdString BelId; -typedef IdString WireId; -typedef IdString PipId; -typedef IdString GroupId; -typedef IdString DecalId; -typedef IdString BelBucketId; -typedef IdString ClusterId; - -struct ArchNetInfo -{ -}; - -struct NetInfo; - -struct ArchCellInfo : BaseClusterInfo -{ - // Is the flip-flop of this slice used - bool ff_used; - // The type of this flip-flop - IdString ff_type; - // Is a slice type primitive - bool is_slice; - - // Only packing rule for slice type primitives is a single clock per tile - const NetInfo *slice_clk; - const NetInfo *slice_ce; - const NetInfo *slice_lsr; -}; - -NEXTPNR_NAMESPACE_END - -#endif /* GOWIN_ARCHDEFS_H */ diff --git a/gowin/cells.cc b/gowin/cells.cc deleted file mode 100644 index c2d77e224b..0000000000 --- a/gowin/cells.cc +++ /dev/null @@ -1,290 +0,0 @@ -/* - * nextpnr -- Next Generation Place and Route - * - * Copyright (C) 2019 gatecat - * Copyright (C) 2020 Pepijn de Vos - * - * 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 "cells.h" -#include -#include "design_utils.h" -#include "log.h" -#include "util.h" - -NEXTPNR_NAMESPACE_BEGIN - -std::unique_ptr create_generic_cell(Context *ctx, IdString type, std::string name) -{ - static int auto_idx = 0; - IdString name_id = - name.empty() ? ctx->id("$nextpnr_" + type.str(ctx) + "_" + std::to_string(auto_idx++)) : ctx->id(name); - auto new_cell = std::make_unique(ctx, name_id, type); - if (type == id_SLICE) { - new_cell->params[id_INIT] = 0; - new_cell->params[id_FF_USED] = 0; - new_cell->params[id_FF_TYPE] = id_DFF.str(ctx); - - IdString names[4] = {id_A, id_B, id_C, id_D}; - for (int i = 0; i < 4; i++) { - new_cell->addInput(names[i]); - } - - new_cell->addInput(id_CLK); - - new_cell->addOutput(id_F); - new_cell->addOutput(id_Q); - new_cell->addInput(id_CE); - new_cell->addInput(id_LSR); - } else if (type == id_RAMW) { - IdString names[8] = {id_A4, id_B4, id_C4, id_D4, id_A5, id_B5, id_C5, id_D5}; - for (int i = 0; i < 8; i++) { - new_cell->addInput(names[i]); - } - new_cell->addInput(id_CLK); - new_cell->addInput(id_CE); - new_cell->addInput(id_LSR); - } else if (type.in(id_MUX2_LUT5, id_MUX2_LUT6, id_MUX2_LUT7, id_MUX2_LUT7, id_MUX2_LUT8)) { - new_cell->addInput(id_I0); - new_cell->addInput(id_I1); - new_cell->addInput(id_SEL); - new_cell->addOutput(id_OF); - } else if (type.in(id_IOB, id_IOBS)) { - new_cell->params[id_INPUT_USED] = 0; - new_cell->params[id_OUTPUT_USED] = 0; - new_cell->params[id_ENABLE_USED] = 0; - - new_cell->addInout(id_PAD); - new_cell->addInput(id_I); - new_cell->addInput(id_OEN); - new_cell->addOutput(id_O); - } else if (type == id_GSR) { - new_cell->addInput(id_GSRI); - } else if (type == id_GND) { - new_cell->addOutput(id_G); - } else if (type == id_VCC) { - new_cell->addOutput(id_V); - } else if (type == id_BUFS) { - new_cell->addInput(id_I); - new_cell->addOutput(id_O); - } else if (type == id_rPLL) { - for (IdString iid : - {id_CLKIN, id_CLKFB, id_FBDSEL0, id_FBDSEL1, id_FBDSEL2, id_FBDSEL3, id_FBDSEL4, id_FBDSEL5, id_IDSEL0, - id_IDSEL1, id_IDSEL2, id_IDSEL3, id_IDSEL4, id_IDSEL5, id_ODSEL0, id_ODSEL1, id_ODSEL2, id_ODSEL3, - id_ODSEL4, id_ODSEL5, id_PSDA0, id_PSDA1, id_PSDA2, id_PSDA3, id_DUTYDA0, id_DUTYDA1, id_DUTYDA2, - id_DUTYDA3, id_FDLY0, id_FDLY1, id_FDLY2, id_FDLY3, id_RESET, id_RESET_P}) { - new_cell->addInput(iid); - } - new_cell->addOutput(id_CLKOUT); - new_cell->addOutput(id_CLKOUTP); - new_cell->addOutput(id_CLKOUTD); - new_cell->addOutput(id_CLKOUTD3); - new_cell->addOutput(id_LOCK); - } else if (type == id_PLLVR) { - for (IdString iid : - {id_CLKIN, id_CLKFB, id_FBDSEL0, id_FBDSEL1, id_FBDSEL2, id_FBDSEL3, id_FBDSEL4, id_FBDSEL5, id_IDSEL0, - id_IDSEL1, id_IDSEL2, id_IDSEL3, id_IDSEL4, id_IDSEL5, id_ODSEL0, id_ODSEL1, id_ODSEL2, id_ODSEL3, - id_ODSEL4, id_ODSEL5, id_PSDA0, id_PSDA1, id_PSDA2, id_PSDA3, id_DUTYDA0, id_DUTYDA1, id_DUTYDA2, - id_DUTYDA3, id_FDLY0, id_FDLY1, id_FDLY2, id_FDLY3, id_RESET, id_RESET_P, id_VREN}) { - new_cell->addInput(iid); - } - new_cell->addOutput(id_CLKOUT); - new_cell->addOutput(id_CLKOUTP); - new_cell->addOutput(id_CLKOUTD); - new_cell->addOutput(id_CLKOUTD3); - new_cell->addOutput(id_LOCK); - } else if (type == id_IOLOGIC) { - new_cell->addInput(id_FCLK); - new_cell->addInput(id_PCLK); - new_cell->addInput(id_RESET); - } else if (type == id_DUMMY_CELL) { - } else { - log_error("unable to create generic cell of type %s\n", type.c_str(ctx)); - } - return new_cell; -} - -void lut_to_lc(const Context *ctx, CellInfo *lut, CellInfo *lc, bool no_dff) -{ - lc->params[id_INIT] = lut->params[id_INIT]; - lc->cluster = lut->cluster; - lc->constr_x = lut->constr_x; - lc->constr_y = lut->constr_y; - lc->constr_z = lut->constr_z; - - // add itself to the cluster root children list - if (lc->cluster != ClusterId()) { - CellInfo *cluster_root = ctx->cells.at(lc->cluster).get(); - lc->constr_x += cluster_root->constr_x; - lc->constr_y += cluster_root->constr_y; - lc->constr_z += cluster_root->constr_z; - if (cluster_root->cluster != cluster_root->name) { - lc->cluster = cluster_root->cluster; - cluster_root = ctx->cells.at(cluster_root->cluster).get(); - } - cluster_root->constr_children.push_back(lc); - } - - IdString sim_names[4] = {id_I0, id_I1, id_I2, id_I3}; - IdString wire_names[4] = {id_A, id_B, id_C, id_D}; - for (int i = 0; i < 4; i++) { - lut->movePortTo(sim_names[i], lc, wire_names[i]); - } - - if (no_dff) { - lc->params[id_FF_USED] = 0; - lut->movePortTo(id_F, lc, id_F); - } -} - -void dff_to_lc(const Context *ctx, CellInfo *dff, CellInfo *lc, bool pass_thru_lut) -{ - lc->params[id_FF_USED] = 1; - lc->params[id_FF_TYPE] = dff->type.str(ctx); - dff->movePortTo(id_CLK, lc, id_CLK); - dff->movePortTo(id_CE, lc, id_CE); - dff->movePortTo(id_SET, lc, id_LSR); - dff->movePortTo(id_RESET, lc, id_LSR); - dff->movePortTo(id_CLEAR, lc, id_LSR); - dff->movePortTo(id_PRESET, lc, id_LSR); - if (pass_thru_lut) { - // Fill LUT with alternating 10 - const int init_size = 1 << 4; - std::string init; - init.reserve(init_size); - for (int i = 0; i < init_size; i += 2) - init.append("10"); - lc->params[id_INIT] = Property::from_string(init); - - dff->movePortTo(id_D, lc, id_A); - } - - dff->movePortTo(id_Q, lc, id_Q); -} - -void gwio_to_iob(Context *ctx, CellInfo *nxio, CellInfo *iob, pool &todelete_cells) -{ - if (nxio->type == id_IBUF) { - if (iob->type == id_IOBS) { - // VCC -> OEN - iob->connectPort(id_OEN, ctx->nets[ctx->id("$PACKER_VCC_NET")].get()); - } - iob->params[id_INPUT_USED] = 1; - nxio->movePortTo(id_O, iob, id_O); - } else if (nxio->type == id_OBUF) { - if (iob->type == id_IOBS) { - // VSS -> OEN - iob->connectPort(id_OEN, ctx->nets[ctx->id("$PACKER_GND_NET")].get()); - } - iob->params[id_OUTPUT_USED] = 1; - nxio->movePortTo(id_I, iob, id_I); - } else if (nxio->type == id_TBUF) { - iob->params[id_ENABLE_USED] = 1; - iob->params[id_OUTPUT_USED] = 1; - nxio->movePortTo(id_I, iob, id_I); - nxio->movePortTo(id_OEN, iob, id_OEN); - } else if (nxio->type == id_IOBUF) { - iob->params[id_ENABLE_USED] = 1; - iob->params[id_INPUT_USED] = 1; - iob->params[id_OUTPUT_USED] = 1; - nxio->movePortTo(id_I, iob, id_I); - nxio->movePortTo(id_O, iob, id_O); - nxio->movePortTo(id_OEN, iob, id_OEN); - } else { - NPNR_ASSERT(false); - } -} - -void reconnect_pllvr(Context *ctx, CellInfo *pll, CellInfo *new_pll) -{ - pll->movePortTo(id_CLKIN, new_pll, id_CLKIN); - pll->movePortTo(id_VREN, new_pll, id_VREN); - pll->movePortTo(id_CLKFB, new_pll, id_CLKFB); - pll->movePortTo(id_RESET, new_pll, id_RESET); - pll->movePortTo(id_RESET_P, new_pll, id_RESET_P); - for (int i = 0; i < 6; ++i) { - pll->movePortTo(ctx->idf("FBDSEL[%d]", i), new_pll, ctx->idf("FBDSEL%d", i)); - pll->movePortTo(ctx->idf("IDSEL[%d]", i), new_pll, ctx->idf("IDSEL%d", i)); - pll->movePortTo(ctx->idf("ODSEL[%d]", i), new_pll, ctx->idf("ODSEL%d", i)); - if (i < 4) { - pll->movePortTo(ctx->idf("PSDA[%d]", i), new_pll, ctx->idf("PSDA%d", i)); - pll->movePortTo(ctx->idf("DUTYDA[%d]", i), new_pll, ctx->idf("DUTYDA%d", i)); - pll->movePortTo(ctx->idf("FDLY[%d]", i), new_pll, ctx->idf("FDLY%d", i)); - } - } - pll->movePortTo(id_CLKOUT, new_pll, id_CLKOUT); - pll->movePortTo(id_CLKOUTP, new_pll, id_CLKOUTP); - pll->movePortTo(id_CLKOUTD, new_pll, id_CLKOUTD); - pll->movePortTo(id_CLKOUTD3, new_pll, id_CLKOUTD3); - pll->movePortTo(id_LOCK, new_pll, id_LOCK); -} - -void reconnect_rpll(Context *ctx, CellInfo *pll, CellInfo *new_pll) -{ - pll->movePortTo(id_CLKIN, new_pll, id_CLKIN); - pll->movePortTo(id_CLKFB, new_pll, id_CLKFB); - pll->movePortTo(id_RESET, new_pll, id_RESET); - pll->movePortTo(id_RESET_P, new_pll, id_RESET_P); - for (int i = 0; i < 6; ++i) { - pll->movePortTo(ctx->idf("FBDSEL[%d]", i), new_pll, ctx->idf("FBDSEL%d", i)); - pll->movePortTo(ctx->idf("IDSEL[%d]", i), new_pll, ctx->idf("IDSEL%d", i)); - pll->movePortTo(ctx->idf("ODSEL[%d]", i), new_pll, ctx->idf("ODSEL%d", i)); - if (i < 4) { - pll->movePortTo(ctx->idf("PSDA[%d]", i), new_pll, ctx->idf("PSDA%d", i)); - pll->movePortTo(ctx->idf("DUTYDA[%d]", i), new_pll, ctx->idf("DUTYDA%d", i)); - pll->movePortTo(ctx->idf("FDLY[%d]", i), new_pll, ctx->idf("FDLY%d", i)); - } - } - pll->movePortTo(id_CLKOUT, new_pll, id_CLKOUT); - pll->movePortTo(id_CLKOUTP, new_pll, id_CLKOUTP); - pll->movePortTo(id_CLKOUTD, new_pll, id_CLKOUTD); - pll->movePortTo(id_CLKOUTD3, new_pll, id_CLKOUTD3); - pll->movePortTo(id_LOCK, new_pll, id_LOCK); -} - -void sram_to_ramw_split(Context *ctx, CellInfo *ram, CellInfo *ramw) -{ - if (ramw->hierpath == IdString()) - ramw->hierpath = ramw->hierpath; - ram->movePortTo(ctx->id("WAD[0]"), ramw, id_A4); - ram->movePortTo(ctx->id("WAD[1]"), ramw, id_B4); - ram->movePortTo(ctx->id("WAD[2]"), ramw, id_C4); - ram->movePortTo(ctx->id("WAD[3]"), ramw, id_D4); - - ram->movePortTo(ctx->id("DI[0]"), ramw, id_A5); - ram->movePortTo(ctx->id("DI[1]"), ramw, id_B5); - ram->movePortTo(ctx->id("DI[2]"), ramw, id_C5); - ram->movePortTo(ctx->id("DI[3]"), ramw, id_D5); - - ram->movePortTo(ctx->id("CLK"), ramw, id_CLK); - ram->movePortTo(ctx->id("WRE"), ramw, id_LSR); -} - -void sram_to_slice(Context *ctx, CellInfo *ram, CellInfo *slice, int index) -{ - if (slice->hierpath == IdString()) - slice->hierpath = slice->hierpath; - - slice->params[id_INIT] = ram->params[ctx->idf("INIT_%d", index)]; - - ram->movePortTo(ctx->idf("DO[%d]", index), slice, id_F); - - ram->copyPortTo(ctx->id("RAD[0]"), slice, id_A); - ram->copyPortTo(ctx->id("RAD[1]"), slice, id_B); - ram->copyPortTo(ctx->id("RAD[2]"), slice, id_C); - ram->copyPortTo(ctx->id("RAD[3]"), slice, id_D); -} - -NEXTPNR_NAMESPACE_END diff --git a/gowin/cells.h b/gowin/cells.h deleted file mode 100644 index 4cabe086b6..0000000000 --- a/gowin/cells.h +++ /dev/null @@ -1,136 +0,0 @@ -/* - * nextpnr -- Next Generation Place and Route - * - * Copyright (C) 2019 gatecat - * Copyright (C) 2020 Pepijn de Vos - * - * 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 "nextpnr.h" - -#ifndef GENERIC_CELLS_H -#define GENERIC_CELLS_H - -NEXTPNR_NAMESPACE_BEGIN - -// Create a generic arch cell and return it -// Name will be automatically assigned if not specified -std::unique_ptr create_generic_cell(Context *ctx, IdString type, std::string name = ""); - -// Return true if a cell is a LUT -inline bool is_lut(const BaseCtx *ctx, const CellInfo *cell) -{ - switch (cell->type.index) { - case ID_LUT1: - case ID_LUT2: - case ID_LUT3: - case ID_LUT4: - return true; - default: - return false; - } -} - -// Return true if a cell is a wide LUT mux -inline bool is_widelut(const BaseCtx *ctx, const CellInfo *cell) -{ - switch (cell->type.index) { - case ID_MUX2_LUT5: - case ID_MUX2_LUT6: - case ID_MUX2_LUT7: - case ID_MUX2_LUT8: - return true; - default: - return false; - } -} - -inline bool is_alu(const BaseCtx *ctx, const CellInfo *cell) { return (cell->type.index == ID_ALU); } - -// is MUX2_LUT5 -inline bool is_mux2_lut5(const BaseCtx *ctx, const CellInfo *cell) { return (cell->type.index == ID_MUX2_LUT5); } - -// is MUX2_LUT6 -inline bool is_mux2_lut6(const BaseCtx *ctx, const CellInfo *cell) { return (cell->type.index == ID_MUX2_LUT6); } - -// is MUX2_LUT7 -inline bool is_mux2_lut7(const BaseCtx *ctx, const CellInfo *cell) { return (cell->type.index == ID_MUX2_LUT7); } - -// is MUX2_LUT8 -inline bool is_mux2_lut8(const BaseCtx *ctx, const CellInfo *cell) { return (cell->type.index == ID_MUX2_LUT8); } - -// Return true if a cell is a flipflop -inline bool is_ff(const BaseCtx *ctx, const CellInfo *cell) -{ - switch (cell->type.index) { - case ID_DFF: - case ID_DFFE: - case ID_DFFS: - case ID_DFFSE: - case ID_DFFR: - case ID_DFFRE: - case ID_DFFP: - case ID_DFFPE: - case ID_DFFC: - case ID_DFFCE: - case ID_DFFN: - case ID_DFFNE: - case ID_DFFNS: - case ID_DFFNSE: - case ID_DFFNR: - case ID_DFFNRE: - case ID_DFFNP: - case ID_DFFNPE: - case ID_DFFNC: - case ID_DFFNCE: - return true; - default: - return false; - } -} - -inline bool is_lc(const BaseCtx *ctx, const CellInfo *cell) { return cell->type == id_SLICE; } - -inline bool is_sram(const BaseCtx *ctx, const CellInfo *cell) { return cell->type == id_RAM16SDP4; } - -inline bool is_iob(const Context *ctx, const CellInfo *cell) { return (cell->type == id_IOB || cell->type == id_IOBS); } - -// Convert a LUT primitive to (part of) an GENERIC_SLICE, swapping ports -// as needed. Set no_dff if a DFF is not being used, so that the output -// can be reconnected -void lut_to_lc(const Context *ctx, CellInfo *lut, CellInfo *lc, bool no_dff = true); - -// Convert a DFF primitive to (part of) an GENERIC_SLICE, setting parameters -// and reconnecting signals as necessary. If pass_thru_lut is True, the LUT will -// be configured as pass through and D connected to I0, otherwise D will be -// ignored -void dff_to_lc(const Context *ctx, CellInfo *dff, CellInfo *lc, bool pass_thru_lut = false); - -// Convert a Gowin IO buffer to a IOB bel -void gwio_to_iob(Context *ctx, CellInfo *nxio, CellInfo *sbio, pool &todelete_cells); - -// Reconnect PLL signals (B) -void reconnect_pllvr(Context *ctx, CellInfo *pll, CellInfo *new_pll); -void reconnect_rpll(Context *ctx, CellInfo *pll, CellInfo *new_pll); - -// Convert RAM16 to write port -void sram_to_ramw_split(Context *ctx, CellInfo *ram, CellInfo *ramw); - -// Convert RAM16 to slice -void sram_to_slice(Context *ctx, CellInfo *ram, CellInfo *slice, int index); - -NEXTPNR_NAMESPACE_END - -#endif diff --git a/gowin/constids.inc b/gowin/constids.inc deleted file mode 100644 index 230abc09cd..0000000000 --- a/gowin/constids.inc +++ /dev/null @@ -1,1058 +0,0 @@ -X(A0) -X(B0) -X(C0) -X(D0) -X(A1) -X(B1) -X(C1) -X(D1) -X(A2) -X(B2) -X(C2) -X(D2) -X(A3) -X(B3) -X(C3) -X(D3) -X(A4) -X(B4) -X(C4) -X(D4) -X(A5) -X(B5) -X(C5) -X(D5) -X(A6) -X(B6) -X(C6) -X(D6) -X(A7) -X(B7) -X(C7) -X(D7) -X(F0) -X(F1) -X(F2) -X(F3) -X(F4) -X(F5) -X(F6) -X(F7) -X(Q0) -X(Q1) -X(Q2) -X(Q3) -X(Q4) -X(Q5) -X(Q6) -X(Q7) -X(OF0) -X(OF1) -X(OF2) -X(OF3) -X(OF4) -X(OF5) -X(OF6) -X(OF7) -X(X01) -X(X02) -X(X03) -X(X04) -X(X05) -X(X06) -X(X07) -X(X08) -X(N100) -X(SN10) -X(SN20) -X(N130) -X(S100) -X(S130) -X(E100) -X(EW10) -X(EW20) -X(E130) -X(W100) -X(W130) -X(N200) -X(N210) -X(N220) -X(N230) -X(N240) -X(N250) -X(N260) -X(N270) -X(S200) -X(S210) -X(S220) -X(S230) -X(S240) -X(S250) -X(S260) -X(S270) -X(E200) -X(E210) -X(E220) -X(E230) -X(E240) -X(E250) -X(E260) -X(E270) -X(W200) -X(W210) -X(W220) -X(W230) -X(W240) -X(W250) -X(W260) -X(W270) -X(N800) -X(N810) -X(N820) -X(N830) -X(S800) -X(S810) -X(S820) -X(S830) -X(E800) -X(E810) -X(E820) -X(E830) -X(W800) -X(W810) -X(W820) -X(W830) -X(CLK0) -X(CLK1) -X(CLK2) -X(LSR0) -X(LSR1) -X(LSR2) -X(CE0) -X(CE1) -X(CE2) -X(SEL0) -X(SEL1) -X(SEL2) -X(SEL3) -X(SEL4) -X(SEL5) -X(SEL6) -X(SEL7) -X(N101) -X(N131) -X(S101) -X(S131) -X(E101) -X(E131) -X(W101) -X(W131) -X(N201) -X(N211) -X(N221) -X(N231) -X(N241) -X(N251) -X(N261) -X(N271) -X(S201) -X(S211) -X(S221) -X(S231) -X(S241) -X(S251) -X(S261) -X(S271) -X(E201) -X(E211) -X(E221) -X(E231) -X(E241) -X(E251) -X(E261) -X(E271) -X(W201) -X(W211) -X(W221) -X(W231) -X(W241) -X(W251) -X(W261) -X(W271) -X(N202) -X(N212) -X(N222) -X(N232) -X(N242) -X(N252) -X(N262) -X(N272) -X(S202) -X(S212) -X(S222) -X(S232) -X(S242) -X(S252) -X(S262) -X(S272) -X(E202) -X(E212) -X(E222) -X(E232) -X(E242) -X(E252) -X(E262) -X(E272) -X(W202) -X(W212) -X(W222) -X(W232) -X(W242) -X(W252) -X(W262) -X(W272) -X(N804) -X(N814) -X(N824) -X(N834) -X(S804) -X(S814) -X(S824) -X(S834) -X(E804) -X(E814) -X(E824) -X(E834) -X(W804) -X(W814) -X(W824) -X(W834) -X(N808) -X(N818) -X(N828) -X(N838) -X(S808) -X(S818) -X(S828) -X(S838) -X(E808) -X(E818) -X(E828) -X(E838) -X(W808) -X(W818) -X(W828) -X(W838) -X(E110) -X(W110) -X(E120) -X(W120) -X(S110) -X(N110) -X(S120) -X(N120) -X(E111) -X(W111) -X(E121) -X(W121) -X(S111) -X(N111) -X(S121) -X(N121) -X(LB01) -X(LB11) -X(LB21) -X(LB31) -X(LB41) -X(LB51) -X(LB61) -X(LB71) -X(GB00) -X(GB10) -X(GB20) -X(GB30) -X(GB40) -X(GB50) -X(GB60) -X(GB70) -X(VCC) -X(VSS) -X(LT00) -X(LT10) -X(LT20) -X(LT30) -X(LT02) -X(LT13) -X(LT01) -X(LT04) -X(LBO0) -X(LBO1) -X(SS00) -X(SS40) -X(GT00) -X(GT10) -X(GBO0) -X(GBO1) -X(DI0) -X(DI1) -X(DI2) -X(DI3) -X(DI4) -X(DI5) -X(DI6) -X(DI7) -X(CIN0) -X(CIN1) -X(CIN2) -X(CIN3) -X(CIN4) -X(CIN5) -X(COUT0) -X(COUT1) -X(COUT2) -X(COUT3) -X(COUT4) -X(COUT5) -X(VREN) - -// wires -// SN -X(S10) -X(S10_loop0) -X(S13) -X(S13_loop0) -X(N10) -X(N10_loop0) -X(N13) -X(N13_loop0) -X(SN10_loop_n) -X(SN10_loop_s) -X(SN20_loop_n) -X(SN20_loop_s) -X(S20) -X(S20_loop0) -X(S20_loop1) -X(S21) -X(S21_loop0) -X(S21_loop1) -X(S22) -X(S22_loop0) -X(S22_loop1) -X(S23) -X(S23_loop0) -X(S23_loop1) -X(S24) -X(S24_loop0) -X(S24_loop1) -X(S25) -X(S25_loop0) -X(S25_loop1) -X(S26) -X(S26_loop0) -X(S26_loop1) -X(S27) -X(S27_loop0) -X(S27_loop1) -X(N20) -X(N20_loop0) -X(N20_loop1) -X(N21) -X(N21_loop0) -X(N21_loop1) -X(N22) -X(N22_loop0) -X(N22_loop1) -X(N23) -X(N23_loop0) -X(N23_loop1) -X(N24) -X(N24_loop0) -X(N24_loop1) -X(N25) -X(N25_loop0) -X(N25_loop1) -X(N26) -X(N26_loop0) -X(N26_loop1) -X(N27) -X(N27_loop0) -X(N27_loop1) -X(S80) -X(S80_loop0) -X(S80_loop1) -X(S80_loop2) -X(S80_loop3) -X(S80_loop4) -X(S80_loop5) -X(S80_loop6) -X(S80_loop7) -X(N80) -X(N80_loop0) -X(N80_loop1) -X(N80_loop2) -X(N80_loop3) -X(N80_loop4) -X(N80_loop5) -X(N80_loop6) -X(N80_loop7) -X(S81) -X(S81_loop0) -X(S81_loop1) -X(S81_loop2) -X(S81_loop3) -X(S81_loop4) -X(S81_loop5) -X(S81_loop6) -X(S81_loop7) -X(N81) -X(N81_loop0) -X(N81_loop1) -X(N81_loop2) -X(N81_loop3) -X(N81_loop4) -X(N81_loop5) -X(N81_loop6) -X(N81_loop7) -X(S82) -X(S82_loop0) -X(S82_loop1) -X(S82_loop2) -X(S82_loop3) -X(S82_loop4) -X(S82_loop5) -X(S82_loop6) -X(S82_loop7) -X(N82) -X(N82_loop0) -X(N82_loop1) -X(N82_loop2) -X(N82_loop3) -X(N82_loop4) -X(N82_loop5) -X(N82_loop6) -X(N82_loop7) -X(S83) -X(S83_loop0) -X(S83_loop1) -X(S83_loop2) -X(S83_loop3) -X(S83_loop4) -X(S83_loop5) -X(S83_loop6) -X(S83_loop7) -X(N83) -X(N83_loop0) -X(N83_loop1) -X(N83_loop2) -X(N83_loop3) -X(N83_loop4) -X(N83_loop5) -X(N83_loop6) -X(N83_loop7) - -// WE -X(E10) -X(E10_loop0) -X(E13) -X(E13_loop0) -X(W10) -X(W10_loop0) -X(W13) -X(W13_loop0) -X(EW10_loop_w) -X(EW10_loop_e) -X(EW20_loop_w) -X(EW20_loop_e) -// -X(E20) -X(E20_loop0) -X(E20_loop1) -X(E21) -X(E21_loop0) -X(E21_loop1) -X(E22) -X(E22_loop0) -X(E22_loop1) -X(E23) -X(E23_loop0) -X(E23_loop1) -X(E24) -X(E24_loop0) -X(E24_loop1) -X(E25) -X(E25_loop0) -X(E25_loop1) -X(E26) -X(E26_loop0) -X(E26_loop1) -X(E27) -X(E27_loop0) -X(E27_loop1) -X(W20) -X(W20_loop0) -X(W20_loop1) -X(W21) -X(W21_loop0) -X(W21_loop1) -X(W22) -X(W22_loop0) -X(W22_loop1) -X(W23) -X(W23_loop0) -X(W23_loop1) -X(W24) -X(W24_loop0) -X(W24_loop1) -X(W25) -X(W25_loop0) -X(W25_loop1) -X(W26) -X(W26_loop0) -X(W26_loop1) -X(W27) -X(W27_loop0) -X(W27_loop1) -// -X(E80) -X(E80_loop0) -X(E80_loop1) -X(E80_loop2) -X(E80_loop3) -X(E80_loop4) -X(E80_loop5) -X(E80_loop6) -X(E80_loop7) -X(W80) -X(W80_loop0) -X(W80_loop1) -X(W80_loop2) -X(W80_loop3) -X(W80_loop4) -X(W80_loop5) -X(W80_loop6) -X(W80_loop7) -X(E81) -X(E81_loop0) -X(E81_loop1) -X(E81_loop2) -X(E81_loop3) -X(E81_loop4) -X(E81_loop5) -X(E81_loop6) -X(E81_loop7) -X(W81) -X(W81_loop0) -X(W81_loop1) -X(W81_loop2) -X(W81_loop3) -X(W81_loop4) -X(W81_loop5) -X(W81_loop6) -X(W81_loop7) -X(E82) -X(E82_loop0) -X(E82_loop1) -X(E82_loop2) -X(E82_loop3) -X(E82_loop4) -X(E82_loop5) -X(E82_loop6) -X(E82_loop7) -X(W82) -X(W82_loop0) -X(W82_loop1) -X(W82_loop2) -X(W82_loop3) -X(W82_loop4) -X(W82_loop5) -X(W82_loop6) -X(W82_loop7) -X(E83) -X(E83_loop0) -X(E83_loop1) -X(E83_loop2) -X(E83_loop3) -X(E83_loop4) -X(E83_loop5) -X(E83_loop6) -X(E83_loop7) -X(W83) -X(W83_loop0) -X(W83_loop1) -X(W83_loop2) -X(W83_loop3) -X(W83_loop4) -X(W83_loop5) -X(W83_loop6) -X(W83_loop7) - -// spines -X(SPINE0) -X(SPINE1) -X(SPINE2) -X(SPINE3) -X(SPINE4) -X(SPINE5) -X(SPINE6) -X(SPINE7) -X(SPINE8) -X(SPINE9) -X(SPINE10) -X(SPINE11) -X(SPINE12) -X(SPINE13) -X(SPINE14) -X(SPINE15) -X(SPINE16) -X(SPINE17) -X(SPINE18) -X(SPINE19) -X(SPINE20) -X(SPINE21) -X(SPINE22) -X(SPINE23) -X(SPINE24) -X(SPINE25) -X(SPINE26) -X(SPINE27) -X(SPINE28) -X(SPINE29) -X(SPINE30) -X(SPINE31) - -// slice items -X(SLICE) -X(CLK) -X(LSR) -X(CE) -X(Q) -X(F) -X(A) -X(B) -X(C) -X(D) -// iob items -X(IOB) -X(I) -X(O) -X(IO) -X(OE) -X(OB) -X(IB) - -// bels -X(DFF0) -X(DFF1) -X(DFF2) -X(DFF3) -X(DFF4) -X(DFF5) - -X(LUT0) -X(LUT1) -X(LUT2) -X(LUT3) -X(LUT4) -X(LUT5) -X(LUT6) -X(LUT7) - -X(IOBA) -X(IOBB) -X(IOBC) -X(IOBD) -X(IOBE) -X(IOBF) -X(IOBG) -X(IOBH) -X(IOBI) -X(IOBJ) - -// misc -X(DUMMY_CELL) - -// simplified iobs -X(IOBS) -X(IOBAS) -X(IOBBS) -X(IOBCS) -X(IOBDS) -X(IOBES) -X(IOBFS) -X(IOBGS) -X(IOBHS) -X(IOBIS) -X(IOBJS) - -// long wires -X(BUFS) -X(BUFS0) -X(BUFS1) -X(BUFS2) -X(BUFS3) -X(BUFS4) -X(BUFS5) -X(BUFS6) -X(BUFS7) -X(LWT0) -X(LWB0) -X(LWT1) -X(LWB1) -X(LWT2) -X(LWB2) -X(LWT3) -X(LWB3) -X(LWT4) -X(LWB4) -X(LWT5) -X(LWB5) -X(LWT6) -X(LWB6) -X(LWT7) -X(LWB7) -X(LWSPINETL0) -X(LWSPINETL1) -X(LWSPINETL2) -X(LWSPINETL3) -X(LWSPINETL4) -X(LWSPINETL5) -X(LWSPINETL6) -X(LWSPINETL7) -X(LWSPINETR0) -X(LWSPINETR1) -X(LWSPINETR2) -X(LWSPINETR3) -X(LWSPINETR4) -X(LWSPINETR5) -X(LWSPINETR6) -X(LWSPINETR7) -X(LWSPINEBL0) -X(LWSPINEBL1) -X(LWSPINEBL2) -X(LWSPINEBL3) -X(LWSPINEBL4) -X(LWSPINEBL5) -X(LWSPINEBL6) -X(LWSPINEBL7) -X(LWSPINEBR0) -X(LWSPINEBR1) -X(LWSPINEBR2) -X(LWSPINEBR3) -X(LWSPINEBR4) -X(LWSPINEBR5) -X(LWSPINEBR6) -X(LWSPINEBR7) -X(LWI0) -X(LWI1) -X(LWI2) -X(LWI3) -X(LWI4) -X(LWI5) -X(LWI6) -X(LWI7) -X(LWO0) -X(LWO1) -X(LWO2) -X(LWO3) -X(LWO4) -X(LWO5) -X(LWO6) -X(LWO7) - -// IOLOGIC -X(TX) -X(TX0) -X(TX1) -X(TX2) -X(TX3) -X(FCLK) -X(PCLK) -X(CALIB) -X(DAADJ0) -X(DAADJ1) -X(GW9_ALWAYS_LOW0) -X(GW9_ALWAYS_LOW1) -X(GW9C_ALWAYS_LOW0) -X(GW9C_ALWAYS_LOW1) -X(OBUF_TYPE) -X(IBUF_TYPE) -X(SBUF) -X(DBUF) -X(ODDR) -X(IDDR) -X(ODDRC) -X(IDDRC) -X(ODDRA) -X(ODDRB) -X(ODDRCA) -X(ODDRCB) -X(OSER4) -X(OSER8) -X(OSER10) -X(OVIDEO) -X(OSER16) -X(IDES4) -X(IDES8) -X(IDES10) -X(IVIDEO) -X(IDES16) -X(IOLOGIC) -X(IOLOGICA) -X(IOLOGICB) -X(IOLOGIC_TYPE) -X(IOLOGIC_FCLK) -X(IOLOGIC_MASTER_CELL) -X(IOLOGIC_AUX_CELL) -X(D8) -X(D9) -X(D10) -X(D11) -X(D12) -X(D13) -X(D14) -X(D15) -X(Q8) -X(Q9) -X(Q10) -X(Q11) -X(Q12) -X(Q13) -X(Q14) -X(Q15) - -// Wide LUTs -X(MUX2_LUT5) -X(MUX2_LUT6) -X(MUX2_LUT7) -X(MUX2_LUT8) -X(I0MUX0) -X(I1MUX0) -X(I0MUX1) -X(I1MUX1) -X(I0MUX2) -X(I1MUX2) -X(I0MUX3) -X(I1MUX3) -X(I0MUX4) -X(I1MUX4) -X(I0MUX5) -X(I1MUX5) -X(I0MUX6) -X(I1MUX6) -X(I0MUX7) -X(I1MUX7) - -// ALU -X(ALU) -X(GND) -X(ALU_MODE) - -// DFF types -X(DFF) -X(DFFE) -X(DFFS) -X(DFFSE) -X(DFFR) -X(DFFRE) -X(DFFP) -X(DFFPE) -X(DFFC) -X(DFFCE) -X(DFFN) -X(DFFNE) -X(DFFNS) -X(DFFNSE) -X(DFFNR) -X(DFFNRE) -X(DFFNP) -X(DFFNPE) -X(DFFNC) -X(DFFNCE) - -// Shadow RAM -X(RAM16) -X(RAMW) -X(RAM16SDP4) -X(WADA) -X(WADB) -X(WADC) -X(WADD) -X(DIA) -X(DIB) -X(DIC) -X(DID) -X(WRE) - -// IOB types -X(IBUF) -X(OBUF) -X(IOBUF) -X(TBUF) -X(TLVDS_OBUF) -X(TLVDS_TBUF) -X(TLVDS_IBUF) -X(TLVDS_IOBUF) -X(ELVDS_OBUF) -X(ELVDS_TBUF) -X(ELVDS_IBUF) -X(ELVDS_IOBUF) - -// global set/reset -X(GSR) -X(GSR0) -X(GSRI) - -// Oscillators -X(OSC) -X(OSCZ) -X(OSCH) -X(OSCF) -X(OSCW) -X(OSCO) - -// PLLs -X(rPLL) -X(RPLLA) -X(PLLVR) - -// primitive attributes -X(INIT) -X(FF_USED) -X(FF_TYPE) -X(INPUT_USED) -X(OUTPUT_USED) -X(ENABLE_USED) -X(BEL) -X(DIFF) -X(DIFF_TYPE) -X(DEVICE) -X(IOLOGIC_IOB) - -// ports -X(EN) -X(E) -X(Y) -X(PAD) -X(RESET) -X(SET) -X(PRESET) -X(CLEAR) -X(I0) -X(I1) -X(I2) -X(I3) -X(OEN) -X(S0) -X(SEL) -X(SUM) -X(CIN) -X(COUT) -X(OF) -X(V) -X(G) -X(OSCOUT) -X(OSCEN) -X(RESET_P) -X(CLKFB) -X(FBDSEL0) -X(FBDSEL1) -X(FBDSEL2) -X(FBDSEL3) -X(FBDSEL4) -X(FBDSEL5) -X(IDSEL0) -X(IDSEL1) -X(IDSEL2) -X(IDSEL3) -X(IDSEL4) -X(IDSEL5) -X(ODSEL0) -X(ODSEL1) -X(ODSEL2) -X(ODSEL3) -X(ODSEL4) -X(ODSEL5) -X(PSDA0) -X(PSDA1) -X(PSDA2) -X(PSDA3) -X(DUTYDA0) -X(DUTYDA1) -X(DUTYDA2) -X(DUTYDA3) -X(FDLY0) -X(FDLY1) -X(FDLY2) -X(FDLY3) -X(CLKIN) -X(CLKOUT) -X(CLKOUTP) -X(CLKOUTD) -X(CLKOUTD3) -X(LOCK) - -// PLL parameters -X(CLKOUTPS) -X(CLKOUTDIV) -X(CLKOUTDIV3) -X(PWDEN) -X(RSTEN) -X(FLOCK) -X(INSEL) -X(FBSEL) -X(CLKFB_SEL) - -// timing -X(X0) -X(FX1) -X(X2) -X(X8) -X(PIO_CENT_PCLK) -X(CENT_SPINE_PCLK) -X(SPINE_TAP_PCLK) -X(TAP_BRANCH_PCLK) -X(BRANCH_PCLK) -X(CENT_SPINE_SCLK) -X(SPINE_TAP_SCLK_0) -X(SPINE_TAP_SCLK_1) -X(TAP_BRANCH_SCLK) -X(BRANCH_SCLK) -X(clksetpos) -X(clkholdpos) -X(clk_qpos) -X(a_f) -X(b_f) -X(c_f) -X(d_f) -X(fx_ofx1) -X(I01) - -// GUI -X(DECAL_LUT_ACTIVE) -X(DECAL_LUT_INACTIVE) -X(DECAL_LUTDFF_ACTIVE) -X(DECAL_LUTDFF_INACTIVE) -X(DECAL_LUT_UNUSED_DFF_ACTIVE) -X(DECAL_GRP_LUT) -X(DECAL_CRU) -X(DECAL_MUXUPPER_INACTIVE) -X(DECAL_MUXUPPER_ACTIVE) -X(DECAL_MUXLOWER_INACTIVE) -X(DECAL_MUXLOWER_ACTIVE) -X(DECAL_IOB_INACTIVE) -X(DECAL_IOB_ACTIVE) -X(DECAL_IOBS_INACTIVE) -X(DECAL_IOBS_ACTIVE) -X(DECAL_ALU_ACTIVE) - - - - -X(SINGLE_INPUT_MUX) -X(cst) -X(none) -X(pack) -X(place) -X(placer) -X(route) -X(router) diff --git a/gowin/cst.cc b/gowin/cst.cc deleted file mode 100644 index 7ed74c6c7f..0000000000 --- a/gowin/cst.cc +++ /dev/null @@ -1,40 +0,0 @@ -/* - * nextpnr -- Next Generation Place and Route - * - * Copyright (C) 2018 Claire Xenia Wolf - * Copyright (C) 2018 gatecat - * - * 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 "cst.h" -#include -#include -#include "arch.h" -#include "log.h" -#include "util.h" - -NEXTPNR_NAMESPACE_BEGIN - -bool read_cst(Context *ctx, std::istream &in) -{ - try { - ctx->read_cst(in); - return true; - } catch (log_execution_error_exception) { - return false; - } -} - -NEXTPNR_NAMESPACE_END diff --git a/gowin/cst.h b/gowin/cst.h deleted file mode 100644 index 3fcfd66385..0000000000 --- a/gowin/cst.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * nextpnr -- Next Generation Place and Route - * - * Copyright (C) 2018 Claire Xenia Wolf - * Copyright (C) 2018 gatecat - * - * 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. - * - */ - -#ifndef CST_H -#define CST_H - -#include -#include "nextpnr.h" - -NEXTPNR_NAMESPACE_BEGIN - -// Read the constraints file -bool read_cst(Context *ctx, std::istream &in); - -NEXTPNR_NAMESPACE_END - -#endif diff --git a/gowin/family.cmake b/gowin/family.cmake deleted file mode 100644 index be607e6a6a..0000000000 --- a/gowin/family.cmake +++ /dev/null @@ -1,53 +0,0 @@ -add_subdirectory(${family}) -message(STATUS "Using Gowin chipdb: ${GOWIN_CHIPDB}") - -set(chipdb_sources) -set(chipdb_binaries) -file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${family}/chipdb) -foreach(device ${GOWIN_DEVICES}) - set(chipdb_bba ${GOWIN_CHIPDB}/chipdb-${device}.bba) - set(chipdb_bin ${family}/chipdb/chipdb-${device}.bin) - set(chipdb_cc ${family}/chipdb/chipdb-${device}.cc) - if(BBASM_MODE STREQUAL "binary") - add_custom_command( - OUTPUT ${chipdb_bin} - COMMAND bbasm ${BBASM_ENDIAN_FLAG} ${chipdb_bba} ${chipdb_bin} - DEPENDS bbasm chipdb-${family}-bbas ${chipdb_bba}) - list(APPEND chipdb_binaries ${chipdb_bin}) - elseif(BBASM_MODE STREQUAL "embed") - add_custom_command( - OUTPUT ${chipdb_cc} ${chipdb_bin} - COMMAND bbasm ${BBASM_ENDIAN_FLAG} --e ${chipdb_bba} ${chipdb_cc} ${chipdb_bin} - DEPENDS bbasm chipdb-${family}-bbas ${chipdb_bba}) - list(APPEND chipdb_sources ${chipdb_cc}) - list(APPEND chipdb_binaries ${chipdb_bin}) - elseif(BBASM_MODE STREQUAL "string") - add_custom_command( - OUTPUT ${chipdb_cc} - COMMAND bbasm ${BBASM_ENDIAN_FLAG} --c ${chipdb_bba} ${chipdb_cc} - DEPENDS bbasm chipdb-${family}-bbas ${chipdb_bba}) - list(APPEND chipdb_sources ${chipdb_cc}) - endif() -endforeach() -if(WIN32) - set(chipdb_rc ${CMAKE_CURRENT_BINARY_DIR}/${family}/resource/chipdb.rc) - list(APPEND chipdb_sources ${chipdb_rc}) - - file(WRITE ${chipdb_rc}) - foreach(device ${GOWIN_DEVICES}) - file(APPEND ${chipdb_rc} - "${family}/chipdb-${device}.bin RCDATA \"${CMAKE_CURRENT_BINARY_DIR}/${family}/chipdb/chipdb-${device}.bin\"") - endforeach() -endif() - -add_custom_target(chipdb-${family}-bins DEPENDS ${chipdb_sources} ${chipdb_binaries}) - -add_library(chipdb-${family} OBJECT ${GOWIN_CHIPDB} ${chipdb_sources}) -add_dependencies(chipdb-${family} chipdb-${family}-bins) -target_compile_options(chipdb-${family} PRIVATE -g0 -O0 -w) -target_compile_definitions(chipdb-${family} PRIVATE NEXTPNR_NAMESPACE=nextpnr_${family}) -target_include_directories(chipdb-${family} PRIVATE ${family}) - -foreach(family_target ${family_targets}) - target_sources(${family_target} PRIVATE $) -endforeach() diff --git a/gowin/gfx.cc b/gowin/gfx.cc deleted file mode 100644 index a06df6f8f3..0000000000 --- a/gowin/gfx.cc +++ /dev/null @@ -1,5830 +0,0 @@ -/* - * nextpnr -- Next Generation Place and Route - * - * Copyright (C) 2018 Claire Xenia 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 -#include - -#include "gfx.h" - -NEXTPNR_NAMESPACE_BEGIN - -#ifndef NO_GUI -// LUTs -const float lut_w = 0.6732 - 0.6386; -const float lut_h = 0.9392 - 0.9074; -const float lut_x = 0.6386; -const float lut_y[] = {1. - 0.9392, 1. - 0.8870, 1. - 0.7864, 1. - 0.7321, - 1. - 0.6399, 1. - 0.5847, 1. - 0.5068, 1. - 0.4503}; -const float dff_w = 0.0580; -const float dff_x = 0.6821; -const float grp_lut_w = 0.1399; -const float grp_lut_h = 0.0954; -const float grp_lut_x = 0.6284; -const float grp_lut_y[] = {1. - 0.9440, 1. - 0.7915, 1. - 0.6442, 1. - 0.5101}; - -// mux -const float mux_w = 0.8134 - 0.7899; -const float mux_f = 0.9450 - 0.9358; -const float mux_h = grp_lut_h; - -const float mux2lut5_x = 0.7900; -const float mux2lut5_y[] = {grp_lut_y[0], grp_lut_y[1], grp_lut_y[2], grp_lut_y[3]}; -const float mux2lut6_x = 0.8378; -const float mux2lut6_y[] = {1. - 0.9261, 1. - 0.6205}; -const float mux2lut7_x = 0.8859; -const float mux2lut7_y = 1. - 0.7870; -const float mux2lut8_x = 0.9337; -const float mux2lut8_y = 1. - 0.8098; - -// pip -enum CruSide -{ - Top, - Bottom, - Left, - Right, - Center -}; -const float cru_x = 0.2568; -const float cru_y = 1. - 0.9783; -const float cru_w = 0.6010 - cru_x; -const float cru_h = 1. - cru_y - 0.3742; - -const float lut_A_off = 1. - 0.9107 - lut_y[0]; -const float lut_D_off = lut_h - lut_A_off; -const float lut_B_off = lut_A_off - (lut_h - lut_D_off) / 3.; -const float lut_C_off = lut_D_off + (lut_h - lut_D_off) / 3.; - -const float right_wire_dist = (grp_lut_y[1] - grp_lut_y[0] - grp_lut_h) / 11.; -const float left_wire_dist = cru_h / 100.; -const float top_wire_dist = cru_w / 100.; -const float clk_ce_set_vdist = (lut_y[1] - lut_y[0] - lut_h) / 4.; - -const float sn_dist = cru_x / 125.; -const float ew_dist = (1. - cru_y - cru_h) / 130.; -const float wrap_len = 0.02f; -const float spine_pip_off = 0.11f; - -const float io_x = cru_x + cru_w + 0.1; -const float io_w = (1. - io_x) / 3.; -const float io_gap = 0.03; -const float io_h = (cru_h - 4. * io_gap) / 2.; -const float io_y = cru_y + io_gap; - -const float ios_scl = 0.5; -const float ios_h = ios_scl * io_h; -const float ios_w = ios_scl * io_w; -const float ios_gap_y = io_gap; -const float ios_gap_x = io_gap * 1.4; -const float ios_x = io_x; -const float ios_y = ios_scl * io_y; - -const dict portPoint = { - {id_O, 3. * io_h / 4.}, - {id_I, 2. * io_h / 4.}, - {id_OEN, 1. * io_h / 4.}, -}; - -const dict>> portSign = { - {id_O, - {{io_h / 14. * 1.33, portPoint.at(id_O) + io_h / 14., io_h / 14. * 1.66, portPoint.at(id_O) + io_h / 14.}, - {io_h / 14. * 1.66, portPoint.at(id_O) + io_h / 14., io_h / 14. * 2., portPoint.at(id_O) + io_h / 14. * 0.6}, - {io_h / 14. * 2., portPoint.at(id_O) + io_h / 14. * 0.6, io_h / 14. * 2., - portPoint.at(id_O) - io_h / 14. * 0.6}, - {io_h / 14. * 2., portPoint.at(id_O) - io_h / 14. * 0.6, io_h / 14. * 1.66, portPoint.at(id_O) - io_h / 14.}, - {io_h / 14. * 1.66, portPoint.at(id_O) - io_h / 14., io_h / 14. * 1.33, portPoint.at(id_O) - io_h / 14.}, - {io_h / 14. * 1.33, portPoint.at(id_O) - io_h / 14., io_h / 14. * 1., portPoint.at(id_O) - io_h / 14. * 0.6}, - {io_h / 14. * 1., portPoint.at(id_O) - io_h / 14. * 0.6, io_h / 14. * 1., - portPoint.at(id_O) + io_h / 14. * 0.6}, - {io_h / 14. * 1., portPoint.at(id_O) + io_h / 14. * 0.6, io_h / 14. * 1.33, - portPoint.at(id_O) + io_h / 14.}}}, - {id_I, - {{io_h / 14., portPoint.at(id_I) + io_h / 14., 2. * io_h / 14., portPoint.at(id_I) + io_h / 14.}, - {io_h / 14. * 1.5, portPoint.at(id_I) + io_h / 14., 1. * io_h / 14. * 1.5, portPoint.at(id_I) - io_h / 14.}, - {io_h / 14., portPoint.at(id_I) - io_h / 14., 2. * io_h / 14., portPoint.at(id_I) - io_h / 14.}}}, - {id_OEN, - {{io_h / 14. * 1.33, portPoint.at(id_OEN) + io_h / 14., io_h / 14. * 1.66, portPoint.at(id_OEN) + io_h / 14.}, - {io_h / 14. * 1.66, portPoint.at(id_OEN) + io_h / 14., io_h / 14. * 2., - portPoint.at(id_OEN) + io_h / 14. * 0.6}, - {io_h / 14. * 2., portPoint.at(id_OEN) + io_h / 14. * 0.6, io_h / 14. * 2., - portPoint.at(id_OEN) - io_h / 14. * 0.6}, - {io_h / 14. * 2., portPoint.at(id_OEN) - io_h / 14. * 0.6, io_h / 14. * 1.66, - portPoint.at(id_OEN) - io_h / 14.}, - {io_h / 14. * 1.66, portPoint.at(id_OEN) - io_h / 14., io_h / 14. * 1.33, portPoint.at(id_OEN) - io_h / 14.}, - {io_h / 14. * 1.33, portPoint.at(id_OEN) - io_h / 14., io_h / 14. * 1., - portPoint.at(id_OEN) - io_h / 14. * 0.6}, - {io_h / 14. * 1., portPoint.at(id_OEN) - io_h / 14. * 0.6, io_h / 14. * 1., - portPoint.at(id_OEN) + io_h / 14. * 0.6}, - {io_h / 14. * 1., portPoint.at(id_OEN) + io_h / 14. * 0.6, io_h / 14. * 1.33, - portPoint.at(id_OEN) + io_h / 14.}, - {io_h / 14. * 2.2, portPoint.at(id_OEN) + io_h / 14., io_h / 14. * 3.2, portPoint.at(id_OEN) + io_h / 14.}, - {io_h / 14. * 2.2, portPoint.at(id_OEN) + 0., io_h / 14. * 3.2, portPoint.at(id_OEN) + 0.}, - {io_h / 14. * 2.2, portPoint.at(id_OEN) - io_h / 14., io_h / 14. * 3.2, portPoint.at(id_OEN) - io_h / 14.}, - {io_h / 14. * 2.2, portPoint.at(id_OEN) + io_h / 14., io_h / 14. * 2.2, portPoint.at(id_OEN) - io_h / 14.}}}, -}; - -const dict spineY = { - {id_SPINE0, 1. - 1. * ew_dist}, {id_SPINE1, 1. - 2. * ew_dist}, {id_SPINE2, 1. - 3. * ew_dist}, - {id_SPINE3, 1. - 4. * ew_dist}, {id_SPINE4, 1. - 5. * ew_dist}, {id_SPINE5, 1. - 6. * ew_dist}, - {id_SPINE6, 1. - 7. * ew_dist}, {id_SPINE7, 1. - 8. * ew_dist}, {id_SPINE8, 1. - 1. * ew_dist}, - {id_SPINE9, 1. - 2. * ew_dist}, {id_SPINE10, 1. - 3. * ew_dist}, {id_SPINE11, 1. - 4. * ew_dist}, - {id_SPINE12, 1. - 5. * ew_dist}, {id_SPINE13, 1. - 6. * ew_dist}, {id_SPINE14, 1. - 7. * ew_dist}, - {id_SPINE15, 1. - 8. * ew_dist}, {id_SPINE16, 1. - 1. * ew_dist}, {id_SPINE17, 1. - 2. * ew_dist}, - {id_SPINE18, 1. - 3. * ew_dist}, {id_SPINE19, 1. - 4. * ew_dist}, {id_SPINE20, 1. - 5. * ew_dist}, - {id_SPINE21, 1. - 6. * ew_dist}, {id_SPINE22, 1. - 7. * ew_dist}, {id_SPINE23, 1. - 8. * ew_dist}, - {id_SPINE24, 1. - 1. * ew_dist}, {id_SPINE25, 1. - 2. * ew_dist}, {id_SPINE26, 1. - 3. * ew_dist}, - {id_SPINE27, 1. - 4. * ew_dist}, {id_SPINE28, 1. - 5. * ew_dist}, {id_SPINE29, 1. - 6. * ew_dist}, - {id_SPINE30, 1. - 7. * ew_dist}, {id_SPINE31, 1. - 8. * ew_dist}, -}; - -const dict> pipPoint = { - {id_X01, {Center, cru_y + 1. * cru_h / 9.}}, - {id_X02, {Center, cru_y + 2. * cru_h / 9.}}, - {id_X03, {Center, cru_y + 3. * cru_h / 9.}}, - {id_X04, {Center, cru_y + 4. * cru_h / 9.}}, - {id_X05, {Center, cru_y + 5. * cru_h / 9.}}, - {id_X06, {Center, cru_y + 6. * cru_h / 9.}}, - {id_X07, {Center, cru_y + 7. * cru_h / 9.}}, - {id_X08, {Center, cru_y + 8. * cru_h / 9.}}, - // LUT inputs - {id_A0, {Right, lut_y[0] + lut_A_off}}, - {id_B0, {Right, lut_y[0] + lut_B_off}}, - {id_C0, {Right, lut_y[0] + lut_C_off}}, - {id_D0, {Right, lut_y[0] + lut_D_off}}, - {id_A1, {Right, lut_y[1] + lut_A_off}}, - {id_B1, {Right, lut_y[1] + lut_B_off}}, - {id_C1, {Right, lut_y[1] + lut_C_off}}, - {id_D1, {Right, lut_y[1] + lut_D_off}}, - {id_A2, {Right, lut_y[2] + lut_A_off}}, - {id_B2, {Right, lut_y[2] + lut_B_off}}, - {id_C2, {Right, lut_y[2] + lut_C_off}}, - {id_D2, {Right, lut_y[2] + lut_D_off}}, - {id_A3, {Right, lut_y[3] + lut_A_off}}, - {id_B3, {Right, lut_y[3] + lut_B_off}}, - {id_C3, {Right, lut_y[3] + lut_C_off}}, - {id_D3, {Right, lut_y[3] + lut_D_off}}, - {id_A4, {Right, lut_y[4] + lut_A_off}}, - {id_B4, {Right, lut_y[4] + lut_B_off}}, - {id_C4, {Right, lut_y[4] + lut_C_off}}, - {id_D4, {Right, lut_y[4] + lut_D_off}}, - {id_A5, {Right, lut_y[5] + lut_A_off}}, - {id_B5, {Right, lut_y[5] + lut_B_off}}, - {id_C5, {Right, lut_y[5] + lut_C_off}}, - {id_D5, {Right, lut_y[5] + lut_D_off}}, - {id_A6, {Right, lut_y[6] + lut_A_off}}, - {id_B6, {Right, lut_y[6] + lut_B_off}}, - {id_C6, {Right, lut_y[6] + lut_C_off}}, - {id_D6, {Right, lut_y[6] + lut_D_off}}, - {id_A7, {Right, lut_y[7] + lut_A_off}}, - {id_B7, {Right, lut_y[7] + lut_B_off}}, - {id_C7, {Right, lut_y[7] + lut_C_off}}, - {id_D7, {Right, lut_y[7] + lut_D_off}}, - // wires below LUT0 - {id_Q0, {Right, grp_lut_y[0] - right_wire_dist}}, - {id_F0, {Right, grp_lut_y[0] - 2. * right_wire_dist}}, - {id_OF3, {Right, grp_lut_y[0] - 3. * right_wire_dist}}, - // wires between LUT1 and LUT2 - {id_Q2, {Right, grp_lut_y[1] - right_wire_dist}}, - {id_F2, {Right, grp_lut_y[1] - 2. * right_wire_dist}}, - {id_OF2, {Right, grp_lut_y[1] - 3. * right_wire_dist}}, - {id_OF1, {Right, grp_lut_y[1] - 4. * right_wire_dist}}, - {id_OF0, {Right, grp_lut_y[1] - 5. * right_wire_dist}}, - {id_SEL1, {Right, grp_lut_y[1] - 6. * right_wire_dist}}, - {id_OF7, {Right, grp_lut_y[1] - 7. * right_wire_dist}}, - {id_SEL0, {Right, grp_lut_y[1] - 8. * right_wire_dist}}, - {id_F1, {Right, grp_lut_y[1] - 9. * right_wire_dist}}, - {id_Q1, {Right, grp_lut_y[1] - 10. * right_wire_dist}}, - // wires between LUT3 and LUT4 - {id_Q4, {Right, grp_lut_y[2] - right_wire_dist}}, - {id_F4, {Right, grp_lut_y[2] - 2. * right_wire_dist}}, - {id_OF4, {Right, grp_lut_y[2] - 3. * right_wire_dist}}, - {id_OF5, {Right, grp_lut_y[2] - 4. * right_wire_dist}}, - {id_SEL7, {Right, grp_lut_y[2] - 5. * right_wire_dist}}, - {id_SEL3, {Right, grp_lut_y[2] - 6. * right_wire_dist}}, - {id_SEL2, {Right, grp_lut_y[2] - 7. * right_wire_dist}}, - {id_F3, {Right, grp_lut_y[2] - 8. * right_wire_dist}}, - {id_Q3, {Right, grp_lut_y[2] - 9. * right_wire_dist}}, - // wires between LUT5 and LUT6 - {id_F6, {Right, grp_lut_y[3] - right_wire_dist}}, - {id_SEL5, {Right, grp_lut_y[3] - 2. * right_wire_dist}}, - {id_SEL4, {Right, grp_lut_y[3] - 4. * right_wire_dist}}, - {id_F5, {Right, grp_lut_y[3] - 5. * right_wire_dist}}, - {id_Q5, {Right, grp_lut_y[3] - 6. * right_wire_dist}}, - // Q6, Q7 --- IOB - {id_Q6, {Right, grp_lut_y[3] + grp_lut_h * 0.33}}, - {id_Q7, {Right, grp_lut_y[3] + grp_lut_h * 0.66}}, - // wires above LUT7 - {id_F7, {Right, grp_lut_y[3] + grp_lut_h + right_wire_dist}}, - {id_SEL6, {Right, grp_lut_y[3] + grp_lut_h + 2. * right_wire_dist}}, - {id_OF6, {Right, grp_lut_y[3] + grp_lut_h + 3. * right_wire_dist}}, - // DI0-5 - {id_DI5, {Right, cru_y + cru_h - 0.5 * right_wire_dist}}, - {id_DI4, {Right, cru_y + cru_h - 1. * right_wire_dist}}, - {id_DI3, {Right, cru_y + cru_h - 1.5 * right_wire_dist}}, - {id_DI2, {Right, cru_y + cru_h - 2. * right_wire_dist}}, - {id_DI1, {Right, cru_y + cru_h - 2.5 * right_wire_dist}}, - {id_DI0, {Right, cru_y + cru_h - 3. * right_wire_dist}}, - // Q6 - // CLK, CE, SET-RESET - {id_CLK0, {Right, lut_y[1] - clk_ce_set_vdist}}, - {id_CE0, {Right, lut_y[1] - 2. * clk_ce_set_vdist}}, - {id_LSR0, {Right, lut_y[1] - 3. * clk_ce_set_vdist}}, - {id_CLK1, {Right, lut_y[3] - clk_ce_set_vdist}}, - {id_CE1, {Right, lut_y[3] - 2. * clk_ce_set_vdist}}, - {id_LSR1, {Right, lut_y[3] - 3. * clk_ce_set_vdist}}, - {id_CLK2, {Right, lut_y[5] - clk_ce_set_vdist}}, - {id_CE2, {Right, lut_y[5] - 2. * clk_ce_set_vdist}}, - {id_LSR2, {Right, lut_y[5] - 3. * clk_ce_set_vdist}}, - // SN - // 1 hop - {id_S100, {Left, cru_y + 1. * left_wire_dist}}, - {id_S101, {Left, cru_y + 2. * left_wire_dist}}, - {id_S130, {Left, cru_y + 3. * left_wire_dist}}, - {id_S131, {Left, cru_y + 4. * left_wire_dist}}, - {id_N101, {Left, cru_y + 5. * left_wire_dist}}, - {id_N100, {Left, cru_y + 6. * left_wire_dist}}, - {id_N131, {Left, cru_y + 7. * left_wire_dist}}, - {id_N130, {Left, cru_y + 8. * left_wire_dist}}, - // 1 hop SN - {id_N111, {Left, cru_y + 9. * left_wire_dist}}, - {id_SN10, {Left, cru_y + 10. * left_wire_dist}}, - {id_S111, {Left, cru_y + 11. * left_wire_dist}}, - {id_N121, {Left, cru_y + 12. * left_wire_dist}}, - {id_SN20, {Left, cru_y + 13. * left_wire_dist}}, - {id_S121, {Left, cru_y + 14. * left_wire_dist}}, - // 2 hop - {id_S200, {Left, cru_y + 15. * left_wire_dist}}, - {id_S201, {Left, cru_y + 16. * left_wire_dist}}, - {id_N202, {Left, cru_y + 17. * left_wire_dist}}, - {id_S202, {Left, cru_y + 18. * left_wire_dist}}, - {id_N201, {Left, cru_y + 19. * left_wire_dist}}, - {id_N200, {Left, cru_y + 20. * left_wire_dist}}, - - {id_S210, {Left, cru_y + 21. * left_wire_dist}}, - {id_S211, {Left, cru_y + 22. * left_wire_dist}}, - {id_N212, {Left, cru_y + 23. * left_wire_dist}}, - {id_S212, {Left, cru_y + 24. * left_wire_dist}}, - {id_N211, {Left, cru_y + 25. * left_wire_dist}}, - {id_N210, {Left, cru_y + 26. * left_wire_dist}}, - - {id_S220, {Left, cru_y + 27. * left_wire_dist}}, - {id_S221, {Left, cru_y + 28. * left_wire_dist}}, - {id_N222, {Left, cru_y + 29. * left_wire_dist}}, - {id_S222, {Left, cru_y + 30. * left_wire_dist}}, - {id_N221, {Left, cru_y + 31. * left_wire_dist}}, - {id_N220, {Left, cru_y + 32. * left_wire_dist}}, - - {id_S230, {Left, cru_y + 33. * left_wire_dist}}, - {id_S231, {Left, cru_y + 34. * left_wire_dist}}, - {id_N232, {Left, cru_y + 35. * left_wire_dist}}, - {id_S232, {Left, cru_y + 36. * left_wire_dist}}, - {id_N231, {Left, cru_y + 37. * left_wire_dist}}, - {id_N230, {Left, cru_y + 38. * left_wire_dist}}, - - {id_S240, {Left, cru_y + 39. * left_wire_dist}}, - {id_S241, {Left, cru_y + 40. * left_wire_dist}}, - {id_N242, {Left, cru_y + 41. * left_wire_dist}}, - {id_S242, {Left, cru_y + 42. * left_wire_dist}}, - {id_N241, {Left, cru_y + 43. * left_wire_dist}}, - {id_N240, {Left, cru_y + 44. * left_wire_dist}}, - - {id_S250, {Left, cru_y + 45. * left_wire_dist}}, - {id_S251, {Left, cru_y + 46. * left_wire_dist}}, - {id_N252, {Left, cru_y + 47. * left_wire_dist}}, - {id_S252, {Left, cru_y + 48. * left_wire_dist}}, - {id_N251, {Left, cru_y + 49. * left_wire_dist}}, - {id_N250, {Left, cru_y + 50. * left_wire_dist}}, - - {id_S260, {Left, cru_y + 51. * left_wire_dist}}, - {id_S261, {Left, cru_y + 52. * left_wire_dist}}, - {id_N262, {Left, cru_y + 53. * left_wire_dist}}, - {id_S262, {Left, cru_y + 54. * left_wire_dist}}, - {id_N261, {Left, cru_y + 55. * left_wire_dist}}, - {id_N260, {Left, cru_y + 56. * left_wire_dist}}, - - {id_S270, {Left, cru_y + 57. * left_wire_dist}}, - {id_S271, {Left, cru_y + 58. * left_wire_dist}}, - {id_N272, {Left, cru_y + 59. * left_wire_dist}}, - {id_S272, {Left, cru_y + 60. * left_wire_dist}}, - {id_N271, {Left, cru_y + 61. * left_wire_dist}}, - {id_N270, {Left, cru_y + 62. * left_wire_dist}}, - - // Clocks - {id_GT10, {Left, cru_y + 63. * left_wire_dist}}, - {id_GT00, {Left, cru_y + 68. * left_wire_dist}}, - - // 4 hop - {id_N808, {Left, cru_y + 73. * left_wire_dist}}, - {id_S800, {Left, cru_y + 74. * left_wire_dist}}, - {id_S804, {Left, cru_y + 75. * left_wire_dist}}, - {id_N804, {Left, cru_y + 76. * left_wire_dist}}, - {id_N800, {Left, cru_y + 77. * left_wire_dist}}, - {id_S808, {Left, cru_y + 78. * left_wire_dist}}, - - {id_N818, {Left, cru_y + 79. * left_wire_dist}}, - {id_S810, {Left, cru_y + 80. * left_wire_dist}}, - {id_S814, {Left, cru_y + 81. * left_wire_dist}}, - {id_N814, {Left, cru_y + 82. * left_wire_dist}}, - {id_N810, {Left, cru_y + 83. * left_wire_dist}}, - {id_S818, {Left, cru_y + 84. * left_wire_dist}}, - - {id_N828, {Left, cru_y + 85. * left_wire_dist}}, - {id_S820, {Left, cru_y + 86. * left_wire_dist}}, - {id_S824, {Left, cru_y + 87. * left_wire_dist}}, - {id_N824, {Left, cru_y + 88. * left_wire_dist}}, - {id_N820, {Left, cru_y + 89. * left_wire_dist}}, - {id_S828, {Left, cru_y + 90. * left_wire_dist}}, - - {id_N838, {Left, cru_y + 91. * left_wire_dist}}, - {id_S830, {Left, cru_y + 92. * left_wire_dist}}, - {id_S834, {Left, cru_y + 93. * left_wire_dist}}, - {id_N834, {Left, cru_y + 94. * left_wire_dist}}, - {id_N830, {Left, cru_y + 95. * left_wire_dist}}, - {id_S838, {Left, cru_y + 96. * left_wire_dist}}, - - // EW - // 1 hop - {id_E101, {Top, cru_x + 1. * top_wire_dist}}, - {id_E100, {Top, cru_x + 2. * top_wire_dist}}, - {id_E131, {Top, cru_x + 3. * top_wire_dist}}, - {id_E130, {Top, cru_x + 4. * top_wire_dist}}, - {id_W100, {Top, cru_x + 5. * top_wire_dist}}, - {id_W101, {Top, cru_x + 6. * top_wire_dist}}, - {id_W130, {Top, cru_x + 7. * top_wire_dist}}, - {id_W131, {Top, cru_x + 8. * top_wire_dist}}, - // 1 hop EW - {id_E111, {Top, cru_x + 9. * top_wire_dist}}, - {id_EW10, {Top, cru_x + 10. * top_wire_dist}}, - {id_W111, {Top, cru_x + 11. * top_wire_dist}}, - {id_E121, {Top, cru_x + 12. * top_wire_dist}}, - {id_EW20, {Top, cru_x + 13. * top_wire_dist}}, - {id_W121, {Top, cru_x + 14. * top_wire_dist}}, - // 2 hop - {id_E202, {Top, cru_x + 15. * top_wire_dist}}, - {id_E201, {Top, cru_x + 16. * top_wire_dist}}, - {id_W200, {Top, cru_x + 17. * top_wire_dist}}, - {id_E200, {Top, cru_x + 18. * top_wire_dist}}, - {id_W201, {Top, cru_x + 19. * top_wire_dist}}, - {id_W202, {Top, cru_x + 20. * top_wire_dist}}, - - {id_E212, {Top, cru_x + 21. * top_wire_dist}}, - {id_E211, {Top, cru_x + 22. * top_wire_dist}}, - {id_W210, {Top, cru_x + 23. * top_wire_dist}}, - {id_E210, {Top, cru_x + 24. * top_wire_dist}}, - {id_W211, {Top, cru_x + 25. * top_wire_dist}}, - {id_W212, {Top, cru_x + 26. * top_wire_dist}}, - - {id_E222, {Top, cru_x + 27. * top_wire_dist}}, - {id_E221, {Top, cru_x + 28. * top_wire_dist}}, - {id_W220, {Top, cru_x + 29. * top_wire_dist}}, - {id_E220, {Top, cru_x + 30. * top_wire_dist}}, - {id_W221, {Top, cru_x + 31. * top_wire_dist}}, - {id_W222, {Top, cru_x + 32. * top_wire_dist}}, - - {id_E232, {Top, cru_x + 33. * top_wire_dist}}, - {id_E231, {Top, cru_x + 34. * top_wire_dist}}, - {id_W230, {Top, cru_x + 35. * top_wire_dist}}, - {id_E230, {Top, cru_x + 36. * top_wire_dist}}, - {id_W231, {Top, cru_x + 37. * top_wire_dist}}, - {id_W232, {Top, cru_x + 38. * top_wire_dist}}, - - {id_E242, {Top, cru_x + 39. * top_wire_dist}}, - {id_E241, {Top, cru_x + 40. * top_wire_dist}}, - {id_W240, {Top, cru_x + 41. * top_wire_dist}}, - {id_E240, {Top, cru_x + 42. * top_wire_dist}}, - {id_W241, {Top, cru_x + 43. * top_wire_dist}}, - {id_W242, {Top, cru_x + 44. * top_wire_dist}}, - - {id_E252, {Top, cru_x + 45. * top_wire_dist}}, - {id_E251, {Top, cru_x + 46. * top_wire_dist}}, - {id_W250, {Top, cru_x + 47. * top_wire_dist}}, - {id_E250, {Top, cru_x + 48. * top_wire_dist}}, - {id_W251, {Top, cru_x + 49. * top_wire_dist}}, - {id_W252, {Top, cru_x + 50. * top_wire_dist}}, - - {id_E262, {Top, cru_x + 51. * top_wire_dist}}, - {id_E261, {Top, cru_x + 52. * top_wire_dist}}, - {id_W260, {Top, cru_x + 53. * top_wire_dist}}, - {id_E260, {Top, cru_x + 54. * top_wire_dist}}, - {id_W261, {Top, cru_x + 55. * top_wire_dist}}, - {id_W262, {Top, cru_x + 56. * top_wire_dist}}, - - {id_E272, {Top, cru_x + 57. * top_wire_dist}}, - {id_E271, {Top, cru_x + 58. * top_wire_dist}}, - {id_W270, {Top, cru_x + 59. * top_wire_dist}}, - {id_E270, {Top, cru_x + 60. * top_wire_dist}}, - {id_W271, {Top, cru_x + 61. * top_wire_dist}}, - {id_W272, {Top, cru_x + 62. * top_wire_dist}}, - - // Global taps -> bracnhes - {id_GBO0, {Top, cru_x + 63. * top_wire_dist}}, - {id_GB00, {Top, cru_x + 64. * top_wire_dist}}, - {id_GB10, {Top, cru_x + 65. * top_wire_dist}}, - {id_GB20, {Top, cru_x + 66. * top_wire_dist}}, - {id_GB30, {Top, cru_x + 67. * top_wire_dist}}, - {id_GBO1, {Top, cru_x + 68. * top_wire_dist}}, - {id_GB40, {Top, cru_x + 68. * top_wire_dist}}, - {id_GB50, {Top, cru_x + 69. * top_wire_dist}}, - {id_GB60, {Top, cru_x + 70. * top_wire_dist}}, - {id_GB70, {Top, cru_x + 71. * top_wire_dist}}, - - // 4 hop - {id_E808, {Top, cru_x + 72. * top_wire_dist}}, - {id_W800, {Top, cru_x + 73. * top_wire_dist}}, - {id_W804, {Top, cru_x + 74. * top_wire_dist}}, - {id_E804, {Top, cru_x + 75. * top_wire_dist}}, - {id_E800, {Top, cru_x + 76. * top_wire_dist}}, - {id_W808, {Top, cru_x + 77. * top_wire_dist}}, - - {id_E818, {Top, cru_x + 78. * top_wire_dist}}, - {id_W810, {Top, cru_x + 79. * top_wire_dist}}, - {id_W814, {Top, cru_x + 80. * top_wire_dist}}, - {id_E814, {Top, cru_x + 81. * top_wire_dist}}, - {id_E810, {Top, cru_x + 82. * top_wire_dist}}, - {id_W818, {Top, cru_x + 83. * top_wire_dist}}, - - {id_E828, {Top, cru_x + 84. * top_wire_dist}}, - {id_W820, {Top, cru_x + 85. * top_wire_dist}}, - {id_W824, {Top, cru_x + 86. * top_wire_dist}}, - {id_E824, {Top, cru_x + 87. * top_wire_dist}}, - {id_E820, {Top, cru_x + 88. * top_wire_dist}}, - {id_W828, {Top, cru_x + 89. * top_wire_dist}}, - - {id_E838, {Top, cru_x + 90. * top_wire_dist}}, - {id_W830, {Top, cru_x + 91. * top_wire_dist}}, - {id_W834, {Top, cru_x + 92. * top_wire_dist}}, - {id_E834, {Top, cru_x + 93. * top_wire_dist}}, - {id_E830, {Top, cru_x + 94. * top_wire_dist}}, - {id_W838, {Top, cru_x + 95. * top_wire_dist}}, - -}; - -// wire -const std::vector decalless_wires = {id_X01, id_X02, id_X03, id_X04, id_X05, id_X06, id_X07}; - -const float clk_ce_set_hdist = dff_w / 4.; -const float dff_f_x = (grp_lut_x + grp_lut_w + dff_x + dff_w) / 2.; -const float mux5i_x = (grp_lut_x + grp_lut_w + mux2lut5_x) / 2.; - -// id, {x1, y1, x2, y2} -const dict>> sliceLocalWires = { - // dff - {id_CLK0, - {{cru_x + cru_w, pipPoint.at(id_CLK0).second, dff_x + clk_ce_set_hdist, pipPoint.at(id_CLK0).second}, - {dff_x + clk_ce_set_hdist, lut_y[1], dff_x + clk_ce_set_hdist, lut_y[0] + lut_h}}}, - {id_CE0, - {{cru_x + cru_w, pipPoint.at(id_CE0).second, dff_x + 2. * clk_ce_set_hdist, pipPoint.at(id_CE0).second}, - {dff_x + 2 * clk_ce_set_hdist, lut_y[1], dff_x + 2. * clk_ce_set_hdist, lut_y[0] + lut_h}}}, - {id_LSR0, - {{cru_x + cru_w, pipPoint.at(id_LSR0).second, dff_x + 3. * clk_ce_set_hdist, pipPoint.at(id_LSR0).second}, - {dff_x + 3 * clk_ce_set_hdist, lut_y[1], dff_x + 3. * clk_ce_set_hdist, lut_y[0] + lut_h}}}, - {id_CLK1, - {{cru_x + cru_w, pipPoint.at(id_CLK1).second, dff_x + clk_ce_set_hdist, pipPoint.at(id_CLK1).second}, - {dff_x + clk_ce_set_hdist, lut_y[3], dff_x + clk_ce_set_hdist, lut_y[2] + lut_h}}}, - {id_CE1, - {{cru_x + cru_w, pipPoint.at(id_CE1).second, dff_x + 2. * clk_ce_set_hdist, pipPoint.at(id_CE1).second}, - {dff_x + 2 * clk_ce_set_hdist, lut_y[3], dff_x + 2. * clk_ce_set_hdist, lut_y[2] + lut_h}}}, - {id_LSR1, - {{cru_x + cru_w, pipPoint.at(id_LSR1).second, dff_x + 3. * clk_ce_set_hdist, pipPoint.at(id_LSR1).second}, - {dff_x + 3 * clk_ce_set_hdist, lut_y[3], dff_x + 3. * clk_ce_set_hdist, lut_y[2] + lut_h}}}, - {id_CLK2, - {{cru_x + cru_w, pipPoint.at(id_CLK2).second, dff_x + clk_ce_set_hdist, pipPoint.at(id_CLK2).second}, - {dff_x + clk_ce_set_hdist, lut_y[5], dff_x + clk_ce_set_hdist, lut_y[4] + lut_h}}}, - {id_CE2, - {{cru_x + cru_w, pipPoint.at(id_CE2).second, dff_x + 2. * clk_ce_set_hdist, pipPoint.at(id_CE2).second}, - {dff_x + 2 * clk_ce_set_hdist, lut_y[5], dff_x + 2. * clk_ce_set_hdist, lut_y[4] + lut_h}}}, - {id_LSR2, - {{cru_x + cru_w, pipPoint.at(id_LSR2).second, dff_x + 3 * clk_ce_set_hdist, pipPoint.at(id_LSR2).second}, - {dff_x + 3 * clk_ce_set_hdist, lut_y[5], dff_x + 3. * clk_ce_set_hdist, lut_y[4] + lut_h}}}, - // lut - {id_A0, {{cru_x + cru_w, lut_y[0] + lut_A_off, lut_x, lut_y[0] + lut_A_off}}}, - {id_B0, {{cru_x + cru_w, lut_y[0] + lut_B_off, lut_x, lut_y[0] + lut_B_off}}}, - {id_C0, {{cru_x + cru_w, lut_y[0] + lut_C_off, lut_x, lut_y[0] + lut_C_off}}}, - {id_D0, {{cru_x + cru_w, lut_y[0] + lut_D_off, lut_x, lut_y[0] + lut_D_off}}}, - {id_A1, {{cru_x + cru_w, lut_y[1] + lut_A_off, lut_x, lut_y[1] + lut_A_off}}}, - {id_B1, {{cru_x + cru_w, lut_y[1] + lut_B_off, lut_x, lut_y[1] + lut_B_off}}}, - {id_C1, {{cru_x + cru_w, lut_y[1] + lut_C_off, lut_x, lut_y[1] + lut_C_off}}}, - {id_D1, {{cru_x + cru_w, lut_y[1] + lut_D_off, lut_x, lut_y[1] + lut_D_off}}}, - {id_A2, {{cru_x + cru_w, lut_y[2] + lut_A_off, lut_x, lut_y[2] + lut_A_off}}}, - {id_B2, {{cru_x + cru_w, lut_y[2] + lut_B_off, lut_x, lut_y[2] + lut_B_off}}}, - {id_C2, {{cru_x + cru_w, lut_y[2] + lut_C_off, lut_x, lut_y[2] + lut_C_off}}}, - {id_D2, {{cru_x + cru_w, lut_y[2] + lut_D_off, lut_x, lut_y[2] + lut_D_off}}}, - {id_A3, {{cru_x + cru_w, lut_y[3] + lut_A_off, lut_x, lut_y[3] + lut_A_off}}}, - {id_B3, {{cru_x + cru_w, lut_y[3] + lut_B_off, lut_x, lut_y[3] + lut_B_off}}}, - {id_C3, {{cru_x + cru_w, lut_y[3] + lut_C_off, lut_x, lut_y[3] + lut_C_off}}}, - {id_D3, {{cru_x + cru_w, lut_y[3] + lut_D_off, lut_x, lut_y[3] + lut_D_off}}}, - {id_A4, {{cru_x + cru_w, lut_y[4] + lut_A_off, lut_x, lut_y[4] + lut_A_off}}}, - {id_B4, {{cru_x + cru_w, lut_y[4] + lut_B_off, lut_x, lut_y[4] + lut_B_off}}}, - {id_C4, {{cru_x + cru_w, lut_y[4] + lut_C_off, lut_x, lut_y[4] + lut_C_off}}}, - {id_D4, {{cru_x + cru_w, lut_y[4] + lut_D_off, lut_x, lut_y[4] + lut_D_off}}}, - {id_A5, {{cru_x + cru_w, lut_y[5] + lut_A_off, lut_x, lut_y[5] + lut_A_off}}}, - {id_B5, {{cru_x + cru_w, lut_y[5] + lut_B_off, lut_x, lut_y[5] + lut_B_off}}}, - {id_C5, {{cru_x + cru_w, lut_y[5] + lut_C_off, lut_x, lut_y[5] + lut_C_off}}}, - {id_D5, {{cru_x + cru_w, lut_y[5] + lut_D_off, lut_x, lut_y[5] + lut_D_off}}}, - {id_A6, {{cru_x + cru_w, lut_y[6] + lut_A_off, lut_x, lut_y[6] + lut_A_off}}}, - {id_B6, {{cru_x + cru_w, lut_y[6] + lut_B_off, lut_x, lut_y[6] + lut_B_off}}}, - {id_C6, {{cru_x + cru_w, lut_y[6] + lut_C_off, lut_x, lut_y[6] + lut_C_off}}}, - {id_D6, {{cru_x + cru_w, lut_y[6] + lut_D_off, lut_x, lut_y[6] + lut_D_off}}}, - {id_A7, {{cru_x + cru_w, lut_y[7] + lut_A_off, lut_x, lut_y[7] + lut_A_off}}}, - {id_B7, {{cru_x + cru_w, lut_y[7] + lut_B_off, lut_x, lut_y[7] + lut_B_off}}}, - {id_C7, {{cru_x + cru_w, lut_y[7] + lut_C_off, lut_x, lut_y[7] + lut_C_off}}}, - {id_D7, {{cru_x + cru_w, lut_y[7] + lut_D_off, lut_x, lut_y[7] + lut_D_off}}}, - // wires below LUT0 - {id_Q0, - {{cru_x + cru_w, grp_lut_y[0] - right_wire_dist, dff_f_x, grp_lut_y[0] - right_wire_dist}, - {dff_f_x, grp_lut_y[0] - right_wire_dist, dff_f_x, lut_y[0] + lut_h / 2.}, - {dff_f_x, lut_y[0] + lut_h / 2., dff_x + dff_w, lut_y[0] + lut_h / 2.}}}, - {id_F0, - {{cru_x + cru_w, grp_lut_y[0] - 2. * right_wire_dist, (lut_x + lut_w + dff_x) / 2., - grp_lut_y[0] - 2. * right_wire_dist}, - {(lut_x + lut_w + dff_x) / 2., grp_lut_y[0] - 2. * right_wire_dist, (lut_x + lut_w + dff_x) / 2., - lut_y[0] + lut_h / 2.}, - {lut_x + lut_w, lut_y[0] + lut_h / 2., dff_x, lut_y[0] + lut_h / 2.}}}, - {id_I0MUX0, - {{(lut_x + lut_w + dff_x) / 2., grp_lut_y[0] - 2. * right_wire_dist, mux5i_x, - grp_lut_y[0] - 2. * right_wire_dist}, - {mux5i_x, grp_lut_y[0] - 2. * right_wire_dist, mux5i_x, lut_y[0] + lut_h / 2.}, - {mux5i_x, lut_y[0] + lut_h / 2., mux2lut5_x, lut_y[0] + lut_h / 2.}}}, - {id_OF3, - {{cru_x + cru_w, grp_lut_y[0] - 3. * right_wire_dist, mux2lut7_x + 4. / 3. * mux_w, - grp_lut_y[0] - 3. * right_wire_dist}, - {mux2lut7_x + 4. / 3. * mux_w, grp_lut_y[0] - 3. * right_wire_dist, mux2lut7_x + 4. / 3. * mux_w, - mux2lut7_y + mux_h / 2.}, - {mux2lut7_x + 4. / 3. * mux_w, mux2lut7_y + mux_h / 2., mux2lut7_x + mux_w, mux2lut7_y + mux_h / 2.}}}, - {id_I1MUX7, {{mux2lut7_x + 4. / 3. * mux_w, mux2lut7_y + mux_h / 2., mux2lut8_x, mux2lut7_y + mux_h / 2.}}}, - // wires between LUT1 and LUT2 - {id_Q1, - {{cru_x + cru_w, grp_lut_y[1] - 10. * right_wire_dist, dff_f_x, grp_lut_y[1] - 10. * right_wire_dist}, - {dff_f_x, grp_lut_y[1] - 10. * right_wire_dist, dff_f_x, lut_y[1] + lut_h / 2.}, - {dff_f_x, lut_y[1] + lut_h / 2., dff_x + dff_w, lut_y[1] + lut_h / 2.}}}, - {id_F1, - {{cru_x + cru_w, grp_lut_y[1] - 9. * right_wire_dist, (lut_x + lut_w + dff_x) / 2., - grp_lut_y[1] - 9. * right_wire_dist}, - {(lut_x + lut_w + dff_x) / 2., grp_lut_y[1] - 9. * right_wire_dist, (lut_x + lut_w + dff_x) / 2., - lut_y[1] + lut_h / 2.}, - {lut_x + lut_w, lut_y[1] + lut_h / 2., dff_x, lut_y[1] + lut_h / 2.}}}, - {id_I1MUX0, - {{(lut_x + lut_w + dff_x) / 2., grp_lut_y[1] - 9. * right_wire_dist, mux5i_x, - grp_lut_y[1] - 9. * right_wire_dist}, - {mux5i_x, grp_lut_y[1] - 9. * right_wire_dist, mux5i_x, lut_y[1] + lut_h / 2.}, - {mux5i_x, lut_y[1] + lut_h / 2., mux2lut5_x, lut_y[1] + lut_h / 2.}}}, - {id_SEL0, - {{cru_x + cru_w, grp_lut_y[1] - 8. * right_wire_dist, mux2lut5_x + mux_w / 2., - grp_lut_y[1] - 8. * right_wire_dist}, - {mux2lut5_x + mux_w / 2., grp_lut_y[1] - 8. * right_wire_dist, mux2lut5_x + mux_w / 2., - mux2lut5_y[0] + mux_h - mux_f / 2.}}}, - {id_OF7, - {{cru_x + cru_w, grp_lut_y[1] - 7. * right_wire_dist, mux2lut8_x + 4. / 3. * mux_w, - grp_lut_y[1] - 7. * right_wire_dist}, - {mux2lut8_x + 4. / 3. * mux_w, grp_lut_y[1] - 7. * right_wire_dist, mux2lut8_x + 4. / 3. * mux_w, - mux2lut8_y + mux_h / 2.}, - {mux2lut8_x + 4. / 3. * mux_w, mux2lut8_y + mux_h / 2., mux2lut8_x + mux_w, mux2lut8_y + mux_h / 2.}}}, - {id_SEL1, - {{cru_x + cru_w, grp_lut_y[1] - 6. * right_wire_dist, mux2lut6_x + mux_w / 2., - grp_lut_y[1] - 6. * right_wire_dist}, - {mux2lut6_x + mux_w / 2., grp_lut_y[1] - 6. * right_wire_dist, mux2lut6_x + mux_w / 2., - mux2lut6_y[0] + mux_h - mux_f / 2.}}}, - {id_OF0, - {{cru_x + cru_w, grp_lut_y[1] - 5. * right_wire_dist, mux2lut5_x + 4. / 3. * mux_w, - grp_lut_y[1] - 5. * right_wire_dist}, - {mux2lut5_x + 4. / 3. * mux_w, grp_lut_y[1] - 5. * right_wire_dist, mux2lut5_x + 4. / 3. * mux_w, - mux2lut5_y[0] + mux_h / 2.}, - {mux2lut5_x + 4. / 3. * mux_w, mux2lut5_y[0] + mux_h / 2., mux2lut5_x + mux_w, mux2lut5_y[0] + mux_h / 2.}}}, - {id_I1MUX1, - {{mux2lut5_x + 4. / 3. * mux_w, mux2lut5_y[0] + mux_h / 2., mux2lut6_x, mux2lut5_y[0] + mux_h / 2.}}}, - {id_OF1, - {{cru_x + cru_w, grp_lut_y[1] - 4. * right_wire_dist, mux2lut6_x + 4. / 3. * mux_w, - grp_lut_y[1] - 4. * right_wire_dist}, - {mux2lut6_x + 4. / 3. * mux_w, grp_lut_y[1] - 4. * right_wire_dist, mux2lut6_x + 4. / 3. * mux_w, - mux2lut6_y[0] + mux_h / 2.}, - {mux2lut6_x + 4. / 3. * mux_w, mux2lut6_y[0] + mux_h / 2., mux2lut6_x + mux_w, mux2lut6_y[0] + mux_h / 2.}}}, - {id_I1MUX3, - {{mux2lut6_x + 4. / 3. * mux_w, grp_lut_y[1] - 4. * right_wire_dist, mux2lut6_x + 4. / 3. * mux_w, - mux2lut7_y + mux_h * 1. / 4.}, - {mux2lut6_x + 4. / 3. * mux_w, mux2lut7_y + mux_h * 1. / 4., mux2lut7_x, mux2lut7_y + mux_h * 1. / 4.}}}, - {id_OF2, - {{cru_x + cru_w, grp_lut_y[1] - 3. * right_wire_dist, mux2lut5_x + 5. / 3. * mux_w, - grp_lut_y[1] - 3. * right_wire_dist}, - {mux2lut5_x + 5. / 3. * mux_w, grp_lut_y[1] - 3. * right_wire_dist, mux2lut5_x + 5. / 3. * mux_w, - mux2lut5_y[1] + mux_h / 2.}, - {mux2lut5_x + 5. / 3. * mux_w, mux2lut5_y[1] + mux_h / 2., mux2lut5_x + mux_w, mux2lut5_y[1] + mux_h / 2.}}}, - {id_I0MUX1, - {{mux2lut5_x + 5. / 3. * mux_w, grp_lut_y[1] - 3. * right_wire_dist, mux2lut5_x + 5. / 3. * mux_w, - mux2lut6_y[0] + mux_h * 3. / 4.}, - {mux2lut5_x + 5. / 3. * mux_w, mux2lut6_y[0] + mux_h * 3. / 4., mux2lut6_x, - mux2lut6_y[0] + mux_h * 3. / 4.}}}, - {id_F2, - {{cru_x + cru_w, grp_lut_y[1] - 2. * right_wire_dist, (lut_x + lut_w + dff_x) / 2., - grp_lut_y[1] - 2. * right_wire_dist}, - {(lut_x + lut_w + dff_x) / 2., grp_lut_y[1] - 2. * right_wire_dist, (lut_x + lut_w + dff_x) / 2., - lut_y[2] + lut_h / 2.}, - {lut_x + lut_w, lut_y[2] + lut_h / 2., dff_x, lut_y[2] + lut_h / 2.}}}, - {id_I0MUX2, - {{(lut_x + lut_w + dff_x) / 2., grp_lut_y[1] - 2. * right_wire_dist, mux5i_x, - grp_lut_y[1] - 2. * right_wire_dist}, - {mux5i_x, grp_lut_y[1] - 2. * right_wire_dist, mux5i_x, lut_y[2] + lut_h / 2.}, - {mux5i_x, lut_y[2] + lut_h / 2., mux2lut5_x, lut_y[2] + lut_h / 2.}}}, - {id_Q2, - {{cru_x + cru_w, grp_lut_y[1] - right_wire_dist, dff_f_x, grp_lut_y[1] - right_wire_dist}, - {dff_f_x, grp_lut_y[1] - right_wire_dist, dff_f_x, lut_y[2] + lut_h / 2.}, - {dff_f_x, lut_y[2] + lut_h / 2., dff_x + dff_w, lut_y[2] + lut_h / 2.}}}, - // wires between LUT3 and LUT4 - {id_Q3, - {{cru_x + cru_w, grp_lut_y[2] - 9. * right_wire_dist, dff_f_x, grp_lut_y[2] - 9. * right_wire_dist}, - {dff_f_x, grp_lut_y[2] - 9. * right_wire_dist, dff_f_x, lut_y[3] + lut_h / 2.}, - {dff_f_x, lut_y[3] + lut_h / 2., dff_x + dff_w, lut_y[3] + lut_h / 2.}}}, - {id_F3, - {{cru_x + cru_w, grp_lut_y[2] - 8. * right_wire_dist, (lut_x + lut_w + dff_x) / 2., - grp_lut_y[2] - 8. * right_wire_dist}, - {(lut_x + lut_w + dff_x) / 2., grp_lut_y[2] - 8. * right_wire_dist, (lut_x + lut_w + dff_x) / 2., - lut_y[3] + lut_h / 2.}, - {lut_x + lut_w, lut_y[3] + lut_h / 2., dff_x, lut_y[3] + lut_h / 2.}}}, - {id_I1MUX2, - {{(lut_x + lut_w + dff_x) / 2., grp_lut_y[2] - 8. * right_wire_dist, mux5i_x, - grp_lut_y[2] - 8. * right_wire_dist}, - {mux5i_x, grp_lut_y[2] - 8. * right_wire_dist, mux5i_x, lut_y[3] + lut_h / 2.}, - {mux5i_x, lut_y[3] + lut_h / 2., mux2lut5_x, lut_y[3] + lut_h / 2.}}}, - {id_SEL2, - {{cru_x + cru_w, grp_lut_y[2] - 7. * right_wire_dist, mux2lut5_x + mux_w / 2., - grp_lut_y[2] - 7. * right_wire_dist}, - {mux2lut5_x + mux_w / 2., grp_lut_y[2] - 7. * right_wire_dist, mux2lut5_x + mux_w / 2., - mux2lut5_y[1] + mux_h - mux_f / 2.}}}, - {id_SEL3, - {{cru_x + cru_w, grp_lut_y[2] - 6. * right_wire_dist, mux2lut7_x + mux_w / 2., - grp_lut_y[2] - 6. * right_wire_dist}, - {mux2lut7_x + mux_w / 2., grp_lut_y[2] - 6. * right_wire_dist, mux2lut7_x + mux_w / 2., - mux2lut7_y + mux_h - mux_f / 2.}}}, - {id_SEL7, - {{cru_x + cru_w, grp_lut_y[2] - 5. * right_wire_dist, mux2lut8_x + mux_w / 2., - grp_lut_y[2] - 5. * right_wire_dist}, - {mux2lut8_x + mux_w / 2., grp_lut_y[2] - 5. * right_wire_dist, mux2lut8_x + mux_w / 2., - mux2lut8_y + mux_h - mux_f / 2.}}}, - {id_OF5, - {{cru_x + cru_w, grp_lut_y[2] - 4. * right_wire_dist, mux2lut6_x + 4. / 3. * mux_w, - grp_lut_y[2] - 4. * right_wire_dist}, - {mux2lut6_x + 4. / 3. * mux_w, grp_lut_y[2] - 4. * right_wire_dist, mux2lut6_x + 4. / 3. * mux_w, - mux2lut6_y[1] + mux_h / 2.}, - {mux2lut6_x + 4. / 3. * mux_w, mux2lut6_y[1] + mux_h / 2., mux2lut6_x + mux_w, mux2lut6_y[1] + mux_h / 2.}}}, - {id_I0MUX3, - {{mux2lut6_x + 4. / 3. * mux_w, grp_lut_y[2] - 4. * right_wire_dist, mux2lut6_x + 4. / 3. * mux_w, - mux2lut7_y + mux_h * 3. / 4.}, - {mux2lut6_x + 4. / 3. * mux_w, mux2lut7_y + mux_h * 3. / 4., mux2lut7_x, mux2lut7_y + mux_h * 3. / 4.}}}, - {id_OF4, - {{cru_x + cru_w, grp_lut_y[2] - 3. * right_wire_dist, mux2lut5_x + 4. / 3. * mux_w, - grp_lut_y[2] - 3. * right_wire_dist}, - {mux2lut5_x + 4. / 3. * mux_w, grp_lut_y[2] - 3. * right_wire_dist, mux2lut5_x + 4. / 3. * mux_w, - mux2lut5_y[2] + mux_h / 2.}, - {mux2lut5_x + 4. / 3. * mux_w, mux2lut5_y[2] + mux_h / 2., mux2lut5_x + mux_w, mux2lut5_y[2] + mux_h / 2.}}}, - {id_I1MUX5, - {{mux2lut5_x + 4. / 3. * mux_w, mux2lut5_y[2] + mux_h / 2., mux2lut6_x, mux2lut5_y[2] + mux_h / 2.}}}, - {id_F4, - {{cru_x + cru_w, grp_lut_y[2] - 2. * right_wire_dist, (lut_x + lut_w + dff_x) / 2., - grp_lut_y[2] - 2. * right_wire_dist}, - {(lut_x + lut_w + dff_x) / 2., grp_lut_y[2] - 2. * right_wire_dist, (lut_x + lut_w + dff_x) / 2., - lut_y[4] + lut_h / 2.}, - {lut_x + lut_w, lut_y[4] + lut_h / 2., dff_x, lut_y[4] + lut_h / 2.}}}, - {id_I0MUX4, - {{(lut_x + lut_w + dff_x) / 2., grp_lut_y[2] - 2. * right_wire_dist, mux5i_x, - grp_lut_y[2] - 2. * right_wire_dist}, - {mux5i_x, grp_lut_y[2] - 2. * right_wire_dist, mux5i_x, lut_y[4] + lut_h / 2.}, - {mux5i_x, lut_y[4] + lut_h / 2., mux2lut5_x, lut_y[4] + lut_h / 2.}}}, - {id_Q4, - {{cru_x + cru_w, grp_lut_y[2] - right_wire_dist, dff_f_x, grp_lut_y[2] - right_wire_dist}, - {dff_f_x, grp_lut_y[2] - right_wire_dist, dff_f_x, lut_y[4] + lut_h / 2.}, - {dff_f_x, lut_y[4] + lut_h / 2., dff_x + dff_w, lut_y[4] + lut_h / 2.}}}, - // wires between LUT5 and LUT6 - {id_Q5, - {{cru_x + cru_w, grp_lut_y[3] - 6. * right_wire_dist, dff_f_x, grp_lut_y[3] - 6. * right_wire_dist}, - {dff_f_x, grp_lut_y[3] - 6. * right_wire_dist, dff_f_x, lut_y[5] + lut_h / 2.}, - {dff_f_x, lut_y[5] + lut_h / 2., dff_x + dff_w, lut_y[5] + lut_h / 2.}}}, - {id_F5, - {{cru_x + cru_w, grp_lut_y[3] - 5. * right_wire_dist, (lut_x + lut_w + dff_x) / 2., - grp_lut_y[3] - 5. * right_wire_dist}, - {(lut_x + lut_w + dff_x) / 2., grp_lut_y[3] - 5. * right_wire_dist, (lut_x + lut_w + dff_x) / 2., - lut_y[5] + lut_h / 2.}, - {lut_x + lut_w, lut_y[5] + lut_h / 2., dff_x, lut_y[5] + lut_h / 2.}}}, - {id_I1MUX4, - {{(lut_x + lut_w + dff_x) / 2., grp_lut_y[3] - 5. * right_wire_dist, mux5i_x, - grp_lut_y[3] - 5. * right_wire_dist}, - {mux5i_x, grp_lut_y[3] - 5. * right_wire_dist, mux5i_x, lut_y[5] + lut_h / 2.}, - {mux5i_x, lut_y[5] + lut_h / 2., mux2lut5_x, lut_y[5] + lut_h / 2.}}}, - {id_SEL4, - {{cru_x + cru_w, grp_lut_y[3] - 4. * right_wire_dist, mux2lut5_x + mux_w / 2., - grp_lut_y[3] - 4. * right_wire_dist}, - {mux2lut5_x + mux_w / 2., grp_lut_y[3] - 4. * right_wire_dist, mux2lut5_x + mux_w / 2., - mux2lut5_y[2] + mux_h - mux_f / 2.}}}, - {id_SEL5, - {{cru_x + cru_w, grp_lut_y[3] - 2. * right_wire_dist, mux2lut6_x + mux_w / 2., - grp_lut_y[3] - 2. * right_wire_dist}, - {mux2lut6_x + mux_w / 2., grp_lut_y[3] - 2. * right_wire_dist, mux2lut6_x + mux_w / 2., - mux2lut6_y[1] + mux_h - mux_f / 2.}}}, - {id_F6, - {{cru_x + cru_w, grp_lut_y[3] - right_wire_dist, (lut_x + lut_w + dff_x) / 2., grp_lut_y[3] - right_wire_dist}, - {(lut_x + lut_w + dff_x) / 2., grp_lut_y[3] - right_wire_dist, (lut_x + lut_w + dff_x) / 2., - lut_y[6] + lut_h / 2.}, - {lut_x + lut_w, lut_y[6] + lut_h / 2., (lut_x + lut_w + dff_x) / 2., lut_y[6] + lut_h / 2.}}}, - {id_I0MUX6, {{(lut_x + lut_w + dff_x) / 2., lut_y[6] + lut_h / 2., mux2lut5_x, lut_y[6] + lut_h / 2.}}}, - // wires above LUT7 - {id_F7, - {{cru_x + cru_w, grp_lut_y[3] + grp_lut_h + right_wire_dist, (lut_x + lut_w + dff_x) / 2., - grp_lut_y[3] + grp_lut_h + right_wire_dist}, - {(lut_x + lut_w + dff_x) / 2., grp_lut_y[3] + grp_lut_h + right_wire_dist, (lut_x + lut_w + dff_x) / 2., - lut_y[7] + lut_h / 2.}, - {lut_x + lut_w, lut_y[7] + lut_h / 2., (lut_x + lut_w + dff_x) / 2., lut_y[7] + lut_h / 2.}}}, - {id_I1MUX6, {{(lut_x + lut_w + dff_x) / 2., lut_y[7] + lut_h / 2., mux2lut5_x, lut_y[7] + lut_h / 2.}}}, - {id_SEL6, - {{cru_x + cru_w, grp_lut_y[3] + grp_lut_h + 2. * right_wire_dist, mux2lut5_x + mux_w / 2., - grp_lut_y[3] + grp_lut_h + 2. * right_wire_dist}, - {mux2lut5_x + mux_w / 2., grp_lut_y[3] + grp_lut_h + 2. * right_wire_dist, mux2lut5_x + mux_w / 2., - mux2lut5_y[3] + mux_h - mux_f / 2.}}}, - {id_OF6, - {{cru_x + cru_w, grp_lut_y[3] + grp_lut_h + 3. * right_wire_dist, mux2lut5_x + 4. / 3. * mux_w, - grp_lut_y[3] + grp_lut_h + 3. * right_wire_dist}, - {mux2lut5_x + 4. / 3. * mux_w, grp_lut_y[3] + grp_lut_h + 3. * right_wire_dist, mux2lut5_x + 4. / 3. * mux_w, - mux2lut5_y[3] + mux_h / 2.}, - {mux2lut5_x + 4. / 3. * mux_w, mux2lut5_y[3] + mux_h / 2., mux2lut5_x + mux_w, mux2lut5_y[3] + mux_h / 2.}}}, - {id_I0MUX5, - {{mux2lut5_x + 4. / 3. * mux_w, mux2lut5_y[3] + mux_h / 2., mux2lut5_x + 4. / 3. * mux_w, - mux2lut6_y[1] + mux_h * 3. / 4.}, - {mux2lut5_x + 4. / 3. * mux_w, mux2lut6_y[1] + mux_h * 3. / 4., mux2lut6_x, - mux2lut6_y[1] + mux_h * 3. / 4.}}}, -}; - -const dict>> globalSimpleWires = { - {id_I0MUX7, - {{mux2lut8_x, mux2lut8_y + mux_h / 4., mux2lut8_x - 1. / 3. * mux_w, mux2lut8_y + mux_h / 4.}, - {mux2lut8_x - 1. / 3. * mux_w, mux2lut8_y + mux_h / 4., mux2lut8_x - 1. / 3. * mux_w, - cru_y - 2. * right_wire_dist}, - {mux2lut8_x - 1. / 3. * mux_w, cru_y - 2. * right_wire_dist, 1. + mux2lut7_x + 4. / 3. * mux_w, - cru_y - 2. * right_wire_dist}, - {1. + mux2lut7_x + 4. / 3. * mux_w, cru_y - 2. * right_wire_dist, 1. + mux2lut7_x + 4. / 3. * mux_w, - grp_lut_y[0] - 3. * right_wire_dist}}}, -}; - -dict>> const globalWires = { -#define PIP_Y(pip_id) (pipPoint.at(pip_id).second) -#define WIRE_X(offset) (cru_x - ((float)offset) * sn_dist) - // 1 hop - {id_S10, - {{WIRE_X(0), PIP_Y(id_S100), WIRE_X(1), PIP_Y(id_S100)}, - {WIRE_X(1), PIP_Y(id_S100), WIRE_X(1), -1. + PIP_Y(id_S101)}, - {WIRE_X(1), -1. + PIP_Y(id_S101), WIRE_X(0), -1. + PIP_Y(id_S101)}}}, - {id_N10, - {{WIRE_X(0), PIP_Y(id_N100), WIRE_X(2), PIP_Y(id_N100)}, - {WIRE_X(2), PIP_Y(id_N100), WIRE_X(2), 1. + PIP_Y(id_N101)}, - {WIRE_X(2), 1. + PIP_Y(id_N101), WIRE_X(0), 1. + PIP_Y(id_N101)}}}, - {id_S10_loop0, - {{WIRE_X(0), PIP_Y(id_S100), WIRE_X(1), PIP_Y(id_S100)}, - {WIRE_X(1), PIP_Y(id_S100), WIRE_X(1), -1. * wrap_len}, - {WIRE_X(1), -1. * wrap_len, WIRE_X(2), -1. * wrap_len}, - {WIRE_X(2), -1. * wrap_len, WIRE_X(2), PIP_Y(id_N101)}, - {WIRE_X(2), PIP_Y(id_N101), WIRE_X(0), PIP_Y(id_N101)}}}, - {id_N10_loop0, - {{WIRE_X(0), PIP_Y(id_N100), WIRE_X(2), PIP_Y(id_N100)}, - {WIRE_X(2), PIP_Y(id_N100), WIRE_X(2), 1. + 1. * wrap_len}, - {WIRE_X(2), 1. + 1. * wrap_len, WIRE_X(1), 1. + 1. * wrap_len}, - {WIRE_X(1), 1. + 1. * wrap_len, WIRE_X(1), PIP_Y(id_S101)}, - {WIRE_X(1), PIP_Y(id_S101), WIRE_X(0), PIP_Y(id_S101)}}}, - {id_S13, - {{WIRE_X(0), PIP_Y(id_S130), WIRE_X(3), PIP_Y(id_S130)}, - {WIRE_X(3), PIP_Y(id_S130), WIRE_X(3), -1. + PIP_Y(id_S131)}, - {WIRE_X(3), -1. + PIP_Y(id_S131), WIRE_X(0), -1. + PIP_Y(id_S131)}}}, - {id_N13, - {{WIRE_X(0), PIP_Y(id_N130), WIRE_X(4), PIP_Y(id_N130)}, - {WIRE_X(4), PIP_Y(id_N130), WIRE_X(4), 1. + PIP_Y(id_N131)}, - {WIRE_X(4), 1. + PIP_Y(id_N131), WIRE_X(0), 1. + PIP_Y(id_N131)}}}, - {id_S13_loop0, - {{WIRE_X(0), PIP_Y(id_S130), WIRE_X(3), PIP_Y(id_S130)}, - {WIRE_X(3), PIP_Y(id_S130), WIRE_X(3), -1. * wrap_len}, - {WIRE_X(3), -1. * wrap_len, WIRE_X(4), -1. * wrap_len}, - {WIRE_X(4), -1. * wrap_len, WIRE_X(4), PIP_Y(id_N131)}, - {WIRE_X(4), PIP_Y(id_N131), WIRE_X(0), PIP_Y(id_N131)}}}, - {id_N13_loop0, - {{WIRE_X(0), PIP_Y(id_N130), WIRE_X(4), PIP_Y(id_N130)}, - {WIRE_X(4), PIP_Y(id_N130), WIRE_X(4), 1. + 1. * wrap_len}, - {WIRE_X(4), 1. + 1. * wrap_len, WIRE_X(3), 1. + 1. * wrap_len}, - {WIRE_X(3), 1. + 1. * wrap_len, WIRE_X(3), PIP_Y(id_S131)}, - {WIRE_X(3), PIP_Y(id_S131), WIRE_X(0), PIP_Y(id_S131)}}}, - // 1 hop SN - {id_SN10, - {{WIRE_X(0), PIP_Y(id_SN10), WIRE_X(6), PIP_Y(id_SN10)}, - {WIRE_X(6), PIP_Y(id_SN10), WIRE_X(6), 1. + PIP_Y(id_N111)}, - {WIRE_X(6), 1. + PIP_Y(id_N111), WIRE_X(0), 1. + PIP_Y(id_N111)}, - {WIRE_X(5), PIP_Y(id_SN10), WIRE_X(5), -1. + PIP_Y(id_S111)}, - {WIRE_X(5), -1. + PIP_Y(id_S111), WIRE_X(0), -1. + PIP_Y(id_S111)}}}, - {id_SN10_loop_n, - {{WIRE_X(0), PIP_Y(id_SN10), WIRE_X(6), PIP_Y(id_SN10)}, - {WIRE_X(6), PIP_Y(id_SN10), WIRE_X(6), 1. + 1. * wrap_len}, - {WIRE_X(6), 1. + 1. * wrap_len, WIRE_X(5), 1. + 1. * wrap_len}, - {WIRE_X(5), 1. + 1. * wrap_len, WIRE_X(5), PIP_Y(id_SN10)}, - {WIRE_X(5), PIP_Y(id_SN10), WIRE_X(5), -1. + PIP_Y(id_S111)}, - {WIRE_X(5), -1. + PIP_Y(id_S111), WIRE_X(0), -1. + PIP_Y(id_S111)}}}, - {id_SN10_loop_s, - {{WIRE_X(0), PIP_Y(id_SN10), WIRE_X(6), PIP_Y(id_SN10)}, - {WIRE_X(6), PIP_Y(id_SN10), WIRE_X(6), 1. + PIP_Y(id_N111)}, - {WIRE_X(6), 1. + PIP_Y(id_N111), WIRE_X(0), 1. + PIP_Y(id_N111)}, - {WIRE_X(5), PIP_Y(id_SN10), WIRE_X(5), -1. * wrap_len}, - {WIRE_X(5), -1. * wrap_len, WIRE_X(6), -1. * wrap_len}, - {WIRE_X(6), -1. * wrap_len, WIRE_X(6), PIP_Y(id_N111)}, - {WIRE_X(6), PIP_Y(id_N111), WIRE_X(0), PIP_Y(id_N111)}}}, - {id_SN20, - {{WIRE_X(0), PIP_Y(id_SN20), WIRE_X(8), PIP_Y(id_SN20)}, - {WIRE_X(8), PIP_Y(id_SN20), WIRE_X(8), 1. + PIP_Y(id_N121)}, - {WIRE_X(8), 1. + PIP_Y(id_N121), WIRE_X(0), 1. + PIP_Y(id_N121)}, - {WIRE_X(7), PIP_Y(id_SN20), WIRE_X(7), -1. + PIP_Y(id_S121)}, - {WIRE_X(7), -1. + PIP_Y(id_S121), WIRE_X(0), -1. + PIP_Y(id_S121)}}}, - {id_SN20_loop_n, - {{WIRE_X(0), PIP_Y(id_SN20), WIRE_X(8), PIP_Y(id_SN20)}, - {WIRE_X(8), PIP_Y(id_SN20), WIRE_X(8), 1. + 1. * wrap_len}, - {WIRE_X(8), 1. + 1. * wrap_len, WIRE_X(7), 1. + 1. * wrap_len}, - {WIRE_X(7), 1. + 1. * wrap_len, WIRE_X(7), PIP_Y(id_SN10)}, - {WIRE_X(7), PIP_Y(id_SN20), WIRE_X(7), -1. + PIP_Y(id_S121)}, - {WIRE_X(7), -1. + PIP_Y(id_S121), WIRE_X(0), -1. + PIP_Y(id_S121)}}}, - {id_SN20_loop_s, - {{WIRE_X(0), PIP_Y(id_SN20), WIRE_X(8), PIP_Y(id_SN20)}, - {WIRE_X(8), PIP_Y(id_SN20), WIRE_X(8), 1. + PIP_Y(id_N121)}, - {WIRE_X(8), 1. + PIP_Y(id_N121), WIRE_X(0), 1. + PIP_Y(id_N121)}, - {WIRE_X(7), PIP_Y(id_SN20), WIRE_X(7), -1. * wrap_len}, - {WIRE_X(7), -1. * wrap_len, WIRE_X(8), -1. * wrap_len}, - {WIRE_X(8), -1. * wrap_len, WIRE_X(8), PIP_Y(id_N121)}, - {WIRE_X(8), PIP_Y(id_N121), WIRE_X(0), PIP_Y(id_N121)}}}, - // 2 hop - {id_S20, - {{WIRE_X(0), PIP_Y(id_S200), WIRE_X(11), PIP_Y(id_S200)}, - {WIRE_X(11), PIP_Y(id_S200), WIRE_X(11), -1. + PIP_Y(id_S201)}, - {WIRE_X(11), -1. + PIP_Y(id_S201), WIRE_X(0), -1. + PIP_Y(id_S201)}, - {WIRE_X(9), -1. + PIP_Y(id_S201), WIRE_X(9), -2. + PIP_Y(id_S202)}, - {WIRE_X(9), -2. + PIP_Y(id_S202), WIRE_X(0), -2. + PIP_Y(id_S202)}}}, - {id_N20, - {{WIRE_X(0), PIP_Y(id_N200), WIRE_X(12), PIP_Y(id_N200)}, - {WIRE_X(12), PIP_Y(id_N200), WIRE_X(12), 1. + PIP_Y(id_N201)}, - {WIRE_X(12), 1. + PIP_Y(id_N201), WIRE_X(0), 1. + PIP_Y(id_N201)}, - {WIRE_X(10), 1. + PIP_Y(id_N201), WIRE_X(10), 2. + PIP_Y(id_N202)}, - {WIRE_X(10), 2. + PIP_Y(id_N202), WIRE_X(0), 2. + PIP_Y(id_N202)}}}, - {id_S20_loop0, - {{WIRE_X(0), PIP_Y(id_S200), WIRE_X(11), PIP_Y(id_S200)}, - {WIRE_X(11), PIP_Y(id_S200), WIRE_X(11), -1. * wrap_len}, - {WIRE_X(11), -1. * wrap_len, WIRE_X(12), -1. * wrap_len}, - {WIRE_X(12), -1. * wrap_len, WIRE_X(12), PIP_Y(id_N201)}, - {WIRE_X(12), PIP_Y(id_N201), WIRE_X(0), PIP_Y(id_N201)}, - {WIRE_X(10), PIP_Y(id_N201), WIRE_X(10), 1. + PIP_Y(id_N202)}, - {WIRE_X(10), 1. + PIP_Y(id_N202), WIRE_X(0), 1. + PIP_Y(id_N202)}}}, - {id_N20_loop0, - {{WIRE_X(0), PIP_Y(id_N200), WIRE_X(12), PIP_Y(id_N200)}, - {WIRE_X(12), PIP_Y(id_N200), WIRE_X(12), 1. + 1. * wrap_len}, - {WIRE_X(12), 1. + 1. * wrap_len, WIRE_X(11), 1. + 1. * wrap_len}, - {WIRE_X(11), 1. + 1. * wrap_len, WIRE_X(11), PIP_Y(id_S201)}, - {WIRE_X(11), PIP_Y(id_S201), WIRE_X(0), PIP_Y(id_S201)}, - {WIRE_X(9), PIP_Y(id_S201), WIRE_X(9), -1. + PIP_Y(id_S202)}, - {WIRE_X(9), -1. + PIP_Y(id_S202), WIRE_X(0), -1. + PIP_Y(id_S202)}}}, - {id_S20_loop1, - {{WIRE_X(0), PIP_Y(id_S200), WIRE_X(11), PIP_Y(id_S200)}, - {WIRE_X(11), PIP_Y(id_S200), WIRE_X(11), -1. + PIP_Y(id_S201)}, - {WIRE_X(11), -1. + PIP_Y(id_S201), WIRE_X(0), -1. + PIP_Y(id_S201)}, - {WIRE_X(9), -1. + PIP_Y(id_S201), WIRE_X(9), -1. + -1. * wrap_len}, - {WIRE_X(9), -1. + -1. * wrap_len, WIRE_X(10), -1. + -1. * wrap_len}, - {WIRE_X(10), -1. + -1. * wrap_len, WIRE_X(10), -1. + PIP_Y(id_N202)}, - {WIRE_X(10), -1. + PIP_Y(id_N202), WIRE_X(0), -1. + PIP_Y(id_N202)}}}, - {id_N20_loop1, - {{WIRE_X(0), PIP_Y(id_N200), WIRE_X(12), PIP_Y(id_N200)}, - {WIRE_X(12), PIP_Y(id_N200), WIRE_X(12), 1. + PIP_Y(id_N201)}, - {WIRE_X(12), 1. + PIP_Y(id_N201), WIRE_X(0), 1. + PIP_Y(id_N201)}, - {WIRE_X(10), 1. + PIP_Y(id_N201), WIRE_X(10), 2. + 1. * wrap_len}, - {WIRE_X(10), 2. + 1. * wrap_len, WIRE_X(9), 2. + 1. * wrap_len}, - {WIRE_X(9), 2. + 1. * wrap_len, WIRE_X(9), 1. + PIP_Y(id_S202)}, - {WIRE_X(9), 1. + PIP_Y(id_S202), WIRE_X(0), 1. + PIP_Y(id_S202)}}}, - {id_S21, - {{WIRE_X(0), PIP_Y(id_S210), WIRE_X(15), PIP_Y(id_S210)}, - {WIRE_X(15), PIP_Y(id_S210), WIRE_X(15), -1. + PIP_Y(id_S211)}, - {WIRE_X(15), -1. + PIP_Y(id_S211), WIRE_X(0), -1. + PIP_Y(id_S211)}, - {WIRE_X(13), -1. + PIP_Y(id_S211), WIRE_X(13), -2. + PIP_Y(id_S212)}, - {WIRE_X(13), -2. + PIP_Y(id_S212), WIRE_X(0), -2. + PIP_Y(id_S212)}}}, - {id_N21, - {{WIRE_X(0), PIP_Y(id_N210), WIRE_X(16), PIP_Y(id_N210)}, - {WIRE_X(16), PIP_Y(id_N210), WIRE_X(16), 1. + PIP_Y(id_N211)}, - {WIRE_X(16), 1. + PIP_Y(id_N211), WIRE_X(0), 1. + PIP_Y(id_N211)}, - {WIRE_X(14), 1. + PIP_Y(id_N211), WIRE_X(14), 2. + PIP_Y(id_N212)}, - {WIRE_X(14), 2. + PIP_Y(id_N212), WIRE_X(0), 2. + PIP_Y(id_N212)}}}, - {id_S21_loop0, - {{WIRE_X(0), PIP_Y(id_S210), WIRE_X(15), PIP_Y(id_S210)}, - {WIRE_X(15), PIP_Y(id_S210), WIRE_X(15), -1. * wrap_len}, - {WIRE_X(15), -1. * wrap_len, WIRE_X(16), -1. * wrap_len}, - {WIRE_X(16), -1. * wrap_len, WIRE_X(16), PIP_Y(id_N211)}, - {WIRE_X(16), PIP_Y(id_N211), WIRE_X(0), PIP_Y(id_N211)}, - {WIRE_X(14), PIP_Y(id_N211), WIRE_X(14), 1. + PIP_Y(id_N212)}, - {WIRE_X(14), 1. + PIP_Y(id_N212), WIRE_X(0), 1. + PIP_Y(id_N212)}}}, - {id_N21_loop0, - {{WIRE_X(0), PIP_Y(id_N210), WIRE_X(16), PIP_Y(id_N210)}, - {WIRE_X(16), PIP_Y(id_N210), WIRE_X(16), 1. + 1. * wrap_len}, - {WIRE_X(16), 1. + 1. * wrap_len, WIRE_X(15), 1. + 1. * wrap_len}, - {WIRE_X(15), 1. + 1. * wrap_len, WIRE_X(15), PIP_Y(id_S211)}, - {WIRE_X(15), PIP_Y(id_S211), WIRE_X(0), PIP_Y(id_S211)}, - {WIRE_X(13), PIP_Y(id_S211), WIRE_X(13), -1. + PIP_Y(id_S212)}, - {WIRE_X(13), -1. + PIP_Y(id_S212), WIRE_X(0), -1. + PIP_Y(id_S212)}}}, - {id_S21_loop1, - {{WIRE_X(0), PIP_Y(id_S210), WIRE_X(15), PIP_Y(id_S210)}, - {WIRE_X(15), PIP_Y(id_S210), WIRE_X(15), -1. + PIP_Y(id_S211)}, - {WIRE_X(15), -1. + PIP_Y(id_S211), WIRE_X(0), -1. + PIP_Y(id_S211)}, - {WIRE_X(13), -1. + PIP_Y(id_S211), WIRE_X(13), -1. + -1. * wrap_len}, - {WIRE_X(13), -1. + -1. * wrap_len, WIRE_X(14), -1. + -1. * wrap_len}, - {WIRE_X(14), -1. + -1. * wrap_len, WIRE_X(14), -1. + PIP_Y(id_N212)}, - {WIRE_X(14), -1. + PIP_Y(id_N212), WIRE_X(0), -1. + PIP_Y(id_N212)}}}, - {id_N21_loop1, - {{WIRE_X(0), PIP_Y(id_N210), WIRE_X(16), PIP_Y(id_N210)}, - {WIRE_X(16), PIP_Y(id_N210), WIRE_X(16), 1. + PIP_Y(id_N211)}, - {WIRE_X(16), 1. + PIP_Y(id_N211), WIRE_X(0), 1. + PIP_Y(id_N211)}, - {WIRE_X(14), 1. + PIP_Y(id_N211), WIRE_X(14), 2. + 1. * wrap_len}, - {WIRE_X(14), 2. + 1. * wrap_len, WIRE_X(13), 2. + 1. * wrap_len}, - {WIRE_X(13), 2. + 1. * wrap_len, WIRE_X(13), 1. + PIP_Y(id_S212)}, - {WIRE_X(13), 1. + PIP_Y(id_S212), WIRE_X(0), 1. + PIP_Y(id_S212)}}}, - {id_S22, - {{WIRE_X(0), PIP_Y(id_S220), WIRE_X(19), PIP_Y(id_S220)}, - {WIRE_X(19), PIP_Y(id_S220), WIRE_X(19), -1. + PIP_Y(id_S221)}, - {WIRE_X(19), -1. + PIP_Y(id_S221), WIRE_X(0), -1. + PIP_Y(id_S221)}, - {WIRE_X(17), -1. + PIP_Y(id_S221), WIRE_X(17), -2. + PIP_Y(id_S222)}, - {WIRE_X(17), -2. + PIP_Y(id_S222), WIRE_X(0), -2. + PIP_Y(id_S222)}}}, - {id_N22, - {{WIRE_X(0), PIP_Y(id_N220), WIRE_X(20), PIP_Y(id_N220)}, - {WIRE_X(20), PIP_Y(id_N220), WIRE_X(20), 1. + PIP_Y(id_N221)}, - {WIRE_X(20), 1. + PIP_Y(id_N221), WIRE_X(0), 1. + PIP_Y(id_N221)}, - {WIRE_X(18), 1. + PIP_Y(id_N221), WIRE_X(18), 2. + PIP_Y(id_N222)}, - {WIRE_X(18), 2. + PIP_Y(id_N222), WIRE_X(0), 2. + PIP_Y(id_N222)}}}, - {id_S22_loop0, - {{WIRE_X(0), PIP_Y(id_S220), WIRE_X(19), PIP_Y(id_S220)}, - {WIRE_X(19), PIP_Y(id_S220), WIRE_X(19), -1. * wrap_len}, - {WIRE_X(19), -1. * wrap_len, WIRE_X(20), -1. * wrap_len}, - {WIRE_X(20), -1. * wrap_len, WIRE_X(20), PIP_Y(id_N221)}, - {WIRE_X(20), PIP_Y(id_N221), WIRE_X(0), PIP_Y(id_N221)}, - {WIRE_X(18), PIP_Y(id_N221), WIRE_X(18), 1. + PIP_Y(id_N222)}, - {WIRE_X(18), 1. + PIP_Y(id_N222), WIRE_X(0), 1. + PIP_Y(id_N222)}}}, - {id_N22_loop0, - {{WIRE_X(0), PIP_Y(id_N220), WIRE_X(20), PIP_Y(id_N220)}, - {WIRE_X(20), PIP_Y(id_N220), WIRE_X(20), 1. + 1. * wrap_len}, - {WIRE_X(20), 1. + 1. * wrap_len, WIRE_X(19), 1. + 1. * wrap_len}, - {WIRE_X(19), 1. + 1. * wrap_len, WIRE_X(19), PIP_Y(id_S221)}, - {WIRE_X(19), PIP_Y(id_S221), WIRE_X(0), PIP_Y(id_S221)}, - {WIRE_X(17), PIP_Y(id_S221), WIRE_X(17), -1. + PIP_Y(id_S222)}, - {WIRE_X(17), -1. + PIP_Y(id_S222), WIRE_X(0), -1. + PIP_Y(id_S222)}}}, - {id_S22_loop1, - {{WIRE_X(0), PIP_Y(id_S220), WIRE_X(19), PIP_Y(id_S220)}, - {WIRE_X(19), PIP_Y(id_S220), WIRE_X(19), -1. + PIP_Y(id_S221)}, - {WIRE_X(19), -1. + PIP_Y(id_S221), WIRE_X(0), -1. + PIP_Y(id_S221)}, - {WIRE_X(17), -1. + PIP_Y(id_S221), WIRE_X(17), -1. + -1. * wrap_len}, - {WIRE_X(17), -1. + -1. * wrap_len, WIRE_X(18), -1. + -1. * wrap_len}, - {WIRE_X(18), -1. + -1. * wrap_len, WIRE_X(18), -1. + PIP_Y(id_N222)}, - {WIRE_X(18), -1. + PIP_Y(id_N222), WIRE_X(0), -1. + PIP_Y(id_N222)}}}, - {id_N22_loop1, - {{WIRE_X(0), PIP_Y(id_N220), WIRE_X(20), PIP_Y(id_N220)}, - {WIRE_X(20), PIP_Y(id_N220), WIRE_X(20), 1. + PIP_Y(id_N221)}, - {WIRE_X(20), 1. + PIP_Y(id_N221), WIRE_X(0), 1. + PIP_Y(id_N221)}, - {WIRE_X(18), 1. + PIP_Y(id_N221), WIRE_X(18), 2. + 1. * wrap_len}, - {WIRE_X(18), 2. + 1. * wrap_len, WIRE_X(17), 2. + 1. * wrap_len}, - {WIRE_X(17), 2. + 1. * wrap_len, WIRE_X(17), 1. + PIP_Y(id_S222)}, - {WIRE_X(17), 1. + PIP_Y(id_S222), WIRE_X(0), 1. + PIP_Y(id_S222)}}}, - {id_S23, - {{WIRE_X(0), PIP_Y(id_S230), WIRE_X(23), PIP_Y(id_S230)}, - {WIRE_X(23), PIP_Y(id_S230), WIRE_X(23), -1. + PIP_Y(id_S231)}, - {WIRE_X(23), -1. + PIP_Y(id_S231), WIRE_X(0), -1. + PIP_Y(id_S231)}, - {WIRE_X(21), -1. + PIP_Y(id_S231), WIRE_X(21), -2. + PIP_Y(id_S232)}, - {WIRE_X(21), -2. + PIP_Y(id_S232), WIRE_X(0), -2. + PIP_Y(id_S232)}}}, - {id_N23, - {{WIRE_X(0), PIP_Y(id_N230), WIRE_X(24), PIP_Y(id_N230)}, - {WIRE_X(24), PIP_Y(id_N230), WIRE_X(24), 1. + PIP_Y(id_N231)}, - {WIRE_X(24), 1. + PIP_Y(id_N231), WIRE_X(0), 1. + PIP_Y(id_N231)}, - {WIRE_X(22), 1. + PIP_Y(id_N231), WIRE_X(22), 2. + PIP_Y(id_N232)}, - {WIRE_X(22), 2. + PIP_Y(id_N232), WIRE_X(0), 2. + PIP_Y(id_N232)}}}, - {id_S23_loop0, - {{WIRE_X(0), PIP_Y(id_S230), WIRE_X(23), PIP_Y(id_S230)}, - {WIRE_X(23), PIP_Y(id_S230), WIRE_X(23), -1. * wrap_len}, - {WIRE_X(23), -1. * wrap_len, WIRE_X(24), -1. * wrap_len}, - {WIRE_X(24), -1. * wrap_len, WIRE_X(24), PIP_Y(id_N231)}, - {WIRE_X(24), PIP_Y(id_N231), WIRE_X(0), PIP_Y(id_N231)}, - {WIRE_X(22), PIP_Y(id_N231), WIRE_X(22), 1. + PIP_Y(id_N232)}, - {WIRE_X(22), 1. + PIP_Y(id_N232), WIRE_X(0), 1. + PIP_Y(id_N232)}}}, - {id_N23_loop0, - {{WIRE_X(0), PIP_Y(id_N230), WIRE_X(24), PIP_Y(id_N230)}, - {WIRE_X(24), PIP_Y(id_N230), WIRE_X(24), 1. + 1. * wrap_len}, - {WIRE_X(24), 1. + 1. * wrap_len, WIRE_X(23), 1. + 1. * wrap_len}, - {WIRE_X(23), 1. + 1. * wrap_len, WIRE_X(23), PIP_Y(id_S231)}, - {WIRE_X(23), PIP_Y(id_S231), WIRE_X(0), PIP_Y(id_S231)}, - {WIRE_X(21), PIP_Y(id_S231), WIRE_X(21), -1. + PIP_Y(id_S232)}, - {WIRE_X(21), -1. + PIP_Y(id_S232), WIRE_X(0), -1. + PIP_Y(id_S232)}}}, - {id_S23_loop1, - {{WIRE_X(0), PIP_Y(id_S230), WIRE_X(23), PIP_Y(id_S230)}, - {WIRE_X(23), PIP_Y(id_S230), WIRE_X(23), -1. + PIP_Y(id_S231)}, - {WIRE_X(23), -1. + PIP_Y(id_S231), WIRE_X(0), -1. + PIP_Y(id_S231)}, - {WIRE_X(21), -1. + PIP_Y(id_S231), WIRE_X(21), -1. + -1. * wrap_len}, - {WIRE_X(21), -1. + -1. * wrap_len, WIRE_X(22), -1. + -1. * wrap_len}, - {WIRE_X(22), -1. + -1. * wrap_len, WIRE_X(22), -1. + PIP_Y(id_N232)}, - {WIRE_X(22), -1. + PIP_Y(id_N232), WIRE_X(0), -1. + PIP_Y(id_N232)}}}, - {id_N23_loop1, - {{WIRE_X(0), PIP_Y(id_N230), WIRE_X(24), PIP_Y(id_N230)}, - {WIRE_X(24), PIP_Y(id_N230), WIRE_X(24), 1. + PIP_Y(id_N231)}, - {WIRE_X(24), 1. + PIP_Y(id_N231), WIRE_X(0), 1. + PIP_Y(id_N231)}, - {WIRE_X(22), 1. + PIP_Y(id_N231), WIRE_X(22), 2. + 1. * wrap_len}, - {WIRE_X(22), 2. + 1. * wrap_len, WIRE_X(21), 2. + 1. * wrap_len}, - {WIRE_X(21), 2. + 1. * wrap_len, WIRE_X(21), 1. + PIP_Y(id_S232)}, - {WIRE_X(21), 1. + PIP_Y(id_S232), WIRE_X(0), 1. + PIP_Y(id_S232)}}}, - {id_S24, - {{WIRE_X(0), PIP_Y(id_S240), WIRE_X(27), PIP_Y(id_S240)}, - {WIRE_X(27), PIP_Y(id_S240), WIRE_X(27), -1. + PIP_Y(id_S241)}, - {WIRE_X(27), -1. + PIP_Y(id_S241), WIRE_X(0), -1. + PIP_Y(id_S241)}, - {WIRE_X(25), -1. + PIP_Y(id_S241), WIRE_X(25), -2. + PIP_Y(id_S242)}, - {WIRE_X(25), -2. + PIP_Y(id_S242), WIRE_X(0), -2. + PIP_Y(id_S242)}}}, - {id_N24, - {{WIRE_X(0), PIP_Y(id_N240), WIRE_X(28), PIP_Y(id_N240)}, - {WIRE_X(28), PIP_Y(id_N240), WIRE_X(28), 1. + PIP_Y(id_N241)}, - {WIRE_X(28), 1. + PIP_Y(id_N241), WIRE_X(0), 1. + PIP_Y(id_N241)}, - {WIRE_X(26), 1. + PIP_Y(id_N241), WIRE_X(26), 2. + PIP_Y(id_N242)}, - {WIRE_X(26), 2. + PIP_Y(id_N242), WIRE_X(0), 2. + PIP_Y(id_N242)}}}, - {id_S24_loop0, - {{WIRE_X(0), PIP_Y(id_S240), WIRE_X(27), PIP_Y(id_S240)}, - {WIRE_X(27), PIP_Y(id_S240), WIRE_X(27), -1. * wrap_len}, - {WIRE_X(27), -1. * wrap_len, WIRE_X(28), -1. * wrap_len}, - {WIRE_X(28), -1. * wrap_len, WIRE_X(28), PIP_Y(id_N241)}, - {WIRE_X(28), PIP_Y(id_N241), WIRE_X(0), PIP_Y(id_N241)}, - {WIRE_X(26), PIP_Y(id_N241), WIRE_X(26), 1. + PIP_Y(id_N242)}, - {WIRE_X(26), 1. + PIP_Y(id_N242), WIRE_X(0), 1. + PIP_Y(id_N242)}}}, - {id_N24_loop0, - {{WIRE_X(0), PIP_Y(id_N240), WIRE_X(28), PIP_Y(id_N240)}, - {WIRE_X(28), PIP_Y(id_N240), WIRE_X(28), 1. + 1. * wrap_len}, - {WIRE_X(28), 1. + 1. * wrap_len, WIRE_X(27), 1. + 1. * wrap_len}, - {WIRE_X(27), 1. + 1. * wrap_len, WIRE_X(27), PIP_Y(id_S241)}, - {WIRE_X(27), PIP_Y(id_S241), WIRE_X(0), PIP_Y(id_S241)}, - {WIRE_X(25), PIP_Y(id_S241), WIRE_X(25), -1. + PIP_Y(id_S242)}, - {WIRE_X(25), -1. + PIP_Y(id_S242), WIRE_X(0), -1. + PIP_Y(id_S242)}}}, - {id_S24_loop1, - {{WIRE_X(0), PIP_Y(id_S240), WIRE_X(27), PIP_Y(id_S240)}, - {WIRE_X(27), PIP_Y(id_S240), WIRE_X(27), -1. + PIP_Y(id_S241)}, - {WIRE_X(27), -1. + PIP_Y(id_S241), WIRE_X(0), -1. + PIP_Y(id_S241)}, - {WIRE_X(25), -1. + PIP_Y(id_S241), WIRE_X(25), -1. + -1. * wrap_len}, - {WIRE_X(25), -1. + -1. * wrap_len, WIRE_X(26), -1. + -1. * wrap_len}, - {WIRE_X(26), -1. + -1. * wrap_len, WIRE_X(26), -1. + PIP_Y(id_N242)}, - {WIRE_X(26), -1. + PIP_Y(id_N242), WIRE_X(0), -1. + PIP_Y(id_N242)}}}, - {id_N24_loop1, - {{WIRE_X(0), PIP_Y(id_N240), WIRE_X(28), PIP_Y(id_N240)}, - {WIRE_X(28), PIP_Y(id_N240), WIRE_X(28), 1. + PIP_Y(id_N241)}, - {WIRE_X(28), 1. + PIP_Y(id_N241), WIRE_X(0), 1. + PIP_Y(id_N241)}, - {WIRE_X(26), 1. + PIP_Y(id_N241), WIRE_X(26), 2. + 1. * wrap_len}, - {WIRE_X(26), 2. + 1. * wrap_len, WIRE_X(25), 2. + 1. * wrap_len}, - {WIRE_X(25), 2. + 1. * wrap_len, WIRE_X(25), 1. + PIP_Y(id_S242)}, - {WIRE_X(25), 1. + PIP_Y(id_S242), WIRE_X(0), 1. + PIP_Y(id_S242)}}}, - {id_S25, - {{WIRE_X(0), PIP_Y(id_S250), WIRE_X(31), PIP_Y(id_S250)}, - {WIRE_X(31), PIP_Y(id_S250), WIRE_X(31), -1. + PIP_Y(id_S251)}, - {WIRE_X(31), -1. + PIP_Y(id_S251), WIRE_X(0), -1. + PIP_Y(id_S251)}, - {WIRE_X(29), -1. + PIP_Y(id_S251), WIRE_X(29), -2. + PIP_Y(id_S252)}, - {WIRE_X(29), -2. + PIP_Y(id_S252), WIRE_X(0), -2. + PIP_Y(id_S252)}}}, - {id_N25, - {{WIRE_X(0), PIP_Y(id_N250), WIRE_X(32), PIP_Y(id_N250)}, - {WIRE_X(32), PIP_Y(id_N250), WIRE_X(32), 1. + PIP_Y(id_N251)}, - {WIRE_X(32), 1. + PIP_Y(id_N251), WIRE_X(0), 1. + PIP_Y(id_N251)}, - {WIRE_X(30), 1. + PIP_Y(id_N251), WIRE_X(30), 2. + PIP_Y(id_N252)}, - {WIRE_X(30), 2. + PIP_Y(id_N252), WIRE_X(0), 2. + PIP_Y(id_N252)}}}, - {id_S25_loop0, - {{WIRE_X(0), PIP_Y(id_S250), WIRE_X(31), PIP_Y(id_S250)}, - {WIRE_X(31), PIP_Y(id_S250), WIRE_X(31), -1. * wrap_len}, - {WIRE_X(31), -1. * wrap_len, WIRE_X(32), -1. * wrap_len}, - {WIRE_X(32), -1. * wrap_len, WIRE_X(32), PIP_Y(id_N251)}, - {WIRE_X(32), PIP_Y(id_N251), WIRE_X(0), PIP_Y(id_N251)}, - {WIRE_X(30), PIP_Y(id_N251), WIRE_X(30), 1. + PIP_Y(id_N252)}, - {WIRE_X(30), 1. + PIP_Y(id_N252), WIRE_X(0), 1. + PIP_Y(id_N252)}}}, - {id_N25_loop0, - {{WIRE_X(0), PIP_Y(id_N250), WIRE_X(32), PIP_Y(id_N250)}, - {WIRE_X(32), PIP_Y(id_N250), WIRE_X(32), 1. + 1. * wrap_len}, - {WIRE_X(32), 1. + 1. * wrap_len, WIRE_X(31), 1. + 1. * wrap_len}, - {WIRE_X(31), 1. + 1. * wrap_len, WIRE_X(31), PIP_Y(id_S251)}, - {WIRE_X(31), PIP_Y(id_S251), WIRE_X(0), PIP_Y(id_S251)}, - {WIRE_X(29), PIP_Y(id_S251), WIRE_X(29), -1. + PIP_Y(id_S252)}, - {WIRE_X(29), -1. + PIP_Y(id_S252), WIRE_X(0), -1. + PIP_Y(id_S252)}}}, - {id_S25_loop1, - {{WIRE_X(0), PIP_Y(id_S250), WIRE_X(31), PIP_Y(id_S250)}, - {WIRE_X(31), PIP_Y(id_S250), WIRE_X(31), -1. + PIP_Y(id_S251)}, - {WIRE_X(31), -1. + PIP_Y(id_S251), WIRE_X(0), -1. + PIP_Y(id_S251)}, - {WIRE_X(29), -1. + PIP_Y(id_S251), WIRE_X(29), -1. + -1. * wrap_len}, - {WIRE_X(29), -1. + -1. * wrap_len, WIRE_X(30), -1. + -1. * wrap_len}, - {WIRE_X(30), -1. + -1. * wrap_len, WIRE_X(30), -1. + PIP_Y(id_N252)}, - {WIRE_X(30), -1. + PIP_Y(id_N252), WIRE_X(0), -1. + PIP_Y(id_N252)}}}, - {id_N25_loop1, - {{WIRE_X(0), PIP_Y(id_N250), WIRE_X(32), PIP_Y(id_N250)}, - {WIRE_X(32), PIP_Y(id_N250), WIRE_X(32), 1. + PIP_Y(id_N251)}, - {WIRE_X(32), 1. + PIP_Y(id_N251), WIRE_X(0), 1. + PIP_Y(id_N251)}, - {WIRE_X(30), 1. + PIP_Y(id_N251), WIRE_X(30), 2. + 1. * wrap_len}, - {WIRE_X(30), 2. + 1. * wrap_len, WIRE_X(29), 2. + 1. * wrap_len}, - {WIRE_X(29), 2. + 1. * wrap_len, WIRE_X(29), 1. + PIP_Y(id_S252)}, - {WIRE_X(29), 1. + PIP_Y(id_S252), WIRE_X(0), 1. + PIP_Y(id_S252)}}}, - {id_S26, - {{WIRE_X(0), PIP_Y(id_S260), WIRE_X(35), PIP_Y(id_S260)}, - {WIRE_X(35), PIP_Y(id_S260), WIRE_X(35), -1. + PIP_Y(id_S261)}, - {WIRE_X(35), -1. + PIP_Y(id_S261), WIRE_X(0), -1. + PIP_Y(id_S261)}, - {WIRE_X(33), -1. + PIP_Y(id_S261), WIRE_X(33), -2. + PIP_Y(id_S262)}, - {WIRE_X(33), -2. + PIP_Y(id_S262), WIRE_X(0), -2. + PIP_Y(id_S262)}}}, - {id_N26, - {{WIRE_X(0), PIP_Y(id_N260), WIRE_X(36), PIP_Y(id_N260)}, - {WIRE_X(36), PIP_Y(id_N260), WIRE_X(36), 1. + PIP_Y(id_N261)}, - {WIRE_X(36), 1. + PIP_Y(id_N261), WIRE_X(0), 1. + PIP_Y(id_N261)}, - {WIRE_X(34), 1. + PIP_Y(id_N261), WIRE_X(34), 2. + PIP_Y(id_N262)}, - {WIRE_X(34), 2. + PIP_Y(id_N262), WIRE_X(0), 2. + PIP_Y(id_N262)}}}, - {id_S26_loop0, - {{WIRE_X(0), PIP_Y(id_S260), WIRE_X(35), PIP_Y(id_S260)}, - {WIRE_X(35), PIP_Y(id_S260), WIRE_X(35), -1. * wrap_len}, - {WIRE_X(35), -1. * wrap_len, WIRE_X(36), -1. * wrap_len}, - {WIRE_X(36), -1. * wrap_len, WIRE_X(36), PIP_Y(id_N261)}, - {WIRE_X(36), PIP_Y(id_N261), WIRE_X(0), PIP_Y(id_N261)}, - {WIRE_X(34), PIP_Y(id_N261), WIRE_X(34), 1. + PIP_Y(id_N262)}, - {WIRE_X(34), 1. + PIP_Y(id_N262), WIRE_X(0), 1. + PIP_Y(id_N262)}}}, - {id_N26_loop0, - {{WIRE_X(0), PIP_Y(id_N260), WIRE_X(36), PIP_Y(id_N260)}, - {WIRE_X(36), PIP_Y(id_N260), WIRE_X(36), 1. + 1. * wrap_len}, - {WIRE_X(36), 1. + 1. * wrap_len, WIRE_X(35), 1. + 1. * wrap_len}, - {WIRE_X(35), 1. + 1. * wrap_len, WIRE_X(35), PIP_Y(id_S261)}, - {WIRE_X(35), PIP_Y(id_S261), WIRE_X(0), PIP_Y(id_S261)}, - {WIRE_X(33), PIP_Y(id_S261), WIRE_X(33), -1. + PIP_Y(id_S262)}, - {WIRE_X(33), -1. + PIP_Y(id_S262), WIRE_X(0), -1. + PIP_Y(id_S262)}}}, - {id_S26_loop1, - {{WIRE_X(0), PIP_Y(id_S260), WIRE_X(35), PIP_Y(id_S260)}, - {WIRE_X(35), PIP_Y(id_S260), WIRE_X(35), -1. + PIP_Y(id_S261)}, - {WIRE_X(35), -1. + PIP_Y(id_S261), WIRE_X(0), -1. + PIP_Y(id_S261)}, - {WIRE_X(33), -1. + PIP_Y(id_S261), WIRE_X(33), -1. + -1. * wrap_len}, - {WIRE_X(33), -1. + -1. * wrap_len, WIRE_X(34), -1. + -1. * wrap_len}, - {WIRE_X(34), -1. + -1. * wrap_len, WIRE_X(34), -1. + PIP_Y(id_N262)}, - {WIRE_X(34), -1. + PIP_Y(id_N262), WIRE_X(0), -1. + PIP_Y(id_N262)}}}, - {id_N26_loop1, - {{WIRE_X(0), PIP_Y(id_N260), WIRE_X(36), PIP_Y(id_N260)}, - {WIRE_X(36), PIP_Y(id_N260), WIRE_X(36), 1. + PIP_Y(id_N261)}, - {WIRE_X(36), 1. + PIP_Y(id_N261), WIRE_X(0), 1. + PIP_Y(id_N261)}, - {WIRE_X(34), 1. + PIP_Y(id_N261), WIRE_X(34), 2. + 1. * wrap_len}, - {WIRE_X(34), 2. + 1. * wrap_len, WIRE_X(33), 2. + 1. * wrap_len}, - {WIRE_X(33), 2. + 1. * wrap_len, WIRE_X(33), 1. + PIP_Y(id_S262)}, - {WIRE_X(33), 1. + PIP_Y(id_S262), WIRE_X(0), 1. + PIP_Y(id_S262)}}}, - {id_S27, - {{WIRE_X(0), PIP_Y(id_S270), WIRE_X(39), PIP_Y(id_S270)}, - {WIRE_X(39), PIP_Y(id_S270), WIRE_X(39), -1. + PIP_Y(id_S271)}, - {WIRE_X(39), -1. + PIP_Y(id_S271), WIRE_X(0), -1. + PIP_Y(id_S271)}, - {WIRE_X(37), -1. + PIP_Y(id_S271), WIRE_X(37), -2. + PIP_Y(id_S272)}, - {WIRE_X(37), -2. + PIP_Y(id_S272), WIRE_X(0), -2. + PIP_Y(id_S272)}}}, - {id_N27, - {{WIRE_X(0), PIP_Y(id_N270), WIRE_X(40), PIP_Y(id_N270)}, - {WIRE_X(40), PIP_Y(id_N270), WIRE_X(40), 1. + PIP_Y(id_N271)}, - {WIRE_X(40), 1. + PIP_Y(id_N271), WIRE_X(0), 1. + PIP_Y(id_N271)}, - {WIRE_X(38), 1. + PIP_Y(id_N271), WIRE_X(38), 2. + PIP_Y(id_N272)}, - {WIRE_X(38), 2. + PIP_Y(id_N272), WIRE_X(0), 2. + PIP_Y(id_N272)}}}, - {id_S27_loop0, - {{WIRE_X(0), PIP_Y(id_S270), WIRE_X(39), PIP_Y(id_S270)}, - {WIRE_X(39), PIP_Y(id_S270), WIRE_X(39), -1. * wrap_len}, - {WIRE_X(39), -1. * wrap_len, WIRE_X(40), -1. * wrap_len}, - {WIRE_X(40), -1. * wrap_len, WIRE_X(40), PIP_Y(id_N271)}, - {WIRE_X(40), PIP_Y(id_N271), WIRE_X(0), PIP_Y(id_N271)}, - {WIRE_X(38), PIP_Y(id_N271), WIRE_X(38), 1. + PIP_Y(id_N272)}, - {WIRE_X(38), 1. + PIP_Y(id_N272), WIRE_X(0), 1. + PIP_Y(id_N272)}}}, - {id_N27_loop0, - {{WIRE_X(0), PIP_Y(id_N270), WIRE_X(40), PIP_Y(id_N270)}, - {WIRE_X(40), PIP_Y(id_N270), WIRE_X(40), 1. + 1. * wrap_len}, - {WIRE_X(40), 1. + 1. * wrap_len, WIRE_X(39), 1. + 1. * wrap_len}, - {WIRE_X(39), 1. + 1. * wrap_len, WIRE_X(39), PIP_Y(id_S271)}, - {WIRE_X(39), PIP_Y(id_S271), WIRE_X(0), PIP_Y(id_S271)}, - {WIRE_X(37), PIP_Y(id_S271), WIRE_X(37), -1. + PIP_Y(id_S272)}, - {WIRE_X(37), -1. + PIP_Y(id_S272), WIRE_X(0), -1. + PIP_Y(id_S272)}}}, - {id_S27_loop1, - {{WIRE_X(0), PIP_Y(id_S270), WIRE_X(39), PIP_Y(id_S270)}, - {WIRE_X(39), PIP_Y(id_S270), WIRE_X(39), -1. + PIP_Y(id_S271)}, - {WIRE_X(39), -1. + PIP_Y(id_S271), WIRE_X(0), -1. + PIP_Y(id_S271)}, - {WIRE_X(37), -1. + PIP_Y(id_S271), WIRE_X(37), -1. + -1. * wrap_len}, - {WIRE_X(37), -1. + -1. * wrap_len, WIRE_X(38), -1. + -1. * wrap_len}, - {WIRE_X(38), -1. + -1. * wrap_len, WIRE_X(38), -1. + PIP_Y(id_N272)}, - {WIRE_X(38), -1. + PIP_Y(id_N272), WIRE_X(0), -1. + PIP_Y(id_N272)}}}, - {id_N27_loop1, - {{WIRE_X(0), PIP_Y(id_N270), WIRE_X(40), PIP_Y(id_N270)}, - {WIRE_X(40), PIP_Y(id_N270), WIRE_X(40), 1. + PIP_Y(id_N271)}, - {WIRE_X(40), 1. + PIP_Y(id_N271), WIRE_X(0), 1. + PIP_Y(id_N271)}, - {WIRE_X(38), 1. + PIP_Y(id_N271), WIRE_X(38), 2. + 1. * wrap_len}, - {WIRE_X(38), 2. + 1. * wrap_len, WIRE_X(37), 2. + 1. * wrap_len}, - {WIRE_X(37), 2. + 1. * wrap_len, WIRE_X(37), 1. + PIP_Y(id_S272)}, - {WIRE_X(37), 1. + PIP_Y(id_S272), WIRE_X(0), 1. + PIP_Y(id_S272)}}}, -// clock taps -#define CLK_GT00_X 41.f -#define CLK_GT10_X 46.f -// 4 hop -#define HOP4X_START (CLK_GT00_X + 10.f) -#define HOP4X(offset) WIRE_X((float)offset + HOP4X_START) - {id_S80, - {{WIRE_X(0), PIP_Y(id_S800), HOP4X(16), PIP_Y(id_S800)}, - {HOP4X(16), PIP_Y(id_S800), HOP4X(16), PIP_Y(id_N808)}, - {HOP4X(16), PIP_Y(id_N808) - 0., HOP4X(14), PIP_Y(id_N808) - left_wire_dist - 0.}, - {HOP4X(14), PIP_Y(id_N808) - left_wire_dist - 0., HOP4X(14), PIP_Y(id_N808) - 1.}, - {HOP4X(14), PIP_Y(id_N808) - 1., HOP4X(12), PIP_Y(id_N808) - left_wire_dist - 1.}, - {HOP4X(12), PIP_Y(id_N808) - left_wire_dist - 1., HOP4X(12), PIP_Y(id_N808) - 2.}, - {HOP4X(12), PIP_Y(id_N808) - 2., HOP4X(10), PIP_Y(id_N808) - left_wire_dist - 2.}, - {HOP4X(10), PIP_Y(id_N808) - left_wire_dist - 2., HOP4X(10), PIP_Y(id_N808) - 3.}, - {HOP4X(10), PIP_Y(id_N808) - 3., HOP4X(8), PIP_Y(id_N808) - left_wire_dist - 3.}, - {HOP4X(8), PIP_Y(id_N808) - left_wire_dist - 3., HOP4X(8), PIP_Y(id_N808) - 4.}, - {HOP4X(8), PIP_Y(id_S804) - 4., WIRE_X(0), PIP_Y(id_S804) - 4.}, - {HOP4X(8), PIP_Y(id_N808) - 4., HOP4X(6), PIP_Y(id_N808) - left_wire_dist - 4.}, - {HOP4X(6), PIP_Y(id_N808) - left_wire_dist - 4., HOP4X(6), PIP_Y(id_N808) - 5.}, - {HOP4X(6), PIP_Y(id_N808) - 5., HOP4X(4), PIP_Y(id_N808) - left_wire_dist - 5.}, - {HOP4X(4), PIP_Y(id_N808) - left_wire_dist - 5., HOP4X(4), PIP_Y(id_N808) - 6.}, - {HOP4X(4), PIP_Y(id_N808) - 6., HOP4X(2), PIP_Y(id_N808) - left_wire_dist - 6.}, - {HOP4X(2), PIP_Y(id_N808) - left_wire_dist - 6., HOP4X(2), PIP_Y(id_N808) - 7.}, - {HOP4X(2), PIP_Y(id_N808) - 7., HOP4X(0), PIP_Y(id_N808) - left_wire_dist - 7.}, - {HOP4X(0), PIP_Y(id_N808) - left_wire_dist - 7., HOP4X(0), PIP_Y(id_S808) - 8.}, - {HOP4X(0), PIP_Y(id_S808) - 8., WIRE_X(0), PIP_Y(id_S808) - 8.}}}, - {id_N80, - {{WIRE_X(0), PIP_Y(id_N800), HOP4X(17), PIP_Y(id_N800)}, - {HOP4X(17), PIP_Y(id_N800) + 0., HOP4X(15), PIP_Y(id_N800) + left_wire_dist + 0.}, - {HOP4X(15), PIP_Y(id_N800) + left_wire_dist + 0., HOP4X(15), PIP_Y(id_N800) + 1.}, - {HOP4X(15), PIP_Y(id_N800) + 1., HOP4X(13), PIP_Y(id_N800) + left_wire_dist + 1.}, - {HOP4X(13), PIP_Y(id_N800) + left_wire_dist + 1., HOP4X(13), PIP_Y(id_N800) + 2.}, - {HOP4X(13), PIP_Y(id_N800) + 2., HOP4X(11), PIP_Y(id_N800) + left_wire_dist + 2.}, - {HOP4X(11), PIP_Y(id_N800) + left_wire_dist + 2., HOP4X(11), PIP_Y(id_N800) + 3.}, - {HOP4X(11), PIP_Y(id_N800) + 3., HOP4X(9), PIP_Y(id_N800) + left_wire_dist + 3.}, - {HOP4X(9), PIP_Y(id_N800) + left_wire_dist + 3., HOP4X(9), PIP_Y(id_N800) + 4.}, - {HOP4X(9), PIP_Y(id_N804) + 4., WIRE_X(0), PIP_Y(id_N804) + 4.}, - {HOP4X(9), PIP_Y(id_N800) + 4., HOP4X(7), PIP_Y(id_N800) + left_wire_dist + 4.}, - {HOP4X(7), PIP_Y(id_N800) + left_wire_dist + 4., HOP4X(7), PIP_Y(id_N800) + 5.}, - {HOP4X(7), PIP_Y(id_N800) + 5., HOP4X(5), PIP_Y(id_N800) + left_wire_dist + 5.}, - {HOP4X(5), PIP_Y(id_N800) + left_wire_dist + 5., HOP4X(5), PIP_Y(id_N800) + 6.}, - {HOP4X(5), PIP_Y(id_N800) + 6., HOP4X(3), PIP_Y(id_N800) + left_wire_dist + 6.}, - {HOP4X(3), PIP_Y(id_N800) + left_wire_dist + 6., HOP4X(3), PIP_Y(id_N800) + 7.}, - {HOP4X(3), PIP_Y(id_N800) + 7., HOP4X(1), PIP_Y(id_N800) + left_wire_dist + 7.}, - {HOP4X(1), PIP_Y(id_N800) + left_wire_dist + 7., HOP4X(1), PIP_Y(id_N808) + 8.}, - {HOP4X(1), PIP_Y(id_N808) + 8., WIRE_X(0), PIP_Y(id_N808) + 8.}}}, - {id_S80_loop0, - {{WIRE_X(0), PIP_Y(id_S800), HOP4X(16), PIP_Y(id_S800)}, - {HOP4X(16), PIP_Y(id_S800), HOP4X(16), PIP_Y(id_N808)}, - {HOP4X(16), PIP_Y(id_N808) - 0., HOP4X(14), PIP_Y(id_N808) - left_wire_dist - 0.}, - {HOP4X(14), PIP_Y(id_N808) - left_wire_dist - 0., HOP4X(14), -wrap_len - 0.}, - {HOP4X(14), -wrap_len - 0., HOP4X(15), -wrap_len - 0.}, - {HOP4X(15), -wrap_len - 0., HOP4X(15), PIP_Y(id_N800) - 0.}, - {HOP4X(15), PIP_Y(id_N800) - 0., HOP4X(13), PIP_Y(id_N800) + left_wire_dist - 0.}, - {HOP4X(13), PIP_Y(id_N800) + left_wire_dist - 0., HOP4X(13), PIP_Y(id_N800) + 1.}, - {HOP4X(13), PIP_Y(id_N800) + 1., HOP4X(11), PIP_Y(id_N800) + left_wire_dist + 1.}, - {HOP4X(11), PIP_Y(id_N800) + left_wire_dist + 1., HOP4X(11), PIP_Y(id_N800) + 2.}, - {HOP4X(11), PIP_Y(id_N800) + 2., HOP4X(9), PIP_Y(id_N800) + left_wire_dist + 2.}, - {HOP4X(9), PIP_Y(id_N800) + left_wire_dist + 2., HOP4X(9), PIP_Y(id_N800) + 3.}, - {HOP4X(9), PIP_Y(id_N800) + 3., HOP4X(7), PIP_Y(id_N800) + left_wire_dist + 3.}, - {HOP4X(9), PIP_Y(id_N804) + 3., WIRE_X(0), PIP_Y(id_N804) + 3.}, - {HOP4X(7), PIP_Y(id_N800) + left_wire_dist + 3., HOP4X(7), PIP_Y(id_N800) + 4.}, - {HOP4X(7), PIP_Y(id_N800) + 4., HOP4X(5), PIP_Y(id_N800) + left_wire_dist + 4.}, - {HOP4X(5), PIP_Y(id_N800) + left_wire_dist + 4., HOP4X(5), PIP_Y(id_N800) + 5.}, - {HOP4X(5), PIP_Y(id_N800) + 5., HOP4X(3), PIP_Y(id_N800) + left_wire_dist + 5.}, - {HOP4X(3), PIP_Y(id_N800) + left_wire_dist + 5., HOP4X(3), PIP_Y(id_N800) + 6.}, - {HOP4X(3), PIP_Y(id_N800) + 6., HOP4X(1), PIP_Y(id_N800) + left_wire_dist + 6.}, - {HOP4X(1), PIP_Y(id_N800) + left_wire_dist + 6., HOP4X(1), PIP_Y(id_N808) + 7.}, - {HOP4X(1), PIP_Y(id_N808) + 7., WIRE_X(0), PIP_Y(id_N808) + 7.}}}, - {id_S80_loop1, - {{WIRE_X(0), PIP_Y(id_S800), HOP4X(16), PIP_Y(id_S800)}, - {HOP4X(16), PIP_Y(id_S800), HOP4X(16), PIP_Y(id_N808)}, - {HOP4X(16), PIP_Y(id_N808) - 0., HOP4X(14), PIP_Y(id_N808) - left_wire_dist - 0.}, - {HOP4X(14), PIP_Y(id_N808) - left_wire_dist - 0., HOP4X(14), PIP_Y(id_N808) - 1.}, - {HOP4X(14), PIP_Y(id_N808) - 1., HOP4X(12), PIP_Y(id_N808) - left_wire_dist - 1.}, - {HOP4X(12), PIP_Y(id_N808) - left_wire_dist - 1., HOP4X(12), -wrap_len - 1.}, - {HOP4X(12), -wrap_len - 1., HOP4X(13), -wrap_len - 1.}, - {HOP4X(13), -wrap_len - 1., HOP4X(13), PIP_Y(id_N800) - 1.}, - {HOP4X(13), PIP_Y(id_N800) - 1., HOP4X(11), PIP_Y(id_N800) + left_wire_dist - 1.}, - {HOP4X(11), PIP_Y(id_N800) + left_wire_dist - 1., HOP4X(11), PIP_Y(id_N800) - 0.}, - {HOP4X(11), PIP_Y(id_N800) - 0., HOP4X(9), PIP_Y(id_N800) + left_wire_dist - 0.}, - {HOP4X(9), PIP_Y(id_N800) + left_wire_dist - 0., HOP4X(9), PIP_Y(id_N800) + 1.}, - {HOP4X(9), PIP_Y(id_N800) + 1., HOP4X(7), PIP_Y(id_N800) + left_wire_dist + 1.}, - {HOP4X(9), PIP_Y(id_N804) + 1., WIRE_X(0), PIP_Y(id_N804) + 1.}, - {HOP4X(7), PIP_Y(id_N800) + left_wire_dist + 1., HOP4X(7), PIP_Y(id_N800) + 2.}, - {HOP4X(7), PIP_Y(id_N800) + 2., HOP4X(5), PIP_Y(id_N800) + left_wire_dist + 2.}, - {HOP4X(5), PIP_Y(id_N800) + left_wire_dist + 2., HOP4X(5), PIP_Y(id_N800) + 3.}, - {HOP4X(5), PIP_Y(id_N800) + 3., HOP4X(3), PIP_Y(id_N800) + left_wire_dist + 3.}, - {HOP4X(3), PIP_Y(id_N800) + left_wire_dist + 3., HOP4X(3), PIP_Y(id_N800) + 4.}, - {HOP4X(3), PIP_Y(id_N800) + 4., HOP4X(1), PIP_Y(id_N800) + left_wire_dist + 4.}, - {HOP4X(1), PIP_Y(id_N800) + left_wire_dist + 4., HOP4X(1), PIP_Y(id_N808) + 5.}, - {HOP4X(1), PIP_Y(id_N808) + 5., WIRE_X(0), PIP_Y(id_N808) + 5.}}}, - {id_S80_loop2, - {{WIRE_X(0), PIP_Y(id_S800), HOP4X(16), PIP_Y(id_S800)}, - {HOP4X(16), PIP_Y(id_S800), HOP4X(16), PIP_Y(id_N808)}, - {HOP4X(16), PIP_Y(id_N808) - 0., HOP4X(14), PIP_Y(id_N808) - left_wire_dist - 0.}, - {HOP4X(14), PIP_Y(id_N808) - left_wire_dist - 0., HOP4X(14), PIP_Y(id_N808) - 1.}, - {HOP4X(14), PIP_Y(id_N808) - 1., HOP4X(12), PIP_Y(id_N808) - left_wire_dist - 1.}, - {HOP4X(12), PIP_Y(id_N808) - left_wire_dist - 1., HOP4X(12), PIP_Y(id_N808) - 2.}, - {HOP4X(12), PIP_Y(id_N808) - 2., HOP4X(10), PIP_Y(id_N808) - left_wire_dist - 2.}, - {HOP4X(10), PIP_Y(id_N808) - left_wire_dist - 2., HOP4X(10), -wrap_len - 2.}, - {HOP4X(10), -wrap_len - 2., HOP4X(11), -wrap_len - 2.}, - {HOP4X(11), -wrap_len - 2., HOP4X(11), PIP_Y(id_N800) - 2.}, - {HOP4X(11), PIP_Y(id_N800) - 2., HOP4X(9), PIP_Y(id_N800) + left_wire_dist - 2.}, - {HOP4X(9), PIP_Y(id_N800) + left_wire_dist - 2., HOP4X(9), PIP_Y(id_N800) - 1.}, - {HOP4X(9), PIP_Y(id_N800) - 1., HOP4X(7), PIP_Y(id_N800) + left_wire_dist - 1.}, - {HOP4X(9), PIP_Y(id_N804) - 1., WIRE_X(0), PIP_Y(id_N804) - 1.}, - {HOP4X(7), PIP_Y(id_N800) + left_wire_dist - 1., HOP4X(7), PIP_Y(id_N800) - 0.}, - {HOP4X(7), PIP_Y(id_N800) - 0., HOP4X(5), PIP_Y(id_N800) + left_wire_dist - 0.}, - {HOP4X(5), PIP_Y(id_N800) + left_wire_dist - 0., HOP4X(5), PIP_Y(id_N800) + 1.}, - {HOP4X(5), PIP_Y(id_N800) + 1., HOP4X(3), PIP_Y(id_N800) + left_wire_dist + 1.}, - {HOP4X(3), PIP_Y(id_N800) + left_wire_dist + 1., HOP4X(3), PIP_Y(id_N800) + 2.}, - {HOP4X(3), PIP_Y(id_N800) + 2., HOP4X(1), PIP_Y(id_N800) + left_wire_dist + 2.}, - {HOP4X(1), PIP_Y(id_N800) + left_wire_dist + 2., HOP4X(1), PIP_Y(id_N808) + 3.}, - {HOP4X(1), PIP_Y(id_N808) + 3., WIRE_X(0), PIP_Y(id_N808) + 3.}}}, - {id_S80_loop3, - {{WIRE_X(0), PIP_Y(id_S800), HOP4X(16), PIP_Y(id_S800)}, - {HOP4X(16), PIP_Y(id_S800), HOP4X(16), PIP_Y(id_N808)}, - {HOP4X(16), PIP_Y(id_N808) - 0., HOP4X(14), PIP_Y(id_N808) - left_wire_dist - 0.}, - {HOP4X(14), PIP_Y(id_N808) - left_wire_dist - 0., HOP4X(14), PIP_Y(id_N808) - 1.}, - {HOP4X(14), PIP_Y(id_N808) - 1., HOP4X(12), PIP_Y(id_N808) - left_wire_dist - 1.}, - {HOP4X(12), PIP_Y(id_N808) - left_wire_dist - 1., HOP4X(12), PIP_Y(id_N808) - 2.}, - {HOP4X(12), PIP_Y(id_N808) - 2., HOP4X(10), PIP_Y(id_N808) - left_wire_dist - 2.}, - {HOP4X(10), PIP_Y(id_N808) - left_wire_dist - 2., HOP4X(10), PIP_Y(id_N808) - 3.}, - {HOP4X(10), PIP_Y(id_N808) - 3., HOP4X(8), PIP_Y(id_N808) - left_wire_dist - 3.}, - {HOP4X(8), PIP_Y(id_N808) - left_wire_dist - 3., HOP4X(8), -wrap_len - 3.}, - {HOP4X(8), -wrap_len - 3., HOP4X(9), -wrap_len - 3.}, - {HOP4X(9), -wrap_len - 3., HOP4X(9), PIP_Y(id_N800) - 3.}, - {HOP4X(9), PIP_Y(id_N804) - 3., WIRE_X(0), PIP_Y(id_N804) - 3.}, - {HOP4X(9), PIP_Y(id_N800) - 3., HOP4X(7), PIP_Y(id_N800) + left_wire_dist - 3.}, - {HOP4X(7), PIP_Y(id_N800) + left_wire_dist - 3., HOP4X(7), PIP_Y(id_N800) - 2.}, - {HOP4X(7), PIP_Y(id_N800) - 2., HOP4X(5), PIP_Y(id_N800) + left_wire_dist - 2.}, - {HOP4X(5), PIP_Y(id_N800) + left_wire_dist - 2., HOP4X(5), PIP_Y(id_N800) - 1.}, - {HOP4X(5), PIP_Y(id_N800) - 1., HOP4X(3), PIP_Y(id_N800) + left_wire_dist - 1.}, - {HOP4X(3), PIP_Y(id_N800) + left_wire_dist - 1., HOP4X(3), PIP_Y(id_N800) - 0.}, - {HOP4X(3), PIP_Y(id_N800) - 0., HOP4X(1), PIP_Y(id_N800) + left_wire_dist - 0.}, - {HOP4X(1), PIP_Y(id_N800) + left_wire_dist - 0., HOP4X(1), PIP_Y(id_N808) + 1.}, - {HOP4X(1), PIP_Y(id_N808) + 1., WIRE_X(0), PIP_Y(id_N808) + 1.}}}, - {id_S80_loop4, - {{WIRE_X(0), PIP_Y(id_S800), HOP4X(16), PIP_Y(id_S800)}, - {HOP4X(16), PIP_Y(id_S800), HOP4X(16), PIP_Y(id_N808)}, - {HOP4X(16), PIP_Y(id_N808) - 0., HOP4X(14), PIP_Y(id_N808) - left_wire_dist - 0.}, - {HOP4X(14), PIP_Y(id_N808) - left_wire_dist - 0., HOP4X(14), PIP_Y(id_N808) - 1.}, - {HOP4X(14), PIP_Y(id_N808) - 1., HOP4X(12), PIP_Y(id_N808) - left_wire_dist - 1.}, - {HOP4X(12), PIP_Y(id_N808) - left_wire_dist - 1., HOP4X(12), PIP_Y(id_N808) - 2.}, - {HOP4X(12), PIP_Y(id_N808) - 2., HOP4X(10), PIP_Y(id_N808) - left_wire_dist - 2.}, - {HOP4X(10), PIP_Y(id_N808) - left_wire_dist - 2., HOP4X(10), PIP_Y(id_N808) - 3.}, - {HOP4X(10), PIP_Y(id_N808) - 3., HOP4X(8), PIP_Y(id_N808) - left_wire_dist - 3.}, - {HOP4X(8), PIP_Y(id_N808) - left_wire_dist - 3., HOP4X(8), PIP_Y(id_N808) - 4.}, - {HOP4X(8), PIP_Y(id_S804) - 4., WIRE_X(0), PIP_Y(id_S804) - 4.}, - {HOP4X(8), PIP_Y(id_N808) - 4., HOP4X(6), PIP_Y(id_N808) - left_wire_dist - 4.}, - {HOP4X(6), PIP_Y(id_N808) - left_wire_dist - 4., HOP4X(6), -wrap_len - 4.}, - {HOP4X(6), -wrap_len - 4., HOP4X(7), -wrap_len - 4.}, - {HOP4X(7), -wrap_len - 4., HOP4X(7), PIP_Y(id_N800) - 4.}, - {HOP4X(7), PIP_Y(id_N800) - 4., HOP4X(5), PIP_Y(id_N800) + left_wire_dist - 4.}, - {HOP4X(5), PIP_Y(id_N800) + left_wire_dist - 4., HOP4X(5), PIP_Y(id_N800) - 3.}, - {HOP4X(5), PIP_Y(id_N800) - 3., HOP4X(3), PIP_Y(id_N800) + left_wire_dist - 3.}, - {HOP4X(3), PIP_Y(id_N800) + left_wire_dist - 3., HOP4X(3), PIP_Y(id_N800) - 2.}, - {HOP4X(3), PIP_Y(id_N800) - 2., HOP4X(1), PIP_Y(id_N800) + left_wire_dist - 2.}, - {HOP4X(1), PIP_Y(id_N800) + left_wire_dist - 2., HOP4X(1), PIP_Y(id_N808) - 1.}, - {HOP4X(1), PIP_Y(id_N808) - 1., WIRE_X(0), PIP_Y(id_N808) - 1.}}}, - {id_S80_loop5, - {{WIRE_X(0), PIP_Y(id_S800), HOP4X(16), PIP_Y(id_S800)}, - {HOP4X(16), PIP_Y(id_S800), HOP4X(16), PIP_Y(id_N808)}, - {HOP4X(16), PIP_Y(id_N808) - 0., HOP4X(14), PIP_Y(id_N808) - left_wire_dist - 0.}, - {HOP4X(14), PIP_Y(id_N808) - left_wire_dist - 0., HOP4X(14), PIP_Y(id_N808) - 1.}, - {HOP4X(14), PIP_Y(id_N808) - 1., HOP4X(12), PIP_Y(id_N808) - left_wire_dist - 1.}, - {HOP4X(12), PIP_Y(id_N808) - left_wire_dist - 1., HOP4X(12), PIP_Y(id_N808) - 2.}, - {HOP4X(12), PIP_Y(id_N808) - 2., HOP4X(10), PIP_Y(id_N808) - left_wire_dist - 2.}, - {HOP4X(10), PIP_Y(id_N808) - left_wire_dist - 2., HOP4X(10), PIP_Y(id_N808) - 3.}, - {HOP4X(10), PIP_Y(id_N808) - 3., HOP4X(8), PIP_Y(id_N808) - left_wire_dist - 3.}, - {HOP4X(8), PIP_Y(id_N808) - left_wire_dist - 3., HOP4X(8), PIP_Y(id_N808) - 4.}, - {HOP4X(8), PIP_Y(id_S804) - 4., WIRE_X(0), PIP_Y(id_S804) - 4.}, - {HOP4X(8), PIP_Y(id_N808) - 4., HOP4X(6), PIP_Y(id_N808) - left_wire_dist - 4.}, - {HOP4X(6), PIP_Y(id_N808) - left_wire_dist - 4., HOP4X(6), PIP_Y(id_N808) - 5.}, - {HOP4X(6), PIP_Y(id_N808) - 5., HOP4X(4), PIP_Y(id_N808) - left_wire_dist - 5.}, - {HOP4X(4), PIP_Y(id_N808) - left_wire_dist - 5., HOP4X(4), -wrap_len - 5.}, - {HOP4X(4), -wrap_len - 5., HOP4X(5), -wrap_len - 5.}, - {HOP4X(5), -wrap_len - 5., HOP4X(5), PIP_Y(id_N800) - 5.}, - {HOP4X(5), PIP_Y(id_N800) - 5., HOP4X(3), PIP_Y(id_N800) + left_wire_dist - 5.}, - {HOP4X(3), PIP_Y(id_N800) + left_wire_dist - 5., HOP4X(3), PIP_Y(id_N800) - 4.}, - {HOP4X(3), PIP_Y(id_N800) - 4., HOP4X(1), PIP_Y(id_N800) + left_wire_dist - 4.}, - {HOP4X(1), PIP_Y(id_N800) + left_wire_dist - 4., HOP4X(1), PIP_Y(id_N808) - 3.}, - {HOP4X(1), PIP_Y(id_N808) - 3., WIRE_X(0), PIP_Y(id_N808) - 3.}}}, - {id_S80_loop6, - {{WIRE_X(0), PIP_Y(id_S800), HOP4X(16), PIP_Y(id_S800)}, - {HOP4X(16), PIP_Y(id_S800), HOP4X(16), PIP_Y(id_N808)}, - {HOP4X(16), PIP_Y(id_N808) - 0., HOP4X(14), PIP_Y(id_N808) - left_wire_dist - 0.}, - {HOP4X(14), PIP_Y(id_N808) - left_wire_dist - 0., HOP4X(14), PIP_Y(id_N808) - 1.}, - {HOP4X(14), PIP_Y(id_N808) - 1., HOP4X(12), PIP_Y(id_N808) - left_wire_dist - 1.}, - {HOP4X(12), PIP_Y(id_N808) - left_wire_dist - 1., HOP4X(12), PIP_Y(id_N808) - 2.}, - {HOP4X(12), PIP_Y(id_N808) - 2., HOP4X(10), PIP_Y(id_N808) - left_wire_dist - 2.}, - {HOP4X(10), PIP_Y(id_N808) - left_wire_dist - 2., HOP4X(10), PIP_Y(id_N808) - 3.}, - {HOP4X(10), PIP_Y(id_N808) - 3., HOP4X(8), PIP_Y(id_N808) - left_wire_dist - 3.}, - {HOP4X(8), PIP_Y(id_N808) - left_wire_dist - 3., HOP4X(8), PIP_Y(id_N808) - 4.}, - {HOP4X(8), PIP_Y(id_S804) - 4., WIRE_X(0), PIP_Y(id_S804) - 4.}, - {HOP4X(8), PIP_Y(id_N808) - 4., HOP4X(6), PIP_Y(id_N808) - left_wire_dist - 4.}, - {HOP4X(6), PIP_Y(id_N808) - left_wire_dist - 4., HOP4X(6), PIP_Y(id_N808) - 5.}, - {HOP4X(6), PIP_Y(id_N808) - 5., HOP4X(4), PIP_Y(id_N808) - left_wire_dist - 5.}, - {HOP4X(4), PIP_Y(id_N808) - left_wire_dist - 5., HOP4X(4), PIP_Y(id_N808) - 6.}, - {HOP4X(4), PIP_Y(id_N808) - 6., HOP4X(2), PIP_Y(id_N808) - left_wire_dist - 6.}, - {HOP4X(2), PIP_Y(id_N808) - left_wire_dist - 6., HOP4X(2), -wrap_len - 6.}, - {HOP4X(2), -wrap_len - 6., HOP4X(3), -wrap_len - 6.}, - {HOP4X(3), -wrap_len - 6., HOP4X(3), PIP_Y(id_N800) - 6.}, - {HOP4X(3), PIP_Y(id_N800) - 6., HOP4X(1), PIP_Y(id_N800) + left_wire_dist - 6.}, - {HOP4X(1), PIP_Y(id_N800) + left_wire_dist - 6., HOP4X(1), PIP_Y(id_N808) - 5.}, - {HOP4X(1), PIP_Y(id_N808) - 5., WIRE_X(0), PIP_Y(id_N808) - 5.}}}, - {id_S80_loop7, - {{WIRE_X(0), PIP_Y(id_S800), HOP4X(16), PIP_Y(id_S800)}, - {HOP4X(16), PIP_Y(id_S800), HOP4X(16), PIP_Y(id_N808)}, - {HOP4X(16), PIP_Y(id_N808) - 0., HOP4X(14), PIP_Y(id_N808) - left_wire_dist - 0.}, - {HOP4X(14), PIP_Y(id_N808) - left_wire_dist - 0., HOP4X(14), PIP_Y(id_N808) - 1.}, - {HOP4X(14), PIP_Y(id_N808) - 1., HOP4X(12), PIP_Y(id_N808) - left_wire_dist - 1.}, - {HOP4X(12), PIP_Y(id_N808) - left_wire_dist - 1., HOP4X(12), PIP_Y(id_N808) - 2.}, - {HOP4X(12), PIP_Y(id_N808) - 2., HOP4X(10), PIP_Y(id_N808) - left_wire_dist - 2.}, - {HOP4X(10), PIP_Y(id_N808) - left_wire_dist - 2., HOP4X(10), PIP_Y(id_N808) - 3.}, - {HOP4X(10), PIP_Y(id_N808) - 3., HOP4X(8), PIP_Y(id_N808) - left_wire_dist - 3.}, - {HOP4X(8), PIP_Y(id_N808) - left_wire_dist - 3., HOP4X(8), PIP_Y(id_N808) - 4.}, - {HOP4X(8), PIP_Y(id_S804) - 4., WIRE_X(0), PIP_Y(id_S804) - 4.}, - {HOP4X(8), PIP_Y(id_N808) - 4., HOP4X(6), PIP_Y(id_N808) - left_wire_dist - 4.}, - {HOP4X(6), PIP_Y(id_N808) - left_wire_dist - 4., HOP4X(6), PIP_Y(id_N808) - 5.}, - {HOP4X(6), PIP_Y(id_N808) - 5., HOP4X(4), PIP_Y(id_N808) - left_wire_dist - 5.}, - {HOP4X(4), PIP_Y(id_N808) - left_wire_dist - 5., HOP4X(4), PIP_Y(id_N808) - 6.}, - {HOP4X(4), PIP_Y(id_N808) - 6., HOP4X(2), PIP_Y(id_N808) - left_wire_dist - 6.}, - {HOP4X(2), PIP_Y(id_N808) - left_wire_dist - 6., HOP4X(2), PIP_Y(id_N808) - 7.}, - {HOP4X(2), PIP_Y(id_N808) - 7., HOP4X(0), PIP_Y(id_N808) - left_wire_dist - 7.}, - {HOP4X(0), PIP_Y(id_N808) - left_wire_dist - 7., HOP4X(0), -wrap_len - 7.}, - {HOP4X(0), -wrap_len - 7., HOP4X(1), -wrap_len - 7.}, - {HOP4X(1), -wrap_len - 7., HOP4X(1), PIP_Y(id_N808) - 7.}, - {HOP4X(1), PIP_Y(id_N808) - 7., WIRE_X(0), PIP_Y(id_N808) - 7.}}}, - {id_N80_loop0, - {{WIRE_X(0), PIP_Y(id_N800), HOP4X(17), PIP_Y(id_N800)}, - {HOP4X(17), PIP_Y(id_N800) + 0., HOP4X(15), PIP_Y(id_N800) + left_wire_dist + 0.}, - {HOP4X(15), PIP_Y(id_N800) + left_wire_dist + 0., HOP4X(15), wrap_len + 1.}, - {HOP4X(15), wrap_len + 1., HOP4X(14), wrap_len + 1.}, - {HOP4X(14), wrap_len + 1., HOP4X(14), PIP_Y(id_N808) + 0.}, - {HOP4X(14), PIP_Y(id_N808) + 0., HOP4X(12), PIP_Y(id_N808) - left_wire_dist + 0.}, - {HOP4X(12), PIP_Y(id_N808) - left_wire_dist + 0., HOP4X(12), PIP_Y(id_N808) - 1.}, - {HOP4X(12), PIP_Y(id_N808) - 1., HOP4X(10), PIP_Y(id_N808) - left_wire_dist - 1.}, - {HOP4X(10), PIP_Y(id_N808) - left_wire_dist - 1., HOP4X(10), PIP_Y(id_N808) - 2.}, - {HOP4X(10), PIP_Y(id_N808) - 2., HOP4X(8), PIP_Y(id_N808) - left_wire_dist - 2.}, - {HOP4X(8), PIP_Y(id_N808) - left_wire_dist - 2., HOP4X(8), PIP_Y(id_N808) - 3.}, - {HOP4X(8), PIP_Y(id_S804) - 3., WIRE_X(0), PIP_Y(id_S804) - 3.}, - {HOP4X(8), PIP_Y(id_N808) - 3., HOP4X(6), PIP_Y(id_N808) - left_wire_dist - 3.}, - {HOP4X(6), PIP_Y(id_N808) - left_wire_dist - 3., HOP4X(6), PIP_Y(id_N808) - 4.}, - {HOP4X(6), PIP_Y(id_N808) - 4., HOP4X(4), PIP_Y(id_N808) - left_wire_dist - 4.}, - {HOP4X(4), PIP_Y(id_N808) - left_wire_dist - 4., HOP4X(4), PIP_Y(id_N808) - 5.}, - {HOP4X(4), PIP_Y(id_N808) - 5., HOP4X(2), PIP_Y(id_N808) - left_wire_dist - 5.}, - {HOP4X(2), PIP_Y(id_N808) - left_wire_dist - 5., HOP4X(2), PIP_Y(id_N808) - 6.}, - {HOP4X(2), PIP_Y(id_N808) - 6., HOP4X(0), PIP_Y(id_N808) - left_wire_dist - 6.}, - {HOP4X(0), PIP_Y(id_N808) - left_wire_dist - 6., HOP4X(0), PIP_Y(id_S808) - 7.}, - {HOP4X(0), PIP_Y(id_S808) - 7., WIRE_X(0), PIP_Y(id_S808) - 7.}}}, - {id_N80_loop1, - {{WIRE_X(0), PIP_Y(id_N800), HOP4X(17), PIP_Y(id_N800)}, - {HOP4X(17), PIP_Y(id_N800) + 0., HOP4X(15), PIP_Y(id_N800) + left_wire_dist + 0.}, - {HOP4X(15), PIP_Y(id_N800) + left_wire_dist + 0., HOP4X(15), PIP_Y(id_N800) + 1.}, - {HOP4X(15), PIP_Y(id_N800) + 1., HOP4X(13), PIP_Y(id_N800) + left_wire_dist + 1.}, - {HOP4X(13), PIP_Y(id_N800) + left_wire_dist + 1., HOP4X(13), wrap_len + 2.}, - {HOP4X(13), wrap_len + 2., HOP4X(12), wrap_len + 2.}, - {HOP4X(12), wrap_len + 2., HOP4X(12), PIP_Y(id_N808) + 1.}, - {HOP4X(12), PIP_Y(id_N808) + 1., HOP4X(10), PIP_Y(id_N808) - left_wire_dist + 1.}, - {HOP4X(10), PIP_Y(id_N808) - left_wire_dist + 1., HOP4X(10), PIP_Y(id_N808) + 0.}, - {HOP4X(10), PIP_Y(id_N808) + 0., HOP4X(8), PIP_Y(id_N808) - left_wire_dist + 0.}, - {HOP4X(8), PIP_Y(id_N808) - left_wire_dist + 0., HOP4X(8), PIP_Y(id_N808) - 1.}, - {HOP4X(8), PIP_Y(id_S804) - 1., WIRE_X(0), PIP_Y(id_S804) - 1.}, - {HOP4X(8), PIP_Y(id_N808) - 1., HOP4X(6), PIP_Y(id_N808) - left_wire_dist - 1.}, - {HOP4X(6), PIP_Y(id_N808) - left_wire_dist - 1., HOP4X(6), PIP_Y(id_N808) - 2.}, - {HOP4X(6), PIP_Y(id_N808) - 2., HOP4X(4), PIP_Y(id_N808) - left_wire_dist - 2.}, - {HOP4X(4), PIP_Y(id_N808) - left_wire_dist - 2., HOP4X(4), PIP_Y(id_N808) - 3.}, - {HOP4X(4), PIP_Y(id_N808) - 3., HOP4X(2), PIP_Y(id_N808) - left_wire_dist - 3.}, - {HOP4X(2), PIP_Y(id_N808) - left_wire_dist - 3., HOP4X(2), PIP_Y(id_N808) - 4.}, - {HOP4X(2), PIP_Y(id_N808) - 4., HOP4X(0), PIP_Y(id_N808) - left_wire_dist - 4.}, - {HOP4X(0), PIP_Y(id_N808) - left_wire_dist - 4., HOP4X(0), PIP_Y(id_S808) - 5.}, - {HOP4X(0), PIP_Y(id_S808) - 5., WIRE_X(0), PIP_Y(id_S808) - 5.}}}, - {id_N80_loop2, - {{WIRE_X(0), PIP_Y(id_N800), HOP4X(17), PIP_Y(id_N800)}, - {HOP4X(17), PIP_Y(id_N800) + 0., HOP4X(15), PIP_Y(id_N800) + left_wire_dist + 0.}, - {HOP4X(15), PIP_Y(id_N800) + left_wire_dist + 0., HOP4X(15), PIP_Y(id_N800) + 1.}, - {HOP4X(15), PIP_Y(id_N800) + 1., HOP4X(13), PIP_Y(id_N800) + left_wire_dist + 1.}, - {HOP4X(13), PIP_Y(id_N800) + left_wire_dist + 1., HOP4X(13), PIP_Y(id_N800) + 2.}, - {HOP4X(13), PIP_Y(id_N800) + 2., HOP4X(11), PIP_Y(id_N800) + left_wire_dist + 2.}, - {HOP4X(11), PIP_Y(id_N800) + left_wire_dist + 2., HOP4X(11), wrap_len + 3.}, - {HOP4X(11), wrap_len + 3., HOP4X(10), wrap_len + 3.}, - {HOP4X(10), wrap_len + 3., HOP4X(10), PIP_Y(id_N808) + 2.}, - {HOP4X(10), PIP_Y(id_N808) + 2., HOP4X(8), PIP_Y(id_N808) - left_wire_dist + 2.}, - {HOP4X(8), PIP_Y(id_N808) - left_wire_dist + 2., HOP4X(8), PIP_Y(id_N808) + 1.}, - {HOP4X(8), PIP_Y(id_S804) + 1., WIRE_X(0), PIP_Y(id_S804) + 1.}, - {HOP4X(8), PIP_Y(id_N808) + 1., HOP4X(6), PIP_Y(id_N808) - left_wire_dist + 1.}, - {HOP4X(6), PIP_Y(id_N808) - left_wire_dist + 1., HOP4X(6), PIP_Y(id_N808) + 0.}, - {HOP4X(6), PIP_Y(id_N808) + 0., HOP4X(4), PIP_Y(id_N808) - left_wire_dist + 0.}, - {HOP4X(4), PIP_Y(id_N808) - left_wire_dist + 0., HOP4X(4), PIP_Y(id_N808) - 1.}, - {HOP4X(4), PIP_Y(id_N808) - 1., HOP4X(2), PIP_Y(id_N808) - left_wire_dist - 1.}, - {HOP4X(2), PIP_Y(id_N808) - left_wire_dist - 1., HOP4X(2), PIP_Y(id_N808) - 2.}, - {HOP4X(2), PIP_Y(id_N808) - 2., HOP4X(0), PIP_Y(id_N808) - left_wire_dist - 2.}, - {HOP4X(0), PIP_Y(id_N808) - left_wire_dist - 2., HOP4X(0), PIP_Y(id_S808) - 3.}, - {HOP4X(0), PIP_Y(id_S808) - 3., WIRE_X(0), PIP_Y(id_S808) - 3.}}}, - {id_N80_loop3, - {{WIRE_X(0), PIP_Y(id_N800), HOP4X(17), PIP_Y(id_N800)}, - {HOP4X(17), PIP_Y(id_N800) + 0., HOP4X(15), PIP_Y(id_N800) + left_wire_dist + 0.}, - {HOP4X(15), PIP_Y(id_N800) + left_wire_dist + 0., HOP4X(15), PIP_Y(id_N800) + 1.}, - {HOP4X(15), PIP_Y(id_N800) + 1., HOP4X(13), PIP_Y(id_N800) + left_wire_dist + 1.}, - {HOP4X(13), PIP_Y(id_N800) + left_wire_dist + 1., HOP4X(13), PIP_Y(id_N800) + 2.}, - {HOP4X(13), PIP_Y(id_N800) + 2., HOP4X(11), PIP_Y(id_N800) + left_wire_dist + 2.}, - {HOP4X(11), PIP_Y(id_N800) + left_wire_dist + 2., HOP4X(11), PIP_Y(id_N800) + 3.}, - {HOP4X(11), PIP_Y(id_N800) + 3., HOP4X(9), PIP_Y(id_N800) + left_wire_dist + 3.}, - {HOP4X(9), PIP_Y(id_N800) + left_wire_dist + 3., HOP4X(9), wrap_len + 4.}, - {HOP4X(9), wrap_len + 4., HOP4X(8), wrap_len + 4.}, - {HOP4X(8), wrap_len + 4., HOP4X(8), PIP_Y(id_N808) + 3.}, - {HOP4X(8), PIP_Y(id_S804) + 3., WIRE_X(0), PIP_Y(id_S804) + 3.}, - {HOP4X(8), PIP_Y(id_N808) + 3., HOP4X(6), PIP_Y(id_N808) - left_wire_dist + 3.}, - {HOP4X(6), PIP_Y(id_N808) - left_wire_dist + 3., HOP4X(6), PIP_Y(id_N808) + 2.}, - {HOP4X(6), PIP_Y(id_N808) + 2., HOP4X(4), PIP_Y(id_N808) - left_wire_dist + 2.}, - {HOP4X(4), PIP_Y(id_N808) - left_wire_dist + 2., HOP4X(4), PIP_Y(id_N808) + 1.}, - {HOP4X(4), PIP_Y(id_N808) + 1., HOP4X(2), PIP_Y(id_N808) - left_wire_dist + 1.}, - {HOP4X(2), PIP_Y(id_N808) - left_wire_dist + 1., HOP4X(2), PIP_Y(id_N808) + 0.}, - {HOP4X(2), PIP_Y(id_N808) + 0., HOP4X(0), PIP_Y(id_N808) - left_wire_dist + 0.}, - {HOP4X(0), PIP_Y(id_N808) - left_wire_dist + 0., HOP4X(0), PIP_Y(id_S808) - 1.}, - {HOP4X(0), PIP_Y(id_S808) - 1., WIRE_X(0), PIP_Y(id_S808) - 1.}}}, - {id_N80_loop4, - {{WIRE_X(0), PIP_Y(id_N800), HOP4X(17), PIP_Y(id_N800)}, - {HOP4X(17), PIP_Y(id_N800) + 0., HOP4X(15), PIP_Y(id_N800) + left_wire_dist + 0.}, - {HOP4X(15), PIP_Y(id_N800) + left_wire_dist + 0., HOP4X(15), PIP_Y(id_N800) + 1.}, - {HOP4X(15), PIP_Y(id_N800) + 1., HOP4X(13), PIP_Y(id_N800) + left_wire_dist + 1.}, - {HOP4X(13), PIP_Y(id_N800) + left_wire_dist + 1., HOP4X(13), PIP_Y(id_N800) + 2.}, - {HOP4X(13), PIP_Y(id_N800) + 2., HOP4X(11), PIP_Y(id_N800) + left_wire_dist + 2.}, - {HOP4X(11), PIP_Y(id_N800) + left_wire_dist + 2., HOP4X(11), PIP_Y(id_N800) + 3.}, - {HOP4X(11), PIP_Y(id_N800) + 3., HOP4X(9), PIP_Y(id_N800) + left_wire_dist + 3.}, - {HOP4X(9), PIP_Y(id_N800) + left_wire_dist + 3., HOP4X(9), PIP_Y(id_N800) + 4.}, - {HOP4X(9), PIP_Y(id_N804) + 4., WIRE_X(0), PIP_Y(id_N804) + 4.}, - {HOP4X(9), PIP_Y(id_N800) + 4., HOP4X(7), PIP_Y(id_N800) + left_wire_dist + 4.}, - {HOP4X(7), PIP_Y(id_N800) + left_wire_dist + 4., HOP4X(7), wrap_len + 5.}, - {HOP4X(7), wrap_len + 5., HOP4X(6), wrap_len + 5.}, - {HOP4X(6), wrap_len + 5., HOP4X(6), PIP_Y(id_N808) + 4.}, - {HOP4X(6), PIP_Y(id_N808) + 4., HOP4X(4), PIP_Y(id_N808) - left_wire_dist + 4.}, - {HOP4X(4), PIP_Y(id_N808) - left_wire_dist + 4., HOP4X(4), PIP_Y(id_N808) + 3.}, - {HOP4X(4), PIP_Y(id_N808) + 3., HOP4X(2), PIP_Y(id_N808) - left_wire_dist + 3.}, - {HOP4X(2), PIP_Y(id_N808) - left_wire_dist + 3., HOP4X(2), PIP_Y(id_N808) + 2.}, - {HOP4X(2), PIP_Y(id_N808) + 2., HOP4X(0), PIP_Y(id_N808) - left_wire_dist + 2.}, - {HOP4X(0), PIP_Y(id_N808) - left_wire_dist + 2., HOP4X(0), PIP_Y(id_S808) + 1.}, - {HOP4X(0), PIP_Y(id_S808) + 1., WIRE_X(0), PIP_Y(id_S808) + 1.}}}, - {id_N80_loop5, - {{WIRE_X(0), PIP_Y(id_N800), HOP4X(17), PIP_Y(id_N800)}, - {HOP4X(17), PIP_Y(id_N800) + 0., HOP4X(15), PIP_Y(id_N800) + left_wire_dist + 0.}, - {HOP4X(15), PIP_Y(id_N800) + left_wire_dist + 0., HOP4X(15), PIP_Y(id_N800) + 1.}, - {HOP4X(15), PIP_Y(id_N800) + 1., HOP4X(13), PIP_Y(id_N800) + left_wire_dist + 1.}, - {HOP4X(13), PIP_Y(id_N800) + left_wire_dist + 1., HOP4X(13), PIP_Y(id_N800) + 2.}, - {HOP4X(13), PIP_Y(id_N800) + 2., HOP4X(11), PIP_Y(id_N800) + left_wire_dist + 2.}, - {HOP4X(11), PIP_Y(id_N800) + left_wire_dist + 2., HOP4X(11), PIP_Y(id_N800) + 3.}, - {HOP4X(11), PIP_Y(id_N800) + 3., HOP4X(9), PIP_Y(id_N800) + left_wire_dist + 3.}, - {HOP4X(9), PIP_Y(id_N800) + left_wire_dist + 3., HOP4X(9), PIP_Y(id_N800) + 4.}, - {HOP4X(9), PIP_Y(id_N804) + 4., WIRE_X(0), PIP_Y(id_N804) + 4.}, - {HOP4X(9), PIP_Y(id_N800) + 4., HOP4X(7), PIP_Y(id_N800) + left_wire_dist + 4.}, - {HOP4X(7), PIP_Y(id_N800) + left_wire_dist + 4., HOP4X(7), PIP_Y(id_N800) + 5.}, - {HOP4X(7), PIP_Y(id_N800) + 5., HOP4X(5), PIP_Y(id_N800) + left_wire_dist + 5.}, - {HOP4X(5), PIP_Y(id_N800) + left_wire_dist + 5., HOP4X(5), wrap_len + 6.}, - {HOP4X(5), wrap_len + 6., HOP4X(4), wrap_len + 6.}, - {HOP4X(4), wrap_len + 6., HOP4X(4), PIP_Y(id_N808) + 5.}, - {HOP4X(4), PIP_Y(id_N808) + 5., HOP4X(2), PIP_Y(id_N808) - left_wire_dist + 5.}, - {HOP4X(2), PIP_Y(id_N808) - left_wire_dist + 5., HOP4X(2), PIP_Y(id_N808) + 4.}, - {HOP4X(2), PIP_Y(id_N808) + 4., HOP4X(0), PIP_Y(id_N808) - left_wire_dist + 4.}, - {HOP4X(0), PIP_Y(id_N808) - left_wire_dist + 4., HOP4X(0), PIP_Y(id_S808) + 3.}, - {HOP4X(0), PIP_Y(id_S808) + 3., WIRE_X(0), PIP_Y(id_S808) + 3.}}}, - {id_N80_loop6, - {{WIRE_X(0), PIP_Y(id_N800), HOP4X(17), PIP_Y(id_N800)}, - {HOP4X(17), PIP_Y(id_N800) + 0., HOP4X(15), PIP_Y(id_N800) + left_wire_dist + 0.}, - {HOP4X(15), PIP_Y(id_N800) + left_wire_dist + 0., HOP4X(15), PIP_Y(id_N800) + 1.}, - {HOP4X(15), PIP_Y(id_N800) + 1., HOP4X(13), PIP_Y(id_N800) + left_wire_dist + 1.}, - {HOP4X(13), PIP_Y(id_N800) + left_wire_dist + 1., HOP4X(13), PIP_Y(id_N800) + 2.}, - {HOP4X(13), PIP_Y(id_N800) + 2., HOP4X(11), PIP_Y(id_N800) + left_wire_dist + 2.}, - {HOP4X(11), PIP_Y(id_N800) + left_wire_dist + 2., HOP4X(11), PIP_Y(id_N800) + 3.}, - {HOP4X(11), PIP_Y(id_N800) + 3., HOP4X(9), PIP_Y(id_N800) + left_wire_dist + 3.}, - {HOP4X(9), PIP_Y(id_N800) + left_wire_dist + 3., HOP4X(9), PIP_Y(id_N800) + 4.}, - {HOP4X(9), PIP_Y(id_N804) + 4., WIRE_X(0), PIP_Y(id_N804) + 4.}, - {HOP4X(9), PIP_Y(id_N800) + 4., HOP4X(7), PIP_Y(id_N800) + left_wire_dist + 4.}, - {HOP4X(7), PIP_Y(id_N800) + left_wire_dist + 4., HOP4X(7), PIP_Y(id_N800) + 5.}, - {HOP4X(7), PIP_Y(id_N800) + 5., HOP4X(5), PIP_Y(id_N800) + left_wire_dist + 5.}, - {HOP4X(5), PIP_Y(id_N800) + left_wire_dist + 5., HOP4X(5), PIP_Y(id_N800) + 6.}, - {HOP4X(5), PIP_Y(id_N800) + 6., HOP4X(3), PIP_Y(id_N800) + left_wire_dist + 6.}, - {HOP4X(3), PIP_Y(id_N800) + left_wire_dist + 6., HOP4X(3), wrap_len + 7.}, - {HOP4X(3), wrap_len + 7., HOP4X(2), wrap_len + 7.}, - {HOP4X(2), wrap_len + 7., HOP4X(2), PIP_Y(id_N808) + 6.}, - {HOP4X(2), PIP_Y(id_N808) + 6., HOP4X(0), PIP_Y(id_N808) - left_wire_dist + 6.}, - {HOP4X(0), PIP_Y(id_N808) - left_wire_dist + 6., HOP4X(0), PIP_Y(id_S808) + 5.}, - {HOP4X(0), PIP_Y(id_S808) + 5., WIRE_X(0), PIP_Y(id_S808) + 5.}}}, - {id_N80_loop7, - {{WIRE_X(0), PIP_Y(id_N800), HOP4X(17), PIP_Y(id_N800)}, - {HOP4X(17), PIP_Y(id_N800) + 0., HOP4X(15), PIP_Y(id_N800) + left_wire_dist + 0.}, - {HOP4X(15), PIP_Y(id_N800) + left_wire_dist + 0., HOP4X(15), PIP_Y(id_N800) + 1.}, - {HOP4X(15), PIP_Y(id_N800) + 1., HOP4X(13), PIP_Y(id_N800) + left_wire_dist + 1.}, - {HOP4X(13), PIP_Y(id_N800) + left_wire_dist + 1., HOP4X(13), PIP_Y(id_N800) + 2.}, - {HOP4X(13), PIP_Y(id_N800) + 2., HOP4X(11), PIP_Y(id_N800) + left_wire_dist + 2.}, - {HOP4X(11), PIP_Y(id_N800) + left_wire_dist + 2., HOP4X(11), PIP_Y(id_N800) + 3.}, - {HOP4X(11), PIP_Y(id_N800) + 3., HOP4X(9), PIP_Y(id_N800) + left_wire_dist + 3.}, - {HOP4X(9), PIP_Y(id_N800) + left_wire_dist + 3., HOP4X(9), PIP_Y(id_N800) + 4.}, - {HOP4X(9), PIP_Y(id_N804) + 4., WIRE_X(0), PIP_Y(id_N804) + 4.}, - {HOP4X(9), PIP_Y(id_N800) + 4., HOP4X(7), PIP_Y(id_N800) + left_wire_dist + 4.}, - {HOP4X(7), PIP_Y(id_N800) + left_wire_dist + 4., HOP4X(7), PIP_Y(id_N800) + 5.}, - {HOP4X(7), PIP_Y(id_N800) + 5., HOP4X(5), PIP_Y(id_N800) + left_wire_dist + 5.}, - {HOP4X(5), PIP_Y(id_N800) + left_wire_dist + 5., HOP4X(5), PIP_Y(id_N800) + 6.}, - {HOP4X(5), PIP_Y(id_N800) + 6., HOP4X(3), PIP_Y(id_N800) + left_wire_dist + 6.}, - {HOP4X(3), PIP_Y(id_N800) + left_wire_dist + 6., HOP4X(3), PIP_Y(id_N800) + 7.}, - {HOP4X(3), PIP_Y(id_N800) + 7., HOP4X(1), PIP_Y(id_N800) + left_wire_dist + 7.}, - {HOP4X(1), PIP_Y(id_N800) + left_wire_dist + 7., HOP4X(1), wrap_len + 8.}, - {HOP4X(1), wrap_len + 8., HOP4X(0), wrap_len + 8.}, - {HOP4X(0), wrap_len + 8., HOP4X(0), PIP_Y(id_S808) + 7.}, - {HOP4X(0), PIP_Y(id_S808) + 7., WIRE_X(0), PIP_Y(id_S808) + 7.}}}, - -#undef HOP4X -#define HOP4X(offset) WIRE_X((float)offset + HOP4X_START + 18.f) - {id_S81, - {{WIRE_X(0), PIP_Y(id_S810), HOP4X(16), PIP_Y(id_S810)}, - {HOP4X(16), PIP_Y(id_S810), HOP4X(16), PIP_Y(id_N818)}, - {HOP4X(16), PIP_Y(id_N818) - 0., HOP4X(14), PIP_Y(id_N818) - left_wire_dist - 0.}, - {HOP4X(14), PIP_Y(id_N818) - left_wire_dist - 0., HOP4X(14), PIP_Y(id_N818) - 1.}, - {HOP4X(14), PIP_Y(id_N818) - 1., HOP4X(12), PIP_Y(id_N818) - left_wire_dist - 1.}, - {HOP4X(12), PIP_Y(id_N818) - left_wire_dist - 1., HOP4X(12), PIP_Y(id_N818) - 2.}, - {HOP4X(12), PIP_Y(id_N818) - 2., HOP4X(10), PIP_Y(id_N818) - left_wire_dist - 2.}, - {HOP4X(10), PIP_Y(id_N818) - left_wire_dist - 2., HOP4X(10), PIP_Y(id_N818) - 3.}, - {HOP4X(10), PIP_Y(id_N818) - 3., HOP4X(8), PIP_Y(id_N818) - left_wire_dist - 3.}, - {HOP4X(8), PIP_Y(id_N818) - left_wire_dist - 3., HOP4X(8), PIP_Y(id_N818) - 4.}, - {HOP4X(8), PIP_Y(id_S814) - 4., WIRE_X(0), PIP_Y(id_S814) - 4.}, - {HOP4X(8), PIP_Y(id_N818) - 4., HOP4X(6), PIP_Y(id_N818) - left_wire_dist - 4.}, - {HOP4X(6), PIP_Y(id_N818) - left_wire_dist - 4., HOP4X(6), PIP_Y(id_N818) - 5.}, - {HOP4X(6), PIP_Y(id_N818) - 5., HOP4X(4), PIP_Y(id_N818) - left_wire_dist - 5.}, - {HOP4X(4), PIP_Y(id_N818) - left_wire_dist - 5., HOP4X(4), PIP_Y(id_N818) - 6.}, - {HOP4X(4), PIP_Y(id_N818) - 6., HOP4X(2), PIP_Y(id_N818) - left_wire_dist - 6.}, - {HOP4X(2), PIP_Y(id_N818) - left_wire_dist - 6., HOP4X(2), PIP_Y(id_N818) - 7.}, - {HOP4X(2), PIP_Y(id_N818) - 7., HOP4X(0), PIP_Y(id_N818) - left_wire_dist - 7.}, - {HOP4X(0), PIP_Y(id_N818) - left_wire_dist - 7., HOP4X(0), PIP_Y(id_S818) - 8.}, - {HOP4X(0), PIP_Y(id_S818) - 8., WIRE_X(0), PIP_Y(id_S818) - 8.}}}, - {id_N81, - {{WIRE_X(0), PIP_Y(id_N810), HOP4X(17), PIP_Y(id_N810)}, - {HOP4X(17), PIP_Y(id_N810) + 0., HOP4X(15), PIP_Y(id_N810) + left_wire_dist + 0.}, - {HOP4X(15), PIP_Y(id_N810) + left_wire_dist + 0., HOP4X(15), PIP_Y(id_N810) + 1.}, - {HOP4X(15), PIP_Y(id_N810) + 1., HOP4X(13), PIP_Y(id_N810) + left_wire_dist + 1.}, - {HOP4X(13), PIP_Y(id_N810) + left_wire_dist + 1., HOP4X(13), PIP_Y(id_N810) + 2.}, - {HOP4X(13), PIP_Y(id_N810) + 2., HOP4X(11), PIP_Y(id_N810) + left_wire_dist + 2.}, - {HOP4X(11), PIP_Y(id_N810) + left_wire_dist + 2., HOP4X(11), PIP_Y(id_N810) + 3.}, - {HOP4X(11), PIP_Y(id_N810) + 3., HOP4X(9), PIP_Y(id_N810) + left_wire_dist + 3.}, - {HOP4X(9), PIP_Y(id_N810) + left_wire_dist + 3., HOP4X(9), PIP_Y(id_N810) + 4.}, - {HOP4X(9), PIP_Y(id_N814) + 4., WIRE_X(0), PIP_Y(id_N814) + 4.}, - {HOP4X(9), PIP_Y(id_N810) + 4., HOP4X(7), PIP_Y(id_N810) + left_wire_dist + 4.}, - {HOP4X(7), PIP_Y(id_N810) + left_wire_dist + 4., HOP4X(7), PIP_Y(id_N810) + 5.}, - {HOP4X(7), PIP_Y(id_N810) + 5., HOP4X(5), PIP_Y(id_N810) + left_wire_dist + 5.}, - {HOP4X(5), PIP_Y(id_N810) + left_wire_dist + 5., HOP4X(5), PIP_Y(id_N810) + 6.}, - {HOP4X(5), PIP_Y(id_N810) + 6., HOP4X(3), PIP_Y(id_N810) + left_wire_dist + 6.}, - {HOP4X(3), PIP_Y(id_N810) + left_wire_dist + 6., HOP4X(3), PIP_Y(id_N810) + 7.}, - {HOP4X(3), PIP_Y(id_N810) + 7., HOP4X(1), PIP_Y(id_N810) + left_wire_dist + 7.}, - {HOP4X(1), PIP_Y(id_N810) + left_wire_dist + 7., HOP4X(1), PIP_Y(id_N818) + 8.}, - {HOP4X(1), PIP_Y(id_N818) + 8., WIRE_X(0), PIP_Y(id_N818) + 8.}}}, - {id_S81_loop0, - {{WIRE_X(0), PIP_Y(id_S810), HOP4X(16), PIP_Y(id_S810)}, - {HOP4X(16), PIP_Y(id_S810), HOP4X(16), PIP_Y(id_N818)}, - {HOP4X(16), PIP_Y(id_N818) - 0., HOP4X(14), PIP_Y(id_N818) - left_wire_dist - 0.}, - {HOP4X(14), PIP_Y(id_N818) - left_wire_dist - 0., HOP4X(14), -wrap_len - 0.}, - {HOP4X(14), -wrap_len - 0., HOP4X(15), -wrap_len - 0.}, - {HOP4X(15), -wrap_len - 0., HOP4X(15), PIP_Y(id_N810) - 0.}, - {HOP4X(15), PIP_Y(id_N810) - 0., HOP4X(13), PIP_Y(id_N810) + left_wire_dist - 0.}, - {HOP4X(13), PIP_Y(id_N810) + left_wire_dist - 0., HOP4X(13), PIP_Y(id_N810) + 1.}, - {HOP4X(13), PIP_Y(id_N810) + 1., HOP4X(11), PIP_Y(id_N810) + left_wire_dist + 1.}, - {HOP4X(11), PIP_Y(id_N810) + left_wire_dist + 1., HOP4X(11), PIP_Y(id_N810) + 2.}, - {HOP4X(11), PIP_Y(id_N810) + 2., HOP4X(9), PIP_Y(id_N810) + left_wire_dist + 2.}, - {HOP4X(9), PIP_Y(id_N810) + left_wire_dist + 2., HOP4X(9), PIP_Y(id_N810) + 3.}, - {HOP4X(9), PIP_Y(id_N810) + 3., HOP4X(7), PIP_Y(id_N810) + left_wire_dist + 3.}, - {HOP4X(9), PIP_Y(id_N814) + 3., WIRE_X(0), PIP_Y(id_N814) + 3.}, - {HOP4X(7), PIP_Y(id_N810) + left_wire_dist + 3., HOP4X(7), PIP_Y(id_N810) + 4.}, - {HOP4X(7), PIP_Y(id_N810) + 4., HOP4X(5), PIP_Y(id_N810) + left_wire_dist + 4.}, - {HOP4X(5), PIP_Y(id_N810) + left_wire_dist + 4., HOP4X(5), PIP_Y(id_N810) + 5.}, - {HOP4X(5), PIP_Y(id_N810) + 5., HOP4X(3), PIP_Y(id_N810) + left_wire_dist + 5.}, - {HOP4X(3), PIP_Y(id_N810) + left_wire_dist + 5., HOP4X(3), PIP_Y(id_N810) + 6.}, - {HOP4X(3), PIP_Y(id_N810) + 6., HOP4X(1), PIP_Y(id_N810) + left_wire_dist + 6.}, - {HOP4X(1), PIP_Y(id_N810) + left_wire_dist + 6., HOP4X(1), PIP_Y(id_N818) + 7.}, - {HOP4X(1), PIP_Y(id_N818) + 7., WIRE_X(0), PIP_Y(id_N818) + 7.}}}, - {id_S81_loop1, - {{WIRE_X(0), PIP_Y(id_S810), HOP4X(16), PIP_Y(id_S810)}, - {HOP4X(16), PIP_Y(id_S810), HOP4X(16), PIP_Y(id_N818)}, - {HOP4X(16), PIP_Y(id_N818) - 0., HOP4X(14), PIP_Y(id_N818) - left_wire_dist - 0.}, - {HOP4X(14), PIP_Y(id_N818) - left_wire_dist - 0., HOP4X(14), PIP_Y(id_N818) - 1.}, - {HOP4X(14), PIP_Y(id_N818) - 1., HOP4X(12), PIP_Y(id_N818) - left_wire_dist - 1.}, - {HOP4X(12), PIP_Y(id_N818) - left_wire_dist - 1., HOP4X(12), -wrap_len - 1.}, - {HOP4X(12), -wrap_len - 1., HOP4X(13), -wrap_len - 1.}, - {HOP4X(13), -wrap_len - 1., HOP4X(13), PIP_Y(id_N810) - 1.}, - {HOP4X(13), PIP_Y(id_N810) - 1., HOP4X(11), PIP_Y(id_N810) + left_wire_dist - 1.}, - {HOP4X(11), PIP_Y(id_N810) + left_wire_dist - 1., HOP4X(11), PIP_Y(id_N810) - 0.}, - {HOP4X(11), PIP_Y(id_N810) - 0., HOP4X(9), PIP_Y(id_N810) + left_wire_dist - 0.}, - {HOP4X(9), PIP_Y(id_N810) + left_wire_dist - 0., HOP4X(9), PIP_Y(id_N810) + 1.}, - {HOP4X(9), PIP_Y(id_N810) + 1., HOP4X(7), PIP_Y(id_N810) + left_wire_dist + 1.}, - {HOP4X(9), PIP_Y(id_N814) + 1., WIRE_X(0), PIP_Y(id_N814) + 1.}, - {HOP4X(7), PIP_Y(id_N810) + left_wire_dist + 1., HOP4X(7), PIP_Y(id_N810) + 2.}, - {HOP4X(7), PIP_Y(id_N810) + 2., HOP4X(5), PIP_Y(id_N810) + left_wire_dist + 2.}, - {HOP4X(5), PIP_Y(id_N810) + left_wire_dist + 2., HOP4X(5), PIP_Y(id_N810) + 3.}, - {HOP4X(5), PIP_Y(id_N810) + 3., HOP4X(3), PIP_Y(id_N810) + left_wire_dist + 3.}, - {HOP4X(3), PIP_Y(id_N810) + left_wire_dist + 3., HOP4X(3), PIP_Y(id_N810) + 4.}, - {HOP4X(3), PIP_Y(id_N810) + 4., HOP4X(1), PIP_Y(id_N810) + left_wire_dist + 4.}, - {HOP4X(1), PIP_Y(id_N810) + left_wire_dist + 4., HOP4X(1), PIP_Y(id_N818) + 5.}, - {HOP4X(1), PIP_Y(id_N818) + 5., WIRE_X(0), PIP_Y(id_N818) + 5.}}}, - {id_S81_loop2, - {{WIRE_X(0), PIP_Y(id_S810), HOP4X(16), PIP_Y(id_S810)}, - {HOP4X(16), PIP_Y(id_S810), HOP4X(16), PIP_Y(id_N818)}, - {HOP4X(16), PIP_Y(id_N818) - 0., HOP4X(14), PIP_Y(id_N818) - left_wire_dist - 0.}, - {HOP4X(14), PIP_Y(id_N818) - left_wire_dist - 0., HOP4X(14), PIP_Y(id_N818) - 1.}, - {HOP4X(14), PIP_Y(id_N818) - 1., HOP4X(12), PIP_Y(id_N818) - left_wire_dist - 1.}, - {HOP4X(12), PIP_Y(id_N818) - left_wire_dist - 1., HOP4X(12), PIP_Y(id_N818) - 2.}, - {HOP4X(12), PIP_Y(id_N818) - 2., HOP4X(10), PIP_Y(id_N818) - left_wire_dist - 2.}, - {HOP4X(10), PIP_Y(id_N818) - left_wire_dist - 2., HOP4X(10), -wrap_len - 2.}, - {HOP4X(10), -wrap_len - 2., HOP4X(11), -wrap_len - 2.}, - {HOP4X(11), -wrap_len - 2., HOP4X(11), PIP_Y(id_N810) - 2.}, - {HOP4X(11), PIP_Y(id_N810) - 2., HOP4X(9), PIP_Y(id_N810) + left_wire_dist - 2.}, - {HOP4X(9), PIP_Y(id_N810) + left_wire_dist - 2., HOP4X(9), PIP_Y(id_N810) - 1.}, - {HOP4X(9), PIP_Y(id_N810) - 1., HOP4X(7), PIP_Y(id_N810) + left_wire_dist - 1.}, - {HOP4X(9), PIP_Y(id_N814) - 1., WIRE_X(0), PIP_Y(id_N814) - 1.}, - {HOP4X(7), PIP_Y(id_N810) + left_wire_dist - 1., HOP4X(7), PIP_Y(id_N810) - 0.}, - {HOP4X(7), PIP_Y(id_N810) - 0., HOP4X(5), PIP_Y(id_N810) + left_wire_dist - 0.}, - {HOP4X(5), PIP_Y(id_N810) + left_wire_dist - 0., HOP4X(5), PIP_Y(id_N810) + 1.}, - {HOP4X(5), PIP_Y(id_N810) + 1., HOP4X(3), PIP_Y(id_N810) + left_wire_dist + 1.}, - {HOP4X(3), PIP_Y(id_N810) + left_wire_dist + 1., HOP4X(3), PIP_Y(id_N810) + 2.}, - {HOP4X(3), PIP_Y(id_N810) + 2., HOP4X(1), PIP_Y(id_N810) + left_wire_dist + 2.}, - {HOP4X(1), PIP_Y(id_N810) + left_wire_dist + 2., HOP4X(1), PIP_Y(id_N818) + 3.}, - {HOP4X(1), PIP_Y(id_N818) + 3., WIRE_X(0), PIP_Y(id_N818) + 3.}}}, - {id_S81_loop3, - {{WIRE_X(0), PIP_Y(id_S810), HOP4X(16), PIP_Y(id_S810)}, - {HOP4X(16), PIP_Y(id_S810), HOP4X(16), PIP_Y(id_N818)}, - {HOP4X(16), PIP_Y(id_N818) - 0., HOP4X(14), PIP_Y(id_N818) - left_wire_dist - 0.}, - {HOP4X(14), PIP_Y(id_N818) - left_wire_dist - 0., HOP4X(14), PIP_Y(id_N818) - 1.}, - {HOP4X(14), PIP_Y(id_N818) - 1., HOP4X(12), PIP_Y(id_N818) - left_wire_dist - 1.}, - {HOP4X(12), PIP_Y(id_N818) - left_wire_dist - 1., HOP4X(12), PIP_Y(id_N818) - 2.}, - {HOP4X(12), PIP_Y(id_N818) - 2., HOP4X(10), PIP_Y(id_N818) - left_wire_dist - 2.}, - {HOP4X(10), PIP_Y(id_N818) - left_wire_dist - 2., HOP4X(10), PIP_Y(id_N818) - 3.}, - {HOP4X(10), PIP_Y(id_N818) - 3., HOP4X(8), PIP_Y(id_N818) - left_wire_dist - 3.}, - {HOP4X(8), PIP_Y(id_N818) - left_wire_dist - 3., HOP4X(8), -wrap_len - 3.}, - {HOP4X(8), -wrap_len - 3., HOP4X(9), -wrap_len - 3.}, - {HOP4X(9), -wrap_len - 3., HOP4X(9), PIP_Y(id_N810) - 3.}, - {HOP4X(9), PIP_Y(id_N814) - 3., WIRE_X(0), PIP_Y(id_N814) - 3.}, - {HOP4X(9), PIP_Y(id_N810) - 3., HOP4X(7), PIP_Y(id_N810) + left_wire_dist - 3.}, - {HOP4X(7), PIP_Y(id_N810) + left_wire_dist - 3., HOP4X(7), PIP_Y(id_N810) - 2.}, - {HOP4X(7), PIP_Y(id_N810) - 2., HOP4X(5), PIP_Y(id_N810) + left_wire_dist - 2.}, - {HOP4X(5), PIP_Y(id_N810) + left_wire_dist - 2., HOP4X(5), PIP_Y(id_N810) - 1.}, - {HOP4X(5), PIP_Y(id_N810) - 1., HOP4X(3), PIP_Y(id_N810) + left_wire_dist - 1.}, - {HOP4X(3), PIP_Y(id_N810) + left_wire_dist - 1., HOP4X(3), PIP_Y(id_N810) - 0.}, - {HOP4X(3), PIP_Y(id_N810) - 0., HOP4X(1), PIP_Y(id_N810) + left_wire_dist - 0.}, - {HOP4X(1), PIP_Y(id_N810) + left_wire_dist - 0., HOP4X(1), PIP_Y(id_N818) + 1.}, - {HOP4X(1), PIP_Y(id_N818) + 1., WIRE_X(0), PIP_Y(id_N818) + 1.}}}, - {id_S81_loop4, - {{WIRE_X(0), PIP_Y(id_S810), HOP4X(16), PIP_Y(id_S810)}, - {HOP4X(16), PIP_Y(id_S810), HOP4X(16), PIP_Y(id_N818)}, - {HOP4X(16), PIP_Y(id_N818) - 0., HOP4X(14), PIP_Y(id_N818) - left_wire_dist - 0.}, - {HOP4X(14), PIP_Y(id_N818) - left_wire_dist - 0., HOP4X(14), PIP_Y(id_N818) - 1.}, - {HOP4X(14), PIP_Y(id_N818) - 1., HOP4X(12), PIP_Y(id_N818) - left_wire_dist - 1.}, - {HOP4X(12), PIP_Y(id_N818) - left_wire_dist - 1., HOP4X(12), PIP_Y(id_N818) - 2.}, - {HOP4X(12), PIP_Y(id_N818) - 2., HOP4X(10), PIP_Y(id_N818) - left_wire_dist - 2.}, - {HOP4X(10), PIP_Y(id_N818) - left_wire_dist - 2., HOP4X(10), PIP_Y(id_N818) - 3.}, - {HOP4X(10), PIP_Y(id_N818) - 3., HOP4X(8), PIP_Y(id_N818) - left_wire_dist - 3.}, - {HOP4X(8), PIP_Y(id_N818) - left_wire_dist - 3., HOP4X(8), PIP_Y(id_N818) - 4.}, - {HOP4X(8), PIP_Y(id_S814) - 4., WIRE_X(0), PIP_Y(id_S814) - 4.}, - {HOP4X(8), PIP_Y(id_N818) - 4., HOP4X(6), PIP_Y(id_N818) - left_wire_dist - 4.}, - {HOP4X(6), PIP_Y(id_N818) - left_wire_dist - 4., HOP4X(6), -wrap_len - 4.}, - {HOP4X(6), -wrap_len - 4., HOP4X(7), -wrap_len - 4.}, - {HOP4X(7), -wrap_len - 4., HOP4X(7), PIP_Y(id_N810) - 4.}, - {HOP4X(7), PIP_Y(id_N810) - 4., HOP4X(5), PIP_Y(id_N810) + left_wire_dist - 4.}, - {HOP4X(5), PIP_Y(id_N810) + left_wire_dist - 4., HOP4X(5), PIP_Y(id_N810) - 3.}, - {HOP4X(5), PIP_Y(id_N810) - 3., HOP4X(3), PIP_Y(id_N810) + left_wire_dist - 3.}, - {HOP4X(3), PIP_Y(id_N810) + left_wire_dist - 3., HOP4X(3), PIP_Y(id_N810) - 2.}, - {HOP4X(3), PIP_Y(id_N810) - 2., HOP4X(1), PIP_Y(id_N810) + left_wire_dist - 2.}, - {HOP4X(1), PIP_Y(id_N810) + left_wire_dist - 2., HOP4X(1), PIP_Y(id_N818) - 1.}, - {HOP4X(1), PIP_Y(id_N818) - 1., WIRE_X(0), PIP_Y(id_N818) - 1.}}}, - {id_S81_loop5, - {{WIRE_X(0), PIP_Y(id_S810), HOP4X(16), PIP_Y(id_S810)}, - {HOP4X(16), PIP_Y(id_S810), HOP4X(16), PIP_Y(id_N818)}, - {HOP4X(16), PIP_Y(id_N818) - 0., HOP4X(14), PIP_Y(id_N818) - left_wire_dist - 0.}, - {HOP4X(14), PIP_Y(id_N818) - left_wire_dist - 0., HOP4X(14), PIP_Y(id_N818) - 1.}, - {HOP4X(14), PIP_Y(id_N818) - 1., HOP4X(12), PIP_Y(id_N818) - left_wire_dist - 1.}, - {HOP4X(12), PIP_Y(id_N818) - left_wire_dist - 1., HOP4X(12), PIP_Y(id_N818) - 2.}, - {HOP4X(12), PIP_Y(id_N818) - 2., HOP4X(10), PIP_Y(id_N818) - left_wire_dist - 2.}, - {HOP4X(10), PIP_Y(id_N818) - left_wire_dist - 2., HOP4X(10), PIP_Y(id_N818) - 3.}, - {HOP4X(10), PIP_Y(id_N818) - 3., HOP4X(8), PIP_Y(id_N818) - left_wire_dist - 3.}, - {HOP4X(8), PIP_Y(id_N818) - left_wire_dist - 3., HOP4X(8), PIP_Y(id_N818) - 4.}, - {HOP4X(8), PIP_Y(id_S814) - 4., WIRE_X(0), PIP_Y(id_S814) - 4.}, - {HOP4X(8), PIP_Y(id_N818) - 4., HOP4X(6), PIP_Y(id_N818) - left_wire_dist - 4.}, - {HOP4X(6), PIP_Y(id_N818) - left_wire_dist - 4., HOP4X(6), PIP_Y(id_N818) - 5.}, - {HOP4X(6), PIP_Y(id_N818) - 5., HOP4X(4), PIP_Y(id_N818) - left_wire_dist - 5.}, - {HOP4X(4), PIP_Y(id_N818) - left_wire_dist - 5., HOP4X(4), -wrap_len - 5.}, - {HOP4X(4), -wrap_len - 5., HOP4X(5), -wrap_len - 5.}, - {HOP4X(5), -wrap_len - 5., HOP4X(5), PIP_Y(id_N810) - 5.}, - {HOP4X(5), PIP_Y(id_N810) - 5., HOP4X(3), PIP_Y(id_N810) + left_wire_dist - 5.}, - {HOP4X(3), PIP_Y(id_N810) + left_wire_dist - 5., HOP4X(3), PIP_Y(id_N810) - 4.}, - {HOP4X(3), PIP_Y(id_N810) - 4., HOP4X(1), PIP_Y(id_N810) + left_wire_dist - 4.}, - {HOP4X(1), PIP_Y(id_N810) + left_wire_dist - 4., HOP4X(1), PIP_Y(id_N818) - 3.}, - {HOP4X(1), PIP_Y(id_N818) - 3., WIRE_X(0), PIP_Y(id_N818) - 3.}}}, - {id_S81_loop6, - {{WIRE_X(0), PIP_Y(id_S810), HOP4X(16), PIP_Y(id_S810)}, - {HOP4X(16), PIP_Y(id_S810), HOP4X(16), PIP_Y(id_N818)}, - {HOP4X(16), PIP_Y(id_N818) - 0., HOP4X(14), PIP_Y(id_N818) - left_wire_dist - 0.}, - {HOP4X(14), PIP_Y(id_N818) - left_wire_dist - 0., HOP4X(14), PIP_Y(id_N818) - 1.}, - {HOP4X(14), PIP_Y(id_N818) - 1., HOP4X(12), PIP_Y(id_N818) - left_wire_dist - 1.}, - {HOP4X(12), PIP_Y(id_N818) - left_wire_dist - 1., HOP4X(12), PIP_Y(id_N818) - 2.}, - {HOP4X(12), PIP_Y(id_N818) - 2., HOP4X(10), PIP_Y(id_N818) - left_wire_dist - 2.}, - {HOP4X(10), PIP_Y(id_N818) - left_wire_dist - 2., HOP4X(10), PIP_Y(id_N818) - 3.}, - {HOP4X(10), PIP_Y(id_N818) - 3., HOP4X(8), PIP_Y(id_N818) - left_wire_dist - 3.}, - {HOP4X(8), PIP_Y(id_N818) - left_wire_dist - 3., HOP4X(8), PIP_Y(id_N818) - 4.}, - {HOP4X(8), PIP_Y(id_S814) - 4., WIRE_X(0), PIP_Y(id_S814) - 4.}, - {HOP4X(8), PIP_Y(id_N818) - 4., HOP4X(6), PIP_Y(id_N818) - left_wire_dist - 4.}, - {HOP4X(6), PIP_Y(id_N818) - left_wire_dist - 4., HOP4X(6), PIP_Y(id_N818) - 5.}, - {HOP4X(6), PIP_Y(id_N818) - 5., HOP4X(4), PIP_Y(id_N818) - left_wire_dist - 5.}, - {HOP4X(4), PIP_Y(id_N818) - left_wire_dist - 5., HOP4X(4), PIP_Y(id_N818) - 6.}, - {HOP4X(4), PIP_Y(id_N818) - 6., HOP4X(2), PIP_Y(id_N818) - left_wire_dist - 6.}, - {HOP4X(2), PIP_Y(id_N818) - left_wire_dist - 6., HOP4X(2), -wrap_len - 6.}, - {HOP4X(2), -wrap_len - 6., HOP4X(3), -wrap_len - 6.}, - {HOP4X(3), -wrap_len - 6., HOP4X(3), PIP_Y(id_N810) - 6.}, - {HOP4X(3), PIP_Y(id_N810) - 6., HOP4X(1), PIP_Y(id_N810) + left_wire_dist - 6.}, - {HOP4X(1), PIP_Y(id_N810) + left_wire_dist - 6., HOP4X(1), PIP_Y(id_N818) - 5.}, - {HOP4X(1), PIP_Y(id_N818) - 5., WIRE_X(0), PIP_Y(id_N818) - 5.}}}, - {id_S81_loop7, - {{WIRE_X(0), PIP_Y(id_S810), HOP4X(16), PIP_Y(id_S810)}, - {HOP4X(16), PIP_Y(id_S810), HOP4X(16), PIP_Y(id_N818)}, - {HOP4X(16), PIP_Y(id_N818) - 0., HOP4X(14), PIP_Y(id_N818) - left_wire_dist - 0.}, - {HOP4X(14), PIP_Y(id_N818) - left_wire_dist - 0., HOP4X(14), PIP_Y(id_N818) - 1.}, - {HOP4X(14), PIP_Y(id_N818) - 1., HOP4X(12), PIP_Y(id_N818) - left_wire_dist - 1.}, - {HOP4X(12), PIP_Y(id_N818) - left_wire_dist - 1., HOP4X(12), PIP_Y(id_N818) - 2.}, - {HOP4X(12), PIP_Y(id_N818) - 2., HOP4X(10), PIP_Y(id_N818) - left_wire_dist - 2.}, - {HOP4X(10), PIP_Y(id_N818) - left_wire_dist - 2., HOP4X(10), PIP_Y(id_N818) - 3.}, - {HOP4X(10), PIP_Y(id_N818) - 3., HOP4X(8), PIP_Y(id_N818) - left_wire_dist - 3.}, - {HOP4X(8), PIP_Y(id_N818) - left_wire_dist - 3., HOP4X(8), PIP_Y(id_N818) - 4.}, - {HOP4X(8), PIP_Y(id_S814) - 4., WIRE_X(0), PIP_Y(id_S814) - 4.}, - {HOP4X(8), PIP_Y(id_N818) - 4., HOP4X(6), PIP_Y(id_N818) - left_wire_dist - 4.}, - {HOP4X(6), PIP_Y(id_N818) - left_wire_dist - 4., HOP4X(6), PIP_Y(id_N818) - 5.}, - {HOP4X(6), PIP_Y(id_N818) - 5., HOP4X(4), PIP_Y(id_N818) - left_wire_dist - 5.}, - {HOP4X(4), PIP_Y(id_N818) - left_wire_dist - 5., HOP4X(4), PIP_Y(id_N818) - 6.}, - {HOP4X(4), PIP_Y(id_N818) - 6., HOP4X(2), PIP_Y(id_N818) - left_wire_dist - 6.}, - {HOP4X(2), PIP_Y(id_N818) - left_wire_dist - 6., HOP4X(2), PIP_Y(id_N818) - 7.}, - {HOP4X(2), PIP_Y(id_N818) - 7., HOP4X(0), PIP_Y(id_N818) - left_wire_dist - 7.}, - {HOP4X(0), PIP_Y(id_N818) - left_wire_dist - 7., HOP4X(0), -wrap_len - 7.}, - {HOP4X(0), -wrap_len - 7., HOP4X(1), -wrap_len - 7.}, - {HOP4X(1), -wrap_len - 7., HOP4X(1), PIP_Y(id_N818) - 7.}, - {HOP4X(1), PIP_Y(id_N818) - 7., WIRE_X(0), PIP_Y(id_N818) - 7.}}}, - {id_N81_loop0, - {{WIRE_X(0), PIP_Y(id_N810), HOP4X(17), PIP_Y(id_N810)}, - {HOP4X(17), PIP_Y(id_N810) + 0., HOP4X(15), PIP_Y(id_N810) + left_wire_dist + 0.}, - {HOP4X(15), PIP_Y(id_N810) + left_wire_dist + 0., HOP4X(15), wrap_len + 1.}, - {HOP4X(15), wrap_len + 1., HOP4X(14), wrap_len + 1.}, - {HOP4X(14), wrap_len + 1., HOP4X(14), PIP_Y(id_N818) + 0.}, - {HOP4X(14), PIP_Y(id_N818) + 0., HOP4X(12), PIP_Y(id_N818) - left_wire_dist + 0.}, - {HOP4X(12), PIP_Y(id_N818) - left_wire_dist + 0., HOP4X(12), PIP_Y(id_N818) - 1.}, - {HOP4X(12), PIP_Y(id_N818) - 1., HOP4X(10), PIP_Y(id_N818) - left_wire_dist - 1.}, - {HOP4X(10), PIP_Y(id_N818) - left_wire_dist - 1., HOP4X(10), PIP_Y(id_N818) - 2.}, - {HOP4X(10), PIP_Y(id_N818) - 2., HOP4X(8), PIP_Y(id_N818) - left_wire_dist - 2.}, - {HOP4X(8), PIP_Y(id_N818) - left_wire_dist - 2., HOP4X(8), PIP_Y(id_N818) - 3.}, - {HOP4X(8), PIP_Y(id_S814) - 3., WIRE_X(0), PIP_Y(id_S814) - 3.}, - {HOP4X(8), PIP_Y(id_N818) - 3., HOP4X(6), PIP_Y(id_N818) - left_wire_dist - 3.}, - {HOP4X(6), PIP_Y(id_N818) - left_wire_dist - 3., HOP4X(6), PIP_Y(id_N818) - 4.}, - {HOP4X(6), PIP_Y(id_N818) - 4., HOP4X(4), PIP_Y(id_N818) - left_wire_dist - 4.}, - {HOP4X(4), PIP_Y(id_N818) - left_wire_dist - 4., HOP4X(4), PIP_Y(id_N818) - 5.}, - {HOP4X(4), PIP_Y(id_N818) - 5., HOP4X(2), PIP_Y(id_N818) - left_wire_dist - 5.}, - {HOP4X(2), PIP_Y(id_N818) - left_wire_dist - 5., HOP4X(2), PIP_Y(id_N818) - 6.}, - {HOP4X(2), PIP_Y(id_N818) - 6., HOP4X(0), PIP_Y(id_N818) - left_wire_dist - 6.}, - {HOP4X(0), PIP_Y(id_N818) - left_wire_dist - 6., HOP4X(0), PIP_Y(id_S818) - 7.}, - {HOP4X(0), PIP_Y(id_S818) - 7., WIRE_X(0), PIP_Y(id_S818) - 7.}}}, - {id_N81_loop1, - {{WIRE_X(0), PIP_Y(id_N810), HOP4X(17), PIP_Y(id_N810)}, - {HOP4X(17), PIP_Y(id_N810) + 0., HOP4X(15), PIP_Y(id_N810) + left_wire_dist + 0.}, - {HOP4X(15), PIP_Y(id_N810) + left_wire_dist + 0., HOP4X(15), PIP_Y(id_N810) + 1.}, - {HOP4X(15), PIP_Y(id_N810) + 1., HOP4X(13), PIP_Y(id_N810) + left_wire_dist + 1.}, - {HOP4X(13), PIP_Y(id_N810) + left_wire_dist + 1., HOP4X(13), wrap_len + 2.}, - {HOP4X(13), wrap_len + 2., HOP4X(12), wrap_len + 2.}, - {HOP4X(12), wrap_len + 2., HOP4X(12), PIP_Y(id_N818) + 1.}, - {HOP4X(12), PIP_Y(id_N818) + 1., HOP4X(10), PIP_Y(id_N818) - left_wire_dist + 1.}, - {HOP4X(10), PIP_Y(id_N818) - left_wire_dist + 1., HOP4X(10), PIP_Y(id_N818) + 0.}, - {HOP4X(10), PIP_Y(id_N818) + 0., HOP4X(8), PIP_Y(id_N818) - left_wire_dist + 0.}, - {HOP4X(8), PIP_Y(id_N818) - left_wire_dist + 0., HOP4X(8), PIP_Y(id_N818) - 1.}, - {HOP4X(8), PIP_Y(id_S814) - 1., WIRE_X(0), PIP_Y(id_S814) - 1.}, - {HOP4X(8), PIP_Y(id_N818) - 1., HOP4X(6), PIP_Y(id_N818) - left_wire_dist - 1.}, - {HOP4X(6), PIP_Y(id_N818) - left_wire_dist - 1., HOP4X(6), PIP_Y(id_N818) - 2.}, - {HOP4X(6), PIP_Y(id_N818) - 2., HOP4X(4), PIP_Y(id_N818) - left_wire_dist - 2.}, - {HOP4X(4), PIP_Y(id_N818) - left_wire_dist - 2., HOP4X(4), PIP_Y(id_N818) - 3.}, - {HOP4X(4), PIP_Y(id_N818) - 3., HOP4X(2), PIP_Y(id_N818) - left_wire_dist - 3.}, - {HOP4X(2), PIP_Y(id_N818) - left_wire_dist - 3., HOP4X(2), PIP_Y(id_N818) - 4.}, - {HOP4X(2), PIP_Y(id_N818) - 4., HOP4X(0), PIP_Y(id_N818) - left_wire_dist - 4.}, - {HOP4X(0), PIP_Y(id_N818) - left_wire_dist - 4., HOP4X(0), PIP_Y(id_S818) - 5.}, - {HOP4X(0), PIP_Y(id_S818) - 5., WIRE_X(0), PIP_Y(id_S818) - 5.}}}, - {id_N81_loop2, - {{WIRE_X(0), PIP_Y(id_N810), HOP4X(17), PIP_Y(id_N810)}, - {HOP4X(17), PIP_Y(id_N810) + 0., HOP4X(15), PIP_Y(id_N810) + left_wire_dist + 0.}, - {HOP4X(15), PIP_Y(id_N810) + left_wire_dist + 0., HOP4X(15), PIP_Y(id_N810) + 1.}, - {HOP4X(15), PIP_Y(id_N810) + 1., HOP4X(13), PIP_Y(id_N810) + left_wire_dist + 1.}, - {HOP4X(13), PIP_Y(id_N810) + left_wire_dist + 1., HOP4X(13), PIP_Y(id_N810) + 2.}, - {HOP4X(13), PIP_Y(id_N810) + 2., HOP4X(11), PIP_Y(id_N810) + left_wire_dist + 2.}, - {HOP4X(11), PIP_Y(id_N810) + left_wire_dist + 2., HOP4X(11), wrap_len + 3.}, - {HOP4X(11), wrap_len + 3., HOP4X(10), wrap_len + 3.}, - {HOP4X(10), wrap_len + 3., HOP4X(10), PIP_Y(id_N818) + 2.}, - {HOP4X(10), PIP_Y(id_N818) + 2., HOP4X(8), PIP_Y(id_N818) - left_wire_dist + 2.}, - {HOP4X(8), PIP_Y(id_N818) - left_wire_dist + 2., HOP4X(8), PIP_Y(id_N818) + 1.}, - {HOP4X(8), PIP_Y(id_S814) + 1., WIRE_X(0), PIP_Y(id_S814) + 1.}, - {HOP4X(8), PIP_Y(id_N818) + 1., HOP4X(6), PIP_Y(id_N818) - left_wire_dist + 1.}, - {HOP4X(6), PIP_Y(id_N818) - left_wire_dist + 1., HOP4X(6), PIP_Y(id_N818) + 0.}, - {HOP4X(6), PIP_Y(id_N818) + 0., HOP4X(4), PIP_Y(id_N818) - left_wire_dist + 0.}, - {HOP4X(4), PIP_Y(id_N818) - left_wire_dist + 0., HOP4X(4), PIP_Y(id_N818) - 1.}, - {HOP4X(4), PIP_Y(id_N818) - 1., HOP4X(2), PIP_Y(id_N818) - left_wire_dist - 1.}, - {HOP4X(2), PIP_Y(id_N818) - left_wire_dist - 1., HOP4X(2), PIP_Y(id_N818) - 2.}, - {HOP4X(2), PIP_Y(id_N818) - 2., HOP4X(0), PIP_Y(id_N818) - left_wire_dist - 2.}, - {HOP4X(0), PIP_Y(id_N818) - left_wire_dist - 2., HOP4X(0), PIP_Y(id_S818) - 3.}, - {HOP4X(0), PIP_Y(id_S818) - 3., WIRE_X(0), PIP_Y(id_S818) - 3.}}}, - {id_N81_loop3, - {{WIRE_X(0), PIP_Y(id_N810), HOP4X(17), PIP_Y(id_N810)}, - {HOP4X(17), PIP_Y(id_N810) + 0., HOP4X(15), PIP_Y(id_N810) + left_wire_dist + 0.}, - {HOP4X(15), PIP_Y(id_N810) + left_wire_dist + 0., HOP4X(15), PIP_Y(id_N810) + 1.}, - {HOP4X(15), PIP_Y(id_N810) + 1., HOP4X(13), PIP_Y(id_N810) + left_wire_dist + 1.}, - {HOP4X(13), PIP_Y(id_N810) + left_wire_dist + 1., HOP4X(13), PIP_Y(id_N810) + 2.}, - {HOP4X(13), PIP_Y(id_N810) + 2., HOP4X(11), PIP_Y(id_N810) + left_wire_dist + 2.}, - {HOP4X(11), PIP_Y(id_N810) + left_wire_dist + 2., HOP4X(11), PIP_Y(id_N810) + 3.}, - {HOP4X(11), PIP_Y(id_N810) + 3., HOP4X(9), PIP_Y(id_N810) + left_wire_dist + 3.}, - {HOP4X(9), PIP_Y(id_N810) + left_wire_dist + 3., HOP4X(9), wrap_len + 4.}, - {HOP4X(9), wrap_len + 4., HOP4X(8), wrap_len + 4.}, - {HOP4X(8), wrap_len + 4., HOP4X(8), PIP_Y(id_N818) + 3.}, - {HOP4X(8), PIP_Y(id_S814) + 3., WIRE_X(0), PIP_Y(id_S814) + 3.}, - {HOP4X(8), PIP_Y(id_N818) + 3., HOP4X(6), PIP_Y(id_N818) - left_wire_dist + 3.}, - {HOP4X(6), PIP_Y(id_N818) - left_wire_dist + 3., HOP4X(6), PIP_Y(id_N818) + 2.}, - {HOP4X(6), PIP_Y(id_N818) + 2., HOP4X(4), PIP_Y(id_N818) - left_wire_dist + 2.}, - {HOP4X(4), PIP_Y(id_N818) - left_wire_dist + 2., HOP4X(4), PIP_Y(id_N818) + 1.}, - {HOP4X(4), PIP_Y(id_N818) + 1., HOP4X(2), PIP_Y(id_N818) - left_wire_dist + 1.}, - {HOP4X(2), PIP_Y(id_N818) - left_wire_dist + 1., HOP4X(2), PIP_Y(id_N818) + 0.}, - {HOP4X(2), PIP_Y(id_N818) + 0., HOP4X(0), PIP_Y(id_N818) - left_wire_dist + 0.}, - {HOP4X(0), PIP_Y(id_N818) - left_wire_dist + 0., HOP4X(0), PIP_Y(id_S818) - 1.}, - {HOP4X(0), PIP_Y(id_S818) - 1., WIRE_X(0), PIP_Y(id_S818) - 1.}}}, - {id_N81_loop4, - {{WIRE_X(0), PIP_Y(id_N810), HOP4X(17), PIP_Y(id_N810)}, - {HOP4X(17), PIP_Y(id_N810) + 0., HOP4X(15), PIP_Y(id_N810) + left_wire_dist + 0.}, - {HOP4X(15), PIP_Y(id_N810) + left_wire_dist + 0., HOP4X(15), PIP_Y(id_N810) + 1.}, - {HOP4X(15), PIP_Y(id_N810) + 1., HOP4X(13), PIP_Y(id_N810) + left_wire_dist + 1.}, - {HOP4X(13), PIP_Y(id_N810) + left_wire_dist + 1., HOP4X(13), PIP_Y(id_N810) + 2.}, - {HOP4X(13), PIP_Y(id_N810) + 2., HOP4X(11), PIP_Y(id_N810) + left_wire_dist + 2.}, - {HOP4X(11), PIP_Y(id_N810) + left_wire_dist + 2., HOP4X(11), PIP_Y(id_N810) + 3.}, - {HOP4X(11), PIP_Y(id_N810) + 3., HOP4X(9), PIP_Y(id_N810) + left_wire_dist + 3.}, - {HOP4X(9), PIP_Y(id_N810) + left_wire_dist + 3., HOP4X(9), PIP_Y(id_N810) + 4.}, - {HOP4X(9), PIP_Y(id_N814) + 4., WIRE_X(0), PIP_Y(id_N814) + 4.}, - {HOP4X(9), PIP_Y(id_N810) + 4., HOP4X(7), PIP_Y(id_N810) + left_wire_dist + 4.}, - {HOP4X(7), PIP_Y(id_N810) + left_wire_dist + 4., HOP4X(7), wrap_len + 5.}, - {HOP4X(7), wrap_len + 5., HOP4X(6), wrap_len + 5.}, - {HOP4X(6), wrap_len + 5., HOP4X(6), PIP_Y(id_N818) + 4.}, - {HOP4X(6), PIP_Y(id_N818) + 4., HOP4X(4), PIP_Y(id_N818) - left_wire_dist + 4.}, - {HOP4X(4), PIP_Y(id_N818) - left_wire_dist + 4., HOP4X(4), PIP_Y(id_N818) + 3.}, - {HOP4X(4), PIP_Y(id_N818) + 3., HOP4X(2), PIP_Y(id_N818) - left_wire_dist + 3.}, - {HOP4X(2), PIP_Y(id_N818) - left_wire_dist + 3., HOP4X(2), PIP_Y(id_N818) + 2.}, - {HOP4X(2), PIP_Y(id_N818) + 2., HOP4X(0), PIP_Y(id_N818) - left_wire_dist + 2.}, - {HOP4X(0), PIP_Y(id_N818) - left_wire_dist + 2., HOP4X(0), PIP_Y(id_S818) + 1.}, - {HOP4X(0), PIP_Y(id_S818) + 1., WIRE_X(0), PIP_Y(id_S818) + 1.}}}, - {id_N81_loop5, - {{WIRE_X(0), PIP_Y(id_N810), HOP4X(17), PIP_Y(id_N810)}, - {HOP4X(17), PIP_Y(id_N810) + 0., HOP4X(15), PIP_Y(id_N810) + left_wire_dist + 0.}, - {HOP4X(15), PIP_Y(id_N810) + left_wire_dist + 0., HOP4X(15), PIP_Y(id_N810) + 1.}, - {HOP4X(15), PIP_Y(id_N810) + 1., HOP4X(13), PIP_Y(id_N810) + left_wire_dist + 1.}, - {HOP4X(13), PIP_Y(id_N810) + left_wire_dist + 1., HOP4X(13), PIP_Y(id_N810) + 2.}, - {HOP4X(13), PIP_Y(id_N810) + 2., HOP4X(11), PIP_Y(id_N810) + left_wire_dist + 2.}, - {HOP4X(11), PIP_Y(id_N810) + left_wire_dist + 2., HOP4X(11), PIP_Y(id_N810) + 3.}, - {HOP4X(11), PIP_Y(id_N810) + 3., HOP4X(9), PIP_Y(id_N810) + left_wire_dist + 3.}, - {HOP4X(9), PIP_Y(id_N810) + left_wire_dist + 3., HOP4X(9), PIP_Y(id_N810) + 4.}, - {HOP4X(9), PIP_Y(id_N814) + 4., WIRE_X(0), PIP_Y(id_N814) + 4.}, - {HOP4X(9), PIP_Y(id_N810) + 4., HOP4X(7), PIP_Y(id_N810) + left_wire_dist + 4.}, - {HOP4X(7), PIP_Y(id_N810) + left_wire_dist + 4., HOP4X(7), PIP_Y(id_N810) + 5.}, - {HOP4X(7), PIP_Y(id_N810) + 5., HOP4X(5), PIP_Y(id_N810) + left_wire_dist + 5.}, - {HOP4X(5), PIP_Y(id_N810) + left_wire_dist + 5., HOP4X(5), wrap_len + 6.}, - {HOP4X(5), wrap_len + 6., HOP4X(4), wrap_len + 6.}, - {HOP4X(4), wrap_len + 6., HOP4X(4), PIP_Y(id_N818) + 5.}, - {HOP4X(4), PIP_Y(id_N818) + 5., HOP4X(2), PIP_Y(id_N818) - left_wire_dist + 5.}, - {HOP4X(2), PIP_Y(id_N818) - left_wire_dist + 5., HOP4X(2), PIP_Y(id_N818) + 4.}, - {HOP4X(2), PIP_Y(id_N818) + 4., HOP4X(0), PIP_Y(id_N818) - left_wire_dist + 4.}, - {HOP4X(0), PIP_Y(id_N818) - left_wire_dist + 4., HOP4X(0), PIP_Y(id_S818) + 3.}, - {HOP4X(0), PIP_Y(id_S818) + 3., WIRE_X(0), PIP_Y(id_S818) + 3.}}}, - {id_N81_loop6, - {{WIRE_X(0), PIP_Y(id_N810), HOP4X(17), PIP_Y(id_N810)}, - {HOP4X(17), PIP_Y(id_N810) + 0., HOP4X(15), PIP_Y(id_N810) + left_wire_dist + 0.}, - {HOP4X(15), PIP_Y(id_N810) + left_wire_dist + 0., HOP4X(15), PIP_Y(id_N810) + 1.}, - {HOP4X(15), PIP_Y(id_N810) + 1., HOP4X(13), PIP_Y(id_N810) + left_wire_dist + 1.}, - {HOP4X(13), PIP_Y(id_N810) + left_wire_dist + 1., HOP4X(13), PIP_Y(id_N810) + 2.}, - {HOP4X(13), PIP_Y(id_N810) + 2., HOP4X(11), PIP_Y(id_N810) + left_wire_dist + 2.}, - {HOP4X(11), PIP_Y(id_N810) + left_wire_dist + 2., HOP4X(11), PIP_Y(id_N810) + 3.}, - {HOP4X(11), PIP_Y(id_N810) + 3., HOP4X(9), PIP_Y(id_N810) + left_wire_dist + 3.}, - {HOP4X(9), PIP_Y(id_N810) + left_wire_dist + 3., HOP4X(9), PIP_Y(id_N810) + 4.}, - {HOP4X(9), PIP_Y(id_N814) + 4., WIRE_X(0), PIP_Y(id_N814) + 4.}, - {HOP4X(9), PIP_Y(id_N810) + 4., HOP4X(7), PIP_Y(id_N810) + left_wire_dist + 4.}, - {HOP4X(7), PIP_Y(id_N810) + left_wire_dist + 4., HOP4X(7), PIP_Y(id_N810) + 5.}, - {HOP4X(7), PIP_Y(id_N810) + 5., HOP4X(5), PIP_Y(id_N810) + left_wire_dist + 5.}, - {HOP4X(5), PIP_Y(id_N810) + left_wire_dist + 5., HOP4X(5), PIP_Y(id_N810) + 6.}, - {HOP4X(5), PIP_Y(id_N810) + 6., HOP4X(3), PIP_Y(id_N810) + left_wire_dist + 6.}, - {HOP4X(3), PIP_Y(id_N810) + left_wire_dist + 6., HOP4X(3), wrap_len + 7.}, - {HOP4X(3), wrap_len + 7., HOP4X(2), wrap_len + 7.}, - {HOP4X(2), wrap_len + 7., HOP4X(2), PIP_Y(id_N818) + 6.}, - {HOP4X(2), PIP_Y(id_N818) + 6., HOP4X(0), PIP_Y(id_N818) - left_wire_dist + 6.}, - {HOP4X(0), PIP_Y(id_N818) - left_wire_dist + 6., HOP4X(0), PIP_Y(id_S818) + 5.}, - {HOP4X(0), PIP_Y(id_S818) + 5., WIRE_X(0), PIP_Y(id_S818) + 5.}}}, - {id_N81_loop7, - {{WIRE_X(0), PIP_Y(id_N810), HOP4X(17), PIP_Y(id_N810)}, - {HOP4X(17), PIP_Y(id_N810) + 0., HOP4X(15), PIP_Y(id_N810) + left_wire_dist + 0.}, - {HOP4X(15), PIP_Y(id_N810) + left_wire_dist + 0., HOP4X(15), PIP_Y(id_N810) + 1.}, - {HOP4X(15), PIP_Y(id_N810) + 1., HOP4X(13), PIP_Y(id_N810) + left_wire_dist + 1.}, - {HOP4X(13), PIP_Y(id_N810) + left_wire_dist + 1., HOP4X(13), PIP_Y(id_N810) + 2.}, - {HOP4X(13), PIP_Y(id_N810) + 2., HOP4X(11), PIP_Y(id_N810) + left_wire_dist + 2.}, - {HOP4X(11), PIP_Y(id_N810) + left_wire_dist + 2., HOP4X(11), PIP_Y(id_N810) + 3.}, - {HOP4X(11), PIP_Y(id_N810) + 3., HOP4X(9), PIP_Y(id_N810) + left_wire_dist + 3.}, - {HOP4X(9), PIP_Y(id_N810) + left_wire_dist + 3., HOP4X(9), PIP_Y(id_N810) + 4.}, - {HOP4X(9), PIP_Y(id_N814) + 4., WIRE_X(0), PIP_Y(id_N814) + 4.}, - {HOP4X(9), PIP_Y(id_N810) + 4., HOP4X(7), PIP_Y(id_N810) + left_wire_dist + 4.}, - {HOP4X(7), PIP_Y(id_N810) + left_wire_dist + 4., HOP4X(7), PIP_Y(id_N810) + 5.}, - {HOP4X(7), PIP_Y(id_N810) + 5., HOP4X(5), PIP_Y(id_N810) + left_wire_dist + 5.}, - {HOP4X(5), PIP_Y(id_N810) + left_wire_dist + 5., HOP4X(5), PIP_Y(id_N810) + 6.}, - {HOP4X(5), PIP_Y(id_N810) + 6., HOP4X(3), PIP_Y(id_N810) + left_wire_dist + 6.}, - {HOP4X(3), PIP_Y(id_N810) + left_wire_dist + 6., HOP4X(3), PIP_Y(id_N810) + 7.}, - {HOP4X(3), PIP_Y(id_N810) + 7., HOP4X(1), PIP_Y(id_N810) + left_wire_dist + 7.}, - {HOP4X(1), PIP_Y(id_N810) + left_wire_dist + 7., HOP4X(1), wrap_len + 8.}, - {HOP4X(1), wrap_len + 8., HOP4X(0), wrap_len + 8.}, - {HOP4X(0), wrap_len + 8., HOP4X(0), PIP_Y(id_S818) + 7.}, - {HOP4X(0), PIP_Y(id_S818) + 7., WIRE_X(0), PIP_Y(id_S818) + 7.}}}, - -#undef HOP4X -#define HOP4X(offset) WIRE_X((float)offset + HOP4X_START + 18.f + 18.f) - {id_S82, - {{WIRE_X(0), PIP_Y(id_S820), HOP4X(16), PIP_Y(id_S820)}, - {HOP4X(16), PIP_Y(id_S820), HOP4X(16), PIP_Y(id_N828)}, - {HOP4X(16), PIP_Y(id_N828) - 0., HOP4X(14), PIP_Y(id_N828) - left_wire_dist - 0.}, - {HOP4X(14), PIP_Y(id_N828) - left_wire_dist - 0., HOP4X(14), PIP_Y(id_N828) - 1.}, - {HOP4X(14), PIP_Y(id_N828) - 1., HOP4X(12), PIP_Y(id_N828) - left_wire_dist - 1.}, - {HOP4X(12), PIP_Y(id_N828) - left_wire_dist - 1., HOP4X(12), PIP_Y(id_N828) - 2.}, - {HOP4X(12), PIP_Y(id_N828) - 2., HOP4X(10), PIP_Y(id_N828) - left_wire_dist - 2.}, - {HOP4X(10), PIP_Y(id_N828) - left_wire_dist - 2., HOP4X(10), PIP_Y(id_N828) - 3.}, - {HOP4X(10), PIP_Y(id_N828) - 3., HOP4X(8), PIP_Y(id_N828) - left_wire_dist - 3.}, - {HOP4X(8), PIP_Y(id_N828) - left_wire_dist - 3., HOP4X(8), PIP_Y(id_N828) - 4.}, - {HOP4X(8), PIP_Y(id_S824) - 4., WIRE_X(0), PIP_Y(id_S824) - 4.}, - {HOP4X(8), PIP_Y(id_N828) - 4., HOP4X(6), PIP_Y(id_N828) - left_wire_dist - 4.}, - {HOP4X(6), PIP_Y(id_N828) - left_wire_dist - 4., HOP4X(6), PIP_Y(id_N828) - 5.}, - {HOP4X(6), PIP_Y(id_N828) - 5., HOP4X(4), PIP_Y(id_N828) - left_wire_dist - 5.}, - {HOP4X(4), PIP_Y(id_N828) - left_wire_dist - 5., HOP4X(4), PIP_Y(id_N828) - 6.}, - {HOP4X(4), PIP_Y(id_N828) - 6., HOP4X(2), PIP_Y(id_N828) - left_wire_dist - 6.}, - {HOP4X(2), PIP_Y(id_N828) - left_wire_dist - 6., HOP4X(2), PIP_Y(id_N828) - 7.}, - {HOP4X(2), PIP_Y(id_N828) - 7., HOP4X(0), PIP_Y(id_N828) - left_wire_dist - 7.}, - {HOP4X(0), PIP_Y(id_N828) - left_wire_dist - 7., HOP4X(0), PIP_Y(id_S828) - 8.}, - {HOP4X(0), PIP_Y(id_S828) - 8., WIRE_X(0), PIP_Y(id_S828) - 8.}}}, - {id_N82, - {{WIRE_X(0), PIP_Y(id_N820), HOP4X(17), PIP_Y(id_N820)}, - {HOP4X(17), PIP_Y(id_N820) + 0., HOP4X(15), PIP_Y(id_N820) + left_wire_dist + 0.}, - {HOP4X(15), PIP_Y(id_N820) + left_wire_dist + 0., HOP4X(15), PIP_Y(id_N820) + 1.}, - {HOP4X(15), PIP_Y(id_N820) + 1., HOP4X(13), PIP_Y(id_N820) + left_wire_dist + 1.}, - {HOP4X(13), PIP_Y(id_N820) + left_wire_dist + 1., HOP4X(13), PIP_Y(id_N820) + 2.}, - {HOP4X(13), PIP_Y(id_N820) + 2., HOP4X(11), PIP_Y(id_N820) + left_wire_dist + 2.}, - {HOP4X(11), PIP_Y(id_N820) + left_wire_dist + 2., HOP4X(11), PIP_Y(id_N820) + 3.}, - {HOP4X(11), PIP_Y(id_N820) + 3., HOP4X(9), PIP_Y(id_N820) + left_wire_dist + 3.}, - {HOP4X(9), PIP_Y(id_N820) + left_wire_dist + 3., HOP4X(9), PIP_Y(id_N820) + 4.}, - {HOP4X(9), PIP_Y(id_N824) + 4., WIRE_X(0), PIP_Y(id_N824) + 4.}, - {HOP4X(9), PIP_Y(id_N820) + 4., HOP4X(7), PIP_Y(id_N820) + left_wire_dist + 4.}, - {HOP4X(7), PIP_Y(id_N820) + left_wire_dist + 4., HOP4X(7), PIP_Y(id_N820) + 5.}, - {HOP4X(7), PIP_Y(id_N820) + 5., HOP4X(5), PIP_Y(id_N820) + left_wire_dist + 5.}, - {HOP4X(5), PIP_Y(id_N820) + left_wire_dist + 5., HOP4X(5), PIP_Y(id_N820) + 6.}, - {HOP4X(5), PIP_Y(id_N820) + 6., HOP4X(3), PIP_Y(id_N820) + left_wire_dist + 6.}, - {HOP4X(3), PIP_Y(id_N820) + left_wire_dist + 6., HOP4X(3), PIP_Y(id_N820) + 7.}, - {HOP4X(3), PIP_Y(id_N820) + 7., HOP4X(1), PIP_Y(id_N820) + left_wire_dist + 7.}, - {HOP4X(1), PIP_Y(id_N820) + left_wire_dist + 7., HOP4X(1), PIP_Y(id_N828) + 8.}, - {HOP4X(1), PIP_Y(id_N828) + 8., WIRE_X(0), PIP_Y(id_N828) + 8.}}}, - {id_S82_loop0, - {{WIRE_X(0), PIP_Y(id_S820), HOP4X(16), PIP_Y(id_S820)}, - {HOP4X(16), PIP_Y(id_S820), HOP4X(16), PIP_Y(id_N828)}, - {HOP4X(16), PIP_Y(id_N828) - 0., HOP4X(14), PIP_Y(id_N828) - left_wire_dist - 0.}, - {HOP4X(14), PIP_Y(id_N828) - left_wire_dist - 0., HOP4X(14), -wrap_len - 0.}, - {HOP4X(14), -wrap_len - 0., HOP4X(15), -wrap_len - 0.}, - {HOP4X(15), -wrap_len - 0., HOP4X(15), PIP_Y(id_N820) - 0.}, - {HOP4X(15), PIP_Y(id_N820) - 0., HOP4X(13), PIP_Y(id_N820) + left_wire_dist - 0.}, - {HOP4X(13), PIP_Y(id_N820) + left_wire_dist - 0., HOP4X(13), PIP_Y(id_N820) + 1.}, - {HOP4X(13), PIP_Y(id_N820) + 1., HOP4X(11), PIP_Y(id_N820) + left_wire_dist + 1.}, - {HOP4X(11), PIP_Y(id_N820) + left_wire_dist + 1., HOP4X(11), PIP_Y(id_N820) + 2.}, - {HOP4X(11), PIP_Y(id_N820) + 2., HOP4X(9), PIP_Y(id_N820) + left_wire_dist + 2.}, - {HOP4X(9), PIP_Y(id_N820) + left_wire_dist + 2., HOP4X(9), PIP_Y(id_N820) + 3.}, - {HOP4X(9), PIP_Y(id_N820) + 3., HOP4X(7), PIP_Y(id_N820) + left_wire_dist + 3.}, - {HOP4X(9), PIP_Y(id_N824) + 3., WIRE_X(0), PIP_Y(id_N824) + 3.}, - {HOP4X(7), PIP_Y(id_N820) + left_wire_dist + 3., HOP4X(7), PIP_Y(id_N820) + 4.}, - {HOP4X(7), PIP_Y(id_N820) + 4., HOP4X(5), PIP_Y(id_N820) + left_wire_dist + 4.}, - {HOP4X(5), PIP_Y(id_N820) + left_wire_dist + 4., HOP4X(5), PIP_Y(id_N820) + 5.}, - {HOP4X(5), PIP_Y(id_N820) + 5., HOP4X(3), PIP_Y(id_N820) + left_wire_dist + 5.}, - {HOP4X(3), PIP_Y(id_N820) + left_wire_dist + 5., HOP4X(3), PIP_Y(id_N820) + 6.}, - {HOP4X(3), PIP_Y(id_N820) + 6., HOP4X(1), PIP_Y(id_N820) + left_wire_dist + 6.}, - {HOP4X(1), PIP_Y(id_N820) + left_wire_dist + 6., HOP4X(1), PIP_Y(id_N828) + 7.}, - {HOP4X(1), PIP_Y(id_N828) + 7., WIRE_X(0), PIP_Y(id_N828) + 7.}}}, - {id_S82_loop1, - {{WIRE_X(0), PIP_Y(id_S820), HOP4X(16), PIP_Y(id_S820)}, - {HOP4X(16), PIP_Y(id_S820), HOP4X(16), PIP_Y(id_N828)}, - {HOP4X(16), PIP_Y(id_N828) - 0., HOP4X(14), PIP_Y(id_N828) - left_wire_dist - 0.}, - {HOP4X(14), PIP_Y(id_N828) - left_wire_dist - 0., HOP4X(14), PIP_Y(id_N828) - 1.}, - {HOP4X(14), PIP_Y(id_N828) - 1., HOP4X(12), PIP_Y(id_N828) - left_wire_dist - 1.}, - {HOP4X(12), PIP_Y(id_N828) - left_wire_dist - 1., HOP4X(12), -wrap_len - 1.}, - {HOP4X(12), -wrap_len - 1., HOP4X(13), -wrap_len - 1.}, - {HOP4X(13), -wrap_len - 1., HOP4X(13), PIP_Y(id_N820) - 1.}, - {HOP4X(13), PIP_Y(id_N820) - 1., HOP4X(11), PIP_Y(id_N820) + left_wire_dist - 1.}, - {HOP4X(11), PIP_Y(id_N820) + left_wire_dist - 1., HOP4X(11), PIP_Y(id_N820) - 0.}, - {HOP4X(11), PIP_Y(id_N820) - 0., HOP4X(9), PIP_Y(id_N820) + left_wire_dist - 0.}, - {HOP4X(9), PIP_Y(id_N820) + left_wire_dist - 0., HOP4X(9), PIP_Y(id_N820) + 1.}, - {HOP4X(9), PIP_Y(id_N820) + 1., HOP4X(7), PIP_Y(id_N820) + left_wire_dist + 1.}, - {HOP4X(9), PIP_Y(id_N824) + 1., WIRE_X(0), PIP_Y(id_N824) + 1.}, - {HOP4X(7), PIP_Y(id_N820) + left_wire_dist + 1., HOP4X(7), PIP_Y(id_N820) + 2.}, - {HOP4X(7), PIP_Y(id_N820) + 2., HOP4X(5), PIP_Y(id_N820) + left_wire_dist + 2.}, - {HOP4X(5), PIP_Y(id_N820) + left_wire_dist + 2., HOP4X(5), PIP_Y(id_N820) + 3.}, - {HOP4X(5), PIP_Y(id_N820) + 3., HOP4X(3), PIP_Y(id_N820) + left_wire_dist + 3.}, - {HOP4X(3), PIP_Y(id_N820) + left_wire_dist + 3., HOP4X(3), PIP_Y(id_N820) + 4.}, - {HOP4X(3), PIP_Y(id_N820) + 4., HOP4X(1), PIP_Y(id_N820) + left_wire_dist + 4.}, - {HOP4X(1), PIP_Y(id_N820) + left_wire_dist + 4., HOP4X(1), PIP_Y(id_N828) + 5.}, - {HOP4X(1), PIP_Y(id_N828) + 5., WIRE_X(0), PIP_Y(id_N828) + 5.}}}, - {id_S82_loop2, - {{WIRE_X(0), PIP_Y(id_S820), HOP4X(16), PIP_Y(id_S820)}, - {HOP4X(16), PIP_Y(id_S820), HOP4X(16), PIP_Y(id_N828)}, - {HOP4X(16), PIP_Y(id_N828) - 0., HOP4X(14), PIP_Y(id_N828) - left_wire_dist - 0.}, - {HOP4X(14), PIP_Y(id_N828) - left_wire_dist - 0., HOP4X(14), PIP_Y(id_N828) - 1.}, - {HOP4X(14), PIP_Y(id_N828) - 1., HOP4X(12), PIP_Y(id_N828) - left_wire_dist - 1.}, - {HOP4X(12), PIP_Y(id_N828) - left_wire_dist - 1., HOP4X(12), PIP_Y(id_N828) - 2.}, - {HOP4X(12), PIP_Y(id_N828) - 2., HOP4X(10), PIP_Y(id_N828) - left_wire_dist - 2.}, - {HOP4X(10), PIP_Y(id_N828) - left_wire_dist - 2., HOP4X(10), -wrap_len - 2.}, - {HOP4X(10), -wrap_len - 2., HOP4X(11), -wrap_len - 2.}, - {HOP4X(11), -wrap_len - 2., HOP4X(11), PIP_Y(id_N820) - 2.}, - {HOP4X(11), PIP_Y(id_N820) - 2., HOP4X(9), PIP_Y(id_N820) + left_wire_dist - 2.}, - {HOP4X(9), PIP_Y(id_N820) + left_wire_dist - 2., HOP4X(9), PIP_Y(id_N820) - 1.}, - {HOP4X(9), PIP_Y(id_N820) - 1., HOP4X(7), PIP_Y(id_N820) + left_wire_dist - 1.}, - {HOP4X(9), PIP_Y(id_N824) - 1., WIRE_X(0), PIP_Y(id_N824) - 1.}, - {HOP4X(7), PIP_Y(id_N820) + left_wire_dist - 1., HOP4X(7), PIP_Y(id_N820) - 0.}, - {HOP4X(7), PIP_Y(id_N820) - 0., HOP4X(5), PIP_Y(id_N820) + left_wire_dist - 0.}, - {HOP4X(5), PIP_Y(id_N820) + left_wire_dist - 0., HOP4X(5), PIP_Y(id_N820) + 1.}, - {HOP4X(5), PIP_Y(id_N820) + 1., HOP4X(3), PIP_Y(id_N820) + left_wire_dist + 1.}, - {HOP4X(3), PIP_Y(id_N820) + left_wire_dist + 1., HOP4X(3), PIP_Y(id_N820) + 2.}, - {HOP4X(3), PIP_Y(id_N820) + 2., HOP4X(1), PIP_Y(id_N820) + left_wire_dist + 2.}, - {HOP4X(1), PIP_Y(id_N820) + left_wire_dist + 2., HOP4X(1), PIP_Y(id_N828) + 3.}, - {HOP4X(1), PIP_Y(id_N828) + 3., WIRE_X(0), PIP_Y(id_N828) + 3.}}}, - {id_S82_loop3, - {{WIRE_X(0), PIP_Y(id_S820), HOP4X(16), PIP_Y(id_S820)}, - {HOP4X(16), PIP_Y(id_S820), HOP4X(16), PIP_Y(id_N828)}, - {HOP4X(16), PIP_Y(id_N828) - 0., HOP4X(14), PIP_Y(id_N828) - left_wire_dist - 0.}, - {HOP4X(14), PIP_Y(id_N828) - left_wire_dist - 0., HOP4X(14), PIP_Y(id_N828) - 1.}, - {HOP4X(14), PIP_Y(id_N828) - 1., HOP4X(12), PIP_Y(id_N828) - left_wire_dist - 1.}, - {HOP4X(12), PIP_Y(id_N828) - left_wire_dist - 1., HOP4X(12), PIP_Y(id_N828) - 2.}, - {HOP4X(12), PIP_Y(id_N828) - 2., HOP4X(10), PIP_Y(id_N828) - left_wire_dist - 2.}, - {HOP4X(10), PIP_Y(id_N828) - left_wire_dist - 2., HOP4X(10), PIP_Y(id_N828) - 3.}, - {HOP4X(10), PIP_Y(id_N828) - 3., HOP4X(8), PIP_Y(id_N828) - left_wire_dist - 3.}, - {HOP4X(8), PIP_Y(id_N828) - left_wire_dist - 3., HOP4X(8), -wrap_len - 3.}, - {HOP4X(8), -wrap_len - 3., HOP4X(9), -wrap_len - 3.}, - {HOP4X(9), -wrap_len - 3., HOP4X(9), PIP_Y(id_N820) - 3.}, - {HOP4X(9), PIP_Y(id_N824) - 3., WIRE_X(0), PIP_Y(id_N824) - 3.}, - {HOP4X(9), PIP_Y(id_N820) - 3., HOP4X(7), PIP_Y(id_N820) + left_wire_dist - 3.}, - {HOP4X(7), PIP_Y(id_N820) + left_wire_dist - 3., HOP4X(7), PIP_Y(id_N820) - 2.}, - {HOP4X(7), PIP_Y(id_N820) - 2., HOP4X(5), PIP_Y(id_N820) + left_wire_dist - 2.}, - {HOP4X(5), PIP_Y(id_N820) + left_wire_dist - 2., HOP4X(5), PIP_Y(id_N820) - 1.}, - {HOP4X(5), PIP_Y(id_N820) - 1., HOP4X(3), PIP_Y(id_N820) + left_wire_dist - 1.}, - {HOP4X(3), PIP_Y(id_N820) + left_wire_dist - 1., HOP4X(3), PIP_Y(id_N820) - 0.}, - {HOP4X(3), PIP_Y(id_N820) - 0., HOP4X(1), PIP_Y(id_N820) + left_wire_dist - 0.}, - {HOP4X(1), PIP_Y(id_N820) + left_wire_dist - 0., HOP4X(1), PIP_Y(id_N828) + 1.}, - {HOP4X(1), PIP_Y(id_N828) + 1., WIRE_X(0), PIP_Y(id_N828) + 1.}}}, - {id_S82_loop4, - {{WIRE_X(0), PIP_Y(id_S820), HOP4X(16), PIP_Y(id_S820)}, - {HOP4X(16), PIP_Y(id_S820), HOP4X(16), PIP_Y(id_N828)}, - {HOP4X(16), PIP_Y(id_N828) - 0., HOP4X(14), PIP_Y(id_N828) - left_wire_dist - 0.}, - {HOP4X(14), PIP_Y(id_N828) - left_wire_dist - 0., HOP4X(14), PIP_Y(id_N828) - 1.}, - {HOP4X(14), PIP_Y(id_N828) - 1., HOP4X(12), PIP_Y(id_N828) - left_wire_dist - 1.}, - {HOP4X(12), PIP_Y(id_N828) - left_wire_dist - 1., HOP4X(12), PIP_Y(id_N828) - 2.}, - {HOP4X(12), PIP_Y(id_N828) - 2., HOP4X(10), PIP_Y(id_N828) - left_wire_dist - 2.}, - {HOP4X(10), PIP_Y(id_N828) - left_wire_dist - 2., HOP4X(10), PIP_Y(id_N828) - 3.}, - {HOP4X(10), PIP_Y(id_N828) - 3., HOP4X(8), PIP_Y(id_N828) - left_wire_dist - 3.}, - {HOP4X(8), PIP_Y(id_N828) - left_wire_dist - 3., HOP4X(8), PIP_Y(id_N828) - 4.}, - {HOP4X(8), PIP_Y(id_S824) - 4., WIRE_X(0), PIP_Y(id_S824) - 4.}, - {HOP4X(8), PIP_Y(id_N828) - 4., HOP4X(6), PIP_Y(id_N828) - left_wire_dist - 4.}, - {HOP4X(6), PIP_Y(id_N828) - left_wire_dist - 4., HOP4X(6), -wrap_len - 4.}, - {HOP4X(6), -wrap_len - 4., HOP4X(7), -wrap_len - 4.}, - {HOP4X(7), -wrap_len - 4., HOP4X(7), PIP_Y(id_N820) - 4.}, - {HOP4X(7), PIP_Y(id_N820) - 4., HOP4X(5), PIP_Y(id_N820) + left_wire_dist - 4.}, - {HOP4X(5), PIP_Y(id_N820) + left_wire_dist - 4., HOP4X(5), PIP_Y(id_N820) - 3.}, - {HOP4X(5), PIP_Y(id_N820) - 3., HOP4X(3), PIP_Y(id_N820) + left_wire_dist - 3.}, - {HOP4X(3), PIP_Y(id_N820) + left_wire_dist - 3., HOP4X(3), PIP_Y(id_N820) - 2.}, - {HOP4X(3), PIP_Y(id_N820) - 2., HOP4X(1), PIP_Y(id_N820) + left_wire_dist - 2.}, - {HOP4X(1), PIP_Y(id_N820) + left_wire_dist - 2., HOP4X(1), PIP_Y(id_N828) - 1.}, - {HOP4X(1), PIP_Y(id_N828) - 1., WIRE_X(0), PIP_Y(id_N828) - 1.}}}, - {id_S82_loop5, - {{WIRE_X(0), PIP_Y(id_S820), HOP4X(16), PIP_Y(id_S820)}, - {HOP4X(16), PIP_Y(id_S820), HOP4X(16), PIP_Y(id_N828)}, - {HOP4X(16), PIP_Y(id_N828) - 0., HOP4X(14), PIP_Y(id_N828) - left_wire_dist - 0.}, - {HOP4X(14), PIP_Y(id_N828) - left_wire_dist - 0., HOP4X(14), PIP_Y(id_N828) - 1.}, - {HOP4X(14), PIP_Y(id_N828) - 1., HOP4X(12), PIP_Y(id_N828) - left_wire_dist - 1.}, - {HOP4X(12), PIP_Y(id_N828) - left_wire_dist - 1., HOP4X(12), PIP_Y(id_N828) - 2.}, - {HOP4X(12), PIP_Y(id_N828) - 2., HOP4X(10), PIP_Y(id_N828) - left_wire_dist - 2.}, - {HOP4X(10), PIP_Y(id_N828) - left_wire_dist - 2., HOP4X(10), PIP_Y(id_N828) - 3.}, - {HOP4X(10), PIP_Y(id_N828) - 3., HOP4X(8), PIP_Y(id_N828) - left_wire_dist - 3.}, - {HOP4X(8), PIP_Y(id_N828) - left_wire_dist - 3., HOP4X(8), PIP_Y(id_N828) - 4.}, - {HOP4X(8), PIP_Y(id_S824) - 4., WIRE_X(0), PIP_Y(id_S824) - 4.}, - {HOP4X(8), PIP_Y(id_N828) - 4., HOP4X(6), PIP_Y(id_N828) - left_wire_dist - 4.}, - {HOP4X(6), PIP_Y(id_N828) - left_wire_dist - 4., HOP4X(6), PIP_Y(id_N828) - 5.}, - {HOP4X(6), PIP_Y(id_N828) - 5., HOP4X(4), PIP_Y(id_N828) - left_wire_dist - 5.}, - {HOP4X(4), PIP_Y(id_N828) - left_wire_dist - 5., HOP4X(4), -wrap_len - 5.}, - {HOP4X(4), -wrap_len - 5., HOP4X(5), -wrap_len - 5.}, - {HOP4X(5), -wrap_len - 5., HOP4X(5), PIP_Y(id_N820) - 5.}, - {HOP4X(5), PIP_Y(id_N820) - 5., HOP4X(3), PIP_Y(id_N820) + left_wire_dist - 5.}, - {HOP4X(3), PIP_Y(id_N820) + left_wire_dist - 5., HOP4X(3), PIP_Y(id_N820) - 4.}, - {HOP4X(3), PIP_Y(id_N820) - 4., HOP4X(1), PIP_Y(id_N820) + left_wire_dist - 4.}, - {HOP4X(1), PIP_Y(id_N820) + left_wire_dist - 4., HOP4X(1), PIP_Y(id_N828) - 3.}, - {HOP4X(1), PIP_Y(id_N828) - 3., WIRE_X(0), PIP_Y(id_N828) - 3.}}}, - {id_S82_loop6, - {{WIRE_X(0), PIP_Y(id_S820), HOP4X(16), PIP_Y(id_S820)}, - {HOP4X(16), PIP_Y(id_S820), HOP4X(16), PIP_Y(id_N828)}, - {HOP4X(16), PIP_Y(id_N828) - 0., HOP4X(14), PIP_Y(id_N828) - left_wire_dist - 0.}, - {HOP4X(14), PIP_Y(id_N828) - left_wire_dist - 0., HOP4X(14), PIP_Y(id_N828) - 1.}, - {HOP4X(14), PIP_Y(id_N828) - 1., HOP4X(12), PIP_Y(id_N828) - left_wire_dist - 1.}, - {HOP4X(12), PIP_Y(id_N828) - left_wire_dist - 1., HOP4X(12), PIP_Y(id_N828) - 2.}, - {HOP4X(12), PIP_Y(id_N828) - 2., HOP4X(10), PIP_Y(id_N828) - left_wire_dist - 2.}, - {HOP4X(10), PIP_Y(id_N828) - left_wire_dist - 2., HOP4X(10), PIP_Y(id_N828) - 3.}, - {HOP4X(10), PIP_Y(id_N828) - 3., HOP4X(8), PIP_Y(id_N828) - left_wire_dist - 3.}, - {HOP4X(8), PIP_Y(id_N828) - left_wire_dist - 3., HOP4X(8), PIP_Y(id_N828) - 4.}, - {HOP4X(8), PIP_Y(id_S824) - 4., WIRE_X(0), PIP_Y(id_S824) - 4.}, - {HOP4X(8), PIP_Y(id_N828) - 4., HOP4X(6), PIP_Y(id_N828) - left_wire_dist - 4.}, - {HOP4X(6), PIP_Y(id_N828) - left_wire_dist - 4., HOP4X(6), PIP_Y(id_N828) - 5.}, - {HOP4X(6), PIP_Y(id_N828) - 5., HOP4X(4), PIP_Y(id_N828) - left_wire_dist - 5.}, - {HOP4X(4), PIP_Y(id_N828) - left_wire_dist - 5., HOP4X(4), PIP_Y(id_N828) - 6.}, - {HOP4X(4), PIP_Y(id_N828) - 6., HOP4X(2), PIP_Y(id_N828) - left_wire_dist - 6.}, - {HOP4X(2), PIP_Y(id_N828) - left_wire_dist - 6., HOP4X(2), -wrap_len - 6.}, - {HOP4X(2), -wrap_len - 6., HOP4X(3), -wrap_len - 6.}, - {HOP4X(3), -wrap_len - 6., HOP4X(3), PIP_Y(id_N820) - 6.}, - {HOP4X(3), PIP_Y(id_N820) - 6., HOP4X(1), PIP_Y(id_N820) + left_wire_dist - 6.}, - {HOP4X(1), PIP_Y(id_N820) + left_wire_dist - 6., HOP4X(1), PIP_Y(id_N828) - 5.}, - {HOP4X(1), PIP_Y(id_N828) - 5., WIRE_X(0), PIP_Y(id_N828) - 5.}}}, - {id_S82_loop7, - {{WIRE_X(0), PIP_Y(id_S820), HOP4X(16), PIP_Y(id_S820)}, - {HOP4X(16), PIP_Y(id_S820), HOP4X(16), PIP_Y(id_N828)}, - {HOP4X(16), PIP_Y(id_N828) - 0., HOP4X(14), PIP_Y(id_N828) - left_wire_dist - 0.}, - {HOP4X(14), PIP_Y(id_N828) - left_wire_dist - 0., HOP4X(14), PIP_Y(id_N828) - 1.}, - {HOP4X(14), PIP_Y(id_N828) - 1., HOP4X(12), PIP_Y(id_N828) - left_wire_dist - 1.}, - {HOP4X(12), PIP_Y(id_N828) - left_wire_dist - 1., HOP4X(12), PIP_Y(id_N828) - 2.}, - {HOP4X(12), PIP_Y(id_N828) - 2., HOP4X(10), PIP_Y(id_N828) - left_wire_dist - 2.}, - {HOP4X(10), PIP_Y(id_N828) - left_wire_dist - 2., HOP4X(10), PIP_Y(id_N828) - 3.}, - {HOP4X(10), PIP_Y(id_N828) - 3., HOP4X(8), PIP_Y(id_N828) - left_wire_dist - 3.}, - {HOP4X(8), PIP_Y(id_N828) - left_wire_dist - 3., HOP4X(8), PIP_Y(id_N828) - 4.}, - {HOP4X(8), PIP_Y(id_S824) - 4., WIRE_X(0), PIP_Y(id_S824) - 4.}, - {HOP4X(8), PIP_Y(id_N828) - 4., HOP4X(6), PIP_Y(id_N828) - left_wire_dist - 4.}, - {HOP4X(6), PIP_Y(id_N828) - left_wire_dist - 4., HOP4X(6), PIP_Y(id_N828) - 5.}, - {HOP4X(6), PIP_Y(id_N828) - 5., HOP4X(4), PIP_Y(id_N828) - left_wire_dist - 5.}, - {HOP4X(4), PIP_Y(id_N828) - left_wire_dist - 5., HOP4X(4), PIP_Y(id_N828) - 6.}, - {HOP4X(4), PIP_Y(id_N828) - 6., HOP4X(2), PIP_Y(id_N828) - left_wire_dist - 6.}, - {HOP4X(2), PIP_Y(id_N828) - left_wire_dist - 6., HOP4X(2), PIP_Y(id_N828) - 7.}, - {HOP4X(2), PIP_Y(id_N828) - 7., HOP4X(0), PIP_Y(id_N828) - left_wire_dist - 7.}, - {HOP4X(0), PIP_Y(id_N828) - left_wire_dist - 7., HOP4X(0), -wrap_len - 7.}, - {HOP4X(0), -wrap_len - 7., HOP4X(1), -wrap_len - 7.}, - {HOP4X(1), -wrap_len - 7., HOP4X(1), PIP_Y(id_N828) - 7.}, - {HOP4X(1), PIP_Y(id_N828) - 7., WIRE_X(0), PIP_Y(id_N828) - 7.}}}, - {id_N82_loop0, - {{WIRE_X(0), PIP_Y(id_N820), HOP4X(17), PIP_Y(id_N820)}, - {HOP4X(17), PIP_Y(id_N820) + 0., HOP4X(15), PIP_Y(id_N820) + left_wire_dist + 0.}, - {HOP4X(15), PIP_Y(id_N820) + left_wire_dist + 0., HOP4X(15), wrap_len + 1.}, - {HOP4X(15), wrap_len + 1., HOP4X(14), wrap_len + 1.}, - {HOP4X(14), wrap_len + 1., HOP4X(14), PIP_Y(id_N828) + 0.}, - {HOP4X(14), PIP_Y(id_N828) + 0., HOP4X(12), PIP_Y(id_N828) - left_wire_dist + 0.}, - {HOP4X(12), PIP_Y(id_N828) - left_wire_dist + 0., HOP4X(12), PIP_Y(id_N828) - 1.}, - {HOP4X(12), PIP_Y(id_N828) - 1., HOP4X(10), PIP_Y(id_N828) - left_wire_dist - 1.}, - {HOP4X(10), PIP_Y(id_N828) - left_wire_dist - 1., HOP4X(10), PIP_Y(id_N828) - 2.}, - {HOP4X(10), PIP_Y(id_N828) - 2., HOP4X(8), PIP_Y(id_N828) - left_wire_dist - 2.}, - {HOP4X(8), PIP_Y(id_N828) - left_wire_dist - 2., HOP4X(8), PIP_Y(id_N828) - 3.}, - {HOP4X(8), PIP_Y(id_S824) - 3., WIRE_X(0), PIP_Y(id_S824) - 3.}, - {HOP4X(8), PIP_Y(id_N828) - 3., HOP4X(6), PIP_Y(id_N828) - left_wire_dist - 3.}, - {HOP4X(6), PIP_Y(id_N828) - left_wire_dist - 3., HOP4X(6), PIP_Y(id_N828) - 4.}, - {HOP4X(6), PIP_Y(id_N828) - 4., HOP4X(4), PIP_Y(id_N828) - left_wire_dist - 4.}, - {HOP4X(4), PIP_Y(id_N828) - left_wire_dist - 4., HOP4X(4), PIP_Y(id_N828) - 5.}, - {HOP4X(4), PIP_Y(id_N828) - 5., HOP4X(2), PIP_Y(id_N828) - left_wire_dist - 5.}, - {HOP4X(2), PIP_Y(id_N828) - left_wire_dist - 5., HOP4X(2), PIP_Y(id_N828) - 6.}, - {HOP4X(2), PIP_Y(id_N828) - 6., HOP4X(0), PIP_Y(id_N828) - left_wire_dist - 6.}, - {HOP4X(0), PIP_Y(id_N828) - left_wire_dist - 6., HOP4X(0), PIP_Y(id_S828) - 7.}, - {HOP4X(0), PIP_Y(id_S828) - 7., WIRE_X(0), PIP_Y(id_S828) - 7.}}}, - {id_N82_loop1, - {{WIRE_X(0), PIP_Y(id_N820), HOP4X(17), PIP_Y(id_N820)}, - {HOP4X(17), PIP_Y(id_N820) + 0., HOP4X(15), PIP_Y(id_N820) + left_wire_dist + 0.}, - {HOP4X(15), PIP_Y(id_N820) + left_wire_dist + 0., HOP4X(15), PIP_Y(id_N820) + 1.}, - {HOP4X(15), PIP_Y(id_N820) + 1., HOP4X(13), PIP_Y(id_N820) + left_wire_dist + 1.}, - {HOP4X(13), PIP_Y(id_N820) + left_wire_dist + 1., HOP4X(13), wrap_len + 2.}, - {HOP4X(13), wrap_len + 2., HOP4X(12), wrap_len + 2.}, - {HOP4X(12), wrap_len + 2., HOP4X(12), PIP_Y(id_N828) + 1.}, - {HOP4X(12), PIP_Y(id_N828) + 1., HOP4X(10), PIP_Y(id_N828) - left_wire_dist + 1.}, - {HOP4X(10), PIP_Y(id_N828) - left_wire_dist + 1., HOP4X(10), PIP_Y(id_N828) + 0.}, - {HOP4X(10), PIP_Y(id_N828) + 0., HOP4X(8), PIP_Y(id_N828) - left_wire_dist + 0.}, - {HOP4X(8), PIP_Y(id_N828) - left_wire_dist + 0., HOP4X(8), PIP_Y(id_N828) - 1.}, - {HOP4X(8), PIP_Y(id_S824) - 1., WIRE_X(0), PIP_Y(id_S824) - 1.}, - {HOP4X(8), PIP_Y(id_N828) - 1., HOP4X(6), PIP_Y(id_N828) - left_wire_dist - 1.}, - {HOP4X(6), PIP_Y(id_N828) - left_wire_dist - 1., HOP4X(6), PIP_Y(id_N828) - 2.}, - {HOP4X(6), PIP_Y(id_N828) - 2., HOP4X(4), PIP_Y(id_N828) - left_wire_dist - 2.}, - {HOP4X(4), PIP_Y(id_N828) - left_wire_dist - 2., HOP4X(4), PIP_Y(id_N828) - 3.}, - {HOP4X(4), PIP_Y(id_N828) - 3., HOP4X(2), PIP_Y(id_N828) - left_wire_dist - 3.}, - {HOP4X(2), PIP_Y(id_N828) - left_wire_dist - 3., HOP4X(2), PIP_Y(id_N828) - 4.}, - {HOP4X(2), PIP_Y(id_N828) - 4., HOP4X(0), PIP_Y(id_N828) - left_wire_dist - 4.}, - {HOP4X(0), PIP_Y(id_N828) - left_wire_dist - 4., HOP4X(0), PIP_Y(id_S828) - 5.}, - {HOP4X(0), PIP_Y(id_S828) - 5., WIRE_X(0), PIP_Y(id_S828) - 5.}}}, - {id_N82_loop2, - {{WIRE_X(0), PIP_Y(id_N820), HOP4X(17), PIP_Y(id_N820)}, - {HOP4X(17), PIP_Y(id_N820) + 0., HOP4X(15), PIP_Y(id_N820) + left_wire_dist + 0.}, - {HOP4X(15), PIP_Y(id_N820) + left_wire_dist + 0., HOP4X(15), PIP_Y(id_N820) + 1.}, - {HOP4X(15), PIP_Y(id_N820) + 1., HOP4X(13), PIP_Y(id_N820) + left_wire_dist + 1.}, - {HOP4X(13), PIP_Y(id_N820) + left_wire_dist + 1., HOP4X(13), PIP_Y(id_N820) + 2.}, - {HOP4X(13), PIP_Y(id_N820) + 2., HOP4X(11), PIP_Y(id_N820) + left_wire_dist + 2.}, - {HOP4X(11), PIP_Y(id_N820) + left_wire_dist + 2., HOP4X(11), wrap_len + 3.}, - {HOP4X(11), wrap_len + 3., HOP4X(10), wrap_len + 3.}, - {HOP4X(10), wrap_len + 3., HOP4X(10), PIP_Y(id_N828) + 2.}, - {HOP4X(10), PIP_Y(id_N828) + 2., HOP4X(8), PIP_Y(id_N828) - left_wire_dist + 2.}, - {HOP4X(8), PIP_Y(id_N828) - left_wire_dist + 2., HOP4X(8), PIP_Y(id_N828) + 1.}, - {HOP4X(8), PIP_Y(id_S824) + 1., WIRE_X(0), PIP_Y(id_S824) + 1.}, - {HOP4X(8), PIP_Y(id_N828) + 1., HOP4X(6), PIP_Y(id_N828) - left_wire_dist + 1.}, - {HOP4X(6), PIP_Y(id_N828) - left_wire_dist + 1., HOP4X(6), PIP_Y(id_N828) + 0.}, - {HOP4X(6), PIP_Y(id_N828) + 0., HOP4X(4), PIP_Y(id_N828) - left_wire_dist + 0.}, - {HOP4X(4), PIP_Y(id_N828) - left_wire_dist + 0., HOP4X(4), PIP_Y(id_N828) - 1.}, - {HOP4X(4), PIP_Y(id_N828) - 1., HOP4X(2), PIP_Y(id_N828) - left_wire_dist - 1.}, - {HOP4X(2), PIP_Y(id_N828) - left_wire_dist - 1., HOP4X(2), PIP_Y(id_N828) - 2.}, - {HOP4X(2), PIP_Y(id_N828) - 2., HOP4X(0), PIP_Y(id_N828) - left_wire_dist - 2.}, - {HOP4X(0), PIP_Y(id_N828) - left_wire_dist - 2., HOP4X(0), PIP_Y(id_S828) - 3.}, - {HOP4X(0), PIP_Y(id_S828) - 3., WIRE_X(0), PIP_Y(id_S828) - 3.}}}, - {id_N82_loop3, - {{WIRE_X(0), PIP_Y(id_N820), HOP4X(17), PIP_Y(id_N820)}, - {HOP4X(17), PIP_Y(id_N820) + 0., HOP4X(15), PIP_Y(id_N820) + left_wire_dist + 0.}, - {HOP4X(15), PIP_Y(id_N820) + left_wire_dist + 0., HOP4X(15), PIP_Y(id_N820) + 1.}, - {HOP4X(15), PIP_Y(id_N820) + 1., HOP4X(13), PIP_Y(id_N820) + left_wire_dist + 1.}, - {HOP4X(13), PIP_Y(id_N820) + left_wire_dist + 1., HOP4X(13), PIP_Y(id_N820) + 2.}, - {HOP4X(13), PIP_Y(id_N820) + 2., HOP4X(11), PIP_Y(id_N820) + left_wire_dist + 2.}, - {HOP4X(11), PIP_Y(id_N820) + left_wire_dist + 2., HOP4X(11), PIP_Y(id_N820) + 3.}, - {HOP4X(11), PIP_Y(id_N820) + 3., HOP4X(9), PIP_Y(id_N820) + left_wire_dist + 3.}, - {HOP4X(9), PIP_Y(id_N820) + left_wire_dist + 3., HOP4X(9), wrap_len + 4.}, - {HOP4X(9), wrap_len + 4., HOP4X(8), wrap_len + 4.}, - {HOP4X(8), wrap_len + 4., HOP4X(8), PIP_Y(id_N828) + 3.}, - {HOP4X(8), PIP_Y(id_S824) + 3., WIRE_X(0), PIP_Y(id_S824) + 3.}, - {HOP4X(8), PIP_Y(id_N828) + 3., HOP4X(6), PIP_Y(id_N828) - left_wire_dist + 3.}, - {HOP4X(6), PIP_Y(id_N828) - left_wire_dist + 3., HOP4X(6), PIP_Y(id_N828) + 2.}, - {HOP4X(6), PIP_Y(id_N828) + 2., HOP4X(4), PIP_Y(id_N828) - left_wire_dist + 2.}, - {HOP4X(4), PIP_Y(id_N828) - left_wire_dist + 2., HOP4X(4), PIP_Y(id_N828) + 1.}, - {HOP4X(4), PIP_Y(id_N828) + 1., HOP4X(2), PIP_Y(id_N828) - left_wire_dist + 1.}, - {HOP4X(2), PIP_Y(id_N828) - left_wire_dist + 1., HOP4X(2), PIP_Y(id_N828) + 0.}, - {HOP4X(2), PIP_Y(id_N828) + 0., HOP4X(0), PIP_Y(id_N828) - left_wire_dist + 0.}, - {HOP4X(0), PIP_Y(id_N828) - left_wire_dist + 0., HOP4X(0), PIP_Y(id_S828) - 1.}, - {HOP4X(0), PIP_Y(id_S828) - 1., WIRE_X(0), PIP_Y(id_S828) - 1.}}}, - {id_N82_loop4, - {{WIRE_X(0), PIP_Y(id_N820), HOP4X(17), PIP_Y(id_N820)}, - {HOP4X(17), PIP_Y(id_N820) + 0., HOP4X(15), PIP_Y(id_N820) + left_wire_dist + 0.}, - {HOP4X(15), PIP_Y(id_N820) + left_wire_dist + 0., HOP4X(15), PIP_Y(id_N820) + 1.}, - {HOP4X(15), PIP_Y(id_N820) + 1., HOP4X(13), PIP_Y(id_N820) + left_wire_dist + 1.}, - {HOP4X(13), PIP_Y(id_N820) + left_wire_dist + 1., HOP4X(13), PIP_Y(id_N820) + 2.}, - {HOP4X(13), PIP_Y(id_N820) + 2., HOP4X(11), PIP_Y(id_N820) + left_wire_dist + 2.}, - {HOP4X(11), PIP_Y(id_N820) + left_wire_dist + 2., HOP4X(11), PIP_Y(id_N820) + 3.}, - {HOP4X(11), PIP_Y(id_N820) + 3., HOP4X(9), PIP_Y(id_N820) + left_wire_dist + 3.}, - {HOP4X(9), PIP_Y(id_N820) + left_wire_dist + 3., HOP4X(9), PIP_Y(id_N820) + 4.}, - {HOP4X(9), PIP_Y(id_N824) + 4., WIRE_X(0), PIP_Y(id_N824) + 4.}, - {HOP4X(9), PIP_Y(id_N820) + 4., HOP4X(7), PIP_Y(id_N820) + left_wire_dist + 4.}, - {HOP4X(7), PIP_Y(id_N820) + left_wire_dist + 4., HOP4X(7), wrap_len + 5.}, - {HOP4X(7), wrap_len + 5., HOP4X(6), wrap_len + 5.}, - {HOP4X(6), wrap_len + 5., HOP4X(6), PIP_Y(id_N828) + 4.}, - {HOP4X(6), PIP_Y(id_N828) + 4., HOP4X(4), PIP_Y(id_N828) - left_wire_dist + 4.}, - {HOP4X(4), PIP_Y(id_N828) - left_wire_dist + 4., HOP4X(4), PIP_Y(id_N828) + 3.}, - {HOP4X(4), PIP_Y(id_N828) + 3., HOP4X(2), PIP_Y(id_N828) - left_wire_dist + 3.}, - {HOP4X(2), PIP_Y(id_N828) - left_wire_dist + 3., HOP4X(2), PIP_Y(id_N828) + 2.}, - {HOP4X(2), PIP_Y(id_N828) + 2., HOP4X(0), PIP_Y(id_N828) - left_wire_dist + 2.}, - {HOP4X(0), PIP_Y(id_N828) - left_wire_dist + 2., HOP4X(0), PIP_Y(id_S828) + 1.}, - {HOP4X(0), PIP_Y(id_S828) + 1., WIRE_X(0), PIP_Y(id_S828) + 1.}}}, - {id_N82_loop5, - {{WIRE_X(0), PIP_Y(id_N820), HOP4X(17), PIP_Y(id_N820)}, - {HOP4X(17), PIP_Y(id_N820) + 0., HOP4X(15), PIP_Y(id_N820) + left_wire_dist + 0.}, - {HOP4X(15), PIP_Y(id_N820) + left_wire_dist + 0., HOP4X(15), PIP_Y(id_N820) + 1.}, - {HOP4X(15), PIP_Y(id_N820) + 1., HOP4X(13), PIP_Y(id_N820) + left_wire_dist + 1.}, - {HOP4X(13), PIP_Y(id_N820) + left_wire_dist + 1., HOP4X(13), PIP_Y(id_N820) + 2.}, - {HOP4X(13), PIP_Y(id_N820) + 2., HOP4X(11), PIP_Y(id_N820) + left_wire_dist + 2.}, - {HOP4X(11), PIP_Y(id_N820) + left_wire_dist + 2., HOP4X(11), PIP_Y(id_N820) + 3.}, - {HOP4X(11), PIP_Y(id_N820) + 3., HOP4X(9), PIP_Y(id_N820) + left_wire_dist + 3.}, - {HOP4X(9), PIP_Y(id_N820) + left_wire_dist + 3., HOP4X(9), PIP_Y(id_N820) + 4.}, - {HOP4X(9), PIP_Y(id_N824) + 4., WIRE_X(0), PIP_Y(id_N824) + 4.}, - {HOP4X(9), PIP_Y(id_N820) + 4., HOP4X(7), PIP_Y(id_N820) + left_wire_dist + 4.}, - {HOP4X(7), PIP_Y(id_N820) + left_wire_dist + 4., HOP4X(7), PIP_Y(id_N820) + 5.}, - {HOP4X(7), PIP_Y(id_N820) + 5., HOP4X(5), PIP_Y(id_N820) + left_wire_dist + 5.}, - {HOP4X(5), PIP_Y(id_N820) + left_wire_dist + 5., HOP4X(5), wrap_len + 6.}, - {HOP4X(5), wrap_len + 6., HOP4X(4), wrap_len + 6.}, - {HOP4X(4), wrap_len + 6., HOP4X(4), PIP_Y(id_N828) + 5.}, - {HOP4X(4), PIP_Y(id_N828) + 5., HOP4X(2), PIP_Y(id_N828) - left_wire_dist + 5.}, - {HOP4X(2), PIP_Y(id_N828) - left_wire_dist + 5., HOP4X(2), PIP_Y(id_N828) + 4.}, - {HOP4X(2), PIP_Y(id_N828) + 4., HOP4X(0), PIP_Y(id_N828) - left_wire_dist + 4.}, - {HOP4X(0), PIP_Y(id_N828) - left_wire_dist + 4., HOP4X(0), PIP_Y(id_S828) + 3.}, - {HOP4X(0), PIP_Y(id_S828) + 3., WIRE_X(0), PIP_Y(id_S828) + 3.}}}, - {id_N82_loop6, - {{WIRE_X(0), PIP_Y(id_N820), HOP4X(17), PIP_Y(id_N820)}, - {HOP4X(17), PIP_Y(id_N820) + 0., HOP4X(15), PIP_Y(id_N820) + left_wire_dist + 0.}, - {HOP4X(15), PIP_Y(id_N820) + left_wire_dist + 0., HOP4X(15), PIP_Y(id_N820) + 1.}, - {HOP4X(15), PIP_Y(id_N820) + 1., HOP4X(13), PIP_Y(id_N820) + left_wire_dist + 1.}, - {HOP4X(13), PIP_Y(id_N820) + left_wire_dist + 1., HOP4X(13), PIP_Y(id_N820) + 2.}, - {HOP4X(13), PIP_Y(id_N820) + 2., HOP4X(11), PIP_Y(id_N820) + left_wire_dist + 2.}, - {HOP4X(11), PIP_Y(id_N820) + left_wire_dist + 2., HOP4X(11), PIP_Y(id_N820) + 3.}, - {HOP4X(11), PIP_Y(id_N820) + 3., HOP4X(9), PIP_Y(id_N820) + left_wire_dist + 3.}, - {HOP4X(9), PIP_Y(id_N820) + left_wire_dist + 3., HOP4X(9), PIP_Y(id_N820) + 4.}, - {HOP4X(9), PIP_Y(id_N824) + 4., WIRE_X(0), PIP_Y(id_N824) + 4.}, - {HOP4X(9), PIP_Y(id_N820) + 4., HOP4X(7), PIP_Y(id_N820) + left_wire_dist + 4.}, - {HOP4X(7), PIP_Y(id_N820) + left_wire_dist + 4., HOP4X(7), PIP_Y(id_N820) + 5.}, - {HOP4X(7), PIP_Y(id_N820) + 5., HOP4X(5), PIP_Y(id_N820) + left_wire_dist + 5.}, - {HOP4X(5), PIP_Y(id_N820) + left_wire_dist + 5., HOP4X(5), PIP_Y(id_N820) + 6.}, - {HOP4X(5), PIP_Y(id_N820) + 6., HOP4X(3), PIP_Y(id_N820) + left_wire_dist + 6.}, - {HOP4X(3), PIP_Y(id_N820) + left_wire_dist + 6., HOP4X(3), wrap_len + 7.}, - {HOP4X(3), wrap_len + 7., HOP4X(2), wrap_len + 7.}, - {HOP4X(2), wrap_len + 7., HOP4X(2), PIP_Y(id_N828) + 6.}, - {HOP4X(2), PIP_Y(id_N828) + 6., HOP4X(0), PIP_Y(id_N828) - left_wire_dist + 6.}, - {HOP4X(0), PIP_Y(id_N828) - left_wire_dist + 6., HOP4X(0), PIP_Y(id_S828) + 5.}, - {HOP4X(0), PIP_Y(id_S828) + 5., WIRE_X(0), PIP_Y(id_S828) + 5.}}}, - {id_N82_loop7, - {{WIRE_X(0), PIP_Y(id_N820), HOP4X(17), PIP_Y(id_N820)}, - {HOP4X(17), PIP_Y(id_N820) + 0., HOP4X(15), PIP_Y(id_N820) + left_wire_dist + 0.}, - {HOP4X(15), PIP_Y(id_N820) + left_wire_dist + 0., HOP4X(15), PIP_Y(id_N820) + 1.}, - {HOP4X(15), PIP_Y(id_N820) + 1., HOP4X(13), PIP_Y(id_N820) + left_wire_dist + 1.}, - {HOP4X(13), PIP_Y(id_N820) + left_wire_dist + 1., HOP4X(13), PIP_Y(id_N820) + 2.}, - {HOP4X(13), PIP_Y(id_N820) + 2., HOP4X(11), PIP_Y(id_N820) + left_wire_dist + 2.}, - {HOP4X(11), PIP_Y(id_N820) + left_wire_dist + 2., HOP4X(11), PIP_Y(id_N820) + 3.}, - {HOP4X(11), PIP_Y(id_N820) + 3., HOP4X(9), PIP_Y(id_N820) + left_wire_dist + 3.}, - {HOP4X(9), PIP_Y(id_N820) + left_wire_dist + 3., HOP4X(9), PIP_Y(id_N820) + 4.}, - {HOP4X(9), PIP_Y(id_N824) + 4., WIRE_X(0), PIP_Y(id_N824) + 4.}, - {HOP4X(9), PIP_Y(id_N820) + 4., HOP4X(7), PIP_Y(id_N820) + left_wire_dist + 4.}, - {HOP4X(7), PIP_Y(id_N820) + left_wire_dist + 4., HOP4X(7), PIP_Y(id_N820) + 5.}, - {HOP4X(7), PIP_Y(id_N820) + 5., HOP4X(5), PIP_Y(id_N820) + left_wire_dist + 5.}, - {HOP4X(5), PIP_Y(id_N820) + left_wire_dist + 5., HOP4X(5), PIP_Y(id_N820) + 6.}, - {HOP4X(5), PIP_Y(id_N820) + 6., HOP4X(3), PIP_Y(id_N820) + left_wire_dist + 6.}, - {HOP4X(3), PIP_Y(id_N820) + left_wire_dist + 6., HOP4X(3), PIP_Y(id_N820) + 7.}, - {HOP4X(3), PIP_Y(id_N820) + 7., HOP4X(1), PIP_Y(id_N820) + left_wire_dist + 7.}, - {HOP4X(1), PIP_Y(id_N820) + left_wire_dist + 7., HOP4X(1), wrap_len + 8.}, - {HOP4X(1), wrap_len + 8., HOP4X(0), wrap_len + 8.}, - {HOP4X(0), wrap_len + 8., HOP4X(0), PIP_Y(id_S828) + 7.}, - {HOP4X(0), PIP_Y(id_S828) + 7., WIRE_X(0), PIP_Y(id_S828) + 7.}}}, - -#undef HOP4X -#define HOP4X(offset) WIRE_X((float)offset + HOP4X_START + 18.f + 18.f + 18.f) - {id_S83, - {{WIRE_X(0), PIP_Y(id_S830), HOP4X(16), PIP_Y(id_S830)}, - {HOP4X(16), PIP_Y(id_S830), HOP4X(16), PIP_Y(id_N838)}, - {HOP4X(16), PIP_Y(id_N838) - 0., HOP4X(14), PIP_Y(id_N838) - left_wire_dist - 0.}, - {HOP4X(14), PIP_Y(id_N838) - left_wire_dist - 0., HOP4X(14), PIP_Y(id_N838) - 1.}, - {HOP4X(14), PIP_Y(id_N838) - 1., HOP4X(12), PIP_Y(id_N838) - left_wire_dist - 1.}, - {HOP4X(12), PIP_Y(id_N838) - left_wire_dist - 1., HOP4X(12), PIP_Y(id_N838) - 2.}, - {HOP4X(12), PIP_Y(id_N838) - 2., HOP4X(10), PIP_Y(id_N838) - left_wire_dist - 2.}, - {HOP4X(10), PIP_Y(id_N838) - left_wire_dist - 2., HOP4X(10), PIP_Y(id_N838) - 3.}, - {HOP4X(10), PIP_Y(id_N838) - 3., HOP4X(8), PIP_Y(id_N838) - left_wire_dist - 3.}, - {HOP4X(8), PIP_Y(id_N838) - left_wire_dist - 3., HOP4X(8), PIP_Y(id_N838) - 4.}, - {HOP4X(8), PIP_Y(id_S834) - 4., WIRE_X(0), PIP_Y(id_S834) - 4.}, - {HOP4X(8), PIP_Y(id_N838) - 4., HOP4X(6), PIP_Y(id_N838) - left_wire_dist - 4.}, - {HOP4X(6), PIP_Y(id_N838) - left_wire_dist - 4., HOP4X(6), PIP_Y(id_N838) - 5.}, - {HOP4X(6), PIP_Y(id_N838) - 5., HOP4X(4), PIP_Y(id_N838) - left_wire_dist - 5.}, - {HOP4X(4), PIP_Y(id_N838) - left_wire_dist - 5., HOP4X(4), PIP_Y(id_N838) - 6.}, - {HOP4X(4), PIP_Y(id_N838) - 6., HOP4X(2), PIP_Y(id_N838) - left_wire_dist - 6.}, - {HOP4X(2), PIP_Y(id_N838) - left_wire_dist - 6., HOP4X(2), PIP_Y(id_N838) - 7.}, - {HOP4X(2), PIP_Y(id_N838) - 7., HOP4X(0), PIP_Y(id_N838) - left_wire_dist - 7.}, - {HOP4X(0), PIP_Y(id_N838) - left_wire_dist - 7., HOP4X(0), PIP_Y(id_S838) - 8.}, - {HOP4X(0), PIP_Y(id_S838) - 8., WIRE_X(0), PIP_Y(id_S838) - 8.}}}, - {id_N83, - {{WIRE_X(0), PIP_Y(id_N830), HOP4X(17), PIP_Y(id_N830)}, - {HOP4X(17), PIP_Y(id_N830) + 0., HOP4X(15), PIP_Y(id_N830) + left_wire_dist + 0.}, - {HOP4X(15), PIP_Y(id_N830) + left_wire_dist + 0., HOP4X(15), PIP_Y(id_N830) + 1.}, - {HOP4X(15), PIP_Y(id_N830) + 1., HOP4X(13), PIP_Y(id_N830) + left_wire_dist + 1.}, - {HOP4X(13), PIP_Y(id_N830) + left_wire_dist + 1., HOP4X(13), PIP_Y(id_N830) + 2.}, - {HOP4X(13), PIP_Y(id_N830) + 2., HOP4X(11), PIP_Y(id_N830) + left_wire_dist + 2.}, - {HOP4X(11), PIP_Y(id_N830) + left_wire_dist + 2., HOP4X(11), PIP_Y(id_N830) + 3.}, - {HOP4X(11), PIP_Y(id_N830) + 3., HOP4X(9), PIP_Y(id_N830) + left_wire_dist + 3.}, - {HOP4X(9), PIP_Y(id_N830) + left_wire_dist + 3., HOP4X(9), PIP_Y(id_N830) + 4.}, - {HOP4X(9), PIP_Y(id_N834) + 4., WIRE_X(0), PIP_Y(id_N834) + 4.}, - {HOP4X(9), PIP_Y(id_N830) + 4., HOP4X(7), PIP_Y(id_N830) + left_wire_dist + 4.}, - {HOP4X(7), PIP_Y(id_N830) + left_wire_dist + 4., HOP4X(7), PIP_Y(id_N830) + 5.}, - {HOP4X(7), PIP_Y(id_N830) + 5., HOP4X(5), PIP_Y(id_N830) + left_wire_dist + 5.}, - {HOP4X(5), PIP_Y(id_N830) + left_wire_dist + 5., HOP4X(5), PIP_Y(id_N830) + 6.}, - {HOP4X(5), PIP_Y(id_N830) + 6., HOP4X(3), PIP_Y(id_N830) + left_wire_dist + 6.}, - {HOP4X(3), PIP_Y(id_N830) + left_wire_dist + 6., HOP4X(3), PIP_Y(id_N830) + 7.}, - {HOP4X(3), PIP_Y(id_N830) + 7., HOP4X(1), PIP_Y(id_N830) + left_wire_dist + 7.}, - {HOP4X(1), PIP_Y(id_N830) + left_wire_dist + 7., HOP4X(1), PIP_Y(id_N838) + 8.}, - {HOP4X(1), PIP_Y(id_N838) + 8., WIRE_X(0), PIP_Y(id_N838) + 8.}}}, - {id_S83_loop0, - {{WIRE_X(0), PIP_Y(id_S830), HOP4X(16), PIP_Y(id_S830)}, - {HOP4X(16), PIP_Y(id_S830), HOP4X(16), PIP_Y(id_N838)}, - {HOP4X(16), PIP_Y(id_N838) - 0., HOP4X(14), PIP_Y(id_N838) - left_wire_dist - 0.}, - {HOP4X(14), PIP_Y(id_N838) - left_wire_dist - 0., HOP4X(14), -wrap_len - 0.}, - {HOP4X(14), -wrap_len - 0., HOP4X(15), -wrap_len - 0.}, - {HOP4X(15), -wrap_len - 0., HOP4X(15), PIP_Y(id_N830) - 0.}, - {HOP4X(15), PIP_Y(id_N830) - 0., HOP4X(13), PIP_Y(id_N830) + left_wire_dist - 0.}, - {HOP4X(13), PIP_Y(id_N830) + left_wire_dist - 0., HOP4X(13), PIP_Y(id_N830) + 1.}, - {HOP4X(13), PIP_Y(id_N830) + 1., HOP4X(11), PIP_Y(id_N830) + left_wire_dist + 1.}, - {HOP4X(11), PIP_Y(id_N830) + left_wire_dist + 1., HOP4X(11), PIP_Y(id_N830) + 2.}, - {HOP4X(11), PIP_Y(id_N830) + 2., HOP4X(9), PIP_Y(id_N830) + left_wire_dist + 2.}, - {HOP4X(9), PIP_Y(id_N830) + left_wire_dist + 2., HOP4X(9), PIP_Y(id_N830) + 3.}, - {HOP4X(9), PIP_Y(id_N830) + 3., HOP4X(7), PIP_Y(id_N830) + left_wire_dist + 3.}, - {HOP4X(9), PIP_Y(id_N834) + 3., WIRE_X(0), PIP_Y(id_N834) + 3.}, - {HOP4X(7), PIP_Y(id_N830) + left_wire_dist + 3., HOP4X(7), PIP_Y(id_N830) + 4.}, - {HOP4X(7), PIP_Y(id_N830) + 4., HOP4X(5), PIP_Y(id_N830) + left_wire_dist + 4.}, - {HOP4X(5), PIP_Y(id_N830) + left_wire_dist + 4., HOP4X(5), PIP_Y(id_N830) + 5.}, - {HOP4X(5), PIP_Y(id_N830) + 5., HOP4X(3), PIP_Y(id_N830) + left_wire_dist + 5.}, - {HOP4X(3), PIP_Y(id_N830) + left_wire_dist + 5., HOP4X(3), PIP_Y(id_N830) + 6.}, - {HOP4X(3), PIP_Y(id_N830) + 6., HOP4X(1), PIP_Y(id_N830) + left_wire_dist + 6.}, - {HOP4X(1), PIP_Y(id_N830) + left_wire_dist + 6., HOP4X(1), PIP_Y(id_N838) + 7.}, - {HOP4X(1), PIP_Y(id_N838) + 7., WIRE_X(0), PIP_Y(id_N838) + 7.}}}, - {id_S83_loop1, - {{WIRE_X(0), PIP_Y(id_S830), HOP4X(16), PIP_Y(id_S830)}, - {HOP4X(16), PIP_Y(id_S830), HOP4X(16), PIP_Y(id_N838)}, - {HOP4X(16), PIP_Y(id_N838) - 0., HOP4X(14), PIP_Y(id_N838) - left_wire_dist - 0.}, - {HOP4X(14), PIP_Y(id_N838) - left_wire_dist - 0., HOP4X(14), PIP_Y(id_N838) - 1.}, - {HOP4X(14), PIP_Y(id_N838) - 1., HOP4X(12), PIP_Y(id_N838) - left_wire_dist - 1.}, - {HOP4X(12), PIP_Y(id_N838) - left_wire_dist - 1., HOP4X(12), -wrap_len - 1.}, - {HOP4X(12), -wrap_len - 1., HOP4X(13), -wrap_len - 1.}, - {HOP4X(13), -wrap_len - 1., HOP4X(13), PIP_Y(id_N830) - 1.}, - {HOP4X(13), PIP_Y(id_N830) - 1., HOP4X(11), PIP_Y(id_N830) + left_wire_dist - 1.}, - {HOP4X(11), PIP_Y(id_N830) + left_wire_dist - 1., HOP4X(11), PIP_Y(id_N830) - 0.}, - {HOP4X(11), PIP_Y(id_N830) - 0., HOP4X(9), PIP_Y(id_N830) + left_wire_dist - 0.}, - {HOP4X(9), PIP_Y(id_N830) + left_wire_dist - 0., HOP4X(9), PIP_Y(id_N830) + 1.}, - {HOP4X(9), PIP_Y(id_N830) + 1., HOP4X(7), PIP_Y(id_N830) + left_wire_dist + 1.}, - {HOP4X(9), PIP_Y(id_N834) + 1., WIRE_X(0), PIP_Y(id_N834) + 1.}, - {HOP4X(7), PIP_Y(id_N830) + left_wire_dist + 1., HOP4X(7), PIP_Y(id_N830) + 2.}, - {HOP4X(7), PIP_Y(id_N830) + 2., HOP4X(5), PIP_Y(id_N830) + left_wire_dist + 2.}, - {HOP4X(5), PIP_Y(id_N830) + left_wire_dist + 2., HOP4X(5), PIP_Y(id_N830) + 3.}, - {HOP4X(5), PIP_Y(id_N830) + 3., HOP4X(3), PIP_Y(id_N830) + left_wire_dist + 3.}, - {HOP4X(3), PIP_Y(id_N830) + left_wire_dist + 3., HOP4X(3), PIP_Y(id_N830) + 4.}, - {HOP4X(3), PIP_Y(id_N830) + 4., HOP4X(1), PIP_Y(id_N830) + left_wire_dist + 4.}, - {HOP4X(1), PIP_Y(id_N830) + left_wire_dist + 4., HOP4X(1), PIP_Y(id_N838) + 5.}, - {HOP4X(1), PIP_Y(id_N838) + 5., WIRE_X(0), PIP_Y(id_N838) + 5.}}}, - {id_S83_loop2, - {{WIRE_X(0), PIP_Y(id_S830), HOP4X(16), PIP_Y(id_S830)}, - {HOP4X(16), PIP_Y(id_S830), HOP4X(16), PIP_Y(id_N838)}, - {HOP4X(16), PIP_Y(id_N838) - 0., HOP4X(14), PIP_Y(id_N838) - left_wire_dist - 0.}, - {HOP4X(14), PIP_Y(id_N838) - left_wire_dist - 0., HOP4X(14), PIP_Y(id_N838) - 1.}, - {HOP4X(14), PIP_Y(id_N838) - 1., HOP4X(12), PIP_Y(id_N838) - left_wire_dist - 1.}, - {HOP4X(12), PIP_Y(id_N838) - left_wire_dist - 1., HOP4X(12), PIP_Y(id_N838) - 2.}, - {HOP4X(12), PIP_Y(id_N838) - 2., HOP4X(10), PIP_Y(id_N838) - left_wire_dist - 2.}, - {HOP4X(10), PIP_Y(id_N838) - left_wire_dist - 2., HOP4X(10), -wrap_len - 2.}, - {HOP4X(10), -wrap_len - 2., HOP4X(11), -wrap_len - 2.}, - {HOP4X(11), -wrap_len - 2., HOP4X(11), PIP_Y(id_N830) - 2.}, - {HOP4X(11), PIP_Y(id_N830) - 2., HOP4X(9), PIP_Y(id_N830) + left_wire_dist - 2.}, - {HOP4X(9), PIP_Y(id_N830) + left_wire_dist - 2., HOP4X(9), PIP_Y(id_N830) - 1.}, - {HOP4X(9), PIP_Y(id_N830) - 1., HOP4X(7), PIP_Y(id_N830) + left_wire_dist - 1.}, - {HOP4X(9), PIP_Y(id_N834) - 1., WIRE_X(0), PIP_Y(id_N834) - 1.}, - {HOP4X(7), PIP_Y(id_N830) + left_wire_dist - 1., HOP4X(7), PIP_Y(id_N830) - 0.}, - {HOP4X(7), PIP_Y(id_N830) - 0., HOP4X(5), PIP_Y(id_N830) + left_wire_dist - 0.}, - {HOP4X(5), PIP_Y(id_N830) + left_wire_dist - 0., HOP4X(5), PIP_Y(id_N830) + 1.}, - {HOP4X(5), PIP_Y(id_N830) + 1., HOP4X(3), PIP_Y(id_N830) + left_wire_dist + 1.}, - {HOP4X(3), PIP_Y(id_N830) + left_wire_dist + 1., HOP4X(3), PIP_Y(id_N830) + 2.}, - {HOP4X(3), PIP_Y(id_N830) + 2., HOP4X(1), PIP_Y(id_N830) + left_wire_dist + 2.}, - {HOP4X(1), PIP_Y(id_N830) + left_wire_dist + 2., HOP4X(1), PIP_Y(id_N838) + 3.}, - {HOP4X(1), PIP_Y(id_N838) + 3., WIRE_X(0), PIP_Y(id_N838) + 3.}}}, - {id_S83_loop3, - {{WIRE_X(0), PIP_Y(id_S830), HOP4X(16), PIP_Y(id_S830)}, - {HOP4X(16), PIP_Y(id_S830), HOP4X(16), PIP_Y(id_N838)}, - {HOP4X(16), PIP_Y(id_N838) - 0., HOP4X(14), PIP_Y(id_N838) - left_wire_dist - 0.}, - {HOP4X(14), PIP_Y(id_N838) - left_wire_dist - 0., HOP4X(14), PIP_Y(id_N838) - 1.}, - {HOP4X(14), PIP_Y(id_N838) - 1., HOP4X(12), PIP_Y(id_N838) - left_wire_dist - 1.}, - {HOP4X(12), PIP_Y(id_N838) - left_wire_dist - 1., HOP4X(12), PIP_Y(id_N838) - 2.}, - {HOP4X(12), PIP_Y(id_N838) - 2., HOP4X(10), PIP_Y(id_N838) - left_wire_dist - 2.}, - {HOP4X(10), PIP_Y(id_N838) - left_wire_dist - 2., HOP4X(10), PIP_Y(id_N838) - 3.}, - {HOP4X(10), PIP_Y(id_N838) - 3., HOP4X(8), PIP_Y(id_N838) - left_wire_dist - 3.}, - {HOP4X(8), PIP_Y(id_N838) - left_wire_dist - 3., HOP4X(8), -wrap_len - 3.}, - {HOP4X(8), -wrap_len - 3., HOP4X(9), -wrap_len - 3.}, - {HOP4X(9), -wrap_len - 3., HOP4X(9), PIP_Y(id_N830) - 3.}, - {HOP4X(9), PIP_Y(id_N834) - 3., WIRE_X(0), PIP_Y(id_N834) - 3.}, - {HOP4X(9), PIP_Y(id_N830) - 3., HOP4X(7), PIP_Y(id_N830) + left_wire_dist - 3.}, - {HOP4X(7), PIP_Y(id_N830) + left_wire_dist - 3., HOP4X(7), PIP_Y(id_N830) - 2.}, - {HOP4X(7), PIP_Y(id_N830) - 2., HOP4X(5), PIP_Y(id_N830) + left_wire_dist - 2.}, - {HOP4X(5), PIP_Y(id_N830) + left_wire_dist - 2., HOP4X(5), PIP_Y(id_N830) - 1.}, - {HOP4X(5), PIP_Y(id_N830) - 1., HOP4X(3), PIP_Y(id_N830) + left_wire_dist - 1.}, - {HOP4X(3), PIP_Y(id_N830) + left_wire_dist - 1., HOP4X(3), PIP_Y(id_N830) - 0.}, - {HOP4X(3), PIP_Y(id_N830) - 0., HOP4X(1), PIP_Y(id_N830) + left_wire_dist - 0.}, - {HOP4X(1), PIP_Y(id_N830) + left_wire_dist - 0., HOP4X(1), PIP_Y(id_N838) + 1.}, - {HOP4X(1), PIP_Y(id_N838) + 1., WIRE_X(0), PIP_Y(id_N838) + 1.}}}, - {id_S83_loop4, - {{WIRE_X(0), PIP_Y(id_S830), HOP4X(16), PIP_Y(id_S830)}, - {HOP4X(16), PIP_Y(id_S830), HOP4X(16), PIP_Y(id_N838)}, - {HOP4X(16), PIP_Y(id_N838) - 0., HOP4X(14), PIP_Y(id_N838) - left_wire_dist - 0.}, - {HOP4X(14), PIP_Y(id_N838) - left_wire_dist - 0., HOP4X(14), PIP_Y(id_N838) - 1.}, - {HOP4X(14), PIP_Y(id_N838) - 1., HOP4X(12), PIP_Y(id_N838) - left_wire_dist - 1.}, - {HOP4X(12), PIP_Y(id_N838) - left_wire_dist - 1., HOP4X(12), PIP_Y(id_N838) - 2.}, - {HOP4X(12), PIP_Y(id_N838) - 2., HOP4X(10), PIP_Y(id_N838) - left_wire_dist - 2.}, - {HOP4X(10), PIP_Y(id_N838) - left_wire_dist - 2., HOP4X(10), PIP_Y(id_N838) - 3.}, - {HOP4X(10), PIP_Y(id_N838) - 3., HOP4X(8), PIP_Y(id_N838) - left_wire_dist - 3.}, - {HOP4X(8), PIP_Y(id_N838) - left_wire_dist - 3., HOP4X(8), PIP_Y(id_N838) - 4.}, - {HOP4X(8), PIP_Y(id_S834) - 4., WIRE_X(0), PIP_Y(id_S834) - 4.}, - {HOP4X(8), PIP_Y(id_N838) - 4., HOP4X(6), PIP_Y(id_N838) - left_wire_dist - 4.}, - {HOP4X(6), PIP_Y(id_N838) - left_wire_dist - 4., HOP4X(6), -wrap_len - 4.}, - {HOP4X(6), -wrap_len - 4., HOP4X(7), -wrap_len - 4.}, - {HOP4X(7), -wrap_len - 4., HOP4X(7), PIP_Y(id_N830) - 4.}, - {HOP4X(7), PIP_Y(id_N830) - 4., HOP4X(5), PIP_Y(id_N830) + left_wire_dist - 4.}, - {HOP4X(5), PIP_Y(id_N830) + left_wire_dist - 4., HOP4X(5), PIP_Y(id_N830) - 3.}, - {HOP4X(5), PIP_Y(id_N830) - 3., HOP4X(3), PIP_Y(id_N830) + left_wire_dist - 3.}, - {HOP4X(3), PIP_Y(id_N830) + left_wire_dist - 3., HOP4X(3), PIP_Y(id_N830) - 2.}, - {HOP4X(3), PIP_Y(id_N830) - 2., HOP4X(1), PIP_Y(id_N830) + left_wire_dist - 2.}, - {HOP4X(1), PIP_Y(id_N830) + left_wire_dist - 2., HOP4X(1), PIP_Y(id_N838) - 1.}, - {HOP4X(1), PIP_Y(id_N838) - 1., WIRE_X(0), PIP_Y(id_N838) - 1.}}}, - {id_S83_loop5, - {{WIRE_X(0), PIP_Y(id_S830), HOP4X(16), PIP_Y(id_S830)}, - {HOP4X(16), PIP_Y(id_S830), HOP4X(16), PIP_Y(id_N838)}, - {HOP4X(16), PIP_Y(id_N838) - 0., HOP4X(14), PIP_Y(id_N838) - left_wire_dist - 0.}, - {HOP4X(14), PIP_Y(id_N838) - left_wire_dist - 0., HOP4X(14), PIP_Y(id_N838) - 1.}, - {HOP4X(14), PIP_Y(id_N838) - 1., HOP4X(12), PIP_Y(id_N838) - left_wire_dist - 1.}, - {HOP4X(12), PIP_Y(id_N838) - left_wire_dist - 1., HOP4X(12), PIP_Y(id_N838) - 2.}, - {HOP4X(12), PIP_Y(id_N838) - 2., HOP4X(10), PIP_Y(id_N838) - left_wire_dist - 2.}, - {HOP4X(10), PIP_Y(id_N838) - left_wire_dist - 2., HOP4X(10), PIP_Y(id_N838) - 3.}, - {HOP4X(10), PIP_Y(id_N838) - 3., HOP4X(8), PIP_Y(id_N838) - left_wire_dist - 3.}, - {HOP4X(8), PIP_Y(id_N838) - left_wire_dist - 3., HOP4X(8), PIP_Y(id_N838) - 4.}, - {HOP4X(8), PIP_Y(id_S834) - 4., WIRE_X(0), PIP_Y(id_S834) - 4.}, - {HOP4X(8), PIP_Y(id_N838) - 4., HOP4X(6), PIP_Y(id_N838) - left_wire_dist - 4.}, - {HOP4X(6), PIP_Y(id_N838) - left_wire_dist - 4., HOP4X(6), PIP_Y(id_N838) - 5.}, - {HOP4X(6), PIP_Y(id_N838) - 5., HOP4X(4), PIP_Y(id_N838) - left_wire_dist - 5.}, - {HOP4X(4), PIP_Y(id_N838) - left_wire_dist - 5., HOP4X(4), -wrap_len - 5.}, - {HOP4X(4), -wrap_len - 5., HOP4X(5), -wrap_len - 5.}, - {HOP4X(5), -wrap_len - 5., HOP4X(5), PIP_Y(id_N830) - 5.}, - {HOP4X(5), PIP_Y(id_N830) - 5., HOP4X(3), PIP_Y(id_N830) + left_wire_dist - 5.}, - {HOP4X(3), PIP_Y(id_N830) + left_wire_dist - 5., HOP4X(3), PIP_Y(id_N830) - 4.}, - {HOP4X(3), PIP_Y(id_N830) - 4., HOP4X(1), PIP_Y(id_N830) + left_wire_dist - 4.}, - {HOP4X(1), PIP_Y(id_N830) + left_wire_dist - 4., HOP4X(1), PIP_Y(id_N838) - 3.}, - {HOP4X(1), PIP_Y(id_N838) - 3., WIRE_X(0), PIP_Y(id_N838) - 3.}}}, - {id_S83_loop6, - {{WIRE_X(0), PIP_Y(id_S830), HOP4X(16), PIP_Y(id_S830)}, - {HOP4X(16), PIP_Y(id_S830), HOP4X(16), PIP_Y(id_N838)}, - {HOP4X(16), PIP_Y(id_N838) - 0., HOP4X(14), PIP_Y(id_N838) - left_wire_dist - 0.}, - {HOP4X(14), PIP_Y(id_N838) - left_wire_dist - 0., HOP4X(14), PIP_Y(id_N838) - 1.}, - {HOP4X(14), PIP_Y(id_N838) - 1., HOP4X(12), PIP_Y(id_N838) - left_wire_dist - 1.}, - {HOP4X(12), PIP_Y(id_N838) - left_wire_dist - 1., HOP4X(12), PIP_Y(id_N838) - 2.}, - {HOP4X(12), PIP_Y(id_N838) - 2., HOP4X(10), PIP_Y(id_N838) - left_wire_dist - 2.}, - {HOP4X(10), PIP_Y(id_N838) - left_wire_dist - 2., HOP4X(10), PIP_Y(id_N838) - 3.}, - {HOP4X(10), PIP_Y(id_N838) - 3., HOP4X(8), PIP_Y(id_N838) - left_wire_dist - 3.}, - {HOP4X(8), PIP_Y(id_N838) - left_wire_dist - 3., HOP4X(8), PIP_Y(id_N838) - 4.}, - {HOP4X(8), PIP_Y(id_S834) - 4., WIRE_X(0), PIP_Y(id_S834) - 4.}, - {HOP4X(8), PIP_Y(id_N838) - 4., HOP4X(6), PIP_Y(id_N838) - left_wire_dist - 4.}, - {HOP4X(6), PIP_Y(id_N838) - left_wire_dist - 4., HOP4X(6), PIP_Y(id_N838) - 5.}, - {HOP4X(6), PIP_Y(id_N838) - 5., HOP4X(4), PIP_Y(id_N838) - left_wire_dist - 5.}, - {HOP4X(4), PIP_Y(id_N838) - left_wire_dist - 5., HOP4X(4), PIP_Y(id_N838) - 6.}, - {HOP4X(4), PIP_Y(id_N838) - 6., HOP4X(2), PIP_Y(id_N838) - left_wire_dist - 6.}, - {HOP4X(2), PIP_Y(id_N838) - left_wire_dist - 6., HOP4X(2), -wrap_len - 6.}, - {HOP4X(2), -wrap_len - 6., HOP4X(3), -wrap_len - 6.}, - {HOP4X(3), -wrap_len - 6., HOP4X(3), PIP_Y(id_N830) - 6.}, - {HOP4X(3), PIP_Y(id_N830) - 6., HOP4X(1), PIP_Y(id_N830) + left_wire_dist - 6.}, - {HOP4X(1), PIP_Y(id_N830) + left_wire_dist - 6., HOP4X(1), PIP_Y(id_N838) - 5.}, - {HOP4X(1), PIP_Y(id_N838) - 5., WIRE_X(0), PIP_Y(id_N838) - 5.}}}, - {id_S83_loop7, - {{WIRE_X(0), PIP_Y(id_S830), HOP4X(16), PIP_Y(id_S830)}, - {HOP4X(16), PIP_Y(id_S830), HOP4X(16), PIP_Y(id_N838)}, - {HOP4X(16), PIP_Y(id_N838) - 0., HOP4X(14), PIP_Y(id_N838) - left_wire_dist - 0.}, - {HOP4X(14), PIP_Y(id_N838) - left_wire_dist - 0., HOP4X(14), PIP_Y(id_N838) - 1.}, - {HOP4X(14), PIP_Y(id_N838) - 1., HOP4X(12), PIP_Y(id_N838) - left_wire_dist - 1.}, - {HOP4X(12), PIP_Y(id_N838) - left_wire_dist - 1., HOP4X(12), PIP_Y(id_N838) - 2.}, - {HOP4X(12), PIP_Y(id_N838) - 2., HOP4X(10), PIP_Y(id_N838) - left_wire_dist - 2.}, - {HOP4X(10), PIP_Y(id_N838) - left_wire_dist - 2., HOP4X(10), PIP_Y(id_N838) - 3.}, - {HOP4X(10), PIP_Y(id_N838) - 3., HOP4X(8), PIP_Y(id_N838) - left_wire_dist - 3.}, - {HOP4X(8), PIP_Y(id_N838) - left_wire_dist - 3., HOP4X(8), PIP_Y(id_N838) - 4.}, - {HOP4X(8), PIP_Y(id_S834) - 4., WIRE_X(0), PIP_Y(id_S834) - 4.}, - {HOP4X(8), PIP_Y(id_N838) - 4., HOP4X(6), PIP_Y(id_N838) - left_wire_dist - 4.}, - {HOP4X(6), PIP_Y(id_N838) - left_wire_dist - 4., HOP4X(6), PIP_Y(id_N838) - 5.}, - {HOP4X(6), PIP_Y(id_N838) - 5., HOP4X(4), PIP_Y(id_N838) - left_wire_dist - 5.}, - {HOP4X(4), PIP_Y(id_N838) - left_wire_dist - 5., HOP4X(4), PIP_Y(id_N838) - 6.}, - {HOP4X(4), PIP_Y(id_N838) - 6., HOP4X(2), PIP_Y(id_N838) - left_wire_dist - 6.}, - {HOP4X(2), PIP_Y(id_N838) - left_wire_dist - 6., HOP4X(2), PIP_Y(id_N838) - 7.}, - {HOP4X(2), PIP_Y(id_N838) - 7., HOP4X(0), PIP_Y(id_N838) - left_wire_dist - 7.}, - {HOP4X(0), PIP_Y(id_N838) - left_wire_dist - 7., HOP4X(0), -wrap_len - 7.}, - {HOP4X(0), -wrap_len - 7., HOP4X(1), -wrap_len - 7.}, - {HOP4X(1), -wrap_len - 7., HOP4X(1), PIP_Y(id_N838) - 7.}, - {HOP4X(1), PIP_Y(id_N838) - 7., WIRE_X(0), PIP_Y(id_N838) - 7.}}}, - {id_N83_loop0, - {{WIRE_X(0), PIP_Y(id_N830), HOP4X(17), PIP_Y(id_N830)}, - {HOP4X(17), PIP_Y(id_N830) + 0., HOP4X(15), PIP_Y(id_N830) + left_wire_dist + 0.}, - {HOP4X(15), PIP_Y(id_N830) + left_wire_dist + 0., HOP4X(15), wrap_len + 1.}, - {HOP4X(15), wrap_len + 1., HOP4X(14), wrap_len + 1.}, - {HOP4X(14), wrap_len + 1., HOP4X(14), PIP_Y(id_N838) + 0.}, - {HOP4X(14), PIP_Y(id_N838) + 0., HOP4X(12), PIP_Y(id_N838) - left_wire_dist + 0.}, - {HOP4X(12), PIP_Y(id_N838) - left_wire_dist + 0., HOP4X(12), PIP_Y(id_N838) - 1.}, - {HOP4X(12), PIP_Y(id_N838) - 1., HOP4X(10), PIP_Y(id_N838) - left_wire_dist - 1.}, - {HOP4X(10), PIP_Y(id_N838) - left_wire_dist - 1., HOP4X(10), PIP_Y(id_N838) - 2.}, - {HOP4X(10), PIP_Y(id_N838) - 2., HOP4X(8), PIP_Y(id_N838) - left_wire_dist - 2.}, - {HOP4X(8), PIP_Y(id_N838) - left_wire_dist - 2., HOP4X(8), PIP_Y(id_N838) - 3.}, - {HOP4X(8), PIP_Y(id_S834) - 3., WIRE_X(0), PIP_Y(id_S834) - 3.}, - {HOP4X(8), PIP_Y(id_N838) - 3., HOP4X(6), PIP_Y(id_N838) - left_wire_dist - 3.}, - {HOP4X(6), PIP_Y(id_N838) - left_wire_dist - 3., HOP4X(6), PIP_Y(id_N838) - 4.}, - {HOP4X(6), PIP_Y(id_N838) - 4., HOP4X(4), PIP_Y(id_N838) - left_wire_dist - 4.}, - {HOP4X(4), PIP_Y(id_N838) - left_wire_dist - 4., HOP4X(4), PIP_Y(id_N838) - 5.}, - {HOP4X(4), PIP_Y(id_N838) - 5., HOP4X(2), PIP_Y(id_N838) - left_wire_dist - 5.}, - {HOP4X(2), PIP_Y(id_N838) - left_wire_dist - 5., HOP4X(2), PIP_Y(id_N838) - 6.}, - {HOP4X(2), PIP_Y(id_N838) - 6., HOP4X(0), PIP_Y(id_N838) - left_wire_dist - 6.}, - {HOP4X(0), PIP_Y(id_N838) - left_wire_dist - 6., HOP4X(0), PIP_Y(id_S838) - 7.}, - {HOP4X(0), PIP_Y(id_S838) - 7., WIRE_X(0), PIP_Y(id_S838) - 7.}}}, - {id_N83_loop1, - {{WIRE_X(0), PIP_Y(id_N830), HOP4X(17), PIP_Y(id_N830)}, - {HOP4X(17), PIP_Y(id_N830) + 0., HOP4X(15), PIP_Y(id_N830) + left_wire_dist + 0.}, - {HOP4X(15), PIP_Y(id_N830) + left_wire_dist + 0., HOP4X(15), PIP_Y(id_N830) + 1.}, - {HOP4X(15), PIP_Y(id_N830) + 1., HOP4X(13), PIP_Y(id_N830) + left_wire_dist + 1.}, - {HOP4X(13), PIP_Y(id_N830) + left_wire_dist + 1., HOP4X(13), wrap_len + 2.}, - {HOP4X(13), wrap_len + 2., HOP4X(12), wrap_len + 2.}, - {HOP4X(12), wrap_len + 2., HOP4X(12), PIP_Y(id_N838) + 1.}, - {HOP4X(12), PIP_Y(id_N838) + 1., HOP4X(10), PIP_Y(id_N838) - left_wire_dist + 1.}, - {HOP4X(10), PIP_Y(id_N838) - left_wire_dist + 1., HOP4X(10), PIP_Y(id_N838) + 0.}, - {HOP4X(10), PIP_Y(id_N838) + 0., HOP4X(8), PIP_Y(id_N838) - left_wire_dist + 0.}, - {HOP4X(8), PIP_Y(id_N838) - left_wire_dist + 0., HOP4X(8), PIP_Y(id_N838) - 1.}, - {HOP4X(8), PIP_Y(id_S834) - 1., WIRE_X(0), PIP_Y(id_S834) - 1.}, - {HOP4X(8), PIP_Y(id_N838) - 1., HOP4X(6), PIP_Y(id_N838) - left_wire_dist - 1.}, - {HOP4X(6), PIP_Y(id_N838) - left_wire_dist - 1., HOP4X(6), PIP_Y(id_N838) - 2.}, - {HOP4X(6), PIP_Y(id_N838) - 2., HOP4X(4), PIP_Y(id_N838) - left_wire_dist - 2.}, - {HOP4X(4), PIP_Y(id_N838) - left_wire_dist - 2., HOP4X(4), PIP_Y(id_N838) - 3.}, - {HOP4X(4), PIP_Y(id_N838) - 3., HOP4X(2), PIP_Y(id_N838) - left_wire_dist - 3.}, - {HOP4X(2), PIP_Y(id_N838) - left_wire_dist - 3., HOP4X(2), PIP_Y(id_N838) - 4.}, - {HOP4X(2), PIP_Y(id_N838) - 4., HOP4X(0), PIP_Y(id_N838) - left_wire_dist - 4.}, - {HOP4X(0), PIP_Y(id_N838) - left_wire_dist - 4., HOP4X(0), PIP_Y(id_S838) - 5.}, - {HOP4X(0), PIP_Y(id_S838) - 5., WIRE_X(0), PIP_Y(id_S838) - 5.}}}, - {id_N83_loop2, - {{WIRE_X(0), PIP_Y(id_N830), HOP4X(17), PIP_Y(id_N830)}, - {HOP4X(17), PIP_Y(id_N830) + 0., HOP4X(15), PIP_Y(id_N830) + left_wire_dist + 0.}, - {HOP4X(15), PIP_Y(id_N830) + left_wire_dist + 0., HOP4X(15), PIP_Y(id_N830) + 1.}, - {HOP4X(15), PIP_Y(id_N830) + 1., HOP4X(13), PIP_Y(id_N830) + left_wire_dist + 1.}, - {HOP4X(13), PIP_Y(id_N830) + left_wire_dist + 1., HOP4X(13), PIP_Y(id_N830) + 2.}, - {HOP4X(13), PIP_Y(id_N830) + 2., HOP4X(11), PIP_Y(id_N830) + left_wire_dist + 2.}, - {HOP4X(11), PIP_Y(id_N830) + left_wire_dist + 2., HOP4X(11), wrap_len + 3.}, - {HOP4X(11), wrap_len + 3., HOP4X(10), wrap_len + 3.}, - {HOP4X(10), wrap_len + 3., HOP4X(10), PIP_Y(id_N838) + 2.}, - {HOP4X(10), PIP_Y(id_N838) + 2., HOP4X(8), PIP_Y(id_N838) - left_wire_dist + 2.}, - {HOP4X(8), PIP_Y(id_N838) - left_wire_dist + 2., HOP4X(8), PIP_Y(id_N838) + 1.}, - {HOP4X(8), PIP_Y(id_S834) + 1., WIRE_X(0), PIP_Y(id_S834) + 1.}, - {HOP4X(8), PIP_Y(id_N838) + 1., HOP4X(6), PIP_Y(id_N838) - left_wire_dist + 1.}, - {HOP4X(6), PIP_Y(id_N838) - left_wire_dist + 1., HOP4X(6), PIP_Y(id_N838) + 0.}, - {HOP4X(6), PIP_Y(id_N838) + 0., HOP4X(4), PIP_Y(id_N838) - left_wire_dist + 0.}, - {HOP4X(4), PIP_Y(id_N838) - left_wire_dist + 0., HOP4X(4), PIP_Y(id_N838) - 1.}, - {HOP4X(4), PIP_Y(id_N838) - 1., HOP4X(2), PIP_Y(id_N838) - left_wire_dist - 1.}, - {HOP4X(2), PIP_Y(id_N838) - left_wire_dist - 1., HOP4X(2), PIP_Y(id_N838) - 2.}, - {HOP4X(2), PIP_Y(id_N838) - 2., HOP4X(0), PIP_Y(id_N838) - left_wire_dist - 2.}, - {HOP4X(0), PIP_Y(id_N838) - left_wire_dist - 2., HOP4X(0), PIP_Y(id_S838) - 3.}, - {HOP4X(0), PIP_Y(id_S838) - 3., WIRE_X(0), PIP_Y(id_S838) - 3.}}}, - {id_N83_loop3, - {{WIRE_X(0), PIP_Y(id_N830), HOP4X(17), PIP_Y(id_N830)}, - {HOP4X(17), PIP_Y(id_N830) + 0., HOP4X(15), PIP_Y(id_N830) + left_wire_dist + 0.}, - {HOP4X(15), PIP_Y(id_N830) + left_wire_dist + 0., HOP4X(15), PIP_Y(id_N830) + 1.}, - {HOP4X(15), PIP_Y(id_N830) + 1., HOP4X(13), PIP_Y(id_N830) + left_wire_dist + 1.}, - {HOP4X(13), PIP_Y(id_N830) + left_wire_dist + 1., HOP4X(13), PIP_Y(id_N830) + 2.}, - {HOP4X(13), PIP_Y(id_N830) + 2., HOP4X(11), PIP_Y(id_N830) + left_wire_dist + 2.}, - {HOP4X(11), PIP_Y(id_N830) + left_wire_dist + 2., HOP4X(11), PIP_Y(id_N830) + 3.}, - {HOP4X(11), PIP_Y(id_N830) + 3., HOP4X(9), PIP_Y(id_N830) + left_wire_dist + 3.}, - {HOP4X(9), PIP_Y(id_N830) + left_wire_dist + 3., HOP4X(9), wrap_len + 4.}, - {HOP4X(9), wrap_len + 4., HOP4X(8), wrap_len + 4.}, - {HOP4X(8), wrap_len + 4., HOP4X(8), PIP_Y(id_N838) + 3.}, - {HOP4X(8), PIP_Y(id_S834) + 3., WIRE_X(0), PIP_Y(id_S834) + 3.}, - {HOP4X(8), PIP_Y(id_N838) + 3., HOP4X(6), PIP_Y(id_N838) - left_wire_dist + 3.}, - {HOP4X(6), PIP_Y(id_N838) - left_wire_dist + 3., HOP4X(6), PIP_Y(id_N838) + 2.}, - {HOP4X(6), PIP_Y(id_N838) + 2., HOP4X(4), PIP_Y(id_N838) - left_wire_dist + 2.}, - {HOP4X(4), PIP_Y(id_N838) - left_wire_dist + 2., HOP4X(4), PIP_Y(id_N838) + 1.}, - {HOP4X(4), PIP_Y(id_N838) + 1., HOP4X(2), PIP_Y(id_N838) - left_wire_dist + 1.}, - {HOP4X(2), PIP_Y(id_N838) - left_wire_dist + 1., HOP4X(2), PIP_Y(id_N838) + 0.}, - {HOP4X(2), PIP_Y(id_N838) + 0., HOP4X(0), PIP_Y(id_N838) - left_wire_dist + 0.}, - {HOP4X(0), PIP_Y(id_N838) - left_wire_dist + 0., HOP4X(0), PIP_Y(id_S838) - 1.}, - {HOP4X(0), PIP_Y(id_S838) - 1., WIRE_X(0), PIP_Y(id_S838) - 1.}}}, - {id_N83_loop4, - {{WIRE_X(0), PIP_Y(id_N830), HOP4X(17), PIP_Y(id_N830)}, - {HOP4X(17), PIP_Y(id_N830) + 0., HOP4X(15), PIP_Y(id_N830) + left_wire_dist + 0.}, - {HOP4X(15), PIP_Y(id_N830) + left_wire_dist + 0., HOP4X(15), PIP_Y(id_N830) + 1.}, - {HOP4X(15), PIP_Y(id_N830) + 1., HOP4X(13), PIP_Y(id_N830) + left_wire_dist + 1.}, - {HOP4X(13), PIP_Y(id_N830) + left_wire_dist + 1., HOP4X(13), PIP_Y(id_N830) + 2.}, - {HOP4X(13), PIP_Y(id_N830) + 2., HOP4X(11), PIP_Y(id_N830) + left_wire_dist + 2.}, - {HOP4X(11), PIP_Y(id_N830) + left_wire_dist + 2., HOP4X(11), PIP_Y(id_N830) + 3.}, - {HOP4X(11), PIP_Y(id_N830) + 3., HOP4X(9), PIP_Y(id_N830) + left_wire_dist + 3.}, - {HOP4X(9), PIP_Y(id_N830) + left_wire_dist + 3., HOP4X(9), PIP_Y(id_N830) + 4.}, - {HOP4X(9), PIP_Y(id_N834) + 4., WIRE_X(0), PIP_Y(id_N834) + 4.}, - {HOP4X(9), PIP_Y(id_N830) + 4., HOP4X(7), PIP_Y(id_N830) + left_wire_dist + 4.}, - {HOP4X(7), PIP_Y(id_N830) + left_wire_dist + 4., HOP4X(7), wrap_len + 5.}, - {HOP4X(7), wrap_len + 5., HOP4X(6), wrap_len + 5.}, - {HOP4X(6), wrap_len + 5., HOP4X(6), PIP_Y(id_N838) + 4.}, - {HOP4X(6), PIP_Y(id_N838) + 4., HOP4X(4), PIP_Y(id_N838) - left_wire_dist + 4.}, - {HOP4X(4), PIP_Y(id_N838) - left_wire_dist + 4., HOP4X(4), PIP_Y(id_N838) + 3.}, - {HOP4X(4), PIP_Y(id_N838) + 3., HOP4X(2), PIP_Y(id_N838) - left_wire_dist + 3.}, - {HOP4X(2), PIP_Y(id_N838) - left_wire_dist + 3., HOP4X(2), PIP_Y(id_N838) + 2.}, - {HOP4X(2), PIP_Y(id_N838) + 2., HOP4X(0), PIP_Y(id_N838) - left_wire_dist + 2.}, - {HOP4X(0), PIP_Y(id_N838) - left_wire_dist + 2., HOP4X(0), PIP_Y(id_S838) + 1.}, - {HOP4X(0), PIP_Y(id_S838) + 1., WIRE_X(0), PIP_Y(id_S838) + 1.}}}, - {id_N83_loop5, - {{WIRE_X(0), PIP_Y(id_N830), HOP4X(17), PIP_Y(id_N830)}, - {HOP4X(17), PIP_Y(id_N830) + 0., HOP4X(15), PIP_Y(id_N830) + left_wire_dist + 0.}, - {HOP4X(15), PIP_Y(id_N830) + left_wire_dist + 0., HOP4X(15), PIP_Y(id_N830) + 1.}, - {HOP4X(15), PIP_Y(id_N830) + 1., HOP4X(13), PIP_Y(id_N830) + left_wire_dist + 1.}, - {HOP4X(13), PIP_Y(id_N830) + left_wire_dist + 1., HOP4X(13), PIP_Y(id_N830) + 2.}, - {HOP4X(13), PIP_Y(id_N830) + 2., HOP4X(11), PIP_Y(id_N830) + left_wire_dist + 2.}, - {HOP4X(11), PIP_Y(id_N830) + left_wire_dist + 2., HOP4X(11), PIP_Y(id_N830) + 3.}, - {HOP4X(11), PIP_Y(id_N830) + 3., HOP4X(9), PIP_Y(id_N830) + left_wire_dist + 3.}, - {HOP4X(9), PIP_Y(id_N830) + left_wire_dist + 3., HOP4X(9), PIP_Y(id_N830) + 4.}, - {HOP4X(9), PIP_Y(id_N834) + 4., WIRE_X(0), PIP_Y(id_N834) + 4.}, - {HOP4X(9), PIP_Y(id_N830) + 4., HOP4X(7), PIP_Y(id_N830) + left_wire_dist + 4.}, - {HOP4X(7), PIP_Y(id_N830) + left_wire_dist + 4., HOP4X(7), PIP_Y(id_N830) + 5.}, - {HOP4X(7), PIP_Y(id_N830) + 5., HOP4X(5), PIP_Y(id_N830) + left_wire_dist + 5.}, - {HOP4X(5), PIP_Y(id_N830) + left_wire_dist + 5., HOP4X(5), wrap_len + 6.}, - {HOP4X(5), wrap_len + 6., HOP4X(4), wrap_len + 6.}, - {HOP4X(4), wrap_len + 6., HOP4X(4), PIP_Y(id_N838) + 5.}, - {HOP4X(4), PIP_Y(id_N838) + 5., HOP4X(2), PIP_Y(id_N838) - left_wire_dist + 5.}, - {HOP4X(2), PIP_Y(id_N838) - left_wire_dist + 5., HOP4X(2), PIP_Y(id_N838) + 4.}, - {HOP4X(2), PIP_Y(id_N838) + 4., HOP4X(0), PIP_Y(id_N838) - left_wire_dist + 4.}, - {HOP4X(0), PIP_Y(id_N838) - left_wire_dist + 4., HOP4X(0), PIP_Y(id_S838) + 3.}, - {HOP4X(0), PIP_Y(id_S838) + 3., WIRE_X(0), PIP_Y(id_S838) + 3.}}}, - {id_N83_loop6, - {{WIRE_X(0), PIP_Y(id_N830), HOP4X(17), PIP_Y(id_N830)}, - {HOP4X(17), PIP_Y(id_N830) + 0., HOP4X(15), PIP_Y(id_N830) + left_wire_dist + 0.}, - {HOP4X(15), PIP_Y(id_N830) + left_wire_dist + 0., HOP4X(15), PIP_Y(id_N830) + 1.}, - {HOP4X(15), PIP_Y(id_N830) + 1., HOP4X(13), PIP_Y(id_N830) + left_wire_dist + 1.}, - {HOP4X(13), PIP_Y(id_N830) + left_wire_dist + 1., HOP4X(13), PIP_Y(id_N830) + 2.}, - {HOP4X(13), PIP_Y(id_N830) + 2., HOP4X(11), PIP_Y(id_N830) + left_wire_dist + 2.}, - {HOP4X(11), PIP_Y(id_N830) + left_wire_dist + 2., HOP4X(11), PIP_Y(id_N830) + 3.}, - {HOP4X(11), PIP_Y(id_N830) + 3., HOP4X(9), PIP_Y(id_N830) + left_wire_dist + 3.}, - {HOP4X(9), PIP_Y(id_N830) + left_wire_dist + 3., HOP4X(9), PIP_Y(id_N830) + 4.}, - {HOP4X(9), PIP_Y(id_N834) + 4., WIRE_X(0), PIP_Y(id_N834) + 4.}, - {HOP4X(9), PIP_Y(id_N830) + 4., HOP4X(7), PIP_Y(id_N830) + left_wire_dist + 4.}, - {HOP4X(7), PIP_Y(id_N830) + left_wire_dist + 4., HOP4X(7), PIP_Y(id_N830) + 5.}, - {HOP4X(7), PIP_Y(id_N830) + 5., HOP4X(5), PIP_Y(id_N830) + left_wire_dist + 5.}, - {HOP4X(5), PIP_Y(id_N830) + left_wire_dist + 5., HOP4X(5), PIP_Y(id_N830) + 6.}, - {HOP4X(5), PIP_Y(id_N830) + 6., HOP4X(3), PIP_Y(id_N830) + left_wire_dist + 6.}, - {HOP4X(3), PIP_Y(id_N830) + left_wire_dist + 6., HOP4X(3), wrap_len + 7.}, - {HOP4X(3), wrap_len + 7., HOP4X(2), wrap_len + 7.}, - {HOP4X(2), wrap_len + 7., HOP4X(2), PIP_Y(id_N838) + 6.}, - {HOP4X(2), PIP_Y(id_N838) + 6., HOP4X(0), PIP_Y(id_N838) - left_wire_dist + 6.}, - {HOP4X(0), PIP_Y(id_N838) - left_wire_dist + 6., HOP4X(0), PIP_Y(id_S838) + 5.}, - {HOP4X(0), PIP_Y(id_S838) + 5., WIRE_X(0), PIP_Y(id_S838) + 5.}}}, - {id_N83_loop7, - {{WIRE_X(0), PIP_Y(id_N830), HOP4X(17), PIP_Y(id_N830)}, - {HOP4X(17), PIP_Y(id_N830) + 0., HOP4X(15), PIP_Y(id_N830) + left_wire_dist + 0.}, - {HOP4X(15), PIP_Y(id_N830) + left_wire_dist + 0., HOP4X(15), PIP_Y(id_N830) + 1.}, - {HOP4X(15), PIP_Y(id_N830) + 1., HOP4X(13), PIP_Y(id_N830) + left_wire_dist + 1.}, - {HOP4X(13), PIP_Y(id_N830) + left_wire_dist + 1., HOP4X(13), PIP_Y(id_N830) + 2.}, - {HOP4X(13), PIP_Y(id_N830) + 2., HOP4X(11), PIP_Y(id_N830) + left_wire_dist + 2.}, - {HOP4X(11), PIP_Y(id_N830) + left_wire_dist + 2., HOP4X(11), PIP_Y(id_N830) + 3.}, - {HOP4X(11), PIP_Y(id_N830) + 3., HOP4X(9), PIP_Y(id_N830) + left_wire_dist + 3.}, - {HOP4X(9), PIP_Y(id_N830) + left_wire_dist + 3., HOP4X(9), PIP_Y(id_N830) + 4.}, - {HOP4X(9), PIP_Y(id_N834) + 4., WIRE_X(0), PIP_Y(id_N834) + 4.}, - {HOP4X(9), PIP_Y(id_N830) + 4., HOP4X(7), PIP_Y(id_N830) + left_wire_dist + 4.}, - {HOP4X(7), PIP_Y(id_N830) + left_wire_dist + 4., HOP4X(7), PIP_Y(id_N830) + 5.}, - {HOP4X(7), PIP_Y(id_N830) + 5., HOP4X(5), PIP_Y(id_N830) + left_wire_dist + 5.}, - {HOP4X(5), PIP_Y(id_N830) + left_wire_dist + 5., HOP4X(5), PIP_Y(id_N830) + 6.}, - {HOP4X(5), PIP_Y(id_N830) + 6., HOP4X(3), PIP_Y(id_N830) + left_wire_dist + 6.}, - {HOP4X(3), PIP_Y(id_N830) + left_wire_dist + 6., HOP4X(3), PIP_Y(id_N830) + 7.}, - {HOP4X(3), PIP_Y(id_N830) + 7., HOP4X(1), PIP_Y(id_N830) + left_wire_dist + 7.}, - {HOP4X(1), PIP_Y(id_N830) + left_wire_dist + 7., HOP4X(1), wrap_len + 8.}, - {HOP4X(1), wrap_len + 8., HOP4X(0), wrap_len + 8.}, - {HOP4X(0), wrap_len + 8., HOP4X(0), PIP_Y(id_S838) + 7.}, - {HOP4X(0), PIP_Y(id_S838) + 7., WIRE_X(0), PIP_Y(id_S838) + 7.}}}, - -#define PIP_X(pip_id) (pipPoint.at(pip_id).second) -#define WIRE_Y(offset) (cru_y + cru_h + ((float)offset) * ew_dist) - // 1 hop - {id_E10, - {{PIP_X(id_E100), WIRE_Y(0), PIP_X(id_E100), WIRE_Y(1)}, - {PIP_X(id_E100), WIRE_Y(1), PIP_X(id_E101) + 1., WIRE_Y(1)}, - {PIP_X(id_E101) + 1., WIRE_Y(1), PIP_X(id_E101) + 1., WIRE_Y(0)}}}, - {id_W10, - {{PIP_X(id_W100), WIRE_Y(0), PIP_X(id_W100), WIRE_Y(2)}, - {PIP_X(id_W100), WIRE_Y(2), PIP_X(id_W101) - 1., WIRE_Y(2)}, - {PIP_X(id_W101) - 1., WIRE_Y(2), PIP_X(id_W101) - 1., WIRE_Y(0)}}}, - {id_E10_loop0, - {{PIP_X(id_E100), WIRE_Y(0), PIP_X(id_E100), WIRE_Y(1)}, - {PIP_X(id_E100), WIRE_Y(1), 1. + wrap_len, WIRE_Y(1)}, - {1. + wrap_len, WIRE_Y(1), 1. + wrap_len, WIRE_Y(2)}, - {1. + wrap_len, WIRE_Y(2), PIP_X(id_W101), WIRE_Y(2)}, - {PIP_X(id_W101), WIRE_Y(2), PIP_X(id_W101), WIRE_Y(0)}}}, - {id_W10_loop0, - {{PIP_X(id_W100), WIRE_Y(0), PIP_X(id_W100), WIRE_Y(2)}, - {PIP_X(id_W100), WIRE_Y(2), -1. * wrap_len, WIRE_Y(2)}, - {-1. * wrap_len, WIRE_Y(2), -1. * wrap_len, WIRE_Y(1)}, - {-1. * wrap_len, WIRE_Y(1), PIP_X(id_E101), WIRE_Y(1)}, - {PIP_X(id_E101), WIRE_Y(1), PIP_X(id_E101), WIRE_Y(0)}}}, - {id_E13, - {{PIP_X(id_E130), WIRE_Y(0), PIP_X(id_E130), WIRE_Y(3)}, - {PIP_X(id_E130), WIRE_Y(3), PIP_X(id_E131) + 1., WIRE_Y(3)}, - {PIP_X(id_E131) + 1., WIRE_Y(3), PIP_X(id_E131) + 1., WIRE_Y(0)}}}, - {id_W13, - {{PIP_X(id_W130), WIRE_Y(0), PIP_X(id_W130), WIRE_Y(4)}, - {PIP_X(id_W130), WIRE_Y(4), PIP_X(id_W131) - 1., WIRE_Y(4)}, - {PIP_X(id_W131) - 1., WIRE_Y(4), PIP_X(id_W131) - 1., WIRE_Y(0)}}}, - {id_E13_loop0, - {{PIP_X(id_E130), WIRE_Y(0), PIP_X(id_E130), WIRE_Y(3)}, - {PIP_X(id_E130), WIRE_Y(3), 1. + wrap_len, WIRE_Y(3)}, - {1. + wrap_len, WIRE_Y(3), 1. + wrap_len, WIRE_Y(4)}, - {1. + wrap_len, WIRE_Y(4), PIP_X(id_W131), WIRE_Y(4)}, - {PIP_X(id_W131), WIRE_Y(4), PIP_X(id_W131), WIRE_Y(0)}}}, - {id_W13_loop0, - {{PIP_X(id_W130), WIRE_Y(0), PIP_X(id_W130), WIRE_Y(4)}, - {PIP_X(id_W130), WIRE_Y(4), -1. * wrap_len, WIRE_Y(4)}, - {-1. * wrap_len, WIRE_Y(4), -1. * wrap_len, WIRE_Y(3)}, - {-1. * wrap_len, WIRE_Y(3), PIP_X(id_E131), WIRE_Y(3)}, - {PIP_X(id_E131), WIRE_Y(3), PIP_X(id_E131), WIRE_Y(0)}}}, - // 1 hop EW - {id_EW10, - {{PIP_X(id_EW10), WIRE_Y(0), PIP_X(id_EW10), WIRE_Y(6)}, - {PIP_X(id_EW10), WIRE_Y(6), PIP_X(id_E111) + 1., WIRE_Y(6)}, - {PIP_X(id_E111) + 1., WIRE_Y(6), PIP_X(id_E111) + 1., WIRE_Y(0)}, - {PIP_X(id_EW10), WIRE_Y(5), PIP_X(id_W111) - 1., WIRE_Y(5)}, - {PIP_X(id_W111) - 1., WIRE_Y(5), PIP_X(id_W111) - 1., WIRE_Y(0)}}}, - {id_EW10_loop_e, - {{PIP_X(id_EW10), WIRE_Y(0), PIP_X(id_EW10), WIRE_Y(6)}, - {PIP_X(id_EW10), WIRE_Y(6), wrap_len + 1., WIRE_Y(6)}, - {wrap_len + 1., WIRE_Y(6), wrap_len + 1., WIRE_Y(5)}, - {wrap_len + 1., WIRE_Y(5), PIP_X(id_W111), WIRE_Y(5)}, - {PIP_X(id_W111), WIRE_Y(5), PIP_X(id_W111), WIRE_Y(0)}, - {PIP_X(id_EW10), WIRE_Y(5), PIP_X(id_W111) - 1., WIRE_Y(5)}, - {PIP_X(id_W111) - 1., WIRE_Y(5), PIP_X(id_W111) - 1., WIRE_Y(0)}}}, - {id_EW10_loop_w, - {{PIP_X(id_EW10), WIRE_Y(0), PIP_X(id_EW10), WIRE_Y(6)}, - {PIP_X(id_EW10), WIRE_Y(6), PIP_X(id_E111) + 1., WIRE_Y(6)}, - {PIP_X(id_E111) + 1., WIRE_Y(6), PIP_X(id_E111) + 1., WIRE_Y(0)}, - {PIP_X(id_EW10), WIRE_Y(5), -wrap_len, WIRE_Y(5)}, - {-wrap_len, WIRE_Y(5), -wrap_len, WIRE_Y(6)}, - {-wrap_len, WIRE_Y(6), PIP_X(id_E111), WIRE_Y(6)}, - {PIP_X(id_E111), WIRE_Y(6), PIP_X(id_E111), WIRE_Y(0)}}}, - {id_EW20, - {{PIP_X(id_EW20), WIRE_Y(0), PIP_X(id_EW20), WIRE_Y(8)}, - {PIP_X(id_EW20), WIRE_Y(8), PIP_X(id_E121) + 1., WIRE_Y(8)}, - {PIP_X(id_E121) + 1., WIRE_Y(8), PIP_X(id_E121) + 1., WIRE_Y(0)}, - {PIP_X(id_EW20), WIRE_Y(7), PIP_X(id_W121) - 1., WIRE_Y(7)}, - {PIP_X(id_W121) - 1., WIRE_Y(7), PIP_X(id_W121) - 1., WIRE_Y(0)}}}, - {id_EW20_loop_e, - {{PIP_X(id_EW20), WIRE_Y(0), PIP_X(id_EW20), WIRE_Y(8)}, - {PIP_X(id_EW20), WIRE_Y(8), wrap_len + 1., WIRE_Y(8)}, - {wrap_len + 1., WIRE_Y(8), wrap_len + 1., WIRE_Y(7)}, - {wrap_len + 1., WIRE_Y(7), PIP_X(id_W121), WIRE_Y(7)}, - {PIP_X(id_W121), WIRE_Y(7), PIP_X(id_W121), WIRE_Y(0)}, - {PIP_X(id_EW20), WIRE_Y(7), PIP_X(id_W121) - 1., WIRE_Y(7)}, - {PIP_X(id_W121) - 1., WIRE_Y(7), PIP_X(id_W121) - 1., WIRE_Y(0)}}}, - {id_EW20_loop_w, - {{PIP_X(id_EW20), WIRE_Y(0), PIP_X(id_EW20), WIRE_Y(8)}, - {PIP_X(id_EW20), WIRE_Y(8), PIP_X(id_E121) + 1., WIRE_Y(8)}, - {PIP_X(id_E121) + 1., WIRE_Y(8), PIP_X(id_E121) + 1., WIRE_Y(0)}, - {PIP_X(id_EW20), WIRE_Y(7), -wrap_len, WIRE_Y(7)}, - {-wrap_len, WIRE_Y(7), -wrap_len, WIRE_Y(8)}, - {-wrap_len, WIRE_Y(8), PIP_X(id_E121), WIRE_Y(8)}, - {PIP_X(id_E121), WIRE_Y(8), PIP_X(id_E121), WIRE_Y(0)}}}, -// 2 hop -#define HOP2Y(offset) WIRE_Y(offset + 9) - {id_E20, - {{PIP_X(id_E200), WIRE_Y(0), PIP_X(id_E200), HOP2Y(2)}, - {PIP_X(id_E200), HOP2Y(2), PIP_X(id_E201) + 1., HOP2Y(2)}, - {PIP_X(id_E201) + 1., HOP2Y(2), PIP_X(id_E201) + 1., WIRE_Y(0)}, - {PIP_X(id_E201) + 1., HOP2Y(0), PIP_X(id_E202) + 2., HOP2Y(0)}, - {PIP_X(id_E202) + 2., HOP2Y(0), PIP_X(id_E202) + 2., WIRE_Y(0)}}}, - {id_W20, - {{PIP_X(id_W200), WIRE_Y(0), PIP_X(id_W200), HOP2Y(3)}, - {PIP_X(id_W200), HOP2Y(3), PIP_X(id_W201) - 1., HOP2Y(3)}, - {PIP_X(id_W201) - 1., HOP2Y(3), PIP_X(id_W201) - 1., WIRE_Y(0)}, - {PIP_X(id_W201) - 1., HOP2Y(1), PIP_X(id_W202) - 2., HOP2Y(1)}, - {PIP_X(id_W202) - 2., HOP2Y(1), PIP_X(id_W202) - 2., WIRE_Y(0)}}}, - {id_E20_loop0, - {{PIP_X(id_E200), WIRE_Y(0), PIP_X(id_E200), HOP2Y(2)}, - {PIP_X(id_E200), HOP2Y(2), wrap_len + 1., HOP2Y(2)}, - {wrap_len + 1., HOP2Y(2), wrap_len + 1., HOP2Y(3)}, - {wrap_len + 1., HOP2Y(3), PIP_X(id_W201), HOP2Y(3)}, - {PIP_X(id_W201), HOP2Y(3), PIP_X(id_W201), WIRE_Y(0)}, - {PIP_X(id_W201), HOP2Y(1), PIP_X(id_W202) - 1., HOP2Y(1)}, - {PIP_X(id_W202) - 1., HOP2Y(1), PIP_X(id_W202) - 1., WIRE_Y(0)}}}, - {id_W20_loop0, - {{PIP_X(id_W200), WIRE_Y(0), PIP_X(id_W200), HOP2Y(3)}, - {PIP_X(id_W200), HOP2Y(3), -wrap_len, HOP2Y(3)}, - {-wrap_len, HOP2Y(3), -wrap_len, HOP2Y(2)}, - {-wrap_len, HOP2Y(2), PIP_X(id_E201), HOP2Y(2)}, - {PIP_X(id_E201), HOP2Y(2), PIP_X(id_E201), WIRE_Y(0)}, - {PIP_X(id_E201), HOP2Y(0), PIP_X(id_E202) + 1., HOP2Y(0)}, - {PIP_X(id_E202) + 1., HOP2Y(0), PIP_X(id_E202) + 1., WIRE_Y(0)}}}, - {id_E20_loop1, - {{PIP_X(id_E200), WIRE_Y(0), PIP_X(id_E200), HOP2Y(2)}, - {PIP_X(id_E200), HOP2Y(2), PIP_X(id_E201) + 1., HOP2Y(2)}, - {PIP_X(id_E201) + 1., HOP2Y(2), PIP_X(id_E201) + 1., WIRE_Y(0)}, - {PIP_X(id_E201) + 1., HOP2Y(0), wrap_len + 2., HOP2Y(0)}, - {wrap_len + 2., HOP2Y(0), wrap_len + 2., HOP2Y(1)}, - {wrap_len + 2., HOP2Y(1), PIP_X(id_W202) + 1., HOP2Y(1)}, - {PIP_X(id_W202) + 1., HOP2Y(1), PIP_X(id_W202) + 1., WIRE_Y(0)}}}, - {id_W20_loop1, - {{PIP_X(id_W200), WIRE_Y(0), PIP_X(id_W200), HOP2Y(3)}, - {PIP_X(id_W200), HOP2Y(3), PIP_X(id_W201) - 1., HOP2Y(3)}, - {PIP_X(id_W201) - 1., HOP2Y(3), PIP_X(id_W201) - 1., WIRE_Y(0)}, - {PIP_X(id_W201) - 1., HOP2Y(1), -wrap_len - 1., HOP2Y(1)}, - {-wrap_len - 1., HOP2Y(1), -wrap_len - 1., HOP2Y(0)}, - {-wrap_len - 1., HOP2Y(0), PIP_X(id_E202) - 1., HOP2Y(0)}, - {PIP_X(id_E202) - 1., HOP2Y(0), PIP_X(id_E202) - 1., WIRE_Y(0)}}}, - -#undef HOP2Y -#define HOP2Y(offset) WIRE_Y(offset + 9 + 4 * 1) - {id_E21, - {{PIP_X(id_E210), WIRE_Y(0), PIP_X(id_E210), HOP2Y(2)}, - {PIP_X(id_E210), HOP2Y(2), PIP_X(id_E211) + 1., HOP2Y(2)}, - {PIP_X(id_E211) + 1., HOP2Y(2), PIP_X(id_E211) + 1., WIRE_Y(0)}, - {PIP_X(id_E211) + 1., HOP2Y(0), PIP_X(id_E212) + 2., HOP2Y(0)}, - {PIP_X(id_E212) + 2., HOP2Y(0), PIP_X(id_E212) + 2., WIRE_Y(0)}}}, - {id_W21, - {{PIP_X(id_W210), WIRE_Y(0), PIP_X(id_W210), HOP2Y(3)}, - {PIP_X(id_W210), HOP2Y(3), PIP_X(id_W211) - 1., HOP2Y(3)}, - {PIP_X(id_W211) - 1., HOP2Y(3), PIP_X(id_W211) - 1., WIRE_Y(0)}, - {PIP_X(id_W211) - 1., HOP2Y(1), PIP_X(id_W212) - 2., HOP2Y(1)}, - {PIP_X(id_W212) - 2., HOP2Y(1), PIP_X(id_W212) - 2., WIRE_Y(0)}}}, - {id_E21_loop0, - {{PIP_X(id_E210), WIRE_Y(0), PIP_X(id_E210), HOP2Y(2)}, - {PIP_X(id_E210), HOP2Y(2), wrap_len + 1., HOP2Y(2)}, - {wrap_len + 1., HOP2Y(2), wrap_len + 1., HOP2Y(3)}, - {wrap_len + 1., HOP2Y(3), PIP_X(id_W211), HOP2Y(3)}, - {PIP_X(id_W211), HOP2Y(3), PIP_X(id_W211), WIRE_Y(0)}, - {PIP_X(id_W211), HOP2Y(1), PIP_X(id_W212) - 1., HOP2Y(1)}, - {PIP_X(id_W212) - 1., HOP2Y(1), PIP_X(id_W212) - 1., WIRE_Y(0)}}}, - {id_W21_loop0, - {{PIP_X(id_W210), WIRE_Y(0), PIP_X(id_W210), HOP2Y(3)}, - {PIP_X(id_W210), HOP2Y(3), -wrap_len, HOP2Y(3)}, - {-wrap_len, HOP2Y(3), -wrap_len, HOP2Y(2)}, - {-wrap_len, HOP2Y(2), PIP_X(id_E211), HOP2Y(2)}, - {PIP_X(id_E211), HOP2Y(2), PIP_X(id_E211), WIRE_Y(0)}, - {PIP_X(id_E211), HOP2Y(0), PIP_X(id_E212) + 1., HOP2Y(0)}, - {PIP_X(id_E212) + 1., HOP2Y(0), PIP_X(id_E212) + 1., WIRE_Y(0)}}}, - {id_E21_loop1, - {{PIP_X(id_E210), WIRE_Y(0), PIP_X(id_E210), HOP2Y(2)}, - {PIP_X(id_E210), HOP2Y(2), PIP_X(id_E211) + 1., HOP2Y(2)}, - {PIP_X(id_E211) + 1., HOP2Y(2), PIP_X(id_E211) + 1., WIRE_Y(0)}, - {PIP_X(id_E211) + 1., HOP2Y(0), wrap_len + 2., HOP2Y(0)}, - {wrap_len + 2., HOP2Y(0), wrap_len + 2., HOP2Y(1)}, - {wrap_len + 2., HOP2Y(1), PIP_X(id_W212) + 1., HOP2Y(1)}, - {PIP_X(id_W212) + 1., HOP2Y(1), PIP_X(id_W212) + 1., WIRE_Y(0)}}}, - {id_W21_loop1, - {{PIP_X(id_W210), WIRE_Y(0), PIP_X(id_W210), HOP2Y(3)}, - {PIP_X(id_W210), HOP2Y(3), PIP_X(id_W211) - 1., HOP2Y(3)}, - {PIP_X(id_W211) - 1., HOP2Y(3), PIP_X(id_W211) - 1., WIRE_Y(0)}, - {PIP_X(id_W211) - 1., HOP2Y(1), -wrap_len - 1., HOP2Y(1)}, - {-wrap_len - 1., HOP2Y(1), -wrap_len - 1., HOP2Y(0)}, - {-wrap_len - 1., HOP2Y(0), PIP_X(id_E212) - 1., HOP2Y(0)}, - {PIP_X(id_E212) - 1., HOP2Y(0), PIP_X(id_E212) - 1., WIRE_Y(0)}}}, - -#undef HOP2Y -#define HOP2Y(offset) WIRE_Y(offset + 9 + 4 * 2) - {id_E22, - {{PIP_X(id_E220), WIRE_Y(0), PIP_X(id_E220), HOP2Y(2)}, - {PIP_X(id_E220), HOP2Y(2), PIP_X(id_E221) + 1., HOP2Y(2)}, - {PIP_X(id_E221) + 1., HOP2Y(2), PIP_X(id_E221) + 1., WIRE_Y(0)}, - {PIP_X(id_E221) + 1., HOP2Y(0), PIP_X(id_E222) + 2., HOP2Y(0)}, - {PIP_X(id_E222) + 2., HOP2Y(0), PIP_X(id_E222) + 2., WIRE_Y(0)}}}, - {id_W22, - {{PIP_X(id_W220), WIRE_Y(0), PIP_X(id_W220), HOP2Y(3)}, - {PIP_X(id_W220), HOP2Y(3), PIP_X(id_W221) - 1., HOP2Y(3)}, - {PIP_X(id_W221) - 1., HOP2Y(3), PIP_X(id_W221) - 1., WIRE_Y(0)}, - {PIP_X(id_W221) - 1., HOP2Y(1), PIP_X(id_W222) - 2., HOP2Y(1)}, - {PIP_X(id_W222) - 2., HOP2Y(1), PIP_X(id_W222) - 2., WIRE_Y(0)}}}, - {id_E22_loop0, - {{PIP_X(id_E220), WIRE_Y(0), PIP_X(id_E220), HOP2Y(2)}, - {PIP_X(id_E220), HOP2Y(2), wrap_len + 1., HOP2Y(2)}, - {wrap_len + 1., HOP2Y(2), wrap_len + 1., HOP2Y(3)}, - {wrap_len + 1., HOP2Y(3), PIP_X(id_W221), HOP2Y(3)}, - {PIP_X(id_W221), HOP2Y(3), PIP_X(id_W221), WIRE_Y(0)}, - {PIP_X(id_W221), HOP2Y(1), PIP_X(id_W222) - 1., HOP2Y(1)}, - {PIP_X(id_W222) - 1., HOP2Y(1), PIP_X(id_W222) - 1., WIRE_Y(0)}}}, - {id_W22_loop0, - {{PIP_X(id_W220), WIRE_Y(0), PIP_X(id_W220), HOP2Y(3)}, - {PIP_X(id_W220), HOP2Y(3), -wrap_len, HOP2Y(3)}, - {-wrap_len, HOP2Y(3), -wrap_len, HOP2Y(2)}, - {-wrap_len, HOP2Y(2), PIP_X(id_E221), HOP2Y(2)}, - {PIP_X(id_E221), HOP2Y(2), PIP_X(id_E221), WIRE_Y(0)}, - {PIP_X(id_E221), HOP2Y(0), PIP_X(id_E222) + 1., HOP2Y(0)}, - {PIP_X(id_E222) + 1., HOP2Y(0), PIP_X(id_E222) + 1., WIRE_Y(0)}}}, - {id_E22_loop1, - {{PIP_X(id_E220), WIRE_Y(0), PIP_X(id_E220), HOP2Y(2)}, - {PIP_X(id_E220), HOP2Y(2), PIP_X(id_E221) + 1., HOP2Y(2)}, - {PIP_X(id_E221) + 1., HOP2Y(2), PIP_X(id_E221) + 1., WIRE_Y(0)}, - {PIP_X(id_E221) + 1., HOP2Y(0), wrap_len + 2., HOP2Y(0)}, - {wrap_len + 2., HOP2Y(0), wrap_len + 2., HOP2Y(1)}, - {wrap_len + 2., HOP2Y(1), PIP_X(id_W222) + 1., HOP2Y(1)}, - {PIP_X(id_W222) + 1., HOP2Y(1), PIP_X(id_W222) + 1., WIRE_Y(0)}}}, - {id_W22_loop1, - {{PIP_X(id_W220), WIRE_Y(0), PIP_X(id_W220), HOP2Y(3)}, - {PIP_X(id_W220), HOP2Y(3), PIP_X(id_W221) - 1., HOP2Y(3)}, - {PIP_X(id_W221) - 1., HOP2Y(3), PIP_X(id_W221) - 1., WIRE_Y(0)}, - {PIP_X(id_W221) - 1., HOP2Y(1), -wrap_len - 1., HOP2Y(1)}, - {-wrap_len - 1., HOP2Y(1), -wrap_len - 1., HOP2Y(0)}, - {-wrap_len - 1., HOP2Y(0), PIP_X(id_E222) - 1., HOP2Y(0)}, - {PIP_X(id_E222) - 1., HOP2Y(0), PIP_X(id_E222) - 1., WIRE_Y(0)}}}, - -#undef HOP2Y -#define HOP2Y(offset) WIRE_Y(offset + 9 + 4 * 3) - {id_E23, - {{PIP_X(id_E230), WIRE_Y(0), PIP_X(id_E230), HOP2Y(2)}, - {PIP_X(id_E230), HOP2Y(2), PIP_X(id_E231) + 1., HOP2Y(2)}, - {PIP_X(id_E231) + 1., HOP2Y(2), PIP_X(id_E231) + 1., WIRE_Y(0)}, - {PIP_X(id_E231) + 1., HOP2Y(0), PIP_X(id_E232) + 2., HOP2Y(0)}, - {PIP_X(id_E232) + 2., HOP2Y(0), PIP_X(id_E232) + 2., WIRE_Y(0)}}}, - {id_W23, - {{PIP_X(id_W230), WIRE_Y(0), PIP_X(id_W230), HOP2Y(3)}, - {PIP_X(id_W230), HOP2Y(3), PIP_X(id_W231) - 1., HOP2Y(3)}, - {PIP_X(id_W231) - 1., HOP2Y(3), PIP_X(id_W231) - 1., WIRE_Y(0)}, - {PIP_X(id_W231) - 1., HOP2Y(1), PIP_X(id_W232) - 2., HOP2Y(1)}, - {PIP_X(id_W232) - 2., HOP2Y(1), PIP_X(id_W232) - 2., WIRE_Y(0)}}}, - {id_E23_loop0, - {{PIP_X(id_E230), WIRE_Y(0), PIP_X(id_E230), HOP2Y(2)}, - {PIP_X(id_E230), HOP2Y(2), wrap_len + 1., HOP2Y(2)}, - {wrap_len + 1., HOP2Y(2), wrap_len + 1., HOP2Y(3)}, - {wrap_len + 1., HOP2Y(3), PIP_X(id_W231), HOP2Y(3)}, - {PIP_X(id_W231), HOP2Y(3), PIP_X(id_W231), WIRE_Y(0)}, - {PIP_X(id_W231), HOP2Y(1), PIP_X(id_W232) - 1., HOP2Y(1)}, - {PIP_X(id_W232) - 1., HOP2Y(1), PIP_X(id_W232) - 1., WIRE_Y(0)}}}, - {id_W23_loop0, - {{PIP_X(id_W230), WIRE_Y(0), PIP_X(id_W230), HOP2Y(3)}, - {PIP_X(id_W230), HOP2Y(3), -wrap_len, HOP2Y(3)}, - {-wrap_len, HOP2Y(3), -wrap_len, HOP2Y(2)}, - {-wrap_len, HOP2Y(2), PIP_X(id_E231), HOP2Y(2)}, - {PIP_X(id_E231), HOP2Y(2), PIP_X(id_E231), WIRE_Y(0)}, - {PIP_X(id_E231), HOP2Y(0), PIP_X(id_E232) + 1., HOP2Y(0)}, - {PIP_X(id_E232) + 1., HOP2Y(0), PIP_X(id_E232) + 1., WIRE_Y(0)}}}, - {id_E23_loop1, - {{PIP_X(id_E230), WIRE_Y(0), PIP_X(id_E230), HOP2Y(2)}, - {PIP_X(id_E230), HOP2Y(2), PIP_X(id_E231) + 1., HOP2Y(2)}, - {PIP_X(id_E231) + 1., HOP2Y(2), PIP_X(id_E231) + 1., WIRE_Y(0)}, - {PIP_X(id_E231) + 1., HOP2Y(0), wrap_len + 2., HOP2Y(0)}, - {wrap_len + 2., HOP2Y(0), wrap_len + 2., HOP2Y(1)}, - {wrap_len + 2., HOP2Y(1), PIP_X(id_W232) + 1., HOP2Y(1)}, - {PIP_X(id_W232) + 1., HOP2Y(1), PIP_X(id_W232) + 1., WIRE_Y(0)}}}, - {id_W23_loop1, - {{PIP_X(id_W230), WIRE_Y(0), PIP_X(id_W230), HOP2Y(3)}, - {PIP_X(id_W230), HOP2Y(3), PIP_X(id_W231) - 1., HOP2Y(3)}, - {PIP_X(id_W231) - 1., HOP2Y(3), PIP_X(id_W231) - 1., WIRE_Y(0)}, - {PIP_X(id_W231) - 1., HOP2Y(1), -wrap_len - 1., HOP2Y(1)}, - {-wrap_len - 1., HOP2Y(1), -wrap_len - 1., HOP2Y(0)}, - {-wrap_len - 1., HOP2Y(0), PIP_X(id_E232) - 1., HOP2Y(0)}, - {PIP_X(id_E232) - 1., HOP2Y(0), PIP_X(id_E232) - 1., WIRE_Y(0)}}}, - -#undef HOP2Y -#define HOP2Y(offset) WIRE_Y(offset + 9 + 4 * 4) - {id_E24, - {{PIP_X(id_E240), WIRE_Y(0), PIP_X(id_E240), HOP2Y(2)}, - {PIP_X(id_E240), HOP2Y(2), PIP_X(id_E241) + 1., HOP2Y(2)}, - {PIP_X(id_E241) + 1., HOP2Y(2), PIP_X(id_E241) + 1., WIRE_Y(0)}, - {PIP_X(id_E241) + 1., HOP2Y(0), PIP_X(id_E242) + 2., HOP2Y(0)}, - {PIP_X(id_E242) + 2., HOP2Y(0), PIP_X(id_E242) + 2., WIRE_Y(0)}}}, - {id_W24, - {{PIP_X(id_W240), WIRE_Y(0), PIP_X(id_W240), HOP2Y(3)}, - {PIP_X(id_W240), HOP2Y(3), PIP_X(id_W241) - 1., HOP2Y(3)}, - {PIP_X(id_W241) - 1., HOP2Y(3), PIP_X(id_W241) - 1., WIRE_Y(0)}, - {PIP_X(id_W241) - 1., HOP2Y(1), PIP_X(id_W242) - 2., HOP2Y(1)}, - {PIP_X(id_W242) - 2., HOP2Y(1), PIP_X(id_W242) - 2., WIRE_Y(0)}}}, - {id_E24_loop0, - {{PIP_X(id_E240), WIRE_Y(0), PIP_X(id_E240), HOP2Y(2)}, - {PIP_X(id_E240), HOP2Y(2), wrap_len + 1., HOP2Y(2)}, - {wrap_len + 1., HOP2Y(2), wrap_len + 1., HOP2Y(3)}, - {wrap_len + 1., HOP2Y(3), PIP_X(id_W241), HOP2Y(3)}, - {PIP_X(id_W241), HOP2Y(3), PIP_X(id_W241), WIRE_Y(0)}, - {PIP_X(id_W241), HOP2Y(1), PIP_X(id_W242) - 1., HOP2Y(1)}, - {PIP_X(id_W242) - 1., HOP2Y(1), PIP_X(id_W242) - 1., WIRE_Y(0)}}}, - {id_W24_loop0, - {{PIP_X(id_W240), WIRE_Y(0), PIP_X(id_W240), HOP2Y(3)}, - {PIP_X(id_W240), HOP2Y(3), -wrap_len, HOP2Y(3)}, - {-wrap_len, HOP2Y(3), -wrap_len, HOP2Y(2)}, - {-wrap_len, HOP2Y(2), PIP_X(id_E241), HOP2Y(2)}, - {PIP_X(id_E241), HOP2Y(2), PIP_X(id_E241), WIRE_Y(0)}, - {PIP_X(id_E241), HOP2Y(0), PIP_X(id_E242) + 1., HOP2Y(0)}, - {PIP_X(id_E242) + 1., HOP2Y(0), PIP_X(id_E242) + 1., WIRE_Y(0)}}}, - {id_E24_loop1, - {{PIP_X(id_E240), WIRE_Y(0), PIP_X(id_E240), HOP2Y(2)}, - {PIP_X(id_E240), HOP2Y(2), PIP_X(id_E241) + 1., HOP2Y(2)}, - {PIP_X(id_E241) + 1., HOP2Y(2), PIP_X(id_E241) + 1., WIRE_Y(0)}, - {PIP_X(id_E241) + 1., HOP2Y(0), wrap_len + 2., HOP2Y(0)}, - {wrap_len + 2., HOP2Y(0), wrap_len + 2., HOP2Y(1)}, - {wrap_len + 2., HOP2Y(1), PIP_X(id_W242) + 1., HOP2Y(1)}, - {PIP_X(id_W242) + 1., HOP2Y(1), PIP_X(id_W242) + 1., WIRE_Y(0)}}}, - {id_W24_loop1, - {{PIP_X(id_W240), WIRE_Y(0), PIP_X(id_W240), HOP2Y(3)}, - {PIP_X(id_W240), HOP2Y(3), PIP_X(id_W241) - 1., HOP2Y(3)}, - {PIP_X(id_W241) - 1., HOP2Y(3), PIP_X(id_W241) - 1., WIRE_Y(0)}, - {PIP_X(id_W241) - 1., HOP2Y(1), -wrap_len - 1., HOP2Y(1)}, - {-wrap_len - 1., HOP2Y(1), -wrap_len - 1., HOP2Y(0)}, - {-wrap_len - 1., HOP2Y(0), PIP_X(id_E242) - 1., HOP2Y(0)}, - {PIP_X(id_E242) - 1., HOP2Y(0), PIP_X(id_E242) - 1., WIRE_Y(0)}}}, - -#undef HOP2Y -#define HOP2Y(offset) WIRE_Y(offset + 9 + 4 * 5) - {id_E25, - {{PIP_X(id_E250), WIRE_Y(0), PIP_X(id_E250), HOP2Y(2)}, - {PIP_X(id_E250), HOP2Y(2), PIP_X(id_E251) + 1., HOP2Y(2)}, - {PIP_X(id_E251) + 1., HOP2Y(2), PIP_X(id_E251) + 1., WIRE_Y(0)}, - {PIP_X(id_E251) + 1., HOP2Y(0), PIP_X(id_E252) + 2., HOP2Y(0)}, - {PIP_X(id_E252) + 2., HOP2Y(0), PIP_X(id_E252) + 2., WIRE_Y(0)}}}, - {id_W25, - {{PIP_X(id_W250), WIRE_Y(0), PIP_X(id_W250), HOP2Y(3)}, - {PIP_X(id_W250), HOP2Y(3), PIP_X(id_W251) - 1., HOP2Y(3)}, - {PIP_X(id_W251) - 1., HOP2Y(3), PIP_X(id_W251) - 1., WIRE_Y(0)}, - {PIP_X(id_W251) - 1., HOP2Y(1), PIP_X(id_W252) - 2., HOP2Y(1)}, - {PIP_X(id_W252) - 2., HOP2Y(1), PIP_X(id_W252) - 2., WIRE_Y(0)}}}, - {id_E25_loop0, - {{PIP_X(id_E250), WIRE_Y(0), PIP_X(id_E250), HOP2Y(2)}, - {PIP_X(id_E250), HOP2Y(2), wrap_len + 1., HOP2Y(2)}, - {wrap_len + 1., HOP2Y(2), wrap_len + 1., HOP2Y(3)}, - {wrap_len + 1., HOP2Y(3), PIP_X(id_W251), HOP2Y(3)}, - {PIP_X(id_W251), HOP2Y(3), PIP_X(id_W251), WIRE_Y(0)}, - {PIP_X(id_W251), HOP2Y(1), PIP_X(id_W252) - 1., HOP2Y(1)}, - {PIP_X(id_W252) - 1., HOP2Y(1), PIP_X(id_W252) - 1., WIRE_Y(0)}}}, - {id_W25_loop0, - {{PIP_X(id_W250), WIRE_Y(0), PIP_X(id_W250), HOP2Y(3)}, - {PIP_X(id_W250), HOP2Y(3), -wrap_len, HOP2Y(3)}, - {-wrap_len, HOP2Y(3), -wrap_len, HOP2Y(2)}, - {-wrap_len, HOP2Y(2), PIP_X(id_E251), HOP2Y(2)}, - {PIP_X(id_E251), HOP2Y(2), PIP_X(id_E251), WIRE_Y(0)}, - {PIP_X(id_E251), HOP2Y(0), PIP_X(id_E252) + 1., HOP2Y(0)}, - {PIP_X(id_E252) + 1., HOP2Y(0), PIP_X(id_E252) + 1., WIRE_Y(0)}}}, - {id_E25_loop1, - {{PIP_X(id_E250), WIRE_Y(0), PIP_X(id_E250), HOP2Y(2)}, - {PIP_X(id_E250), HOP2Y(2), PIP_X(id_E251) + 1., HOP2Y(2)}, - {PIP_X(id_E251) + 1., HOP2Y(2), PIP_X(id_E251) + 1., WIRE_Y(0)}, - {PIP_X(id_E251) + 1., HOP2Y(0), wrap_len + 2., HOP2Y(0)}, - {wrap_len + 2., HOP2Y(0), wrap_len + 2., HOP2Y(1)}, - {wrap_len + 2., HOP2Y(1), PIP_X(id_W252) + 1., HOP2Y(1)}, - {PIP_X(id_W252) + 1., HOP2Y(1), PIP_X(id_W252) + 1., WIRE_Y(0)}}}, - {id_W25_loop1, - {{PIP_X(id_W250), WIRE_Y(0), PIP_X(id_W250), HOP2Y(3)}, - {PIP_X(id_W250), HOP2Y(3), PIP_X(id_W251) - 1., HOP2Y(3)}, - {PIP_X(id_W251) - 1., HOP2Y(3), PIP_X(id_W251) - 1., WIRE_Y(0)}, - {PIP_X(id_W251) - 1., HOP2Y(1), -wrap_len - 1., HOP2Y(1)}, - {-wrap_len - 1., HOP2Y(1), -wrap_len - 1., HOP2Y(0)}, - {-wrap_len - 1., HOP2Y(0), PIP_X(id_E252) - 1., HOP2Y(0)}, - {PIP_X(id_E252) - 1., HOP2Y(0), PIP_X(id_E252) - 1., WIRE_Y(0)}}}, - -#undef HOP2Y -#define HOP2Y(offset) WIRE_Y(offset + 9 + 4 * 6) - {id_E26, - {{PIP_X(id_E260), WIRE_Y(0), PIP_X(id_E260), HOP2Y(2)}, - {PIP_X(id_E260), HOP2Y(2), PIP_X(id_E261) + 1., HOP2Y(2)}, - {PIP_X(id_E261) + 1., HOP2Y(2), PIP_X(id_E261) + 1., WIRE_Y(0)}, - {PIP_X(id_E261) + 1., HOP2Y(0), PIP_X(id_E262) + 2., HOP2Y(0)}, - {PIP_X(id_E262) + 2., HOP2Y(0), PIP_X(id_E262) + 2., WIRE_Y(0)}}}, - {id_W26, - {{PIP_X(id_W260), WIRE_Y(0), PIP_X(id_W260), HOP2Y(3)}, - {PIP_X(id_W260), HOP2Y(3), PIP_X(id_W261) - 1., HOP2Y(3)}, - {PIP_X(id_W261) - 1., HOP2Y(3), PIP_X(id_W261) - 1., WIRE_Y(0)}, - {PIP_X(id_W261) - 1., HOP2Y(1), PIP_X(id_W262) - 2., HOP2Y(1)}, - {PIP_X(id_W262) - 2., HOP2Y(1), PIP_X(id_W262) - 2., WIRE_Y(0)}}}, - {id_E26_loop0, - {{PIP_X(id_E260), WIRE_Y(0), PIP_X(id_E260), HOP2Y(2)}, - {PIP_X(id_E260), HOP2Y(2), wrap_len + 1., HOP2Y(2)}, - {wrap_len + 1., HOP2Y(2), wrap_len + 1., HOP2Y(3)}, - {wrap_len + 1., HOP2Y(3), PIP_X(id_W261), HOP2Y(3)}, - {PIP_X(id_W261), HOP2Y(3), PIP_X(id_W261), WIRE_Y(0)}, - {PIP_X(id_W261), HOP2Y(1), PIP_X(id_W262) - 1., HOP2Y(1)}, - {PIP_X(id_W262) - 1., HOP2Y(1), PIP_X(id_W262) - 1., WIRE_Y(0)}}}, - {id_W26_loop0, - {{PIP_X(id_W260), WIRE_Y(0), PIP_X(id_W260), HOP2Y(3)}, - {PIP_X(id_W260), HOP2Y(3), -wrap_len, HOP2Y(3)}, - {-wrap_len, HOP2Y(3), -wrap_len, HOP2Y(2)}, - {-wrap_len, HOP2Y(2), PIP_X(id_E261), HOP2Y(2)}, - {PIP_X(id_E261), HOP2Y(2), PIP_X(id_E261), WIRE_Y(0)}, - {PIP_X(id_E261), HOP2Y(0), PIP_X(id_E262) + 1., HOP2Y(0)}, - {PIP_X(id_E262) + 1., HOP2Y(0), PIP_X(id_E262) + 1., WIRE_Y(0)}}}, - {id_E26_loop1, - {{PIP_X(id_E260), WIRE_Y(0), PIP_X(id_E260), HOP2Y(2)}, - {PIP_X(id_E260), HOP2Y(2), PIP_X(id_E261) + 1., HOP2Y(2)}, - {PIP_X(id_E261) + 1., HOP2Y(2), PIP_X(id_E261) + 1., WIRE_Y(0)}, - {PIP_X(id_E261) + 1., HOP2Y(0), wrap_len + 2., HOP2Y(0)}, - {wrap_len + 2., HOP2Y(0), wrap_len + 2., HOP2Y(1)}, - {wrap_len + 2., HOP2Y(1), PIP_X(id_W262) + 1., HOP2Y(1)}, - {PIP_X(id_W262) + 1., HOP2Y(1), PIP_X(id_W262) + 1., WIRE_Y(0)}}}, - {id_W26_loop1, - {{PIP_X(id_W260), WIRE_Y(0), PIP_X(id_W260), HOP2Y(3)}, - {PIP_X(id_W260), HOP2Y(3), PIP_X(id_W261) - 1., HOP2Y(3)}, - {PIP_X(id_W261) - 1., HOP2Y(3), PIP_X(id_W261) - 1., WIRE_Y(0)}, - {PIP_X(id_W261) - 1., HOP2Y(1), -wrap_len - 1., HOP2Y(1)}, - {-wrap_len - 1., HOP2Y(1), -wrap_len - 1., HOP2Y(0)}, - {-wrap_len - 1., HOP2Y(0), PIP_X(id_E262) - 1., HOP2Y(0)}, - {PIP_X(id_E262) - 1., HOP2Y(0), PIP_X(id_E262) - 1., WIRE_Y(0)}}}, - -#undef HOP2Y -#define HOP2Y(offset) WIRE_Y(offset + 9 + 4 * 7) - {id_E27, - {{PIP_X(id_E270), WIRE_Y(0), PIP_X(id_E270), HOP2Y(2)}, - {PIP_X(id_E270), HOP2Y(2), PIP_X(id_E271) + 1., HOP2Y(2)}, - {PIP_X(id_E271) + 1., HOP2Y(2), PIP_X(id_E271) + 1., WIRE_Y(0)}, - {PIP_X(id_E271) + 1., HOP2Y(0), PIP_X(id_E272) + 2., HOP2Y(0)}, - {PIP_X(id_E272) + 2., HOP2Y(0), PIP_X(id_E272) + 2., WIRE_Y(0)}}}, - {id_W27, - {{PIP_X(id_W270), WIRE_Y(0), PIP_X(id_W270), HOP2Y(3)}, - {PIP_X(id_W270), HOP2Y(3), PIP_X(id_W271) - 1., HOP2Y(3)}, - {PIP_X(id_W271) - 1., HOP2Y(3), PIP_X(id_W271) - 1., WIRE_Y(0)}, - {PIP_X(id_W271) - 1., HOP2Y(1), PIP_X(id_W272) - 2., HOP2Y(1)}, - {PIP_X(id_W272) - 2., HOP2Y(1), PIP_X(id_W272) - 2., WIRE_Y(0)}}}, - {id_E27_loop0, - {{PIP_X(id_E270), WIRE_Y(0), PIP_X(id_E270), HOP2Y(2)}, - {PIP_X(id_E270), HOP2Y(2), wrap_len + 1., HOP2Y(2)}, - {wrap_len + 1., HOP2Y(2), wrap_len + 1., HOP2Y(3)}, - {wrap_len + 1., HOP2Y(3), PIP_X(id_W271), HOP2Y(3)}, - {PIP_X(id_W271), HOP2Y(3), PIP_X(id_W271), WIRE_Y(0)}, - {PIP_X(id_W271), HOP2Y(1), PIP_X(id_W272) - 1., HOP2Y(1)}, - {PIP_X(id_W272) - 1., HOP2Y(1), PIP_X(id_W272) - 1., WIRE_Y(0)}}}, - {id_W27_loop0, - {{PIP_X(id_W270), WIRE_Y(0), PIP_X(id_W270), HOP2Y(3)}, - {PIP_X(id_W270), HOP2Y(3), -wrap_len, HOP2Y(3)}, - {-wrap_len, HOP2Y(3), -wrap_len, HOP2Y(2)}, - {-wrap_len, HOP2Y(2), PIP_X(id_E271), HOP2Y(2)}, - {PIP_X(id_E271), HOP2Y(2), PIP_X(id_E271), WIRE_Y(0)}, - {PIP_X(id_E271), HOP2Y(0), PIP_X(id_E272) + 1., HOP2Y(0)}, - {PIP_X(id_E272) + 1., HOP2Y(0), PIP_X(id_E272) + 1., WIRE_Y(0)}}}, - {id_E27_loop1, - {{PIP_X(id_E270), WIRE_Y(0), PIP_X(id_E270), HOP2Y(2)}, - {PIP_X(id_E270), HOP2Y(2), PIP_X(id_E271) + 1., HOP2Y(2)}, - {PIP_X(id_E271) + 1., HOP2Y(2), PIP_X(id_E271) + 1., WIRE_Y(0)}, - {PIP_X(id_E271) + 1., HOP2Y(0), wrap_len + 2., HOP2Y(0)}, - {wrap_len + 2., HOP2Y(0), wrap_len + 2., HOP2Y(1)}, - {wrap_len + 2., HOP2Y(1), PIP_X(id_W272) + 1., HOP2Y(1)}, - {PIP_X(id_W272) + 1., HOP2Y(1), PIP_X(id_W272) + 1., WIRE_Y(0)}}}, - {id_W27_loop1, - {{PIP_X(id_W270), WIRE_Y(0), PIP_X(id_W270), HOP2Y(3)}, - {PIP_X(id_W270), HOP2Y(3), PIP_X(id_W271) - 1., HOP2Y(3)}, - {PIP_X(id_W271) - 1., HOP2Y(3), PIP_X(id_W271) - 1., WIRE_Y(0)}, - {PIP_X(id_W271) - 1., HOP2Y(1), -wrap_len - 1., HOP2Y(1)}, - {-wrap_len - 1., HOP2Y(1), -wrap_len - 1., HOP2Y(0)}, - {-wrap_len - 1., HOP2Y(0), PIP_X(id_E272) - 1., HOP2Y(0)}, - {PIP_X(id_E272) - 1., HOP2Y(0), PIP_X(id_E272) - 1., WIRE_Y(0)}}}, - -// clock branches -#define CLK_GBO0_Y 41.f -#define CLK_GBO1_Y 46.f -// 4 hop -#define HOP4Y_START (CLK_GBO0_Y + 10.f) -#define HOP4Y(offset) WIRE_Y((float)offset + HOP4Y_START) - {id_E80, - {{PIP_X(id_E800), WIRE_Y(0), PIP_X(id_E800), HOP4Y(16)}, - {PIP_X(id_E800), HOP4Y(16), PIP_X(id_W808), HOP4Y(16)}, - {PIP_X(id_W808) + 0., HOP4Y(16), PIP_X(id_W808) + top_wire_dist + 0., HOP4Y(14)}, - {PIP_X(id_W808) + top_wire_dist + 0., HOP4Y(14), PIP_X(id_W808) + 1., HOP4Y(14)}, - {PIP_X(id_W808) + 1., HOP4Y(14), PIP_X(id_W808) + top_wire_dist + 1., HOP4Y(12)}, - {PIP_X(id_W808) + top_wire_dist + 1., HOP4Y(12), PIP_X(id_W808) + 2., HOP4Y(12)}, - {PIP_X(id_W808) + 2., HOP4Y(12), PIP_X(id_W808) + top_wire_dist + 2., HOP4Y(10)}, - {PIP_X(id_W808) + top_wire_dist + 2., HOP4Y(10), PIP_X(id_W808) + 3., HOP4Y(10)}, - {PIP_X(id_W808) + 3., HOP4Y(10), PIP_X(id_W808) + top_wire_dist + 3., HOP4Y(8)}, - {PIP_X(id_W808) + top_wire_dist + 3., HOP4Y(8), PIP_X(id_W808) + 4., HOP4Y(8)}, - {PIP_X(id_W808) + 4., HOP4Y(8), PIP_X(id_W808) + top_wire_dist + 4., HOP4Y(6)}, - {PIP_X(id_E804) + 4., HOP4Y(8), PIP_X(id_E804) + 4., WIRE_Y(0)}, - {PIP_X(id_W808) + top_wire_dist + 4., HOP4Y(6), PIP_X(id_W808) + 5., HOP4Y(6)}, - {PIP_X(id_W808) + 5., HOP4Y(6), PIP_X(id_W808) + top_wire_dist + 5., HOP4Y(4)}, - {PIP_X(id_W808) + top_wire_dist + 5., HOP4Y(4), PIP_X(id_W808) + 6., HOP4Y(4)}, - {PIP_X(id_W808) + 6., HOP4Y(4), PIP_X(id_W808) + top_wire_dist + 6., HOP4Y(2)}, - {PIP_X(id_W808) + top_wire_dist + 6., HOP4Y(2), PIP_X(id_W808) + 7., HOP4Y(2)}, - {PIP_X(id_W808) + 7., HOP4Y(2), PIP_X(id_W808) + top_wire_dist + 7., HOP4Y(0)}, - {PIP_X(id_W808) + top_wire_dist + 7., HOP4Y(0), PIP_X(id_E808) + 8., HOP4Y(0)}, - {PIP_X(id_E808) + 8, HOP4Y(0), PIP_X(id_E808) + 8., WIRE_Y(0)}}}, - {id_W80, - {{PIP_X(id_W800), WIRE_Y(0), PIP_X(id_W800), HOP4Y(17)}, - {PIP_X(id_W800) - 0., HOP4Y(17), PIP_X(id_W800) - top_wire_dist - 0., HOP4Y(15)}, - {PIP_X(id_W800) - top_wire_dist - 0., HOP4Y(15), PIP_X(id_W800) - 1., HOP4Y(15)}, - {PIP_X(id_W800) - 1., HOP4Y(15), PIP_X(id_W800) - top_wire_dist - 1., HOP4Y(13)}, - {PIP_X(id_W800) - top_wire_dist - 1., HOP4Y(13), PIP_X(id_W800) - 2., HOP4Y(13)}, - {PIP_X(id_W800) - 2., HOP4Y(13), PIP_X(id_W800) - top_wire_dist - 2., HOP4Y(11)}, - {PIP_X(id_W800) - top_wire_dist - 2., HOP4Y(11), PIP_X(id_W800) - 3., HOP4Y(11)}, - {PIP_X(id_W800) - 3., HOP4Y(11), PIP_X(id_W800) - top_wire_dist - 3., HOP4Y(9)}, - {PIP_X(id_W800) - top_wire_dist - 3., HOP4Y(9), PIP_X(id_W800) - 4., HOP4Y(9)}, - {PIP_X(id_W800) - 4., HOP4Y(9), PIP_X(id_W800) - top_wire_dist - 4., HOP4Y(7)}, - {PIP_X(id_W804) - 4., HOP4Y(9), PIP_X(id_W804) - 4., WIRE_Y(0)}, - {PIP_X(id_W800) - top_wire_dist - 4., HOP4Y(7), PIP_X(id_W800) - 5., HOP4Y(7)}, - {PIP_X(id_W800) - 5., HOP4Y(7), PIP_X(id_W800) - top_wire_dist - 5., HOP4Y(5)}, - {PIP_X(id_W800) - top_wire_dist - 5., HOP4Y(5), PIP_X(id_W800) - 6., HOP4Y(5)}, - {PIP_X(id_W800) - 6., HOP4Y(5), PIP_X(id_W800) - top_wire_dist - 6., HOP4Y(3)}, - {PIP_X(id_W800) - top_wire_dist - 6., HOP4Y(3), PIP_X(id_W800) - 7., HOP4Y(3)}, - {PIP_X(id_W800) - 7., HOP4Y(3), PIP_X(id_W800) - top_wire_dist - 7., HOP4Y(1)}, - {PIP_X(id_W800) - top_wire_dist - 7., HOP4Y(1), PIP_X(id_W808) - 8., HOP4Y(1)}, - {PIP_X(id_W808) - 8, HOP4Y(1), PIP_X(id_W808) - 8., WIRE_Y(0)}}}, - {id_E80_loop0, - {{PIP_X(id_E800), WIRE_Y(0), PIP_X(id_E800), HOP4Y(16)}, - {PIP_X(id_E800), HOP4Y(16), PIP_X(id_W808), HOP4Y(16)}, - {PIP_X(id_W808) + 0., HOP4Y(16), PIP_X(id_W808) + top_wire_dist + 0., HOP4Y(14)}, - {PIP_X(id_W808) + top_wire_dist + 0., HOP4Y(14), wrap_len + 1., HOP4Y(14)}, - {wrap_len + 1., HOP4Y(14), wrap_len + 1., HOP4Y(15)}, - {wrap_len + 1., HOP4Y(15), PIP_X(id_W800) - 0., HOP4Y(15)}, - {PIP_X(id_W800) - 0., HOP4Y(15), PIP_X(id_W800) - top_wire_dist - 0., HOP4Y(13)}, - {PIP_X(id_W800) - top_wire_dist - 0., HOP4Y(13), PIP_X(id_W800) - 1., HOP4Y(13)}, - {PIP_X(id_W800) - 1., HOP4Y(13), PIP_X(id_W800) - top_wire_dist - 1., HOP4Y(11)}, - {PIP_X(id_W800) - top_wire_dist - 1., HOP4Y(11), PIP_X(id_W800) - 2., HOP4Y(11)}, - {PIP_X(id_W800) - 2., HOP4Y(11), PIP_X(id_W800) - top_wire_dist - 2., HOP4Y(9)}, - {PIP_X(id_W800) - top_wire_dist - 2., HOP4Y(9), PIP_X(id_W800) - 3., HOP4Y(9)}, - {PIP_X(id_W800) - 3., HOP4Y(9), PIP_X(id_W800) - top_wire_dist - 3., HOP4Y(7)}, - {PIP_X(id_W804) - 3., HOP4Y(9), PIP_X(id_W804) - 3., WIRE_Y(0)}, - {PIP_X(id_W800) - top_wire_dist - 3., HOP4Y(7), PIP_X(id_W800) - 4., HOP4Y(7)}, - {PIP_X(id_W800) - 4., HOP4Y(7), PIP_X(id_W800) - top_wire_dist - 4., HOP4Y(5)}, - {PIP_X(id_W800) - top_wire_dist - 4., HOP4Y(5), PIP_X(id_W800) - 5., HOP4Y(5)}, - {PIP_X(id_W800) - 5., HOP4Y(5), PIP_X(id_W800) - top_wire_dist - 5., HOP4Y(3)}, - {PIP_X(id_W800) - top_wire_dist - 5., HOP4Y(3), PIP_X(id_W800) - 6., HOP4Y(3)}, - {PIP_X(id_W800) - 6., HOP4Y(3), PIP_X(id_W800) - top_wire_dist - 6., HOP4Y(1)}, - {PIP_X(id_W800) - top_wire_dist - 6., HOP4Y(1), PIP_X(id_W808) - 7., HOP4Y(1)}, - {PIP_X(id_W808) - 7, HOP4Y(1), PIP_X(id_W808) - 7., WIRE_Y(0)}}}, - {id_E80_loop1, - {{PIP_X(id_E800), WIRE_Y(0), PIP_X(id_E800), HOP4Y(16)}, - {PIP_X(id_E800), HOP4Y(16), PIP_X(id_W808), HOP4Y(16)}, - {PIP_X(id_W808) + 0., HOP4Y(16), PIP_X(id_W808) + top_wire_dist + 0., HOP4Y(14)}, - {PIP_X(id_W808) + top_wire_dist + 0., HOP4Y(14), PIP_X(id_W808) + 1., HOP4Y(14)}, - {PIP_X(id_W808) + 1., HOP4Y(14), PIP_X(id_W808) + top_wire_dist + 1., HOP4Y(12)}, - {PIP_X(id_W808) + top_wire_dist + 1., HOP4Y(12), wrap_len + 2., HOP4Y(12)}, - {wrap_len + 2., HOP4Y(12), wrap_len + 2., HOP4Y(13)}, - {wrap_len + 2., HOP4Y(13), PIP_X(id_W800) + 1., HOP4Y(13)}, - {PIP_X(id_W800) + 1., HOP4Y(13), PIP_X(id_W800) - top_wire_dist + 1., HOP4Y(11)}, - {PIP_X(id_W800) - top_wire_dist + 1., HOP4Y(11), PIP_X(id_W800) - 0., HOP4Y(11)}, - {PIP_X(id_W800) - 0., HOP4Y(11), PIP_X(id_W800) - top_wire_dist - 0., HOP4Y(9)}, - {PIP_X(id_W800) - top_wire_dist - 0., HOP4Y(9), PIP_X(id_W800) - 1., HOP4Y(9)}, - {PIP_X(id_W804) - 1., HOP4Y(9), PIP_X(id_W804) - 1., WIRE_Y(0)}, - {PIP_X(id_W800) - 1., HOP4Y(9), PIP_X(id_W800) - top_wire_dist - 1., HOP4Y(7)}, - {PIP_X(id_W800) - top_wire_dist - 1., HOP4Y(7), PIP_X(id_W800) - 2., HOP4Y(7)}, - {PIP_X(id_W800) - 2., HOP4Y(7), PIP_X(id_W800) - top_wire_dist - 2., HOP4Y(5)}, - {PIP_X(id_W800) - top_wire_dist - 2., HOP4Y(5), PIP_X(id_W800) - 3., HOP4Y(5)}, - {PIP_X(id_W800) - 3., HOP4Y(5), PIP_X(id_W800) - top_wire_dist - 3., HOP4Y(3)}, - {PIP_X(id_W800) - top_wire_dist - 3., HOP4Y(3), PIP_X(id_W800) - 4., HOP4Y(3)}, - {PIP_X(id_W800) - 4., HOP4Y(3), PIP_X(id_W800) - top_wire_dist - 4., HOP4Y(1)}, - {PIP_X(id_W800) - top_wire_dist - 4., HOP4Y(1), PIP_X(id_W808) - 5., HOP4Y(1)}, - {PIP_X(id_W808) - 5., HOP4Y(1), PIP_X(id_W808) - 5., WIRE_Y(0)}}}, - {id_E80_loop2, - {{PIP_X(id_E800), WIRE_Y(0), PIP_X(id_E800), HOP4Y(16)}, - {PIP_X(id_E800), HOP4Y(16), PIP_X(id_W808), HOP4Y(16)}, - {PIP_X(id_W808) + 0., HOP4Y(16), PIP_X(id_W808) + top_wire_dist + 0., HOP4Y(14)}, - {PIP_X(id_W808) + top_wire_dist + 0., HOP4Y(14), PIP_X(id_W808) + 1., HOP4Y(14)}, - {PIP_X(id_W808) + 1., HOP4Y(14), PIP_X(id_W808) + top_wire_dist + 1., HOP4Y(12)}, - {PIP_X(id_W808) + top_wire_dist + 1., HOP4Y(12), PIP_X(id_W808) + 2., HOP4Y(12)}, - {PIP_X(id_W808) + 2., HOP4Y(12), PIP_X(id_W808) + top_wire_dist + 2., HOP4Y(10)}, - {PIP_X(id_W808) + top_wire_dist + 2., HOP4Y(10), wrap_len + 3., HOP4Y(10)}, - {wrap_len + 3., HOP4Y(10), wrap_len + 3., HOP4Y(11)}, - {wrap_len + 3., HOP4Y(11), PIP_X(id_W800) + 2., HOP4Y(11)}, - {PIP_X(id_W800) + 2., HOP4Y(11), PIP_X(id_W800) - top_wire_dist + 2., HOP4Y(9)}, - {PIP_X(id_W800) - top_wire_dist + 2., HOP4Y(9), PIP_X(id_W800) + 1., HOP4Y(9)}, - {PIP_X(id_W804) + 1., HOP4Y(9), PIP_X(id_W804) + 1., WIRE_Y(0)}, - {PIP_X(id_W800) + 1., HOP4Y(9), PIP_X(id_W800) - top_wire_dist + 1., HOP4Y(7)}, - {PIP_X(id_W800) - top_wire_dist + 1., HOP4Y(7), PIP_X(id_W800) + 0., HOP4Y(7)}, - {PIP_X(id_W800) + 0., HOP4Y(7), PIP_X(id_W800) - top_wire_dist - 0., HOP4Y(5)}, - {PIP_X(id_W800) - top_wire_dist - 0., HOP4Y(5), PIP_X(id_W800) - 1., HOP4Y(5)}, - {PIP_X(id_W800) - 1., HOP4Y(5), PIP_X(id_W800) - top_wire_dist - 1., HOP4Y(3)}, - {PIP_X(id_W800) - top_wire_dist - 1., HOP4Y(3), PIP_X(id_W800) - 2., HOP4Y(3)}, - {PIP_X(id_W800) - 2., HOP4Y(3), PIP_X(id_W800) - top_wire_dist - 2., HOP4Y(1)}, - {PIP_X(id_W800) - top_wire_dist - 2., HOP4Y(1), PIP_X(id_W808) - 3., HOP4Y(1)}, - {PIP_X(id_W808) - 3., HOP4Y(1), PIP_X(id_W808) - 3., WIRE_Y(0)}}}, - {id_E80_loop3, - {{PIP_X(id_E800), WIRE_Y(0), PIP_X(id_E800), HOP4Y(16)}, - {PIP_X(id_E800), HOP4Y(16), PIP_X(id_W808), HOP4Y(16)}, - {PIP_X(id_W808) + 0., HOP4Y(16), PIP_X(id_W808) + top_wire_dist + 0., HOP4Y(14)}, - {PIP_X(id_W808) + top_wire_dist + 0., HOP4Y(14), PIP_X(id_W808) + 1., HOP4Y(14)}, - {PIP_X(id_W808) + 1., HOP4Y(14), PIP_X(id_W808) + top_wire_dist + 1., HOP4Y(12)}, - {PIP_X(id_W808) + top_wire_dist + 1., HOP4Y(12), PIP_X(id_W808) + 2., HOP4Y(12)}, - {PIP_X(id_W808) + 2., HOP4Y(12), PIP_X(id_W808) + top_wire_dist + 2., HOP4Y(10)}, - {PIP_X(id_W808) + top_wire_dist + 2., HOP4Y(10), PIP_X(id_W808) + 3., HOP4Y(10)}, - {PIP_X(id_W808) + 3., HOP4Y(10), PIP_X(id_W808) + top_wire_dist + 3., HOP4Y(8)}, - {PIP_X(id_W808) + top_wire_dist + 3., HOP4Y(8), wrap_len + 4., HOP4Y(8)}, - {wrap_len + 4., HOP4Y(8), wrap_len + 4., HOP4Y(9)}, - {wrap_len + 4., HOP4Y(9), PIP_X(id_W800) + 3., HOP4Y(9)}, - {PIP_X(id_W804) + 3., HOP4Y(9), PIP_X(id_W804) + 3., WIRE_Y(0)}, - {PIP_X(id_W800) + 3., HOP4Y(9), PIP_X(id_W800) - top_wire_dist + 3., HOP4Y(7)}, - {PIP_X(id_W800) - top_wire_dist + 3., HOP4Y(7), PIP_X(id_W800) + 2., HOP4Y(7)}, - {PIP_X(id_W800) + 2., HOP4Y(7), PIP_X(id_W800) - top_wire_dist + 2., HOP4Y(5)}, - {PIP_X(id_W800) - top_wire_dist + 2., HOP4Y(5), PIP_X(id_W800) + 1., HOP4Y(5)}, - {PIP_X(id_W800) + 1., HOP4Y(5), PIP_X(id_W800) - top_wire_dist + 1., HOP4Y(3)}, - {PIP_X(id_W800) - top_wire_dist + 1., HOP4Y(3), PIP_X(id_W800) - 0., HOP4Y(3)}, - {PIP_X(id_W800) - 0., HOP4Y(3), PIP_X(id_W800) - top_wire_dist - 0., HOP4Y(1)}, - {PIP_X(id_W800) - top_wire_dist - 0., HOP4Y(1), PIP_X(id_W808) - 1., HOP4Y(1)}, - {PIP_X(id_W808) - 1., HOP4Y(1), PIP_X(id_W808) - 1., WIRE_Y(0)}}}, - {id_E80_loop4, - {{PIP_X(id_E800), WIRE_Y(0), PIP_X(id_E800), HOP4Y(16)}, - {PIP_X(id_E800), HOP4Y(16), PIP_X(id_W808), HOP4Y(16)}, - {PIP_X(id_W808) + 0., HOP4Y(16), PIP_X(id_W808) + top_wire_dist + 0., HOP4Y(14)}, - {PIP_X(id_W808) + top_wire_dist + 0., HOP4Y(14), PIP_X(id_W808) + 1., HOP4Y(14)}, - {PIP_X(id_W808) + 1., HOP4Y(14), PIP_X(id_W808) + top_wire_dist + 1., HOP4Y(12)}, - {PIP_X(id_W808) + top_wire_dist + 1., HOP4Y(12), PIP_X(id_W808) + 2., HOP4Y(12)}, - {PIP_X(id_W808) + 2., HOP4Y(12), PIP_X(id_W808) + top_wire_dist + 2., HOP4Y(10)}, - {PIP_X(id_W808) + top_wire_dist + 2., HOP4Y(10), PIP_X(id_W808) + 3., HOP4Y(10)}, - {PIP_X(id_W808) + 3., HOP4Y(10), PIP_X(id_W808) + top_wire_dist + 3., HOP4Y(8)}, - {PIP_X(id_W808) + top_wire_dist + 3., HOP4Y(8), PIP_X(id_W808) + 4., HOP4Y(8)}, - {PIP_X(id_E804) + 4., HOP4Y(8), PIP_X(id_E804) + 4., WIRE_Y(0)}, - {PIP_X(id_W808) + 4., HOP4Y(8), PIP_X(id_W808) + top_wire_dist + 4., HOP4Y(6)}, - {PIP_X(id_W808) + top_wire_dist + 4., HOP4Y(6), wrap_len + 5., HOP4Y(6)}, - {wrap_len + 5., HOP4Y(6), wrap_len + 5., HOP4Y(7)}, - {wrap_len + 5., HOP4Y(7), PIP_X(id_W800) + 4., HOP4Y(7)}, - {PIP_X(id_W800) + 4., HOP4Y(7), PIP_X(id_W800) - top_wire_dist + 4., HOP4Y(5)}, - {PIP_X(id_W800) - top_wire_dist + 4., HOP4Y(5), PIP_X(id_W800) + 3., HOP4Y(5)}, - {PIP_X(id_W800) + 3., HOP4Y(5), PIP_X(id_W800) - top_wire_dist + 3., HOP4Y(3)}, - {PIP_X(id_W800) - top_wire_dist + 3., HOP4Y(3), PIP_X(id_W800) + 2., HOP4Y(3)}, - {PIP_X(id_W800) + 2., HOP4Y(3), PIP_X(id_W800) - top_wire_dist + 2., HOP4Y(1)}, - {PIP_X(id_W800) - top_wire_dist + 2., HOP4Y(1), PIP_X(id_W808) + 1., HOP4Y(1)}, - {PIP_X(id_W808) + 1., HOP4Y(1), PIP_X(id_W808) + 1., WIRE_Y(0)}}}, - {id_E80_loop5, - {{PIP_X(id_E800), WIRE_Y(0), PIP_X(id_E800), HOP4Y(16)}, - {PIP_X(id_E800), HOP4Y(16), PIP_X(id_W808), HOP4Y(16)}, - {PIP_X(id_W808) + 0., HOP4Y(16), PIP_X(id_W808) + top_wire_dist + 0., HOP4Y(14)}, - {PIP_X(id_W808) + top_wire_dist + 0., HOP4Y(14), PIP_X(id_W808) + 1., HOP4Y(14)}, - {PIP_X(id_W808) + 1., HOP4Y(14), PIP_X(id_W808) + top_wire_dist + 1., HOP4Y(12)}, - {PIP_X(id_W808) + top_wire_dist + 1., HOP4Y(12), PIP_X(id_W808) + 2., HOP4Y(12)}, - {PIP_X(id_W808) + 2., HOP4Y(12), PIP_X(id_W808) + top_wire_dist + 2., HOP4Y(10)}, - {PIP_X(id_W808) + top_wire_dist + 2., HOP4Y(10), PIP_X(id_W808) + 3., HOP4Y(10)}, - {PIP_X(id_W808) + 3., HOP4Y(10), PIP_X(id_W808) + top_wire_dist + 3., HOP4Y(8)}, - {PIP_X(id_W808) + top_wire_dist + 3., HOP4Y(8), PIP_X(id_W808) + 4., HOP4Y(8)}, - {PIP_X(id_E804) + 4., HOP4Y(8), PIP_X(id_E804) + 4., WIRE_Y(0)}, - {PIP_X(id_W808) + 4., HOP4Y(8), PIP_X(id_W808) + top_wire_dist + 4., HOP4Y(6)}, - {PIP_X(id_W808) + top_wire_dist + 4., HOP4Y(6), PIP_X(id_W808) + 5., HOP4Y(6)}, - {PIP_X(id_W808) + 5., HOP4Y(6), PIP_X(id_W808) + top_wire_dist + 5., HOP4Y(4)}, - {PIP_X(id_W808) + top_wire_dist + 5., HOP4Y(4), wrap_len + 6., HOP4Y(4)}, - {wrap_len + 6., HOP4Y(4), wrap_len + 6., HOP4Y(5)}, - {wrap_len + 6., HOP4Y(5), PIP_X(id_W800) + 5., HOP4Y(5)}, - {PIP_X(id_W800) + 5., HOP4Y(5), PIP_X(id_W800) - top_wire_dist + 5., HOP4Y(3)}, - {PIP_X(id_W800) - top_wire_dist + 5., HOP4Y(3), PIP_X(id_W800) + 4., HOP4Y(3)}, - {PIP_X(id_W800) + 4., HOP4Y(3), PIP_X(id_W800) - top_wire_dist + 4., HOP4Y(1)}, - {PIP_X(id_W800) - top_wire_dist + 4., HOP4Y(1), PIP_X(id_W808) + 3., HOP4Y(1)}, - {PIP_X(id_W808) + 3., HOP4Y(1), PIP_X(id_W808) + 3., WIRE_Y(0)}}}, - {id_E80_loop6, - {{PIP_X(id_E800), WIRE_Y(0), PIP_X(id_E800), HOP4Y(16)}, - {PIP_X(id_E800), HOP4Y(16), PIP_X(id_W808), HOP4Y(16)}, - {PIP_X(id_W808) + 0., HOP4Y(16), PIP_X(id_W808) + top_wire_dist + 0., HOP4Y(14)}, - {PIP_X(id_W808) + top_wire_dist + 0., HOP4Y(14), PIP_X(id_W808) + 1., HOP4Y(14)}, - {PIP_X(id_W808) + 1., HOP4Y(14), PIP_X(id_W808) + top_wire_dist + 1., HOP4Y(12)}, - {PIP_X(id_W808) + top_wire_dist + 1., HOP4Y(12), PIP_X(id_W808) + 2., HOP4Y(12)}, - {PIP_X(id_W808) + 2., HOP4Y(12), PIP_X(id_W808) + top_wire_dist + 2., HOP4Y(10)}, - {PIP_X(id_W808) + top_wire_dist + 2., HOP4Y(10), PIP_X(id_W808) + 3., HOP4Y(10)}, - {PIP_X(id_W808) + 3., HOP4Y(10), PIP_X(id_W808) + top_wire_dist + 3., HOP4Y(8)}, - {PIP_X(id_W808) + top_wire_dist + 3., HOP4Y(8), PIP_X(id_W808) + 4., HOP4Y(8)}, - {PIP_X(id_W808) + 4., HOP4Y(8), PIP_X(id_W808) + top_wire_dist + 4., HOP4Y(6)}, - {PIP_X(id_E804) + 4., HOP4Y(8), PIP_X(id_E804) + 4., WIRE_Y(0)}, - {PIP_X(id_W808) + top_wire_dist + 4., HOP4Y(6), PIP_X(id_W808) + 5., HOP4Y(6)}, - {PIP_X(id_W808) + 5., HOP4Y(6), PIP_X(id_W808) + top_wire_dist + 5., HOP4Y(4)}, - {PIP_X(id_W808) + top_wire_dist + 5., HOP4Y(4), PIP_X(id_W808) + 6., HOP4Y(4)}, - {PIP_X(id_W808) + 6., HOP4Y(4), PIP_X(id_W808) + top_wire_dist + 6., HOP4Y(2)}, - {PIP_X(id_W808) + top_wire_dist + 6., HOP4Y(2), wrap_len + 7., HOP4Y(2)}, - {wrap_len + 7., HOP4Y(2), wrap_len + 7., HOP4Y(3)}, - {wrap_len + 7., HOP4Y(3), PIP_X(id_W800) + 6., HOP4Y(3)}, - {PIP_X(id_W800) + 6., HOP4Y(3), PIP_X(id_W800) - top_wire_dist + 6., HOP4Y(1)}, - {PIP_X(id_W800) - top_wire_dist + 6., HOP4Y(1), PIP_X(id_W808) + 5., HOP4Y(1)}, - {PIP_X(id_W808) + 5., HOP4Y(1), PIP_X(id_W808) + 5., WIRE_Y(0)}}}, - {id_E80_loop7, - {{PIP_X(id_E800), WIRE_Y(0), PIP_X(id_E800), HOP4Y(16)}, - {PIP_X(id_E800), HOP4Y(16), PIP_X(id_W808), HOP4Y(16)}, - {PIP_X(id_W808) + 0., HOP4Y(16), PIP_X(id_W808) + top_wire_dist + 0., HOP4Y(14)}, - {PIP_X(id_W808) + top_wire_dist + 0., HOP4Y(14), PIP_X(id_W808) + 1., HOP4Y(14)}, - {PIP_X(id_W808) + 1., HOP4Y(14), PIP_X(id_W808) + top_wire_dist + 1., HOP4Y(12)}, - {PIP_X(id_W808) + top_wire_dist + 1., HOP4Y(12), PIP_X(id_W808) + 2., HOP4Y(12)}, - {PIP_X(id_W808) + 2., HOP4Y(12), PIP_X(id_W808) + top_wire_dist + 2., HOP4Y(10)}, - {PIP_X(id_W808) + top_wire_dist + 2., HOP4Y(10), PIP_X(id_W808) + 3., HOP4Y(10)}, - {PIP_X(id_W808) + 3., HOP4Y(10), PIP_X(id_W808) + top_wire_dist + 3., HOP4Y(8)}, - {PIP_X(id_W808) + top_wire_dist + 3., HOP4Y(8), PIP_X(id_W808) + 4., HOP4Y(8)}, - {PIP_X(id_W808) + 4., HOP4Y(8), PIP_X(id_W808) + top_wire_dist + 4., HOP4Y(6)}, - {PIP_X(id_E804) + 4., HOP4Y(8), PIP_X(id_E804) + 4., WIRE_Y(0)}, - {PIP_X(id_W808) + top_wire_dist + 4., HOP4Y(6), PIP_X(id_W808) + 5., HOP4Y(6)}, - {PIP_X(id_W808) + 5., HOP4Y(6), PIP_X(id_W808) + top_wire_dist + 5., HOP4Y(4)}, - {PIP_X(id_W808) + top_wire_dist + 5., HOP4Y(4), PIP_X(id_W808) + 6., HOP4Y(4)}, - {PIP_X(id_W808) + 6., HOP4Y(4), PIP_X(id_W808) + top_wire_dist + 6., HOP4Y(2)}, - {PIP_X(id_W808) + top_wire_dist + 6., HOP4Y(2), PIP_X(id_W808) + 7., HOP4Y(2)}, - {PIP_X(id_W808) + 7., HOP4Y(2), PIP_X(id_W808) + top_wire_dist + 7., HOP4Y(0)}, - {PIP_X(id_W808) + top_wire_dist + 7., HOP4Y(0), wrap_len + 8., HOP4Y(0)}, - {wrap_len + 8., HOP4Y(0), wrap_len + 8., HOP4Y(1)}, - {wrap_len + 8., HOP4Y(1), PIP_X(id_W808) + 7., HOP4Y(1)}, - {PIP_X(id_W808) + 7., HOP4Y(1), PIP_X(id_W808) + 7., WIRE_Y(0)}}}, - {id_W80_loop0, - {{PIP_X(id_W800), WIRE_Y(0), PIP_X(id_W800), HOP4Y(17)}, - {PIP_X(id_W800) - 0., HOP4Y(17), PIP_X(id_W800) - top_wire_dist - 0., HOP4Y(15)}, - {PIP_X(id_W800) - top_wire_dist - 0., HOP4Y(15), -wrap_len - 0., HOP4Y(15)}, - {-wrap_len - 0., HOP4Y(15), -wrap_len - 0., HOP4Y(14)}, - {-wrap_len - 0., HOP4Y(14), PIP_X(id_W808) + 0., HOP4Y(14)}, - {PIP_X(id_W808) + 0., HOP4Y(14), PIP_X(id_W808) + top_wire_dist + 0., HOP4Y(12)}, - {PIP_X(id_W808) + top_wire_dist + 0., HOP4Y(12), PIP_X(id_W808) + 1., HOP4Y(12)}, - {PIP_X(id_W808) + 1., HOP4Y(12), PIP_X(id_W808) + top_wire_dist + 1., HOP4Y(10)}, - {PIP_X(id_W808) + top_wire_dist + 1., HOP4Y(10), PIP_X(id_W808) + 2., HOP4Y(10)}, - {PIP_X(id_W808) + 2., HOP4Y(10), PIP_X(id_W808) + top_wire_dist + 2., HOP4Y(8)}, - {PIP_X(id_W808) + top_wire_dist + 2., HOP4Y(8), PIP_X(id_W808) + 3., HOP4Y(8)}, - {PIP_X(id_W808) + 3., HOP4Y(8), PIP_X(id_W808) + top_wire_dist + 3., HOP4Y(6)}, - {PIP_X(id_E804) + 3., HOP4Y(8), PIP_X(id_E804) + 3., WIRE_Y(0)}, - {PIP_X(id_W808) + top_wire_dist + 3., HOP4Y(6), PIP_X(id_W808) + 4., HOP4Y(6)}, - {PIP_X(id_W808) + 4., HOP4Y(6), PIP_X(id_W808) + top_wire_dist + 4., HOP4Y(4)}, - {PIP_X(id_W808) + top_wire_dist + 4., HOP4Y(4), PIP_X(id_W808) + 5., HOP4Y(4)}, - {PIP_X(id_W808) + 5., HOP4Y(4), PIP_X(id_W808) + top_wire_dist + 5., HOP4Y(2)}, - {PIP_X(id_W808) + top_wire_dist + 5., HOP4Y(2), PIP_X(id_W808) + 6., HOP4Y(2)}, - {PIP_X(id_W808) + 6., HOP4Y(2), PIP_X(id_W808) + top_wire_dist + 6., HOP4Y(0)}, - {PIP_X(id_W808) + top_wire_dist + 6., HOP4Y(0), PIP_X(id_E808) + 7., HOP4Y(0)}, - {PIP_X(id_E808) + 7., HOP4Y(0), PIP_X(id_E808) + 7., WIRE_Y(0)}}}, - {id_W80_loop1, - {{PIP_X(id_W800), WIRE_Y(0), PIP_X(id_W800), HOP4Y(17)}, - {PIP_X(id_W800) - 0., HOP4Y(17), PIP_X(id_W800) - top_wire_dist - 0., HOP4Y(15)}, - {PIP_X(id_W800) - top_wire_dist - 0., HOP4Y(15), PIP_X(id_W800) - 1., HOP4Y(15)}, - {PIP_X(id_W800) - 1., HOP4Y(15), PIP_X(id_W800) - top_wire_dist - 1., HOP4Y(13)}, - {PIP_X(id_W800) - top_wire_dist - 1., HOP4Y(13), -wrap_len - 1., HOP4Y(13)}, - {-wrap_len - 1., HOP4Y(13), -wrap_len - 1., HOP4Y(12)}, - {-wrap_len - 1., HOP4Y(12), PIP_X(id_W808) - 1., HOP4Y(12)}, - {PIP_X(id_W808) - 1., HOP4Y(12), PIP_X(id_W808) + top_wire_dist - 1., HOP4Y(10)}, - {PIP_X(id_W808) + top_wire_dist - 1., HOP4Y(10), PIP_X(id_W808) + 0., HOP4Y(10)}, - {PIP_X(id_W808) + 0., HOP4Y(10), PIP_X(id_W808) + top_wire_dist + 0., HOP4Y(8)}, - {PIP_X(id_W808) + top_wire_dist + 0., HOP4Y(8), PIP_X(id_W808) + 1., HOP4Y(8)}, - {PIP_X(id_W808) + 1., HOP4Y(8), PIP_X(id_W808) + top_wire_dist + 1., HOP4Y(6)}, - {PIP_X(id_E804) + 1., HOP4Y(8), PIP_X(id_E804) + 1., WIRE_Y(0)}, - {PIP_X(id_W808) + top_wire_dist + 1., HOP4Y(6), PIP_X(id_W808) + 2., HOP4Y(6)}, - {PIP_X(id_W808) + 2., HOP4Y(6), PIP_X(id_W808) + top_wire_dist + 2., HOP4Y(4)}, - {PIP_X(id_W808) + top_wire_dist + 2., HOP4Y(4), PIP_X(id_W808) + 3., HOP4Y(4)}, - {PIP_X(id_W808) + 3., HOP4Y(4), PIP_X(id_W808) + top_wire_dist + 3., HOP4Y(2)}, - {PIP_X(id_W808) + top_wire_dist + 3., HOP4Y(2), PIP_X(id_W808) + 4., HOP4Y(2)}, - {PIP_X(id_W808) + 4., HOP4Y(2), PIP_X(id_W808) + top_wire_dist + 4., HOP4Y(0)}, - {PIP_X(id_W808) + top_wire_dist + 4., HOP4Y(0), PIP_X(id_E808) + 5., HOP4Y(0)}, - {PIP_X(id_E808) + 5., HOP4Y(0), PIP_X(id_E808) + 5., WIRE_Y(0)}}}, - {id_W80_loop2, - {{PIP_X(id_W800), WIRE_Y(0), PIP_X(id_W800), HOP4Y(17)}, - {PIP_X(id_W800) - 0., HOP4Y(17), PIP_X(id_W800) - top_wire_dist - 0., HOP4Y(15)}, - {PIP_X(id_W800) - top_wire_dist - 0., HOP4Y(15), PIP_X(id_W800) - 1., HOP4Y(15)}, - {PIP_X(id_W800) - 1., HOP4Y(15), PIP_X(id_W800) - top_wire_dist - 1., HOP4Y(13)}, - {PIP_X(id_W800) - top_wire_dist - 1., HOP4Y(13), PIP_X(id_W800) - 2., HOP4Y(13)}, - {PIP_X(id_W800) - 2., HOP4Y(13), PIP_X(id_W800) - top_wire_dist - 2., HOP4Y(11)}, - {PIP_X(id_W800) - top_wire_dist - 2., HOP4Y(11), -wrap_len - 2., HOP4Y(11)}, - {-wrap_len - 2., HOP4Y(11), -wrap_len - 2., HOP4Y(10)}, - {-wrap_len - 2., HOP4Y(10), PIP_X(id_W808) - 2., HOP4Y(10)}, - {PIP_X(id_W808) - 2., HOP4Y(10), PIP_X(id_W808) + top_wire_dist - 2., HOP4Y(8)}, - {PIP_X(id_W808) + top_wire_dist - 2., HOP4Y(8), PIP_X(id_W808) - 1., HOP4Y(8)}, - {PIP_X(id_W808) - 1., HOP4Y(8), PIP_X(id_W808) + top_wire_dist - 1., HOP4Y(6)}, - {PIP_X(id_E804) - 1., HOP4Y(8), PIP_X(id_E804) - 1., WIRE_Y(0)}, - {PIP_X(id_W808) + top_wire_dist - 1., HOP4Y(6), PIP_X(id_W808) + 0., HOP4Y(6)}, - {PIP_X(id_W808) + 0., HOP4Y(6), PIP_X(id_W808) + top_wire_dist + 0., HOP4Y(4)}, - {PIP_X(id_W808) + top_wire_dist + 0., HOP4Y(4), PIP_X(id_W808) + 1., HOP4Y(4)}, - {PIP_X(id_W808) + 1., HOP4Y(4), PIP_X(id_W808) + top_wire_dist + 1., HOP4Y(2)}, - {PIP_X(id_W808) + top_wire_dist + 1., HOP4Y(2), PIP_X(id_W808) + 2., HOP4Y(2)}, - {PIP_X(id_W808) + 2., HOP4Y(2), PIP_X(id_W808) + top_wire_dist + 2., HOP4Y(0)}, - {PIP_X(id_W808) + top_wire_dist + 2., HOP4Y(0), PIP_X(id_E808) + 3., HOP4Y(0)}, - {PIP_X(id_E808) + 3., HOP4Y(0), PIP_X(id_E808) + 3., WIRE_Y(0)}}}, - {id_W80_loop3, - {{PIP_X(id_W800), WIRE_Y(0), PIP_X(id_W800), HOP4Y(17)}, - {PIP_X(id_W800) - 0., HOP4Y(17), PIP_X(id_W800) - top_wire_dist - 0., HOP4Y(15)}, - {PIP_X(id_W800) - top_wire_dist - 0., HOP4Y(15), PIP_X(id_W800) - 1., HOP4Y(15)}, - {PIP_X(id_W800) - 1., HOP4Y(15), PIP_X(id_W800) - top_wire_dist - 1., HOP4Y(13)}, - {PIP_X(id_W800) - top_wire_dist - 1., HOP4Y(13), PIP_X(id_W800) - 2., HOP4Y(13)}, - {PIP_X(id_W800) - 2., HOP4Y(13), PIP_X(id_W800) - top_wire_dist - 2., HOP4Y(11)}, - {PIP_X(id_W800) - top_wire_dist - 2., HOP4Y(11), PIP_X(id_W800) - 3., HOP4Y(11)}, - {PIP_X(id_W800) - 3., HOP4Y(11), PIP_X(id_W800) - top_wire_dist - 3., HOP4Y(9)}, - {PIP_X(id_W800) - top_wire_dist - 3., HOP4Y(9), -wrap_len - 3., HOP4Y(9)}, - {-wrap_len - 3., HOP4Y(9), -wrap_len - 3., HOP4Y(8)}, - {-wrap_len - 3., HOP4Y(8), PIP_X(id_W808) - 3., HOP4Y(8)}, - {PIP_X(id_W808) - 3., HOP4Y(8), PIP_X(id_W808) + top_wire_dist - 3., HOP4Y(6)}, - {PIP_X(id_E804) - 3., HOP4Y(8), PIP_X(id_E804) - 3., WIRE_Y(0)}, - {PIP_X(id_W808) + top_wire_dist - 3., HOP4Y(6), PIP_X(id_W808) - 2., HOP4Y(6)}, - {PIP_X(id_W808) - 2., HOP4Y(6), PIP_X(id_W808) + top_wire_dist - 2., HOP4Y(4)}, - {PIP_X(id_W808) + top_wire_dist - 2., HOP4Y(4), PIP_X(id_W808) - 1., HOP4Y(4)}, - {PIP_X(id_W808) - 1., HOP4Y(4), PIP_X(id_W808) + top_wire_dist - 1., HOP4Y(2)}, - {PIP_X(id_W808) + top_wire_dist - 1., HOP4Y(2), PIP_X(id_W808) + 0., HOP4Y(2)}, - {PIP_X(id_W808) + 0., HOP4Y(2), PIP_X(id_W808) + top_wire_dist + 0., HOP4Y(0)}, - {PIP_X(id_W808) + top_wire_dist + 0., HOP4Y(0), PIP_X(id_E808) + 1., HOP4Y(0)}, - {PIP_X(id_E808) + 1., HOP4Y(0), PIP_X(id_E808) + 1., WIRE_Y(0)}}}, - {id_W80_loop4, - {{PIP_X(id_W800), WIRE_Y(0), PIP_X(id_W800), HOP4Y(17)}, - {PIP_X(id_W800) - 0., HOP4Y(17), PIP_X(id_W800) - top_wire_dist - 0., HOP4Y(15)}, - {PIP_X(id_W800) - top_wire_dist - 0., HOP4Y(15), PIP_X(id_W800) - 1., HOP4Y(15)}, - {PIP_X(id_W800) - 1., HOP4Y(15), PIP_X(id_W800) - top_wire_dist - 1., HOP4Y(13)}, - {PIP_X(id_W800) - top_wire_dist - 1., HOP4Y(13), PIP_X(id_W800) - 2., HOP4Y(13)}, - {PIP_X(id_W800) - 2., HOP4Y(13), PIP_X(id_W800) - top_wire_dist - 2., HOP4Y(11)}, - {PIP_X(id_W800) - top_wire_dist - 2., HOP4Y(11), PIP_X(id_W800) - 3., HOP4Y(11)}, - {PIP_X(id_W800) - 3., HOP4Y(11), PIP_X(id_W800) - top_wire_dist - 3., HOP4Y(9)}, - {PIP_X(id_W800) - top_wire_dist - 3., HOP4Y(9), PIP_X(id_W800) - 4., HOP4Y(9)}, - {PIP_X(id_W800) - 4., HOP4Y(9), PIP_X(id_W800) - top_wire_dist - 4., HOP4Y(7)}, - {PIP_X(id_W800) - top_wire_dist - 4., HOP4Y(7), -wrap_len - 4., HOP4Y(7)}, - {-wrap_len - 4., HOP4Y(7), -wrap_len - 4., HOP4Y(6)}, - {PIP_X(id_W804) - 4., HOP4Y(6), PIP_X(id_W804) - 4., WIRE_Y(0)}, - {-wrap_len - 4., HOP4Y(6), PIP_X(id_W808) - 4., HOP4Y(6)}, - {PIP_X(id_W808) - 4., HOP4Y(6), PIP_X(id_W808) + top_wire_dist - 4., HOP4Y(4)}, - {PIP_X(id_W808) + top_wire_dist - 4., HOP4Y(4), PIP_X(id_W808) - 3., HOP4Y(4)}, - {PIP_X(id_W808) - 3., HOP4Y(4), PIP_X(id_W808) + top_wire_dist - 3., HOP4Y(2)}, - {PIP_X(id_W808) + top_wire_dist - 3., HOP4Y(2), PIP_X(id_W808) - 2., HOP4Y(2)}, - {PIP_X(id_W808) - 2., HOP4Y(2), PIP_X(id_W808) + top_wire_dist - 2., HOP4Y(0)}, - {PIP_X(id_W808) + top_wire_dist - 2., HOP4Y(0), PIP_X(id_E808) - 1., HOP4Y(0)}, - {PIP_X(id_E808) - 1., HOP4Y(0), PIP_X(id_E808) - 1., WIRE_Y(0)}}}, - {id_W80_loop5, - {{PIP_X(id_W800), WIRE_Y(0), PIP_X(id_W800), HOP4Y(17)}, - {PIP_X(id_W800) - 0., HOP4Y(17), PIP_X(id_W800) - top_wire_dist - 0., HOP4Y(15)}, - {PIP_X(id_W800) - top_wire_dist - 0., HOP4Y(15), PIP_X(id_W800) - 1., HOP4Y(15)}, - {PIP_X(id_W800) - 1., HOP4Y(15), PIP_X(id_W800) - top_wire_dist - 1., HOP4Y(13)}, - {PIP_X(id_W800) - top_wire_dist - 1., HOP4Y(13), PIP_X(id_W800) - 2., HOP4Y(13)}, - {PIP_X(id_W800) - 2., HOP4Y(13), PIP_X(id_W800) - top_wire_dist - 2., HOP4Y(11)}, - {PIP_X(id_W800) - top_wire_dist - 2., HOP4Y(11), PIP_X(id_W800) - 3., HOP4Y(11)}, - {PIP_X(id_W800) - 3., HOP4Y(11), PIP_X(id_W800) - top_wire_dist - 3., HOP4Y(9)}, - {PIP_X(id_W800) - top_wire_dist - 3., HOP4Y(9), PIP_X(id_W800) - 4., HOP4Y(9)}, - {PIP_X(id_W800) - 4., HOP4Y(9), PIP_X(id_W800) - top_wire_dist - 4., HOP4Y(7)}, - {PIP_X(id_W804) - 4., HOP4Y(9), PIP_X(id_W804) - 4., WIRE_Y(0)}, - {PIP_X(id_W800) - top_wire_dist - 4., HOP4Y(7), PIP_X(id_W800) - 5., HOP4Y(7)}, - {PIP_X(id_W800) - 5., HOP4Y(7), PIP_X(id_W800) - top_wire_dist - 5., HOP4Y(5)}, - {PIP_X(id_W800) - top_wire_dist - 5., HOP4Y(5), -wrap_len - 5., HOP4Y(5)}, - {-wrap_len - 5., HOP4Y(5), -wrap_len - 5., HOP4Y(4)}, - {-wrap_len - 5., HOP4Y(4), PIP_X(id_W808) - 5., HOP4Y(4)}, - {PIP_X(id_W808) - 5., HOP4Y(4), PIP_X(id_W808) + top_wire_dist - 5., HOP4Y(2)}, - {PIP_X(id_W808) + top_wire_dist - 5., HOP4Y(2), PIP_X(id_W808) - 4., HOP4Y(2)}, - {PIP_X(id_W808) - 4., HOP4Y(2), PIP_X(id_W808) + top_wire_dist - 4., HOP4Y(0)}, - {PIP_X(id_W808) + top_wire_dist - 4., HOP4Y(0), PIP_X(id_E808) - 3., HOP4Y(0)}, - {PIP_X(id_E808) - 3., HOP4Y(0), PIP_X(id_E808) - 3., WIRE_Y(0)}}}, - {id_W80_loop6, - {{PIP_X(id_W800), WIRE_Y(0), PIP_X(id_W800), HOP4Y(17)}, - {PIP_X(id_W800) - 0., HOP4Y(17), PIP_X(id_W800) - top_wire_dist - 0., HOP4Y(15)}, - {PIP_X(id_W800) - top_wire_dist - 0., HOP4Y(15), PIP_X(id_W800) - 1., HOP4Y(15)}, - {PIP_X(id_W800) - 1., HOP4Y(15), PIP_X(id_W800) - top_wire_dist - 1., HOP4Y(13)}, - {PIP_X(id_W800) - top_wire_dist - 1., HOP4Y(13), PIP_X(id_W800) - 2., HOP4Y(13)}, - {PIP_X(id_W800) - 2., HOP4Y(13), PIP_X(id_W800) - top_wire_dist - 2., HOP4Y(11)}, - {PIP_X(id_W800) - top_wire_dist - 2., HOP4Y(11), PIP_X(id_W800) - 3., HOP4Y(11)}, - {PIP_X(id_W800) - 3., HOP4Y(11), PIP_X(id_W800) - top_wire_dist - 3., HOP4Y(9)}, - {PIP_X(id_W800) - top_wire_dist - 3., HOP4Y(9), PIP_X(id_W800) - 4., HOP4Y(9)}, - {PIP_X(id_W800) - 4., HOP4Y(9), PIP_X(id_W800) - top_wire_dist - 4., HOP4Y(7)}, - {PIP_X(id_W804) - 4., HOP4Y(9), PIP_X(id_W804) - 4., WIRE_Y(0)}, - {PIP_X(id_W800) - top_wire_dist - 4., HOP4Y(7), PIP_X(id_W800) - 5., HOP4Y(7)}, - {PIP_X(id_W800) - 5., HOP4Y(7), PIP_X(id_W800) - top_wire_dist - 5., HOP4Y(5)}, - {PIP_X(id_W800) - top_wire_dist - 5., HOP4Y(5), PIP_X(id_W800) - 6., HOP4Y(5)}, - {PIP_X(id_W800) - 6., HOP4Y(5), PIP_X(id_W800) - top_wire_dist - 6., HOP4Y(3)}, - {PIP_X(id_W800) - top_wire_dist - 6., HOP4Y(3), -wrap_len - 6., HOP4Y(3)}, - {-wrap_len - 6., HOP4Y(3), -wrap_len - 6., HOP4Y(2)}, - {-wrap_len - 6., HOP4Y(2), PIP_X(id_W808) - 6., HOP4Y(2)}, - {PIP_X(id_W808) - 6., HOP4Y(2), PIP_X(id_W808) + top_wire_dist - 6., HOP4Y(0)}, - {PIP_X(id_W808) + top_wire_dist - 6., HOP4Y(0), PIP_X(id_E808) - 5., HOP4Y(0)}, - {PIP_X(id_E808) - 5., HOP4Y(0), PIP_X(id_E808) - 5., WIRE_Y(0)}}}, - {id_W80_loop7, - {{PIP_X(id_W800), WIRE_Y(0), PIP_X(id_W800), HOP4Y(17)}, - {PIP_X(id_W800) - 0., HOP4Y(17), PIP_X(id_W800) - top_wire_dist - 0., HOP4Y(15)}, - {PIP_X(id_W800) - top_wire_dist - 0., HOP4Y(15), PIP_X(id_W800) - 1., HOP4Y(15)}, - {PIP_X(id_W800) - 1., HOP4Y(15), PIP_X(id_W800) - top_wire_dist - 1., HOP4Y(13)}, - {PIP_X(id_W800) - top_wire_dist - 1., HOP4Y(13), PIP_X(id_W800) - 2., HOP4Y(13)}, - {PIP_X(id_W800) - 2., HOP4Y(13), PIP_X(id_W800) - top_wire_dist - 2., HOP4Y(11)}, - {PIP_X(id_W800) - top_wire_dist - 2., HOP4Y(11), PIP_X(id_W800) - 3., HOP4Y(11)}, - {PIP_X(id_W800) - 3., HOP4Y(11), PIP_X(id_W800) - top_wire_dist - 3., HOP4Y(9)}, - {PIP_X(id_W800) - top_wire_dist - 3., HOP4Y(9), PIP_X(id_W800) - 4., HOP4Y(9)}, - {PIP_X(id_W800) - 4., HOP4Y(9), PIP_X(id_W800) - top_wire_dist - 4., HOP4Y(7)}, - {PIP_X(id_W804) - 4., HOP4Y(9), PIP_X(id_W804) - 4., WIRE_Y(0)}, - {PIP_X(id_W800) - top_wire_dist - 4., HOP4Y(7), PIP_X(id_W800) - 5., HOP4Y(7)}, - {PIP_X(id_W800) - 5., HOP4Y(7), PIP_X(id_W800) - top_wire_dist - 5., HOP4Y(5)}, - {PIP_X(id_W800) - top_wire_dist - 5., HOP4Y(5), PIP_X(id_W800) - 6., HOP4Y(5)}, - {PIP_X(id_W800) - 6., HOP4Y(5), PIP_X(id_W800) - top_wire_dist - 6., HOP4Y(3)}, - {PIP_X(id_W800) - top_wire_dist - 6., HOP4Y(3), PIP_X(id_W800) - 7., HOP4Y(3)}, - {PIP_X(id_W800) - 7., HOP4Y(3), PIP_X(id_W800) - top_wire_dist - 7., HOP4Y(1)}, - {PIP_X(id_W800) - top_wire_dist - 7., HOP4Y(1), -wrap_len - 7., HOP4Y(1)}, - {-wrap_len - 7., HOP4Y(1), -wrap_len - 7., HOP4Y(0)}, - {-wrap_len - 7., HOP4Y(0), PIP_X(id_E808) - 7., HOP4Y(0)}, - {PIP_X(id_E808) - 7., HOP4Y(0), PIP_X(id_E808) - 7., WIRE_Y(0)}}}, - -#undef HOP4Y -#define HOP4Y(offset) WIRE_Y((float)offset + HOP4Y_START + 18.f) - {id_E81, - {{PIP_X(id_E810), WIRE_Y(0), PIP_X(id_E810), HOP4Y(16)}, - {PIP_X(id_E810), HOP4Y(16), PIP_X(id_W818), HOP4Y(16)}, - {PIP_X(id_W818) + 0., HOP4Y(16), PIP_X(id_W818) + top_wire_dist + 0., HOP4Y(14)}, - {PIP_X(id_W818) + top_wire_dist + 0., HOP4Y(14), PIP_X(id_W818) + 1., HOP4Y(14)}, - {PIP_X(id_W818) + 1., HOP4Y(14), PIP_X(id_W818) + top_wire_dist + 1., HOP4Y(12)}, - {PIP_X(id_W818) + top_wire_dist + 1., HOP4Y(12), PIP_X(id_W818) + 2., HOP4Y(12)}, - {PIP_X(id_W818) + 2., HOP4Y(12), PIP_X(id_W818) + top_wire_dist + 2., HOP4Y(10)}, - {PIP_X(id_W818) + top_wire_dist + 2., HOP4Y(10), PIP_X(id_W818) + 3., HOP4Y(10)}, - {PIP_X(id_W818) + 3., HOP4Y(10), PIP_X(id_W818) + top_wire_dist + 3., HOP4Y(8)}, - {PIP_X(id_W818) + top_wire_dist + 3., HOP4Y(8), PIP_X(id_W818) + 4., HOP4Y(8)}, - {PIP_X(id_W818) + 4., HOP4Y(8), PIP_X(id_W818) + top_wire_dist + 4., HOP4Y(6)}, - {PIP_X(id_E814) + 4., HOP4Y(8), PIP_X(id_E814) + 4., WIRE_Y(0)}, - {PIP_X(id_W818) + top_wire_dist + 4., HOP4Y(6), PIP_X(id_W818) + 5., HOP4Y(6)}, - {PIP_X(id_W818) + 5., HOP4Y(6), PIP_X(id_W818) + top_wire_dist + 5., HOP4Y(4)}, - {PIP_X(id_W818) + top_wire_dist + 5., HOP4Y(4), PIP_X(id_W818) + 6., HOP4Y(4)}, - {PIP_X(id_W818) + 6., HOP4Y(4), PIP_X(id_W818) + top_wire_dist + 6., HOP4Y(2)}, - {PIP_X(id_W818) + top_wire_dist + 6., HOP4Y(2), PIP_X(id_W818) + 7., HOP4Y(2)}, - {PIP_X(id_W818) + 7., HOP4Y(2), PIP_X(id_W818) + top_wire_dist + 7., HOP4Y(0)}, - {PIP_X(id_W818) + top_wire_dist + 7., HOP4Y(0), PIP_X(id_E818) + 8., HOP4Y(0)}, - {PIP_X(id_E818) + 8, HOP4Y(0), PIP_X(id_E818) + 8., WIRE_Y(0)}}}, - {id_W81, - {{PIP_X(id_W810), WIRE_Y(0), PIP_X(id_W810), HOP4Y(17)}, - {PIP_X(id_W810) - 0., HOP4Y(17), PIP_X(id_W810) - top_wire_dist - 0., HOP4Y(15)}, - {PIP_X(id_W810) - top_wire_dist - 0., HOP4Y(15), PIP_X(id_W810) - 1., HOP4Y(15)}, - {PIP_X(id_W810) - 1., HOP4Y(15), PIP_X(id_W810) - top_wire_dist - 1., HOP4Y(13)}, - {PIP_X(id_W810) - top_wire_dist - 1., HOP4Y(13), PIP_X(id_W810) - 2., HOP4Y(13)}, - {PIP_X(id_W810) - 2., HOP4Y(13), PIP_X(id_W810) - top_wire_dist - 2., HOP4Y(11)}, - {PIP_X(id_W810) - top_wire_dist - 2., HOP4Y(11), PIP_X(id_W810) - 3., HOP4Y(11)}, - {PIP_X(id_W810) - 3., HOP4Y(11), PIP_X(id_W810) - top_wire_dist - 3., HOP4Y(9)}, - {PIP_X(id_W810) - top_wire_dist - 3., HOP4Y(9), PIP_X(id_W810) - 4., HOP4Y(9)}, - {PIP_X(id_W810) - 4., HOP4Y(9), PIP_X(id_W810) - top_wire_dist - 4., HOP4Y(7)}, - {PIP_X(id_W814) - 4., HOP4Y(9), PIP_X(id_W814) - 4., WIRE_Y(0)}, - {PIP_X(id_W810) - top_wire_dist - 4., HOP4Y(7), PIP_X(id_W810) - 5., HOP4Y(7)}, - {PIP_X(id_W810) - 5., HOP4Y(7), PIP_X(id_W810) - top_wire_dist - 5., HOP4Y(5)}, - {PIP_X(id_W810) - top_wire_dist - 5., HOP4Y(5), PIP_X(id_W810) - 6., HOP4Y(5)}, - {PIP_X(id_W810) - 6., HOP4Y(5), PIP_X(id_W810) - top_wire_dist - 6., HOP4Y(3)}, - {PIP_X(id_W810) - top_wire_dist - 6., HOP4Y(3), PIP_X(id_W810) - 7., HOP4Y(3)}, - {PIP_X(id_W810) - 7., HOP4Y(3), PIP_X(id_W810) - top_wire_dist - 7., HOP4Y(1)}, - {PIP_X(id_W810) - top_wire_dist - 7., HOP4Y(1), PIP_X(id_W818) - 8., HOP4Y(1)}, - {PIP_X(id_W818) - 8, HOP4Y(1), PIP_X(id_W818) - 8., WIRE_Y(0)}}}, - {id_E81_loop0, - {{PIP_X(id_E810), WIRE_Y(0), PIP_X(id_E810), HOP4Y(16)}, - {PIP_X(id_E810), HOP4Y(16), PIP_X(id_W818), HOP4Y(16)}, - {PIP_X(id_W818) + 0., HOP4Y(16), PIP_X(id_W818) + top_wire_dist + 0., HOP4Y(14)}, - {PIP_X(id_W818) + top_wire_dist + 0., HOP4Y(14), wrap_len + 1., HOP4Y(14)}, - {wrap_len + 1., HOP4Y(14), wrap_len + 1., HOP4Y(15)}, - {wrap_len + 1., HOP4Y(15), PIP_X(id_W810) - 0., HOP4Y(15)}, - {PIP_X(id_W810) - 0., HOP4Y(15), PIP_X(id_W810) - top_wire_dist - 0., HOP4Y(13)}, - {PIP_X(id_W810) - top_wire_dist - 0., HOP4Y(13), PIP_X(id_W810) - 1., HOP4Y(13)}, - {PIP_X(id_W810) - 1., HOP4Y(13), PIP_X(id_W810) - top_wire_dist - 1., HOP4Y(11)}, - {PIP_X(id_W810) - top_wire_dist - 1., HOP4Y(11), PIP_X(id_W810) - 2., HOP4Y(11)}, - {PIP_X(id_W810) - 2., HOP4Y(11), PIP_X(id_W810) - top_wire_dist - 2., HOP4Y(9)}, - {PIP_X(id_W810) - top_wire_dist - 2., HOP4Y(9), PIP_X(id_W810) - 3., HOP4Y(9)}, - {PIP_X(id_W810) - 3., HOP4Y(9), PIP_X(id_W810) - top_wire_dist - 3., HOP4Y(7)}, - {PIP_X(id_W814) - 3., HOP4Y(9), PIP_X(id_W814) - 3., WIRE_Y(0)}, - {PIP_X(id_W810) - top_wire_dist - 3., HOP4Y(7), PIP_X(id_W810) - 4., HOP4Y(7)}, - {PIP_X(id_W810) - 4., HOP4Y(7), PIP_X(id_W810) - top_wire_dist - 4., HOP4Y(5)}, - {PIP_X(id_W810) - top_wire_dist - 4., HOP4Y(5), PIP_X(id_W810) - 5., HOP4Y(5)}, - {PIP_X(id_W810) - 5., HOP4Y(5), PIP_X(id_W810) - top_wire_dist - 5., HOP4Y(3)}, - {PIP_X(id_W810) - top_wire_dist - 5., HOP4Y(3), PIP_X(id_W810) - 6., HOP4Y(3)}, - {PIP_X(id_W810) - 6., HOP4Y(3), PIP_X(id_W810) - top_wire_dist - 6., HOP4Y(1)}, - {PIP_X(id_W810) - top_wire_dist - 6., HOP4Y(1), PIP_X(id_W818) - 7., HOP4Y(1)}, - {PIP_X(id_W818) - 7, HOP4Y(1), PIP_X(id_W818) - 7., WIRE_Y(0)}}}, - {id_E81_loop1, - {{PIP_X(id_E810), WIRE_Y(0), PIP_X(id_E810), HOP4Y(16)}, - {PIP_X(id_E810), HOP4Y(16), PIP_X(id_W818), HOP4Y(16)}, - {PIP_X(id_W818) + 0., HOP4Y(16), PIP_X(id_W818) + top_wire_dist + 0., HOP4Y(14)}, - {PIP_X(id_W818) + top_wire_dist + 0., HOP4Y(14), PIP_X(id_W818) + 1., HOP4Y(14)}, - {PIP_X(id_W818) + 1., HOP4Y(14), PIP_X(id_W818) + top_wire_dist + 1., HOP4Y(12)}, - {PIP_X(id_W818) + top_wire_dist + 1., HOP4Y(12), wrap_len + 2., HOP4Y(12)}, - {wrap_len + 2., HOP4Y(12), wrap_len + 2., HOP4Y(13)}, - {wrap_len + 2., HOP4Y(13), PIP_X(id_W810) + 1., HOP4Y(13)}, - {PIP_X(id_W810) + 1., HOP4Y(13), PIP_X(id_W810) - top_wire_dist + 1., HOP4Y(11)}, - {PIP_X(id_W810) - top_wire_dist + 1., HOP4Y(11), PIP_X(id_W810) - 0., HOP4Y(11)}, - {PIP_X(id_W810) - 0., HOP4Y(11), PIP_X(id_W810) - top_wire_dist - 0., HOP4Y(9)}, - {PIP_X(id_W810) - top_wire_dist - 0., HOP4Y(9), PIP_X(id_W810) - 1., HOP4Y(9)}, - {PIP_X(id_W814) - 1., HOP4Y(9), PIP_X(id_W814) - 1., WIRE_Y(0)}, - {PIP_X(id_W810) - 1., HOP4Y(9), PIP_X(id_W810) - top_wire_dist - 1., HOP4Y(7)}, - {PIP_X(id_W810) - top_wire_dist - 1., HOP4Y(7), PIP_X(id_W810) - 2., HOP4Y(7)}, - {PIP_X(id_W810) - 2., HOP4Y(7), PIP_X(id_W810) - top_wire_dist - 2., HOP4Y(5)}, - {PIP_X(id_W810) - top_wire_dist - 2., HOP4Y(5), PIP_X(id_W810) - 3., HOP4Y(5)}, - {PIP_X(id_W810) - 3., HOP4Y(5), PIP_X(id_W810) - top_wire_dist - 3., HOP4Y(3)}, - {PIP_X(id_W810) - top_wire_dist - 3., HOP4Y(3), PIP_X(id_W810) - 4., HOP4Y(3)}, - {PIP_X(id_W810) - 4., HOP4Y(3), PIP_X(id_W810) - top_wire_dist - 4., HOP4Y(1)}, - {PIP_X(id_W810) - top_wire_dist - 4., HOP4Y(1), PIP_X(id_W818) - 5., HOP4Y(1)}, - {PIP_X(id_W818) - 5., HOP4Y(1), PIP_X(id_W818) - 5., WIRE_Y(0)}}}, - {id_E81_loop2, - {{PIP_X(id_E810), WIRE_Y(0), PIP_X(id_E810), HOP4Y(16)}, - {PIP_X(id_E810), HOP4Y(16), PIP_X(id_W818), HOP4Y(16)}, - {PIP_X(id_W818) + 0., HOP4Y(16), PIP_X(id_W818) + top_wire_dist + 0., HOP4Y(14)}, - {PIP_X(id_W818) + top_wire_dist + 0., HOP4Y(14), PIP_X(id_W818) + 1., HOP4Y(14)}, - {PIP_X(id_W818) + 1., HOP4Y(14), PIP_X(id_W818) + top_wire_dist + 1., HOP4Y(12)}, - {PIP_X(id_W818) + top_wire_dist + 1., HOP4Y(12), PIP_X(id_W818) + 2., HOP4Y(12)}, - {PIP_X(id_W818) + 2., HOP4Y(12), PIP_X(id_W818) + top_wire_dist + 2., HOP4Y(10)}, - {PIP_X(id_W818) + top_wire_dist + 2., HOP4Y(10), wrap_len + 3., HOP4Y(10)}, - {wrap_len + 3., HOP4Y(10), wrap_len + 3., HOP4Y(11)}, - {wrap_len + 3., HOP4Y(11), PIP_X(id_W810) + 2., HOP4Y(11)}, - {PIP_X(id_W810) + 2., HOP4Y(11), PIP_X(id_W810) - top_wire_dist + 2., HOP4Y(9)}, - {PIP_X(id_W810) - top_wire_dist + 2., HOP4Y(9), PIP_X(id_W810) + 1., HOP4Y(9)}, - {PIP_X(id_W814) + 1., HOP4Y(9), PIP_X(id_W814) + 1., WIRE_Y(0)}, - {PIP_X(id_W810) + 1., HOP4Y(9), PIP_X(id_W810) - top_wire_dist + 1., HOP4Y(7)}, - {PIP_X(id_W810) - top_wire_dist + 1., HOP4Y(7), PIP_X(id_W810) + 0., HOP4Y(7)}, - {PIP_X(id_W810) + 0., HOP4Y(7), PIP_X(id_W810) - top_wire_dist - 0., HOP4Y(5)}, - {PIP_X(id_W810) - top_wire_dist - 0., HOP4Y(5), PIP_X(id_W810) - 1., HOP4Y(5)}, - {PIP_X(id_W810) - 1., HOP4Y(5), PIP_X(id_W810) - top_wire_dist - 1., HOP4Y(3)}, - {PIP_X(id_W810) - top_wire_dist - 1., HOP4Y(3), PIP_X(id_W810) - 2., HOP4Y(3)}, - {PIP_X(id_W810) - 2., HOP4Y(3), PIP_X(id_W810) - top_wire_dist - 2., HOP4Y(1)}, - {PIP_X(id_W810) - top_wire_dist - 2., HOP4Y(1), PIP_X(id_W818) - 3., HOP4Y(1)}, - {PIP_X(id_W818) - 3., HOP4Y(1), PIP_X(id_W818) - 3., WIRE_Y(0)}}}, - {id_E81_loop3, - {{PIP_X(id_E810), WIRE_Y(0), PIP_X(id_E810), HOP4Y(16)}, - {PIP_X(id_E810), HOP4Y(16), PIP_X(id_W818), HOP4Y(16)}, - {PIP_X(id_W818) + 0., HOP4Y(16), PIP_X(id_W818) + top_wire_dist + 0., HOP4Y(14)}, - {PIP_X(id_W818) + top_wire_dist + 0., HOP4Y(14), PIP_X(id_W818) + 1., HOP4Y(14)}, - {PIP_X(id_W818) + 1., HOP4Y(14), PIP_X(id_W818) + top_wire_dist + 1., HOP4Y(12)}, - {PIP_X(id_W818) + top_wire_dist + 1., HOP4Y(12), PIP_X(id_W818) + 2., HOP4Y(12)}, - {PIP_X(id_W818) + 2., HOP4Y(12), PIP_X(id_W818) + top_wire_dist + 2., HOP4Y(10)}, - {PIP_X(id_W818) + top_wire_dist + 2., HOP4Y(10), PIP_X(id_W818) + 3., HOP4Y(10)}, - {PIP_X(id_W818) + 3., HOP4Y(10), PIP_X(id_W818) + top_wire_dist + 3., HOP4Y(8)}, - {PIP_X(id_W818) + top_wire_dist + 3., HOP4Y(8), wrap_len + 4., HOP4Y(8)}, - {wrap_len + 4., HOP4Y(8), wrap_len + 4., HOP4Y(9)}, - {wrap_len + 4., HOP4Y(9), PIP_X(id_W810) + 3., HOP4Y(9)}, - {PIP_X(id_W814) + 3., HOP4Y(9), PIP_X(id_W814) + 3., WIRE_Y(0)}, - {PIP_X(id_W810) + 3., HOP4Y(9), PIP_X(id_W810) - top_wire_dist + 3., HOP4Y(7)}, - {PIP_X(id_W810) - top_wire_dist + 3., HOP4Y(7), PIP_X(id_W810) + 2., HOP4Y(7)}, - {PIP_X(id_W810) + 2., HOP4Y(7), PIP_X(id_W810) - top_wire_dist + 2., HOP4Y(5)}, - {PIP_X(id_W810) - top_wire_dist + 2., HOP4Y(5), PIP_X(id_W810) + 1., HOP4Y(5)}, - {PIP_X(id_W810) + 1., HOP4Y(5), PIP_X(id_W810) - top_wire_dist + 1., HOP4Y(3)}, - {PIP_X(id_W810) - top_wire_dist + 1., HOP4Y(3), PIP_X(id_W810) - 0., HOP4Y(3)}, - {PIP_X(id_W810) - 0., HOP4Y(3), PIP_X(id_W810) - top_wire_dist - 0., HOP4Y(1)}, - {PIP_X(id_W810) - top_wire_dist - 0., HOP4Y(1), PIP_X(id_W818) - 1., HOP4Y(1)}, - {PIP_X(id_W818) - 1., HOP4Y(1), PIP_X(id_W818) - 1., WIRE_Y(0)}}}, - {id_E81_loop4, - {{PIP_X(id_E810), WIRE_Y(0), PIP_X(id_E810), HOP4Y(16)}, - {PIP_X(id_E810), HOP4Y(16), PIP_X(id_W818), HOP4Y(16)}, - {PIP_X(id_W818) + 0., HOP4Y(16), PIP_X(id_W818) + top_wire_dist + 0., HOP4Y(14)}, - {PIP_X(id_W818) + top_wire_dist + 0., HOP4Y(14), PIP_X(id_W818) + 1., HOP4Y(14)}, - {PIP_X(id_W818) + 1., HOP4Y(14), PIP_X(id_W818) + top_wire_dist + 1., HOP4Y(12)}, - {PIP_X(id_W818) + top_wire_dist + 1., HOP4Y(12), PIP_X(id_W818) + 2., HOP4Y(12)}, - {PIP_X(id_W818) + 2., HOP4Y(12), PIP_X(id_W818) + top_wire_dist + 2., HOP4Y(10)}, - {PIP_X(id_W818) + top_wire_dist + 2., HOP4Y(10), PIP_X(id_W818) + 3., HOP4Y(10)}, - {PIP_X(id_W818) + 3., HOP4Y(10), PIP_X(id_W818) + top_wire_dist + 3., HOP4Y(8)}, - {PIP_X(id_W818) + top_wire_dist + 3., HOP4Y(8), PIP_X(id_W818) + 4., HOP4Y(8)}, - {PIP_X(id_E814) + 4., HOP4Y(8), PIP_X(id_E814) + 4., WIRE_Y(0)}, - {PIP_X(id_W818) + 4., HOP4Y(8), PIP_X(id_W818) + top_wire_dist + 4., HOP4Y(6)}, - {PIP_X(id_W818) + top_wire_dist + 4., HOP4Y(6), wrap_len + 5., HOP4Y(6)}, - {wrap_len + 5., HOP4Y(6), wrap_len + 5., HOP4Y(7)}, - {wrap_len + 5., HOP4Y(7), PIP_X(id_W810) + 4., HOP4Y(7)}, - {PIP_X(id_W810) + 4., HOP4Y(7), PIP_X(id_W810) - top_wire_dist + 4., HOP4Y(5)}, - {PIP_X(id_W810) - top_wire_dist + 4., HOP4Y(5), PIP_X(id_W810) + 3., HOP4Y(5)}, - {PIP_X(id_W810) + 3., HOP4Y(5), PIP_X(id_W810) - top_wire_dist + 3., HOP4Y(3)}, - {PIP_X(id_W810) - top_wire_dist + 3., HOP4Y(3), PIP_X(id_W810) + 2., HOP4Y(3)}, - {PIP_X(id_W810) + 2., HOP4Y(3), PIP_X(id_W810) - top_wire_dist + 2., HOP4Y(1)}, - {PIP_X(id_W810) - top_wire_dist + 2., HOP4Y(1), PIP_X(id_W818) + 1., HOP4Y(1)}, - {PIP_X(id_W818) + 1., HOP4Y(1), PIP_X(id_W818) + 1., WIRE_Y(0)}}}, - {id_E81_loop5, - {{PIP_X(id_E810), WIRE_Y(0), PIP_X(id_E810), HOP4Y(16)}, - {PIP_X(id_E810), HOP4Y(16), PIP_X(id_W818), HOP4Y(16)}, - {PIP_X(id_W818) + 0., HOP4Y(16), PIP_X(id_W818) + top_wire_dist + 0., HOP4Y(14)}, - {PIP_X(id_W818) + top_wire_dist + 0., HOP4Y(14), PIP_X(id_W818) + 1., HOP4Y(14)}, - {PIP_X(id_W818) + 1., HOP4Y(14), PIP_X(id_W818) + top_wire_dist + 1., HOP4Y(12)}, - {PIP_X(id_W818) + top_wire_dist + 1., HOP4Y(12), PIP_X(id_W818) + 2., HOP4Y(12)}, - {PIP_X(id_W818) + 2., HOP4Y(12), PIP_X(id_W818) + top_wire_dist + 2., HOP4Y(10)}, - {PIP_X(id_W818) + top_wire_dist + 2., HOP4Y(10), PIP_X(id_W818) + 3., HOP4Y(10)}, - {PIP_X(id_W818) + 3., HOP4Y(10), PIP_X(id_W818) + top_wire_dist + 3., HOP4Y(8)}, - {PIP_X(id_W818) + top_wire_dist + 3., HOP4Y(8), PIP_X(id_W818) + 4., HOP4Y(8)}, - {PIP_X(id_E814) + 4., HOP4Y(8), PIP_X(id_E814) + 4., WIRE_Y(0)}, - {PIP_X(id_W818) + 4., HOP4Y(8), PIP_X(id_W818) + top_wire_dist + 4., HOP4Y(6)}, - {PIP_X(id_W818) + top_wire_dist + 4., HOP4Y(6), PIP_X(id_W818) + 5., HOP4Y(6)}, - {PIP_X(id_W818) + 5., HOP4Y(6), PIP_X(id_W818) + top_wire_dist + 5., HOP4Y(4)}, - {PIP_X(id_W818) + top_wire_dist + 5., HOP4Y(4), wrap_len + 6., HOP4Y(4)}, - {wrap_len + 6., HOP4Y(4), wrap_len + 6., HOP4Y(5)}, - {wrap_len + 6., HOP4Y(5), PIP_X(id_W810) + 5., HOP4Y(5)}, - {PIP_X(id_W810) + 5., HOP4Y(5), PIP_X(id_W810) - top_wire_dist + 5., HOP4Y(3)}, - {PIP_X(id_W810) - top_wire_dist + 5., HOP4Y(3), PIP_X(id_W810) + 4., HOP4Y(3)}, - {PIP_X(id_W810) + 4., HOP4Y(3), PIP_X(id_W810) - top_wire_dist + 4., HOP4Y(1)}, - {PIP_X(id_W810) - top_wire_dist + 4., HOP4Y(1), PIP_X(id_W818) + 3., HOP4Y(1)}, - {PIP_X(id_W818) + 3., HOP4Y(1), PIP_X(id_W818) + 3., WIRE_Y(0)}}}, - {id_E81_loop6, - {{PIP_X(id_E810), WIRE_Y(0), PIP_X(id_E810), HOP4Y(16)}, - {PIP_X(id_E810), HOP4Y(16), PIP_X(id_W818), HOP4Y(16)}, - {PIP_X(id_W818) + 0., HOP4Y(16), PIP_X(id_W818) + top_wire_dist + 0., HOP4Y(14)}, - {PIP_X(id_W818) + top_wire_dist + 0., HOP4Y(14), PIP_X(id_W818) + 1., HOP4Y(14)}, - {PIP_X(id_W818) + 1., HOP4Y(14), PIP_X(id_W818) + top_wire_dist + 1., HOP4Y(12)}, - {PIP_X(id_W818) + top_wire_dist + 1., HOP4Y(12), PIP_X(id_W818) + 2., HOP4Y(12)}, - {PIP_X(id_W818) + 2., HOP4Y(12), PIP_X(id_W818) + top_wire_dist + 2., HOP4Y(10)}, - {PIP_X(id_W818) + top_wire_dist + 2., HOP4Y(10), PIP_X(id_W818) + 3., HOP4Y(10)}, - {PIP_X(id_W818) + 3., HOP4Y(10), PIP_X(id_W818) + top_wire_dist + 3., HOP4Y(8)}, - {PIP_X(id_W818) + top_wire_dist + 3., HOP4Y(8), PIP_X(id_W818) + 4., HOP4Y(8)}, - {PIP_X(id_W818) + 4., HOP4Y(8), PIP_X(id_W818) + top_wire_dist + 4., HOP4Y(6)}, - {PIP_X(id_E814) + 4., HOP4Y(8), PIP_X(id_E814) + 4., WIRE_Y(0)}, - {PIP_X(id_W818) + top_wire_dist + 4., HOP4Y(6), PIP_X(id_W818) + 5., HOP4Y(6)}, - {PIP_X(id_W818) + 5., HOP4Y(6), PIP_X(id_W818) + top_wire_dist + 5., HOP4Y(4)}, - {PIP_X(id_W818) + top_wire_dist + 5., HOP4Y(4), PIP_X(id_W818) + 6., HOP4Y(4)}, - {PIP_X(id_W818) + 6., HOP4Y(4), PIP_X(id_W818) + top_wire_dist + 6., HOP4Y(2)}, - {PIP_X(id_W818) + top_wire_dist + 6., HOP4Y(2), wrap_len + 7., HOP4Y(2)}, - {wrap_len + 7., HOP4Y(2), wrap_len + 7., HOP4Y(3)}, - {wrap_len + 7., HOP4Y(3), PIP_X(id_W810) + 6., HOP4Y(3)}, - {PIP_X(id_W810) + 6., HOP4Y(3), PIP_X(id_W810) - top_wire_dist + 6., HOP4Y(1)}, - {PIP_X(id_W810) - top_wire_dist + 6., HOP4Y(1), PIP_X(id_W818) + 5., HOP4Y(1)}, - {PIP_X(id_W818) + 5., HOP4Y(1), PIP_X(id_W818) + 5., WIRE_Y(0)}}}, - {id_E81_loop7, - {{PIP_X(id_E810), WIRE_Y(0), PIP_X(id_E810), HOP4Y(16)}, - {PIP_X(id_E810), HOP4Y(16), PIP_X(id_W818), HOP4Y(16)}, - {PIP_X(id_W818) + 0., HOP4Y(16), PIP_X(id_W818) + top_wire_dist + 0., HOP4Y(14)}, - {PIP_X(id_W818) + top_wire_dist + 0., HOP4Y(14), PIP_X(id_W818) + 1., HOP4Y(14)}, - {PIP_X(id_W818) + 1., HOP4Y(14), PIP_X(id_W818) + top_wire_dist + 1., HOP4Y(12)}, - {PIP_X(id_W818) + top_wire_dist + 1., HOP4Y(12), PIP_X(id_W818) + 2., HOP4Y(12)}, - {PIP_X(id_W818) + 2., HOP4Y(12), PIP_X(id_W818) + top_wire_dist + 2., HOP4Y(10)}, - {PIP_X(id_W818) + top_wire_dist + 2., HOP4Y(10), PIP_X(id_W818) + 3., HOP4Y(10)}, - {PIP_X(id_W818) + 3., HOP4Y(10), PIP_X(id_W818) + top_wire_dist + 3., HOP4Y(8)}, - {PIP_X(id_W818) + top_wire_dist + 3., HOP4Y(8), PIP_X(id_W818) + 4., HOP4Y(8)}, - {PIP_X(id_W818) + 4., HOP4Y(8), PIP_X(id_W818) + top_wire_dist + 4., HOP4Y(6)}, - {PIP_X(id_E814) + 4., HOP4Y(8), PIP_X(id_E814) + 4., WIRE_Y(0)}, - {PIP_X(id_W818) + top_wire_dist + 4., HOP4Y(6), PIP_X(id_W818) + 5., HOP4Y(6)}, - {PIP_X(id_W818) + 5., HOP4Y(6), PIP_X(id_W818) + top_wire_dist + 5., HOP4Y(4)}, - {PIP_X(id_W818) + top_wire_dist + 5., HOP4Y(4), PIP_X(id_W818) + 6., HOP4Y(4)}, - {PIP_X(id_W818) + 6., HOP4Y(4), PIP_X(id_W818) + top_wire_dist + 6., HOP4Y(2)}, - {PIP_X(id_W818) + top_wire_dist + 6., HOP4Y(2), PIP_X(id_W818) + 7., HOP4Y(2)}, - {PIP_X(id_W818) + 7., HOP4Y(2), PIP_X(id_W818) + top_wire_dist + 7., HOP4Y(0)}, - {PIP_X(id_W818) + top_wire_dist + 7., HOP4Y(0), wrap_len + 8., HOP4Y(0)}, - {wrap_len + 8., HOP4Y(0), wrap_len + 8., HOP4Y(1)}, - {wrap_len + 8., HOP4Y(1), PIP_X(id_W818) + 7., HOP4Y(1)}, - {PIP_X(id_W818) + 7., HOP4Y(1), PIP_X(id_W818) + 7., WIRE_Y(0)}}}, - {id_W81_loop0, - {{PIP_X(id_W810), WIRE_Y(0), PIP_X(id_W810), HOP4Y(17)}, - {PIP_X(id_W810) - 0., HOP4Y(17), PIP_X(id_W810) - top_wire_dist - 0., HOP4Y(15)}, - {PIP_X(id_W810) - top_wire_dist - 0., HOP4Y(15), -wrap_len - 0., HOP4Y(15)}, - {-wrap_len - 0., HOP4Y(15), -wrap_len - 0., HOP4Y(14)}, - {-wrap_len - 0., HOP4Y(14), PIP_X(id_W818) + 0., HOP4Y(14)}, - {PIP_X(id_W818) + 0., HOP4Y(14), PIP_X(id_W818) + top_wire_dist + 0., HOP4Y(12)}, - {PIP_X(id_W818) + top_wire_dist + 0., HOP4Y(12), PIP_X(id_W818) + 1., HOP4Y(12)}, - {PIP_X(id_W818) + 1., HOP4Y(12), PIP_X(id_W818) + top_wire_dist + 1., HOP4Y(10)}, - {PIP_X(id_W818) + top_wire_dist + 1., HOP4Y(10), PIP_X(id_W818) + 2., HOP4Y(10)}, - {PIP_X(id_W818) + 2., HOP4Y(10), PIP_X(id_W818) + top_wire_dist + 2., HOP4Y(8)}, - {PIP_X(id_W818) + top_wire_dist + 2., HOP4Y(8), PIP_X(id_W818) + 3., HOP4Y(8)}, - {PIP_X(id_W818) + 3., HOP4Y(8), PIP_X(id_W818) + top_wire_dist + 3., HOP4Y(6)}, - {PIP_X(id_E814) + 3., HOP4Y(8), PIP_X(id_E814) + 3., WIRE_Y(0)}, - {PIP_X(id_W818) + top_wire_dist + 3., HOP4Y(6), PIP_X(id_W818) + 4., HOP4Y(6)}, - {PIP_X(id_W818) + 4., HOP4Y(6), PIP_X(id_W818) + top_wire_dist + 4., HOP4Y(4)}, - {PIP_X(id_W818) + top_wire_dist + 4., HOP4Y(4), PIP_X(id_W818) + 5., HOP4Y(4)}, - {PIP_X(id_W818) + 5., HOP4Y(4), PIP_X(id_W818) + top_wire_dist + 5., HOP4Y(2)}, - {PIP_X(id_W818) + top_wire_dist + 5., HOP4Y(2), PIP_X(id_W818) + 6., HOP4Y(2)}, - {PIP_X(id_W818) + 6., HOP4Y(2), PIP_X(id_W818) + top_wire_dist + 6., HOP4Y(0)}, - {PIP_X(id_W818) + top_wire_dist + 6., HOP4Y(0), PIP_X(id_E818) + 7., HOP4Y(0)}, - {PIP_X(id_E818) + 7., HOP4Y(0), PIP_X(id_E818) + 7., WIRE_Y(0)}}}, - {id_W81_loop1, - {{PIP_X(id_W810), WIRE_Y(0), PIP_X(id_W810), HOP4Y(17)}, - {PIP_X(id_W810) - 0., HOP4Y(17), PIP_X(id_W810) - top_wire_dist - 0., HOP4Y(15)}, - {PIP_X(id_W810) - top_wire_dist - 0., HOP4Y(15), PIP_X(id_W810) - 1., HOP4Y(15)}, - {PIP_X(id_W810) - 1., HOP4Y(15), PIP_X(id_W810) - top_wire_dist - 1., HOP4Y(13)}, - {PIP_X(id_W810) - top_wire_dist - 1., HOP4Y(13), -wrap_len - 1., HOP4Y(13)}, - {-wrap_len - 1., HOP4Y(13), -wrap_len - 1., HOP4Y(12)}, - {-wrap_len - 1., HOP4Y(12), PIP_X(id_W818) - 1., HOP4Y(12)}, - {PIP_X(id_W818) - 1., HOP4Y(12), PIP_X(id_W818) + top_wire_dist - 1., HOP4Y(10)}, - {PIP_X(id_W818) + top_wire_dist - 1., HOP4Y(10), PIP_X(id_W818) + 0., HOP4Y(10)}, - {PIP_X(id_W818) + 0., HOP4Y(10), PIP_X(id_W818) + top_wire_dist + 0., HOP4Y(8)}, - {PIP_X(id_W818) + top_wire_dist + 0., HOP4Y(8), PIP_X(id_W818) + 1., HOP4Y(8)}, - {PIP_X(id_W818) + 1., HOP4Y(8), PIP_X(id_W818) + top_wire_dist + 1., HOP4Y(6)}, - {PIP_X(id_E814) + 1., HOP4Y(8), PIP_X(id_E814) + 1., WIRE_Y(0)}, - {PIP_X(id_W818) + top_wire_dist + 1., HOP4Y(6), PIP_X(id_W818) + 2., HOP4Y(6)}, - {PIP_X(id_W818) + 2., HOP4Y(6), PIP_X(id_W818) + top_wire_dist + 2., HOP4Y(4)}, - {PIP_X(id_W818) + top_wire_dist + 2., HOP4Y(4), PIP_X(id_W818) + 3., HOP4Y(4)}, - {PIP_X(id_W818) + 3., HOP4Y(4), PIP_X(id_W818) + top_wire_dist + 3., HOP4Y(2)}, - {PIP_X(id_W818) + top_wire_dist + 3., HOP4Y(2), PIP_X(id_W818) + 4., HOP4Y(2)}, - {PIP_X(id_W818) + 4., HOP4Y(2), PIP_X(id_W818) + top_wire_dist + 4., HOP4Y(0)}, - {PIP_X(id_W818) + top_wire_dist + 4., HOP4Y(0), PIP_X(id_E818) + 5., HOP4Y(0)}, - {PIP_X(id_E818) + 5., HOP4Y(0), PIP_X(id_E818) + 5., WIRE_Y(0)}}}, - {id_W81_loop2, - {{PIP_X(id_W810), WIRE_Y(0), PIP_X(id_W810), HOP4Y(17)}, - {PIP_X(id_W810) - 0., HOP4Y(17), PIP_X(id_W810) - top_wire_dist - 0., HOP4Y(15)}, - {PIP_X(id_W810) - top_wire_dist - 0., HOP4Y(15), PIP_X(id_W810) - 1., HOP4Y(15)}, - {PIP_X(id_W810) - 1., HOP4Y(15), PIP_X(id_W810) - top_wire_dist - 1., HOP4Y(13)}, - {PIP_X(id_W810) - top_wire_dist - 1., HOP4Y(13), PIP_X(id_W810) - 2., HOP4Y(13)}, - {PIP_X(id_W810) - 2., HOP4Y(13), PIP_X(id_W810) - top_wire_dist - 2., HOP4Y(11)}, - {PIP_X(id_W810) - top_wire_dist - 2., HOP4Y(11), -wrap_len - 2., HOP4Y(11)}, - {-wrap_len - 2., HOP4Y(11), -wrap_len - 2., HOP4Y(10)}, - {-wrap_len - 2., HOP4Y(10), PIP_X(id_W818) - 2., HOP4Y(10)}, - {PIP_X(id_W818) - 2., HOP4Y(10), PIP_X(id_W818) + top_wire_dist - 2., HOP4Y(8)}, - {PIP_X(id_W818) + top_wire_dist - 2., HOP4Y(8), PIP_X(id_W818) - 1., HOP4Y(8)}, - {PIP_X(id_W818) - 1., HOP4Y(8), PIP_X(id_W818) + top_wire_dist - 1., HOP4Y(6)}, - {PIP_X(id_E814) - 1., HOP4Y(8), PIP_X(id_E814) - 1., WIRE_Y(0)}, - {PIP_X(id_W818) + top_wire_dist - 1., HOP4Y(6), PIP_X(id_W818) + 0., HOP4Y(6)}, - {PIP_X(id_W818) + 0., HOP4Y(6), PIP_X(id_W818) + top_wire_dist + 0., HOP4Y(4)}, - {PIP_X(id_W818) + top_wire_dist + 0., HOP4Y(4), PIP_X(id_W818) + 1., HOP4Y(4)}, - {PIP_X(id_W818) + 1., HOP4Y(4), PIP_X(id_W818) + top_wire_dist + 1., HOP4Y(2)}, - {PIP_X(id_W818) + top_wire_dist + 1., HOP4Y(2), PIP_X(id_W818) + 2., HOP4Y(2)}, - {PIP_X(id_W818) + 2., HOP4Y(2), PIP_X(id_W818) + top_wire_dist + 2., HOP4Y(0)}, - {PIP_X(id_W818) + top_wire_dist + 2., HOP4Y(0), PIP_X(id_E818) + 3., HOP4Y(0)}, - {PIP_X(id_E818) + 3., HOP4Y(0), PIP_X(id_E818) + 3., WIRE_Y(0)}}}, - {id_W81_loop3, - {{PIP_X(id_W810), WIRE_Y(0), PIP_X(id_W810), HOP4Y(17)}, - {PIP_X(id_W810) - 0., HOP4Y(17), PIP_X(id_W810) - top_wire_dist - 0., HOP4Y(15)}, - {PIP_X(id_W810) - top_wire_dist - 0., HOP4Y(15), PIP_X(id_W810) - 1., HOP4Y(15)}, - {PIP_X(id_W810) - 1., HOP4Y(15), PIP_X(id_W810) - top_wire_dist - 1., HOP4Y(13)}, - {PIP_X(id_W810) - top_wire_dist - 1., HOP4Y(13), PIP_X(id_W810) - 2., HOP4Y(13)}, - {PIP_X(id_W810) - 2., HOP4Y(13), PIP_X(id_W810) - top_wire_dist - 2., HOP4Y(11)}, - {PIP_X(id_W810) - top_wire_dist - 2., HOP4Y(11), PIP_X(id_W810) - 3., HOP4Y(11)}, - {PIP_X(id_W810) - 3., HOP4Y(11), PIP_X(id_W810) - top_wire_dist - 3., HOP4Y(9)}, - {PIP_X(id_W810) - top_wire_dist - 3., HOP4Y(9), -wrap_len - 3., HOP4Y(9)}, - {-wrap_len - 3., HOP4Y(9), -wrap_len - 3., HOP4Y(8)}, - {-wrap_len - 3., HOP4Y(8), PIP_X(id_W818) - 3., HOP4Y(8)}, - {PIP_X(id_W818) - 3., HOP4Y(8), PIP_X(id_W818) + top_wire_dist - 3., HOP4Y(6)}, - {PIP_X(id_E814) - 3., HOP4Y(8), PIP_X(id_E814) - 3., WIRE_Y(0)}, - {PIP_X(id_W818) + top_wire_dist - 3., HOP4Y(6), PIP_X(id_W818) - 2., HOP4Y(6)}, - {PIP_X(id_W818) - 2., HOP4Y(6), PIP_X(id_W818) + top_wire_dist - 2., HOP4Y(4)}, - {PIP_X(id_W818) + top_wire_dist - 2., HOP4Y(4), PIP_X(id_W818) - 1., HOP4Y(4)}, - {PIP_X(id_W818) - 1., HOP4Y(4), PIP_X(id_W818) + top_wire_dist - 1., HOP4Y(2)}, - {PIP_X(id_W818) + top_wire_dist - 1., HOP4Y(2), PIP_X(id_W818) + 0., HOP4Y(2)}, - {PIP_X(id_W818) + 0., HOP4Y(2), PIP_X(id_W818) + top_wire_dist + 0., HOP4Y(0)}, - {PIP_X(id_W818) + top_wire_dist + 0., HOP4Y(0), PIP_X(id_E818) + 1., HOP4Y(0)}, - {PIP_X(id_E818) + 1., HOP4Y(0), PIP_X(id_E818) + 1., WIRE_Y(0)}}}, - {id_W81_loop4, - {{PIP_X(id_W810), WIRE_Y(0), PIP_X(id_W810), HOP4Y(17)}, - {PIP_X(id_W810) - 0., HOP4Y(17), PIP_X(id_W810) - top_wire_dist - 0., HOP4Y(15)}, - {PIP_X(id_W810) - top_wire_dist - 0., HOP4Y(15), PIP_X(id_W810) - 1., HOP4Y(15)}, - {PIP_X(id_W810) - 1., HOP4Y(15), PIP_X(id_W810) - top_wire_dist - 1., HOP4Y(13)}, - {PIP_X(id_W810) - top_wire_dist - 1., HOP4Y(13), PIP_X(id_W810) - 2., HOP4Y(13)}, - {PIP_X(id_W810) - 2., HOP4Y(13), PIP_X(id_W810) - top_wire_dist - 2., HOP4Y(11)}, - {PIP_X(id_W810) - top_wire_dist - 2., HOP4Y(11), PIP_X(id_W810) - 3., HOP4Y(11)}, - {PIP_X(id_W810) - 3., HOP4Y(11), PIP_X(id_W810) - top_wire_dist - 3., HOP4Y(9)}, - {PIP_X(id_W810) - top_wire_dist - 3., HOP4Y(9), PIP_X(id_W810) - 4., HOP4Y(9)}, - {PIP_X(id_W810) - 4., HOP4Y(9), PIP_X(id_W810) - top_wire_dist - 4., HOP4Y(7)}, - {PIP_X(id_W810) - top_wire_dist - 4., HOP4Y(7), -wrap_len - 4., HOP4Y(7)}, - {-wrap_len - 4., HOP4Y(7), -wrap_len - 4., HOP4Y(6)}, - {PIP_X(id_W814) - 4., HOP4Y(6), PIP_X(id_W814) - 4., WIRE_Y(0)}, - {-wrap_len - 4., HOP4Y(6), PIP_X(id_W818) - 4., HOP4Y(6)}, - {PIP_X(id_W818) - 4., HOP4Y(6), PIP_X(id_W818) + top_wire_dist - 4., HOP4Y(4)}, - {PIP_X(id_W818) + top_wire_dist - 4., HOP4Y(4), PIP_X(id_W818) - 3., HOP4Y(4)}, - {PIP_X(id_W818) - 3., HOP4Y(4), PIP_X(id_W818) + top_wire_dist - 3., HOP4Y(2)}, - {PIP_X(id_W818) + top_wire_dist - 3., HOP4Y(2), PIP_X(id_W818) - 2., HOP4Y(2)}, - {PIP_X(id_W818) - 2., HOP4Y(2), PIP_X(id_W818) + top_wire_dist - 2., HOP4Y(0)}, - {PIP_X(id_W818) + top_wire_dist - 2., HOP4Y(0), PIP_X(id_E818) - 1., HOP4Y(0)}, - {PIP_X(id_E818) - 1., HOP4Y(0), PIP_X(id_E818) - 1., WIRE_Y(0)}}}, - {id_W81_loop5, - {{PIP_X(id_W810), WIRE_Y(0), PIP_X(id_W810), HOP4Y(17)}, - {PIP_X(id_W810) - 0., HOP4Y(17), PIP_X(id_W810) - top_wire_dist - 0., HOP4Y(15)}, - {PIP_X(id_W810) - top_wire_dist - 0., HOP4Y(15), PIP_X(id_W810) - 1., HOP4Y(15)}, - {PIP_X(id_W810) - 1., HOP4Y(15), PIP_X(id_W810) - top_wire_dist - 1., HOP4Y(13)}, - {PIP_X(id_W810) - top_wire_dist - 1., HOP4Y(13), PIP_X(id_W810) - 2., HOP4Y(13)}, - {PIP_X(id_W810) - 2., HOP4Y(13), PIP_X(id_W810) - top_wire_dist - 2., HOP4Y(11)}, - {PIP_X(id_W810) - top_wire_dist - 2., HOP4Y(11), PIP_X(id_W810) - 3., HOP4Y(11)}, - {PIP_X(id_W810) - 3., HOP4Y(11), PIP_X(id_W810) - top_wire_dist - 3., HOP4Y(9)}, - {PIP_X(id_W810) - top_wire_dist - 3., HOP4Y(9), PIP_X(id_W810) - 4., HOP4Y(9)}, - {PIP_X(id_W810) - 4., HOP4Y(9), PIP_X(id_W810) - top_wire_dist - 4., HOP4Y(7)}, - {PIP_X(id_W814) - 4., HOP4Y(9), PIP_X(id_W814) - 4., WIRE_Y(0)}, - {PIP_X(id_W810) - top_wire_dist - 4., HOP4Y(7), PIP_X(id_W810) - 5., HOP4Y(7)}, - {PIP_X(id_W810) - 5., HOP4Y(7), PIP_X(id_W810) - top_wire_dist - 5., HOP4Y(5)}, - {PIP_X(id_W810) - top_wire_dist - 5., HOP4Y(5), -wrap_len - 5., HOP4Y(5)}, - {-wrap_len - 5., HOP4Y(5), -wrap_len - 5., HOP4Y(4)}, - {-wrap_len - 5., HOP4Y(4), PIP_X(id_W818) - 5., HOP4Y(4)}, - {PIP_X(id_W818) - 5., HOP4Y(4), PIP_X(id_W818) + top_wire_dist - 5., HOP4Y(2)}, - {PIP_X(id_W818) + top_wire_dist - 5., HOP4Y(2), PIP_X(id_W818) - 4., HOP4Y(2)}, - {PIP_X(id_W818) - 4., HOP4Y(2), PIP_X(id_W818) + top_wire_dist - 4., HOP4Y(0)}, - {PIP_X(id_W818) + top_wire_dist - 4., HOP4Y(0), PIP_X(id_E818) - 3., HOP4Y(0)}, - {PIP_X(id_E818) - 3., HOP4Y(0), PIP_X(id_E818) - 3., WIRE_Y(0)}}}, - {id_W81_loop6, - {{PIP_X(id_W810), WIRE_Y(0), PIP_X(id_W810), HOP4Y(17)}, - {PIP_X(id_W810) - 0., HOP4Y(17), PIP_X(id_W810) - top_wire_dist - 0., HOP4Y(15)}, - {PIP_X(id_W810) - top_wire_dist - 0., HOP4Y(15), PIP_X(id_W810) - 1., HOP4Y(15)}, - {PIP_X(id_W810) - 1., HOP4Y(15), PIP_X(id_W810) - top_wire_dist - 1., HOP4Y(13)}, - {PIP_X(id_W810) - top_wire_dist - 1., HOP4Y(13), PIP_X(id_W810) - 2., HOP4Y(13)}, - {PIP_X(id_W810) - 2., HOP4Y(13), PIP_X(id_W810) - top_wire_dist - 2., HOP4Y(11)}, - {PIP_X(id_W810) - top_wire_dist - 2., HOP4Y(11), PIP_X(id_W810) - 3., HOP4Y(11)}, - {PIP_X(id_W810) - 3., HOP4Y(11), PIP_X(id_W810) - top_wire_dist - 3., HOP4Y(9)}, - {PIP_X(id_W810) - top_wire_dist - 3., HOP4Y(9), PIP_X(id_W810) - 4., HOP4Y(9)}, - {PIP_X(id_W810) - 4., HOP4Y(9), PIP_X(id_W810) - top_wire_dist - 4., HOP4Y(7)}, - {PIP_X(id_W814) - 4., HOP4Y(9), PIP_X(id_W814) - 4., WIRE_Y(0)}, - {PIP_X(id_W810) - top_wire_dist - 4., HOP4Y(7), PIP_X(id_W810) - 5., HOP4Y(7)}, - {PIP_X(id_W810) - 5., HOP4Y(7), PIP_X(id_W810) - top_wire_dist - 5., HOP4Y(5)}, - {PIP_X(id_W810) - top_wire_dist - 5., HOP4Y(5), PIP_X(id_W810) - 6., HOP4Y(5)}, - {PIP_X(id_W810) - 6., HOP4Y(5), PIP_X(id_W810) - top_wire_dist - 6., HOP4Y(3)}, - {PIP_X(id_W810) - top_wire_dist - 6., HOP4Y(3), -wrap_len - 6., HOP4Y(3)}, - {-wrap_len - 6., HOP4Y(3), -wrap_len - 6., HOP4Y(2)}, - {-wrap_len - 6., HOP4Y(2), PIP_X(id_W818) - 6., HOP4Y(2)}, - {PIP_X(id_W818) - 6., HOP4Y(2), PIP_X(id_W818) + top_wire_dist - 6., HOP4Y(0)}, - {PIP_X(id_W818) + top_wire_dist - 6., HOP4Y(0), PIP_X(id_E818) - 5., HOP4Y(0)}, - {PIP_X(id_E818) - 5., HOP4Y(0), PIP_X(id_E818) - 5., WIRE_Y(0)}}}, - {id_W81_loop7, - {{PIP_X(id_W810), WIRE_Y(0), PIP_X(id_W810), HOP4Y(17)}, - {PIP_X(id_W810) - 0., HOP4Y(17), PIP_X(id_W810) - top_wire_dist - 0., HOP4Y(15)}, - {PIP_X(id_W810) - top_wire_dist - 0., HOP4Y(15), PIP_X(id_W810) - 1., HOP4Y(15)}, - {PIP_X(id_W810) - 1., HOP4Y(15), PIP_X(id_W810) - top_wire_dist - 1., HOP4Y(13)}, - {PIP_X(id_W810) - top_wire_dist - 1., HOP4Y(13), PIP_X(id_W810) - 2., HOP4Y(13)}, - {PIP_X(id_W810) - 2., HOP4Y(13), PIP_X(id_W810) - top_wire_dist - 2., HOP4Y(11)}, - {PIP_X(id_W810) - top_wire_dist - 2., HOP4Y(11), PIP_X(id_W810) - 3., HOP4Y(11)}, - {PIP_X(id_W810) - 3., HOP4Y(11), PIP_X(id_W810) - top_wire_dist - 3., HOP4Y(9)}, - {PIP_X(id_W810) - top_wire_dist - 3., HOP4Y(9), PIP_X(id_W810) - 4., HOP4Y(9)}, - {PIP_X(id_W810) - 4., HOP4Y(9), PIP_X(id_W810) - top_wire_dist - 4., HOP4Y(7)}, - {PIP_X(id_W814) - 4., HOP4Y(9), PIP_X(id_W814) - 4., WIRE_Y(0)}, - {PIP_X(id_W810) - top_wire_dist - 4., HOP4Y(7), PIP_X(id_W810) - 5., HOP4Y(7)}, - {PIP_X(id_W810) - 5., HOP4Y(7), PIP_X(id_W810) - top_wire_dist - 5., HOP4Y(5)}, - {PIP_X(id_W810) - top_wire_dist - 5., HOP4Y(5), PIP_X(id_W810) - 6., HOP4Y(5)}, - {PIP_X(id_W810) - 6., HOP4Y(5), PIP_X(id_W810) - top_wire_dist - 6., HOP4Y(3)}, - {PIP_X(id_W810) - top_wire_dist - 6., HOP4Y(3), PIP_X(id_W810) - 7., HOP4Y(3)}, - {PIP_X(id_W810) - 7., HOP4Y(3), PIP_X(id_W810) - top_wire_dist - 7., HOP4Y(1)}, - {PIP_X(id_W810) - top_wire_dist - 7., HOP4Y(1), -wrap_len - 7., HOP4Y(1)}, - {-wrap_len - 7., HOP4Y(1), -wrap_len - 7., HOP4Y(0)}, - {-wrap_len - 7., HOP4Y(0), PIP_X(id_E818) - 7., HOP4Y(0)}, - {PIP_X(id_E818) - 7., HOP4Y(0), PIP_X(id_E818) - 7., WIRE_Y(0)}}}, - -#undef HOP4Y -#define HOP4Y(offset) WIRE_Y((float)offset + HOP4Y_START + 18.f + 18.f) - {id_E82, - {{PIP_X(id_E820), WIRE_Y(0), PIP_X(id_E820), HOP4Y(16)}, - {PIP_X(id_E820), HOP4Y(16), PIP_X(id_W828), HOP4Y(16)}, - {PIP_X(id_W828) + 0., HOP4Y(16), PIP_X(id_W828) + top_wire_dist + 0., HOP4Y(14)}, - {PIP_X(id_W828) + top_wire_dist + 0., HOP4Y(14), PIP_X(id_W828) + 1., HOP4Y(14)}, - {PIP_X(id_W828) + 1., HOP4Y(14), PIP_X(id_W828) + top_wire_dist + 1., HOP4Y(12)}, - {PIP_X(id_W828) + top_wire_dist + 1., HOP4Y(12), PIP_X(id_W828) + 2., HOP4Y(12)}, - {PIP_X(id_W828) + 2., HOP4Y(12), PIP_X(id_W828) + top_wire_dist + 2., HOP4Y(10)}, - {PIP_X(id_W828) + top_wire_dist + 2., HOP4Y(10), PIP_X(id_W828) + 3., HOP4Y(10)}, - {PIP_X(id_W828) + 3., HOP4Y(10), PIP_X(id_W828) + top_wire_dist + 3., HOP4Y(8)}, - {PIP_X(id_W828) + top_wire_dist + 3., HOP4Y(8), PIP_X(id_W828) + 4., HOP4Y(8)}, - {PIP_X(id_W828) + 4., HOP4Y(8), PIP_X(id_W828) + top_wire_dist + 4., HOP4Y(6)}, - {PIP_X(id_E824) + 4., HOP4Y(8), PIP_X(id_E824) + 4., WIRE_Y(0)}, - {PIP_X(id_W828) + top_wire_dist + 4., HOP4Y(6), PIP_X(id_W828) + 5., HOP4Y(6)}, - {PIP_X(id_W828) + 5., HOP4Y(6), PIP_X(id_W828) + top_wire_dist + 5., HOP4Y(4)}, - {PIP_X(id_W828) + top_wire_dist + 5., HOP4Y(4), PIP_X(id_W828) + 6., HOP4Y(4)}, - {PIP_X(id_W828) + 6., HOP4Y(4), PIP_X(id_W828) + top_wire_dist + 6., HOP4Y(2)}, - {PIP_X(id_W828) + top_wire_dist + 6., HOP4Y(2), PIP_X(id_W828) + 7., HOP4Y(2)}, - {PIP_X(id_W828) + 7., HOP4Y(2), PIP_X(id_W828) + top_wire_dist + 7., HOP4Y(0)}, - {PIP_X(id_W828) + top_wire_dist + 7., HOP4Y(0), PIP_X(id_E828) + 8., HOP4Y(0)}, - {PIP_X(id_E828) + 8, HOP4Y(0), PIP_X(id_E828) + 8., WIRE_Y(0)}}}, - {id_W82, - {{PIP_X(id_W820), WIRE_Y(0), PIP_X(id_W820), HOP4Y(17)}, - {PIP_X(id_W820) - 0., HOP4Y(17), PIP_X(id_W820) - top_wire_dist - 0., HOP4Y(15)}, - {PIP_X(id_W820) - top_wire_dist - 0., HOP4Y(15), PIP_X(id_W820) - 1., HOP4Y(15)}, - {PIP_X(id_W820) - 1., HOP4Y(15), PIP_X(id_W820) - top_wire_dist - 1., HOP4Y(13)}, - {PIP_X(id_W820) - top_wire_dist - 1., HOP4Y(13), PIP_X(id_W820) - 2., HOP4Y(13)}, - {PIP_X(id_W820) - 2., HOP4Y(13), PIP_X(id_W820) - top_wire_dist - 2., HOP4Y(11)}, - {PIP_X(id_W820) - top_wire_dist - 2., HOP4Y(11), PIP_X(id_W820) - 3., HOP4Y(11)}, - {PIP_X(id_W820) - 3., HOP4Y(11), PIP_X(id_W820) - top_wire_dist - 3., HOP4Y(9)}, - {PIP_X(id_W820) - top_wire_dist - 3., HOP4Y(9), PIP_X(id_W820) - 4., HOP4Y(9)}, - {PIP_X(id_W820) - 4., HOP4Y(9), PIP_X(id_W820) - top_wire_dist - 4., HOP4Y(7)}, - {PIP_X(id_W824) - 4., HOP4Y(9), PIP_X(id_W824) - 4., WIRE_Y(0)}, - {PIP_X(id_W820) - top_wire_dist - 4., HOP4Y(7), PIP_X(id_W820) - 5., HOP4Y(7)}, - {PIP_X(id_W820) - 5., HOP4Y(7), PIP_X(id_W820) - top_wire_dist - 5., HOP4Y(5)}, - {PIP_X(id_W820) - top_wire_dist - 5., HOP4Y(5), PIP_X(id_W820) - 6., HOP4Y(5)}, - {PIP_X(id_W820) - 6., HOP4Y(5), PIP_X(id_W820) - top_wire_dist - 6., HOP4Y(3)}, - {PIP_X(id_W820) - top_wire_dist - 6., HOP4Y(3), PIP_X(id_W820) - 7., HOP4Y(3)}, - {PIP_X(id_W820) - 7., HOP4Y(3), PIP_X(id_W820) - top_wire_dist - 7., HOP4Y(1)}, - {PIP_X(id_W820) - top_wire_dist - 7., HOP4Y(1), PIP_X(id_W828) - 8., HOP4Y(1)}, - {PIP_X(id_W828) - 8, HOP4Y(1), PIP_X(id_W828) - 8., WIRE_Y(0)}}}, - {id_E82_loop0, - {{PIP_X(id_E820), WIRE_Y(0), PIP_X(id_E820), HOP4Y(16)}, - {PIP_X(id_E820), HOP4Y(16), PIP_X(id_W828), HOP4Y(16)}, - {PIP_X(id_W828) + 0., HOP4Y(16), PIP_X(id_W828) + top_wire_dist + 0., HOP4Y(14)}, - {PIP_X(id_W828) + top_wire_dist + 0., HOP4Y(14), wrap_len + 1., HOP4Y(14)}, - {wrap_len + 1., HOP4Y(14), wrap_len + 1., HOP4Y(15)}, - {wrap_len + 1., HOP4Y(15), PIP_X(id_W820) - 0., HOP4Y(15)}, - {PIP_X(id_W820) - 0., HOP4Y(15), PIP_X(id_W820) - top_wire_dist - 0., HOP4Y(13)}, - {PIP_X(id_W820) - top_wire_dist - 0., HOP4Y(13), PIP_X(id_W820) - 1., HOP4Y(13)}, - {PIP_X(id_W820) - 1., HOP4Y(13), PIP_X(id_W820) - top_wire_dist - 1., HOP4Y(11)}, - {PIP_X(id_W820) - top_wire_dist - 1., HOP4Y(11), PIP_X(id_W820) - 2., HOP4Y(11)}, - {PIP_X(id_W820) - 2., HOP4Y(11), PIP_X(id_W820) - top_wire_dist - 2., HOP4Y(9)}, - {PIP_X(id_W820) - top_wire_dist - 2., HOP4Y(9), PIP_X(id_W820) - 3., HOP4Y(9)}, - {PIP_X(id_W820) - 3., HOP4Y(9), PIP_X(id_W820) - top_wire_dist - 3., HOP4Y(7)}, - {PIP_X(id_W824) - 3., HOP4Y(9), PIP_X(id_W824) - 3., WIRE_Y(0)}, - {PIP_X(id_W820) - top_wire_dist - 3., HOP4Y(7), PIP_X(id_W820) - 4., HOP4Y(7)}, - {PIP_X(id_W820) - 4., HOP4Y(7), PIP_X(id_W820) - top_wire_dist - 4., HOP4Y(5)}, - {PIP_X(id_W820) - top_wire_dist - 4., HOP4Y(5), PIP_X(id_W820) - 5., HOP4Y(5)}, - {PIP_X(id_W820) - 5., HOP4Y(5), PIP_X(id_W820) - top_wire_dist - 5., HOP4Y(3)}, - {PIP_X(id_W820) - top_wire_dist - 5., HOP4Y(3), PIP_X(id_W820) - 6., HOP4Y(3)}, - {PIP_X(id_W820) - 6., HOP4Y(3), PIP_X(id_W820) - top_wire_dist - 6., HOP4Y(1)}, - {PIP_X(id_W820) - top_wire_dist - 6., HOP4Y(1), PIP_X(id_W828) - 7., HOP4Y(1)}, - {PIP_X(id_W828) - 7, HOP4Y(1), PIP_X(id_W828) - 7., WIRE_Y(0)}}}, - {id_E82_loop1, - {{PIP_X(id_E820), WIRE_Y(0), PIP_X(id_E820), HOP4Y(16)}, - {PIP_X(id_E820), HOP4Y(16), PIP_X(id_W828), HOP4Y(16)}, - {PIP_X(id_W828) + 0., HOP4Y(16), PIP_X(id_W828) + top_wire_dist + 0., HOP4Y(14)}, - {PIP_X(id_W828) + top_wire_dist + 0., HOP4Y(14), PIP_X(id_W828) + 1., HOP4Y(14)}, - {PIP_X(id_W828) + 1., HOP4Y(14), PIP_X(id_W828) + top_wire_dist + 1., HOP4Y(12)}, - {PIP_X(id_W828) + top_wire_dist + 1., HOP4Y(12), wrap_len + 2., HOP4Y(12)}, - {wrap_len + 2., HOP4Y(12), wrap_len + 2., HOP4Y(13)}, - {wrap_len + 2., HOP4Y(13), PIP_X(id_W820) + 1., HOP4Y(13)}, - {PIP_X(id_W820) + 1., HOP4Y(13), PIP_X(id_W820) - top_wire_dist + 1., HOP4Y(11)}, - {PIP_X(id_W820) - top_wire_dist + 1., HOP4Y(11), PIP_X(id_W820) - 0., HOP4Y(11)}, - {PIP_X(id_W820) - 0., HOP4Y(11), PIP_X(id_W820) - top_wire_dist - 0., HOP4Y(9)}, - {PIP_X(id_W820) - top_wire_dist - 0., HOP4Y(9), PIP_X(id_W820) - 1., HOP4Y(9)}, - {PIP_X(id_W824) - 1., HOP4Y(9), PIP_X(id_W824) - 1., WIRE_Y(0)}, - {PIP_X(id_W820) - 1., HOP4Y(9), PIP_X(id_W820) - top_wire_dist - 1., HOP4Y(7)}, - {PIP_X(id_W820) - top_wire_dist - 1., HOP4Y(7), PIP_X(id_W820) - 2., HOP4Y(7)}, - {PIP_X(id_W820) - 2., HOP4Y(7), PIP_X(id_W820) - top_wire_dist - 2., HOP4Y(5)}, - {PIP_X(id_W820) - top_wire_dist - 2., HOP4Y(5), PIP_X(id_W820) - 3., HOP4Y(5)}, - {PIP_X(id_W820) - 3., HOP4Y(5), PIP_X(id_W820) - top_wire_dist - 3., HOP4Y(3)}, - {PIP_X(id_W820) - top_wire_dist - 3., HOP4Y(3), PIP_X(id_W820) - 4., HOP4Y(3)}, - {PIP_X(id_W820) - 4., HOP4Y(3), PIP_X(id_W820) - top_wire_dist - 4., HOP4Y(1)}, - {PIP_X(id_W820) - top_wire_dist - 4., HOP4Y(1), PIP_X(id_W828) - 5., HOP4Y(1)}, - {PIP_X(id_W828) - 5., HOP4Y(1), PIP_X(id_W828) - 5., WIRE_Y(0)}}}, - {id_E82_loop2, - {{PIP_X(id_E820), WIRE_Y(0), PIP_X(id_E820), HOP4Y(16)}, - {PIP_X(id_E820), HOP4Y(16), PIP_X(id_W828), HOP4Y(16)}, - {PIP_X(id_W828) + 0., HOP4Y(16), PIP_X(id_W828) + top_wire_dist + 0., HOP4Y(14)}, - {PIP_X(id_W828) + top_wire_dist + 0., HOP4Y(14), PIP_X(id_W828) + 1., HOP4Y(14)}, - {PIP_X(id_W828) + 1., HOP4Y(14), PIP_X(id_W828) + top_wire_dist + 1., HOP4Y(12)}, - {PIP_X(id_W828) + top_wire_dist + 1., HOP4Y(12), PIP_X(id_W828) + 2., HOP4Y(12)}, - {PIP_X(id_W828) + 2., HOP4Y(12), PIP_X(id_W828) + top_wire_dist + 2., HOP4Y(10)}, - {PIP_X(id_W828) + top_wire_dist + 2., HOP4Y(10), wrap_len + 3., HOP4Y(10)}, - {wrap_len + 3., HOP4Y(10), wrap_len + 3., HOP4Y(11)}, - {wrap_len + 3., HOP4Y(11), PIP_X(id_W820) + 2., HOP4Y(11)}, - {PIP_X(id_W820) + 2., HOP4Y(11), PIP_X(id_W820) - top_wire_dist + 2., HOP4Y(9)}, - {PIP_X(id_W820) - top_wire_dist + 2., HOP4Y(9), PIP_X(id_W820) + 1., HOP4Y(9)}, - {PIP_X(id_W824) + 1., HOP4Y(9), PIP_X(id_W824) + 1., WIRE_Y(0)}, - {PIP_X(id_W820) + 1., HOP4Y(9), PIP_X(id_W820) - top_wire_dist + 1., HOP4Y(7)}, - {PIP_X(id_W820) - top_wire_dist + 1., HOP4Y(7), PIP_X(id_W820) + 0., HOP4Y(7)}, - {PIP_X(id_W820) + 0., HOP4Y(7), PIP_X(id_W820) - top_wire_dist - 0., HOP4Y(5)}, - {PIP_X(id_W820) - top_wire_dist - 0., HOP4Y(5), PIP_X(id_W820) - 1., HOP4Y(5)}, - {PIP_X(id_W820) - 1., HOP4Y(5), PIP_X(id_W820) - top_wire_dist - 1., HOP4Y(3)}, - {PIP_X(id_W820) - top_wire_dist - 1., HOP4Y(3), PIP_X(id_W820) - 2., HOP4Y(3)}, - {PIP_X(id_W820) - 2., HOP4Y(3), PIP_X(id_W820) - top_wire_dist - 2., HOP4Y(1)}, - {PIP_X(id_W820) - top_wire_dist - 2., HOP4Y(1), PIP_X(id_W828) - 3., HOP4Y(1)}, - {PIP_X(id_W828) - 3., HOP4Y(1), PIP_X(id_W828) - 3., WIRE_Y(0)}}}, - {id_E82_loop3, - {{PIP_X(id_E820), WIRE_Y(0), PIP_X(id_E820), HOP4Y(16)}, - {PIP_X(id_E820), HOP4Y(16), PIP_X(id_W828), HOP4Y(16)}, - {PIP_X(id_W828) + 0., HOP4Y(16), PIP_X(id_W828) + top_wire_dist + 0., HOP4Y(14)}, - {PIP_X(id_W828) + top_wire_dist + 0., HOP4Y(14), PIP_X(id_W828) + 1., HOP4Y(14)}, - {PIP_X(id_W828) + 1., HOP4Y(14), PIP_X(id_W828) + top_wire_dist + 1., HOP4Y(12)}, - {PIP_X(id_W828) + top_wire_dist + 1., HOP4Y(12), PIP_X(id_W828) + 2., HOP4Y(12)}, - {PIP_X(id_W828) + 2., HOP4Y(12), PIP_X(id_W828) + top_wire_dist + 2., HOP4Y(10)}, - {PIP_X(id_W828) + top_wire_dist + 2., HOP4Y(10), PIP_X(id_W828) + 3., HOP4Y(10)}, - {PIP_X(id_W828) + 3., HOP4Y(10), PIP_X(id_W828) + top_wire_dist + 3., HOP4Y(8)}, - {PIP_X(id_W828) + top_wire_dist + 3., HOP4Y(8), wrap_len + 4., HOP4Y(8)}, - {wrap_len + 4., HOP4Y(8), wrap_len + 4., HOP4Y(9)}, - {wrap_len + 4., HOP4Y(9), PIP_X(id_W820) + 3., HOP4Y(9)}, - {PIP_X(id_W824) + 3., HOP4Y(9), PIP_X(id_W824) + 3., WIRE_Y(0)}, - {PIP_X(id_W820) + 3., HOP4Y(9), PIP_X(id_W820) - top_wire_dist + 3., HOP4Y(7)}, - {PIP_X(id_W820) - top_wire_dist + 3., HOP4Y(7), PIP_X(id_W820) + 2., HOP4Y(7)}, - {PIP_X(id_W820) + 2., HOP4Y(7), PIP_X(id_W820) - top_wire_dist + 2., HOP4Y(5)}, - {PIP_X(id_W820) - top_wire_dist + 2., HOP4Y(5), PIP_X(id_W820) + 1., HOP4Y(5)}, - {PIP_X(id_W820) + 1., HOP4Y(5), PIP_X(id_W820) - top_wire_dist + 1., HOP4Y(3)}, - {PIP_X(id_W820) - top_wire_dist + 1., HOP4Y(3), PIP_X(id_W820) - 0., HOP4Y(3)}, - {PIP_X(id_W820) - 0., HOP4Y(3), PIP_X(id_W820) - top_wire_dist - 0., HOP4Y(1)}, - {PIP_X(id_W820) - top_wire_dist - 0., HOP4Y(1), PIP_X(id_W828) - 1., HOP4Y(1)}, - {PIP_X(id_W828) - 1., HOP4Y(1), PIP_X(id_W828) - 1., WIRE_Y(0)}}}, - {id_E82_loop4, - {{PIP_X(id_E820), WIRE_Y(0), PIP_X(id_E820), HOP4Y(16)}, - {PIP_X(id_E820), HOP4Y(16), PIP_X(id_W828), HOP4Y(16)}, - {PIP_X(id_W828) + 0., HOP4Y(16), PIP_X(id_W828) + top_wire_dist + 0., HOP4Y(14)}, - {PIP_X(id_W828) + top_wire_dist + 0., HOP4Y(14), PIP_X(id_W828) + 1., HOP4Y(14)}, - {PIP_X(id_W828) + 1., HOP4Y(14), PIP_X(id_W828) + top_wire_dist + 1., HOP4Y(12)}, - {PIP_X(id_W828) + top_wire_dist + 1., HOP4Y(12), PIP_X(id_W828) + 2., HOP4Y(12)}, - {PIP_X(id_W828) + 2., HOP4Y(12), PIP_X(id_W828) + top_wire_dist + 2., HOP4Y(10)}, - {PIP_X(id_W828) + top_wire_dist + 2., HOP4Y(10), PIP_X(id_W828) + 3., HOP4Y(10)}, - {PIP_X(id_W828) + 3., HOP4Y(10), PIP_X(id_W828) + top_wire_dist + 3., HOP4Y(8)}, - {PIP_X(id_W828) + top_wire_dist + 3., HOP4Y(8), PIP_X(id_W828) + 4., HOP4Y(8)}, - {PIP_X(id_E824) + 4., HOP4Y(8), PIP_X(id_E824) + 4., WIRE_Y(0)}, - {PIP_X(id_W828) + 4., HOP4Y(8), PIP_X(id_W828) + top_wire_dist + 4., HOP4Y(6)}, - {PIP_X(id_W828) + top_wire_dist + 4., HOP4Y(6), wrap_len + 5., HOP4Y(6)}, - {wrap_len + 5., HOP4Y(6), wrap_len + 5., HOP4Y(7)}, - {wrap_len + 5., HOP4Y(7), PIP_X(id_W820) + 4., HOP4Y(7)}, - {PIP_X(id_W820) + 4., HOP4Y(7), PIP_X(id_W820) - top_wire_dist + 4., HOP4Y(5)}, - {PIP_X(id_W820) - top_wire_dist + 4., HOP4Y(5), PIP_X(id_W820) + 3., HOP4Y(5)}, - {PIP_X(id_W820) + 3., HOP4Y(5), PIP_X(id_W820) - top_wire_dist + 3., HOP4Y(3)}, - {PIP_X(id_W820) - top_wire_dist + 3., HOP4Y(3), PIP_X(id_W820) + 2., HOP4Y(3)}, - {PIP_X(id_W820) + 2., HOP4Y(3), PIP_X(id_W820) - top_wire_dist + 2., HOP4Y(1)}, - {PIP_X(id_W820) - top_wire_dist + 2., HOP4Y(1), PIP_X(id_W828) + 1., HOP4Y(1)}, - {PIP_X(id_W828) + 1., HOP4Y(1), PIP_X(id_W828) + 1., WIRE_Y(0)}}}, - {id_E82_loop5, - {{PIP_X(id_E820), WIRE_Y(0), PIP_X(id_E820), HOP4Y(16)}, - {PIP_X(id_E820), HOP4Y(16), PIP_X(id_W828), HOP4Y(16)}, - {PIP_X(id_W828) + 0., HOP4Y(16), PIP_X(id_W828) + top_wire_dist + 0., HOP4Y(14)}, - {PIP_X(id_W828) + top_wire_dist + 0., HOP4Y(14), PIP_X(id_W828) + 1., HOP4Y(14)}, - {PIP_X(id_W828) + 1., HOP4Y(14), PIP_X(id_W828) + top_wire_dist + 1., HOP4Y(12)}, - {PIP_X(id_W828) + top_wire_dist + 1., HOP4Y(12), PIP_X(id_W828) + 2., HOP4Y(12)}, - {PIP_X(id_W828) + 2., HOP4Y(12), PIP_X(id_W828) + top_wire_dist + 2., HOP4Y(10)}, - {PIP_X(id_W828) + top_wire_dist + 2., HOP4Y(10), PIP_X(id_W828) + 3., HOP4Y(10)}, - {PIP_X(id_W828) + 3., HOP4Y(10), PIP_X(id_W828) + top_wire_dist + 3., HOP4Y(8)}, - {PIP_X(id_W828) + top_wire_dist + 3., HOP4Y(8), PIP_X(id_W828) + 4., HOP4Y(8)}, - {PIP_X(id_E824) + 4., HOP4Y(8), PIP_X(id_E824) + 4., WIRE_Y(0)}, - {PIP_X(id_W828) + 4., HOP4Y(8), PIP_X(id_W828) + top_wire_dist + 4., HOP4Y(6)}, - {PIP_X(id_W828) + top_wire_dist + 4., HOP4Y(6), PIP_X(id_W828) + 5., HOP4Y(6)}, - {PIP_X(id_W828) + 5., HOP4Y(6), PIP_X(id_W828) + top_wire_dist + 5., HOP4Y(4)}, - {PIP_X(id_W828) + top_wire_dist + 5., HOP4Y(4), wrap_len + 6., HOP4Y(4)}, - {wrap_len + 6., HOP4Y(4), wrap_len + 6., HOP4Y(5)}, - {wrap_len + 6., HOP4Y(5), PIP_X(id_W820) + 5., HOP4Y(5)}, - {PIP_X(id_W820) + 5., HOP4Y(5), PIP_X(id_W820) - top_wire_dist + 5., HOP4Y(3)}, - {PIP_X(id_W820) - top_wire_dist + 5., HOP4Y(3), PIP_X(id_W820) + 4., HOP4Y(3)}, - {PIP_X(id_W820) + 4., HOP4Y(3), PIP_X(id_W820) - top_wire_dist + 4., HOP4Y(1)}, - {PIP_X(id_W820) - top_wire_dist + 4., HOP4Y(1), PIP_X(id_W828) + 3., HOP4Y(1)}, - {PIP_X(id_W828) + 3., HOP4Y(1), PIP_X(id_W828) + 3., WIRE_Y(0)}}}, - {id_E82_loop6, - {{PIP_X(id_E820), WIRE_Y(0), PIP_X(id_E820), HOP4Y(16)}, - {PIP_X(id_E820), HOP4Y(16), PIP_X(id_W828), HOP4Y(16)}, - {PIP_X(id_W828) + 0., HOP4Y(16), PIP_X(id_W828) + top_wire_dist + 0., HOP4Y(14)}, - {PIP_X(id_W828) + top_wire_dist + 0., HOP4Y(14), PIP_X(id_W828) + 1., HOP4Y(14)}, - {PIP_X(id_W828) + 1., HOP4Y(14), PIP_X(id_W828) + top_wire_dist + 1., HOP4Y(12)}, - {PIP_X(id_W828) + top_wire_dist + 1., HOP4Y(12), PIP_X(id_W828) + 2., HOP4Y(12)}, - {PIP_X(id_W828) + 2., HOP4Y(12), PIP_X(id_W828) + top_wire_dist + 2., HOP4Y(10)}, - {PIP_X(id_W828) + top_wire_dist + 2., HOP4Y(10), PIP_X(id_W828) + 3., HOP4Y(10)}, - {PIP_X(id_W828) + 3., HOP4Y(10), PIP_X(id_W828) + top_wire_dist + 3., HOP4Y(8)}, - {PIP_X(id_W828) + top_wire_dist + 3., HOP4Y(8), PIP_X(id_W828) + 4., HOP4Y(8)}, - {PIP_X(id_W828) + 4., HOP4Y(8), PIP_X(id_W828) + top_wire_dist + 4., HOP4Y(6)}, - {PIP_X(id_E824) + 4., HOP4Y(8), PIP_X(id_E824) + 4., WIRE_Y(0)}, - {PIP_X(id_W828) + top_wire_dist + 4., HOP4Y(6), PIP_X(id_W828) + 5., HOP4Y(6)}, - {PIP_X(id_W828) + 5., HOP4Y(6), PIP_X(id_W828) + top_wire_dist + 5., HOP4Y(4)}, - {PIP_X(id_W828) + top_wire_dist + 5., HOP4Y(4), PIP_X(id_W828) + 6., HOP4Y(4)}, - {PIP_X(id_W828) + 6., HOP4Y(4), PIP_X(id_W828) + top_wire_dist + 6., HOP4Y(2)}, - {PIP_X(id_W828) + top_wire_dist + 6., HOP4Y(2), wrap_len + 7., HOP4Y(2)}, - {wrap_len + 7., HOP4Y(2), wrap_len + 7., HOP4Y(3)}, - {wrap_len + 7., HOP4Y(3), PIP_X(id_W820) + 6., HOP4Y(3)}, - {PIP_X(id_W820) + 6., HOP4Y(3), PIP_X(id_W820) - top_wire_dist + 6., HOP4Y(1)}, - {PIP_X(id_W820) - top_wire_dist + 6., HOP4Y(1), PIP_X(id_W828) + 5., HOP4Y(1)}, - {PIP_X(id_W828) + 5., HOP4Y(1), PIP_X(id_W828) + 5., WIRE_Y(0)}}}, - {id_E82_loop7, - {{PIP_X(id_E820), WIRE_Y(0), PIP_X(id_E820), HOP4Y(16)}, - {PIP_X(id_E820), HOP4Y(16), PIP_X(id_W828), HOP4Y(16)}, - {PIP_X(id_W828) + 0., HOP4Y(16), PIP_X(id_W828) + top_wire_dist + 0., HOP4Y(14)}, - {PIP_X(id_W828) + top_wire_dist + 0., HOP4Y(14), PIP_X(id_W828) + 1., HOP4Y(14)}, - {PIP_X(id_W828) + 1., HOP4Y(14), PIP_X(id_W828) + top_wire_dist + 1., HOP4Y(12)}, - {PIP_X(id_W828) + top_wire_dist + 1., HOP4Y(12), PIP_X(id_W828) + 2., HOP4Y(12)}, - {PIP_X(id_W828) + 2., HOP4Y(12), PIP_X(id_W828) + top_wire_dist + 2., HOP4Y(10)}, - {PIP_X(id_W828) + top_wire_dist + 2., HOP4Y(10), PIP_X(id_W828) + 3., HOP4Y(10)}, - {PIP_X(id_W828) + 3., HOP4Y(10), PIP_X(id_W828) + top_wire_dist + 3., HOP4Y(8)}, - {PIP_X(id_W828) + top_wire_dist + 3., HOP4Y(8), PIP_X(id_W828) + 4., HOP4Y(8)}, - {PIP_X(id_W828) + 4., HOP4Y(8), PIP_X(id_W828) + top_wire_dist + 4., HOP4Y(6)}, - {PIP_X(id_E824) + 4., HOP4Y(8), PIP_X(id_E824) + 4., WIRE_Y(0)}, - {PIP_X(id_W828) + top_wire_dist + 4., HOP4Y(6), PIP_X(id_W828) + 5., HOP4Y(6)}, - {PIP_X(id_W828) + 5., HOP4Y(6), PIP_X(id_W828) + top_wire_dist + 5., HOP4Y(4)}, - {PIP_X(id_W828) + top_wire_dist + 5., HOP4Y(4), PIP_X(id_W828) + 6., HOP4Y(4)}, - {PIP_X(id_W828) + 6., HOP4Y(4), PIP_X(id_W828) + top_wire_dist + 6., HOP4Y(2)}, - {PIP_X(id_W828) + top_wire_dist + 6., HOP4Y(2), PIP_X(id_W828) + 7., HOP4Y(2)}, - {PIP_X(id_W828) + 7., HOP4Y(2), PIP_X(id_W828) + top_wire_dist + 7., HOP4Y(0)}, - {PIP_X(id_W828) + top_wire_dist + 7., HOP4Y(0), wrap_len + 8., HOP4Y(0)}, - {wrap_len + 8., HOP4Y(0), wrap_len + 8., HOP4Y(1)}, - {wrap_len + 8., HOP4Y(1), PIP_X(id_W828) + 7., HOP4Y(1)}, - {PIP_X(id_W828) + 7., HOP4Y(1), PIP_X(id_W828) + 7., WIRE_Y(0)}}}, - {id_W82_loop0, - {{PIP_X(id_W820), WIRE_Y(0), PIP_X(id_W820), HOP4Y(17)}, - {PIP_X(id_W820) - 0., HOP4Y(17), PIP_X(id_W820) - top_wire_dist - 0., HOP4Y(15)}, - {PIP_X(id_W820) - top_wire_dist - 0., HOP4Y(15), -wrap_len - 0., HOP4Y(15)}, - {-wrap_len - 0., HOP4Y(15), -wrap_len - 0., HOP4Y(14)}, - {-wrap_len - 0., HOP4Y(14), PIP_X(id_W828) + 0., HOP4Y(14)}, - {PIP_X(id_W828) + 0., HOP4Y(14), PIP_X(id_W828) + top_wire_dist + 0., HOP4Y(12)}, - {PIP_X(id_W828) + top_wire_dist + 0., HOP4Y(12), PIP_X(id_W828) + 1., HOP4Y(12)}, - {PIP_X(id_W828) + 1., HOP4Y(12), PIP_X(id_W828) + top_wire_dist + 1., HOP4Y(10)}, - {PIP_X(id_W828) + top_wire_dist + 1., HOP4Y(10), PIP_X(id_W828) + 2., HOP4Y(10)}, - {PIP_X(id_W828) + 2., HOP4Y(10), PIP_X(id_W828) + top_wire_dist + 2., HOP4Y(8)}, - {PIP_X(id_W828) + top_wire_dist + 2., HOP4Y(8), PIP_X(id_W828) + 3., HOP4Y(8)}, - {PIP_X(id_W828) + 3., HOP4Y(8), PIP_X(id_W828) + top_wire_dist + 3., HOP4Y(6)}, - {PIP_X(id_E824) + 3., HOP4Y(8), PIP_X(id_E824) + 3., WIRE_Y(0)}, - {PIP_X(id_W828) + top_wire_dist + 3., HOP4Y(6), PIP_X(id_W828) + 4., HOP4Y(6)}, - {PIP_X(id_W828) + 4., HOP4Y(6), PIP_X(id_W828) + top_wire_dist + 4., HOP4Y(4)}, - {PIP_X(id_W828) + top_wire_dist + 4., HOP4Y(4), PIP_X(id_W828) + 5., HOP4Y(4)}, - {PIP_X(id_W828) + 5., HOP4Y(4), PIP_X(id_W828) + top_wire_dist + 5., HOP4Y(2)}, - {PIP_X(id_W828) + top_wire_dist + 5., HOP4Y(2), PIP_X(id_W828) + 6., HOP4Y(2)}, - {PIP_X(id_W828) + 6., HOP4Y(2), PIP_X(id_W828) + top_wire_dist + 6., HOP4Y(0)}, - {PIP_X(id_W828) + top_wire_dist + 6., HOP4Y(0), PIP_X(id_E828) + 7., HOP4Y(0)}, - {PIP_X(id_E828) + 7., HOP4Y(0), PIP_X(id_E828) + 7., WIRE_Y(0)}}}, - {id_W82_loop1, - {{PIP_X(id_W820), WIRE_Y(0), PIP_X(id_W820), HOP4Y(17)}, - {PIP_X(id_W820) - 0., HOP4Y(17), PIP_X(id_W820) - top_wire_dist - 0., HOP4Y(15)}, - {PIP_X(id_W820) - top_wire_dist - 0., HOP4Y(15), PIP_X(id_W820) - 1., HOP4Y(15)}, - {PIP_X(id_W820) - 1., HOP4Y(15), PIP_X(id_W820) - top_wire_dist - 1., HOP4Y(13)}, - {PIP_X(id_W820) - top_wire_dist - 1., HOP4Y(13), -wrap_len - 1., HOP4Y(13)}, - {-wrap_len - 1., HOP4Y(13), -wrap_len - 1., HOP4Y(12)}, - {-wrap_len - 1., HOP4Y(12), PIP_X(id_W828) - 1., HOP4Y(12)}, - {PIP_X(id_W828) - 1., HOP4Y(12), PIP_X(id_W828) + top_wire_dist - 1., HOP4Y(10)}, - {PIP_X(id_W828) + top_wire_dist - 1., HOP4Y(10), PIP_X(id_W828) + 0., HOP4Y(10)}, - {PIP_X(id_W828) + 0., HOP4Y(10), PIP_X(id_W828) + top_wire_dist + 0., HOP4Y(8)}, - {PIP_X(id_W828) + top_wire_dist + 0., HOP4Y(8), PIP_X(id_W828) + 1., HOP4Y(8)}, - {PIP_X(id_W828) + 1., HOP4Y(8), PIP_X(id_W828) + top_wire_dist + 1., HOP4Y(6)}, - {PIP_X(id_E824) + 1., HOP4Y(8), PIP_X(id_E824) + 1., WIRE_Y(0)}, - {PIP_X(id_W828) + top_wire_dist + 1., HOP4Y(6), PIP_X(id_W828) + 2., HOP4Y(6)}, - {PIP_X(id_W828) + 2., HOP4Y(6), PIP_X(id_W828) + top_wire_dist + 2., HOP4Y(4)}, - {PIP_X(id_W828) + top_wire_dist + 2., HOP4Y(4), PIP_X(id_W828) + 3., HOP4Y(4)}, - {PIP_X(id_W828) + 3., HOP4Y(4), PIP_X(id_W828) + top_wire_dist + 3., HOP4Y(2)}, - {PIP_X(id_W828) + top_wire_dist + 3., HOP4Y(2), PIP_X(id_W828) + 4., HOP4Y(2)}, - {PIP_X(id_W828) + 4., HOP4Y(2), PIP_X(id_W828) + top_wire_dist + 4., HOP4Y(0)}, - {PIP_X(id_W828) + top_wire_dist + 4., HOP4Y(0), PIP_X(id_E828) + 5., HOP4Y(0)}, - {PIP_X(id_E828) + 5., HOP4Y(0), PIP_X(id_E828) + 5., WIRE_Y(0)}}}, - {id_W82_loop2, - {{PIP_X(id_W820), WIRE_Y(0), PIP_X(id_W820), HOP4Y(17)}, - {PIP_X(id_W820) - 0., HOP4Y(17), PIP_X(id_W820) - top_wire_dist - 0., HOP4Y(15)}, - {PIP_X(id_W820) - top_wire_dist - 0., HOP4Y(15), PIP_X(id_W820) - 1., HOP4Y(15)}, - {PIP_X(id_W820) - 1., HOP4Y(15), PIP_X(id_W820) - top_wire_dist - 1., HOP4Y(13)}, - {PIP_X(id_W820) - top_wire_dist - 1., HOP4Y(13), PIP_X(id_W820) - 2., HOP4Y(13)}, - {PIP_X(id_W820) - 2., HOP4Y(13), PIP_X(id_W820) - top_wire_dist - 2., HOP4Y(11)}, - {PIP_X(id_W820) - top_wire_dist - 2., HOP4Y(11), -wrap_len - 2., HOP4Y(11)}, - {-wrap_len - 2., HOP4Y(11), -wrap_len - 2., HOP4Y(10)}, - {-wrap_len - 2., HOP4Y(10), PIP_X(id_W828) - 2., HOP4Y(10)}, - {PIP_X(id_W828) - 2., HOP4Y(10), PIP_X(id_W828) + top_wire_dist - 2., HOP4Y(8)}, - {PIP_X(id_W828) + top_wire_dist - 2., HOP4Y(8), PIP_X(id_W828) - 1., HOP4Y(8)}, - {PIP_X(id_W828) - 1., HOP4Y(8), PIP_X(id_W828) + top_wire_dist - 1., HOP4Y(6)}, - {PIP_X(id_E824) - 1., HOP4Y(8), PIP_X(id_E824) - 1., WIRE_Y(0)}, - {PIP_X(id_W828) + top_wire_dist - 1., HOP4Y(6), PIP_X(id_W828) + 0., HOP4Y(6)}, - {PIP_X(id_W828) + 0., HOP4Y(6), PIP_X(id_W828) + top_wire_dist + 0., HOP4Y(4)}, - {PIP_X(id_W828) + top_wire_dist + 0., HOP4Y(4), PIP_X(id_W828) + 1., HOP4Y(4)}, - {PIP_X(id_W828) + 1., HOP4Y(4), PIP_X(id_W828) + top_wire_dist + 1., HOP4Y(2)}, - {PIP_X(id_W828) + top_wire_dist + 1., HOP4Y(2), PIP_X(id_W828) + 2., HOP4Y(2)}, - {PIP_X(id_W828) + 2., HOP4Y(2), PIP_X(id_W828) + top_wire_dist + 2., HOP4Y(0)}, - {PIP_X(id_W828) + top_wire_dist + 2., HOP4Y(0), PIP_X(id_E828) + 3., HOP4Y(0)}, - {PIP_X(id_E828) + 3., HOP4Y(0), PIP_X(id_E828) + 3., WIRE_Y(0)}}}, - {id_W82_loop3, - {{PIP_X(id_W820), WIRE_Y(0), PIP_X(id_W820), HOP4Y(17)}, - {PIP_X(id_W820) - 0., HOP4Y(17), PIP_X(id_W820) - top_wire_dist - 0., HOP4Y(15)}, - {PIP_X(id_W820) - top_wire_dist - 0., HOP4Y(15), PIP_X(id_W820) - 1., HOP4Y(15)}, - {PIP_X(id_W820) - 1., HOP4Y(15), PIP_X(id_W820) - top_wire_dist - 1., HOP4Y(13)}, - {PIP_X(id_W820) - top_wire_dist - 1., HOP4Y(13), PIP_X(id_W820) - 2., HOP4Y(13)}, - {PIP_X(id_W820) - 2., HOP4Y(13), PIP_X(id_W820) - top_wire_dist - 2., HOP4Y(11)}, - {PIP_X(id_W820) - top_wire_dist - 2., HOP4Y(11), PIP_X(id_W820) - 3., HOP4Y(11)}, - {PIP_X(id_W820) - 3., HOP4Y(11), PIP_X(id_W820) - top_wire_dist - 3., HOP4Y(9)}, - {PIP_X(id_W820) - top_wire_dist - 3., HOP4Y(9), -wrap_len - 3., HOP4Y(9)}, - {-wrap_len - 3., HOP4Y(9), -wrap_len - 3., HOP4Y(8)}, - {-wrap_len - 3., HOP4Y(8), PIP_X(id_W828) - 3., HOP4Y(8)}, - {PIP_X(id_W828) - 3., HOP4Y(8), PIP_X(id_W828) + top_wire_dist - 3., HOP4Y(6)}, - {PIP_X(id_E824) - 3., HOP4Y(8), PIP_X(id_E824) - 3., WIRE_Y(0)}, - {PIP_X(id_W828) + top_wire_dist - 3., HOP4Y(6), PIP_X(id_W828) - 2., HOP4Y(6)}, - {PIP_X(id_W828) - 2., HOP4Y(6), PIP_X(id_W828) + top_wire_dist - 2., HOP4Y(4)}, - {PIP_X(id_W828) + top_wire_dist - 2., HOP4Y(4), PIP_X(id_W828) - 1., HOP4Y(4)}, - {PIP_X(id_W828) - 1., HOP4Y(4), PIP_X(id_W828) + top_wire_dist - 1., HOP4Y(2)}, - {PIP_X(id_W828) + top_wire_dist - 1., HOP4Y(2), PIP_X(id_W828) + 0., HOP4Y(2)}, - {PIP_X(id_W828) + 0., HOP4Y(2), PIP_X(id_W828) + top_wire_dist + 0., HOP4Y(0)}, - {PIP_X(id_W828) + top_wire_dist + 0., HOP4Y(0), PIP_X(id_E828) + 1., HOP4Y(0)}, - {PIP_X(id_E828) + 1., HOP4Y(0), PIP_X(id_E828) + 1., WIRE_Y(0)}}}, - {id_W82_loop4, - {{PIP_X(id_W820), WIRE_Y(0), PIP_X(id_W820), HOP4Y(17)}, - {PIP_X(id_W820) - 0., HOP4Y(17), PIP_X(id_W820) - top_wire_dist - 0., HOP4Y(15)}, - {PIP_X(id_W820) - top_wire_dist - 0., HOP4Y(15), PIP_X(id_W820) - 1., HOP4Y(15)}, - {PIP_X(id_W820) - 1., HOP4Y(15), PIP_X(id_W820) - top_wire_dist - 1., HOP4Y(13)}, - {PIP_X(id_W820) - top_wire_dist - 1., HOP4Y(13), PIP_X(id_W820) - 2., HOP4Y(13)}, - {PIP_X(id_W820) - 2., HOP4Y(13), PIP_X(id_W820) - top_wire_dist - 2., HOP4Y(11)}, - {PIP_X(id_W820) - top_wire_dist - 2., HOP4Y(11), PIP_X(id_W820) - 3., HOP4Y(11)}, - {PIP_X(id_W820) - 3., HOP4Y(11), PIP_X(id_W820) - top_wire_dist - 3., HOP4Y(9)}, - {PIP_X(id_W820) - top_wire_dist - 3., HOP4Y(9), PIP_X(id_W820) - 4., HOP4Y(9)}, - {PIP_X(id_W820) - 4., HOP4Y(9), PIP_X(id_W820) - top_wire_dist - 4., HOP4Y(7)}, - {PIP_X(id_W820) - top_wire_dist - 4., HOP4Y(7), -wrap_len - 4., HOP4Y(7)}, - {-wrap_len - 4., HOP4Y(7), -wrap_len - 4., HOP4Y(6)}, - {PIP_X(id_W824) - 4., HOP4Y(6), PIP_X(id_W824) - 4., WIRE_Y(0)}, - {-wrap_len - 4., HOP4Y(6), PIP_X(id_W828) - 4., HOP4Y(6)}, - {PIP_X(id_W828) - 4., HOP4Y(6), PIP_X(id_W828) + top_wire_dist - 4., HOP4Y(4)}, - {PIP_X(id_W828) + top_wire_dist - 4., HOP4Y(4), PIP_X(id_W828) - 3., HOP4Y(4)}, - {PIP_X(id_W828) - 3., HOP4Y(4), PIP_X(id_W828) + top_wire_dist - 3., HOP4Y(2)}, - {PIP_X(id_W828) + top_wire_dist - 3., HOP4Y(2), PIP_X(id_W828) - 2., HOP4Y(2)}, - {PIP_X(id_W828) - 2., HOP4Y(2), PIP_X(id_W828) + top_wire_dist - 2., HOP4Y(0)}, - {PIP_X(id_W828) + top_wire_dist - 2., HOP4Y(0), PIP_X(id_E828) - 1., HOP4Y(0)}, - {PIP_X(id_E828) - 1., HOP4Y(0), PIP_X(id_E828) - 1., WIRE_Y(0)}}}, - {id_W82_loop5, - {{PIP_X(id_W820), WIRE_Y(0), PIP_X(id_W820), HOP4Y(17)}, - {PIP_X(id_W820) - 0., HOP4Y(17), PIP_X(id_W820) - top_wire_dist - 0., HOP4Y(15)}, - {PIP_X(id_W820) - top_wire_dist - 0., HOP4Y(15), PIP_X(id_W820) - 1., HOP4Y(15)}, - {PIP_X(id_W820) - 1., HOP4Y(15), PIP_X(id_W820) - top_wire_dist - 1., HOP4Y(13)}, - {PIP_X(id_W820) - top_wire_dist - 1., HOP4Y(13), PIP_X(id_W820) - 2., HOP4Y(13)}, - {PIP_X(id_W820) - 2., HOP4Y(13), PIP_X(id_W820) - top_wire_dist - 2., HOP4Y(11)}, - {PIP_X(id_W820) - top_wire_dist - 2., HOP4Y(11), PIP_X(id_W820) - 3., HOP4Y(11)}, - {PIP_X(id_W820) - 3., HOP4Y(11), PIP_X(id_W820) - top_wire_dist - 3., HOP4Y(9)}, - {PIP_X(id_W820) - top_wire_dist - 3., HOP4Y(9), PIP_X(id_W820) - 4., HOP4Y(9)}, - {PIP_X(id_W820) - 4., HOP4Y(9), PIP_X(id_W820) - top_wire_dist - 4., HOP4Y(7)}, - {PIP_X(id_W824) - 4., HOP4Y(9), PIP_X(id_W824) - 4., WIRE_Y(0)}, - {PIP_X(id_W820) - top_wire_dist - 4., HOP4Y(7), PIP_X(id_W820) - 5., HOP4Y(7)}, - {PIP_X(id_W820) - 5., HOP4Y(7), PIP_X(id_W820) - top_wire_dist - 5., HOP4Y(5)}, - {PIP_X(id_W820) - top_wire_dist - 5., HOP4Y(5), -wrap_len - 5., HOP4Y(5)}, - {-wrap_len - 5., HOP4Y(5), -wrap_len - 5., HOP4Y(4)}, - {-wrap_len - 5., HOP4Y(4), PIP_X(id_W828) - 5., HOP4Y(4)}, - {PIP_X(id_W828) - 5., HOP4Y(4), PIP_X(id_W828) + top_wire_dist - 5., HOP4Y(2)}, - {PIP_X(id_W828) + top_wire_dist - 5., HOP4Y(2), PIP_X(id_W828) - 4., HOP4Y(2)}, - {PIP_X(id_W828) - 4., HOP4Y(2), PIP_X(id_W828) + top_wire_dist - 4., HOP4Y(0)}, - {PIP_X(id_W828) + top_wire_dist - 4., HOP4Y(0), PIP_X(id_E828) - 3., HOP4Y(0)}, - {PIP_X(id_E828) - 3., HOP4Y(0), PIP_X(id_E828) - 3., WIRE_Y(0)}}}, - {id_W82_loop6, - {{PIP_X(id_W820), WIRE_Y(0), PIP_X(id_W820), HOP4Y(17)}, - {PIP_X(id_W820) - 0., HOP4Y(17), PIP_X(id_W820) - top_wire_dist - 0., HOP4Y(15)}, - {PIP_X(id_W820) - top_wire_dist - 0., HOP4Y(15), PIP_X(id_W820) - 1., HOP4Y(15)}, - {PIP_X(id_W820) - 1., HOP4Y(15), PIP_X(id_W820) - top_wire_dist - 1., HOP4Y(13)}, - {PIP_X(id_W820) - top_wire_dist - 1., HOP4Y(13), PIP_X(id_W820) - 2., HOP4Y(13)}, - {PIP_X(id_W820) - 2., HOP4Y(13), PIP_X(id_W820) - top_wire_dist - 2., HOP4Y(11)}, - {PIP_X(id_W820) - top_wire_dist - 2., HOP4Y(11), PIP_X(id_W820) - 3., HOP4Y(11)}, - {PIP_X(id_W820) - 3., HOP4Y(11), PIP_X(id_W820) - top_wire_dist - 3., HOP4Y(9)}, - {PIP_X(id_W820) - top_wire_dist - 3., HOP4Y(9), PIP_X(id_W820) - 4., HOP4Y(9)}, - {PIP_X(id_W820) - 4., HOP4Y(9), PIP_X(id_W820) - top_wire_dist - 4., HOP4Y(7)}, - {PIP_X(id_W824) - 4., HOP4Y(9), PIP_X(id_W824) - 4., WIRE_Y(0)}, - {PIP_X(id_W820) - top_wire_dist - 4., HOP4Y(7), PIP_X(id_W820) - 5., HOP4Y(7)}, - {PIP_X(id_W820) - 5., HOP4Y(7), PIP_X(id_W820) - top_wire_dist - 5., HOP4Y(5)}, - {PIP_X(id_W820) - top_wire_dist - 5., HOP4Y(5), PIP_X(id_W820) - 6., HOP4Y(5)}, - {PIP_X(id_W820) - 6., HOP4Y(5), PIP_X(id_W820) - top_wire_dist - 6., HOP4Y(3)}, - {PIP_X(id_W820) - top_wire_dist - 6., HOP4Y(3), -wrap_len - 6., HOP4Y(3)}, - {-wrap_len - 6., HOP4Y(3), -wrap_len - 6., HOP4Y(2)}, - {-wrap_len - 6., HOP4Y(2), PIP_X(id_W828) - 6., HOP4Y(2)}, - {PIP_X(id_W828) - 6., HOP4Y(2), PIP_X(id_W828) + top_wire_dist - 6., HOP4Y(0)}, - {PIP_X(id_W828) + top_wire_dist - 6., HOP4Y(0), PIP_X(id_E828) - 5., HOP4Y(0)}, - {PIP_X(id_E828) - 5., HOP4Y(0), PIP_X(id_E828) - 5., WIRE_Y(0)}}}, - {id_W82_loop7, - {{PIP_X(id_W820), WIRE_Y(0), PIP_X(id_W820), HOP4Y(17)}, - {PIP_X(id_W820) - 0., HOP4Y(17), PIP_X(id_W820) - top_wire_dist - 0., HOP4Y(15)}, - {PIP_X(id_W820) - top_wire_dist - 0., HOP4Y(15), PIP_X(id_W820) - 1., HOP4Y(15)}, - {PIP_X(id_W820) - 1., HOP4Y(15), PIP_X(id_W820) - top_wire_dist - 1., HOP4Y(13)}, - {PIP_X(id_W820) - top_wire_dist - 1., HOP4Y(13), PIP_X(id_W820) - 2., HOP4Y(13)}, - {PIP_X(id_W820) - 2., HOP4Y(13), PIP_X(id_W820) - top_wire_dist - 2., HOP4Y(11)}, - {PIP_X(id_W820) - top_wire_dist - 2., HOP4Y(11), PIP_X(id_W820) - 3., HOP4Y(11)}, - {PIP_X(id_W820) - 3., HOP4Y(11), PIP_X(id_W820) - top_wire_dist - 3., HOP4Y(9)}, - {PIP_X(id_W820) - top_wire_dist - 3., HOP4Y(9), PIP_X(id_W820) - 4., HOP4Y(9)}, - {PIP_X(id_W820) - 4., HOP4Y(9), PIP_X(id_W820) - top_wire_dist - 4., HOP4Y(7)}, - {PIP_X(id_W824) - 4., HOP4Y(9), PIP_X(id_W824) - 4., WIRE_Y(0)}, - {PIP_X(id_W820) - top_wire_dist - 4., HOP4Y(7), PIP_X(id_W820) - 5., HOP4Y(7)}, - {PIP_X(id_W820) - 5., HOP4Y(7), PIP_X(id_W820) - top_wire_dist - 5., HOP4Y(5)}, - {PIP_X(id_W820) - top_wire_dist - 5., HOP4Y(5), PIP_X(id_W820) - 6., HOP4Y(5)}, - {PIP_X(id_W820) - 6., HOP4Y(5), PIP_X(id_W820) - top_wire_dist - 6., HOP4Y(3)}, - {PIP_X(id_W820) - top_wire_dist - 6., HOP4Y(3), PIP_X(id_W820) - 7., HOP4Y(3)}, - {PIP_X(id_W820) - 7., HOP4Y(3), PIP_X(id_W820) - top_wire_dist - 7., HOP4Y(1)}, - {PIP_X(id_W820) - top_wire_dist - 7., HOP4Y(1), -wrap_len - 7., HOP4Y(1)}, - {-wrap_len - 7., HOP4Y(1), -wrap_len - 7., HOP4Y(0)}, - {-wrap_len - 7., HOP4Y(0), PIP_X(id_E828) - 7., HOP4Y(0)}, - {PIP_X(id_E828) - 7., HOP4Y(0), PIP_X(id_E828) - 7., WIRE_Y(0)}}}, - -#undef HOP4Y -#define HOP4Y(offset) WIRE_Y((float)offset + HOP4Y_START + 18.f + 18.f + 18.f) - {id_E83, - {{PIP_X(id_E830), WIRE_Y(0), PIP_X(id_E830), HOP4Y(16)}, - {PIP_X(id_E830), HOP4Y(16), PIP_X(id_W838), HOP4Y(16)}, - {PIP_X(id_W838) + 0., HOP4Y(16), PIP_X(id_W838) + top_wire_dist + 0., HOP4Y(14)}, - {PIP_X(id_W838) + top_wire_dist + 0., HOP4Y(14), PIP_X(id_W838) + 1., HOP4Y(14)}, - {PIP_X(id_W838) + 1., HOP4Y(14), PIP_X(id_W838) + top_wire_dist + 1., HOP4Y(12)}, - {PIP_X(id_W838) + top_wire_dist + 1., HOP4Y(12), PIP_X(id_W838) + 2., HOP4Y(12)}, - {PIP_X(id_W838) + 2., HOP4Y(12), PIP_X(id_W838) + top_wire_dist + 2., HOP4Y(10)}, - {PIP_X(id_W838) + top_wire_dist + 2., HOP4Y(10), PIP_X(id_W838) + 3., HOP4Y(10)}, - {PIP_X(id_W838) + 3., HOP4Y(10), PIP_X(id_W838) + top_wire_dist + 3., HOP4Y(8)}, - {PIP_X(id_W838) + top_wire_dist + 3., HOP4Y(8), PIP_X(id_W838) + 4., HOP4Y(8)}, - {PIP_X(id_W838) + 4., HOP4Y(8), PIP_X(id_W838) + top_wire_dist + 4., HOP4Y(6)}, - {PIP_X(id_E834) + 4., HOP4Y(8), PIP_X(id_E834) + 4., WIRE_Y(0)}, - {PIP_X(id_W838) + top_wire_dist + 4., HOP4Y(6), PIP_X(id_W838) + 5., HOP4Y(6)}, - {PIP_X(id_W838) + 5., HOP4Y(6), PIP_X(id_W838) + top_wire_dist + 5., HOP4Y(4)}, - {PIP_X(id_W838) + top_wire_dist + 5., HOP4Y(4), PIP_X(id_W838) + 6., HOP4Y(4)}, - {PIP_X(id_W838) + 6., HOP4Y(4), PIP_X(id_W838) + top_wire_dist + 6., HOP4Y(2)}, - {PIP_X(id_W838) + top_wire_dist + 6., HOP4Y(2), PIP_X(id_W838) + 7., HOP4Y(2)}, - {PIP_X(id_W838) + 7., HOP4Y(2), PIP_X(id_W838) + top_wire_dist + 7., HOP4Y(0)}, - {PIP_X(id_W838) + top_wire_dist + 7., HOP4Y(0), PIP_X(id_E838) + 8., HOP4Y(0)}, - {PIP_X(id_E838) + 8, HOP4Y(0), PIP_X(id_E838) + 8., WIRE_Y(0)}}}, - {id_W83, - {{PIP_X(id_W830), WIRE_Y(0), PIP_X(id_W830), HOP4Y(17)}, - {PIP_X(id_W830) - 0., HOP4Y(17), PIP_X(id_W830) - top_wire_dist - 0., HOP4Y(15)}, - {PIP_X(id_W830) - top_wire_dist - 0., HOP4Y(15), PIP_X(id_W830) - 1., HOP4Y(15)}, - {PIP_X(id_W830) - 1., HOP4Y(15), PIP_X(id_W830) - top_wire_dist - 1., HOP4Y(13)}, - {PIP_X(id_W830) - top_wire_dist - 1., HOP4Y(13), PIP_X(id_W830) - 2., HOP4Y(13)}, - {PIP_X(id_W830) - 2., HOP4Y(13), PIP_X(id_W830) - top_wire_dist - 2., HOP4Y(11)}, - {PIP_X(id_W830) - top_wire_dist - 2., HOP4Y(11), PIP_X(id_W830) - 3., HOP4Y(11)}, - {PIP_X(id_W830) - 3., HOP4Y(11), PIP_X(id_W830) - top_wire_dist - 3., HOP4Y(9)}, - {PIP_X(id_W830) - top_wire_dist - 3., HOP4Y(9), PIP_X(id_W830) - 4., HOP4Y(9)}, - {PIP_X(id_W830) - 4., HOP4Y(9), PIP_X(id_W830) - top_wire_dist - 4., HOP4Y(7)}, - {PIP_X(id_W834) - 4., HOP4Y(9), PIP_X(id_W834) - 4., WIRE_Y(0)}, - {PIP_X(id_W830) - top_wire_dist - 4., HOP4Y(7), PIP_X(id_W830) - 5., HOP4Y(7)}, - {PIP_X(id_W830) - 5., HOP4Y(7), PIP_X(id_W830) - top_wire_dist - 5., HOP4Y(5)}, - {PIP_X(id_W830) - top_wire_dist - 5., HOP4Y(5), PIP_X(id_W830) - 6., HOP4Y(5)}, - {PIP_X(id_W830) - 6., HOP4Y(5), PIP_X(id_W830) - top_wire_dist - 6., HOP4Y(3)}, - {PIP_X(id_W830) - top_wire_dist - 6., HOP4Y(3), PIP_X(id_W830) - 7., HOP4Y(3)}, - {PIP_X(id_W830) - 7., HOP4Y(3), PIP_X(id_W830) - top_wire_dist - 7., HOP4Y(1)}, - {PIP_X(id_W830) - top_wire_dist - 7., HOP4Y(1), PIP_X(id_W838) - 8., HOP4Y(1)}, - {PIP_X(id_W838) - 8, HOP4Y(1), PIP_X(id_W838) - 8., WIRE_Y(0)}}}, - {id_E83_loop0, - {{PIP_X(id_E830), WIRE_Y(0), PIP_X(id_E830), HOP4Y(16)}, - {PIP_X(id_E830), HOP4Y(16), PIP_X(id_W838), HOP4Y(16)}, - {PIP_X(id_W838) + 0., HOP4Y(16), PIP_X(id_W838) + top_wire_dist + 0., HOP4Y(14)}, - {PIP_X(id_W838) + top_wire_dist + 0., HOP4Y(14), wrap_len + 1., HOP4Y(14)}, - {wrap_len + 1., HOP4Y(14), wrap_len + 1., HOP4Y(15)}, - {wrap_len + 1., HOP4Y(15), PIP_X(id_W830) - 0., HOP4Y(15)}, - {PIP_X(id_W830) - 0., HOP4Y(15), PIP_X(id_W830) - top_wire_dist - 0., HOP4Y(13)}, - {PIP_X(id_W830) - top_wire_dist - 0., HOP4Y(13), PIP_X(id_W830) - 1., HOP4Y(13)}, - {PIP_X(id_W830) - 1., HOP4Y(13), PIP_X(id_W830) - top_wire_dist - 1., HOP4Y(11)}, - {PIP_X(id_W830) - top_wire_dist - 1., HOP4Y(11), PIP_X(id_W830) - 2., HOP4Y(11)}, - {PIP_X(id_W830) - 2., HOP4Y(11), PIP_X(id_W830) - top_wire_dist - 2., HOP4Y(9)}, - {PIP_X(id_W830) - top_wire_dist - 2., HOP4Y(9), PIP_X(id_W830) - 3., HOP4Y(9)}, - {PIP_X(id_W830) - 3., HOP4Y(9), PIP_X(id_W830) - top_wire_dist - 3., HOP4Y(7)}, - {PIP_X(id_W834) - 3., HOP4Y(9), PIP_X(id_W834) - 3., WIRE_Y(0)}, - {PIP_X(id_W830) - top_wire_dist - 3., HOP4Y(7), PIP_X(id_W830) - 4., HOP4Y(7)}, - {PIP_X(id_W830) - 4., HOP4Y(7), PIP_X(id_W830) - top_wire_dist - 4., HOP4Y(5)}, - {PIP_X(id_W830) - top_wire_dist - 4., HOP4Y(5), PIP_X(id_W830) - 5., HOP4Y(5)}, - {PIP_X(id_W830) - 5., HOP4Y(5), PIP_X(id_W830) - top_wire_dist - 5., HOP4Y(3)}, - {PIP_X(id_W830) - top_wire_dist - 5., HOP4Y(3), PIP_X(id_W830) - 6., HOP4Y(3)}, - {PIP_X(id_W830) - 6., HOP4Y(3), PIP_X(id_W830) - top_wire_dist - 6., HOP4Y(1)}, - {PIP_X(id_W830) - top_wire_dist - 6., HOP4Y(1), PIP_X(id_W838) - 7., HOP4Y(1)}, - {PIP_X(id_W838) - 7, HOP4Y(1), PIP_X(id_W838) - 7., WIRE_Y(0)}}}, - {id_E83_loop1, - {{PIP_X(id_E830), WIRE_Y(0), PIP_X(id_E830), HOP4Y(16)}, - {PIP_X(id_E830), HOP4Y(16), PIP_X(id_W838), HOP4Y(16)}, - {PIP_X(id_W838) + 0., HOP4Y(16), PIP_X(id_W838) + top_wire_dist + 0., HOP4Y(14)}, - {PIP_X(id_W838) + top_wire_dist + 0., HOP4Y(14), PIP_X(id_W838) + 1., HOP4Y(14)}, - {PIP_X(id_W838) + 1., HOP4Y(14), PIP_X(id_W838) + top_wire_dist + 1., HOP4Y(12)}, - {PIP_X(id_W838) + top_wire_dist + 1., HOP4Y(12), wrap_len + 2., HOP4Y(12)}, - {wrap_len + 2., HOP4Y(12), wrap_len + 2., HOP4Y(13)}, - {wrap_len + 2., HOP4Y(13), PIP_X(id_W830) + 1., HOP4Y(13)}, - {PIP_X(id_W830) + 1., HOP4Y(13), PIP_X(id_W830) - top_wire_dist + 1., HOP4Y(11)}, - {PIP_X(id_W830) - top_wire_dist + 1., HOP4Y(11), PIP_X(id_W830) - 0., HOP4Y(11)}, - {PIP_X(id_W830) - 0., HOP4Y(11), PIP_X(id_W830) - top_wire_dist - 0., HOP4Y(9)}, - {PIP_X(id_W830) - top_wire_dist - 0., HOP4Y(9), PIP_X(id_W830) - 1., HOP4Y(9)}, - {PIP_X(id_W834) - 1., HOP4Y(9), PIP_X(id_W834) - 1., WIRE_Y(0)}, - {PIP_X(id_W830) - 1., HOP4Y(9), PIP_X(id_W830) - top_wire_dist - 1., HOP4Y(7)}, - {PIP_X(id_W830) - top_wire_dist - 1., HOP4Y(7), PIP_X(id_W830) - 2., HOP4Y(7)}, - {PIP_X(id_W830) - 2., HOP4Y(7), PIP_X(id_W830) - top_wire_dist - 2., HOP4Y(5)}, - {PIP_X(id_W830) - top_wire_dist - 2., HOP4Y(5), PIP_X(id_W830) - 3., HOP4Y(5)}, - {PIP_X(id_W830) - 3., HOP4Y(5), PIP_X(id_W830) - top_wire_dist - 3., HOP4Y(3)}, - {PIP_X(id_W830) - top_wire_dist - 3., HOP4Y(3), PIP_X(id_W830) - 4., HOP4Y(3)}, - {PIP_X(id_W830) - 4., HOP4Y(3), PIP_X(id_W830) - top_wire_dist - 4., HOP4Y(1)}, - {PIP_X(id_W830) - top_wire_dist - 4., HOP4Y(1), PIP_X(id_W838) - 5., HOP4Y(1)}, - {PIP_X(id_W838) - 5., HOP4Y(1), PIP_X(id_W838) - 5., WIRE_Y(0)}}}, - {id_E83_loop2, - {{PIP_X(id_E830), WIRE_Y(0), PIP_X(id_E830), HOP4Y(16)}, - {PIP_X(id_E830), HOP4Y(16), PIP_X(id_W838), HOP4Y(16)}, - {PIP_X(id_W838) + 0., HOP4Y(16), PIP_X(id_W838) + top_wire_dist + 0., HOP4Y(14)}, - {PIP_X(id_W838) + top_wire_dist + 0., HOP4Y(14), PIP_X(id_W838) + 1., HOP4Y(14)}, - {PIP_X(id_W838) + 1., HOP4Y(14), PIP_X(id_W838) + top_wire_dist + 1., HOP4Y(12)}, - {PIP_X(id_W838) + top_wire_dist + 1., HOP4Y(12), PIP_X(id_W838) + 2., HOP4Y(12)}, - {PIP_X(id_W838) + 2., HOP4Y(12), PIP_X(id_W838) + top_wire_dist + 2., HOP4Y(10)}, - {PIP_X(id_W838) + top_wire_dist + 2., HOP4Y(10), wrap_len + 3., HOP4Y(10)}, - {wrap_len + 3., HOP4Y(10), wrap_len + 3., HOP4Y(11)}, - {wrap_len + 3., HOP4Y(11), PIP_X(id_W830) + 2., HOP4Y(11)}, - {PIP_X(id_W830) + 2., HOP4Y(11), PIP_X(id_W830) - top_wire_dist + 2., HOP4Y(9)}, - {PIP_X(id_W830) - top_wire_dist + 2., HOP4Y(9), PIP_X(id_W830) + 1., HOP4Y(9)}, - {PIP_X(id_W834) + 1., HOP4Y(9), PIP_X(id_W834) + 1., WIRE_Y(0)}, - {PIP_X(id_W830) + 1., HOP4Y(9), PIP_X(id_W830) - top_wire_dist + 1., HOP4Y(7)}, - {PIP_X(id_W830) - top_wire_dist + 1., HOP4Y(7), PIP_X(id_W830) + 0., HOP4Y(7)}, - {PIP_X(id_W830) + 0., HOP4Y(7), PIP_X(id_W830) - top_wire_dist - 0., HOP4Y(5)}, - {PIP_X(id_W830) - top_wire_dist - 0., HOP4Y(5), PIP_X(id_W830) - 1., HOP4Y(5)}, - {PIP_X(id_W830) - 1., HOP4Y(5), PIP_X(id_W830) - top_wire_dist - 1., HOP4Y(3)}, - {PIP_X(id_W830) - top_wire_dist - 1., HOP4Y(3), PIP_X(id_W830) - 2., HOP4Y(3)}, - {PIP_X(id_W830) - 2., HOP4Y(3), PIP_X(id_W830) - top_wire_dist - 2., HOP4Y(1)}, - {PIP_X(id_W830) - top_wire_dist - 2., HOP4Y(1), PIP_X(id_W838) - 3., HOP4Y(1)}, - {PIP_X(id_W838) - 3., HOP4Y(1), PIP_X(id_W838) - 3., WIRE_Y(0)}}}, - {id_E83_loop3, - {{PIP_X(id_E830), WIRE_Y(0), PIP_X(id_E830), HOP4Y(16)}, - {PIP_X(id_E830), HOP4Y(16), PIP_X(id_W838), HOP4Y(16)}, - {PIP_X(id_W838) + 0., HOP4Y(16), PIP_X(id_W838) + top_wire_dist + 0., HOP4Y(14)}, - {PIP_X(id_W838) + top_wire_dist + 0., HOP4Y(14), PIP_X(id_W838) + 1., HOP4Y(14)}, - {PIP_X(id_W838) + 1., HOP4Y(14), PIP_X(id_W838) + top_wire_dist + 1., HOP4Y(12)}, - {PIP_X(id_W838) + top_wire_dist + 1., HOP4Y(12), PIP_X(id_W838) + 2., HOP4Y(12)}, - {PIP_X(id_W838) + 2., HOP4Y(12), PIP_X(id_W838) + top_wire_dist + 2., HOP4Y(10)}, - {PIP_X(id_W838) + top_wire_dist + 2., HOP4Y(10), PIP_X(id_W838) + 3., HOP4Y(10)}, - {PIP_X(id_W838) + 3., HOP4Y(10), PIP_X(id_W838) + top_wire_dist + 3., HOP4Y(8)}, - {PIP_X(id_W838) + top_wire_dist + 3., HOP4Y(8), wrap_len + 4., HOP4Y(8)}, - {wrap_len + 4., HOP4Y(8), wrap_len + 4., HOP4Y(9)}, - {wrap_len + 4., HOP4Y(9), PIP_X(id_W830) + 3., HOP4Y(9)}, - {PIP_X(id_W834) + 3., HOP4Y(9), PIP_X(id_W834) + 3., WIRE_Y(0)}, - {PIP_X(id_W830) + 3., HOP4Y(9), PIP_X(id_W830) - top_wire_dist + 3., HOP4Y(7)}, - {PIP_X(id_W830) - top_wire_dist + 3., HOP4Y(7), PIP_X(id_W830) + 2., HOP4Y(7)}, - {PIP_X(id_W830) + 2., HOP4Y(7), PIP_X(id_W830) - top_wire_dist + 2., HOP4Y(5)}, - {PIP_X(id_W830) - top_wire_dist + 2., HOP4Y(5), PIP_X(id_W830) + 1., HOP4Y(5)}, - {PIP_X(id_W830) + 1., HOP4Y(5), PIP_X(id_W830) - top_wire_dist + 1., HOP4Y(3)}, - {PIP_X(id_W830) - top_wire_dist + 1., HOP4Y(3), PIP_X(id_W830) - 0., HOP4Y(3)}, - {PIP_X(id_W830) - 0., HOP4Y(3), PIP_X(id_W830) - top_wire_dist - 0., HOP4Y(1)}, - {PIP_X(id_W830) - top_wire_dist - 0., HOP4Y(1), PIP_X(id_W838) - 1., HOP4Y(1)}, - {PIP_X(id_W838) - 1., HOP4Y(1), PIP_X(id_W838) - 1., WIRE_Y(0)}}}, - {id_E83_loop4, - {{PIP_X(id_E830), WIRE_Y(0), PIP_X(id_E830), HOP4Y(16)}, - {PIP_X(id_E830), HOP4Y(16), PIP_X(id_W838), HOP4Y(16)}, - {PIP_X(id_W838) + 0., HOP4Y(16), PIP_X(id_W838) + top_wire_dist + 0., HOP4Y(14)}, - {PIP_X(id_W838) + top_wire_dist + 0., HOP4Y(14), PIP_X(id_W838) + 1., HOP4Y(14)}, - {PIP_X(id_W838) + 1., HOP4Y(14), PIP_X(id_W838) + top_wire_dist + 1., HOP4Y(12)}, - {PIP_X(id_W838) + top_wire_dist + 1., HOP4Y(12), PIP_X(id_W838) + 2., HOP4Y(12)}, - {PIP_X(id_W838) + 2., HOP4Y(12), PIP_X(id_W838) + top_wire_dist + 2., HOP4Y(10)}, - {PIP_X(id_W838) + top_wire_dist + 2., HOP4Y(10), PIP_X(id_W838) + 3., HOP4Y(10)}, - {PIP_X(id_W838) + 3., HOP4Y(10), PIP_X(id_W838) + top_wire_dist + 3., HOP4Y(8)}, - {PIP_X(id_W838) + top_wire_dist + 3., HOP4Y(8), PIP_X(id_W838) + 4., HOP4Y(8)}, - {PIP_X(id_E834) + 4., HOP4Y(8), PIP_X(id_E834) + 4., WIRE_Y(0)}, - {PIP_X(id_W838) + 4., HOP4Y(8), PIP_X(id_W838) + top_wire_dist + 4., HOP4Y(6)}, - {PIP_X(id_W838) + top_wire_dist + 4., HOP4Y(6), wrap_len + 5., HOP4Y(6)}, - {wrap_len + 5., HOP4Y(6), wrap_len + 5., HOP4Y(7)}, - {wrap_len + 5., HOP4Y(7), PIP_X(id_W830) + 4., HOP4Y(7)}, - {PIP_X(id_W830) + 4., HOP4Y(7), PIP_X(id_W830) - top_wire_dist + 4., HOP4Y(5)}, - {PIP_X(id_W830) - top_wire_dist + 4., HOP4Y(5), PIP_X(id_W830) + 3., HOP4Y(5)}, - {PIP_X(id_W830) + 3., HOP4Y(5), PIP_X(id_W830) - top_wire_dist + 3., HOP4Y(3)}, - {PIP_X(id_W830) - top_wire_dist + 3., HOP4Y(3), PIP_X(id_W830) + 2., HOP4Y(3)}, - {PIP_X(id_W830) + 2., HOP4Y(3), PIP_X(id_W830) - top_wire_dist + 2., HOP4Y(1)}, - {PIP_X(id_W830) - top_wire_dist + 2., HOP4Y(1), PIP_X(id_W838) + 1., HOP4Y(1)}, - {PIP_X(id_W838) + 1., HOP4Y(1), PIP_X(id_W838) + 1., WIRE_Y(0)}}}, - {id_E83_loop5, - {{PIP_X(id_E830), WIRE_Y(0), PIP_X(id_E830), HOP4Y(16)}, - {PIP_X(id_E830), HOP4Y(16), PIP_X(id_W838), HOP4Y(16)}, - {PIP_X(id_W838) + 0., HOP4Y(16), PIP_X(id_W838) + top_wire_dist + 0., HOP4Y(14)}, - {PIP_X(id_W838) + top_wire_dist + 0., HOP4Y(14), PIP_X(id_W838) + 1., HOP4Y(14)}, - {PIP_X(id_W838) + 1., HOP4Y(14), PIP_X(id_W838) + top_wire_dist + 1., HOP4Y(12)}, - {PIP_X(id_W838) + top_wire_dist + 1., HOP4Y(12), PIP_X(id_W838) + 2., HOP4Y(12)}, - {PIP_X(id_W838) + 2., HOP4Y(12), PIP_X(id_W838) + top_wire_dist + 2., HOP4Y(10)}, - {PIP_X(id_W838) + top_wire_dist + 2., HOP4Y(10), PIP_X(id_W838) + 3., HOP4Y(10)}, - {PIP_X(id_W838) + 3., HOP4Y(10), PIP_X(id_W838) + top_wire_dist + 3., HOP4Y(8)}, - {PIP_X(id_W838) + top_wire_dist + 3., HOP4Y(8), PIP_X(id_W838) + 4., HOP4Y(8)}, - {PIP_X(id_E834) + 4., HOP4Y(8), PIP_X(id_E834) + 4., WIRE_Y(0)}, - {PIP_X(id_W838) + 4., HOP4Y(8), PIP_X(id_W838) + top_wire_dist + 4., HOP4Y(6)}, - {PIP_X(id_W838) + top_wire_dist + 4., HOP4Y(6), PIP_X(id_W838) + 5., HOP4Y(6)}, - {PIP_X(id_W838) + 5., HOP4Y(6), PIP_X(id_W838) + top_wire_dist + 5., HOP4Y(4)}, - {PIP_X(id_W838) + top_wire_dist + 5., HOP4Y(4), wrap_len + 6., HOP4Y(4)}, - {wrap_len + 6., HOP4Y(4), wrap_len + 6., HOP4Y(5)}, - {wrap_len + 6., HOP4Y(5), PIP_X(id_W830) + 5., HOP4Y(5)}, - {PIP_X(id_W830) + 5., HOP4Y(5), PIP_X(id_W830) - top_wire_dist + 5., HOP4Y(3)}, - {PIP_X(id_W830) - top_wire_dist + 5., HOP4Y(3), PIP_X(id_W830) + 4., HOP4Y(3)}, - {PIP_X(id_W830) + 4., HOP4Y(3), PIP_X(id_W830) - top_wire_dist + 4., HOP4Y(1)}, - {PIP_X(id_W830) - top_wire_dist + 4., HOP4Y(1), PIP_X(id_W838) + 3., HOP4Y(1)}, - {PIP_X(id_W838) + 3., HOP4Y(1), PIP_X(id_W838) + 3., WIRE_Y(0)}}}, - {id_E83_loop6, - {{PIP_X(id_E830), WIRE_Y(0), PIP_X(id_E830), HOP4Y(16)}, - {PIP_X(id_E830), HOP4Y(16), PIP_X(id_W838), HOP4Y(16)}, - {PIP_X(id_W838) + 0., HOP4Y(16), PIP_X(id_W838) + top_wire_dist + 0., HOP4Y(14)}, - {PIP_X(id_W838) + top_wire_dist + 0., HOP4Y(14), PIP_X(id_W838) + 1., HOP4Y(14)}, - {PIP_X(id_W838) + 1., HOP4Y(14), PIP_X(id_W838) + top_wire_dist + 1., HOP4Y(12)}, - {PIP_X(id_W838) + top_wire_dist + 1., HOP4Y(12), PIP_X(id_W838) + 2., HOP4Y(12)}, - {PIP_X(id_W838) + 2., HOP4Y(12), PIP_X(id_W838) + top_wire_dist + 2., HOP4Y(10)}, - {PIP_X(id_W838) + top_wire_dist + 2., HOP4Y(10), PIP_X(id_W838) + 3., HOP4Y(10)}, - {PIP_X(id_W838) + 3., HOP4Y(10), PIP_X(id_W838) + top_wire_dist + 3., HOP4Y(8)}, - {PIP_X(id_W838) + top_wire_dist + 3., HOP4Y(8), PIP_X(id_W838) + 4., HOP4Y(8)}, - {PIP_X(id_W838) + 4., HOP4Y(8), PIP_X(id_W838) + top_wire_dist + 4., HOP4Y(6)}, - {PIP_X(id_E834) + 4., HOP4Y(8), PIP_X(id_E834) + 4., WIRE_Y(0)}, - {PIP_X(id_W838) + top_wire_dist + 4., HOP4Y(6), PIP_X(id_W838) + 5., HOP4Y(6)}, - {PIP_X(id_W838) + 5., HOP4Y(6), PIP_X(id_W838) + top_wire_dist + 5., HOP4Y(4)}, - {PIP_X(id_W838) + top_wire_dist + 5., HOP4Y(4), PIP_X(id_W838) + 6., HOP4Y(4)}, - {PIP_X(id_W838) + 6., HOP4Y(4), PIP_X(id_W838) + top_wire_dist + 6., HOP4Y(2)}, - {PIP_X(id_W838) + top_wire_dist + 6., HOP4Y(2), wrap_len + 7., HOP4Y(2)}, - {wrap_len + 7., HOP4Y(2), wrap_len + 7., HOP4Y(3)}, - {wrap_len + 7., HOP4Y(3), PIP_X(id_W830) + 6., HOP4Y(3)}, - {PIP_X(id_W830) + 6., HOP4Y(3), PIP_X(id_W830) - top_wire_dist + 6., HOP4Y(1)}, - {PIP_X(id_W830) - top_wire_dist + 6., HOP4Y(1), PIP_X(id_W838) + 5., HOP4Y(1)}, - {PIP_X(id_W838) + 5., HOP4Y(1), PIP_X(id_W838) + 5., WIRE_Y(0)}}}, - {id_E83_loop7, - {{PIP_X(id_E830), WIRE_Y(0), PIP_X(id_E830), HOP4Y(16)}, - {PIP_X(id_E830), HOP4Y(16), PIP_X(id_W838), HOP4Y(16)}, - {PIP_X(id_W838) + 0., HOP4Y(16), PIP_X(id_W838) + top_wire_dist + 0., HOP4Y(14)}, - {PIP_X(id_W838) + top_wire_dist + 0., HOP4Y(14), PIP_X(id_W838) + 1., HOP4Y(14)}, - {PIP_X(id_W838) + 1., HOP4Y(14), PIP_X(id_W838) + top_wire_dist + 1., HOP4Y(12)}, - {PIP_X(id_W838) + top_wire_dist + 1., HOP4Y(12), PIP_X(id_W838) + 2., HOP4Y(12)}, - {PIP_X(id_W838) + 2., HOP4Y(12), PIP_X(id_W838) + top_wire_dist + 2., HOP4Y(10)}, - {PIP_X(id_W838) + top_wire_dist + 2., HOP4Y(10), PIP_X(id_W838) + 3., HOP4Y(10)}, - {PIP_X(id_W838) + 3., HOP4Y(10), PIP_X(id_W838) + top_wire_dist + 3., HOP4Y(8)}, - {PIP_X(id_W838) + top_wire_dist + 3., HOP4Y(8), PIP_X(id_W838) + 4., HOP4Y(8)}, - {PIP_X(id_W838) + 4., HOP4Y(8), PIP_X(id_W838) + top_wire_dist + 4., HOP4Y(6)}, - {PIP_X(id_E834) + 4., HOP4Y(8), PIP_X(id_E834) + 4., WIRE_Y(0)}, - {PIP_X(id_W838) + top_wire_dist + 4., HOP4Y(6), PIP_X(id_W838) + 5., HOP4Y(6)}, - {PIP_X(id_W838) + 5., HOP4Y(6), PIP_X(id_W838) + top_wire_dist + 5., HOP4Y(4)}, - {PIP_X(id_W838) + top_wire_dist + 5., HOP4Y(4), PIP_X(id_W838) + 6., HOP4Y(4)}, - {PIP_X(id_W838) + 6., HOP4Y(4), PIP_X(id_W838) + top_wire_dist + 6., HOP4Y(2)}, - {PIP_X(id_W838) + top_wire_dist + 6., HOP4Y(2), PIP_X(id_W838) + 7., HOP4Y(2)}, - {PIP_X(id_W838) + 7., HOP4Y(2), PIP_X(id_W838) + top_wire_dist + 7., HOP4Y(0)}, - {PIP_X(id_W838) + top_wire_dist + 7., HOP4Y(0), wrap_len + 8., HOP4Y(0)}, - {wrap_len + 8., HOP4Y(0), wrap_len + 8., HOP4Y(1)}, - {wrap_len + 8., HOP4Y(1), PIP_X(id_W838) + 7., HOP4Y(1)}, - {PIP_X(id_W838) + 7., HOP4Y(1), PIP_X(id_W838) + 7., WIRE_Y(0)}}}, - {id_W83_loop0, - {{PIP_X(id_W830), WIRE_Y(0), PIP_X(id_W830), HOP4Y(17)}, - {PIP_X(id_W830) - 0., HOP4Y(17), PIP_X(id_W830) - top_wire_dist - 0., HOP4Y(15)}, - {PIP_X(id_W830) - top_wire_dist - 0., HOP4Y(15), -wrap_len - 0., HOP4Y(15)}, - {-wrap_len - 0., HOP4Y(15), -wrap_len - 0., HOP4Y(14)}, - {-wrap_len - 0., HOP4Y(14), PIP_X(id_W838) + 0., HOP4Y(14)}, - {PIP_X(id_W838) + 0., HOP4Y(14), PIP_X(id_W838) + top_wire_dist + 0., HOP4Y(12)}, - {PIP_X(id_W838) + top_wire_dist + 0., HOP4Y(12), PIP_X(id_W838) + 1., HOP4Y(12)}, - {PIP_X(id_W838) + 1., HOP4Y(12), PIP_X(id_W838) + top_wire_dist + 1., HOP4Y(10)}, - {PIP_X(id_W838) + top_wire_dist + 1., HOP4Y(10), PIP_X(id_W838) + 2., HOP4Y(10)}, - {PIP_X(id_W838) + 2., HOP4Y(10), PIP_X(id_W838) + top_wire_dist + 2., HOP4Y(8)}, - {PIP_X(id_W838) + top_wire_dist + 2., HOP4Y(8), PIP_X(id_W838) + 3., HOP4Y(8)}, - {PIP_X(id_W838) + 3., HOP4Y(8), PIP_X(id_W838) + top_wire_dist + 3., HOP4Y(6)}, - {PIP_X(id_E834) + 3., HOP4Y(8), PIP_X(id_E834) + 3., WIRE_Y(0)}, - {PIP_X(id_W838) + top_wire_dist + 3., HOP4Y(6), PIP_X(id_W838) + 4., HOP4Y(6)}, - {PIP_X(id_W838) + 4., HOP4Y(6), PIP_X(id_W838) + top_wire_dist + 4., HOP4Y(4)}, - {PIP_X(id_W838) + top_wire_dist + 4., HOP4Y(4), PIP_X(id_W838) + 5., HOP4Y(4)}, - {PIP_X(id_W838) + 5., HOP4Y(4), PIP_X(id_W838) + top_wire_dist + 5., HOP4Y(2)}, - {PIP_X(id_W838) + top_wire_dist + 5., HOP4Y(2), PIP_X(id_W838) + 6., HOP4Y(2)}, - {PIP_X(id_W838) + 6., HOP4Y(2), PIP_X(id_W838) + top_wire_dist + 6., HOP4Y(0)}, - {PIP_X(id_W838) + top_wire_dist + 6., HOP4Y(0), PIP_X(id_E838) + 7., HOP4Y(0)}, - {PIP_X(id_E838) + 7., HOP4Y(0), PIP_X(id_E838) + 7., WIRE_Y(0)}}}, - {id_W83_loop1, - {{PIP_X(id_W830), WIRE_Y(0), PIP_X(id_W830), HOP4Y(17)}, - {PIP_X(id_W830) - 0., HOP4Y(17), PIP_X(id_W830) - top_wire_dist - 0., HOP4Y(15)}, - {PIP_X(id_W830) - top_wire_dist - 0., HOP4Y(15), PIP_X(id_W830) - 1., HOP4Y(15)}, - {PIP_X(id_W830) - 1., HOP4Y(15), PIP_X(id_W830) - top_wire_dist - 1., HOP4Y(13)}, - {PIP_X(id_W830) - top_wire_dist - 1., HOP4Y(13), -wrap_len - 1., HOP4Y(13)}, - {-wrap_len - 1., HOP4Y(13), -wrap_len - 1., HOP4Y(12)}, - {-wrap_len - 1., HOP4Y(12), PIP_X(id_W838) - 1., HOP4Y(12)}, - {PIP_X(id_W838) - 1., HOP4Y(12), PIP_X(id_W838) + top_wire_dist - 1., HOP4Y(10)}, - {PIP_X(id_W838) + top_wire_dist - 1., HOP4Y(10), PIP_X(id_W838) + 0., HOP4Y(10)}, - {PIP_X(id_W838) + 0., HOP4Y(10), PIP_X(id_W838) + top_wire_dist + 0., HOP4Y(8)}, - {PIP_X(id_W838) + top_wire_dist + 0., HOP4Y(8), PIP_X(id_W838) + 1., HOP4Y(8)}, - {PIP_X(id_W838) + 1., HOP4Y(8), PIP_X(id_W838) + top_wire_dist + 1., HOP4Y(6)}, - {PIP_X(id_E834) + 1., HOP4Y(8), PIP_X(id_E834) + 1., WIRE_Y(0)}, - {PIP_X(id_W838) + top_wire_dist + 1., HOP4Y(6), PIP_X(id_W838) + 2., HOP4Y(6)}, - {PIP_X(id_W838) + 2., HOP4Y(6), PIP_X(id_W838) + top_wire_dist + 2., HOP4Y(4)}, - {PIP_X(id_W838) + top_wire_dist + 2., HOP4Y(4), PIP_X(id_W838) + 3., HOP4Y(4)}, - {PIP_X(id_W838) + 3., HOP4Y(4), PIP_X(id_W838) + top_wire_dist + 3., HOP4Y(2)}, - {PIP_X(id_W838) + top_wire_dist + 3., HOP4Y(2), PIP_X(id_W838) + 4., HOP4Y(2)}, - {PIP_X(id_W838) + 4., HOP4Y(2), PIP_X(id_W838) + top_wire_dist + 4., HOP4Y(0)}, - {PIP_X(id_W838) + top_wire_dist + 4., HOP4Y(0), PIP_X(id_E838) + 5., HOP4Y(0)}, - {PIP_X(id_E838) + 5., HOP4Y(0), PIP_X(id_E838) + 5., WIRE_Y(0)}}}, - {id_W83_loop2, - {{PIP_X(id_W830), WIRE_Y(0), PIP_X(id_W830), HOP4Y(17)}, - {PIP_X(id_W830) - 0., HOP4Y(17), PIP_X(id_W830) - top_wire_dist - 0., HOP4Y(15)}, - {PIP_X(id_W830) - top_wire_dist - 0., HOP4Y(15), PIP_X(id_W830) - 1., HOP4Y(15)}, - {PIP_X(id_W830) - 1., HOP4Y(15), PIP_X(id_W830) - top_wire_dist - 1., HOP4Y(13)}, - {PIP_X(id_W830) - top_wire_dist - 1., HOP4Y(13), PIP_X(id_W830) - 2., HOP4Y(13)}, - {PIP_X(id_W830) - 2., HOP4Y(13), PIP_X(id_W830) - top_wire_dist - 2., HOP4Y(11)}, - {PIP_X(id_W830) - top_wire_dist - 2., HOP4Y(11), -wrap_len - 2., HOP4Y(11)}, - {-wrap_len - 2., HOP4Y(11), -wrap_len - 2., HOP4Y(10)}, - {-wrap_len - 2., HOP4Y(10), PIP_X(id_W838) - 2., HOP4Y(10)}, - {PIP_X(id_W838) - 2., HOP4Y(10), PIP_X(id_W838) + top_wire_dist - 2., HOP4Y(8)}, - {PIP_X(id_W838) + top_wire_dist - 2., HOP4Y(8), PIP_X(id_W838) - 1., HOP4Y(8)}, - {PIP_X(id_W838) - 1., HOP4Y(8), PIP_X(id_W838) + top_wire_dist - 1., HOP4Y(6)}, - {PIP_X(id_E834) - 1., HOP4Y(8), PIP_X(id_E834) - 1., WIRE_Y(0)}, - {PIP_X(id_W838) + top_wire_dist - 1., HOP4Y(6), PIP_X(id_W838) + 0., HOP4Y(6)}, - {PIP_X(id_W838) + 0., HOP4Y(6), PIP_X(id_W838) + top_wire_dist + 0., HOP4Y(4)}, - {PIP_X(id_W838) + top_wire_dist + 0., HOP4Y(4), PIP_X(id_W838) + 1., HOP4Y(4)}, - {PIP_X(id_W838) + 1., HOP4Y(4), PIP_X(id_W838) + top_wire_dist + 1., HOP4Y(2)}, - {PIP_X(id_W838) + top_wire_dist + 1., HOP4Y(2), PIP_X(id_W838) + 2., HOP4Y(2)}, - {PIP_X(id_W838) + 2., HOP4Y(2), PIP_X(id_W838) + top_wire_dist + 2., HOP4Y(0)}, - {PIP_X(id_W838) + top_wire_dist + 2., HOP4Y(0), PIP_X(id_E838) + 3., HOP4Y(0)}, - {PIP_X(id_E838) + 3., HOP4Y(0), PIP_X(id_E838) + 3., WIRE_Y(0)}}}, - {id_W83_loop3, - {{PIP_X(id_W830), WIRE_Y(0), PIP_X(id_W830), HOP4Y(17)}, - {PIP_X(id_W830) - 0., HOP4Y(17), PIP_X(id_W830) - top_wire_dist - 0., HOP4Y(15)}, - {PIP_X(id_W830) - top_wire_dist - 0., HOP4Y(15), PIP_X(id_W830) - 1., HOP4Y(15)}, - {PIP_X(id_W830) - 1., HOP4Y(15), PIP_X(id_W830) - top_wire_dist - 1., HOP4Y(13)}, - {PIP_X(id_W830) - top_wire_dist - 1., HOP4Y(13), PIP_X(id_W830) - 2., HOP4Y(13)}, - {PIP_X(id_W830) - 2., HOP4Y(13), PIP_X(id_W830) - top_wire_dist - 2., HOP4Y(11)}, - {PIP_X(id_W830) - top_wire_dist - 2., HOP4Y(11), PIP_X(id_W830) - 3., HOP4Y(11)}, - {PIP_X(id_W830) - 3., HOP4Y(11), PIP_X(id_W830) - top_wire_dist - 3., HOP4Y(9)}, - {PIP_X(id_W830) - top_wire_dist - 3., HOP4Y(9), -wrap_len - 3., HOP4Y(9)}, - {-wrap_len - 3., HOP4Y(9), -wrap_len - 3., HOP4Y(8)}, - {-wrap_len - 3., HOP4Y(8), PIP_X(id_W838) - 3., HOP4Y(8)}, - {PIP_X(id_W838) - 3., HOP4Y(8), PIP_X(id_W838) + top_wire_dist - 3., HOP4Y(6)}, - {PIP_X(id_E834) - 3., HOP4Y(8), PIP_X(id_E834) - 3., WIRE_Y(0)}, - {PIP_X(id_W838) + top_wire_dist - 3., HOP4Y(6), PIP_X(id_W838) - 2., HOP4Y(6)}, - {PIP_X(id_W838) - 2., HOP4Y(6), PIP_X(id_W838) + top_wire_dist - 2., HOP4Y(4)}, - {PIP_X(id_W838) + top_wire_dist - 2., HOP4Y(4), PIP_X(id_W838) - 1., HOP4Y(4)}, - {PIP_X(id_W838) - 1., HOP4Y(4), PIP_X(id_W838) + top_wire_dist - 1., HOP4Y(2)}, - {PIP_X(id_W838) + top_wire_dist - 1., HOP4Y(2), PIP_X(id_W838) + 0., HOP4Y(2)}, - {PIP_X(id_W838) + 0., HOP4Y(2), PIP_X(id_W838) + top_wire_dist + 0., HOP4Y(0)}, - {PIP_X(id_W838) + top_wire_dist + 0., HOP4Y(0), PIP_X(id_E838) + 1., HOP4Y(0)}, - {PIP_X(id_E838) + 1., HOP4Y(0), PIP_X(id_E838) + 1., WIRE_Y(0)}}}, - {id_W83_loop4, - {{PIP_X(id_W830), WIRE_Y(0), PIP_X(id_W830), HOP4Y(17)}, - {PIP_X(id_W830) - 0., HOP4Y(17), PIP_X(id_W830) - top_wire_dist - 0., HOP4Y(15)}, - {PIP_X(id_W830) - top_wire_dist - 0., HOP4Y(15), PIP_X(id_W830) - 1., HOP4Y(15)}, - {PIP_X(id_W830) - 1., HOP4Y(15), PIP_X(id_W830) - top_wire_dist - 1., HOP4Y(13)}, - {PIP_X(id_W830) - top_wire_dist - 1., HOP4Y(13), PIP_X(id_W830) - 2., HOP4Y(13)}, - {PIP_X(id_W830) - 2., HOP4Y(13), PIP_X(id_W830) - top_wire_dist - 2., HOP4Y(11)}, - {PIP_X(id_W830) - top_wire_dist - 2., HOP4Y(11), PIP_X(id_W830) - 3., HOP4Y(11)}, - {PIP_X(id_W830) - 3., HOP4Y(11), PIP_X(id_W830) - top_wire_dist - 3., HOP4Y(9)}, - {PIP_X(id_W830) - top_wire_dist - 3., HOP4Y(9), PIP_X(id_W830) - 4., HOP4Y(9)}, - {PIP_X(id_W830) - 4., HOP4Y(9), PIP_X(id_W830) - top_wire_dist - 4., HOP4Y(7)}, - {PIP_X(id_W830) - top_wire_dist - 4., HOP4Y(7), -wrap_len - 4., HOP4Y(7)}, - {-wrap_len - 4., HOP4Y(7), -wrap_len - 4., HOP4Y(6)}, - {PIP_X(id_W834) - 4., HOP4Y(6), PIP_X(id_W834) - 4., WIRE_Y(0)}, - {-wrap_len - 4., HOP4Y(6), PIP_X(id_W838) - 4., HOP4Y(6)}, - {PIP_X(id_W838) - 4., HOP4Y(6), PIP_X(id_W838) + top_wire_dist - 4., HOP4Y(4)}, - {PIP_X(id_W838) + top_wire_dist - 4., HOP4Y(4), PIP_X(id_W838) - 3., HOP4Y(4)}, - {PIP_X(id_W838) - 3., HOP4Y(4), PIP_X(id_W838) + top_wire_dist - 3., HOP4Y(2)}, - {PIP_X(id_W838) + top_wire_dist - 3., HOP4Y(2), PIP_X(id_W838) - 2., HOP4Y(2)}, - {PIP_X(id_W838) - 2., HOP4Y(2), PIP_X(id_W838) + top_wire_dist - 2., HOP4Y(0)}, - {PIP_X(id_W838) + top_wire_dist - 2., HOP4Y(0), PIP_X(id_E838) - 1., HOP4Y(0)}, - {PIP_X(id_E838) - 1., HOP4Y(0), PIP_X(id_E838) - 1., WIRE_Y(0)}}}, - {id_W83_loop5, - {{PIP_X(id_W830), WIRE_Y(0), PIP_X(id_W830), HOP4Y(17)}, - {PIP_X(id_W830) - 0., HOP4Y(17), PIP_X(id_W830) - top_wire_dist - 0., HOP4Y(15)}, - {PIP_X(id_W830) - top_wire_dist - 0., HOP4Y(15), PIP_X(id_W830) - 1., HOP4Y(15)}, - {PIP_X(id_W830) - 1., HOP4Y(15), PIP_X(id_W830) - top_wire_dist - 1., HOP4Y(13)}, - {PIP_X(id_W830) - top_wire_dist - 1., HOP4Y(13), PIP_X(id_W830) - 2., HOP4Y(13)}, - {PIP_X(id_W830) - 2., HOP4Y(13), PIP_X(id_W830) - top_wire_dist - 2., HOP4Y(11)}, - {PIP_X(id_W830) - top_wire_dist - 2., HOP4Y(11), PIP_X(id_W830) - 3., HOP4Y(11)}, - {PIP_X(id_W830) - 3., HOP4Y(11), PIP_X(id_W830) - top_wire_dist - 3., HOP4Y(9)}, - {PIP_X(id_W830) - top_wire_dist - 3., HOP4Y(9), PIP_X(id_W830) - 4., HOP4Y(9)}, - {PIP_X(id_W830) - 4., HOP4Y(9), PIP_X(id_W830) - top_wire_dist - 4., HOP4Y(7)}, - {PIP_X(id_W834) - 4., HOP4Y(9), PIP_X(id_W834) - 4., WIRE_Y(0)}, - {PIP_X(id_W830) - top_wire_dist - 4., HOP4Y(7), PIP_X(id_W830) - 5., HOP4Y(7)}, - {PIP_X(id_W830) - 5., HOP4Y(7), PIP_X(id_W830) - top_wire_dist - 5., HOP4Y(5)}, - {PIP_X(id_W830) - top_wire_dist - 5., HOP4Y(5), -wrap_len - 5., HOP4Y(5)}, - {-wrap_len - 5., HOP4Y(5), -wrap_len - 5., HOP4Y(4)}, - {-wrap_len - 5., HOP4Y(4), PIP_X(id_W838) - 5., HOP4Y(4)}, - {PIP_X(id_W838) - 5., HOP4Y(4), PIP_X(id_W838) + top_wire_dist - 5., HOP4Y(2)}, - {PIP_X(id_W838) + top_wire_dist - 5., HOP4Y(2), PIP_X(id_W838) - 4., HOP4Y(2)}, - {PIP_X(id_W838) - 4., HOP4Y(2), PIP_X(id_W838) + top_wire_dist - 4., HOP4Y(0)}, - {PIP_X(id_W838) + top_wire_dist - 4., HOP4Y(0), PIP_X(id_E838) - 3., HOP4Y(0)}, - {PIP_X(id_E838) - 3., HOP4Y(0), PIP_X(id_E838) - 3., WIRE_Y(0)}}}, - {id_W83_loop6, - {{PIP_X(id_W830), WIRE_Y(0), PIP_X(id_W830), HOP4Y(17)}, - {PIP_X(id_W830) - 0., HOP4Y(17), PIP_X(id_W830) - top_wire_dist - 0., HOP4Y(15)}, - {PIP_X(id_W830) - top_wire_dist - 0., HOP4Y(15), PIP_X(id_W830) - 1., HOP4Y(15)}, - {PIP_X(id_W830) - 1., HOP4Y(15), PIP_X(id_W830) - top_wire_dist - 1., HOP4Y(13)}, - {PIP_X(id_W830) - top_wire_dist - 1., HOP4Y(13), PIP_X(id_W830) - 2., HOP4Y(13)}, - {PIP_X(id_W830) - 2., HOP4Y(13), PIP_X(id_W830) - top_wire_dist - 2., HOP4Y(11)}, - {PIP_X(id_W830) - top_wire_dist - 2., HOP4Y(11), PIP_X(id_W830) - 3., HOP4Y(11)}, - {PIP_X(id_W830) - 3., HOP4Y(11), PIP_X(id_W830) - top_wire_dist - 3., HOP4Y(9)}, - {PIP_X(id_W830) - top_wire_dist - 3., HOP4Y(9), PIP_X(id_W830) - 4., HOP4Y(9)}, - {PIP_X(id_W830) - 4., HOP4Y(9), PIP_X(id_W830) - top_wire_dist - 4., HOP4Y(7)}, - {PIP_X(id_W834) - 4., HOP4Y(9), PIP_X(id_W834) - 4., WIRE_Y(0)}, - {PIP_X(id_W830) - top_wire_dist - 4., HOP4Y(7), PIP_X(id_W830) - 5., HOP4Y(7)}, - {PIP_X(id_W830) - 5., HOP4Y(7), PIP_X(id_W830) - top_wire_dist - 5., HOP4Y(5)}, - {PIP_X(id_W830) - top_wire_dist - 5., HOP4Y(5), PIP_X(id_W830) - 6., HOP4Y(5)}, - {PIP_X(id_W830) - 6., HOP4Y(5), PIP_X(id_W830) - top_wire_dist - 6., HOP4Y(3)}, - {PIP_X(id_W830) - top_wire_dist - 6., HOP4Y(3), -wrap_len - 6., HOP4Y(3)}, - {-wrap_len - 6., HOP4Y(3), -wrap_len - 6., HOP4Y(2)}, - {-wrap_len - 6., HOP4Y(2), PIP_X(id_W838) - 6., HOP4Y(2)}, - {PIP_X(id_W838) - 6., HOP4Y(2), PIP_X(id_W838) + top_wire_dist - 6., HOP4Y(0)}, - {PIP_X(id_W838) + top_wire_dist - 6., HOP4Y(0), PIP_X(id_E838) - 5., HOP4Y(0)}, - {PIP_X(id_E838) - 5., HOP4Y(0), PIP_X(id_E838) - 5., WIRE_Y(0)}}}, - {id_W83_loop7, - {{PIP_X(id_W830), WIRE_Y(0), PIP_X(id_W830), HOP4Y(17)}, - {PIP_X(id_W830) - 0., HOP4Y(17), PIP_X(id_W830) - top_wire_dist - 0., HOP4Y(15)}, - {PIP_X(id_W830) - top_wire_dist - 0., HOP4Y(15), PIP_X(id_W830) - 1., HOP4Y(15)}, - {PIP_X(id_W830) - 1., HOP4Y(15), PIP_X(id_W830) - top_wire_dist - 1., HOP4Y(13)}, - {PIP_X(id_W830) - top_wire_dist - 1., HOP4Y(13), PIP_X(id_W830) - 2., HOP4Y(13)}, - {PIP_X(id_W830) - 2., HOP4Y(13), PIP_X(id_W830) - top_wire_dist - 2., HOP4Y(11)}, - {PIP_X(id_W830) - top_wire_dist - 2., HOP4Y(11), PIP_X(id_W830) - 3., HOP4Y(11)}, - {PIP_X(id_W830) - 3., HOP4Y(11), PIP_X(id_W830) - top_wire_dist - 3., HOP4Y(9)}, - {PIP_X(id_W830) - top_wire_dist - 3., HOP4Y(9), PIP_X(id_W830) - 4., HOP4Y(9)}, - {PIP_X(id_W830) - 4., HOP4Y(9), PIP_X(id_W830) - top_wire_dist - 4., HOP4Y(7)}, - {PIP_X(id_W834) - 4., HOP4Y(9), PIP_X(id_W834) - 4., WIRE_Y(0)}, - {PIP_X(id_W830) - top_wire_dist - 4., HOP4Y(7), PIP_X(id_W830) - 5., HOP4Y(7)}, - {PIP_X(id_W830) - 5., HOP4Y(7), PIP_X(id_W830) - top_wire_dist - 5., HOP4Y(5)}, - {PIP_X(id_W830) - top_wire_dist - 5., HOP4Y(5), PIP_X(id_W830) - 6., HOP4Y(5)}, - {PIP_X(id_W830) - 6., HOP4Y(5), PIP_X(id_W830) - top_wire_dist - 6., HOP4Y(3)}, - {PIP_X(id_W830) - top_wire_dist - 6., HOP4Y(3), PIP_X(id_W830) - 7., HOP4Y(3)}, - {PIP_X(id_W830) - 7., HOP4Y(3), PIP_X(id_W830) - top_wire_dist - 7., HOP4Y(1)}, - {PIP_X(id_W830) - top_wire_dist - 7., HOP4Y(1), -wrap_len - 7., HOP4Y(1)}, - {-wrap_len - 7., HOP4Y(1), -wrap_len - 7., HOP4Y(0)}, - {-wrap_len - 7., HOP4Y(0), PIP_X(id_E838) - 7., HOP4Y(0)}, - {PIP_X(id_E838) - 7., HOP4Y(0), PIP_X(id_E838) - 7., WIRE_Y(0)}}}, -}; -const int PIP_SRC_DST_LEN = 20; - -static void get_pip_xy(CruSide side, float &off, float &x, float &y) -{ - switch (side) { - case Top: - x = off; - y = cru_y + cru_h; - break; - case Bottom: - x = off; - y = cru_y; - break; - case Left: - x = cru_x; - y = off; - break; - case Right: - x = cru_x + cru_w; - y = off; - break; - case Center: - x = cru_x + cru_w / 2.f; - y = off; - break; - } -} - -void gfxSetPipDefaultDecal(Arch *arch, PipInfo &pip) -{ - DecalXY active, inactive; - std::vector split_res; - IdString src_loc_id, dst_loc_id; - char buf[PIP_SRC_DST_LEN]; - - active.x = inactive.x = pip.loc.x; - active.y = inactive.y = arch->gridDimY - 1. - pip.loc.y; - boost::split(split_res, pip.name.str(arch), [](char c) { return c == '_'; }); - src_loc_id = arch->id(split_res.at(1)); - dst_loc_id = arch->id(split_res.at(2)); - snprintf(buf, PIP_SRC_DST_LEN, "%s_%s_active", src_loc_id.c_str(arch), dst_loc_id.c_str(arch)); - IdString active_id = arch->id(buf); - active.decal = active_id; - snprintf(buf, PIP_SRC_DST_LEN, "%s_%s_inactive", src_loc_id.c_str(arch), dst_loc_id.c_str(arch)); - IdString inactive_id = arch->id(buf); - inactive.decal = inactive_id; - // create if absent - if (arch->decal_graphics.count(active_id) == 0) { - // clock? - if (dst_loc_id.in(id_GT00, id_GT10)) { - WireInfo &wi = arch->wire_info(pip.srcWire); - if (wi.type.str(arch).substr(0, 5) == "SPINE") { - // create pip - GraphicElement el; - el.type = GraphicElement::TYPE_LOCAL_LINE; - el.style = GraphicElement::STYLE_ACTIVE; - if (dst_loc_id == id_GT00) { - el.x1 = WIRE_X(CLK_GT00_X); - } else { - el.x1 = WIRE_X(CLK_GT10_X); - } - el.x2 = el.x1 + spine_pip_off; - el.y2 = spineY.at(arch->wire_info(pip.srcWire).type); - el.y1 = el.y2 - spine_pip_off; - arch->addDecalGraphic(active_id, el); - el.style = GraphicElement::STYLE_INACTIVE; - arch->addDecalGraphic(inactive_id, el); - } - } else { - // XXX - if (pipPoint.count(src_loc_id) == 0 || pipPoint.count(dst_loc_id) == 0) { - // std::cout << "*R" << pip.loc.y + 1 << "C" << pip.loc.x + 1 << " no " << pip.name.str(arch) << " " << - // buf << std::endl; - } else { - GraphicElement el; - el.type = GraphicElement::TYPE_LOCAL_ARROW; - el.style = GraphicElement::STYLE_ACTIVE; - CruSide srcSide = pipPoint.at(src_loc_id).first; - float srcOff = pipPoint.at(src_loc_id).second; - CruSide dstSide = pipPoint.at(dst_loc_id).first; - float dstOff = pipPoint.at(dst_loc_id).second; - if (srcSide != dstSide) { - get_pip_xy(srcSide, srcOff, el.x1, el.y1); - get_pip_xy(dstSide, dstOff, el.x2, el.y2); - arch->addDecalGraphic(active_id, el); - el.style = GraphicElement::STYLE_HIDDEN; - arch->addDecalGraphic(inactive_id, el); - } else { - get_pip_xy(srcSide, srcOff, el.x1, el.y1); - float dst_x = 0, dst_y = 0, m_x = 0, m_y = 0; - get_pip_xy(dstSide, dstOff, dst_x, dst_y); - switch (dstSide) { - case Top: - m_x = el.x1 + (dst_x - el.x1) / 2.f; - m_y = dst_y - std::max(cru_h * 0.1f, std::min(cru_h * 0.4f, std::abs(el.x1 - dst_x))); - break; - case Bottom: - m_x = el.x1 + (dst_x - el.x1) / 2.f; - m_y = dst_y + std::max(cru_h * 0.1f, std::min(cru_h * 0.4f, std::abs(el.x1 - dst_x))); - break; - case Right: - m_x = dst_x - std::max(cru_w * 0.1f, std::min(cru_w * 0.4f, std::abs(el.y1 - dst_y))); - m_y = el.y1 + (dst_y - el.y1) / 2.f; - break; - case Left: - m_x = dst_x + std::max(cru_w * 0.1f, std::min(cru_w * 0.4f, std::abs(el.y1 - dst_y))); - m_y = el.y1 + (dst_y - el.y1) / 2.f; - break; - default: // unreachable - break; - } - el.x2 = m_x; - el.y2 = m_y; - arch->addDecalGraphic(active_id, el); - el.style = GraphicElement::STYLE_HIDDEN; - arch->addDecalGraphic(inactive_id, el); - el.style = GraphicElement::STYLE_ACTIVE; - el.x1 = m_x; - el.y1 = m_y; - el.x2 = dst_x; - el.y2 = dst_y; - arch->addDecalGraphic(active_id, el); - el.style = GraphicElement::STYLE_HIDDEN; - arch->addDecalGraphic(inactive_id, el); - } - } - } - } - arch->setPipDecal(pip.name, active, inactive); -} - -const int WIRE_ID_LEN = 30; - -void gfxSetWireDefaultDecal(Arch *arch, WireInfo &wire) -{ - DecalXY active, inactive; - IdString active_id, inactive_id; - GraphicElement el; - std::vector split_res; - char buf[WIRE_ID_LEN]; - - if (std::find(decalless_wires.begin(), decalless_wires.end(), wire.name) != decalless_wires.end()) { - arch->setWireDecal(wire.type, DecalXY(), DecalXY()); - return; - } - // local to cell - if (arch->haveBelType(wire.x, wire.y, id_SLICE) && sliceLocalWires.count(wire.type) != 0) { - snprintf(buf, sizeof(buf), "%s_active", wire.type.c_str(arch)); - active_id = arch->id(buf); - active.decal = active_id; - snprintf(buf, sizeof(buf), "%s_inactive", wire.type.c_str(arch)); - inactive_id = arch->id(buf); - inactive.decal = inactive_id; - active.x = inactive.x = wire.x; - active.y = inactive.y = arch->gridDimY - 1. - wire.y; - - // create if absent - if (arch->decal_graphics.count(active_id) == 0) { - el.type = GraphicElement::TYPE_LOCAL_LINE; - for (auto seg : sliceLocalWires.at(wire.type)) { - el.style = GraphicElement::STYLE_ACTIVE; - el.x1 = std::get<0>(seg); - el.y1 = std::get<1>(seg); - el.x2 = std::get<2>(seg); - el.y2 = std::get<3>(seg); - arch->addDecalGraphic(active_id, el); - el.style = GraphicElement::STYLE_INACTIVE; - arch->addDecalGraphic(inactive_id, el); - } - } - arch->setWireDecal(wire.name, active, inactive); - return; - } - // spines - if (spineY.count(wire.type) != 0) { - snprintf(buf, sizeof(buf), "%s_active", wire.type.c_str(arch)); - active_id = arch->id(buf); - active.decal = active_id; - snprintf(buf, sizeof(buf), "%s_inactive", wire.type.c_str(arch)); - inactive_id = arch->id(buf); - inactive.decal = inactive_id; - active.x = inactive.x = 0.; - active.y = inactive.y = 0.; - - // update clock spines cache - arch->updateClockSpinesCache(wire.type, wire.name); - - if (arch->decal_graphics.count(active_id) == 0) { - el.type = GraphicElement::TYPE_LINE; - el.style = GraphicElement::STYLE_ACTIVE; - el.x1 = 0.2; // cell's x will be added later in fixClockSpineDecals - el.x2 = 0.7; // cell's x will be added later in fixClockSpineDecals - el.y1 = spineY.at(wire.type) + arch->gridDimY - 1.; // cell's y will be added later in fixClockSpineDecals - el.y2 = el.y1; - arch->addDecalGraphic(active_id, el); - el.style = GraphicElement::STYLE_HIDDEN; - arch->addDecalGraphic(inactive_id, el); - } - arch->setWireDecal(wire.name, active, inactive); - return; - } - - // global simple wires like IMUX - if (globalSimpleWires.count(wire.type) != 0) { - snprintf(buf, sizeof(buf), "%s_active", wire.name.c_str(arch)); - active_id = arch->id(buf); - active.decal = active_id; - snprintf(buf, sizeof(buf), "%s_inactive", wire.name.c_str(arch)); - inactive_id = arch->id(buf); - inactive.decal = inactive_id; - active.x = inactive.x = 0; - active.y = inactive.y = 0; - - // create if absent - if (arch->decal_graphics.count(active_id) == 0) { - el.type = GraphicElement::TYPE_LINE; - for (auto seg : globalSimpleWires.at(wire.type)) { - el.style = GraphicElement::STYLE_ACTIVE; - el.x1 = std::get<0>(seg) + wire.x; - el.y1 = std::get<1>(seg) + arch->gridDimY - 1. - wire.y; - el.x2 = std::get<2>(seg) + wire.x; - el.y2 = std::get<3>(seg) + arch->gridDimY - 1. - wire.y; - arch->addDecalGraphic(active_id, el); - el.style = GraphicElement::STYLE_INACTIVE; - arch->addDecalGraphic(inactive_id, el); - } - } - arch->setWireDecal(wire.name, active, inactive); - return; - } - - // global - boost::split(split_res, wire.name.str(arch), [](char c) { return c == '_'; }); - if (split_res.size() >= 2) { - IdString wire_id = arch->id(split_res.at(1)); - // wrap - if ((wire.y == (arch->gridDimY - 1) && split_res.at(1).at(0) == 'S') || - (wire.y == 0 && split_res.at(1).at(0) == 'N')) { - wire_id = arch->id(split_res.at(1) + "_loop0"); - } - if ((wire.x == (arch->gridDimX - 1) && split_res.at(1).at(0) == 'E') || - (wire.x == 0 && split_res.at(1).at(0) == 'W')) { - wire_id = arch->id(split_res.at(1) + "_loop0"); - } - // SN wires - if (split_res.at(1).substr(0, 2) == "SN") { - if (wire.y == 0) { - wire_id = arch->id(split_res.at(1) + "_loop_n"); - } else { - if (wire.y == (arch->gridDimY - 1)) { - wire_id = arch->id(split_res.at(1) + "_loop_s"); - } - } - } else { - // wrap 2 hop - if ((wire.y == (arch->gridDimY - 2) && split_res.at(1).substr(0, 2) == "S2") || - (wire.y == 1 && split_res.at(1).substr(0, 2) == "N2")) { - wire_id = arch->id(split_res.at(1) + "_loop1"); - } - // wrap 4 hop - if (split_res.at(1).substr(0, 2) == "S8" || split_res.at(1).substr(0, 2) == "N8") { - char loop_buf[5 + 2]; - if (split_res.at(1).substr(0, 2) == "N8") { - if (wire.y < 8) { - snprintf(loop_buf, sizeof(loop_buf), "_loop%1u", wire.y); - wire_id = arch->id(split_res.at(1) + loop_buf); - } - } else { - if (arch->gridDimY - 1 - wire.y < 8) { - snprintf(loop_buf, sizeof(loop_buf), "_loop%1u", arch->gridDimY - 1 - wire.y); - wire_id = arch->id(split_res.at(1) + loop_buf); - } - } - } - } - // EW wires - if (split_res.at(1).substr(0, 2) == "EW") { - if (wire.x == 0) { - wire_id = arch->id(split_res.at(1) + "_loop_w"); - } else { - if (wire.x == (arch->gridDimX - 1)) { - wire_id = arch->id(split_res.at(1) + "_loop_e"); - } - } - } else { - // wrap 2 hop - if ((wire.x == (arch->gridDimX - 2) && split_res.at(1).substr(0, 2) == "E2") || - (wire.x == 1 && split_res.at(1).substr(0, 2) == "W2")) { - wire_id = arch->id(split_res.at(1) + "_loop1"); - } - // wrap 4 hop - if (split_res.at(1).substr(0, 2) == "E8" || split_res.at(1).substr(0, 2) == "W8") { - char loop_buf[5 + 2]; - if (split_res.at(1).substr(0, 2) == "W8") { - if (wire.x < 8) { - snprintf(loop_buf, sizeof(loop_buf), "_loop%1u", wire.x); - wire_id = arch->id(split_res.at(1) + loop_buf); - } - } else { - if (arch->gridDimX - 1 - wire.x < 8) { - snprintf(loop_buf, sizeof(loop_buf), "_loop%1u", arch->gridDimX - 1 - wire.x); - wire_id = arch->id(split_res.at(1) + loop_buf); - } - } - } - } - // really create decal - if (globalWires.count(wire_id) != 0) { - snprintf(buf, sizeof(buf), "%s_active", wire.name.c_str(arch)); - active_id = arch->id(buf); - active.decal = active_id; - snprintf(buf, sizeof(buf), "%s_inactive", wire.name.c_str(arch)); - inactive_id = arch->id(buf); - inactive.decal = inactive_id; - active.x = inactive.x = 0; - active.y = inactive.y = 0; - - // create if absent - if (arch->decal_graphics.count(active_id) == 0) { - el.type = GraphicElement::TYPE_LINE; - for (auto seg : globalWires.at(wire_id)) { - el.style = GraphicElement::STYLE_ACTIVE; - el.x1 = std::get<0>(seg) + wire.x; - el.y1 = std::get<1>(seg) + arch->gridDimY - 1. - wire.y; - el.x2 = std::get<2>(seg) + wire.x; - el.y2 = std::get<3>(seg) + arch->gridDimY - 1. - wire.y; - arch->addDecalGraphic(active_id, el); - el.style = GraphicElement::STYLE_INACTIVE; - arch->addDecalGraphic(inactive_id, el); - } - } - arch->setWireDecal(wire.name, active, inactive); - return; - } - // clock branches - // # of rows is unknown so generate wire ids at runtime - if (split_res.at(1).substr(0, 3) == "GBO") { - snprintf(buf, sizeof(buf), "%s_active", wire.name.c_str(arch)); - active_id = arch->id(buf); - active.decal = active_id; - snprintf(buf, sizeof(buf), "%s_inactive", wire.name.c_str(arch)); - inactive_id = arch->id(buf); - inactive.decal = inactive_id; - active.x = inactive.x = 0; - active.y = inactive.y = 0; - - float pip_x = PIP_X(id_GBO0); - float line_y = WIRE_Y(CLK_GBO0_Y) + arch->gridDimY - 1. - wire.y; - float line_0 = WIRE_Y(0) + arch->gridDimY - 1. - wire.y; - if (split_res.at(1).at(3) == '1') { - pip_x = PIP_X(id_GBO1); - line_y = WIRE_Y(CLK_GBO1_Y) + arch->gridDimY - 1. - wire.y; - } - - // create if absent - if (arch->decal_graphics.count(active_id) == 0) { - el.type = GraphicElement::TYPE_LINE; - el.style = GraphicElement::STYLE_ACTIVE; - el.x1 = wire.x + pip_x; - el.y1 = line_y; - el.x2 = el.x1; - el.y2 = line_0; - arch->addDecalGraphic(active_id, el); - el.style = GraphicElement::STYLE_HIDDEN; - arch->addDecalGraphic(inactive_id, el); - - el.style = GraphicElement::STYLE_ACTIVE; - el.x1 = pip_x; - el.y1 = line_y; - el.x2 = pip_x + arch->gridDimX - 1.; - el.y2 = el.y1; - arch->addDecalGraphic(active_id, el); - el.style = GraphicElement::STYLE_HIDDEN; - arch->addDecalGraphic(inactive_id, el); - } - arch->setWireDecal(wire.name, active, inactive); - return; - } else { - if (split_res.at(1).substr(0, 2) == "GT") { - snprintf(buf, sizeof(buf), "%s_active", wire.name.c_str(arch)); - active_id = arch->id(buf); - active.decal = active_id; - snprintf(buf, sizeof(buf), "%s_inactive", wire.name.c_str(arch)); - inactive_id = arch->id(buf); - inactive.decal = inactive_id; - active.x = inactive.x = 0; - active.y = inactive.y = 0; - - float pip_y = PIP_Y(id_GT00); - float line_x = WIRE_X(CLK_GT00_X) + wire.x; - float line_0 = WIRE_X(0) + wire.x; - if (split_res.at(1).at(2) == '1') { - pip_y = PIP_Y(id_GT10); - line_x = WIRE_X(CLK_GT10_X) + wire.x; - } - - // create if absent - if (arch->decal_graphics.count(active_id) == 0) { - el.type = GraphicElement::TYPE_LINE; - el.style = GraphicElement::STYLE_ACTIVE; - el.x1 = line_x; - el.y1 = pip_y + arch->gridDimY - 1.; - el.x2 = el.x1; - el.y2 = pip_y; - arch->addDecalGraphic(active_id, el); - el.style = GraphicElement::STYLE_HIDDEN; - arch->addDecalGraphic(inactive_id, el); - - for (int i = 0; i <= arch->gridDimY - 1; ++i) { - el.style = GraphicElement::STYLE_ACTIVE; - el.x1 = line_x; - el.y1 = pip_y + arch->gridDimY - 1. - i; - el.x2 = line_0; - el.y2 = el.y1; - arch->addDecalGraphic(active_id, el); - el.style = GraphicElement::STYLE_HIDDEN; - arch->addDecalGraphic(inactive_id, el); - } - } - arch->setWireDecal(wire.name, active, inactive); - return; - } else { - if (split_res.at(1).substr(0, 2) == "GB") { - snprintf(buf, sizeof(buf), "%s_active", wire.name.c_str(arch)); - active_id = arch->id(buf); - active.decal = active_id; - snprintf(buf, sizeof(buf), "%s_inactive", wire.name.c_str(arch)); - inactive_id = arch->id(buf); - inactive.decal = inactive_id; - active.x = inactive.x = 0; - active.y = inactive.y = 0; - - float line_y = WIRE_Y(CLK_GBO0_Y) + arch->gridDimY - 1. - wire.y; - float line_0 = WIRE_Y(0) + arch->gridDimY - 1. - wire.y; - float pip_x = PIP_X(arch->id(split_res.at(1))); - if (split_res.at(1).at(2) >= '4') { - line_y = WIRE_Y(CLK_GBO1_Y) + arch->gridDimY - 1. - wire.y; - } - - // create if absent - if (arch->decal_graphics.count(active_id) == 0) { - el.type = GraphicElement::TYPE_LINE; - el.style = GraphicElement::STYLE_ACTIVE; - el.x1 = wire.x + pip_x; - el.y1 = line_y; - el.x2 = el.x1; - el.y2 = line_0; - arch->addDecalGraphic(active_id, el); - el.style = GraphicElement::STYLE_INACTIVE; - arch->addDecalGraphic(inactive_id, el); - } - arch->setWireDecal(wire.name, active, inactive); - return; - } - } - } - } - // std::cout << wire.name.str(arch) << ":" << wire.type.str(arch) << " R" << wire.y + 1 << "C" << wire.x + 1 << - // std::endl; -} - -void gfxCreateBelDecals(Arch *arch) -{ - GraphicElement el; - // LUTs - el.type = GraphicElement::TYPE_BOX; - el.style = GraphicElement::STYLE_ACTIVE; - el.x1 = lut_x; - el.x2 = el.x1 + lut_w; - el.y1 = 0.; - el.y2 = el.y1 + lut_h; - arch->addDecalGraphic(id_DECAL_LUT_ACTIVE, el); - arch->addDecalGraphic(id_DECAL_LUTDFF_ACTIVE, el); - arch->addDecalGraphic(id_DECAL_LUT_UNUSED_DFF_ACTIVE, el); - arch->addDecalGraphic(id_DECAL_ALU_ACTIVE, el); - el.style = GraphicElement::STYLE_INACTIVE; - arch->addDecalGraphic(id_DECAL_LUT_INACTIVE, el); - arch->addDecalGraphic(id_DECAL_LUTDFF_INACTIVE, el); - el.x1 = dff_x; - el.x2 = el.x1 + dff_w; - el.y1 = 0.; - el.y2 = el.y1 + lut_h; - arch->addDecalGraphic(id_DECAL_LUTDFF_INACTIVE, el); - arch->addDecalGraphic(id_DECAL_LUT_UNUSED_DFF_ACTIVE, el); - arch->addDecalGraphic(id_DECAL_ALU_ACTIVE, el); - el.style = GraphicElement::STYLE_ACTIVE; - arch->addDecalGraphic(id_DECAL_LUTDFF_ACTIVE, el); - el.type = GraphicElement::TYPE_LOCAL_LINE; - el.x1 = lut_x + 0.33f * lut_w; - el.x2 = el.x1 + 0.33f * lut_w; - el.y1 = 0.66f * lut_h; - el.y2 = el.y1; - arch->addDecalGraphic(id_DECAL_ALU_ACTIVE, el); - el.y1 = 0.3f * lut_h; - el.y2 = el.y1; - arch->addDecalGraphic(id_DECAL_ALU_ACTIVE, el); - el.x1 = lut_x + 0.5f * lut_w; - el.x2 = el.x1; - el.y1 = 0.5f * lut_h; - el.y2 = el.y1 + 0.33f * lut_h; - arch->addDecalGraphic(id_DECAL_ALU_ACTIVE, el); - - // LUT group - el.type = GraphicElement::TYPE_BOX; - el.style = GraphicElement::STYLE_FRAME; - el.x1 = grp_lut_x; - el.x2 = el.x1 + grp_lut_w; - el.y1 = 0.; - el.y2 = el.y1 + grp_lut_h; - arch->addDecalGraphic(id_DECAL_GRP_LUT, el); - - // CRU group - el.type = GraphicElement::TYPE_BOX; - el.style = GraphicElement::STYLE_FRAME; - el.x1 = cru_x; - el.x2 = el.x1 + cru_w; - el.y1 = cru_y; - el.y2 = el.y1 + cru_h; - arch->addDecalGraphic(id_DECAL_CRU, el); - - // Mux with upper 1 input - el.type = GraphicElement::TYPE_LINE; - el.style = GraphicElement::STYLE_INACTIVE; - el.x1 = 0.; - el.x2 = mux_w; - el.y1 = 0.; - el.y2 = mux_f; - arch->addDecalGraphic(id_DECAL_MUXUPPER_INACTIVE, el); - el.style = GraphicElement::STYLE_ACTIVE; - arch->addDecalGraphic(id_DECAL_MUXUPPER_ACTIVE, el); - el.style = GraphicElement::STYLE_INACTIVE; - el.x1 = el.x2; - el.y1 = el.y2; - el.y2 = mux_h - mux_f; - arch->addDecalGraphic(id_DECAL_MUXUPPER_INACTIVE, el); - el.style = GraphicElement::STYLE_ACTIVE; - arch->addDecalGraphic(id_DECAL_MUXUPPER_ACTIVE, el); - el.style = GraphicElement::STYLE_INACTIVE; - el.x2 = 0.; - el.y1 = el.y2; - el.y2 = mux_h; - arch->addDecalGraphic(id_DECAL_MUXUPPER_INACTIVE, el); - el.style = GraphicElement::STYLE_ACTIVE; - arch->addDecalGraphic(id_DECAL_MUXUPPER_ACTIVE, el); - el.style = GraphicElement::STYLE_INACTIVE; - el.x1 = el.x2; - el.y1 = mux_h; - el.y2 = 0.; - arch->addDecalGraphic(id_DECAL_MUXUPPER_INACTIVE, el); - el.style = GraphicElement::STYLE_ACTIVE; - arch->addDecalGraphic(id_DECAL_MUXUPPER_ACTIVE, el); - // 1 - el.style = GraphicElement::STYLE_INACTIVE; - el.x1 = 0.0038; - el.x2 = 0.0118; - el.y1 = el.y2 = 0.0598; - arch->addDecalGraphic(id_DECAL_MUXUPPER_INACTIVE, el); - el.style = GraphicElement::STYLE_ACTIVE; - arch->addDecalGraphic(id_DECAL_MUXUPPER_ACTIVE, el); - el.style = GraphicElement::STYLE_INACTIVE; - el.x1 = (el.x1 + el.x2) / 2.; - el.x2 = el.x1; - el.y2 = 0.0808; - arch->addDecalGraphic(id_DECAL_MUXUPPER_INACTIVE, el); - el.style = GraphicElement::STYLE_ACTIVE; - arch->addDecalGraphic(id_DECAL_MUXUPPER_ACTIVE, el); - el.style = GraphicElement::STYLE_INACTIVE; - el.x2 = 0.0038; - el.y1 = el.y2; - el.y2 = 0.0797; - arch->addDecalGraphic(id_DECAL_MUXUPPER_INACTIVE, el); - el.style = GraphicElement::STYLE_ACTIVE; - arch->addDecalGraphic(id_DECAL_MUXUPPER_ACTIVE, el); - - // Mux with lower 1 input - el.type = GraphicElement::TYPE_LINE; - el.style = GraphicElement::STYLE_INACTIVE; - el.x1 = 0.; - el.x2 = mux_w; - el.y1 = 0.; - el.y2 = mux_f; - arch->addDecalGraphic(id_DECAL_MUXLOWER_INACTIVE, el); - el.style = GraphicElement::STYLE_ACTIVE; - arch->addDecalGraphic(id_DECAL_MUXLOWER_ACTIVE, el); - el.style = GraphicElement::STYLE_INACTIVE; - el.x1 = el.x2; - el.y1 = el.y2; - el.y2 = mux_h - mux_f; - arch->addDecalGraphic(id_DECAL_MUXLOWER_INACTIVE, el); - el.style = GraphicElement::STYLE_ACTIVE; - arch->addDecalGraphic(id_DECAL_MUXLOWER_ACTIVE, el); - el.style = GraphicElement::STYLE_INACTIVE; - el.x2 = 0.; - el.y1 = el.y2; - el.y2 = mux_h; - arch->addDecalGraphic(id_DECAL_MUXLOWER_INACTIVE, el); - el.style = GraphicElement::STYLE_ACTIVE; - arch->addDecalGraphic(id_DECAL_MUXLOWER_ACTIVE, el); - el.style = GraphicElement::STYLE_INACTIVE; - el.x1 = el.x2; - el.y1 = mux_h; - el.y2 = 0.; - arch->addDecalGraphic(id_DECAL_MUXLOWER_INACTIVE, el); - el.style = GraphicElement::STYLE_ACTIVE; - arch->addDecalGraphic(id_DECAL_MUXLOWER_ACTIVE, el); - // 1 - el.style = GraphicElement::STYLE_INACTIVE; - el.x1 = 0.0038; - el.x2 = 0.0118; - el.y1 = el.y2 = 0.0140; - arch->addDecalGraphic(id_DECAL_MUXLOWER_INACTIVE, el); - el.style = GraphicElement::STYLE_ACTIVE; - arch->addDecalGraphic(id_DECAL_MUXLOWER_ACTIVE, el); - el.style = GraphicElement::STYLE_INACTIVE; - el.x1 = (el.x1 + el.x2) / 2.; - el.x2 = el.x1; - el.y2 = 0.0352; - arch->addDecalGraphic(id_DECAL_MUXLOWER_INACTIVE, el); - el.style = GraphicElement::STYLE_ACTIVE; - arch->addDecalGraphic(id_DECAL_MUXLOWER_ACTIVE, el); - el.style = GraphicElement::STYLE_INACTIVE; - el.x2 = 0.0038; - el.y1 = el.y2; - el.y2 = 0.0341; - arch->addDecalGraphic(id_DECAL_MUXLOWER_INACTIVE, el); - el.style = GraphicElement::STYLE_ACTIVE; - arch->addDecalGraphic(id_DECAL_MUXLOWER_ACTIVE, el); - - // IOB - el.type = GraphicElement::TYPE_LINE; - el.style = GraphicElement::STYLE_INACTIVE; - el.x1 = 0.; - el.x2 = io_w; - el.y1 = 0.; - el.y2 = el.y1; - arch->addDecalGraphic(id_DECAL_IOB_INACTIVE, el); - el.style = GraphicElement::STYLE_ACTIVE; - arch->addDecalGraphic(id_DECAL_IOB_ACTIVE, el); - el.style = GraphicElement::STYLE_INACTIVE; - el.x1 = el.x2; - el.y2 = io_h; - arch->addDecalGraphic(id_DECAL_IOB_INACTIVE, el); - el.style = GraphicElement::STYLE_ACTIVE; - arch->addDecalGraphic(id_DECAL_IOB_ACTIVE, el); - el.style = GraphicElement::STYLE_INACTIVE; - el.x1 = 0.; - el.y1 = el.y2; - arch->addDecalGraphic(id_DECAL_IOB_INACTIVE, el); - el.style = GraphicElement::STYLE_ACTIVE; - arch->addDecalGraphic(id_DECAL_IOB_ACTIVE, el); - el.style = GraphicElement::STYLE_INACTIVE; - el.x2 = el.x1; - el.y2 = 0.; - arch->addDecalGraphic(id_DECAL_IOB_INACTIVE, el); - el.style = GraphicElement::STYLE_ACTIVE; - arch->addDecalGraphic(id_DECAL_IOB_ACTIVE, el); - el.style = GraphicElement::STYLE_INACTIVE; - el.x1 = io_w; - el.x2 = io_w * 1.3f; - el.y2 = el.y1 = io_h / 2.f; - arch->addDecalGraphic(id_DECAL_IOB_INACTIVE, el); - el.style = GraphicElement::STYLE_ACTIVE; - arch->addDecalGraphic(id_DECAL_IOB_ACTIVE, el); - - // IOBS - el.type = GraphicElement::TYPE_LINE; - el.style = GraphicElement::STYLE_INACTIVE; - el.x1 = 0.; - el.x2 = ios_w; - el.y1 = 0.; - el.y2 = el.y1; - arch->addDecalGraphic(id_DECAL_IOBS_INACTIVE, el); - el.style = GraphicElement::STYLE_ACTIVE; - arch->addDecalGraphic(id_DECAL_IOBS_ACTIVE, el); - el.style = GraphicElement::STYLE_INACTIVE; - el.x1 = el.x2; - el.y2 = ios_h; - arch->addDecalGraphic(id_DECAL_IOBS_INACTIVE, el); - el.style = GraphicElement::STYLE_ACTIVE; - arch->addDecalGraphic(id_DECAL_IOBS_ACTIVE, el); - el.style = GraphicElement::STYLE_INACTIVE; - el.x1 = 0.; - el.y1 = el.y2; - arch->addDecalGraphic(id_DECAL_IOBS_INACTIVE, el); - el.style = GraphicElement::STYLE_ACTIVE; - arch->addDecalGraphic(id_DECAL_IOBS_ACTIVE, el); - el.style = GraphicElement::STYLE_INACTIVE; - el.x2 = el.x1; - el.y2 = 0.; - arch->addDecalGraphic(id_DECAL_IOBS_INACTIVE, el); - el.style = GraphicElement::STYLE_ACTIVE; - arch->addDecalGraphic(id_DECAL_IOBS_ACTIVE, el); - el.style = GraphicElement::STYLE_INACTIVE; - el.x1 = ios_w; - el.x2 = ios_w * 1.3f; - el.y2 = el.y1 = ios_h / 2.f; - arch->addDecalGraphic(id_DECAL_IOBS_INACTIVE, el); - el.style = GraphicElement::STYLE_ACTIVE; - arch->addDecalGraphic(id_DECAL_IOBS_ACTIVE, el); -} - -void gfxSetBelDefaultDecal(Arch *arch, BelInfo &bel) -{ - DecalXY active, inactive; - switch (bel.type.hash()) { - case ID_SLICE: - active.x = inactive.x = bel.x; - active.y = inactive.y = arch->gridDimY - 1. - bel.y + lut_y[bel.z]; - if (bel.z < 6) { - active.decal = id_DECAL_LUTDFF_ACTIVE; - inactive.decal = id_DECAL_LUTDFF_INACTIVE; - } else { - active.decal = id_DECAL_LUT_ACTIVE; - inactive.decal = id_DECAL_LUT_INACTIVE; - } - arch->setBelDecal(bel.name, active, inactive); - break; - case ID_MUX2_LUT5: - active.x = inactive.x = bel.x + mux2lut5_x; - active.y = inactive.y = arch->gridDimY - 1. - bel.y + mux2lut5_y[(bel.z - BelZ::mux_0_z) >> 1]; - active.decal = id_DECAL_MUXUPPER_ACTIVE; - inactive.decal = id_DECAL_MUXUPPER_INACTIVE; - arch->setBelDecal(bel.name, active, inactive); - break; - case ID_MUX2_LUT6: - active.x = inactive.x = bel.x + mux2lut6_x; - active.y = inactive.y = arch->gridDimY - 1. - bel.y + mux2lut6_y[(bel.z - BelZ::mux_0_z) / 5]; - active.decal = id_DECAL_MUXLOWER_ACTIVE; - inactive.decal = id_DECAL_MUXLOWER_INACTIVE; - arch->setBelDecal(bel.name, active, inactive); - break; - case ID_MUX2_LUT7: - active.x = inactive.x = bel.x + mux2lut7_x; - active.y = inactive.y = arch->gridDimY - 1. - bel.y + mux2lut7_y; - active.decal = id_DECAL_MUXLOWER_ACTIVE; - inactive.decal = id_DECAL_MUXLOWER_INACTIVE; - arch->setBelDecal(bel.name, active, inactive); - break; - case ID_MUX2_LUT8: - active.x = inactive.x = bel.x + mux2lut8_x; - active.y = inactive.y = arch->gridDimY - 1. - bel.y + mux2lut8_y; - active.decal = id_DECAL_MUXUPPER_ACTIVE; - inactive.decal = id_DECAL_MUXUPPER_INACTIVE; - arch->setBelDecal(bel.name, active, inactive); - break; - case ID_IOB: - active.x = inactive.x = bel.x + io_x; - active.y = inactive.y = arch->gridDimY - 1. - bel.y + io_y + bel.z * (2 * io_gap + io_h); - active.decal = id_DECAL_IOB_ACTIVE; - inactive.decal = id_DECAL_IOB_INACTIVE; - arch->setBelDecal(bel.name, active, inactive); - gfxSetIOBWireDecals(arch, bel); - break; - case ID_IOBS: - active.x = inactive.x = bel.x + ios_x + (ios_w + ios_gap_x) * (bel.z % 3); - active.y = inactive.y = arch->gridDimY - 1. - bel.y + ios_y + (ios_h + ios_gap_y) * (bel.z / 3); - active.decal = id_DECAL_IOBS_ACTIVE; - inactive.decal = id_DECAL_IOBS_INACTIVE; - arch->setBelDecal(bel.name, active, inactive); - gfxSetIOBSWireDecals(arch, bel); - break; - default: - break; - } -} - -void gfxSetIOBWireDecals(Arch *arch, BelInfo &bel) -{ - DecalXY active, inactive; - GraphicElement el; - char buf[20]; - - // set decals for I, O and OE input wires - for (auto pi : bel.pins) { - WireInfo &wi = arch->wire_info(pi.second.wire); - // decal name: wire_port_z_active|inactive - snprintf(buf, sizeof(buf), "%s_%s_%u_active", wi.type.c_str(arch), pi.first.c_str(arch), bel.z); - IdString active_id = arch->id(buf); - active.decal = active_id; - snprintf(buf, sizeof(buf), "%s_%s_%u_inactive", wi.type.c_str(arch), pi.first.c_str(arch), bel.z); - IdString inactive_id = arch->id(buf); - inactive.decal = inactive_id; - active.x = inactive.x = bel.x; - active.y = inactive.y = arch->gridDimY - 1. - bel.y; - if (arch->decal_graphics.count(active_id) == 0) { - el.type = GraphicElement::TYPE_LOCAL_LINE; - el.style = GraphicElement::STYLE_ACTIVE; - el.x1 = cru_x + cru_w; - el.y1 = pipPoint.at(wi.type).second; - el.x2 = io_x; - el.y2 = portPoint.at(pi.first) + io_y + bel.z * (2 * io_gap + io_h); - arch->addDecalGraphic(active_id, el); - el.style = GraphicElement::STYLE_INACTIVE; - arch->addDecalGraphic(inactive_id, el); - for (auto seg : portSign.at(pi.first)) { - el.style = GraphicElement::STYLE_ACTIVE; - el.x1 = std::get<0>(seg) + io_x; - el.y1 = std::get<1>(seg) + io_y + bel.z * (2 * io_gap + io_h); - el.x2 = std::get<2>(seg) + io_x; - el.y2 = std::get<3>(seg) + io_y + bel.z * (2 * io_gap + io_h); - arch->addDecalGraphic(active_id, el); - el.style = GraphicElement::STYLE_INACTIVE; - arch->addDecalGraphic(inactive_id, el); - } - } - arch->setWireDecal(wi.name, active, inactive); - } -} - -void gfxSetIOBSWireDecals(Arch *arch, BelInfo &bel) -{ - DecalXY active, inactive; - GraphicElement el; - char buf[20]; - - // set decals for I, O and OE input wires - for (auto pi : bel.pins) { - WireInfo &wi = arch->wire_info(pi.second.wire); - // decal name: ios_wire_port_z_active|inactive - snprintf(buf, sizeof(buf), "ios_%s_%s_%u_active", wi.type.c_str(arch), pi.first.c_str(arch), bel.z); - IdString active_id = arch->id(buf); - active.decal = active_id; - snprintf(buf, sizeof(buf), "ios_%s_%s_%u_inactive", wi.type.c_str(arch), pi.first.c_str(arch), bel.z); - IdString inactive_id = arch->id(buf); - inactive.decal = inactive_id; - active.x = inactive.x = bel.x; - active.y = inactive.y = arch->gridDimY - 1. - bel.y; - if (arch->decal_graphics.count(active_id) == 0) { - // leftmost wires - el.type = GraphicElement::TYPE_LOCAL_LINE; - if (bel.z % 3 == 0) { - el.style = GraphicElement::STYLE_ACTIVE; - el.x1 = cru_x + cru_w; - el.y1 = pipPoint.at(wi.type).second; - el.x2 = ios_x; - el.y2 = ios_scl * portPoint.at(pi.first) + ios_y + (ios_h + ios_gap_y) * (bel.z / 3); - arch->addDecalGraphic(active_id, el); - el.style = GraphicElement::STYLE_INACTIVE; - arch->addDecalGraphic(inactive_id, el); - } else { - float col = (bel.z % 3) - 1; - float rel_port = portPoint.at(pi.first) / io_h; - el.style = GraphicElement::STYLE_ACTIVE; - el.x1 = cru_x + cru_w; - el.y1 = pipPoint.at(wi.type).second; - el.x2 = ios_x * (0.97 - 0.02 * col); - el.y2 = (rel_port + col) * 0.5 * ios_gap_y + ios_y + ios_h + (ios_h + ios_gap_y) * (bel.z / 3); - arch->addDecalGraphic(active_id, el); - el.style = GraphicElement::STYLE_INACTIVE; - arch->addDecalGraphic(inactive_id, el); - el.style = GraphicElement::STYLE_ACTIVE; - el.x1 = ios_x + (ios_w + ios_gap_x) * (col + 1) - ios_gap_x + ios_w * 0.3 + - rel_port * (ios_gap_x - 0.3 * ios_w); - el.y1 = el.y2; - arch->addDecalGraphic(active_id, el); - el.style = GraphicElement::STYLE_INACTIVE; - arch->addDecalGraphic(inactive_id, el); - el.style = GraphicElement::STYLE_ACTIVE; - el.x2 = el.x1; - el.y2 = ios_scl * portPoint.at(pi.first) + ios_y + (ios_h + ios_gap_y) * (bel.z / 3); - arch->addDecalGraphic(active_id, el); - el.style = GraphicElement::STYLE_INACTIVE; - arch->addDecalGraphic(inactive_id, el); - el.style = GraphicElement::STYLE_ACTIVE; - el.x1 = ios_x + (ios_w + ios_gap_x) * (col + 1); - el.y1 = el.y2; - arch->addDecalGraphic(active_id, el); - el.style = GraphicElement::STYLE_INACTIVE; - arch->addDecalGraphic(inactive_id, el); - el.style = GraphicElement::STYLE_ACTIVE; - } - // signs - for (auto seg : portSign.at(pi.first)) { - el.style = GraphicElement::STYLE_ACTIVE; - el.x1 = ios_scl * std::get<0>(seg) + ios_x + (ios_w + ios_gap_x) * (bel.z % 3); - el.y1 = ios_scl * std::get<1>(seg) + ios_y + (ios_h + ios_gap_y) * (bel.z / 3); - el.x2 = ios_scl * std::get<2>(seg) + ios_x + (ios_w + ios_gap_x) * (bel.z % 3); - el.y2 = ios_scl * std::get<3>(seg) + ios_y + (ios_h + ios_gap_y) * (bel.z / 3); - arch->addDecalGraphic(active_id, el); - el.style = GraphicElement::STYLE_INACTIVE; - arch->addDecalGraphic(inactive_id, el); - } - } - arch->setWireDecal(wi.name, active, inactive); - } -} - -DecalXY gfxGetLutGroupDecalXY(int x, int y, int z) -{ - DecalXY decalxy; - decalxy.decal = id_DECAL_GRP_LUT; - decalxy.x = x; - decalxy.y = y + grp_lut_y[z]; - return decalxy; -} - -DecalXY gfxGetCruGroupDecalXY(int x, int y) -{ - DecalXY decalxy; - decalxy.decal = id_DECAL_CRU; - decalxy.x = x; - decalxy.y = y; - return decalxy; -} -#endif // NO_GUI - -NEXTPNR_NAMESPACE_END diff --git a/gowin/gfx.h b/gowin/gfx.h deleted file mode 100644 index 4c798ed901..0000000000 --- a/gowin/gfx.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * nextpnr -- Next Generation Place and Route - * - * Copyright (C) 2018 Claire Xenia 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. - * - */ - -#ifndef GFX_H -#define GFX_H - -#include "nextpnr.h" - -NEXTPNR_NAMESPACE_BEGIN - -#ifndef NO_GUI -void gfxCreateBelDecals(Arch *arch); -void gfxSetBelDefaultDecal(Arch *arch, BelInfo &bel); -void gfxSetIOBWireDecals(Arch *arch, BelInfo &bel); -void gfxSetIOBSWireDecals(Arch *arch, BelInfo &bel); -void gfxSetPipDefaultDecal(Arch *arch, PipInfo &pip); -void gfxSetWireDefaultDecal(Arch *arch, WireInfo &wire); -DecalXY gfxGetLutGroupDecalXY(int x, int y, int z); -DecalXY gfxGetCruGroupDecalXY(int x, int y); -#endif - -NEXTPNR_NAMESPACE_END - -#endif // GFX_H diff --git a/gowin/globals.cc b/gowin/globals.cc deleted file mode 100644 index 3273191c10..0000000000 --- a/gowin/globals.cc +++ /dev/null @@ -1,332 +0,0 @@ -/* - * nextpnr -- Next Generation Place and Route - * - * Copyright (C) 2018 gatecat - * Copyright (C) 2022 YRabbit - * - * 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 -#include -#include -#include -#include "cells.h" -#include "log.h" -#include "nextpnr.h" -#include "place_common.h" -#include "util.h" - -NEXTPNR_NAMESPACE_BEGIN - -bool GowinGlobalRouter::is_clock_port(PortRef const &user) -{ - if ((user.cell->type.in(id_SLICE, id_ODDR, id_ODDRC)) && user.port == id_CLK) { - return true; - } - return false; -} - -std::pair GowinGlobalRouter::clock_src(Context *ctx, PortRef const &driver) -{ - if (driver.cell == nullptr) { - return std::make_pair(WireId(), BelId()); - } - - BelInfo &bel = ctx->bel_info(driver.cell->bel); - WireId wire; - if (driver.cell->type == id_IOB) { - if (ctx->is_GCLKT_iob(driver.cell)) { - wire = bel.pins[id_O].wire; - return std::make_pair(wire, bel.name); - } - return std::make_pair(WireId(), BelId()); - } - if (driver.cell->type == id_rPLL || driver.cell->type == id_PLLVR) { - if (driver.port == id_CLKOUT || driver.port == id_CLKOUTP || driver.port == id_CLKOUTD || - driver.port == id_CLKOUTD3) { - wire = bel.pins[driver.port].wire; - return std::make_pair(wire, bel.name); - } - return std::make_pair(WireId(), BelId()); - } - return std::make_pair(WireId(), BelId()); -} - -// gather the clock nets -void GowinGlobalRouter::gather_clock_nets(Context *ctx, std::vector &clock_nets) -{ - for (auto const &net : ctx->nets) { - NetInfo const *ni = net.second.get(); - auto new_clock = clock_nets.end(); - auto clock_wire_bel = clock_src(ctx, ni->driver); - if (clock_wire_bel.first != WireId()) { - clock_nets.emplace_back(net.first); - new_clock = --clock_nets.end(); - new_clock->clock_wire = clock_wire_bel.first; - new_clock->clock_bel = clock_wire_bel.second; - } - for (auto const &user : ni->users) { - if (is_clock_port(user)) { - if (new_clock == clock_nets.end()) { - clock_nets.emplace_back(net.first); - new_clock = --clock_nets.end(); - } - ++(new_clock->clock_ports); - } - } - } - // need to prioritize the nets - std::sort(clock_nets.begin(), clock_nets.end()); - - if (ctx->verbose) { - for (auto const &net : clock_nets) { - log_info(" Net:%s, ports:%d, clock source:%s\n", net.name.c_str(ctx), net.clock_ports, - net.clock_wire == WireId() ? "No" : net.clock_wire.c_str(ctx)); - } - } -} - -// non clock port -// returns GB pip -IdString GowinGlobalRouter::route_to_non_clock_port(Context *ctx, WireId const dstWire, int clock, - pool &used_pips, pool &undo_wires) -{ - static std::vector one_hop_0 = {id_W111, id_W121, id_E111, id_E121}; - static std::vector one_hop_4 = {id_S111, id_S121, id_N111, id_N121}; - // uphill pips - for (auto const uphill : ctx->getPipsUphill(dstWire)) { - WireId srcWire = ctx->getPipSrcWire(uphill); - bool found; - if (clock < 4) { - found = find(one_hop_0.begin(), one_hop_0.end(), ctx->wire_info(ctx->getPipSrcWire(uphill)).type) != - one_hop_0.end(); - } else { - found = find(one_hop_4.begin(), one_hop_4.end(), ctx->wire_info(ctx->getPipSrcWire(uphill)).type) != - one_hop_4.end(); - } - if (found) { - // found one hop pip - if (used_wires.count(srcWire)) { - if (used_wires[srcWire] != clock) { - continue; - } - } - WireInfo wi = ctx->wire_info(srcWire); - std::string wire_alias = srcWire.str(ctx).substr(srcWire.str(ctx).rfind("_") + 1); - IdString gb = ctx->idf("R%dC%d_GB%d0_%s", wi.y + 1, wi.x + 1, clock, wire_alias.c_str()); - if (ctx->verbose) { - log_info(" 1-hop gb:%s\n", gb.c_str(ctx)); - } - // sanity - NPNR_ASSERT(find(ctx->getPipsUphill(srcWire).begin(), ctx->getPipsUphill(srcWire).end(), gb) != - ctx->getPipsUphill(srcWire).end()); - auto up_pips = ctx->getPipsUphill(srcWire); - if (find(up_pips.begin(), up_pips.end(), gb) != up_pips.end()) { - if (!used_wires.count(srcWire)) { - used_wires.insert(std::make_pair(srcWire, clock)); - undo_wires.insert(srcWire); - } - used_pips.insert(uphill); - if (ctx->verbose) { - log_info(" 1-hop Pip:%s\n", uphill.c_str(ctx)); - } - return gb; - } - } - } - return IdString(); -} - -// route one net -void GowinGlobalRouter::route_net(Context *ctx, globalnet_t const &net) -{ - // For failed routing undo - pool used_pips; - pool undo_wires; - - log_info(" Route net %s, use clock #%d.\n", net.name.c_str(ctx), net.clock); - for (auto const &user : ctx->net_info(net.name).users) { - // >>> port <- GB0 - WireId dstWire = ctx->getNetinfoSinkWire(&ctx->net_info(net.name), user, 0); - if (ctx->verbose) { - log_info(" Cell:%s, port:%s, wire:%s\n", user.cell->name.c_str(ctx), user.port.c_str(ctx), - dstWire.c_str(ctx)); - } - - char buf[30]; - PipId gb_pip_id; - if (user.port == id_CLK || user.port == id_CLKIN) { - WireInfo const wi = ctx->wire_info(dstWire); - gb_pip_id = - ctx->idf("R%dC%d_GB%d0_%s", wi.y + 1, wi.x + 1, net.clock, ctx->wire_info(dstWire).type.c_str(ctx)); - // sanity - NPNR_ASSERT(find(ctx->getPipsUphill(dstWire).begin(), ctx->getPipsUphill(dstWire).end(), gb_pip_id) != - ctx->getPipsUphill(dstWire).end()); - } else { - // Non clock port - gb_pip_id = route_to_non_clock_port(ctx, dstWire, net.clock, used_pips, undo_wires); - if (gb_pip_id == IdString()) { - if (ctx->verbose) { - log_info(" Can't find route to %s, net %s will be routed in a standard way.\n", dstWire.c_str(ctx), - net.name.c_str(ctx)); - } - for (IdString const undo : undo_wires) { - used_wires.erase(undo); - } - return; - } - } - if (ctx->verbose) { - log_info(" GB Pip:%s\n", gb_pip_id.c_str(ctx)); - } - - if (used_pips.count(gb_pip_id)) { - if (ctx->verbose) { - log_info(" ^routed already^\n"); - } - continue; - } - used_pips.insert(gb_pip_id); - - // >>> GBOx <- GTx0 - dstWire = ctx->getPipSrcWire(gb_pip_id); - WireInfo dstWireInfo = ctx->wire_info(dstWire); - int branch_tap_idx = net.clock > 3 ? 1 : 0; - PipId gt_pip_id = - ctx->idf("R%dC%d_GT%d0_GBO%d", dstWireInfo.y + 1, dstWireInfo.x + 1, branch_tap_idx, branch_tap_idx); - if (ctx->verbose) { - log_info(" GT Pip:%s\n", gt_pip_id.c_str(ctx)); - } - // sanity - NPNR_ASSERT(find(ctx->getPipsUphill(dstWire).begin(), ctx->getPipsUphill(dstWire).end(), gt_pip_id) != - ctx->getPipsUphill(dstWire).end()); - // if already routed - if (used_pips.count(gt_pip_id)) { - if (ctx->verbose) { - log_info(" ^routed already^\n"); - } - continue; - } - used_pips.insert(gt_pip_id); - - // >>> GTx0 <- SPINExx - // XXX no optimization here, we need to store - // the SPINE <-> clock# correspondence in the database. In the - // meantime, we define in run-time in a completely suboptimal way. - std::vector clock_spine; - dstWire = ctx->getPipSrcWire(gt_pip_id); - for (auto const uphill_pip : ctx->getPipsUphill(dstWire)) { - std::string name = ctx->wire_info(ctx->getPipSrcWire(uphill_pip)).type.str(ctx); - if (name.rfind("SPINE", 0) == 0) { - clock_spine.push_back(name); - } - } - sort(clock_spine.begin(), clock_spine.end(), [](const std::string &a, const std::string &b) -> bool { - return (a.size() < b.size()) || (a.size() == b.size() && a < b); - }); - dstWireInfo = ctx->wire_info(dstWire); - snprintf(buf, sizeof(buf), "R%dC%d_%s_GT%d0", dstWireInfo.y + 1, dstWireInfo.x + 1, - clock_spine[net.clock - branch_tap_idx * 4].c_str(), branch_tap_idx); - PipId spine_pip_id = ctx->id(buf); - if (ctx->verbose) { - log_info(" Spine Pip:%s\n", buf); - } - // sanity - NPNR_ASSERT(find(ctx->getPipsUphill(dstWire).begin(), ctx->getPipsUphill(dstWire).end(), spine_pip_id) != - ctx->getPipsUphill(dstWire).end()); - // if already routed - if (used_pips.count(spine_pip_id)) { - if (ctx->verbose) { - log_info(" ^routed already^\n"); - } - continue; - } - used_pips.insert(spine_pip_id); - - // >>> SPINExx <- Src - dstWire = ctx->getPipSrcWire(spine_pip_id); - dstWireInfo = ctx->wire_info(dstWire); - PipId src_pip_id = PipId(); - for (auto const uphill_pip : ctx->getPipsUphill(dstWire)) { - if (ctx->getPipSrcWire(uphill_pip) == net.clock_wire) { - src_pip_id = uphill_pip; - break; - } - } - if (ctx->verbose) { - log_info(" Src Pip:%s\n", src_pip_id.c_str(ctx)); - } - NPNR_ASSERT(src_pip_id != PipId()); - // if already routed - if (used_pips.count(src_pip_id)) { - if (ctx->verbose) { - log_info(" ^routed already^\n"); - } - continue; - } - used_pips.insert(src_pip_id); - } - log_info(" Net %s is routed.\n", net.name.c_str(ctx)); - if (!ctx->net_info(net.name).users.empty()) { - for (auto const pip : used_pips) { - ctx->bindPip(pip, &ctx->net_info(net.name), STRENGTH_LOCKED); - } - ctx->bindWire(net.clock_wire, &ctx->net_info(net.name), STRENGTH_LOCKED); - } -} - -void GowinGlobalRouter::route_globals(Context *ctx) -{ - log_info("Routing globals...\n"); - - for (auto const &net : nets) { - route_net(ctx, net); - } -} - -// Allocate networks that will be routed through the global system. -// Mark their driver cells as global buffers to exclude them from the analysis. -void GowinGlobalRouter::mark_globals(Context *ctx) -{ - log_info("Find global nets...\n"); - - std::vector clock_nets; - gather_clock_nets(ctx, clock_nets); - // XXX we need to use the list of indexes of clocks from the database - // use 6 clocks (XXX 3 for GW1NZ-1) - int max_clock = ctx->max_clock, cur_clock = -1; - for (auto &net : clock_nets) { - // XXX only IO clock for now - if (net.clock_wire == WireId()) { - log_info(" Non clock source, skip %s.\n", net.name.c_str(ctx)); - continue; - } - if (++cur_clock >= max_clock) { - log_info(" No more clock wires left, skip the remaining nets.\n"); - break; - } - if (ctx->net_info(net.name).users.empty()) { - --cur_clock; - net.clock = -1; - } else { - net.clock = cur_clock; - } - BelInfo &bi = ctx->bel_info(net.clock_bel); - bi.gb = true; - nets.emplace_back(net); - } -} - -NEXTPNR_NAMESPACE_END diff --git a/gowin/globals.h b/gowin/globals.h deleted file mode 100644 index 307a1a2c2b..0000000000 --- a/gowin/globals.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * nextpnr -- Next Generation Place and Route - * - * Copyright (C) 2018 gatecat - * Copyright (C) 2022 YRabbit - * - * 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. - * - */ - -#ifndef GOWIN_GLOBALS_H -#define GOWIN_GLOBALS_H - -#include "nextpnr.h" - -NEXTPNR_NAMESPACE_BEGIN - -class GowinGlobalRouter -{ - public: - GowinGlobalRouter() {} - - private: - // wire -> clock# - dict used_wires; - - // ordered nets - struct globalnet_t - { - IdString name; - int clock_ports; - BelId clock_bel; - WireId clock_wire; // clock wire if there is one - int clock; // clock # - - globalnet_t() - { - name = IdString(); - clock_ports = 0; - clock_bel = BelId(); - clock_wire = WireId(); - clock = -1; - } - globalnet_t(IdString _name) - { - name = _name; - clock_ports = 0; - clock_bel = BelId(); - clock_wire = WireId(); - clock = -1; - } - - // sort - bool operator<(const globalnet_t &other) const - { - if ((clock_wire != WireId()) ^ (other.clock_wire != WireId())) { - return !(clock_wire != WireId()); - } - return clock_ports < other.clock_ports; - } - // search - bool operator==(const globalnet_t &other) const { return name == other.name; } - }; - - // discovered nets - std::vector nets; - - bool is_clock_port(PortRef const &user); - std::pair clock_src(Context *ctx, PortRef const &driver); - void gather_clock_nets(Context *ctx, std::vector &clock_nets); - IdString route_to_non_clock_port(Context *ctx, WireId const dstWire, int clock, pool &used_pips, - pool &undo_wires); - void route_net(Context *ctx, globalnet_t const &net); - - public: - void mark_globals(Context *ctx); - void route_globals(Context *ctx); -}; - -NEXTPNR_NAMESPACE_END -#endif // GOWIN_GLOBALS_H diff --git a/gowin/main.cc b/gowin/main.cc deleted file mode 100644 index 15b1914d86..0000000000 --- a/gowin/main.cc +++ /dev/null @@ -1,129 +0,0 @@ -/* - * nextpnr -- Next Generation Place and Route - * - * Copyright (C) 2018 Claire Xenia Wolf - * Copyright (C) 2020 Pepijn de Vos - * - * 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. - * - */ - -#ifdef MAIN_EXECUTABLE - -#include -#include -#include -#include "command.h" -#include "design_utils.h" -#include "log.h" -#include "timing.h" - -USING_NEXTPNR_NAMESPACE - -class GowinCommandHandler : public CommandHandler -{ - public: - GowinCommandHandler(int argc, char **argv); - virtual ~GowinCommandHandler(){}; - std::unique_ptr createContext(dict &values) override; - void setupArchContext(Context *ctx) override{}; - void customAfterLoad(Context *ctx) override; - - protected: - po::options_description getArchOptions() override; -}; - -GowinCommandHandler::GowinCommandHandler(int argc, char **argv) : CommandHandler(argc, argv) {} - -po::options_description GowinCommandHandler::getArchOptions() -{ - po::options_description specific("Architecture specific options"); - specific.add_options()("device", po::value(), "device name"); - specific.add_options()("family", po::value(), "family name"); - specific.add_options()("cst", po::value(), "physical constraints file"); - specific.add_options()("enable-globals", "enable separate routing of the clocks"); - specific.add_options()("disable-globals", "disable separate routing of the clocks"); - specific.add_options()("enable-auto-longwires", "automatic detection and routing of long wires"); - return specific; -} - -std::unique_ptr GowinCommandHandler::createContext(dict &values) -{ - if (!vm.count("device")) { - log_error("The device must be specified\n"); - } - - std::regex devicere = std::regex("GW1N([SZ]?)[A-Z]*-(LV|UV|UX)([0-9])(C?).*"); - std::smatch match; - std::string device = vm["device"].as(); - bool GW2 = device == "GW2A-LV18PG256C8/I7"; - - if (!GW2 && !std::regex_match(device, match, devicere)) { - log_error("Invalid device %s\n", device.c_str()); - } - ArchArgs chipArgs; - chipArgs.gui = vm.count("gui") != 0; - if (vm.count("family")) { - chipArgs.family = vm["family"].as(); - } else { - if (!GW2) { - char buf[36]; - // GW1N and GW1NR variants share the same database. - // Most Gowin devices are a System in Package with some SDRAM wirebonded to a GPIO bank. - // However, it appears that the S series with embedded ARM core are unique silicon. - snprintf(buf, 36, "GW1N%s-%s", match[1].str().c_str(), match[3].str().c_str()); - chipArgs.family = buf; - } else { - chipArgs.family = "GW2A-18"; - } - } - if (!GW2) { - chipArgs.partnumber = match[0]; - } else { - chipArgs.partnumber = device; - } - - auto ctx = std::unique_ptr(new Context(chipArgs)); - // routing options - ctx->settings[ctx->id("arch.enable-globals")] = 1; - ctx->settings[ctx->id("arch.enable-auto-longwires")] = 0; - if (vm.count("disable-globals")) { - ctx->settings[ctx->id("arch.enable-globals")] = 0; - } - if (vm.count("enable-auto-longwires")) { - ctx->settings[ctx->id("arch.enable-auto-longwires")] = 1; - } - // XXX disable clock lines for now - if (GW2) { - ctx->settings[ctx->id("arch.enable-globals")] = 0; - } - return ctx; -} - -void GowinCommandHandler::customAfterLoad(Context *ctx) -{ - if (vm.count("cst")) { - std::string filename = vm["cst"].as(); - std::ifstream in(filename); - if (!in) - log_error("Failed to open input CST file %s.\n", filename.c_str()); - ctx->read_cst(in); - } -} - -int main(int argc, char *argv[]) -{ - GowinCommandHandler handler(argc, argv); - return handler.exec(); -} -#endif diff --git a/gowin/pack.cc b/gowin/pack.cc deleted file mode 100644 index 951f94f3a0..0000000000 --- a/gowin/pack.cc +++ /dev/null @@ -1,1919 +0,0 @@ -/* - * nextpnr -- Next Generation Place and Route - * - * Copyright (C) 2018-19 gatecat - * Copyright (C) 2020 Pepijn de Vos - * - * 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 -#include -#include -#include -#include "cells.h" -#include "design_utils.h" -#include "log.h" -#include "util.h" - -#include "globals.h" - -NEXTPNR_NAMESPACE_BEGIN - -static bool check_availability(const Context *ctx, IdString type) -{ - switch (type.hash()) { - case ID_ELVDS_IBUF: - if (ctx->device != "GW1NZ-1") { - return true; - } - break; - case ID_ELVDS_IOBUF: - if (ctx->device == "GW1NZ-1") { - return true; - } - break; - case ID_TLVDS_IBUF: - if (ctx->device != "GW1NZ-1") { - return true; - } - break; - case ID_TLVDS_OBUF: - if (ctx->device != "GW1NZ-1" && ctx->device != "GW1N-1") { - return true; - } - break; - case ID_TLVDS_TBUF: - if (ctx->device != "GW1NZ-1" && ctx->device != "GW1N-1") { - return true; - } - break; - case ID_TLVDS_IOBUF: - if (ctx->device == "GW1N-4") { - return true; - } - break; - default: - return true; - } - log_info("%s is not supported for device %s.\n", type.c_str(ctx), ctx->device.c_str()); - return false; -} - -static void make_dummy_alu(Context *ctx, int alu_idx, CellInfo *ci, CellInfo *packed_head, - std::vector> &new_cells) -{ - if ((alu_idx % 2) == 0) { - return; - } - std::unique_ptr dummy = create_generic_cell(ctx, id_SLICE, ci->name.str(ctx) + "_DUMMY_ALULC"); - if (ctx->verbose) { - log_info("packed dummy ALU %s.\n", ctx->nameOf(dummy.get())); - } - dummy->params[id_ALU_MODE] = std::string("C2L"); - // add to cluster - dummy->cluster = packed_head->name; - dummy->constr_z = alu_idx % 6; - dummy->constr_x = alu_idx / 6; - dummy->constr_y = 0; - packed_head->constr_children.push_back(dummy.get()); - new_cells.push_back(std::move(dummy)); -} - -// replace ALU with LUT -static void pack_alus(Context *ctx) -{ - log_info("Packing ALUs..\n"); - - // cell name, CIN net name - pool> alu_heads; - - // collect heads - for (auto &cell : ctx->cells) { - CellInfo *ci = cell.second.get(); - if (is_alu(ctx, ci)) { - NetInfo *cin = ci->ports.at(id_CIN).net; - CellInfo *cin_ci = cin->driver.cell; - - if (cin == nullptr || cin_ci == nullptr) { - log_error("CIN disconnected at ALU:%s\n", ctx->nameOf(ci)); - continue; - } - - if (!is_alu(ctx, cin_ci) || cin->users.entries() > 1) { - if (ctx->verbose) { - log_info("ALU head found %s. CIN net is %s\n", ctx->nameOf(ci), ctx->nameOf(cin)); - } - alu_heads.insert(std::make_pair(ci->name, cin->name)); - } - } - } - - pool packed_cells; - pool delete_nets; - std::vector> new_cells; - - for (auto &head : alu_heads) { - CellInfo *ci = ctx->cells[head.first].get(); - IdString cin_netId = head.second; - if (ctx->verbose) { - log_info("cell '%s' is of type '%s'\n", ctx->nameOf(ci), ci->type.c_str(ctx)); - } - std::unique_ptr packed_head = create_generic_cell(ctx, id_SLICE, ci->name.str(ctx) + "_HEAD_ALULC"); - - // Head is always SLICE0 - packed_head->constr_z = 0; - packed_head->constr_abs_z = true; - if (ctx->verbose) { - log_info("packed ALU head into %s. CIN net is %s\n", ctx->nameOf(packed_head.get()), - ctx->nameOf(cin_netId)); - } - packed_head->connectPort(id_C, ctx->nets[ctx->id("$PACKER_VCC_NET")].get()); - if (cin_netId == ctx->id("$PACKER_GND_NET")) { - // CIN = 0 - packed_head->params[id_ALU_MODE] = std::string("C2L"); - } else { - if (cin_netId == ctx->id("$PACKER_VCC_NET")) { - // CIN = 1 - packed_head->params[id_ALU_MODE] = std::string("ONE2C"); - } else { - // CIN from logic - packed_head->connectPort(id_B, ctx->nets[cin_netId].get()); - packed_head->connectPort(id_D, ctx->nets[cin_netId].get()); - packed_head->params[id_ALU_MODE] = std::string("0"); // ADD - } - } - - int alu_idx = 1; - do { // go through the ALU chain - auto alu_bel = ci->attrs.find(id_BEL); - if (alu_bel != ci->attrs.end()) { - log_error("ALU %s placement restrictions are not supported.\n", ctx->nameOf(ci)); - return; - } - // remove cell - packed_cells.insert(ci->name); - - // CIN/COUT are hardwired, delete - ci->disconnectPort(id_CIN); - NetInfo *cout = ci->ports.at(id_COUT).net; - ci->disconnectPort(id_COUT); - - std::unique_ptr packed = create_generic_cell(ctx, id_SLICE, ci->name.str(ctx) + "_ALULC"); - if (ctx->verbose) { - log_info("packed ALU into %s. COUT net is %s\n", ctx->nameOf(packed.get()), ctx->nameOf(cout)); - } - - int mode = int_or_default(ci->params, id_ALU_MODE); - packed->params[id_ALU_MODE] = mode; - if (mode == 9) { // MULT - packed->connectPort(id_C, ctx->nets[ctx->id("$PACKER_GND_NET")].get()); - } else { - packed->connectPort(id_C, ctx->nets[ctx->id("$PACKER_VCC_NET")].get()); - } - - // add to cluster - packed->cluster = packed_head->name; - packed->constr_z = alu_idx % 6; - packed->constr_x = alu_idx / 6; - packed->constr_y = 0; - packed_head->constr_children.push_back(packed.get()); - ++alu_idx; - - // connect all remainig ports - ci->movePortTo(id_SUM, packed.get(), id_F); - switch (mode) { - case 0: // ADD - ci->movePortTo(id_I0, packed.get(), id_B); - ci->movePortTo(id_I1, packed.get(), id_D); - break; - case 1: // SUB - ci->movePortTo(id_I0, packed.get(), id_A); - ci->movePortTo(id_I1, packed.get(), id_D); - break; - case 5: // LE - ci->movePortTo(id_I0, packed.get(), id_A); - ci->movePortTo(id_I1, packed.get(), id_B); - break; - case 9: // MULT - ci->movePortTo(id_I0, packed.get(), id_A); - ci->movePortTo(id_I1, packed.get(), id_B); - packed->disconnectPort(id_D); - packed->connectPort(id_D, ctx->nets[ctx->id("$PACKER_VCC_NET")].get()); - break; - default: - ci->movePortTo(id_I0, packed.get(), id_A); - ci->movePortTo(id_I1, packed.get(), id_B); - ci->movePortTo(id_I3, packed.get(), id_D); - } - - new_cells.push_back(std::move(packed)); - - if (cout != nullptr && cout->users.entries() > 0) { - // if COUT used by logic - if ((cout->users.entries() > 1) || (!is_alu(ctx, (*cout->users.begin()).cell))) { - if (ctx->verbose) { - log_info("COUT is used by logic\n"); - } - // make gate C->logic - std::unique_ptr packed_tail = - create_generic_cell(ctx, id_SLICE, ci->name.str(ctx) + "_TAIL_ALULC"); - if (ctx->verbose) { - log_info("packed ALU tail into %s. COUT net is %s\n", ctx->nameOf(packed_tail.get()), - ctx->nameOf(cout)); - } - packed_tail->params[id_ALU_MODE] = std::string("C2L"); - packed_tail->connectPort(id_F, cout); - // add to cluster - packed_tail->cluster = packed_head->name; - packed_tail->constr_z = alu_idx % 6; - packed_tail->constr_x = alu_idx / 6; - packed_tail->constr_y = 0; - ++alu_idx; - packed_head->constr_children.push_back(packed_tail.get()); - new_cells.push_back(std::move(packed_tail)); - make_dummy_alu(ctx, alu_idx, ci, packed_head.get(), new_cells); - break; - } - // next ALU - ci = (*cout->users.begin()).cell; - // if ALU is too big - if (alu_idx == (ctx->gridDimX - 2) * 6 - 1) { - log_error("ALU %s is the %dth in the chain. Such long chains are not supported.\n", ctx->nameOf(ci), - alu_idx); - break; - } - } else { - // COUT is unused - if (ctx->verbose) { - log_info("cell is the ALU tail. Index is %d\n", alu_idx); - } - make_dummy_alu(ctx, alu_idx, ci, packed_head.get(), new_cells); - break; - } - } while (1); - - // add head to the cluster - packed_head->cluster = packed_head->name; - new_cells.push_back(std::move(packed_head)); - } - - // actual delete, erase and move cells/nets - for (auto pcell : packed_cells) { - ctx->cells.erase(pcell); - } - for (auto dnet : delete_nets) { - ctx->nets.erase(dnet); - } - for (auto &ncell : new_cells) { - ctx->cells[ncell->name] = std::move(ncell); - } -} - -// pack MUX2_LUT5 -static void pack_mux2_lut5(Context *ctx, CellInfo *ci, pool &packed_cells, pool &delete_nets, - std::vector> &new_cells) -{ - - if (bool_or_default(ci->attrs, id_SINGLE_INPUT_MUX)) { - // find the muxed LUT - NetInfo *i1 = ci->ports.at(id_I1).net; - - CellInfo *lut1 = net_driven_by(ctx, i1, is_lut, id_F); - if (lut1 == nullptr) { - log_error("MUX2_LUT5 '%s' port I1 isn't connected to the LUT\n", ctx->nameOf(ci)); - return; - } - if (ctx->verbose) { - log_info("found attached lut1 %s\n", ctx->nameOf(lut1)); - } - - // XXX enable the placement constraints - auto mux_bel = ci->attrs.find(id_BEL); - auto lut1_bel = lut1->attrs.find(id_BEL); - if (lut1_bel != lut1->attrs.end() || mux_bel != ci->attrs.end()) { - log_error("MUX2_LUT5 '%s' placement restrictions are not supported yet\n", ctx->nameOf(ci)); - return; - } - - std::unique_ptr packed = create_generic_cell(ctx, id_MUX2_LUT5, ci->name.str(ctx) + "_LC"); - if (ctx->verbose) { - log_info("packed cell %s into %s\n", ctx->nameOf(ci), ctx->nameOf(packed.get())); - } - // mux is the cluster root - packed->cluster = packed->name; - lut1->cluster = packed->name; - lut1->constr_z = -BelZ::mux_0_z + 1; - packed->constr_children.clear(); - - // reconnect MUX ports - ci->movePortTo(id_O, packed.get(), id_OF); - ci->movePortTo(id_I1, packed.get(), id_I1); - - // remove cells - packed_cells.insert(ci->name); - // new MUX cell - new_cells.push_back(std::move(packed)); - } else { - // find the muxed LUTs - NetInfo *i0 = ci->ports.at(id_I0).net; - NetInfo *i1 = ci->ports.at(id_I1).net; - - CellInfo *lut0 = net_driven_by(ctx, i0, is_lut, id_F); - CellInfo *lut1 = net_driven_by(ctx, i1, is_lut, id_F); - if (lut0 == nullptr || lut1 == nullptr) { - log_error("MUX2_LUT5 '%s' port I0 or I1 isn't connected to the LUT\n", ctx->nameOf(ci)); - return; - } - if (ctx->verbose) { - log_info("found attached lut0 %s\n", ctx->nameOf(lut0)); - log_info("found attached lut1 %s\n", ctx->nameOf(lut1)); - } - - // XXX enable the placement constraints - auto mux_bel = ci->attrs.find(id_BEL); - auto lut0_bel = lut0->attrs.find(id_BEL); - auto lut1_bel = lut1->attrs.find(id_BEL); - if (lut0_bel != lut0->attrs.end() || lut1_bel != lut1->attrs.end() || mux_bel != ci->attrs.end()) { - log_error("MUX2_LUT5 '%s' placement restrictions are not supported yet\n", ctx->nameOf(ci)); - return; - } - - std::unique_ptr packed = create_generic_cell(ctx, id_MUX2_LUT5, ci->name.str(ctx) + "_LC"); - if (ctx->verbose) { - log_info("packed cell %s into %s\n", ctx->nameOf(ci), ctx->nameOf(packed.get())); - } - // mux is the cluster root - packed->cluster = packed->name; - lut0->cluster = packed->name; - lut0->constr_z = -BelZ::mux_0_z; - lut1->cluster = packed->name; - lut1->constr_z = -BelZ::mux_0_z + 1; - packed->constr_children.clear(); - - // reconnect MUX ports - ci->movePortTo(id_O, packed.get(), id_OF); - ci->movePortTo(id_S0, packed.get(), id_SEL); - ci->movePortTo(id_I0, packed.get(), id_I0); - ci->movePortTo(id_I1, packed.get(), id_I1); - - // remove cells - packed_cells.insert(ci->name); - // new MUX cell - new_cells.push_back(std::move(packed)); - } -} - -// Common MUX2 packing routine -static void pack_mux2_lut(Context *ctx, CellInfo *ci, bool (*pred)(const BaseCtx *, const CellInfo *), - char const type_suffix, IdString const type_id, int const x[2], int const z[2], - pool &packed_cells, pool &delete_nets, - std::vector> &new_cells) -{ - // find the muxed LUTs - NetInfo *i0 = ci->ports.at(id_I0).net; - NetInfo *i1 = ci->ports.at(id_I1).net; - - CellInfo *mux0 = net_driven_by(ctx, i0, pred, id_OF); - CellInfo *mux1 = net_driven_by(ctx, i1, pred, id_OF); - if (mux0 == nullptr || mux1 == nullptr) { - log_error("MUX2_LUT%c '%s' port I0 or I1 isn't connected to the MUX\n", type_suffix, ctx->nameOf(ci)); - return; - } - if (ctx->verbose) { - log_info("found attached mux0 %s\n", ctx->nameOf(mux0)); - log_info("found attached mux1 %s\n", ctx->nameOf(mux1)); - } - - // XXX enable the placement constraints - auto mux_bel = ci->attrs.find(id_BEL); - auto mux0_bel = mux0->attrs.find(id_BEL); - auto mux1_bel = mux1->attrs.find(id_BEL); - if (mux0_bel != mux0->attrs.end() || mux1_bel != mux1->attrs.end() || mux_bel != ci->attrs.end()) { - log_error("MUX2_LUT%c '%s' placement restrictions are not supported yet\n", type_suffix, ctx->nameOf(ci)); - return; - } - - std::unique_ptr packed = create_generic_cell(ctx, type_id, ci->name.str(ctx) + "_LC"); - if (ctx->verbose) { - log_info("packed cell %s into %s\n", ctx->nameOf(ci), ctx->nameOf(packed.get())); - } - // mux is the cluster root - packed->cluster = packed->name; - mux0->cluster = packed->name; - mux0->constr_x = x[0]; - mux0->constr_y = 0; - mux0->constr_z = z[0]; - for (auto &child : mux0->constr_children) { - child->cluster = packed->name; - child->constr_x += mux0->constr_x; - child->constr_z += mux0->constr_z; - packed->constr_children.push_back(child); - } - mux0->constr_children.clear(); - mux1->cluster = packed->name; - mux1->constr_x = x[1]; - mux0->constr_y = 0; - mux1->constr_z = z[1]; - for (auto &child : mux1->constr_children) { - child->cluster = packed->name; - child->constr_x += mux1->constr_x; - child->constr_z += mux1->constr_z; - packed->constr_children.push_back(child); - } - mux1->constr_children.clear(); - packed->constr_children.push_back(mux0); - packed->constr_children.push_back(mux1); - - // reconnect MUX ports - ci->movePortTo(id_O, packed.get(), id_OF); - ci->movePortTo(id_S0, packed.get(), id_SEL); - ci->movePortTo(id_I0, packed.get(), id_I0); - ci->movePortTo(id_I1, packed.get(), id_I1); - - // remove cells - packed_cells.insert(ci->name); - // new MUX cell - new_cells.push_back(std::move(packed)); -} - -// pack MUX2_LUT6 -static void pack_mux2_lut6(Context *ctx, CellInfo *ci, pool &packed_cells, pool &delete_nets, - std::vector> &new_cells) -{ - static int x[] = {0, 0}; - static int z[] = {+1, -1}; - pack_mux2_lut(ctx, ci, is_mux2_lut5, '6', id_MUX2_LUT6, x, z, packed_cells, delete_nets, new_cells); -} - -// pack MUX2_LUT7 -static void pack_mux2_lut7(Context *ctx, CellInfo *ci, pool &packed_cells, pool &delete_nets, - std::vector> &new_cells) -{ - static int x[] = {0, 0}; - static int z[] = {+2, -2}; - pack_mux2_lut(ctx, ci, is_mux2_lut6, '7', id_MUX2_LUT7, x, z, packed_cells, delete_nets, new_cells); -} - -// pack MUX2_LUT8 -static void pack_mux2_lut8(Context *ctx, CellInfo *ci, pool &packed_cells, pool &delete_nets, - std::vector> &new_cells) -{ - static int x[] = {1, 0}; - static int z[] = {-4, -4}; - pack_mux2_lut(ctx, ci, is_mux2_lut7, '8', id_MUX2_LUT8, x, z, packed_cells, delete_nets, new_cells); -} - -// Pack wide LUTs -static void pack_wideluts(Context *ctx) -{ - log_info("Packing wide LUTs..\n"); - - pool packed_cells; - pool delete_nets; - std::vector> new_cells; - - pool mux2lut6; - pool mux2lut7; - pool mux2lut8; - - // do MUX2_LUT5 and collect LUT6/7/8 - log_info("Packing LUT5s..\n"); - for (auto &cell : ctx->cells) { - CellInfo *ci = cell.second.get(); - if (ctx->verbose) { - log_info("cell '%s' is of type '%s'\n", ctx->nameOf(ci), ci->type.c_str(ctx)); - } - if (is_widelut(ctx, ci)) { - if (is_mux2_lut5(ctx, ci)) { - pack_mux2_lut5(ctx, ci, packed_cells, delete_nets, new_cells); - } else { - if (is_mux2_lut6(ctx, ci)) { - mux2lut6.insert(ci->name); - } else { - if (is_mux2_lut7(ctx, ci)) { - mux2lut7.insert(ci->name); - } else { - if (is_mux2_lut8(ctx, ci)) { - mux2lut8.insert(ci->name); - } - } - } - } - } - } - // do MUX_LUT6 - log_info("Packing LUT6s..\n"); - for (auto &cell_name : mux2lut6) { - pack_mux2_lut6(ctx, ctx->cells[cell_name].get(), packed_cells, delete_nets, new_cells); - } - - // do MUX_LUT7 - log_info("Packing LUT7s..\n"); - for (auto &cell_name : mux2lut7) { - pack_mux2_lut7(ctx, ctx->cells[cell_name].get(), packed_cells, delete_nets, new_cells); - } - - // do MUX_LUT8 - log_info("Packing LUT8s..\n"); - for (auto &cell_name : mux2lut8) { - pack_mux2_lut8(ctx, ctx->cells[cell_name].get(), packed_cells, delete_nets, new_cells); - } - - // actual delete, erase and move cells/nets - for (auto pcell : packed_cells) { - ctx->cells.erase(pcell); - } - for (auto dnet : delete_nets) { - ctx->nets.erase(dnet); - } - for (auto &ncell : new_cells) { - ctx->cells[ncell->name] = std::move(ncell); - } -} - -// Pack LUTs and LUT-FF pairs -static void pack_lut_lutffs(Context *ctx) -{ - log_info("Packing LUT-FFs..\n"); - - pool packed_cells; - std::vector> new_cells; - for (auto &cell : ctx->cells) { - CellInfo *ci = cell.second.get(); - if (ctx->verbose) - log_info("cell '%s' is of type '%s'\n", ctx->nameOf(ci), ci->type.c_str(ctx)); - if (is_lut(ctx, ci)) { - std::unique_ptr packed = create_generic_cell(ctx, id_SLICE, ci->name.str(ctx) + "_LC"); - for (auto &attr : ci->attrs) - packed->attrs[attr.first] = attr.second; - packed_cells.insert(ci->name); - if (ctx->verbose) - log_info("packed cell %s into %s\n", ctx->nameOf(ci), ctx->nameOf(packed.get())); - // See if we can pack into a DFF - // TODO: LUT cascade - NetInfo *o = ci->ports.at(id_F).net; - CellInfo *dff = net_only_drives(ctx, o, is_ff, id_D, true); - auto lut_bel = ci->attrs.find(id_BEL); - bool packed_dff = false; - if (dff) { - if (ctx->verbose) - log_info("found attached dff %s\n", ctx->nameOf(dff)); - auto dff_bel = dff->attrs.find(id_BEL); - if (lut_bel != ci->attrs.end() && dff_bel != dff->attrs.end() && lut_bel->second != dff_bel->second) { - // Locations don't match, can't pack - } else { - lut_to_lc(ctx, ci, packed.get(), false); - dff_to_lc(ctx, dff, packed.get(), false); - ctx->nets.erase(o->name); - if (dff_bel != dff->attrs.end()) - packed->attrs[id_BEL] = dff_bel->second; - packed_cells.insert(dff->name); - if (ctx->verbose) - log_info("packed cell %s into %s\n", ctx->nameOf(dff), ctx->nameOf(packed.get())); - packed_dff = true; - } - } - if (!packed_dff) { - lut_to_lc(ctx, ci, packed.get(), true); - } - new_cells.push_back(std::move(packed)); - } - } - for (auto pcell : packed_cells) { - ctx->cells.erase(pcell); - } - for (auto &ncell : new_cells) { - ctx->cells[ncell->name] = std::move(ncell); - } -} - -// Pack FFs not packed as LUTFFs -static void pack_nonlut_ffs(Context *ctx) -{ - log_info("Packing non-LUT FFs..\n"); - - pool packed_cells; - std::vector> new_cells; - - for (auto &cell : ctx->cells) { - CellInfo *ci = cell.second.get(); - if (is_ff(ctx, ci)) { - std::unique_ptr packed = create_generic_cell(ctx, id_SLICE, ci->name.str(ctx) + "_DFFLC"); - for (auto &attr : ci->attrs) - packed->attrs[attr.first] = attr.second; - if (ctx->verbose) - log_info("packed cell %s into %s\n", ctx->nameOf(ci), ctx->nameOf(packed.get())); - packed_cells.insert(ci->name); - dff_to_lc(ctx, ci, packed.get(), true); - new_cells.push_back(std::move(packed)); - } - } - for (auto pcell : packed_cells) { - ctx->cells.erase(pcell); - } - for (auto &ncell : new_cells) { - ctx->cells[ncell->name] = std::move(ncell); - } -} - -// Merge a net into a constant net -static void set_net_constant(const Context *ctx, NetInfo *orig, NetInfo *constnet) -{ - orig->driver.cell = nullptr; - for (auto user : orig->users) { - if (user.cell != nullptr) { - CellInfo *uc = user.cell; - if (ctx->verbose) - log_info("%s user %s\n", ctx->nameOf(orig), ctx->nameOf(uc)); - - if (is_lut(ctx, uc) && (user.port.str(ctx).at(0) == 'I')) { - auto it_param = uc->params.find(id_INIT); - if (it_param == uc->params.end()) - log_error("No initialization for lut found.\n"); - - int64_t uc_init = it_param->second.intval; - int64_t mask = 0; - uint8_t amt = 0; - - if (user.port == id_I0) { - mask = 0x5555; - amt = 1; - } else if (user.port == id_I1) { - mask = 0x3333; - amt = 2; - } else if (user.port == id_I2) { - mask = 0x0F0F; - amt = 4; - } else if (user.port == id_I3) { - mask = 0x00FF; - amt = 8; - } else { - log_error("Port number invalid.\n"); - } - - if ((constnet->name == ctx->id("$PACKER_GND_NET"))) { - uc_init = (uc_init & mask) | ((uc_init & mask) << amt); - } else { - uc_init = (uc_init & (mask << amt)) | ((uc_init & (mask << amt)) >> amt); - } - - size_t uc_init_len = it_param->second.to_string().length(); - uc_init &= (1LL << uc_init_len) - 1; - - if (ctx->verbose) - log_info("%s lut config modified from 0x%" PRIX64 " to 0x%" PRIX64 "\n", ctx->nameOf(uc), - it_param->second.intval, uc_init); - - it_param->second = Property(uc_init, uc_init_len); - uc->ports[user.port].net = nullptr; - uc->ports[user.port].user_idx = {}; - } else { - uc->ports[user.port].net = constnet; - uc->ports[user.port].user_idx = constnet->users.add(user); - } - } - } - orig->users.clear(); -} - -// Pack constants (simple implementation) -static void pack_constants(Context *ctx) -{ - log_info("Packing constants..\n"); - - std::unique_ptr gnd_cell = create_generic_cell(ctx, id_GND, "$PACKER_GND"); - auto gnd_net = std::make_unique(ctx->id("$PACKER_GND_NET")); - gnd_net->driver.cell = gnd_cell.get(); - gnd_net->driver.port = id_G; - gnd_cell->ports.at(id_G).net = gnd_net.get(); - - std::unique_ptr vcc_cell = create_generic_cell(ctx, id_VCC, "$PACKER_VCC"); - auto vcc_net = std::make_unique(ctx->id("$PACKER_VCC_NET")); - vcc_net->driver.cell = vcc_cell.get(); - vcc_net->driver.port = id_V; - vcc_cell->ports.at(id_V).net = vcc_net.get(); - - std::vector dead_nets; - - bool gnd_used = true; // XXX May be needed for simplified IO - - for (auto &net : ctx->nets) { - NetInfo *ni = net.second.get(); - if (ni->driver.cell != nullptr && ni->driver.cell->type == id_GND) { - IdString drv_cell = ni->driver.cell->name; - set_net_constant(ctx, ni, gnd_net.get()); - gnd_used = true; - dead_nets.push_back(net.first); - ctx->cells.erase(drv_cell); - } else if (ni->driver.cell != nullptr && ni->driver.cell->type == id_VCC) { - IdString drv_cell = ni->driver.cell->name; - set_net_constant(ctx, ni, vcc_net.get()); - dead_nets.push_back(net.first); - ctx->cells.erase(drv_cell); - } - } - - if (gnd_used) { - ctx->cells[gnd_cell->name] = std::move(gnd_cell); - ctx->nets[gnd_net->name] = std::move(gnd_net); - } - // Vcc cell always inserted for now, as it may be needed during carry legalisation (TODO: trim later if actually - // never used?) - ctx->cells[vcc_cell->name] = std::move(vcc_cell); - ctx->nets[vcc_net->name] = std::move(vcc_net); - - for (auto dn : dead_nets) { - ctx->nets.erase(dn); - } -} - -// Pack global set-reset -static void pack_gsr(Context *ctx) -{ - log_info("Packing GSR..\n"); - - bool user_gsr = false; - for (auto &cell : ctx->cells) { - CellInfo *ci = cell.second.get(); - if (ctx->verbose) - log_info("cell '%s' is of type '%s'\n", ctx->nameOf(ci), ci->type.c_str(ctx)); - if (ci->type == id_GSR) { - user_gsr = true; - break; - } - } - if (!user_gsr) { - // XXX - bool have_gsr_bel = false; - for (auto bi : ctx->bels) { - if (bi.second.type == id_GSR) { - have_gsr_bel = true; - break; - } - } - if (have_gsr_bel) { - // make default GSR - std::unique_ptr gsr_cell = create_generic_cell(ctx, id_GSR, "GSR"); - gsr_cell->connectPort(id_GSRI, ctx->nets[ctx->id("$PACKER_VCC_NET")].get()); - ctx->cells[gsr_cell->name] = std::move(gsr_cell); - } else { - log_info("No GSR in the chip base\n"); - } - } -} - -// Pack shadow RAM -void pack_sram(Context *ctx) -{ - log_info("Packing Shadow RAM..\n"); - - pool packed_cells; - std::vector> new_cells; - - for (auto &cell : ctx->cells) { - CellInfo *ci = cell.second.get(); - if (is_sram(ctx, ci)) { - - // Create RAMW slice - std::unique_ptr ramw_slice = create_generic_cell(ctx, id_RAMW, ci->name.str(ctx) + "$RAMW_SLICE"); - sram_to_ramw_split(ctx, ci, ramw_slice.get()); - ramw_slice->connectPort(id_CE, ctx->nets[ctx->id("$PACKER_VCC_NET")].get()); - - // Create actual RAM slices - std::unique_ptr ram_comb[4]; - for (int i = 0; i < 4; i++) { - ram_comb[i] = create_generic_cell(ctx, id_SLICE, ci->name.str(ctx) + "$SRAM_SLICE" + std::to_string(i)); - ram_comb[i]->params[id_FF_USED] = 1; - ram_comb[i]->params[id_FF_TYPE] = std::string("RAM"); - sram_to_slice(ctx, ci, ram_comb[i].get(), i); - } - // Create 'block' SLICEs as a placement hint that these cells are mutually exclusive with the RAMW - std::unique_ptr ramw_block[2]; - for (int i = 0; i < 2; i++) { - ramw_block[i] = - create_generic_cell(ctx, id_SLICE, ci->name.str(ctx) + "$RAMW_BLOCK" + std::to_string(i)); - ram_comb[i]->params[id_FF_USED] = 1; - ramw_block[i]->params[id_FF_TYPE] = std::string("RAM"); - } - - // Disconnect ports of original cell after packing - // ci->disconnectPort(id_WCK); - // ci->disconnectPort(id_WRE); - - for (int i = 0; i < 4; i++) - ci->disconnectPort(ctx->idf("RAD[%d]", i)); - - // Setup placement constraints - // Use the 0th bit as an anchor - ram_comb[0]->constr_abs_z = true; - ram_comb[0]->constr_z = 0; - ram_comb[0]->cluster = ram_comb[0]->name; - for (int i = 1; i < 4; i++) { - ram_comb[i]->cluster = ram_comb[0]->name; - ram_comb[i]->constr_abs_z = true; - ram_comb[i]->constr_x = 0; - ram_comb[i]->constr_y = 0; - ram_comb[i]->constr_z = i; - ram_comb[0]->constr_children.push_back(ram_comb[i].get()); - } - for (int i = 0; i < 2; i++) { - ramw_block[i]->cluster = ram_comb[0]->name; - ramw_block[i]->constr_abs_z = true; - ramw_block[i]->constr_x = 0; - ramw_block[i]->constr_y = 0; - ramw_block[i]->constr_z = i + 4; - ram_comb[0]->constr_children.push_back(ramw_block[i].get()); - } - - ramw_slice->cluster = ram_comb[0]->name; - ramw_slice->constr_abs_z = true; - ramw_slice->constr_x = 0; - ramw_slice->constr_y = 0; - ramw_slice->constr_z = BelZ::lutram_0_z; - ram_comb[0]->constr_children.push_back(ramw_slice.get()); - - for (int i = 0; i < 4; i++) - new_cells.push_back(std::move(ram_comb[i])); - for (int i = 0; i < 2; i++) - new_cells.push_back(std::move(ramw_block[i])); - new_cells.push_back(std::move(ramw_slice)); - packed_cells.insert(ci->name); - } - } - for (auto pcell : packed_cells) { - ctx->cells.erase(pcell); - } - for (auto &ncell : new_cells) { - ctx->cells[ncell->name] = std::move(ncell); - } -} - -static bool is_nextpnr_iob(const Context *ctx, CellInfo *cell) -{ - return cell->type == ctx->id("$nextpnr_ibuf") || cell->type == ctx->id("$nextpnr_obuf") || - cell->type == ctx->id("$nextpnr_iobuf"); -} - -static bool is_gowin_iob(const Context *ctx, const CellInfo *cell) -{ - switch (cell->type.index) { - case ID_IBUF: - case ID_OBUF: - case ID_IOBUF: - case ID_TBUF: - return true; - default: - return false; - } -} - -static bool is_gowin_diff_iob(const Context *ctx, const CellInfo *cell) -{ - switch (cell->type.index) { - case ID_TLVDS_OBUF: - case ID_TLVDS_TBUF: - case ID_TLVDS_IBUF: - case ID_TLVDS_IOBUF: - case ID_ELVDS_OBUF: - case ID_ELVDS_TBUF: - case ID_ELVDS_IBUF: - case ID_ELVDS_IOBUF: - return true; - default: - return false; - } -} - -static bool is_gowin_iologic(const Context *ctx, const CellInfo *cell) -{ - switch (cell->type.index) { - case ID_ODDR: /* fall-through*/ - case ID_ODDRC: /* fall-through*/ - case ID_OSER4: /* fall-through*/ - case ID_OSER8: /* fall-through*/ - case ID_OSER10: /* fall-through*/ - case ID_OSER16: /* fall-through*/ - case ID_OVIDEO: /* fall-through*/ - case ID_IDDR: /* fall-through*/ - case ID_IDDRC: /* fall-through*/ - case ID_IDES4: /* fall-through*/ - case ID_IDES8: /* fall-through*/ - case ID_IDES10: /* fall-through*/ - case ID_IDES16: /* fall-through*/ - case ID_IVIDEO: - return true; - default: - return false; - } -} - -// IDES has different outputs -static void reconnect_ides_outs(CellInfo *ci) -{ - switch (ci->type.hash()) { - case ID_IDDR: /* fall-through*/ - case ID_IDDRC: - ci->renamePort(id_Q1, id_Q9); - ci->renamePort(id_Q0, id_Q8); - break; - case ID_IDES4: - ci->renamePort(id_Q3, id_Q9); - ci->renamePort(id_Q2, id_Q8); - ci->renamePort(id_Q1, id_Q7); - ci->renamePort(id_Q0, id_Q6); - break; - case ID_IVIDEO: - ci->renamePort(id_Q6, id_Q9); - ci->renamePort(id_Q5, id_Q8); - ci->renamePort(id_Q4, id_Q7); - ci->renamePort(id_Q3, id_Q6); - ci->renamePort(id_Q2, id_Q5); - ci->renamePort(id_Q1, id_Q4); - ci->renamePort(id_Q0, id_Q3); - break; - case ID_IDES8: - ci->renamePort(id_Q7, id_Q9); - ci->renamePort(id_Q6, id_Q8); - ci->renamePort(id_Q5, id_Q7); - ci->renamePort(id_Q4, id_Q6); - ci->renamePort(id_Q3, id_Q5); - ci->renamePort(id_Q2, id_Q4); - ci->renamePort(id_Q1, id_Q3); - ci->renamePort(id_Q0, id_Q2); - break; - default: - break; - } -} - -static void get_next_oser16_loc(std::string device, Loc &loc) -{ - if (device == "GW1NSR-4C") { - if (loc.y == 0) { - ++loc.x; - } else { - ++loc.y; - } - } else { - if (device == "GW1NR-9" || device == "GW1NR-9C") { - ++loc.x; - } - } -} - -// create IOB connections for gowin_pack -static void make_iob_nets(Context *ctx, CellInfo *iob) -{ - for (const auto &port : iob->ports) { - const NetInfo *net = iob->getPort(port.first); - std::string connected_net = "NET"; - if (net != nullptr) { - if (ctx->verbose) { - log_info("%s: %s - %s\n", ctx->nameOf(iob), port.first.c_str(ctx), ctx->nameOf(net)); - } - if (net->name == ctx->id("$PACKER_VCC_NET")) { - connected_net = "VCC"; - } else if (net->name == ctx->id("$PACKER_GND_NET")) { - connected_net = "GND"; - } - iob->setParam(ctx->idf("NET_%s", port.first.c_str(ctx)), connected_net); - } - } -} - -// Pack IO logic -static void pack_iologic(Context *ctx) -{ - pool packed_cells; - pool delete_nets; - - std::vector> new_cells; - log_info("Packing IO logic..\n"); - - for (auto &cell : ctx->cells) { - CellInfo *ci = cell.second.get(); - if (ctx->verbose) - log_info("cell '%s' is of type '%s'\n", ctx->nameOf(ci), ci->type.c_str(ctx)); - if (ci->type == id_IOB) { - make_iob_nets(ctx, ci); - } - if (is_gowin_iologic(ctx, ci)) { - CellInfo *q0_dst = nullptr; - CellInfo *q1_dst = nullptr; - switch (ci->type.hash()) { - case ID_ODDR: /* fall-through */ - case ID_ODDRC: /* fall-through */ - case ID_OSER4: /* fall-through */ - case ID_OSER8: /* fall-through */ - case ID_OSER10: /* fall-through */ - case ID_OVIDEO: { - IdString output = id_Q; - IdString output_1 = IdString(); - if (ci->type == id_ODDR || ci->type == id_ODDRC || ci->type == id_OSER4 || ci->type == id_OSER8) { - output = id_Q0; - output_1 = id_Q1; - } - q0_dst = net_only_drives(ctx, ci->ports.at(output).net, is_iob, id_I); - NPNR_ASSERT(q0_dst != nullptr); - - auto iob_bel = q0_dst->attrs.find(id_BEL); - if (iob_bel == q0_dst->attrs.end()) { - log_error("No constraints for %s. The pins for IDES/OSER must be specified explicitly.\n", - ctx->nameOf(q0_dst)); - } - - Loc loc = ctx->getBelLocation(ctx->getBelByNameStr(iob_bel->second.as_string())); - loc.z += BelZ::iologic_z; - ci->setAttr(id_BEL, ctx->getBelName(ctx->getBelByLocation(loc)).str(ctx)); - BelId bel = ctx->getBelByLocation(loc); - if (bel == BelId()) { - log_info("No bel for %s at %s. Can't place IDES/OSER here\n", ctx->nameOf(ci), - iob_bel->second.as_string().c_str()); - } - - std::string out_mode; - switch (ci->type.hash()) { - case ID_ODDR: - case ID_ODDRC: - out_mode = "ODDRX1"; - break; - case ID_OSER4: - out_mode = "ODDRX2"; - break; - case ID_OSER8: - out_mode = "ODDRX4"; - break; - case ID_OSER10: - out_mode = "ODDRX5"; - break; - case ID_OVIDEO: - out_mode = "VIDEORX"; - break; - } - ci->setParam(ctx->id("OUTMODE"), out_mode); - - // mark IOB as used by IOLOGIC - q0_dst->setParam(id_IOLOGIC_IOB, 1); - - bool use_diff_io = false; - if (q0_dst->attrs.count(id_DIFF_TYPE)) { - ci->setAttr(id_OBUF_TYPE, std::string("DBUF")); // XXX compatibility - ci->setParam(id_OBUF_TYPE, std::string("DBUF")); - use_diff_io = true; - } else { - ci->setAttr(id_OBUF_TYPE, std::string("SBUF")); // XXX compatibility - ci->setParam(id_OBUF_TYPE, std::string("SBUF")); - } - - // disconnect Q output: it is wired internally - delete_nets.insert(ci->ports.at(output).net->name); - q0_dst->disconnectPort(id_I); - ci->disconnectPort(output); - if (ctx->bels.at(ctx->getBelByNameStr(iob_bel->second.as_string())).pins.count(id_GW9C_ALWAYS_LOW1)) { - q0_dst->disconnectPort(id_GW9C_ALWAYS_LOW1); - q0_dst->connectPort(id_GW9C_ALWAYS_LOW1, ctx->nets[ctx->id("$PACKER_VCC_NET")].get()); - } - if (ctx->bels.at(ctx->getBelByLocation(loc)).pins.count(id_DAADJ0)) { - ci->addInput(id_DAADJ0); - ci->connectPort(id_DAADJ0, ctx->nets[ctx->id("$PACKER_GND_NET")].get()); - } - if (ctx->bels.at(ctx->getBelByLocation(loc)).pins.count(id_DAADJ1)) { - ci->addInput(id_DAADJ1); - ci->connectPort(id_DAADJ1, ctx->nets[ctx->id("$PACKER_VCC_NET")].get()); - } - - // if Q1 is connected then disconnet it too - if (output_1 != IdString() && port_used(ci, output_1)) { - q1_dst = net_only_drives(ctx, ci->ports.at(output_1).net, is_iob, id_OEN); - if (q1_dst != nullptr) { - delete_nets.insert(ci->ports.at(output_1).net->name); - q0_dst->disconnectPort(id_OEN); - ci->disconnectPort(output_1); - ci->setAttr(id_IOBUF, 1); - } - } - ci->setAttr(id_IOBUF, 0); - ci->setAttr(id_IOLOGIC_TYPE, ci->type.str(ctx)); - - if (ci->type == id_OSER4 || ci->type == id_ODDR || ci->type == id_ODDRC) { - if (ci->type == id_OSER4) { - // two OSER4 share FCLK, check it - Loc other_loc = loc; - other_loc.z = 1 - loc.z + 2 * BelZ::iologic_z; - BelId other_bel = ctx->getBelByLocation(other_loc); - CellInfo *other_cell = ctx->getBoundBelCell(other_bel); - if (other_cell != nullptr) { - NPNR_ASSERT(other_cell->type == id_OSER4); - if (ci->ports.at(id_FCLK).net != other_cell->ports.at(id_FCLK).net) { - log_error("%s and %s have differnet FCLK nets\n", ctx->nameOf(ci), - ctx->nameOf(other_cell)); - } - } - } - } else { - std::unique_ptr dummy = - create_generic_cell(ctx, id_DUMMY_CELL, ci->name.str(ctx) + "_IOLOGIC_IO"); - loc.z = 1 - loc.z + BelZ::iologic_z; - if (!use_diff_io) { - dummy->setAttr(id_BEL, ctx->getBelName(ctx->getBelByLocation(loc)).str(ctx)); - new_cells.push_back(std::move(dummy)); - } - loc.z += BelZ::iologic_z; - - std::unique_ptr aux_cell = - create_generic_cell(ctx, id_IOLOGIC, ci->name.str(ctx) + "_AUX"); - aux_cell->setAttr(id_IOLOGIC_TYPE, std::string("DUMMY")); - aux_cell->setParam(ctx->id("OUTMODE"), std::string("DDRENABLE")); - aux_cell->setAttr(ctx->id("IOLOGIC_MASTER_CELL"), ci->name.str(ctx)); - aux_cell->setAttr(id_BEL, ctx->getBelName(ctx->getBelByLocation(loc)).str(ctx)); - if (port_used(ci, id_RESET)) { - aux_cell->connectPort(id_RESET, ci->ports.at(id_RESET).net); - } - if (port_used(ci, id_PCLK)) { - aux_cell->connectPort(id_PCLK, ci->ports.at(id_PCLK).net); - } - new_cells.push_back(std::move(aux_cell)); - } - ci->type = id_IOLOGIC; - } break; - case ID_IDDR: /* fall-through */ - case ID_IDDRC: /* fall-through */ - case ID_IDES4: /* fall-through */ - case ID_IDES8: /* fall-through */ - case ID_IDES10: /* fall-through */ - case ID_IVIDEO: { - CellInfo *d_src = net_driven_by(ctx, ci->getPort(id_D), is_iob, id_O); - NPNR_ASSERT(d_src != nullptr); - - auto iob_bel = d_src->attrs.find(id_BEL); - if (iob_bel == d_src->attrs.end()) { - log_error("No constraints for %s. The pins for IDES/OSER must be specified explicitly.\n", - ctx->nameOf(d_src)); - } - - Loc loc = ctx->getBelLocation(ctx->getBelByNameStr(iob_bel->second.as_string())); - loc.z += BelZ::iologic_z; - ci->setAttr(id_BEL, ctx->getBelName(ctx->getBelByLocation(loc)).str(ctx)); - BelId bel = ctx->getBelByLocation(loc); - if (bel == BelId()) { - log_error("No bel for %s at %s. Can't place IDES/OSER here\n", ctx->nameOf(ci), - iob_bel->second.as_string().c_str()); - } - std::string in_mode; - switch (ci->type.hash()) { - case ID_IDDR: /* fall-through */ - case ID_IDDRC: - in_mode = "IDDRX1"; - break; - case ID_IDES4: - in_mode = "IDDRX2"; - break; - case ID_IDES8: - in_mode = "IDDRX4"; - break; - case ID_IDES10: - in_mode = "IDDRX5"; - break; - case ID_IVIDEO: - in_mode = "VIDEORX"; - break; - } - ci->setParam(ctx->id("INMODE"), in_mode); - - // mark IOB as used by IOLOGIC - d_src->setParam(id_IOLOGIC_IOB, 1); - - bool use_diff_io = false; - if (d_src->attrs.count(id_DIFF_TYPE)) { - ci->setAttr(id_IBUF_TYPE, std::string("DBUF")); // XXX compatibility - ci->setParam(id_IBUF_TYPE, std::string("DBUF")); - use_diff_io = true; - } else { - ci->setAttr(id_IBUF_TYPE, std::string("SBUF")); // XXX compatibility - ci->setParam(id_IBUF_TYPE, std::string("SBUF")); - } - - // disconnect D input: it is wired internally - delete_nets.insert(ci->getPort(id_D)->name); - d_src->disconnectPort(id_O); - ci->disconnectPort(id_D); - ci->setAttr(id_IOLOGIC_TYPE, ci->type.str(ctx)); - reconnect_ides_outs(ci); - - // common clock inputs - if (ci->type == id_IDES4 || ci->type == id_IDDR || ci->type == id_IDDRC) { - if (ci->type == id_IDES4) { - // two IDER4 share FCLK, check it - Loc other_loc = loc; - other_loc.z = 1 - loc.z + 2 * BelZ::iologic_z; - BelId other_bel = ctx->getBelByLocation(other_loc); - CellInfo *other_cell = ctx->getBoundBelCell(other_bel); - if (other_cell != nullptr) { - NPNR_ASSERT(other_cell->type == id_IDES4); - if (ci->ports.at(id_FCLK).net != other_cell->ports.at(id_FCLK).net) { - log_error("%s and %s have differnet FCLK nets\n", ctx->nameOf(ci), - ctx->nameOf(other_cell)); - } - } - } - } else { - std::unique_ptr dummy = - create_generic_cell(ctx, id_DUMMY_CELL, ci->name.str(ctx) + "_IOLOGIC_IO"); - loc.z = 1 - loc.z + BelZ::iologic_z; - if (!use_diff_io) { - dummy->setAttr(id_BEL, ctx->getBelName(ctx->getBelByLocation(loc)).str(ctx)); - new_cells.push_back(std::move(dummy)); - } - loc.z += BelZ::iologic_z; - - std::unique_ptr aux_cell = - create_generic_cell(ctx, id_IOLOGIC, ci->name.str(ctx) + "_AUX"); - aux_cell->setAttr(id_IOLOGIC_TYPE, std::string("DUMMY")); - aux_cell->setParam(ctx->id("INMODE"), std::string("DDRENABLE")); - aux_cell->setAttr(ctx->id("IOLOGIC_MASTER_CELL"), ci->name.str(ctx)); - aux_cell->setAttr(id_BEL, ctx->getBelName(ctx->getBelByLocation(loc)).str(ctx)); - if (port_used(ci, id_RESET)) { - aux_cell->connectPort(id_RESET, ci->ports.at(id_RESET).net); - } - if (port_used(ci, id_PCLK)) { - aux_cell->connectPort(id_PCLK, ci->ports.at(id_PCLK).net); - } - new_cells.push_back(std::move(aux_cell)); - } - ci->type = id_IOLOGIC; - } break; - case ID_OSER16: { - IdString output = id_Q; - q0_dst = net_only_drives(ctx, ci->ports.at(output).net, is_iob, id_I); - NPNR_ASSERT(q0_dst != nullptr); - - auto iob_bel = q0_dst->attrs.find(id_BEL); - if (iob_bel == q0_dst->attrs.end()) { - log_error("No constraints for %s. The pins for IDES/OSER must be specified explicitly.\n", - ctx->nameOf(q0_dst)); - } - - Loc loc = ctx->getBelLocation(ctx->getBelByNameStr(iob_bel->second.as_string())); - if (loc.z != BelZ::ioba_z) { - log_error("IDES16/OSER16 %s must be an A pin.\n", ctx->nameOf(ci)); - } - - loc.z = BelZ::oser16_z; - ci->setAttr(id_BEL, ctx->getBelName(ctx->getBelByLocation(loc)).str(ctx)); - BelId bel = ctx->getBelByLocation(loc); - if (bel == BelId()) { - log_error("No bel for %s at %s. Can't place IDES/OSER here\n", ctx->nameOf(ci), - iob_bel->second.as_string().c_str()); - } - - // mark IOB as used by IOLOGIC - q0_dst->setParam(id_IOLOGIC_IOB, 1); - - bool use_diff_io = false; - if (q0_dst->attrs.count(id_DIFF_TYPE)) { - ci->setAttr(id_OBUF_TYPE, std::string("DBUF")); // compatibility - ci->setParam(id_OBUF_TYPE, std::string("DBUF")); - use_diff_io = true; - } else { - ci->setAttr(id_OBUF_TYPE, std::string("SBUF")); // compatibility - ci->setParam(id_OBUF_TYPE, std::string("SBUF")); - } - - // disconnect Q output: it is wired internally - delete_nets.insert(ci->ports.at(output).net->name); - q0_dst->disconnectPort(id_I); - ci->disconnectPort(output); - loc.z = BelZ::ioba_z; - if (ctx->bels.at(ctx->getBelByLocation(loc)).pins.count(id_GW9C_ALWAYS_LOW1)) { - q0_dst->disconnectPort(id_GW9C_ALWAYS_LOW1); - q0_dst->connectPort(id_GW9C_ALWAYS_LOW1, ctx->nets[ctx->id("$PACKER_VCC_NET")].get()); - } - if (ctx->bels.at(ctx->getBelByLocation(loc)).pins.count(id_GW9_ALWAYS_LOW0)) { - q0_dst->disconnectPort(id_GW9_ALWAYS_LOW0); - q0_dst->connectPort(id_GW9_ALWAYS_LOW0, ctx->nets[ctx->id("$PACKER_VCC_NET")].get()); - } - - // make aux cells - std::unique_ptr dummy = - create_generic_cell(ctx, id_DUMMY_CELL, ci->name.str(ctx) + "_IOLOGIC_IO"); - loc.z = BelZ::iobb_z; - if (!use_diff_io) { - dummy->setAttr(id_BEL, ctx->getBelName(ctx->getBelByLocation(loc)).str(ctx)); - new_cells.push_back(std::move(dummy)); - } - loc.z = BelZ::iologic_z; - - // main iologic cell - std::string master_name = ci->name.str(ctx) + "_MAIN"; - - // aux cells - std::unique_ptr aux_cell = create_generic_cell(ctx, id_IOLOGIC, ci->name.str(ctx) + "_AUX0"); - aux_cell->setAttr(id_IOLOGIC_TYPE, std::string("OSER16")); - aux_cell->setAttr(ctx->id("IOLOGIC_MASTER_CELL"), master_name); - aux_cell->setAttr(id_BEL, ctx->getBelName(ctx->getBelByLocation(loc)).str(ctx)); - aux_cell->setParam(ctx->id("OUTMODE"), std::string("ODDRX8")); - aux_cell->setParam(ctx->id("UPDATE"), std::string("SAME")); - if (port_used(ci, id_RESET)) { - aux_cell->connectPort(id_RESET, ci->ports.at(id_RESET).net); - } - if (port_used(ci, id_PCLK)) { - aux_cell->connectPort(id_PCLK, ci->ports.at(id_PCLK).net); - } - new_cells.push_back(std::move(aux_cell)); - - // aux iologic cells - loc.z = BelZ::iologic_z + 1; - aux_cell = create_generic_cell(ctx, id_IOLOGIC, ci->name.str(ctx) + "_AUX1"); - aux_cell->setAttr(id_IOLOGIC_TYPE, std::string("DUMMY")); - aux_cell->setAttr(ctx->id("IOLOGIC_MASTER_CELL"), master_name); - aux_cell->setAttr(id_BEL, ctx->getBelName(ctx->getBelByLocation(loc)).str(ctx)); - aux_cell->setParam(ctx->id("OUTMODE"), std::string("DDRENABLE16")); - aux_cell->setParam(ctx->id("UPDATE"), std::string("SAME")); - if (port_used(ci, id_RESET)) { - aux_cell->connectPort(id_RESET, ci->ports.at(id_RESET).net); - } - if (port_used(ci, id_PCLK)) { - aux_cell->connectPort(id_PCLK, ci->ports.at(id_PCLK).net); - } - new_cells.push_back(std::move(aux_cell)); - - // master - get_next_oser16_loc(ctx->device, loc); - loc.z = BelZ::iologic_z; - aux_cell = create_generic_cell(ctx, id_IOLOGIC, master_name); - aux_cell->setAttr(id_IOLOGIC_TYPE, std::string("DUMMY")); - aux_cell->setAttr(id_BEL, ctx->getBelName(ctx->getBelByLocation(loc)).str(ctx)); - aux_cell->setParam(ctx->id("OUTMODE"), std::string("DDRENABLE16")); - aux_cell->setParam(ctx->id("UPDATE"), std::string("SAME")); - if (port_used(ci, id_RESET)) { - aux_cell->connectPort(id_RESET, ci->ports.at(id_RESET).net); - } - if (port_used(ci, id_PCLK)) { - aux_cell->connectPort(id_PCLK, ci->ports.at(id_PCLK).net); - } - ci->movePortTo(id_FCLK, aux_cell.get(), id_FCLK); - ci->movePortTo(id_D12, aux_cell.get(), id_D0); - ci->movePortTo(id_D13, aux_cell.get(), id_D1); - ci->movePortTo(id_D14, aux_cell.get(), id_D2); - ci->movePortTo(id_D15, aux_cell.get(), id_D3); - new_cells.push_back(std::move(aux_cell)); - - // bottom row is special and may need two additional ports - loc.z = BelZ::ioba_z; - if (ctx->getBelByLocation(loc) != BelId()) { - dummy = create_generic_cell(ctx, id_DUMMY_CELL, ci->name.str(ctx) + "_IOLOGIC_IO0"); - dummy->setAttr(id_BEL, ctx->getBelName(ctx->getBelByLocation(loc)).str(ctx)); - new_cells.push_back(std::move(dummy)); - } - - // XXX Prohibit the use of 4th IO and IOLOGIC - loc.z = BelZ::iobb_z; - if (ctx->getBelByLocation(loc) != BelId()) { - dummy = create_generic_cell(ctx, id_DUMMY_CELL, ci->name.str(ctx) + "_IOLOGIC_IO1"); - dummy->setAttr(id_BEL, ctx->getBelName(ctx->getBelByLocation(loc)).str(ctx)); - new_cells.push_back(std::move(dummy)); - } - master_name = ci->name.str(ctx) + "_AUX2"; - loc.z = BelZ::iologic_z + 1; - dummy = create_generic_cell(ctx, id_DUMMY_CELL, master_name); - dummy->setAttr(id_BEL, ctx->getBelName(ctx->getBelByLocation(loc)).str(ctx)); - new_cells.push_back(std::move(dummy)); - } break; - case ID_IDES16: { - CellInfo *d_src = net_driven_by(ctx, ci->getPort(id_D), is_iob, id_O); - NPNR_ASSERT(d_src != nullptr); - - auto iob_bel = d_src->attrs.find(id_BEL); - if (iob_bel == d_src->attrs.end()) { - log_error("No constraints for %s. The pins for IDES/OSER must be specified explicitly.\n", - ctx->nameOf(d_src)); - } - Loc loc = ctx->getBelLocation(ctx->getBelByNameStr(iob_bel->second.as_string())); - if (loc.z != BelZ::ioba_z) { - log_error("IDES16/OSER16 %s must be an A pin.\n", ctx->nameOf(ci)); - } - - loc.z += BelZ::ides16_z; - ci->setAttr(id_BEL, ctx->getBelName(ctx->getBelByLocation(loc)).str(ctx)); - BelId bel = ctx->getBelByLocation(loc); - if (bel == BelId()) { - log_error("No bel for %s at %s. Can't place IDES/OSER here\n", ctx->nameOf(ci), - iob_bel->second.as_string().c_str()); - } - // mark IOB as used by IOLOGIC - d_src->setParam(id_IOLOGIC_IOB, 1); - - bool use_diff_io = false; - if (d_src->attrs.count(id_DIFF_TYPE)) { - ci->setAttr(id_IBUF_TYPE, std::string("DBUF")); // XXX compatibility - ci->setParam(id_IBUF_TYPE, std::string("DBUF")); - use_diff_io = true; - } else { - ci->setAttr(id_IBUF_TYPE, std::string("SBUF")); // XXX compatibility - ci->setParam(id_IBUF_TYPE, std::string("SBUF")); - } - // disconnect D input: it is wired internally - delete_nets.insert(ci->getPort(id_D)->name); - d_src->disconnectPort(id_O); - ci->disconnectPort(id_D); - ci->setAttr(id_IOLOGIC_TYPE, ci->type.str(ctx)); - - // make aux cells - std::unique_ptr dummy = - create_generic_cell(ctx, id_DUMMY_CELL, ci->name.str(ctx) + "_IOLOGIC_IO"); - loc.z = BelZ::iobb_z; - if (!use_diff_io) { - dummy->setAttr(id_BEL, ctx->getBelName(ctx->getBelByLocation(loc)).str(ctx)); - new_cells.push_back(std::move(dummy)); - } - loc.z = BelZ::iologic_z; - - // main iologic cell - std::string master_name = ci->name.str(ctx) + "_MAIN"; - - // aux cells - std::unique_ptr aux_cell = create_generic_cell(ctx, id_IOLOGIC, ci->name.str(ctx) + "_AUX0"); - aux_cell->setAttr(id_IOLOGIC_TYPE, std::string("IDES16")); - aux_cell->setAttr(ctx->id("IOLOGIC_MASTER_CELL"), master_name); - aux_cell->setAttr(id_BEL, ctx->getBelName(ctx->getBelByLocation(loc)).str(ctx)); - aux_cell->setParam(ctx->id("INMODE"), std::string("IDDRX8")); - aux_cell->setParam(ctx->id("UPDATE"), std::string("SAME")); - if (port_used(ci, id_RESET)) { - aux_cell->connectPort(id_RESET, ci->ports.at(id_RESET).net); - } - if (port_used(ci, id_PCLK)) { - aux_cell->connectPort(id_PCLK, ci->ports.at(id_PCLK).net); - } - new_cells.push_back(std::move(aux_cell)); - - // aux iologic cells - loc.z = BelZ::iologic_z + 1; - aux_cell = create_generic_cell(ctx, id_IOLOGIC, ci->name.str(ctx) + "_AUX1"); - aux_cell->setAttr(id_IOLOGIC_TYPE, std::string("DUMMY")); - aux_cell->setAttr(ctx->id("IOLOGIC_MASTER_CELL"), master_name); - aux_cell->setAttr(id_BEL, ctx->getBelName(ctx->getBelByLocation(loc)).str(ctx)); - aux_cell->setParam(ctx->id("INMODE"), std::string("DDRENABLE16")); - aux_cell->setParam(ctx->id("UPDATE"), std::string("SAME")); - if (port_used(ci, id_RESET)) { - aux_cell->connectPort(id_RESET, ci->ports.at(id_RESET).net); - } - if (port_used(ci, id_PCLK)) { - aux_cell->connectPort(id_PCLK, ci->ports.at(id_PCLK).net); - } - new_cells.push_back(std::move(aux_cell)); - - // master - get_next_oser16_loc(ctx->device, loc); - loc.z = BelZ::iologic_z; - aux_cell = create_generic_cell(ctx, id_IOLOGIC, master_name); - aux_cell->setAttr(id_IOLOGIC_TYPE, std::string("DUMMY")); - aux_cell->setAttr(id_BEL, ctx->getBelName(ctx->getBelByLocation(loc)).str(ctx)); - aux_cell->setParam(ctx->id("INMODE"), std::string("DDRENABLE16")); - aux_cell->setParam(ctx->id("UPDATE"), std::string("SAME")); - if (port_used(ci, id_RESET)) { - aux_cell->connectPort(id_RESET, ci->ports.at(id_RESET).net); - } - if (port_used(ci, id_PCLK)) { - aux_cell->connectPort(id_PCLK, ci->ports.at(id_PCLK).net); - } - ci->movePortTo(id_FCLK, aux_cell.get(), id_FCLK); - ci->movePortTo(id_Q0, aux_cell.get(), id_Q6); - ci->movePortTo(id_Q1, aux_cell.get(), id_Q7); - ci->movePortTo(id_Q2, aux_cell.get(), id_Q8); - ci->movePortTo(id_Q3, aux_cell.get(), id_Q9); - new_cells.push_back(std::move(aux_cell)); - - // bottom row is special and may need two additional ports - loc.z = BelZ::ioba_z; - if (ctx->getBelByLocation(loc) != BelId()) { - dummy = create_generic_cell(ctx, id_DUMMY_CELL, ci->name.str(ctx) + "_IOLOGIC_IO0"); - dummy->setAttr(id_BEL, ctx->getBelName(ctx->getBelByLocation(loc)).str(ctx)); - new_cells.push_back(std::move(dummy)); - } - - // XXX Prohibit the use of 4th IO and IOLOGIC - loc.z = BelZ::iobb_z; - if (ctx->getBelByLocation(loc) != BelId()) { - dummy = create_generic_cell(ctx, id_DUMMY_CELL, ci->name.str(ctx) + "_IOLOGIC_IO1"); - dummy->setAttr(id_BEL, ctx->getBelName(ctx->getBelByLocation(loc)).str(ctx)); - new_cells.push_back(std::move(dummy)); - } - master_name = ci->name.str(ctx) + "_AUX2"; - loc.z = BelZ::iologic_z + 1; - dummy = create_generic_cell(ctx, id_DUMMY_CELL, master_name); - dummy->setAttr(id_BEL, ctx->getBelName(ctx->getBelByLocation(loc)).str(ctx)); - new_cells.push_back(std::move(dummy)); - } break; - default: - break; - } - } - } - for (auto pcell : packed_cells) { - ctx->cells.erase(pcell); - } - for (auto dnet : delete_nets) { - ctx->nets.erase(dnet); - } - for (auto &ncell : new_cells) { - ctx->cells[ncell->name] = std::move(ncell); - } -} - -// Pack differential IO buffers -static void pack_diff_io(Context *ctx) -{ - pool packed_cells; - pool delete_nets; - - std::vector> new_cells; - log_info("Packing diff IOs..\n"); - - for (auto &cell : ctx->cells) { - CellInfo *ci = cell.second.get(); - if (ctx->verbose) - log_info("cell '%s' is of type '%s'\n", ctx->nameOf(ci), ci->type.c_str(ctx)); - if (is_gowin_diff_iob(ctx, ci)) { - CellInfo *iob_p = nullptr; - CellInfo *iob_n = nullptr; - switch (ci->type.index) { - case ID_ELVDS_IOBUF: /* fall-through*/ - case ID_ELVDS_IBUF: /* fall-through*/ - case ID_ELVDS_TBUF: /* fall-through*/ - case ID_ELVDS_OBUF: /* fall-through*/ - case ID_TLVDS_IOBUF: /* fall-through*/ - case ID_TLVDS_IBUF: /* fall-through*/ - case ID_TLVDS_TBUF: /* fall-through*/ - case ID_TLVDS_OBUF: { - NPNR_ASSERT(check_availability(ctx, ci->type)); - if (ci->type.in(id_TLVDS_TBUF, id_TLVDS_OBUF, id_TLVDS_IOBUF, id_ELVDS_TBUF, id_ELVDS_OBUF, - id_ELVDS_IOBUF)) { - iob_p = net_only_drives(ctx, ci->ports.at(id_O).net, is_iob, id_I); - iob_n = net_only_drives(ctx, ci->ports.at(id_OB).net, is_iob, id_I); - } else { - iob_p = net_driven_by(ctx, ci->ports.at(id_I).net, is_iob, id_O); - iob_n = net_driven_by(ctx, ci->ports.at(id_IB).net, is_iob, id_O); - } - NPNR_ASSERT(iob_p != nullptr); - NPNR_ASSERT(iob_n != nullptr); - auto iob_p_bel_a = iob_p->attrs.find(id_BEL); - if (iob_p_bel_a == iob_p->attrs.end()) { - log_error("LVDS '%s' must be restricted.\n", ctx->nameOf(ci)); - } - BelId iob_p_bel = ctx->getBelByNameStr(iob_p_bel_a->second.as_string()); - Loc loc_p = ctx->getBelLocation(iob_p_bel); - // restrict the N buffer - ++loc_p.z; - BelId n_bel = ctx->getBelByLocation(loc_p); - if (n_bel == BelId()) { - log_error("Invalid pin for '%s'.\n", ctx->nameOf(ci)); - } - iob_n->attrs[id_BEL] = ctx->getBelName(n_bel).str(ctx); - iob_n->type = iob_p->type; - // mark IOBs as part of DS pair - std::string io_type = ci->type.c_str(ctx); - // XXX compatibility - iob_n->setAttr(id_DIFF, std::string("N")); - iob_n->setAttr(id_DIFF_TYPE, io_type); - iob_p->setAttr(id_DIFF, std::string("P")); - iob_p->setAttr(id_DIFF_TYPE, io_type); - - iob_n->setParam(id_DIFF, std::string("N")); - iob_n->setParam(id_DIFF_TYPE, io_type); - iob_p->setParam(id_DIFF, std::string("P")); - iob_p->setParam(id_DIFF_TYPE, io_type); - - if (ci->type.in(id_TLVDS_TBUF, id_TLVDS_OBUF, id_ELVDS_TBUF, id_ELVDS_OBUF)) { - // disconnect N input: it is wired internally - delete_nets.insert(iob_n->ports.at(id_I).net->name); - iob_n->disconnectPort(id_I); - ci->disconnectPort(id_OB); - // disconnect P output - delete_nets.insert(ci->ports.at(id_O).net->name); - ci->disconnectPort(id_O); - // connect TLVDS input to P input - ci->movePortTo(id_I, iob_p, id_I); - if (ci->type.in(id_TLVDS_TBUF, id_ELVDS_TBUF)) { - if (iob_p->type == id_IOBS) { - iob_p->disconnectPort(id_OEN); - iob_n->disconnectPort(id_OEN); - } - ci->movePortTo(id_OEN, iob_p, id_OEN); - } - } - if (ci->type.in(id_TLVDS_IBUF, id_ELVDS_IBUF)) { - // disconnect N input: it is wired internally - delete_nets.insert(iob_n->ports.at(id_O).net->name); - iob_n->disconnectPort(id_O); - ci->disconnectPort(id_IB); - // disconnect P input - delete_nets.insert(ci->ports.at(id_I).net->name); - ci->disconnectPort(id_I); - // connect TLVDS output to P output - ci->movePortTo(id_O, iob_p, id_O); - } - if (ci->type.in(id_TLVDS_IOBUF, id_ELVDS_IOBUF)) { - // disconnect N io: it is wired internally - // O port is missing after iopadmap so leave it as is - delete_nets.insert(iob_n->getPort(id_I)->name); - iob_n->disconnectPort(id_I); - iob_n->disconnectPort(id_OEN); - ci->disconnectPort(id_IOB); - - // disconnect P io - delete_nets.insert(ci->getPort(id_IO)->name); - iob_p->disconnectPort(id_I); - iob_p->disconnectPort(id_OEN); - ci->disconnectPort(id_IO); - ci->movePortTo(id_I, iob_p, id_I); - ci->movePortTo(id_O, iob_p, id_O); - // OEN - if (iob_p->type == id_IOBS) { - iob_p->disconnectPort(id_OEN); - iob_n->disconnectPort(id_OEN); - } - ci->movePortTo(id_OEN, iob_p, id_OEN); - } - packed_cells.insert(ci->name); - } break; - default: - break; - } - } - } - for (auto pcell : packed_cells) { - ctx->cells.erase(pcell); - } - for (auto dnet : delete_nets) { - ctx->nets.erase(dnet); - } - for (auto &ncell : new_cells) { - ctx->cells[ncell->name] = std::move(ncell); - } -} - -static bool is_pll(const Context *ctx, const CellInfo *cell) -{ - switch (cell->type.hash()) { - case ID_rPLL: - return true; - case ID_PLLVR: - return true; - default: - return false; - } -} - -static void pll_disable_unused_ports(Context *ctx, CellInfo *ci) -{ - // Unused ports will be disabled during image generation. Here we add flags for such ports. - Property pr_enable("ENABLE"), pr_disable("DISABLE"); - IdString ports[][2] = { - {id_CLKOUTP, id_CLKOUTPS}, {id_CLKOUTD, id_CLKOUTDIV}, {id_CLKOUTD3, id_CLKOUTDIV3}, {id_LOCK, id_FLOCK}}; - for (int i = 0; i < 4; ++i) { - ci->setParam(ports[i][1], port_used(ci, ports[i][0]) ? pr_enable : pr_disable); - } - // resets - NetInfo *net = ci->getPort(id_RESET); - ci->setParam(id_RSTEN, pr_enable); - if (!port_used(ci, id_RESET) || net->name == ctx->id("$PACKER_VCC_NET") || - net->name == ctx->id("$PACKER_GND_NET")) { - ci->setParam(id_RSTEN, pr_disable); - } - ci->setParam(id_PWDEN, pr_enable); - net = ci->getPort(id_RESET_P); - if (!port_used(ci, id_RESET_P) || net->name == ctx->id("$PACKER_VCC_NET") || - net->name == ctx->id("$PACKER_GND_NET")) { - ci->setParam(id_PWDEN, pr_disable); - } -} - -// Pack PLLs -static void pack_plls(Context *ctx) -{ - pool packed_cells; - pool delete_nets; - - std::vector> new_cells; - log_info("Packing PLLs..\n"); - - for (auto &cell : ctx->cells) { - CellInfo *ci = cell.second.get(); - if (ctx->verbose) - log_info("cell '%s' is of type '%s'\n", ctx->nameOf(ci), ci->type.c_str(ctx)); - if (is_pll(ctx, ci)) { - std::string parm_device = str_or_default(ci->params, id_DEVICE, ctx->device.c_str()); - if (parm_device != ctx->device) { - log_error("Cell '%s': wrong PLL device:%s instead of %s\n", ctx->nameOf(ci), parm_device.c_str(), - ctx->device.c_str()); - continue; - } - - switch (ci->type.hash()) { - case ID_rPLL: { - if (parm_device == "GW1N-1" || parm_device == "GW1NZ-1" || parm_device == "GW1NR-9C" || - parm_device == "GW1NR-9" || parm_device == "GW1N-4" || parm_device == "GW1NS-2C") { - pll_disable_unused_ports(ctx, ci); - // A cell - std::unique_ptr cell = create_generic_cell(ctx, id_rPLL, ci->name.str(ctx) + "$rpll"); - reconnect_rpll(ctx, ci, cell.get()); - new_cells.push_back(std::move(cell)); - auto pll_cell = new_cells.back().get(); - - // need params for gowin_pack - for (auto &parm : ci->params) { - pll_cell->setParam(parm.first, parm.second); - } - packed_cells.insert(ci->name); - } else { - log_error("rPLL isn't supported for %s\n", ctx->device.c_str()); - } - } break; - case ID_PLLVR: { - if (parm_device == "GW1NSR-4C") { - pll_disable_unused_ports(ctx, ci); - std::unique_ptr cell = create_generic_cell(ctx, id_PLLVR, ci->name.str(ctx) + "$pllvr"); - reconnect_pllvr(ctx, ci, cell.get()); - new_cells.push_back(std::move(cell)); - auto pll_cell = new_cells.back().get(); - - // need params for gowin_pack - for (auto &parm : ci->params) { - pll_cell->setParam(parm.first, parm.second); - } - packed_cells.insert(ci->name); - } else { - log_error("PLLVR isn't supported for %s\n", ctx->device.c_str()); - } - } break; - default: - break; - } - } - } - - for (auto pcell : packed_cells) { - ctx->cells.erase(pcell); - } - for (auto dnet : delete_nets) { - ctx->nets.erase(dnet); - } - for (auto &ncell : new_cells) { - ctx->cells[ncell->name] = std::move(ncell); - } -} - -// Pack IO buffers -static void pack_io(Context *ctx) -{ - pool packed_cells; - pool delete_nets; - - std::vector> new_cells; - log_info("Packing IOs..\n"); - - for (auto &cell : ctx->cells) { - CellInfo *ci = cell.second.get(); - if (ctx->verbose) - log_info("cell '%s' is of type '%s'\n", ctx->nameOf(ci), ci->type.c_str(ctx)); - if (is_gowin_iob(ctx, ci)) { - CellInfo *iob = nullptr; - switch (ci->type.index) { - case ID_IBUF: - iob = net_driven_by(ctx, ci->ports.at(id_I).net, is_nextpnr_iob, id_O); - break; - case ID_OBUF: - iob = net_only_drives(ctx, ci->ports.at(id_O).net, is_nextpnr_iob, id_I); - break; - case ID_IOBUF: - iob = net_driven_by(ctx, ci->ports.at(id_IO).net, is_nextpnr_iob, id_O); - break; - case ID_TBUF: - iob = net_only_drives(ctx, ci->ports.at(id_O).net, is_nextpnr_iob, id_I); - break; - default: - break; - } - if (iob != nullptr) { - // delete the $nexpnr_[io]buf - for (auto &p : iob->ports) { - IdString netname = p.second.net->name; - iob->disconnectPort(p.first); - delete_nets.insert(netname); - } - packed_cells.insert(iob->name); - } - // what type to create - IdString new_cell_type = id_IOB; - std::string constr_bel_name = std::string(""); - bool have_xxx_port = false; - bool have_xxx0_port = false; - // check whether the given IO is limited to simplified IO cells - auto constr_bel = ci->attrs.find(id_BEL); - if (constr_bel != ci->attrs.end()) { - constr_bel_name = constr_bel->second.as_string(); - } - if (iob != nullptr) { - constr_bel = iob->attrs.find(id_BEL); - if (constr_bel != iob->attrs.end()) { - constr_bel_name = constr_bel->second.as_string(); - } - } - if (!constr_bel_name.empty()) { - BelId constr_bel = ctx->getBelByNameStr(constr_bel_name); - if (constr_bel != BelId()) { - new_cell_type = ctx->bels.at(constr_bel).type; - if (ctx->gw1n9_quirk) { - have_xxx_port = ctx->bels.at(constr_bel).pins.count(id_GW9_ALWAYS_LOW0) != 0; - } - have_xxx0_port = ctx->bels.at(constr_bel).pins.count(id_GW9C_ALWAYS_LOW0) != 0; - } - } - - // Create a IOB buffer - std::unique_ptr ice_cell = create_generic_cell(ctx, new_cell_type, ci->name.str(ctx) + "$iob"); - gwio_to_iob(ctx, ci, ice_cell.get(), packed_cells); - new_cells.push_back(std::move(ice_cell)); - auto gwiob = new_cells.back().get(); - // XXX GW1NR-9 quirks - if (have_xxx_port && ci->type != id_IBUF) { - gwiob->addInput(id_GW9_ALWAYS_LOW0); - gwiob->connectPort(id_GW9_ALWAYS_LOW0, ctx->nets[ctx->id("$PACKER_GND_NET")].get()); - gwiob->addInput(id_GW9_ALWAYS_LOW1); - gwiob->connectPort(id_GW9_ALWAYS_LOW1, ctx->nets[ctx->id("$PACKER_GND_NET")].get()); - } - if (have_xxx0_port && ci->type != id_IBUF) { - gwiob->addInput(id_GW9C_ALWAYS_LOW0); - gwiob->connectPort(id_GW9C_ALWAYS_LOW0, ctx->nets[ctx->id("$PACKER_GND_NET")].get()); - gwiob->addInput(id_GW9C_ALWAYS_LOW1); - gwiob->connectPort(id_GW9C_ALWAYS_LOW1, ctx->nets[ctx->id("$PACKER_GND_NET")].get()); - } - - packed_cells.insert(ci->name); - if (iob != nullptr) { - // in Gowin .CST port attributes take precedence over cell attributes. - // first copy cell attrs related to IO - for (auto &attr : ci->attrs) { - if (attr.first == IdString(ID_BEL) || attr.first.str(ctx)[0] == '&') { - gwiob->setAttr(attr.first, attr.second); - } - } - // rewrite attributes from the port - for (auto &attr : iob->attrs) { - gwiob->setAttr(attr.first, attr.second); - } - } - } - } - for (auto pcell : packed_cells) { - ctx->cells.erase(pcell); - } - for (auto dnet : delete_nets) { - ctx->nets.erase(dnet); - } - for (auto &ncell : new_cells) { - ctx->cells[ncell->name] = std::move(ncell); - } -} - -// Main pack function -bool Arch::pack() -{ - Context *ctx = getCtx(); - try { - log_break(); - pre_pack(ctx); - pack_constants(ctx); - pack_sram(ctx); - pack_gsr(ctx); - pack_io(ctx); - pack_diff_io(ctx); - pack_iologic(ctx); - pack_wideluts(ctx); - pack_alus(ctx); - pack_lut_lutffs(ctx); - pack_nonlut_ffs(ctx); - pack_plls(ctx); - post_pack(ctx); - ctx->settings[id_pack] = 1; - ctx->assignArchInfo(); - log_info("Checksum: 0x%08x\n", ctx->checksum()); - return true; - } catch (log_execution_error_exception) { - return false; - } -} - -NEXTPNR_NAMESPACE_END diff --git a/gui/gowin/family.cmake b/gui/gowin/family.cmake deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/gui/gowin/mainwindow.cc b/gui/gowin/mainwindow.cc deleted file mode 100644 index 195a083d5d..0000000000 --- a/gui/gowin/mainwindow.cc +++ /dev/null @@ -1,103 +0,0 @@ -/* - * nextpnr -- Next Generation Place and Route - * - * Copyright (C) 2018 Miodrag Milanovic - * - * 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 "mainwindow.h" - -#include -#include -#include - -#include "cst.h" - -static void initMainResource() { Q_INIT_RESOURCE(nextpnr); } - -NEXTPNR_NAMESPACE_BEGIN - -MainWindow::MainWindow(std::unique_ptr context, CommandHandler *handler, QWidget *parent) - : BaseMainWindow(std::move(context), handler, parent) -{ - initMainResource(); - std::string title = "nextpnr-gowin - [EMPTY]"; - setWindowTitle(title.c_str()); - connect(this, &BaseMainWindow::contextChanged, this, &MainWindow::newContext); - createMenu(); -} - -MainWindow::~MainWindow() {} - -void MainWindow::newContext(Context *ctx) -{ - std::string title = "nextpnr-gowin - " + ctx->getChipName(); - setWindowTitle(title.c_str()); -} - -void MainWindow::load_cst(std::string filename) -{ - disableActions(); - std::ifstream f(filename); - if (read_cst(ctx.get(), f)) { - log("Loading CST successful.\n"); - actionPack->setEnabled(true); - } else { - actionLoadCST->setEnabled(true); - log("Loading CST failed.\n"); - } -} - -void MainWindow::createMenu() -{ - actionLoadCST = new QAction("Open CST", this); - actionLoadCST->setIcon(QIcon(":/icons/resources/open_cst.png")); - actionLoadCST->setStatusTip("Open CST file"); - actionLoadCST->setEnabled(false); - connect(actionLoadCST, &QAction::triggered, this, &MainWindow::open_cst); - - // Add actions in menus - mainActionBar->addSeparator(); - mainActionBar->addAction(actionLoadCST); - - menuDesign->addSeparator(); - menuDesign->addAction(actionLoadCST); -} - -void MainWindow::new_proj() {} - -void MainWindow::open_cst() -{ - QString fileName = QFileDialog::getOpenFileName(this, QString("Open CST"), QString(), QString("*.cst")); - if (!fileName.isEmpty()) { - load_cst(fileName.toStdString()); - } -} - -void MainWindow::onDisableActions() { actionLoadCST->setEnabled(false); } - -void MainWindow::onUpdateActions() -{ - if (ctx->settings.find(ctx->id("synth")) != ctx->settings.end()) { - actionLoadCST->setEnabled(true); - } - if (ctx->settings.find(ctx->id("cst")) != ctx->settings.end()) { - actionLoadCST->setEnabled(false); - } - if (ctx->settings.find(ctx->id("pack")) != ctx->settings.end()) { - actionLoadCST->setEnabled(false); - } -} -NEXTPNR_NAMESPACE_END diff --git a/gui/gowin/mainwindow.h b/gui/gowin/mainwindow.h deleted file mode 100644 index 4ca901a6ab..0000000000 --- a/gui/gowin/mainwindow.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * nextpnr -- Next Generation Place and Route - * - * Copyright (C) 2018 Miodrag Milanovic - * - * 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. - * - */ - -#ifndef MAINWINDOW_H -#define MAINWINDOW_H - -#include "../basewindow.h" - -NEXTPNR_NAMESPACE_BEGIN - -class MainWindow : public BaseMainWindow -{ - Q_OBJECT - - public: - explicit MainWindow(std::unique_ptr context, CommandHandler *handler, QWidget *parent = 0); - virtual ~MainWindow(); - - public: - void createMenu(); - - protected: - void onDisableActions() override; - void onUpdateActions() override; - - void load_cst(std::string filename); - - protected Q_SLOTS: - void new_proj() override; - - void open_cst(); - - void newContext(Context *ctx); - - private: - QAction *actionLoadCST; -}; - -NEXTPNR_NAMESPACE_END - -#endif // MAINWINDOW_H diff --git a/gui/gowin/nextpnr.qrc b/gui/gowin/nextpnr.qrc deleted file mode 100644 index 921cfdd194..0000000000 --- a/gui/gowin/nextpnr.qrc +++ /dev/null @@ -1,5 +0,0 @@ - - - resources/open_cst.png - - diff --git a/gui/gowin/resources/open_cst.png b/gui/gowin/resources/open_cst.png deleted file mode 100644 index 23fe9cf88c..0000000000 Binary files a/gui/gowin/resources/open_cst.png and /dev/null differ