Merge pull request #53 from YosysHQ/archattr

Add Attributes on arch objects and improve iCE40 gfx (IO tiles, BRAM tiles)
This commit is contained in:
Clifford Wolf 2018-08-18 19:22:46 +02:00 committed by GitHub
commit 1e8e873c9f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 644 additions and 26 deletions

View File

@ -46,6 +46,18 @@ void (*log_error_atexit)() = NULL;
// static bool next_print_log = false;
static int log_newline_count = 0;
std::string stringf(const char *fmt, ...)
{
std::string string;
va_list ap;
va_start(ap, fmt);
string = vstringf(fmt, ap);
va_end(ap);
return string;
}
std::string vstringf(const char *fmt, va_list ap)
{
std::string string;

View File

@ -51,6 +51,9 @@ extern bool log_quiet_warnings;
extern std::string log_last_error;
extern void (*log_error_atexit)();
std::string stringf(const char *fmt, ...);
std::string vstringf(const char *fmt, va_list ap);
extern std::ostream clog;
void log(const char *format, ...) NPNR_ATTRIBUTE(format(printf, 1, 2));
void log_always(const char *format, ...) NPNR_ATTRIBUTE(format(printf, 1, 2));

View File

@ -151,6 +151,11 @@ Return a list of all bels on the device.
Return the type of a given bel.
### const\_range\<std\:\:pair\<IdString, std::string\>\> getBelAttrs(BelId bel) const
Return the attributes for that bel. Bel attributes are only informal. They are displayed by the GUI but are otherwise
unused. An implementation may simply return an empty range.
### WireId getBelPinWire(BelId bel, IdString pin) const
Return the wire connected to the given bel pin.
@ -180,6 +185,11 @@ Get the type of a wire. The wire type is purely informal and
isn't used by any of the core algorithms. Implementations may
simply return `IdString()`.
### const\_range\<std\:\:pair\<IdString, std::string\>\> getWireAttrs(WireId wire) const
Return the attributes for that wire. Wire attributes are only informal. They are displayed by the GUI but are otherwise
unused. An implementation may simply return an empty range.
### uint32\_t getWireChecksum(WireId wire) const
Return a (preferably unique) number that represents this wire. This is used in design state checksum calculations.
@ -242,6 +252,11 @@ Get the name for a pip. (Pip names must be unique.)
Get the type of a pip. Pip types are purely informal and
implementations may simply return `IdString()`.
### const\_range\<std\:\:pair\<IdString, std::string\>\> getPipAttrs(PipId pip) const
Return the attributes for that pip. Pip attributes are only informal. They are displayed by the GUI but are otherwise
unused. An implementation may simply return an empty range.
### Loc getPipLocation(PipId pip) const
Get the X/Y/Z location of a given pip. Pip locations do not need to be unique, and in most cases they aren't. So

View File

@ -522,6 +522,12 @@ struct Arch : BaseCtx
return id;
}
std::vector<std::pair<IdString, std::string>> getBelAttrs(BelId) const
{
std::vector<std::pair<IdString, std::string>> ret;
return ret;
}
WireId getBelPinWire(BelId bel, IdString pin) const;
BelPinRange getWireBelPins(WireId wire) const
@ -553,6 +559,12 @@ struct Arch : BaseCtx
IdString getWireType(WireId wire) const { return IdString(); }
std::vector<std::pair<IdString, std::string>> getWireAttrs(WireId) const
{
std::vector<std::pair<IdString, std::string>> ret;
return ret;
}
uint32_t getWireChecksum(WireId wire) const { return wire.index; }
void bindWire(WireId wire, NetInfo *net, PlaceStrength strength)
@ -633,6 +645,12 @@ struct Arch : BaseCtx
IdString getPipType(PipId pip) const { return IdString(); }
std::vector<std::pair<IdString, std::string>> getPipAttrs(PipId) const
{
std::vector<std::pair<IdString, std::string>> ret;
return ret;
}
uint32_t getPipChecksum(PipId pip) const { return pip.index; }
void bindPip(PipId pip, NetInfo *net, PlaceStrength strength)

View File

