aboutsummaryrefslogtreecommitdiffstats
path: root/generic/arch.cc
diff options
context:
space:
mode:
Diffstat (limited to 'generic/arch.cc')
-rw-r--r--generic/arch.cc333
1 files changed, 184 insertions, 149 deletions
diff --git a/generic/arch.cc b/generic/arch.cc
index ebc1ef26..ad054efd 100644
--- a/generic/arch.cc
+++ b/generic/arch.cc
@@ -25,49 +25,31 @@
#include "router1.h"
#include "router2.h"
#include "util.h"
+#include "viaduct_api.h"
NEXTPNR_NAMESPACE_BEGIN
-WireInfo &Arch::wire_info(IdStringList wire)
+WireId Arch::addWire(IdStringList name, IdString type, int x, int y)
{
- auto w = wires.find(wire);
- if (w == wires.end())
- NPNR_ASSERT_FALSE_STR("no wire named " + wire.str(getCtx()));
- return w->second;
-}
-
-PipInfo &Arch::pip_info(IdStringList pip)
-{
- auto p = pips.find(pip);
- if (p == pips.end())
- NPNR_ASSERT_FALSE_STR("no pip named " + pip.str(getCtx()));
- return p->second;
-}
-
-BelInfo &Arch::bel_info(IdStringList bel)
-{
- auto b = bels.find(bel);
- if (b == bels.end())
- NPNR_ASSERT_FALSE_STR("no bel named " + bel.str(getCtx()));
- return b->second;
-}
-
-void Arch::addWire(IdStringList name, IdString type, int x, int y)
-{
- NPNR_ASSERT(wires.count(name) == 0);
- WireInfo &wi = wires[name];
+ NPNR_ASSERT(wire_by_name.count(name) == 0);
+ WireId wire(wires.size());
+ wire_by_name[name] = wire;
+ wires.emplace_back();
+ WireInfo &wi = wires.back();
wi.name = name;
wi.type = type;
wi.x = x;
wi.y = y;
-
- wire_ids.push_back(name);
+ return wire;
}
-void Arch::addPip(IdStringList name, IdString type, IdStringList srcWire, IdStringList dstWire, delay_t delay, Loc loc)
+PipId Arch::addPip(IdStringList name, IdString type, WireId srcWire, WireId dstWire, delay_t delay, Loc loc)
{
- NPNR_ASSERT(pips.count(name) == 0);
- PipInfo &pi = pips[name];
+ NPNR_ASSERT(pip_by_name.count(name) == 0);
+ PipId pip(pips.size());
+ pip_by_name[name] = pip;
+ pips.emplace_back();
+ PipInfo &pi = pips.back();
pi.name = name;
pi.type = type;
pi.srcWire = srcWire;
@@ -75,9 +57,8 @@ void Arch::addPip(IdStringList name, IdString type, IdStringList srcWire, IdStri
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);
+ wire_info(srcWire).downhill.push_back(pip);
+ wire_info(dstWire).uphill.push_back(pip);
if (int(tilePipDimZ.size()) <= loc.x)
tilePipDimZ.resize(loc.x + 1);
@@ -88,13 +69,17 @@ void Arch::addPip(IdStringList name, IdString type, IdStringList srcWire, IdStri
gridDimX = std::max(gridDimX, loc.x + 1);
gridDimY = std::max(gridDimY, loc.x + 1);
tilePipDimZ[loc.x][loc.y] = std::max(tilePipDimZ[loc.x][loc.y], loc.z + 1);
+ return pip;
}
-void Arch::addBel(IdStringList name, IdString type, Loc loc, bool gb, bool hidden)
+BelId Arch::addBel(IdStringList name, IdString type, Loc loc, bool gb, bool hidden)
{
- NPNR_ASSERT(bels.count(name) == 0);
+ NPNR_ASSERT(bel_by_name.count(name) == 0);
NPNR_ASSERT(bel_by_loc.count(loc) == 0);
- BelInfo &bi = bels[name];
+ BelId bel(bels.size());
+ bel_by_name[name] = bel;
+ bels.emplace_back();
+ BelInfo &bi = bels.back();
bi.name = name;
bi.type = type;
bi.x = loc.x;
@@ -103,8 +88,7 @@ void Arch::addBel(IdStringList name, IdString type, Loc loc, bool gb, bool hidde
bi.gb = gb;
bi.hidden = hidden;
- bel_ids.push_back(name);
- bel_by_loc[loc] = name;
+ bel_by_loc[loc] = bel;
if (int(bels_by_tile.size()) <= loc.x)
bels_by_tile.resize(loc.x + 1);
@@ -112,7 +96,7 @@ void Arch::addBel(IdStringList name, IdString type, Loc loc, bool gb, bool hidde
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);
+ bels_by_tile[loc.x][loc.y].push_back(bel);
if (int(tileBelDimZ.size()) <= loc.x)
tileBelDimZ.resize(loc.x + 1);
@@ -123,49 +107,50 @@ void Arch::addBel(IdStringList name, IdString type, Loc loc, bool gb, bool hidde
gridDimX = std::max(gridDimX, loc.x + 1);
gridDimY = std::max(gridDimY, loc.x + 1);
tileBelDimZ[loc.x][loc.y] = std::max(tileBelDimZ[loc.x][loc.y], loc.z + 1);
+ return bel;
}
-void Arch::addBelInput(IdStringList bel, IdString name, IdStringList wire)
+void Arch::addBelInput(BelId bel, IdString name, WireId wire)
{
- NPNR_ASSERT(bel_info(bel).pins.count(name) == 0);
- PinInfo &pi = bel_info(bel).pins[name];
+ auto &bi = bel_info(bel);
+ NPNR_ASSERT(bi.pins.count(name) == 0);
+ PinInfo &pi = bi.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(IdStringList bel, IdString name, IdStringList wire)
+void Arch::addBelOutput(BelId bel, IdString name, WireId wire)
{
- NPNR_ASSERT(bel_info(bel).pins.count(name) == 0);
- PinInfo &pi = bel_info(bel).pins[name];
+ auto &bi = bel_info(bel);
+ NPNR_ASSERT(bi.pins.count(name) == 0);
+ PinInfo &pi = bi.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(IdStringList bel, IdString name, IdStringList wire)
+void Arch::addBelInout(BelId bel, IdString name, WireId wire)
{
- NPNR_ASSERT(bel_info(bel).pins.count(name) == 0);
- PinInfo &pi = bel_info(bel).pins[name];
+ auto &bi = bel_info(bel);
+ NPNR_ASSERT(bi.pins.count(name) == 0);
+ PinInfo &pi = bi.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(IdStringList group, IdStringList bel) { groups[group].bels.push_back(bel); }
+void Arch::addGroupBel(IdStringList group, BelId bel) { groups[group].bels.push_back(bel); }
-void Arch::addGroupWire(IdStringList group, IdStringList wire) { groups[group].wires.push_back(wire); }
+void Arch::addGroupWire(IdStringList group, WireId wire) { groups[group].wires.push_back(wire); }
-void Arch::addGroupPip(IdStringList group, IdStringList pip) { groups[group].pips.push_back(pip); }
+void Arch::addGroupPip(IdStringList group, PipId pip) { groups[group].pips.push_back(pip); }
void Arch::addGroupGroup(IdStringList group, IdStringList grp) { groups[group].groups.push_back(grp); }
@@ -177,19 +162,19 @@ void Arch::addDecalGraphic(DecalId decal, const GraphicElement &graphic)
void Arch::setWireDecal(WireId wire, DecalXY decalxy)
{
- wire_info(wire).decalxy = decalxy;
+ wires.at(wire.index).decalxy = decalxy;
refreshUiWire(wire);
}
void Arch::setPipDecal(PipId pip, DecalXY decalxy)
{
- pip_info(pip).decalxy = decalxy;
+ pips.at(pip.index).decalxy = decalxy;
refreshUiPip(pip);
}
void Arch::setBelDecal(BelId bel, DecalXY decalxy)
{
- bel_info(bel).decalxy = decalxy;
+ bels.at(bel.index).decalxy = decalxy;
refreshUiBel(bel);
}
@@ -199,14 +184,11 @@ void Arch::setGroupDecal(GroupId group, DecalXY decalxy)
refreshUiGroup(group);
}
-void Arch::setWireAttr(IdStringList wire, IdString key, const std::string &value)
-{
- wire_info(wire).attrs[key] = value;
-}
+void Arch::setWireAttr(WireId wire, IdString key, const std::string &value) { wire_info(wire).attrs[key] = value; }
-void Arch::setPipAttr(IdStringList pip, IdString key, const std::string &value) { pip_info(pip).attrs[key] = value; }
+void Arch::setPipAttr(PipId pip, IdString key, const std::string &value) { pip_info(pip).attrs[key] = value; }
-void Arch::setBelAttr(IdStringList bel, IdString key, const std::string &value) { bel_info(bel).attrs[key] = value; }
+void Arch::setBelAttr(BelId bel, IdString key, const std::string &value) { bel_info(bel).attrs[key] = value; }
void Arch::setLutK(int K) { args.K = K; }
@@ -268,16 +250,19 @@ void IdString::initialize_arch(const BaseCtx *ctx) {}
BelId Arch::getBelByName(IdStringList name) const
{
- if (bels.count(name))
- return name;
- return BelId();
+ if (name.size() == 0)
+ return BelId();
+ auto fnd = bel_by_name.find(name);
+ if (fnd == bel_by_name.end())
+ NPNR_ASSERT_FALSE_STR("no bel named " + name.str(getCtx()));
+ return fnd->second;
}
-IdStringList Arch::getBelName(BelId bel) const { return bel; }
+IdStringList Arch::getBelName(BelId bel) const { return bel_info(bel).name; }
Loc Arch::getBelLocation(BelId bel) const
{
- auto &info = bels.at(bel);
+ auto &info = bel_info(bel);
return Loc(info.x, info.y, info.z);
}
@@ -291,7 +276,7 @@ BelId Arch::getBelByLocation(Loc loc) const
const std::vector<BelId> &Arch::getBelsByTile(int x, int y) const { return bels_by_tile.at(x).at(y); }
-bool Arch::getBelGlobalBuf(BelId bel) const { return bels.at(bel).gb; }
+bool Arch::getBelGlobalBuf(BelId bel) const { return bel_info(bel).gb; }
uint32_t Arch::getBelChecksum(BelId bel) const
{
@@ -301,7 +286,9 @@ uint32_t Arch::getBelChecksum(BelId bel) const
void Arch::bindBel(BelId bel, CellInfo *cell, PlaceStrength strength)
{
- bels.at(bel).bound_cell = cell;
+ if (uarch)
+ uarch->notifyBelChange(bel, cell);
+ bel_info(bel).bound_cell = cell;
cell->bel = bel;
cell->belStrength = strength;
refreshUiBel(bel);
@@ -309,40 +296,46 @@ void Arch::bindBel(BelId bel, CellInfo *cell, PlaceStrength strength)
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;
+ if (uarch)
+ uarch->notifyBelChange(bel, nullptr);
+ auto &bi = bel_info(bel);
+ bi.bound_cell->bel = BelId();
+ bi.bound_cell->belStrength = STRENGTH_NONE;
+ bi.bound_cell = nullptr;
refreshUiBel(bel);
}
-bool Arch::checkBelAvail(BelId bel) const { return bels.at(bel).bound_cell == nullptr; }
+bool Arch::checkBelAvail(BelId bel) const
+{
+ return (!uarch || uarch->checkBelAvail(bel)) && (bel_info(bel).bound_cell == nullptr);
+}
-CellInfo *Arch::getBoundBelCell(BelId bel) const { return bels.at(bel).bound_cell; }
+CellInfo *Arch::getBoundBelCell(BelId bel) const { return bel_info(bel).bound_cell; }
-CellInfo *Arch::getConflictingBelCell(BelId bel) const { return bels.at(bel).bound_cell; }
+CellInfo *Arch::getConflictingBelCell(BelId bel) const { return bel_info(bel).bound_cell; }
-const std::vector<BelId> &Arch::getBels() const { return bel_ids; }
+linear_range<BelId> Arch::getBels() const { return linear_range<BelId>(bels.size()); }
-IdString Arch::getBelType(BelId bel) const { return bels.at(bel).type; }
+IdString Arch::getBelType(BelId bel) const { return bel_info(bel).type; }
-bool Arch::getBelHidden(BelId bel) const { return bels.at(bel).hidden; }
+bool Arch::getBelHidden(BelId bel) const { return bel_info(bel).hidden; }
-const std::map<IdString, std::string> &Arch::getBelAttrs(BelId bel) const { return bels.at(bel).attrs; }
+const std::map<IdString, std::string> &Arch::getBelAttrs(BelId bel) const { return bel_info(bel).attrs; }
WireId Arch::getBelPinWire(BelId bel, IdString pin) const
{
- const auto &bdata = bels.at(bel);
+ const auto &bdata = bel_info(bel);
if (!bdata.pins.count(pin))
log_error("bel '%s' has no pin '%s'\n", getCtx()->nameOfBel(bel), 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; }
+PortType Arch::getBelPinType(BelId bel, IdString pin) const { return bel_info(bel).pins.at(pin).type; }
std::vector<IdString> Arch::getBelPins(BelId bel) const
{
std::vector<IdString> ret;
- for (auto &it : bels.at(bel).pins)
+ for (auto &it : bel_info(bel).pins)
ret.push_back(it.first);
return ret;
}
@@ -356,26 +349,27 @@ const std::vector<IdString> &Arch::getBelPinsForCellPin(const CellInfo *cell_inf
WireId Arch::getWireByName(IdStringList name) const
{
- if (wires.count(name))
- return name;
- return WireId();
+ if (name.size() == 0)
+ return WireId();
+ auto fnd = wire_by_name.find(name);
+ if (fnd == wire_by_name.end())
+ NPNR_ASSERT_FALSE_STR("no wire named " + name.str(getCtx()));
+ return fnd->second;
}
-IdStringList Arch::getWireName(WireId wire) const { return wire; }
+IdStringList Arch::getWireName(WireId wire) const { return wire_info(wire).name; }
-IdString Arch::getWireType(WireId wire) const { return wires.at(wire).type; }
+IdString Arch::getWireType(WireId wire) const { return wire_info(wire).type; }
-const std::map<IdString, std::string> &Arch::getWireAttrs(WireId wire) const { return wires.at(wire).attrs; }
+const std::map<IdString, std::string> &Arch::getWireAttrs(WireId wire) const { return wire_info(wire).attrs; }
-uint32_t Arch::getWireChecksum(WireId wire) const
-{
- // FIXME
- return 0;
-}
+uint32_t Arch::getWireChecksum(WireId wire) const { return wire.index; }
void Arch::bindWire(WireId wire, NetInfo *net, PlaceStrength strength)
{
- wires.at(wire).bound_net = net;
+ if (uarch)
+ uarch->notifyWireChange(wire, net);
+ wire_info(wire).bound_net = net;
net->wires[wire].pip = PipId();
net->wires[wire].strength = strength;
refreshUiWire(wire);
@@ -383,55 +377,64 @@ void Arch::bindWire(WireId wire, NetInfo *net, PlaceStrength strength)
void Arch::unbindWire(WireId wire)
{
- auto &net_wires = wires.at(wire).bound_net->wires;
+ auto &net_wires = wire_info(wire).bound_net->wires;
auto pip = net_wires.at(wire).pip;
if (pip != PipId()) {
- pips.at(pip).bound_net = nullptr;
+ if (uarch)
+ uarch->notifyPipChange(pip, nullptr);
+ pip_info(pip).bound_net = nullptr;
refreshUiPip(pip);
}
+ uarch->notifyWireChange(wire, nullptr);
net_wires.erase(wire);
- wires.at(wire).bound_net = nullptr;
+ wire_info(wire).bound_net = nullptr;
refreshUiWire(wire);
}
-bool Arch::checkWireAvail(WireId wire) const { return wires.at(wire).bound_net == nullptr; }
+bool Arch::checkWireAvail(WireId wire) const
+{
+ return (!uarch || uarch->checkWireAvail(wire)) && (wire_info(wire).bound_net == nullptr);
+}
-NetInfo *Arch::getBoundWireNet(WireId wire) const { return wires.at(wire).bound_net; }
+NetInfo *Arch::getBoundWireNet(WireId wire) const { return wire_info(wire).bound_net; }
-NetInfo *Arch::getConflictingWireNet(WireId wire) const { return wires.at(wire).bound_net; }
+NetInfo *Arch::getConflictingWireNet(WireId wire) const { return wire_info(wire).bound_net; }
-const std::vector<BelPin> &Arch::getWireBelPins(WireId wire) const { return wires.at(wire).bel_pins; }
+const std::vector<BelPin> &Arch::getWireBelPins(WireId wire) const { return wire_info(wire).bel_pins; }
-const std::vector<WireId> &Arch::getWires() const { return wire_ids; }
+linear_range<WireId> Arch::getWires() const { return linear_range<WireId>(wires.size()); }
// ---------------------------------------------------------------
PipId Arch::getPipByName(IdStringList name) const
{
- if (pips.count(name))
- return name;
- return PipId();
+ if (name.size() == 0)
+ return PipId();
+ auto fnd = pip_by_name.find(name);
+ if (fnd == pip_by_name.end())
+ NPNR_ASSERT_FALSE_STR("no pip named " + name.str(getCtx()));
+ return fnd->second;
}
-IdStringList Arch::getPipName(PipId pip) const { return pip; }
+IdStringList Arch::getPipName(PipId pip) const { return pip_info(pip).name; }
-IdString Arch::getPipType(PipId pip) const { return pips.at(pip).type; }
+IdString Arch::getPipType(PipId pip) const { return pip_info(pip).type; }
-const std::map<IdString, std::string> &Arch::getPipAttrs(PipId pip) const { return pips.at(pip).attrs; }
+const std::map<IdString, std::string> &Arch::getPipAttrs(PipId pip) const { return pip_info(pip).attrs; }
-uint32_t Arch::getPipChecksum(PipId wire) const
-{
- // FIXME
- return 0;
-}
+uint32_t Arch::getPipChecksum(PipId pip) const { return pip.index; }
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;
+ WireId wire = pip_info(pip).dstWire;
+ if (uarch) {
+ uarch->notifyPipChange(pip, net);
+ uarch->notifyWireChange(wire, net);
+ }
+ pip_info(pip).bound_net = net;
+ wire_info(wire).bound_net = net;
net->wires[wire].pip = pip;
net->wires[wire].strength = strength;
refreshUiPip(pip);
@@ -440,41 +443,53 @@ void Arch::bindPip(PipId pip, NetInfo *net, PlaceStrength strength)
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;
+ WireId wire = pip_info(pip).dstWire;
+ if (uarch) {
+ uarch->notifyPipChange(pip, nullptr);
+ uarch->notifyWireChange(wire, nullptr);
+ }
+ wire_info(wire).bound_net->wires.erase(wire);
+ pip_info(pip).bound_net = nullptr;
+ wire_info(wire).bound_net = nullptr;
refreshUiPip(pip);
refreshUiWire(wire);
}
-bool Arch::checkPipAvail(PipId pip) const { return pips.at(pip).bound_net == nullptr; }
+bool Arch::checkPipAvail(PipId pip) const
+{
+ return (!uarch || uarch->checkPipAvail(pip)) && (pip_info(pip).bound_net == nullptr);
+}
bool Arch::checkPipAvailForNet(PipId pip, NetInfo *net) const
{
- NetInfo *bound_net = pips.at(pip).bound_net;
+ if (uarch && !uarch->checkPipAvailForNet(pip, net))
+ return false;
+ NetInfo *bound_net = pip_info(pip).bound_net;
return bound_net == nullptr || bound_net == net;
}
-NetInfo *Arch::getBoundPipNet(PipId pip) const { return pips.at(pip).bound_net; }
+NetInfo *Arch::getBoundPipNet(PipId pip) const { return pip_info(pip).bound_net; }
-NetInfo *Arch::getConflictingPipNet(PipId pip) const { return pips.at(pip).bound_net; }
+NetInfo *Arch::getConflictingPipNet(PipId pip) const { return pip_info(pip).bound_net; }
-WireId Arch::getConflictingPipWire(PipId pip) const { return pips.at(pip).bound_net ? pips.at(pip).dstWire : WireId(); }
+WireId Arch::getConflictingPipWire(PipId pip) const
+{
+ return pip_info(pip).bound_net ? pip_info(pip).dstWire : WireId();
+}
-const std::vector<PipId> &Arch::getPips() const { return pip_ids; }
+linear_range<PipId> Arch::getPips() const { return linear_range<PipId>(pips.size()); }
-Loc Arch::getPipLocation(PipId pip) const { return pips.at(pip).loc; }
+Loc Arch::getPipLocation(PipId pip) const { return pip_info(pip).loc; }
-WireId Arch::getPipSrcWire(PipId pip) const { return pips.at(pip).srcWire; }
+WireId Arch::getPipSrcWire(PipId pip) const { return pip_info(pip).srcWire; }
-WireId Arch::getPipDstWire(PipId pip) const { return pips.at(pip).dstWire; }
+WireId Arch::getPipDstWire(PipId pip) const { return pip_info(pip).dstWire; }
-DelayQuad Arch::getPipDelay(PipId pip) const { return DelayQuad(pips.at(pip).delay); }
+DelayQuad Arch::getPipDelay(PipId pip) const { return DelayQuad(pip_info(pip).delay); }
-const std::vector<PipId> &Arch::getPipsDownhill(WireId wire) const { return wires.at(wire).downhill; }
+const std::vector<PipId> &Arch::getPipsDownhill(WireId wire) const { return wire_info(wire).downhill; }
-const std::vector<PipId> &Arch::getPipsUphill(WireId wire) const { return wires.at(wire).uphill; }
+const std::vector<PipId> &Arch::getPipsUphill(WireId wire) const { return wire_info(wire).uphill; }
// ---------------------------------------------------------------
@@ -502,18 +517,21 @@ const std::vector<GroupId> &Arch::getGroupGroups(GroupId group) const { return g
delay_t Arch::estimateDelay(WireId src, WireId dst) const
{
- const WireInfo &s = wires.at(src);
- const WireInfo &d = wires.at(dst);
+ if (uarch)
+ return uarch->estimateDelay(src, dst);
+ const WireInfo &s = wire_info(src);
+ const WireInfo &d = wire_info(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(const NetInfo *net_info, const PortRef &sink) const
+delay_t Arch::predictDelay(BelId src_bel, IdString src_pin, BelId dst_bel, IdString dst_pin) const
{
- const auto &driver = net_info->driver;
- auto driver_loc = getBelLocation(driver.cell->bel);
- auto sink_loc = getBelLocation(sink.cell->bel);
+ if (uarch)
+ return uarch->predictDelay(src_bel, src_pin, dst_bel, 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);
@@ -524,12 +542,14 @@ bool Arch::getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay
ArcBounds Arch::getRouteBoundingBox(WireId src, WireId dst) const
{
+ if (uarch)
+ return uarch->getRouteBoundingBox(src, dst);
ArcBounds 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;
+ int src_x = wire_info(src).x;
+ int src_y = wire_info(src).y;
+ int dst_x = wire_info(dst).x;
+ int dst_y = wire_info(dst).y;
bb.x0 = src_x;
bb.y0 = src_y;
@@ -550,6 +570,8 @@ ArcBounds Arch::getRouteBoundingBox(WireId src, WireId dst) const
bool Arch::place()
{
+ if (uarch)
+ uarch->prePlace();
std::string placer = str_or_default(settings, id("placer"), defaultPlacer);
if (placer == "heap") {
bool have_iobuf_or_constr = false;
@@ -561,7 +583,7 @@ bool Arch::place()
}
}
bool retVal;
- if (!have_iobuf_or_constr) {
+ if (!have_iobuf_or_constr && !uarch) {
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()));
@@ -570,11 +592,15 @@ bool Arch::place()
cfg.ioBufTypes.insert(id("GENERIC_IOB"));
retVal = placer_heap(getCtx(), cfg);
}
+ if (uarch)
+ uarch->postPlace();
getCtx()->settings[getCtx()->id("place")] = 1;
archInfoToAttributes();
return retVal;
} else if (placer == "sa") {
bool retVal = placer1(getCtx(), Placer1Cfg(getCtx()));
+ if (uarch)
+ uarch->postPlace();
getCtx()->settings[getCtx()->id("place")] = 1;
archInfoToAttributes();
return retVal;
@@ -585,6 +611,8 @@ bool Arch::place()
bool Arch::route()
{
+ if (uarch)
+ uarch->preRoute();
std::string router = str_or_default(settings, id("router"), defaultRouter);
bool result;
if (router == "router1") {
@@ -595,6 +623,8 @@ bool Arch::route()
} else {
log_error("iCE40 architecture does not support router '%s'\n", router.c_str());
}
+ if (uarch)
+ uarch->postRoute();
getCtx()->settings[getCtx()->id("route")] = 1;
archInfoToAttributes();
return result;
@@ -610,11 +640,11 @@ const std::vector<GraphicElement> &Arch::getDecalGraphics(DecalId decal) const
return decal_graphics.at(decal);
}
-DecalXY Arch::getBelDecal(BelId bel) const { return bels.at(bel).decalxy; }
+DecalXY Arch::getBelDecal(BelId bel) const { return bel_info(bel).decalxy; }
-DecalXY Arch::getWireDecal(WireId wire) const { return wires.at(wire).decalxy; }
+DecalXY Arch::getWireDecal(WireId wire) const { return wire_info(wire).decalxy; }
-DecalXY Arch::getPipDecal(PipId pip) const { return pips.at(pip).decalxy; }
+DecalXY Arch::getPipDecal(PipId pip) const { return pip_info(pip).decalxy; }
DecalXY Arch::getGroupDecal(GroupId group) const { return groups.at(group).decalxy; }
@@ -657,6 +687,8 @@ TimingClockingInfo Arch::getPortClockingInfo(const CellInfo *cell, IdString port
bool Arch::isBelLocationValid(BelId bel) const
{
+ if (uarch)
+ return uarch->isBelLocationValid(bel);
std::vector<const CellInfo *> cells;
Loc loc = getBelLocation(bel);
for (auto tbel : getBelsByTile(loc.x, loc.y)) {
@@ -684,6 +716,7 @@ const std::vector<std::string> Arch::availableRouters = {"router1", "router2"};
void Arch::assignArchInfo()
{
+ int index = 0;
for (auto &cell : getCtx()->cells) {
CellInfo *ci = cell.second.get();
if (ci->type == id("GENERIC_SLICE")) {
@@ -697,6 +730,8 @@ void Arch::assignArchInfo()
for (auto &p : ci->ports)
if (!ci->bel_pins.count(p.first))
ci->bel_pins.emplace(p.first, std::vector<IdString>{p.first});
+ ci->flat_index = index;
+ ++index;
}
}