Finishes placement now

This commit is contained in:
Eddie Hung 2018-08-11 22:24:13 -07:00
parent 32f5346378
commit 57c273898c
7 changed files with 225 additions and 198 deletions

View File

@ -173,6 +173,9 @@ WireId Arch::getBelPinWire(BelId bel, IdString pin) const
{
WireId ret;
const auto& site = ddbSites->getSite(bel.index);
ret.index = site.getPinTilewire(pin.str(this));
// NPNR_ASSERT(bel != BelId());
//
// int num_bel_wires = chip_info->bel_data[bel.index].num_bel_wires;
@ -229,9 +232,9 @@ WireId Arch::getWireByName(IdString name) const
wire_by_name[id(chip_info->wire_data[i].name.get())] = i;
}
auto it = wire_by_name.find(name);
if (it != wire_by_name.end())
ret.index = it->second;
//auto it = wire_by_name.find(name);
//if (it != wire_by_name.end())
// ret.index = it->second;
return ret;
}
@ -239,38 +242,38 @@ WireId Arch::getWireByName(IdString name) const
IdString Arch::getWireType(WireId wire) const
{
NPNR_ASSERT(wire != WireId());
switch (chip_info->wire_data[wire.index].type) {
case WireInfoPOD::WIRE_TYPE_NONE:
return IdString();
case WireInfoPOD::WIRE_TYPE_GLB2LOCAL:
return id("GLB2LOCAL");
case WireInfoPOD::WIRE_TYPE_GLB_NETWK:
return id("GLB_NETWK");
case WireInfoPOD::WIRE_TYPE_LOCAL:
return id("LOCAL");
case WireInfoPOD::WIRE_TYPE_LUTFF_IN:
return id("LUTFF_IN");
case WireInfoPOD::WIRE_TYPE_LUTFF_IN_LUT:
return id("LUTFF_IN_LUT");
case WireInfoPOD::WIRE_TYPE_LUTFF_LOUT:
return id("LUTFF_LOUT");
case WireInfoPOD::WIRE_TYPE_LUTFF_OUT:
return id("LUTFF_OUT");
case WireInfoPOD::WIRE_TYPE_LUTFF_COUT:
return id("LUTFF_COUT");
case WireInfoPOD::WIRE_TYPE_LUTFF_GLOBAL:
return id("LUTFF_GLOBAL");
case WireInfoPOD::WIRE_TYPE_CARRY_IN_MUX:
return id("CARRY_IN_MUX");
case WireInfoPOD::WIRE_TYPE_SP4_V:
return id("SP4_V");
case WireInfoPOD::WIRE_TYPE_SP4_H:
return id("SP4_H");
case WireInfoPOD::WIRE_TYPE_SP12_V:
return id("SP12_V");
case WireInfoPOD::WIRE_TYPE_SP12_H:
return id("SP12_H");
}
// switch (chip_info->wire_data[wire.index].type) {
// case WireInfoPOD::WIRE_TYPE_NONE:
// return IdString();
// case WireInfoPOD::WIRE_TYPE_GLB2LOCAL:
// return id("GLB2LOCAL");
// case WireInfoPOD::WIRE_TYPE_GLB_NETWK:
// return id("GLB_NETWK");
// case WireInfoPOD::WIRE_TYPE_LOCAL:
// return id("LOCAL");
// case WireInfoPOD::WIRE_TYPE_LUTFF_IN:
// return id("LUTFF_IN");
// case WireInfoPOD::WIRE_TYPE_LUTFF_IN_LUT:
// return id("LUTFF_IN_LUT");
// case WireInfoPOD::WIRE_TYPE_LUTFF_LOUT:
// return id("LUTFF_LOUT");
// case WireInfoPOD::WIRE_TYPE_LUTFF_OUT:
// return id("LUTFF_OUT");
// case WireInfoPOD::WIRE_TYPE_LUTFF_COUT:
// return id("LUTFF_COUT");
// case WireInfoPOD::WIRE_TYPE_LUTFF_GLOBAL:
// return id("LUTFF_GLOBAL");
// case WireInfoPOD::WIRE_TYPE_CARRY_IN_MUX:
// return id("CARRY_IN_MUX");
// case WireInfoPOD::WIRE_TYPE_SP4_V:
// return id("SP4_V");
// case WireInfoPOD::WIRE_TYPE_SP4_H:
// return id("SP4_H");
// case WireInfoPOD::WIRE_TYPE_SP12_V:
// return id("SP12_V");
// case WireInfoPOD::WIRE_TYPE_SP12_H:
// return id("SP12_H");
// }
return IdString();
}
@ -507,8 +510,8 @@ DecalXY Arch::getWireDecal(WireId wire) const
{
DecalXY decalxy;
decalxy.decal.type = DecalId::TYPE_WIRE;
decalxy.decal.index = wire.index;
decalxy.decal.active = wire_to_net.at(wire.index) != nullptr;
//decalxy.decal.index = wire.index;
//decalxy.decal.active = wire_to_net.at(wire.index) != nullptr;
return decalxy;
}
@ -671,6 +674,15 @@ std::vector<GraphicElement> Arch::getDecalGraphics(DecalId decal) const
bool Arch::getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort, DelayInfo &delay) const
{
if (cell->type == id_SLICEL)
{
if (fromPort.index >= id_A1.index && fromPort.index <= id_A6.index)
return toPort == id_A || toPort == id_AQ;
}
else if (cell->type == id_BUFGCTRL)
{
return true;
}
return false;
}
@ -682,19 +694,16 @@ TimingPortClass Arch::getPortTimingClass(const CellInfo *cell, IdString port, Id
return TMG_CLOCK_INPUT;
if (port == id_CIN)
return TMG_COMB_INPUT;
if (port == id_COUT || port == id_O)
if (port == id_COUT || port == id_A)
return TMG_COMB_OUTPUT;
if (cell->lcInfo.dffEnable) {
clockPort = id_CLK;
if (port == id_OQ)
if (port == id_AQ)
return TMG_REGISTER_OUTPUT;
else
return TMG_REGISTER_INPUT;
} else {
if (port == id_O)
return TMG_COMB_OUTPUT;
else
return TMG_COMB_INPUT;
return TMG_COMB_INPUT;
}
// TODO
//if (port == id_OMUX)

View File

@ -305,10 +305,11 @@ struct BelPinRange
struct WireIterator
{
int cursor = -1;
Tilewire cursor;
void operator++() { cursor++; }
bool operator!=(const WireIterator &other) const { return cursor != other.cursor; }
// TODO
void operator++() { /*cursor++;*/ }
bool operator!=(const WireIterator &other) const { return !(cursor == other.cursor); }
WireId operator*() const
{
@ -511,18 +512,19 @@ struct Arch : BaseCtx
IdString getWireName(WireId wire) const
{
NPNR_ASSERT(wire != WireId());
return id(chip_info->wire_data[wire.index].name.get());
//return id(chip_info->wire_data[wire.index].name.get());
return IdString();
}
IdString getWireType(WireId wire) const;
uint32_t getWireChecksum(WireId wire) const { return wire.index; }
uint32_t getWireChecksum(WireId wire) const { return hash_value(wire.index); }
void bindWire(WireId wire, NetInfo *net, PlaceStrength strength)
{
NPNR_ASSERT(wire != WireId());
NPNR_ASSERT(wire_to_net[wire.index] == nullptr);
wire_to_net[wire.index] = net;
//NPNR_ASSERT(wire_to_net[wire.index] == nullptr);
//wire_to_net[wire.index] = net;
net->wires[wire].pip = PipId();
net->wires[wire].strength = strength;
refreshUiWire(wire);
@ -531,49 +533,52 @@ struct Arch : BaseCtx
void unbindWire(WireId wire)
{
NPNR_ASSERT(wire != WireId());
NPNR_ASSERT(wire_to_net[wire.index] != nullptr);
//NPNR_ASSERT(wire_to_net[wire.index] != nullptr);
auto &net_wires = wire_to_net[wire.index]->wires;
auto it = net_wires.find(wire);
NPNR_ASSERT(it != net_wires.end());
//auto &net_wires = wire_to_net[wire.index]->wires;
//auto it = net_wires.find(wire);
//NPNR_ASSERT(it != net_wires.end());
auto pip = it->second.pip;
if (pip != PipId()) {
pip_to_net[pip.index] = nullptr;
switches_locked[chip_info->pip_data[pip.index].switch_index] = nullptr;
}
//auto pip = it->second.pip;
//if (pip != PipId()) {
// pip_to_net[pip.index] = nullptr;
// switches_locked[chip_info->pip_data[pip.index].switch_index] = nullptr;
//}
net_wires.erase(it);
wire_to_net[wire.index] = nullptr;
//net_wires.erase(it);
//wire_to_net[wire.index] = nullptr;
refreshUiWire(wire);
}
bool checkWireAvail(WireId wire) const
{
NPNR_ASSERT(wire != WireId());
return wire_to_net[wire.index] == nullptr;
//NPNR_ASSERT(wire != WireId());
//return wire_to_net[wire.index] == nullptr;
return true;
}
NetInfo *getBoundWireNet(WireId wire) const
{
NPNR_ASSERT(wire != WireId());
return wire_to_net[wire.index];
//NPNR_ASSERT(wire != WireId());
//return wire_to_net[wire.index];
return nullptr;
}
NetInfo *getConflictingWireNet(WireId wire) const
{
NPNR_ASSERT(wire != WireId());
return wire_to_net[wire.index];
//NPNR_ASSERT(wire != WireId());
//return wire_to_net[wire.index];
return nullptr;
}
DelayInfo getWireDelay(WireId wire) const
{
DelayInfo delay;
NPNR_ASSERT(wire != WireId());
if (fast_part)
delay.delay = chip_info->wire_data[wire.index].fast_delay;
else
delay.delay = chip_info->wire_data[wire.index].slow_delay;
//NPNR_ASSERT(wire != WireId());
//if (fast_part)
// delay.delay = chip_info->wire_data[wire.index].fast_delay;
//else
// delay.delay = chip_info->wire_data[wire.index].slow_delay;
return delay;
}
@ -589,8 +594,8 @@ struct Arch : BaseCtx
WireRange getWires() const
{
WireRange range;
range.b.cursor = 0;
range.e.cursor = 0; //chip_info->num_wires;
//range.b.cursor = 0;
//range.e.cursor = chip_info->num_wires;
return range;
}
@ -608,11 +613,11 @@ struct Arch : BaseCtx
switches_locked[chip_info->pip_data[pip.index].switch_index] = net;
WireId dst;
dst.index = chip_info->pip_data[pip.index].dst;
NPNR_ASSERT(wire_to_net[dst.index] == nullptr);
wire_to_net[dst.index] = net;
net->wires[dst].pip = pip;
net->wires[dst].strength = strength;
//dst.index = chip_info->pip_data[pip.index].dst;
//NPNR_ASSERT(wire_to_net[dst.index] == nullptr);
//wire_to_net[dst.index] = net;
//net->wires[dst].pip = pip;
//net->wires[dst].strength = strength;
refreshUiPip(pip);
refreshUiWire(dst);
}
@ -624,9 +629,9 @@ struct Arch : BaseCtx
NPNR_ASSERT(switches_locked[chip_info->pip_data[pip.index].switch_index] != nullptr);
WireId dst;
dst.index = chip_info->pip_data[pip.index].dst;
NPNR_ASSERT(wire_to_net[dst.index] != nullptr);
wire_to_net[dst.index] = nullptr;
//dst.index = chip_info->pip_data[pip.index].dst;
//NPNR_ASSERT(wire_to_net[dst.index] != nullptr);
//wire_to_net[dst.index] = nullptr;
pip_to_net[pip.index]->wires.erase(dst);
pip_to_net[pip.index] = nullptr;
@ -698,7 +703,7 @@ struct Arch : BaseCtx
{
WireId wire;
NPNR_ASSERT(pip != PipId());
wire.index = chip_info->pip_data[pip.index].src;
//wire.index = chip_info->pip_data[pip.index].src;
return wire;
}
@ -706,7 +711,7 @@ struct Arch : BaseCtx
{
WireId wire;
NPNR_ASSERT(pip != PipId());
wire.index = chip_info->pip_data[pip.index].dst;
//wire.index = chip_info->pip_data[pip.index].dst;
return wire;
}
@ -725,8 +730,8 @@ struct Arch : BaseCtx
{
PipRange range;
NPNR_ASSERT(wire != WireId());
range.b.cursor = chip_info->wire_data[wire.index].pips_downhill.get();
range.e.cursor = range.b.cursor + chip_info->wire_data[wire.index].num_downhill;
//range.b.cursor = chip_info->wire_data[wire.index].pips_downhill.get();
//range.e.cursor = range.b.cursor + chip_info->wire_data[wire.index].num_downhill;
return range;
}
@ -734,8 +739,8 @@ struct Arch : BaseCtx
{
PipRange range;
NPNR_ASSERT(wire != WireId());
range.b.cursor = chip_info->wire_data[wire.index].pips_uphill.get();
range.e.cursor = range.b.cursor + chip_info->wire_data[wire.index].num_uphill;
//range.b.cursor = chip_info->wire_data[wire.index].pips_uphill.get();
//range.e.cursor = range.b.cursor + chip_info->wire_data[wire.index].num_uphill;
return range;
}

View File

@ -22,6 +22,7 @@
#endif
#include "torc/Architecture.hpp"
using namespace torc::architecture;
using namespace torc::architecture::xilinx;
NEXTPNR_NAMESPACE_BEGIN
@ -73,10 +74,10 @@ struct BelId
struct WireId
{
int32_t index = -1;
Tilewire index;
bool operator==(const WireId &other) const { return index == other.index; }
bool operator!=(const WireId &other) const { return index != other.index; }
bool operator!=(const WireId &other) const { return !(index == other.index); }
};
struct PipId
@ -163,7 +164,7 @@ template <> struct hash<NEXTPNR_NAMESPACE_PREFIX WireId>
{
std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX WireId &wire) const noexcept
{
return hash<int>()(wire.index);
return hash_value(wire.index);
}
};

View File

@ -53,21 +53,21 @@ std::unique_ptr<CellInfo> create_ice_cell(Context *ctx, IdString type, std::stri
new_cell->params[ctx->id("CIN_CONST")] = "0";
new_cell->params[ctx->id("CIN_SET")] = "0";
add_port(ctx, new_cell.get(), "I0", PORT_IN);
add_port(ctx, new_cell.get(), "I1", PORT_IN);
add_port(ctx, new_cell.get(), "I2", PORT_IN);
add_port(ctx, new_cell.get(), "I3", PORT_IN);
add_port(ctx, new_cell.get(), "I4", PORT_IN);
add_port(ctx, new_cell.get(), "I5", PORT_IN);
add_port(ctx, new_cell.get(), "A1", PORT_IN);
add_port(ctx, new_cell.get(), "A2", PORT_IN);
add_port(ctx, new_cell.get(), "A3", PORT_IN);
add_port(ctx, new_cell.get(), "A4", PORT_IN);
add_port(ctx, new_cell.get(), "A5", PORT_IN);
add_port(ctx, new_cell.get(), "A6", PORT_IN);
add_port(ctx, new_cell.get(), "CIN", PORT_IN);
add_port(ctx, new_cell.get(), "CLK", PORT_IN);
add_port(ctx, new_cell.get(), "CE", PORT_IN);
add_port(ctx, new_cell.get(), "SR", PORT_IN);
add_port(ctx, new_cell.get(), "O", PORT_OUT);
add_port(ctx, new_cell.get(), "OMUX", PORT_OUT);
add_port(ctx, new_cell.get(), "OQ", PORT_OUT);
add_port(ctx, new_cell.get(), "A", PORT_OUT);
add_port(ctx, new_cell.get(), "AQ", PORT_OUT);
add_port(ctx, new_cell.get(), "AMUX", PORT_OUT);
add_port(ctx, new_cell.get(), "COUT", PORT_OUT);
} else if (type == ctx->id("IOBUF")) {
new_cell->type = id_IOB33S;
@ -259,19 +259,19 @@ std::unique_ptr<CellInfo> create_ice_cell(Context *ctx, IdString type, std::stri
void lut_to_lc(const Context *ctx, CellInfo *lut, CellInfo *lc, bool no_dff)
{
lc->params[ctx->id("LUT_INIT")] = lut->params[ctx->id("LUT_INIT")];
replace_port(lut, ctx->id("I0"), lc, ctx->id("I0"));
replace_port(lut, ctx->id("I0"), lc, ctx->id("A1"));
if (get_net_or_empty(lut, ctx->id("I1")))
replace_port(lut, ctx->id("I1"), lc, ctx->id("I1"));
replace_port(lut, ctx->id("I1"), lc, ctx->id("A2"));
if (get_net_or_empty(lut, ctx->id("I2")))
replace_port(lut, ctx->id("I2"), lc, ctx->id("I2"));
replace_port(lut, ctx->id("I2"), lc, ctx->id("A3"));
if (get_net_or_empty(lut, ctx->id("I3")))
replace_port(lut, ctx->id("I3"), lc, ctx->id("I3"));
replace_port(lut, ctx->id("I3"), lc, ctx->id("A4"));
if (get_net_or_empty(lut, ctx->id("I4")))
replace_port(lut, ctx->id("I4"), lc, ctx->id("I3"));
replace_port(lut, ctx->id("I4"), lc, ctx->id("A5"));
if (get_net_or_empty(lut, ctx->id("I5")))
replace_port(lut, ctx->id("I5"), lc, ctx->id("I3"));
replace_port(lut, ctx->id("I5"), lc, ctx->id("A6"));
if (no_dff) {
replace_port(lut, ctx->id("O"), lc, ctx->id("O"));
replace_port(lut, ctx->id("O"), lc, ctx->id("A"));
lc->params[ctx->id("DFF_ENABLE")] = "0";
}
}
@ -318,10 +318,10 @@ void dff_to_lc(const Context *ctx, CellInfo *dff, CellInfo *lc, bool pass_thru_l
if (pass_thru_lut) {
lc->params[ctx->id("LUT_INIT")] = "2";
replace_port(dff, ctx->id("D"), lc, ctx->id("I0"));
replace_port(dff, ctx->id("D"), lc, ctx->id("A1"));
}
replace_port(dff, ctx->id("Q"), lc, ctx->id("OQ"));
replace_port(dff, ctx->id("Q"), lc, ctx->id("AQ"));
}
void nxio_to_sb(Context *ctx, CellInfo *nxio, CellInfo *sbio)

View File

@ -441,6 +441,16 @@ X(NEG_CLK)
X(I)
X(A1)
X(A2)
X(A3)
X(A4)
X(A5)
X(A6)
X(A)
X(AQ)
X(AMUX)
X(LUT1)
X(LUT2)
X(LUT3)

View File

@ -27,75 +27,75 @@ NEXTPNR_NAMESPACE_BEGIN
void ice40DelayFuzzerMain(Context *ctx)
{
std::vector<WireId> srcWires, dstWires;
for (int i = 0; i < ctx->chip_info->num_wires; i++) {
WireId wire;
wire.index = i;
switch (ctx->chip_info->wire_data[i].type) {
case WireInfoPOD::WIRE_TYPE_LUTFF_OUT:
srcWires.push_back(wire);
break;
case WireInfoPOD::WIRE_TYPE_LUTFF_IN_LUT:
dstWires.push_back(wire);
break;
default:
break;
}
}
ctx->shuffle(srcWires);
ctx->shuffle(dstWires);
int index = 0;
int cnt = 0;
while (cnt < NUM_FUZZ_ROUTES) {
if (index >= int(srcWires.size()) || index >= int(dstWires.size())) {
index = 0;
ctx->shuffle(srcWires);
ctx->shuffle(dstWires);
}
WireId src = srcWires[index];
WireId dst = dstWires[index++];
std::unordered_map<WireId, PipId> route;
#if NUM_FUZZ_ROUTES <= 1000
if (!ctx->getActualRouteDelay(src, dst, nullptr, &route, false))
continue;
#else
if (!ctx->getActualRouteDelay(src, dst, nullptr, &route, true))
continue;
#endif
WireId cursor = dst;
delay_t delay = 0;
while (1) {
delay += ctx->getWireDelay(cursor).maxDelay();
printf("%s %d %d %s %s %d %d\n", cursor == dst ? "dst" : "src",
int(ctx->chip_info->wire_data[cursor.index].x), int(ctx->chip_info->wire_data[cursor.index].y),
ctx->getWireType(cursor).c_str(ctx), ctx->getWireName(cursor).c_str(ctx), int(delay),
int(ctx->estimateDelay(cursor, dst)));
if (cursor == src)
break;
PipId pip = route.at(cursor);
delay += ctx->getPipDelay(pip).maxDelay();
cursor = ctx->getPipSrcWire(pip);
}
cnt++;
if (cnt % 100 == 0)
fprintf(stderr, "Fuzzed %d arcs.\n", cnt);
}
// std::vector<WireId> srcWires, dstWires;
//
// for (int i = 0; i < ctx->chip_info->num_wires; i++) {
// WireId wire;
// wire.index = i;
//
// switch (ctx->chip_info->wire_data[i].type) {
// case WireInfoPOD::WIRE_TYPE_LUTFF_OUT:
// srcWires.push_back(wire);
// break;
//
// case WireInfoPOD::WIRE_TYPE_LUTFF_IN_LUT:
// dstWires.push_back(wire);
// break;
//
// default:
// break;
// }
// }
//
// ctx->shuffle(srcWires);
// ctx->shuffle(dstWires);
//
// int index = 0;
// int cnt = 0;
//
// while (cnt < NUM_FUZZ_ROUTES) {
// if (index >= int(srcWires.size()) || index >= int(dstWires.size())) {
// index = 0;
// ctx->shuffle(srcWires);
// ctx->shuffle(dstWires);
// }
//
// WireId src = srcWires[index];
// WireId dst = dstWires[index++];
// std::unordered_map<WireId, PipId> route;
//
//#if NUM_FUZZ_ROUTES <= 1000
// if (!ctx->getActualRouteDelay(src, dst, nullptr, &route, false))
// continue;
//#else
// if (!ctx->getActualRouteDelay(src, dst, nullptr, &route, true))
// continue;
//#endif
//
// WireId cursor = dst;
// delay_t delay = 0;
//
// while (1) {
// delay += ctx->getWireDelay(cursor).maxDelay();
//
// printf("%s %d %d %s %s %d %d\n", cursor == dst ? "dst" : "src",
// int(ctx->chip_info->wire_data[cursor.index].x), int(ctx->chip_info->wire_data[cursor.index].y),
// ctx->getWireType(cursor).c_str(ctx), ctx->getWireName(cursor).c_str(ctx), int(delay),
// int(ctx->estimateDelay(cursor, dst)));
//
// if (cursor == src)
// break;
//
// PipId pip = route.at(cursor);
// delay += ctx->getPipDelay(pip).maxDelay();
// cursor = ctx->getPipSrcWire(pip);
// }
//
// cnt++;
//
// if (cnt % 100 == 0)
// fprintf(stderr, "Fuzzed %d arcs.\n", cnt);
// }
}
delay_t Arch::estimateDelay(WireId src, WireId dst) const

View File

@ -336,16 +336,16 @@ static void pack_constants(Context *ctx)
std::unique_ptr<NetInfo> gnd_net = std::unique_ptr<NetInfo>(new NetInfo);
gnd_net->name = ctx->id("$PACKER_GND_NET");
gnd_net->driver.cell = gnd_cell.get();
gnd_net->driver.port = ctx->id("O");
gnd_cell->ports.at(ctx->id("O")).net = gnd_net.get();
gnd_net->driver.port = ctx->id("A");
gnd_cell->ports.at(ctx->id("A")).net = gnd_net.get();
std::unique_ptr<CellInfo> vcc_cell = create_ice_cell(ctx, ctx->id("XC7_LC"), "$PACKER_VCC");
vcc_cell->params[ctx->id("LUT_INIT")] = "1";
std::unique_ptr<NetInfo> vcc_net = std::unique_ptr<NetInfo>(new NetInfo);
vcc_net->name = ctx->id("$PACKER_VCC_NET");
vcc_net->driver.cell = vcc_cell.get();
vcc_net->driver.port = ctx->id("O");
vcc_cell->ports.at(ctx->id("O")).net = vcc_net.get();
vcc_net->driver.port = ctx->id("A");
vcc_cell->ports.at(ctx->id("A")).net = vcc_net.get();
std::vector<IdString> dead_nets;
@ -451,6 +451,7 @@ static bool is_logic_port(BaseCtx *ctx, const PortRef &port)
static void insert_global(Context *ctx, NetInfo *net, bool is_reset, bool is_cen, bool is_logic)
{
asm("int3");
std::string glb_name = net->name.str(ctx) + std::string("_$glb_") + (is_reset ? "sr" : (is_cen ? "ce" : "clk"));
std::unique_ptr<CellInfo> gb = create_ice_cell(ctx, id_BUFGCTRL, "$bufg_" + glb_name);
gb->ports[ctx->id("I0")].net = net;
@ -847,25 +848,25 @@ static void pack_special(Context *ctx)
// Find wire that will be driven by this port.
const auto pll_out_wire = ctx->getBelPinWire(pll_bel, port.name);
NPNR_ASSERT(pll_out_wire.index != -1);
NPNR_ASSERT(pll_out_wire != WireId());
// Now, constrain all LUTs on the output of the signal to be at
// the correct Bel relative to the PLL Bel.
int x = ctx->chip_info->wire_data[pll_out_wire.index].x;
int y = ctx->chip_info->wire_data[pll_out_wire.index].y;
int z = 0;
for (const auto &user : port.net->users) {
NPNR_ASSERT(user.cell != nullptr);
NPNR_ASSERT(user.cell->type == ctx->id("XC7_LC"));
//int x = ctx->chip_info->wire_data[pll_out_wire.index].x;
//int y = ctx->chip_info->wire_data[pll_out_wire.index].y;
//int z = 0;
//for (const auto &user : port.net->users) {
// NPNR_ASSERT(user.cell != nullptr);
// NPNR_ASSERT(user.cell->type == ctx->id("XC7_LC"));
// TODO(q3k): handle when the Bel might be already the
// target of another constraint.
NPNR_ASSERT(z < 8);
auto target_bel = ctx->getBelByLocation(Loc(x, y, z++));
auto target_bel_name = ctx->getBelName(target_bel).str(ctx);
user.cell->attrs[ctx->id("BEL")] = target_bel_name;
log_info(" constrained '%s' to %s\n", user.cell->name.c_str(ctx), target_bel_name.c_str());
}
// // TODO(q3k): handle when the Bel might be already the
// // target of another constraint.
// NPNR_ASSERT(z < 8);
// auto target_bel = ctx->getBelByLocation(Loc(x, y, z++));
// auto target_bel_name = ctx->getBelName(target_bel).str(ctx);
// user.cell->attrs[ctx->id("BEL")] = target_bel_name;
// log_info(" constrained '%s' to %s\n", user.cell->name.c_str(ctx), target_bel_name.c_str());
//}
}
new_cells.push_back(std::move(packed));
@ -887,7 +888,8 @@ bool Arch::pack()
try {
log_break();
pack_constants(ctx);
promote_globals(ctx);
// TODO
//promote_globals(ctx);
pack_io(ctx);
pack_lut_lutffs(ctx);
pack_nonlut_ffs(ctx);