@ -184,6 +184,21 @@ void Arch::setGroupDecal(GroupId group, DecalXY decalxy)
refreshUiGroup(group);
}
void Arch::setWireAttr(IdString wire, IdString key, const std::string &value)
{
wires.at(wire).attrs[key] = value;
}
void Arch::setPipAttr(IdString pip, IdString key, const std::string &value)
{
pips.at(pip).attrs[key] = value;
}
void Arch::setBelAttr(IdString bel, IdString key, const std::string &value)
{
bels.at(bel).attrs[key] = value;
}
// ---------------------------------------------------------------
Arch::Arch(ArchArgs args) : chipName("generic"), args(args) {}
@ -251,6 +266,8 @@ const std::vector<BelId> &Arch::getBels() const { return bel_ids; }
IdString Arch::getBelType(BelId bel) const { return bels.at(bel).type; }
const std::map<IdString, std::string> &Arch::getBelAttrs(BelId bel) const { return bels.at(bel).attrs; }
WireId Arch::getBelPinWire(BelId bel, IdString pin) const { return bels.at(bel).pins.at(pin).wire; }
PortType Arch::getBelPinType(BelId bel, IdString pin) const { return bels.at(bel).pins.at(pin).type; }
@ -276,6 +293,8 @@ IdString Arch::getWireName(WireId wire) const { return wire; }
IdString Arch::getWireType(WireId wire) const { return wires.at(wire).type; }
const std::map<IdString, std::string> &Arch::getWireAttrs(WireId wire) const { return wires.at(wire).attrs; }
uint32_t Arch::getWireChecksum(WireId wire) const
{
// FIXME
@ -328,6 +347,8 @@ IdString Arch::getPipName(PipId pip) const { return pip; }
IdString Arch::getPipType(PipId pip) const { return pips.at(pip).type; }
const std::map<IdString, std::string> &Arch::getPipAttrs(PipId pip) const { return pips.at(pip).attrs; }
uint32_t Arch::getPipChecksum(PipId wire) const
{
// FIXME

View File

@ -32,6 +32,7 @@ struct WireInfo;
struct PipInfo
{
IdString name, type;
std::map<IdString, std::string> attrs;
NetInfo *bound_net;
WireId srcWire, dstWire;
DelayInfo delay;
@ -42,6 +43,7 @@ struct PipInfo
struct WireInfo
{
IdString name, type;
std::map<IdString, std::string> attrs;
NetInfo *bound_net;
std::vector<PipId> downhill, uphill, aliases;
BelPin uphill_bel_pin;
@ -61,6 +63,7 @@ struct PinInfo
struct BelInfo
{
IdString name, type;
std::map<IdString, std::string> attrs;
CellInfo *bound_cell;
std::unordered_map<IdString, PinInfo> pins;
DecalXY decalxy;
@ -120,6 +123,10 @@ struct Arch : BaseCtx
void setBelDecal(BelId bel, DecalXY decalxy);
void setGroupDecal(GroupId group, DecalXY decalxy);
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);
// ---------------------------------------------------------------
// Common Arch API. Every arch must provide the following methods.
@ -151,6 +158,7 @@ struct Arch : BaseCtx
CellInfo *getConflictingBelCell(BelId bel) const;
const std::vector<BelId> &getBels() const;
IdString getBelType(BelId bel) const;
const std::map<IdString, std::string> &getBelAttrs(BelId bel) const;
WireId getBelPinWire(BelId bel, IdString pin) const;
PortType getBelPinType(BelId bel, IdString pin) const;
std::vector<IdString> getBelPins(BelId bel) const;
@ -158,6 +166,7 @@ struct Arch : BaseCtx
WireId getWireByName(IdString name) const;
IdString getWireName(WireId wire) const;
IdString getWireType(WireId wire) const;
const std::map<IdString, std::string> &getWireAttrs(WireId wire) const;
uint32_t getWireChecksum(WireId wire) const;
void bindWire(WireId wire, NetInfo *net, PlaceStrength strength);
void unbindWire(WireId wire);
@ -171,6 +180,7 @@ struct Arch : BaseCtx
PipId getPipByName(IdString name) const;
IdString getPipName(PipId pip) const;
IdString getPipType(PipId pip) const;
const std::map<IdString, std::string> &getPipAttrs(PipId pip) const;
uint32_t getPipChecksum(PipId pip) const;
void bindPip(PipId pip, NetInfo *net, PlaceStrength strength);
void unbindPip(PipId pip);

View File

@ -411,6 +411,11 @@ void DesignWidget::onSelectionChanged(const QItemSelection &, const QItemSelecti
addProperty(topItem, QVariant::String, "Conflicting Cell", ctx->nameOf(ctx->getConflictingBelCell(bel)),
ElementType::CELL);
QtProperty *attrsItem = addSubGroup(topItem, "Attributes");
for (auto &item : ctx->getBelAttrs(bel)) {
addProperty(attrsItem, QVariant::String, item.first.c_str(ctx), item.second.c_str());
}
QtProperty *belpinsItem = addSubGroup(topItem, "Ports");
for (const auto &item : ctx->getBelPins(bel)) {
QtProperty *portInfoItem = addSubGroup(belpinsItem, item.c_str(ctx));
@ -433,6 +438,11 @@ void DesignWidget::onSelectionChanged(const QItemSelection &, const QItemSelecti
addProperty(topItem, QVariant::String, "Conflicting Net", ctx->nameOf(ctx->getConflictingWireNet(wire)),
ElementType::NET);
QtProperty *attrsItem = addSubGroup(topItem, "Attributes");
for (auto &item : ctx->getWireAttrs(wire)) {
addProperty(attrsItem, QVariant::String, item.first.c_str(ctx), item.second.c_str());
}
DelayInfo delay = ctx->getWireDelay(wire);
QtProperty *delayItem = addSubGroup(topItem, "Delay");
@ -492,6 +502,11 @@ void DesignWidget::onSelectionChanged(const QItemSelection &, const QItemSelecti
addProperty(topItem, QVariant::String, "Dest Wire", ctx->getWireName(ctx->getPipDstWire(pip)).c_str(ctx),
ElementType::WIRE);
QtProperty *attrsItem = addSubGroup(topItem, "Attributes");
for (auto &item : ctx->getPipAttrs(pip)) {
addProperty(attrsItem, QVariant::String, item.first.c_str(ctx), item.second.c_str());
}
DelayInfo delay = ctx->getPipDelay(pip);
QtProperty *delayItem = addSubGroup(topItem, "Delay");

View File

@ -226,6 +226,12 @@ PortType Arch::getBelPinType(BelId bel, IdString pin) const
return PORT_INOUT;
}
std::vector<std::pair<IdString, std::string>> Arch::getBelAttrs(BelId) const
{
std::vector<std::pair<IdString, std::string>> ret;
return ret;
}
WireId Arch::getBelPinWire(BelId bel, IdString pin) const
{
WireId ret;
@ -331,6 +337,28 @@ IdString Arch::getWireType(WireId wire) const
return IdString();
}
std::vector<std::pair<IdString, std::string>> Arch::getWireAttrs(WireId wire) const
{
std::vector<std::pair<IdString, std::string>> ret;
auto &wi = chip_info->wire_data[wire.index];
ret.push_back(std::make_pair(id("INDEX"), stringf("%d", wi.netidx)));
ret.push_back(std::make_pair(id("GRID_X"), stringf("%d", wi.x)));
ret.push_back(std::make_pair(id("GRID_Y"), stringf("%d", wi.y)));
ret.push_back(std::make_pair(id("GRID_Z"), stringf("%d", wi.z)));
#if 0
for (int i = 0; i < wi.num_segments; i++) {
auto &si = wi.segments[i];
ret.push_back(std::make_pair(id(stringf("segment[%d]", i)),
stringf("X%d/Y%d/%s", si.x, si.y, chip_info->tile_wire_names[si.index].get())));
}
#endif
return ret;
}
// -----------------------------------------------------------------------
PipId Arch::getPipByName(IdString name) const
@ -372,6 +400,15 @@ IdString Arch::getPipName(PipId pip) const
#endif
}
IdString Arch::getPipType(PipId pip) const { return IdString(); }
std::vector<std::pair<IdString, std::string>> Arch::getPipAttrs(PipId) const
{
std::vector<std::pair<IdString, std::string>> ret;
return ret;
}
// -----------------------------------------------------------------------
BelId Arch::getPackagePinBel(const std::string &pin) const
@ -727,7 +764,7 @@ std::vector<GraphicElement> Arch::getDecalGraphics(DecalId decal) const
GraphicElement el;
el.type = GraphicElement::TYPE_BOX;
el.style = decal.active ? GraphicElement::STYLE_ACTIVE : GraphicElement::STYLE_INACTIVE;
el.x1 = chip_info->bel_data[bel.index].x + logic_cell_x1;
el.x1 = chip_info->bel_data[bel.index].x + lut_swbox_x1;
el.x2 = chip_info->bel_data[bel.index].x + logic_cell_x2;
el.y1 = chip_info->bel_data[bel.index].y + logic_cell_y1 +
(4 * chip_info->bel_data[bel.index].z) * logic_cell_pitch;
@ -741,7 +778,7 @@ std::vector<GraphicElement> Arch::getDecalGraphics(DecalId decal) const
GraphicElement el;
el.type = GraphicElement::TYPE_BOX;
el.style = decal.active ? GraphicElement::STYLE_ACTIVE : GraphicElement::STYLE_INACTIVE;
el.x1 = chip_info->bel_data[bel.index].x + logic_cell_x1;
el.x1 = chip_info->bel_data[bel.index].x + lut_swbox_x1;
el.x2 = chip_info->bel_data[bel.index].x + logic_cell_x2;
el.y1 = chip_info->bel_data[bel.index].y + logic_cell_y1 + i;
el.y2 = chip_info->bel_data[bel.index].y + logic_cell_y2 + i + 7 * logic_cell_pitch;

View File

@ -108,6 +108,8 @@ NPNR_PACKED_STRUCT(struct WireInfoPOD {
};
RelPtr<char> name;
int32_t netidx;
int32_t num_uphill, num_downhill;
RelPtr<int32_t> pips_uphill, pips_downhill;
@ -225,6 +227,7 @@ NPNR_PACKED_STRUCT(struct ChipInfoPOD {
RelPtr<BelConfigPOD> bel_config;
RelPtr<PackageInfoPOD> packages_data;
RelPtr<CellTimingPOD> cell_timing;
RelPtr<RelPtr<char>> tile_wire_names;
});
#if defined(_MSC_VER)
@ -502,6 +505,8 @@ struct Arch : BaseCtx
return IdString(chip_info->bel_data[bel.index].type);
}
std::vector<std::pair<IdString, std::string>> getBelAttrs(BelId bel) const;
WireId getBelPinWire(BelId bel, IdString pin) const;
PortType getBelPinType(BelId bel, IdString pin) const;
std::vector<IdString> getBelPins(BelId bel) const;
@ -517,6 +522,7 @@ struct Arch : BaseCtx
}
IdString getWireType(WireId wire) const;
std::vector<std::pair<IdString, std::string>> getWireAttrs(WireId wire) const;
uint32_t getWireChecksum(WireId wire) const { return wire.index; }
@ -692,7 +698,8 @@ struct Arch : BaseCtx
IdString getPipName(PipId pip) const;
IdString getPipType(PipId pip) const { return IdString(); }
IdString getPipType(PipId pip) const;
std::vector<std::pair<IdString, std::string>> getPipAttrs(PipId pip) const;
uint32_t getPipChecksum(PipId pip) const { return pip.index; }

View File

@ -50,6 +50,7 @@ tiletypes = dict()
wiretypes = dict()
gfx_wire_ids = dict()
gfx_wire_names = list()
wire_segments = dict()
fast_timings = None
@ -93,6 +94,136 @@ with open(args.gfxh) as f:
idx = len(gfx_wire_ids)
name = line.strip().rstrip(",")
gfx_wire_ids[name] = idx
gfx_wire_names.append(name)
def gfx_wire_alias(old, new):
assert old in gfx_wire_ids
assert new not in gfx_wire_ids
gfx_wire_ids[new] = gfx_wire_ids[old]
# GFX aliases for RAM tiles
gfx_wire_alias("TILE_WIRE_LUTFF_0_IN_0", "TILE_WIRE_RAM_RADDR_0")
gfx_wire_alias("TILE_WIRE_LUTFF_0_IN_1", "TILE_WIRE_RAM_RADDR_1")
gfx_wire_alias("TILE_WIRE_LUTFF_0_IN_2", "TILE_WIRE_RAM_RADDR_2")
gfx_wire_alias("TILE_WIRE_LUTFF_0_IN_3", "TILE_WIRE_RAM_RADDR_3")
gfx_wire_alias("TILE_WIRE_LUTFF_1_IN_0", "TILE_WIRE_RAM_RADDR_4")
gfx_wire_alias("TILE_WIRE_LUTFF_1_IN_1", "TILE_WIRE_RAM_RADDR_5")
gfx_wire_alias("TILE_WIRE_LUTFF_1_IN_2", "TILE_WIRE_RAM_RADDR_6")
gfx_wire_alias("TILE_WIRE_LUTFF_1_IN_3", "TILE_WIRE_RAM_RADDR_7")
gfx_wire_alias("TILE_WIRE_LUTFF_2_IN_0", "TILE_WIRE_RAM_RADDR_8")
gfx_wire_alias("TILE_WIRE_LUTFF_2_IN_1", "TILE_WIRE_RAM_RADDR_9")
gfx_wire_alias("TILE_WIRE_LUTFF_2_IN_2", "TILE_WIRE_RAM_RADDR_10")
gfx_wire_alias("TILE_WIRE_LUTFF_0_IN_0", "TILE_WIRE_RAM_WADDR_0")
gfx_wire_alias("TILE_WIRE_LUTFF_0_IN_1", "TILE_WIRE_RAM_WADDR_1")
gfx_wire_alias("TILE_WIRE_LUTFF_0_IN_2", "TILE_WIRE_RAM_WADDR_2")
gfx_wire_alias("TILE_WIRE_LUTFF_0_IN_3", "TILE_WIRE_RAM_WADDR_3")
gfx_wire_alias("TILE_WIRE_LUTFF_1_IN_0", "TILE_WIRE_RAM_WADDR_4")
gfx_wire_alias("TILE_WIRE_LUTFF_1_IN_1", "TILE_WIRE_RAM_WADDR_5")
gfx_wire_alias("TILE_WIRE_LUTFF_1_IN_2", "TILE_WIRE_RAM_WADDR_6")
gfx_wire_alias("TILE_WIRE_LUTFF_1_IN_3", "TILE_WIRE_RAM_WADDR_7")
gfx_wire_alias("TILE_WIRE_LUTFF_2_IN_0", "TILE_WIRE_RAM_WADDR_8")
gfx_wire_alias("TILE_WIRE_LUTFF_2_IN_1", "TILE_WIRE_RAM_WADDR_9")
gfx_wire_alias("TILE_WIRE_LUTFF_2_IN_2", "TILE_WIRE_RAM_WADDR_10")
gfx_wire_alias("TILE_WIRE_LUTFF_3_IN_0", "TILE_WIRE_RAM_MASK_0")
gfx_wire_alias("TILE_WIRE_LUTFF_3_IN_1", "TILE_WIRE_RAM_MASK_1")
gfx_wire_alias("TILE_WIRE_LUTFF_3_IN_2", "TILE_WIRE_RAM_MASK_2")
gfx_wire_alias("TILE_WIRE_LUTFF_3_IN_3", "TILE_WIRE_RAM_MASK_3")
gfx_wire_alias("TILE_WIRE_LUTFF_4_IN_0", "TILE_WIRE_RAM_MASK_4")
gfx_wire_alias("TILE_WIRE_LUTFF_4_IN_1", "TILE_WIRE_RAM_MASK_5")
gfx_wire_alias("TILE_WIRE_LUTFF_4_IN_2", "TILE_WIRE_RAM_MASK_6")
gfx_wire_alias("TILE_WIRE_LUTFF_4_IN_3", "TILE_WIRE_RAM_MASK_7")
gfx_wire_alias("TILE_WIRE_LUTFF_3_IN_0", "TILE_WIRE_RAM_MASK_8")
gfx_wire_alias("TILE_WIRE_LUTFF_3_IN_1", "TILE_WIRE_RAM_MASK_9")
gfx_wire_alias("TILE_WIRE_LUTFF_3_IN_2", "TILE_WIRE_RAM_MASK_10")
gfx_wire_alias("TILE_WIRE_LUTFF_3_IN_3", "TILE_WIRE_RAM_MASK_11")
gfx_wire_alias("TILE_WIRE_LUTFF_4_IN_0", "TILE_WIRE_RAM_MASK_12")
gfx_wire_alias("TILE_WIRE_LUTFF_4_IN_1", "TILE_WIRE_RAM_MASK_13")
gfx_wire_alias("TILE_WIRE_LUTFF_4_IN_2", "TILE_WIRE_RAM_MASK_14")
gfx_wire_alias("TILE_WIRE_LUTFF_4_IN_3", "TILE_WIRE_RAM_MASK_15")
gfx_wire_alias("TILE_WIRE_LUTFF_5_IN_0", "TILE_WIRE_RAM_WDATA_0")
gfx_wire_alias("TILE_WIRE_LUTFF_5_IN_1", "TILE_WIRE_RAM_WDATA_1")
gfx_wire_alias("TILE_WIRE_LUTFF_5_IN_2", "TILE_WIRE_RAM_WDATA_2")
gfx_wire_alias("TILE_WIRE_LUTFF_5_IN_3", "TILE_WIRE_RAM_WDATA_3")
gfx_wire_alias("TILE_WIRE_LUTFF_6_IN_0", "TILE_WIRE_RAM_WDATA_4")
gfx_wire_alias("TILE_WIRE_LUTFF_6_IN_1", "TILE_WIRE_RAM_WDATA_5")
gfx_wire_alias("TILE_WIRE_LUTFF_6_IN_2", "TILE_WIRE_RAM_WDATA_6")
gfx_wire_alias("TILE_WIRE_LUTFF_6_IN_3", "TILE_WIRE_RAM_WDATA_7")
gfx_wire_alias("TILE_WIRE_LUTFF_5_IN_0", "TILE_WIRE_RAM_WDATA_8")
gfx_wire_alias("TILE_WIRE_LUTFF_5_IN_1", "TILE_WIRE_RAM_WDATA_9")
gfx_wire_alias("TILE_WIRE_LUTFF_5_IN_2", "TILE_WIRE_RAM_WDATA_10")
gfx_wire_alias("TILE_WIRE_LUTFF_5_IN_3", "TILE_WIRE_RAM_WDATA_11")
gfx_wire_alias("TILE_WIRE_LUTFF_6_IN_0", "TILE_WIRE_RAM_WDATA_12")
gfx_wire_alias("TILE_WIRE_LUTFF_6_IN_1", "TILE_WIRE_RAM_WDATA_13")
gfx_wire_alias("TILE_WIRE_LUTFF_6_IN_2", "TILE_WIRE_RAM_WDATA_14")
gfx_wire_alias("TILE_WIRE_LUTFF_6_IN_3", "TILE_WIRE_RAM_WDATA_15")
gfx_wire_alias("TILE_WIRE_LUTFF_0_OUT", "TILE_WIRE_RAM_RDATA_0")
gfx_wire_alias("TILE_WIRE_LUTFF_1_OUT", "TILE_WIRE_RAM_RDATA_1")
gfx_wire_alias("TILE_WIRE_LUTFF_2_OUT", "TILE_WIRE_RAM_RDATA_2")
gfx_wire_alias("TILE_WIRE_LUTFF_3_OUT", "TILE_WIRE_RAM_RDATA_3")
gfx_wire_alias("TILE_WIRE_LUTFF_4_OUT", "TILE_WIRE_RAM_RDATA_4")
gfx_wire_alias("TILE_WIRE_LUTFF_5_OUT", "TILE_WIRE_RAM_RDATA_5")
gfx_wire_alias("TILE_WIRE_LUTFF_6_OUT", "TILE_WIRE_RAM_RDATA_6")
gfx_wire_alias("TILE_WIRE_LUTFF_7_OUT", "TILE_WIRE_RAM_RDATA_7")
gfx_wire_alias("TILE_WIRE_LUTFF_0_OUT", "TILE_WIRE_RAM_RDATA_8")
gfx_wire_alias("TILE_WIRE_LUTFF_1_OUT", "TILE_WIRE_RAM_RDATA_9")
gfx_wire_alias("TILE_WIRE_LUTFF_2_OUT", "TILE_WIRE_RAM_RDATA_10")
gfx_wire_alias("TILE_WIRE_LUTFF_3_OUT", "TILE_WIRE_RAM_RDATA_11")
gfx_wire_alias("TILE_WIRE_LUTFF_4_OUT", "TILE_WIRE_RAM_RDATA_12")
gfx_wire_alias("TILE_WIRE_LUTFF_5_OUT", "TILE_WIRE_RAM_RDATA_13")
gfx_wire_alias("TILE_WIRE_LUTFF_6_OUT", "TILE_WIRE_RAM_RDATA_14")
gfx_wire_alias("TILE_WIRE_LUTFF_7_OUT", "TILE_WIRE_RAM_RDATA_15")
gfx_wire_alias("TILE_WIRE_FUNC_GLOBAL_CEN", "TILE_WIRE_RAM_RCLKE")
gfx_wire_alias("TILE_WIRE_FUNC_GLOBAL_CEN", "TILE_WIRE_RAM_WCLKE")
gfx_wire_alias("TILE_WIRE_FUNC_GLOBAL_CLK", "TILE_WIRE_RAM_RCLK")
gfx_wire_alias("TILE_WIRE_FUNC_GLOBAL_CLK", "TILE_WIRE_RAM_WCLK")
gfx_wire_alias("TILE_WIRE_FUNC_GLOBAL_S_R", "TILE_WIRE_RAM_RE")
gfx_wire_alias("TILE_WIRE_FUNC_GLOBAL_S_R", "TILE_WIRE_RAM_WE")
# GFX aliases for IO tiles
gfx_wire_alias("TILE_WIRE_LUTFF_0_IN_0", "TILE_WIRE_IO_0_D_OUT_0")
gfx_wire_alias("TILE_WIRE_LUTFF_0_IN_1", "TILE_WIRE_IO_0_D_OUT_1")
gfx_wire_alias("TILE_WIRE_LUTFF_0_IN_3", "TILE_WIRE_IO_0_OUT_ENB")
gfx_wire_alias("TILE_WIRE_LUTFF_0_OUT", "TILE_WIRE_IO_0_D_IN_0")
gfx_wire_alias("TILE_WIRE_LUTFF_1_OUT", "TILE_WIRE_IO_0_D_IN_1")
gfx_wire_alias("TILE_WIRE_LUTFF_4_IN_0", "TILE_WIRE_IO_1_D_OUT_0")
gfx_wire_alias("TILE_WIRE_LUTFF_4_IN_1", "TILE_WIRE_IO_1_D_OUT_1")
gfx_wire_alias("TILE_WIRE_LUTFF_4_IN_3", "TILE_WIRE_IO_1_OUT_ENB")
gfx_wire_alias("TILE_WIRE_LUTFF_4_OUT", "TILE_WIRE_IO_1_D_IN_0")
gfx_wire_alias("TILE_WIRE_LUTFF_5_OUT", "TILE_WIRE_IO_1_D_IN_1")
gfx_wire_alias("TILE_WIRE_FUNC_GLOBAL_CEN", "TILE_WIRE_IO_GLOBAL_CEN")
gfx_wire_alias("TILE_WIRE_FUNC_GLOBAL_CLK", "TILE_WIRE_IO_GLOBAL_INCLK")
gfx_wire_alias("TILE_WIRE_FUNC_GLOBAL_S_R", "TILE_WIRE_IO_GLOBAL_OUTCLK")
gfx_wire_alias("TILE_WIRE_FUNC_GLOBAL_G0", "TILE_WIRE_IO_GLOBAL_LATCH")
for neigh in "BNL BNR BOT LFT RGT TNL TNR TOP".split():
for i in range(8):
gfx_wire_alias("TILE_WIRE_NEIGH_OP_%s_%d" % (neigh, i), "TILE_WIRE_LOGIC_OP_%s_%d" % (neigh, i))
# End of GFX aliases
def read_timings(filename):
db = dict()
@ -165,6 +296,18 @@ def maj_wire_name(name):
return name[2] in ("sp12_v_b_0", "sp12_v_b_1")
return False
def norm_wire_xy(x, y, name):
if name.startswith("glb_netwk_"):
return None
if name.startswith("neigh_op_"):
return None
if name.startswith("logic_op_"):
return None
if name.startswith("io_global/latch"):
return None
return None # FIXME
return (x, y)
def cmp_wire_names(newname, oldname):
if maj_wire_name(newname):
return True
@ -508,11 +651,13 @@ with open(args.filename, "r") as f:
wire_names_r[mode[1]] = wname
if mode[1] not in wire_xy:
wire_xy[mode[1]] = list()
wire_xy[mode[1]].append((int(line[0]), int(line[1])))
wire_xy[mode[1]].append(wname)
if mode[1] not in wire_segments:
wire_segments[mode[1]] = dict()
if ("TILE_WIRE_" + wname[2].upper().replace("/", "_")) in gfx_wire_ids:
wire_segments[mode[1]][(wname[0], wname[1])] = wname[2]
if (wname[0], wname[1]) not in wire_segments[mode[1]]:
wire_segments[mode[1]][(wname[0], wname[1])] = list()
wire_segments[mode[1]][(wname[0], wname[1])].append(wname[2])
continue
if mode[0] in ("buffer", "routing"):
@ -561,7 +706,9 @@ def add_wire(x, y, name):
wire_names_r[wire_idx] = wname
wire_segments[wire_idx] = dict()
if ("TILE_WIRE_" + wname[2].upper().replace("/", "_")) in gfx_wire_ids:
wire_segments[wire_idx][(wname[0], wname[1])] = wname[2]
if (wname[0], wname[1]) not in wire_segments[wire_idx]:
wire_segments[wire_idx][(wname[0], wname[1])] = list()
wire_segments[wire_idx][(wname[0], wname[1])].append(wname[2])
return wire_idx
def add_switch(x, y, bel=-1):
@ -932,6 +1079,10 @@ bba.post('NEXTPNR_NAMESPACE_END')
bba.push("chipdb_blob_%s" % dev_name)
bba.r("chip_info_%s" % dev_name, "chip_info")
bba.l("tile_wire_names")
for name in gfx_wire_names:
bba.s(name, name)
for bel in range(len(bel_name)):
bba.l("bel_wires_%d" % bel, "BelWirePOD")
for data in sorted(bel_wires[bel]):
@ -1028,20 +1179,32 @@ for wire in range(num_wires):
info["num_bel_pins"] = num_bel_pins
info["list_bel_pins"] = ("wire%d_bels" % wire) if num_bel_pins > 0 else None
pos_xy = None
first = None
if wire in wire_xy:
avg_x, avg_y = 0, 0
for x, y, n in wire_xy[wire]:
norm_xy = norm_wire_xy(x, y, n)
if norm_xy is None:
continue
if pos_xy is None:
pos_xy = norm_xy
first = (x, y, n)
elif pos_xy != norm_xy:
print("Conflicting positions for wire %s: (%d, %d, %s) -> (%d, %d), (%d, %d, %s) -> (%d, %d)" % \
((info["name"],) + first + pos_xy + (x, y, n) + norm_xy), file=sys.stderr)
assert 0
if (pos_xy is None) and (len(wire_xy[wire]) > 1):
# print("Only 'None' positions for wire %s." % info["name"], file=sys.stderr)
# assert 0
pass
for x, y in wire_xy[wire]:
avg_x += x
avg_y += y
avg_x /= len(wire_xy[wire])
avg_y /= len(wire_xy[wire])
info["x"] = int(round(avg_x))
info["y"] = int(round(avg_y))
else:
if pos_xy is None:
info["x"] = wire_names_r[wire][0]
info["y"] = wire_names_r[wire][1]
else:
info["x"] = pos_xy[0]
info["y"] = pos_xy[1]
wireinfo.append(info)
@ -1102,14 +1265,21 @@ for t in range(num_tile_types):
bba.l("wire_data_%s" % dev_name, "WireInfoPOD")
for wire, info in enumerate(wireinfo):
bba.s(info["name"], "name")
bba.u32(wire, "netidx")
bba.u32(info["num_uphill"], "num_uphill")
bba.u32(info["num_downhill"], "num_downhill")
bba.r(info["list_uphill"], "pips_uphill")
bba.r(info["list_downhill"], "pips_downhill")
bba.u32(info["num_bel_pins"], "num_bel_pins")
bba.r(info["list_bel_pins"], "bel_pins")
bba.u32(len(wire_segments[wire]), "num_segments")
if len(wire_segments[wire]):
num_segments = 0
for segs in wire_segments[wire].values():
num_segments += len(segs)
bba.u32(num_segments, "num_segments")
if num_segments:
bba.r("wire_segments_%d" % wire, "segments")
else:
bba.u32(0, "segments")
@ -1125,24 +1295,25 @@ for wire, info in enumerate(wireinfo):
for wire in range(num_wires):
if len(wire_segments[wire]):
bba.l("wire_segments_%d" % wire, "WireSegmentPOD")
for xy, seg in sorted(wire_segments[wire].items()):
bba.u8(xy[0], "x")
bba.u8(xy[1], "y")
bba.u16(gfx_wire_ids["TILE_WIRE_" + seg.upper().replace("/", "_")], "index")
for xy, segs in sorted(wire_segments[wire].items()):
for seg in segs:
bba.u8(xy[0], "x")
bba.u8(xy[1], "y")
bba.u16(gfx_wire_ids["TILE_WIRE_" + seg.upper().replace("/", "_")], "index")
bba.l("pip_data_%s" % dev_name, "PipInfoPOD")
for info in pipinfo:
src_seg = -1
src_segname = wire_names_r[info["src"]]
if (info["x"], info["y"]) in wire_segments[info["src"]]:
src_segname = wire_segments[info["src"]][(info["x"], info["y"])]
src_segname = wire_segments[info["src"]][(info["x"], info["y"])][0]
src_seg = gfx_wire_ids["TILE_WIRE_" + src_segname.upper().replace("/", "_")]
src_segname = src_segname.replace("/", ".")
dst_seg = -1
dst_segname = wire_names_r[info["dst"]]
if (info["x"], info["y"]) in wire_segments[info["dst"]]:
dst_segname = wire_segments[info["dst"]][(info["x"], info["y"])]
dst_segname = wire_segments[info["dst"]][(info["x"], info["y"])][0]
dst_seg = gfx_wire_ids["TILE_WIRE_" + dst_segname.upper().replace("/", "_")]
dst_segname = dst_segname.replace("/", ".")
@ -1276,5 +1447,6 @@ bba.r("bits_info_%s" % dev_name, "bits_info")
bba.r("bel_config_%s" % dev_name if len(extra_cell_config) > 0 else None, "bel_config")
bba.r("package_info_%s" % dev_name, "packages_data")
bba.r("cell_timings_%s" % dev_name, "cell_timing")
bba.r("tile_wire_names", "tile_wire_names")
bba.pop()

View File

@ -36,7 +36,7 @@ if (MSVC)
set(DEV_GFXH ${CMAKE_CURRENT_SOURCE_DIR}/ice40/gfx.h)
add_custom_command(OUTPUT ${DEV_CC_BBA_DB}
COMMAND ${PYTHON_EXECUTABLE} ${DB_PY} -p ${DEV_CONSTIDS_INC} -g ${DEV_GFXH} ${OPT_FAST} ${OPT_SLOW} ${DEV_TXT_DB} > ${DEV_CC_BBA_DB}
DEPENDS ${DEV_TXT_DB} ${DB_PY}
DEPENDS ${DEV_CONSTIDS_INC} ${DEV_GFXH} ${DEV_TXT_DB} ${DB_PY}
)
add_custom_command(OUTPUT ${DEV_CC_DB}
COMMAND bbasm ${DEV_CC_BBA_DB} ${DEV_CC_DB}
@ -69,7 +69,7 @@ else()
add_custom_command(OUTPUT ${DEV_CC_BBA_DB}
COMMAND ${PYTHON_EXECUTABLE} ${DB_PY} -p ${DEV_CONSTIDS_INC} -g ${DEV_GFXH} ${OPT_FAST} ${OPT_SLOW} ${DEV_TXT_DB} > ${DEV_CC_BBA_DB}.new
COMMAND mv ${DEV_CC_BBA_DB}.new ${DEV_CC_BBA_DB}
DEPENDS ${DEV_TXT_DB} ${DB_PY}
DEPENDS ${DEV_CONSTIDS_INC} ${DEV_GFXH} ${DEV_TXT_DB} ${DB_PY}
)
add_custom_command(OUTPUT ${DEV_CC_DB}
COMMAND bbasm --c ${DEV_CC_BBA_DB} ${DEV_CC_DB}.new

View File

@ -339,6 +339,78 @@ void gfxTileWire(std::vector<GraphicElement> &g, int x, int y, GfxTileWireId id,
g.push_back(el);
}
// IO Span-4 Wires connecting to fabric
if (id >= TILE_WIRE_SPAN4_HORZ_0 && id <= TILE_WIRE_SPAN4_HORZ_47) {
int idx = id - TILE_WIRE_SPAN4_HORZ_0;
float y1 = y + 1.0 - (0.03 + 0.0025 * (48 - (idx ^ 1)));
el.x1 = x;
el.x2 = x + 1.0;
el.y1 = y1;
el.y2 = y1;
g.push_back(el);
el.x1 = x + main_swbox_x1 + 0.0025 * ((idx ^ 1) + 35);
el.x2 = el.x1;
el.y1 = y1;
el.y2 = y + main_swbox_y2;
g.push_back(el);
}
if (id >= TILE_WIRE_SPAN4_VERT_0 && id <= TILE_WIRE_SPAN4_VERT_47) {
int idx = id - TILE_WIRE_SPAN4_VERT_0;
float x1 = x + 0.03 + 0.0025 * (48 - (idx ^ 1));
el.x1 = x1;
el.x2 = x1;
el.y1 = y;
el.y2 = y + 1.0;
g.push_back(el);
el.y1 = y + 1.0 - (0.03 + 0.0025 * (270 - (idx ^ 1)));
el.y2 = el.y1;
el.x1 = x1;
el.x2 = x + main_swbox_x1;
g.push_back(el);
}
// IO Span-12 Wires connecting to fabric
if (id >= TILE_WIRE_SPAN12_HORZ_0 && id <= TILE_WIRE_SPAN12_HORZ_23) {
int idx = id - TILE_WIRE_SPAN12_HORZ_0;
float y1 = y + 1.0 - (0.03 + 0.0025 * (88 - (idx ^ 1)));
el.x1 = x;
el.x2 = x + 1.0;
el.y1 = y1;
el.y2 = y1;
g.push_back(el);
el.x1 = x + main_swbox_x1 + 0.0025 * ((idx ^ 1) + 5);
el.x2 = el.x1;
el.y1 = y1;
el.y2 = y + main_swbox_y2;
g.push_back(el);
}
if (id >= TILE_WIRE_SPAN12_VERT_0 && id <= TILE_WIRE_SPAN12_VERT_23) {
int idx = id - TILE_WIRE_SPAN12_VERT_0;
float x1 = x + 0.03 + 0.0025 * (88 - (idx ^ 1));
el.x1 = x1;
el.x2 = x1;
el.y1 = y;
el.y2 = y + 1.0;
g.push_back(el);
el.y1 = y + 1.0 - (0.03 + 0.0025 * (300 - (idx ^ 1)));
el.y2 = el.y1;
el.x1 = x1;
el.x2 = x + main_swbox_x1;
g.push_back(el);
}
// Global2Local
if (id >= TILE_WIRE_GLB2LOCAL_0 && id <= TILE_WIRE_GLB2LOCAL_3) {
@ -457,6 +529,42 @@ void gfxTileWire(std::vector<GraphicElement> &g, int x, int y, GfxTileWireId id,
}
}
// LC Control for IO and BRAM
if (id >= TILE_WIRE_FUNC_GLOBAL_CEN && id <= TILE_WIRE_FUNC_GLOBAL_S_R) {
int idx = id - TILE_WIRE_FUNC_GLOBAL_CEN;
el.x1 = x + main_swbox_x2 - 0.005 * (idx + 5);
el.x2 = el.x1;
el.y1 = y + main_swbox_y1;
el.y2 = el.y1 - 0.005 * (idx + 2);
g.push_back(el);
el.y1 = el.y2;
el.x2 = x + logic_cell_x2 - 0.005 * (2 - idx + 5);
g.push_back(el);
el.y2 = y + logic_cell_y1;
el.x1 = el.x2;
g.push_back(el);
}
if (id == TILE_WIRE_FABOUT) {
el.y1 = y + main_swbox_y1;
el.y2 = el.y1 - 0.005 * 4;
el.x1 = x + main_swbox_x2 - 0.005 * 9;
el.x2 = el.x1;
g.push_back(el);
}
if (id == TILE_WIRE_FUNC_GLOBAL_G0) {
el.y1 = y + logic_cell_y1;
el.y2 = el.y1 - 0.005 * 4;
el.x1 = x + logic_cell_x2 - 0.005 * 3;
el.x2 = el.x1;
g.push_back(el);
}
// LC Cascade
if (id >= TILE_WIRE_LUTFF_0_LOUT && id <= TILE_WIRE_LUTFF_6_LOUT) {
@ -571,6 +679,38 @@ static bool getWireXY_main(GfxTileWireId id, float &x, float &y)
return true;
}
// IO Span-4 Wires connecting to fabric
if (id >= TILE_WIRE_SPAN4_HORZ_0 && id <= TILE_WIRE_SPAN4_HORZ_47) {
int idx = id - TILE_WIRE_SPAN4_HORZ_0;
x = main_swbox_x1 + 0.0025 * ((idx ^ 1) + 35);
y = main_swbox_y2;
return true;
}
if (id >= TILE_WIRE_SPAN4_VERT_0 && id <= TILE_WIRE_SPAN4_VERT_47) {
int idx = id - TILE_WIRE_SPAN4_VERT_0;
y = 1.0 - (0.03 + 0.0025 * (270 - (idx ^ 1)));
x = main_swbox_x1;
return true;
}
// IO Span-12 Wires connecting to fabric
if (id >= TILE_WIRE_SPAN12_HORZ_0 && id <= TILE_WIRE_SPAN12_HORZ_23) {
int idx = id - TILE_WIRE_SPAN12_HORZ_0;
x = main_swbox_x1 + 0.0025 * ((idx ^ 1) + 5);
y = main_swbox_y2;
return true;
}
if (id >= TILE_WIRE_SPAN12_VERT_0 && id <= TILE_WIRE_SPAN12_VERT_23) {
int idx = id - TILE_WIRE_SPAN12_VERT_0;
y = 1.0 - (0.03 + 0.0025 * (300 - (idx ^ 1)));
x = main_swbox_x1;
return true;
}
// Global2Local
if (id >= TILE_WIRE_GLB2LOCAL_0 && id <= TILE_WIRE_GLB2LOCAL_3) {
@ -626,6 +766,19 @@ static bool getWireXY_main(GfxTileWireId id, float &x, float &y)
return true;
}
if (id >= TILE_WIRE_FUNC_GLOBAL_CEN && id <= TILE_WIRE_FUNC_GLOBAL_S_R) {
int idx = id - TILE_WIRE_FUNC_GLOBAL_CEN;
x = main_swbox_x2 - 0.005 * (idx + 5);
y = main_swbox_y1;
return true;
}
if (id == TILE_WIRE_FABOUT) {
x = main_swbox_x2 - 0.005 * 9;
y = main_swbox_y1;
return true;
}
return false;
}

View File

@ -205,6 +205,13 @@ enum GfxTileWireId
TILE_WIRE_LUTFF_GLOBAL_CLK,
TILE_WIRE_LUTFF_GLOBAL_S_R,
TILE_WIRE_FUNC_GLOBAL_CEN,
TILE_WIRE_FUNC_GLOBAL_CLK,
TILE_WIRE_FUNC_GLOBAL_S_R,
TILE_WIRE_FUNC_GLOBAL_G0,
TILE_WIRE_FABOUT,
TILE_WIRE_CARRY_IN,
TILE_WIRE_CARRY_IN_MUX,
@ -509,6 +516,154 @@ enum GfxTileWireId
TILE_WIRE_SP12_H_L_22,
TILE_WIRE_SP12_H_L_23,
TILE_WIRE_SPAN4_VERT_0,
TILE_WIRE_SPAN4_VERT_1,
TILE_WIRE_SPAN4_VERT_2,
TILE_WIRE_SPAN4_VERT_3,
TILE_WIRE_SPAN4_VERT_4,
TILE_WIRE_SPAN4_VERT_5,
TILE_WIRE_SPAN4_VERT_6,
TILE_WIRE_SPAN4_VERT_7,
TILE_WIRE_SPAN4_VERT_8,
TILE_WIRE_SPAN4_VERT_9,
TILE_WIRE_SPAN4_VERT_10,
TILE_WIRE_SPAN4_VERT_11,
TILE_WIRE_SPAN4_VERT_12,
TILE_WIRE_SPAN4_VERT_13,
TILE_WIRE_SPAN4_VERT_14,
TILE_WIRE_SPAN4_VERT_15,
TILE_WIRE_SPAN4_VERT_16,
TILE_WIRE_SPAN4_VERT_17,
TILE_WIRE_SPAN4_VERT_18,
TILE_WIRE_SPAN4_VERT_19,
TILE_WIRE_SPAN4_VERT_20,
TILE_WIRE_SPAN4_VERT_21,
TILE_WIRE_SPAN4_VERT_22,
TILE_WIRE_SPAN4_VERT_23,
TILE_WIRE_SPAN4_VERT_24,
TILE_WIRE_SPAN4_VERT_25,
TILE_WIRE_SPAN4_VERT_26,
TILE_WIRE_SPAN4_VERT_27,
TILE_WIRE_SPAN4_VERT_28,
TILE_WIRE_SPAN4_VERT_29,
TILE_WIRE_SPAN4_VERT_30,
TILE_WIRE_SPAN4_VERT_31,
TILE_WIRE_SPAN4_VERT_32,
TILE_WIRE_SPAN4_VERT_33,
TILE_WIRE_SPAN4_VERT_34,
TILE_WIRE_SPAN4_VERT_35,
TILE_WIRE_SPAN4_VERT_36,
TILE_WIRE_SPAN4_VERT_37,
TILE_WIRE_SPAN4_VERT_38,
TILE_WIRE_SPAN4_VERT_39,
TILE_WIRE_SPAN4_VERT_40,
TILE_WIRE_SPAN4_VERT_41,
TILE_WIRE_SPAN4_VERT_42,
TILE_WIRE_SPAN4_VERT_43,
TILE_WIRE_SPAN4_VERT_44,
TILE_WIRE_SPAN4_VERT_45,
TILE_WIRE_SPAN4_VERT_46,
TILE_WIRE_SPAN4_VERT_47,
TILE_WIRE_SPAN4_HORZ_0,
TILE_WIRE_SPAN4_HORZ_1,
TILE_WIRE_SPAN4_HORZ_2,
TILE_WIRE_SPAN4_HORZ_3,
TILE_WIRE_SPAN4_HORZ_4,
TILE_WIRE_SPAN4_HORZ_5,
TILE_WIRE_SPAN4_HORZ_6,
TILE_WIRE_SPAN4_HORZ_7,
TILE_WIRE_SPAN4_HORZ_8,
TILE_WIRE_SPAN4_HORZ_9,
TILE_WIRE_SPAN4_HORZ_10,
TILE_WIRE_SPAN4_HORZ_11,
TILE_WIRE_SPAN4_HORZ_12,
TILE_WIRE_SPAN4_HORZ_13,
TILE_WIRE_SPAN4_HORZ_14,
TILE_WIRE_SPAN4_HORZ_15,
TILE_WIRE_SPAN4_HORZ_16,
TILE_WIRE_SPAN4_HORZ_17,
TILE_WIRE_SPAN4_HORZ_18,
TILE_WIRE_SPAN4_HORZ_19,
TILE_WIRE_SPAN4_HORZ_20,
TILE_WIRE_SPAN4_HORZ_21,
TILE_WIRE_SPAN4_HORZ_22,
TILE_WIRE_SPAN4_HORZ_23,
TILE_WIRE_SPAN4_HORZ_24,
TILE_WIRE_SPAN4_HORZ_25,
TILE_WIRE_SPAN4_HORZ_26,
TILE_WIRE_SPAN4_HORZ_27,
TILE_WIRE_SPAN4_HORZ_28,
TILE_WIRE_SPAN4_HORZ_29,
TILE_WIRE_SPAN4_HORZ_30,
TILE_WIRE_SPAN4_HORZ_31,
TILE_WIRE_SPAN4_HORZ_32,
TILE_WIRE_SPAN4_HORZ_33,
TILE_WIRE_SPAN4_HORZ_34,
TILE_WIRE_SPAN4_HORZ_35,
TILE_WIRE_SPAN4_HORZ_36,
TILE_WIRE_SPAN4_HORZ_37,
TILE_WIRE_SPAN4_HORZ_38,
TILE_WIRE_SPAN4_HORZ_39,
TILE_WIRE_SPAN4_HORZ_40,
TILE_WIRE_SPAN4_HORZ_41,
TILE_WIRE_SPAN4_HORZ_42,
TILE_WIRE_SPAN4_HORZ_43,
TILE_WIRE_SPAN4_HORZ_44,
TILE_WIRE_SPAN4_HORZ_45,
TILE_WIRE_SPAN4_HORZ_46,
TILE_WIRE_SPAN4_HORZ_47,
TILE_WIRE_SPAN12_VERT_0,
TILE_WIRE_SPAN12_VERT_1,
TILE_WIRE_SPAN12_VERT_2,
TILE_WIRE_SPAN12_VERT_3,
TILE_WIRE_SPAN12_VERT_4,
TILE_WIRE_SPAN12_VERT_5,
TILE_WIRE_SPAN12_VERT_6,
TILE_WIRE_SPAN12_VERT_7,
TILE_WIRE_SPAN12_VERT_8,
TILE_WIRE_SPAN12_VERT_9,
TILE_WIRE_SPAN12_VERT_10,
TILE_WIRE_SPAN12_VERT_11,
TILE_WIRE_SPAN12_VERT_12,
TILE_WIRE_SPAN12_VERT_13,
TILE_WIRE_SPAN12_VERT_14,
TILE_WIRE_SPAN12_VERT_15,
TILE_WIRE_SPAN12_VERT_16,
TILE_WIRE_SPAN12_VERT_17,
TILE_WIRE_SPAN12_VERT_18,
TILE_WIRE_SPAN12_VERT_19,
TILE_WIRE_SPAN12_VERT_20,
TILE_WIRE_SPAN12_VERT_21,
TILE_WIRE_SPAN12_VERT_22,
TILE_WIRE_SPAN12_VERT_23,
TILE_WIRE_SPAN12_HORZ_0,
TILE_WIRE_SPAN12_HORZ_1,
TILE_WIRE_SPAN12_HORZ_2,
TILE_WIRE_SPAN12_HORZ_3,
TILE_WIRE_SPAN12_HORZ_4,
TILE_WIRE_SPAN12_HORZ_5,
TILE_WIRE_SPAN12_HORZ_6,
TILE_WIRE_SPAN12_HORZ_7,
TILE_WIRE_SPAN12_HORZ_8,
TILE_WIRE_SPAN12_HORZ_9,
TILE_WIRE_SPAN12_HORZ_10,
TILE_WIRE_SPAN12_HORZ_11,
TILE_WIRE_SPAN12_HORZ_12,
TILE_WIRE_SPAN12_HORZ_13,
TILE_WIRE_SPAN12_HORZ_14,
TILE_WIRE_SPAN12_HORZ_15,
TILE_WIRE_SPAN12_HORZ_16,
TILE_WIRE_SPAN12_HORZ_17,
TILE_WIRE_SPAN12_HORZ_18,
TILE_WIRE_SPAN12_HORZ_19,
TILE_WIRE_SPAN12_HORZ_20,
TILE_WIRE_SPAN12_HORZ_21,
TILE_WIRE_SPAN12_HORZ_22,
TILE_WIRE_SPAN12_HORZ_23,
TILE_WIRE_PLLIN,
TILE_WIRE_PLLOUT_A,
TILE_WIRE_PLLOUT_B