Refactoring bind/unbind API
Signed-off-by: Clifford Wolf <clifford@clifford.at>
This commit is contained in:
parent
d72fe0c230
commit
746d63f9fa
@ -97,20 +97,12 @@ uint32_t Context::checksum() const
|
|||||||
for (auto &w : ni.wires) {
|
for (auto &w : ni.wires) {
|
||||||
uint32_t wire_x = 123456789;
|
uint32_t wire_x = 123456789;
|
||||||
wire_x = xorshift32(wire_x + xorshift32(getWireChecksum(w.first)));
|
wire_x = xorshift32(wire_x + xorshift32(getWireChecksum(w.first)));
|
||||||
wire_x = xorshift32(wire_x + xorshift32(getPipChecksum(w.second)));
|
wire_x = xorshift32(wire_x + xorshift32(getPipChecksum(w.second.pip)));
|
||||||
|
wire_x = xorshift32(wire_x + xorshift32(int(w.second.strength)));
|
||||||
wire_x_sum += wire_x;
|
wire_x_sum += wire_x;
|
||||||
}
|
}
|
||||||
x = xorshift32(x + xorshift32(wire_x_sum));
|
x = xorshift32(x + xorshift32(wire_x_sum));
|
||||||
|
|
||||||
uint32_t pip_x_sum = 0;
|
|
||||||
for (auto &p : ni.pips) {
|
|
||||||
uint32_t pip_x = 123456789;
|
|
||||||
pip_x = xorshift32(pip_x + xorshift32(getPipChecksum(p.first)));
|
|
||||||
pip_x = xorshift32(pip_x + xorshift32(p.second));
|
|
||||||
pip_x_sum += pip_x;
|
|
||||||
}
|
|
||||||
x = xorshift32(x + xorshift32(pip_x_sum));
|
|
||||||
|
|
||||||
cksum_nets_sum += x;
|
cksum_nets_sum += x;
|
||||||
}
|
}
|
||||||
cksum = xorshift32(cksum + xorshift32(cksum_nets_sum));
|
cksum = xorshift32(cksum + xorshift32(cksum_nets_sum));
|
||||||
@ -175,4 +167,32 @@ uint32_t Context::checksum() const
|
|||||||
return cksum;
|
return cksum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Context::check() const
|
||||||
|
{
|
||||||
|
for (auto &n : nets) {
|
||||||
|
auto ni = n.second;
|
||||||
|
assert(n.first == ni->name);
|
||||||
|
for (auto &w : ni->wires) {
|
||||||
|
assert(n.first == getBoundWireNet(w.first));
|
||||||
|
if (w.second.pip != PipId()) {
|
||||||
|
assert(w.first == getPipDstWire(w.second.pip));
|
||||||
|
assert(n.first == getBoundPipNet(w.second.pip));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto w : getWires()) {
|
||||||
|
IdString net = getBoundWireNet(w);
|
||||||
|
if (net != IdString()) {
|
||||||
|
assert(nets.at(net)->wires.count(w));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto &c : cells) {
|
||||||
|
assert(c.first == c.second->name);
|
||||||
|
if (c.second->bel != BelId())
|
||||||
|
assert(getBoundBelCell(c.second->bel) == c.first);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
NEXTPNR_NAMESPACE_END
|
NEXTPNR_NAMESPACE_END
|
||||||
|
@ -211,6 +211,12 @@ struct PortRef
|
|||||||
delay_t budget = 0;
|
delay_t budget = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct PipMap
|
||||||
|
{
|
||||||
|
PipId pip = PipId();
|
||||||
|
PlaceStrength strength = STRENGTH_NONE;
|
||||||
|
};
|
||||||
|
|
||||||
struct NetInfo
|
struct NetInfo
|
||||||
{
|
{
|
||||||
IdString name;
|
IdString name;
|
||||||
@ -219,9 +225,7 @@ struct NetInfo
|
|||||||
std::unordered_map<IdString, std::string> attrs;
|
std::unordered_map<IdString, std::string> attrs;
|
||||||
|
|
||||||
// wire -> uphill_pip
|
// wire -> uphill_pip
|
||||||
std::unordered_map<WireId, PipId> wires;
|
std::unordered_map<WireId, PipMap> wires;
|
||||||
|
|
||||||
std::unordered_map<PipId, PlaceStrength> pips;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum PortType
|
enum PortType
|
||||||
@ -357,6 +361,7 @@ struct Context : Arch
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint32_t checksum() const;
|
uint32_t checksum() const;
|
||||||
|
void check() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
NEXTPNR_NAMESPACE_END
|
NEXTPNR_NAMESPACE_END
|
||||||
|
@ -103,9 +103,7 @@ class SAPlacer
|
|||||||
cell->name.c_str(ctx), cell->type.c_str(ctx));
|
cell->name.c_str(ctx), cell->type.c_str(ctx));
|
||||||
}
|
}
|
||||||
|
|
||||||
cell->bel = bel;
|
ctx->bindBel(bel, cell->name, STRENGTH_USER);
|
||||||
cell->belStrength = STRENGTH_USER;
|
|
||||||
ctx->bindBel(bel, cell->name);
|
|
||||||
locked_bels.insert(bel);
|
locked_bels.insert(bel);
|
||||||
placed_cells++;
|
placed_cells++;
|
||||||
}
|
}
|
||||||
@ -231,7 +229,7 @@ class SAPlacer
|
|||||||
}
|
}
|
||||||
// Final post-pacement validitiy check
|
// Final post-pacement validitiy check
|
||||||
for (auto bel : ctx->getBels()) {
|
for (auto bel : ctx->getBels()) {
|
||||||
IdString cell = ctx->getBelCell(bel, false);
|
IdString cell = ctx->getBoundBelCell(bel);
|
||||||
if (!checker->isBelLocationValid(bel)) {
|
if (!checker->isBelLocationValid(bel)) {
|
||||||
std::string cell_text = "no cell";
|
std::string cell_text = "no cell";
|
||||||
if (cell != IdString())
|
if (cell != IdString())
|
||||||
@ -266,7 +264,6 @@ class SAPlacer
|
|||||||
BelId ripup_bel = BelId();
|
BelId ripup_bel = BelId();
|
||||||
if (cell->bel != BelId()) {
|
if (cell->bel != BelId()) {
|
||||||
ctx->unbindBel(cell->bel);
|
ctx->unbindBel(cell->bel);
|
||||||
cell->bel = BelId();
|
|
||||||
}
|
}
|
||||||
BelType targetType = ctx->belTypeFromId(cell->type);
|
BelType targetType = ctx->belTypeFromId(cell->type);
|
||||||
for (auto bel : ctx->getBels()) {
|
for (auto bel : ctx->getBels()) {
|
||||||
@ -283,7 +280,7 @@ class SAPlacer
|
|||||||
if (score <= best_ripup_score) {
|
if (score <= best_ripup_score) {
|
||||||
best_ripup_score = score;
|
best_ripup_score = score;
|
||||||
ripup_target =
|
ripup_target =
|
||||||
ctx->cells.at(ctx->getBelCell(bel, true));
|
ctx->cells.at(ctx->getBoundBelCell(bel));
|
||||||
ripup_bel = bel;
|
ripup_bel = bel;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -295,14 +292,11 @@ class SAPlacer
|
|||||||
cell->name.c_str(ctx), cell->type.c_str(ctx));
|
cell->name.c_str(ctx), cell->type.c_str(ctx));
|
||||||
--iters;
|
--iters;
|
||||||
ctx->unbindBel(ripup_target->bel);
|
ctx->unbindBel(ripup_target->bel);
|
||||||
ripup_target->bel = BelId();
|
|
||||||
best_bel = ripup_bel;
|
best_bel = ripup_bel;
|
||||||
} else {
|
} else {
|
||||||
all_placed = true;
|
all_placed = true;
|
||||||
}
|
}
|
||||||
cell->bel = best_bel;
|
ctx->bindBel(best_bel, cell->name, STRENGTH_WEAK);
|
||||||
cell->belStrength = STRENGTH_WEAK;
|
|
||||||
ctx->bindBel(cell->bel, cell->name);
|
|
||||||
|
|
||||||
// Back annotate location
|
// Back annotate location
|
||||||
cell->attrs[ctx->id("BEL")] = ctx->getBelName(cell->bel).str(ctx);
|
cell->attrs[ctx->id("BEL")] = ctx->getBelName(cell->bel).str(ctx);
|
||||||
@ -375,7 +369,7 @@ class SAPlacer
|
|||||||
new_lengths.clear();
|
new_lengths.clear();
|
||||||
update.clear();
|
update.clear();
|
||||||
BelId oldBel = cell->bel;
|
BelId oldBel = cell->bel;
|
||||||
IdString other = ctx->getBelCell(newBel, true);
|
IdString other = ctx->getBoundBelCell(newBel);
|
||||||
CellInfo *other_cell = nullptr;
|
CellInfo *other_cell = nullptr;
|
||||||
wirelen_t new_wirelength = 0, delta;
|
wirelen_t new_wirelength = 0, delta;
|
||||||
ctx->unbindBel(oldBel);
|
ctx->unbindBel(oldBel);
|
||||||
@ -394,10 +388,10 @@ class SAPlacer
|
|||||||
update.insert(port.second.net);
|
update.insert(port.second.net);
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx->bindBel(newBel, cell->name);
|
ctx->bindBel(newBel, cell->name, STRENGTH_WEAK);
|
||||||
|
|
||||||
if (other != IdString()) {
|
if (other != IdString()) {
|
||||||
ctx->bindBel(oldBel, other_cell->name);
|
ctx->bindBel(oldBel, other_cell->name, STRENGTH_WEAK);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!checker->isBelLocationValid(newBel) ||
|
if (!checker->isBelLocationValid(newBel) ||
|
||||||
@ -408,10 +402,6 @@ class SAPlacer
|
|||||||
goto swap_fail;
|
goto swap_fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
cell->bel = newBel;
|
|
||||||
if (other != IdString())
|
|
||||||
other_cell->bel = oldBel;
|
|
||||||
|
|
||||||
new_wirelength = curr_wirelength;
|
new_wirelength = curr_wirelength;
|
||||||
|
|
||||||
// Recalculate wirelengths for all nets touched by the peturbation
|
// Recalculate wirelengths for all nets touched by the peturbation
|
||||||
@ -442,11 +432,9 @@ class SAPlacer
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
swap_fail:
|
swap_fail:
|
||||||
ctx->bindBel(oldBel, cell->name);
|
ctx->bindBel(oldBel, cell->name, STRENGTH_WEAK);
|
||||||
cell->bel = oldBel;
|
|
||||||
if (other != IdString()) {
|
if (other != IdString()) {
|
||||||
ctx->bindBel(newBel, other);
|
ctx->bindBel(newBel, other, STRENGTH_WEAK);
|
||||||
other_cell->bel = newBel;
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -498,8 +486,14 @@ bool place_design_sa(Context *ctx, bool timing_driven)
|
|||||||
SAPlacer placer(ctx, timing_driven);
|
SAPlacer placer(ctx, timing_driven);
|
||||||
placer.place();
|
placer.place();
|
||||||
log_info("Checksum: 0x%08x\n", ctx->checksum());
|
log_info("Checksum: 0x%08x\n", ctx->checksum());
|
||||||
|
#ifndef NDEBUG
|
||||||
|
ctx->check();
|
||||||
|
#endif
|
||||||
return true;
|
return true;
|
||||||
} catch (log_execution_error_exception) {
|
} catch (log_execution_error_exception) {
|
||||||
|
#ifndef NDEBUG
|
||||||
|
ctx->check();
|
||||||
|
#endif
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -79,14 +79,26 @@ struct RipupScoreboard
|
|||||||
void ripup_net(Context *ctx, IdString net_name)
|
void ripup_net(Context *ctx, IdString net_name)
|
||||||
{
|
{
|
||||||
auto net_info = ctx->nets.at(net_name);
|
auto net_info = ctx->nets.at(net_name);
|
||||||
|
std::vector<PipId> pips;
|
||||||
|
std::vector<WireId> wires;
|
||||||
|
|
||||||
|
pips.reserve(net_info->wires.size());
|
||||||
|
wires.reserve(net_info->wires.size());
|
||||||
|
|
||||||
for (auto &it : net_info->wires) {
|
for (auto &it : net_info->wires) {
|
||||||
if (it.second != PipId())
|
if (it.second.pip != PipId())
|
||||||
ctx->unbindPip(it.second);
|
pips.push_back(it.second.pip);
|
||||||
ctx->unbindWire(it.first);
|
else
|
||||||
|
wires.push_back(it.first);
|
||||||
}
|
}
|
||||||
|
|
||||||
net_info->wires.clear();
|
for (auto pip : pips)
|
||||||
|
ctx->unbindPip(pip);
|
||||||
|
|
||||||
|
for (auto wire : wires)
|
||||||
|
ctx->unbindWire(wire);
|
||||||
|
|
||||||
|
assert(net_info->wires.empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Router
|
struct Router
|
||||||
@ -147,7 +159,7 @@ struct Router
|
|||||||
if (!ctx->checkWireAvail(next_wire)) {
|
if (!ctx->checkWireAvail(next_wire)) {
|
||||||
if (!ripup)
|
if (!ripup)
|
||||||
continue;
|
continue;
|
||||||
IdString ripupWireNet = ctx->getWireNet(next_wire, true);
|
IdString ripupWireNet = ctx->getConflictingWireNet(next_wire);
|
||||||
if (ripupWireNet == net_name || ripupWireNet == IdString())
|
if (ripupWireNet == net_name || ripupWireNet == IdString())
|
||||||
continue;
|
continue;
|
||||||
auto it = scores.wireScores.find(
|
auto it = scores.wireScores.find(
|
||||||
@ -160,7 +172,7 @@ struct Router
|
|||||||
if (!ctx->checkPipAvail(pip)) {
|
if (!ctx->checkPipAvail(pip)) {
|
||||||
if (!ripup)
|
if (!ripup)
|
||||||
continue;
|
continue;
|
||||||
IdString ripupPipNet = ctx->getPipNet(pip, true);
|
IdString ripupPipNet = ctx->getConflictingPipNet(pip);
|
||||||
if (ripupPipNet == net_name || ripupPipNet == IdString())
|
if (ripupPipNet == net_name || ripupPipNet == IdString())
|
||||||
continue;
|
continue;
|
||||||
auto it = scores.pipScores.find(
|
auto it = scores.pipScores.find(
|
||||||
@ -280,8 +292,7 @@ struct Router
|
|||||||
|
|
||||||
std::unordered_map<WireId, delay_t> src_wires;
|
std::unordered_map<WireId, delay_t> src_wires;
|
||||||
src_wires[src_wire] = 0;
|
src_wires[src_wire] = 0;
|
||||||
net_info->wires[src_wire] = PipId();
|
ctx->bindWire(src_wire, net_name, STRENGTH_WEAK);
|
||||||
ctx->bindWire(src_wire, net_name);
|
|
||||||
|
|
||||||
std::vector<PortRef> users_array = net_info->users;
|
std::vector<PortRef> users_array = net_info->users;
|
||||||
ctx->shuffle(users_array);
|
ctx->shuffle(users_array);
|
||||||
@ -361,9 +372,9 @@ struct Router
|
|||||||
if (src_wires.count(cursor))
|
if (src_wires.count(cursor))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
IdString conflicting_wire_net = ctx->getWireNet(cursor, true);
|
IdString conflicting_wire_net = ctx->getConflictingWireNet(cursor);
|
||||||
IdString conflicting_pip_net =
|
IdString conflicting_pip_net =
|
||||||
ctx->getPipNet(visited[cursor].pip, true);
|
ctx->getConflictingPipNet(visited[cursor].pip);
|
||||||
|
|
||||||
if (conflicting_wire_net != IdString()) {
|
if (conflicting_wire_net != IdString()) {
|
||||||
assert(ripup);
|
assert(ripup);
|
||||||
@ -388,10 +399,7 @@ struct Router
|
|||||||
visited[cursor].pip)]++;
|
visited[cursor].pip)]++;
|
||||||
}
|
}
|
||||||
|
|
||||||
net_info->wires[cursor] = visited[cursor].pip;
|
ctx->bindPip(visited[cursor].pip, net_name, STRENGTH_WEAK);
|
||||||
ctx->bindWire(cursor, net_name);
|
|
||||||
ctx->bindPip(visited[cursor].pip, net_name);
|
|
||||||
|
|
||||||
src_wires[cursor] = visited[cursor].delay;
|
src_wires[cursor] = visited[cursor].delay;
|
||||||
cursor = ctx->getPipSrcWire(visited[cursor].pip);
|
cursor = ctx->getPipSrcWire(visited[cursor].pip);
|
||||||
}
|
}
|
||||||
@ -495,6 +503,9 @@ bool route_design(Context *ctx)
|
|||||||
if (iterCnt == 200) {
|
if (iterCnt == 200) {
|
||||||
log_warning("giving up after %d iterations.\n", iterCnt);
|
log_warning("giving up after %d iterations.\n", iterCnt);
|
||||||
log_info("Checksum: 0x%08x\n", ctx->checksum());
|
log_info("Checksum: 0x%08x\n", ctx->checksum());
|
||||||
|
#ifndef NDEBUG
|
||||||
|
ctx->check();
|
||||||
|
#endif
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -655,8 +666,14 @@ bool route_design(Context *ctx)
|
|||||||
(100.0 * totalOvertimeRevisitCnt) / totalVisitCnt);
|
(100.0 * totalOvertimeRevisitCnt) / totalVisitCnt);
|
||||||
|
|
||||||
log_info("Checksum: 0x%08x\n", ctx->checksum());
|
log_info("Checksum: 0x%08x\n", ctx->checksum());
|
||||||
|
#ifndef NDEBUG
|
||||||
|
ctx->check();
|
||||||
|
#endif
|
||||||
return true;
|
return true;
|
||||||
} catch (log_execution_error_exception) {
|
} catch (log_execution_error_exception) {
|
||||||
|
#ifndef NDEBUG
|
||||||
|
ctx->check();
|
||||||
|
#endif
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,16 +36,15 @@ IdString Arch::getBelName(BelId bel) const { return IdString(); }
|
|||||||
|
|
||||||
uint32_t Arch::getBelChecksum(BelId bel) const { return 0; }
|
uint32_t Arch::getBelChecksum(BelId bel) const { return 0; }
|
||||||
|
|
||||||
void Arch::bindBel(BelId bel, IdString cell) {}
|
void Arch::bindBel(BelId bel, IdString cell, PlaceStrength strength) {}
|
||||||
|
|
||||||
void Arch::unbindBel(BelId bel) {}
|
void Arch::unbindBel(BelId bel) {}
|
||||||
|
|
||||||
bool Arch::checkBelAvail(BelId bel) const { return false; }
|
bool Arch::checkBelAvail(BelId bel) const { return false; }
|
||||||
|
|
||||||
IdString Arch::getBelCell(BelId bel, bool conflicting) const
|
IdString Arch::getBoundBelCell(BelId bel) const { return IdString(); }
|
||||||
{
|
|
||||||
return IdString();
|
IdString Arch::getConflictingBelCell(BelId bel) const { return IdString(); }
|
||||||
}
|
|
||||||
|
|
||||||
const std::vector<BelId> &Arch::getBels() const
|
const std::vector<BelId> &Arch::getBels() const
|
||||||
{
|
{
|
||||||
@ -79,16 +78,15 @@ IdString Arch::getWireName(WireId wire) const { return IdString(); }
|
|||||||
|
|
||||||
uint32_t Arch::getWireChecksum(WireId wire) const { return 0; }
|
uint32_t Arch::getWireChecksum(WireId wire) const { return 0; }
|
||||||
|
|
||||||
void Arch::bindWire(WireId wire, IdString net) {}
|
void Arch::bindWire(WireId wire, IdString net, PlaceStrength strength) {}
|
||||||
|
|
||||||
void Arch::unbindWire(WireId wire) {}
|
void Arch::unbindWire(WireId wire) {}
|
||||||
|
|
||||||
bool Arch::checkWireAvail(WireId wire) const { return false; }
|
bool Arch::checkWireAvail(WireId wire) const { return false; }
|
||||||
|
|
||||||
IdString Arch::getWireNet(WireId wire, bool conflicting) const
|
IdString Arch::getBoundWireNet(WireId wire) const { return IdString(); }
|
||||||
{
|
|
||||||
return IdString();
|
IdString Arch::getConflictingWireNet(WireId wire) const { return IdString(); }
|
||||||
}
|
|
||||||
|
|
||||||
const std::vector<WireId> &Arch::getWires() const
|
const std::vector<WireId> &Arch::getWires() const
|
||||||
{
|
{
|
||||||
@ -104,16 +102,15 @@ IdString Arch::getPipName(PipId pip) const { return IdString(); }
|
|||||||
|
|
||||||
uint32_t Arch::getPipChecksum(PipId wire) const { return 0; }
|
uint32_t Arch::getPipChecksum(PipId wire) const { return 0; }
|
||||||
|
|
||||||
void Arch::bindPip(PipId pip, IdString net) {}
|
void Arch::bindPip(PipId pip, IdString net, PlaceStrength strength) {}
|
||||||
|
|
||||||
void Arch::unbindPip(PipId pip) {}
|
void Arch::unbindPip(PipId pip) {}
|
||||||
|
|
||||||
bool Arch::checkPipAvail(PipId pip) const { return false; }
|
bool Arch::checkPipAvail(PipId pip) const { return false; }
|
||||||
|
|
||||||
IdString Arch::getPipNet(PipId pip, bool conflicting) const
|
IdString Arch::getBoundPipNet(PipId pip) const { return IdString(); }
|
||||||
{
|
|
||||||
return IdString();
|
IdString Arch::getConflictingPipNet(PipId pip) const { return IdString(); }
|
||||||
}
|
|
||||||
|
|
||||||
const std::vector<PipId> &Arch::getPips() const
|
const std::vector<PipId> &Arch::getPips() const
|
||||||
{
|
{
|
||||||
|
15
dummy/arch.h
15
dummy/arch.h
@ -88,10 +88,11 @@ struct Arch : BaseCtx
|
|||||||
BelId getBelByName(IdString name) const;
|
BelId getBelByName(IdString name) const;
|
||||||
IdString getBelName(BelId bel) const;
|
IdString getBelName(BelId bel) const;
|
||||||
uint32_t getBelChecksum(BelId bel) const;
|
uint32_t getBelChecksum(BelId bel) const;
|
||||||
void bindBel(BelId bel, IdString cell);
|
void bindBel(BelId bel, IdString cell, PlaceStrength strength);
|
||||||
void unbindBel(BelId bel);
|
void unbindBel(BelId bel);
|
||||||
bool checkBelAvail(BelId bel) const;
|
bool checkBelAvail(BelId bel) const;
|
||||||
IdString getBelCell(BelId bel, bool conflicting = false) const;
|
IdString getBoundBelCell(BelId bel) const;
|
||||||
|
IdString getConflictingBelCell(BelId bel) const;
|
||||||
const std::vector<BelId> &getBels() const;
|
const std::vector<BelId> &getBels() const;
|
||||||
const std::vector<BelId> &getBelsByType(BelType type) const;
|
const std::vector<BelId> &getBelsByType(BelType type) const;
|
||||||
BelType getBelType(BelId bel) const;
|
BelType getBelType(BelId bel) const;
|
||||||
@ -102,19 +103,21 @@ struct Arch : BaseCtx
|
|||||||
WireId getWireByName(IdString name) const;
|
WireId getWireByName(IdString name) const;
|
||||||
IdString getWireName(WireId wire) const;
|
IdString getWireName(WireId wire) const;
|
||||||
uint32_t getWireChecksum(WireId wire) const;
|
uint32_t getWireChecksum(WireId wire) const;
|
||||||
void bindWire(WireId wire, IdString net);
|
void bindWire(WireId wire, IdString net, PlaceStrength strength);
|
||||||
void unbindWire(WireId wire);
|
void unbindWire(WireId wire);
|
||||||
bool checkWireAvail(WireId wire) const;
|
bool checkWireAvail(WireId wire) const;
|
||||||
IdString getWireNet(WireId wire, bool conflicting = false) const;
|
IdString getBoundWireNet(WireId wire) const;
|
||||||
|
IdString getConflictingWireNet(WireId wire) const;
|
||||||
const std::vector<WireId> &getWires() const;
|
const std::vector<WireId> &getWires() const;
|
||||||
|
|
||||||
PipId getPipByName(IdString name) const;
|
PipId getPipByName(IdString name) const;
|
||||||
IdString getPipName(PipId pip) const;
|
IdString getPipName(PipId pip) const;
|
||||||
uint32_t getPipChecksum(PipId pip) const;
|
uint32_t getPipChecksum(PipId pip) const;
|
||||||
void bindPip(PipId pip, IdString net);
|
void bindPip(PipId pip, IdString net, PlaceStrength strength);
|
||||||
void unbindPip(PipId pip);
|
void unbindPip(PipId pip);
|
||||||
bool checkPipAvail(PipId pip) const;
|
bool checkPipAvail(PipId pip) const;
|
||||||
IdString getPipNet(PipId pip, bool conflicting = false) const;
|
IdString getBoundPipNet(PipId pip) const;
|
||||||
|
IdString getConflictingPipNet(PipId pip) const;
|
||||||
const std::vector<PipId> &getPips() const;
|
const std::vector<PipId> &getPips() const;
|
||||||
WireId getPipSrcWire(PipId pip) const;
|
WireId getPipSrcWire(PipId pip) const;
|
||||||
WireId getPipDstWire(PipId pip) const;
|
WireId getPipDstWire(PipId pip) const;
|
||||||
|
54
ice40/arch.h
54
ice40/arch.h
@ -533,17 +533,21 @@ struct Arch : BaseCtx
|
|||||||
|
|
||||||
uint32_t getBelChecksum(BelId bel) const { return bel.index; }
|
uint32_t getBelChecksum(BelId bel) const { return bel.index; }
|
||||||
|
|
||||||
void bindBel(BelId bel, IdString cell)
|
void bindBel(BelId bel, IdString cell, PlaceStrength strength)
|
||||||
{
|
{
|
||||||
assert(bel != BelId());
|
assert(bel != BelId());
|
||||||
assert(bel_to_cell[bel.index] == IdString());
|
assert(bel_to_cell[bel.index] == IdString());
|
||||||
bel_to_cell[bel.index] = cell;
|
bel_to_cell[bel.index] = cell;
|
||||||
|
cells[cell]->bel = bel;
|
||||||
|
cells[cell]->belStrength = strength;
|
||||||
}
|
}
|
||||||
|
|
||||||
void unbindBel(BelId bel)
|
void unbindBel(BelId bel)
|
||||||
{
|
{
|
||||||
assert(bel != BelId());
|
assert(bel != BelId());
|
||||||
assert(bel_to_cell[bel.index] != IdString());
|
assert(bel_to_cell[bel.index] != IdString());
|
||||||
|
cells[bel_to_cell[bel.index]]->bel = BelId();
|
||||||
|
cells[bel_to_cell[bel.index]]->belStrength = STRENGTH_NONE;
|
||||||
bel_to_cell[bel.index] = IdString();
|
bel_to_cell[bel.index] = IdString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -553,7 +557,13 @@ struct Arch : BaseCtx
|
|||||||
return bel_to_cell[bel.index] == IdString();
|
return bel_to_cell[bel.index] == IdString();
|
||||||
}
|
}
|
||||||
|
|
||||||
IdString getBelCell(BelId bel, bool conflicting = false) const
|
IdString getBoundBelCell(BelId bel) const
|
||||||
|
{
|
||||||
|
assert(bel != BelId());
|
||||||
|
return bel_to_cell[bel.index];
|
||||||
|
}
|
||||||
|
|
||||||
|
IdString getConflictingBelCell(BelId bel) const
|
||||||
{
|
{
|
||||||
assert(bel != BelId());
|
assert(bel != BelId());
|
||||||
return bel_to_cell[bel.index];
|
return bel_to_cell[bel.index];
|
||||||
@ -627,17 +637,20 @@ struct Arch : BaseCtx
|
|||||||
|
|
||||||
uint32_t getWireChecksum(WireId wire) const { return wire.index; }
|
uint32_t getWireChecksum(WireId wire) const { return wire.index; }
|
||||||
|
|
||||||
void bindWire(WireId wire, IdString net)
|
void bindWire(WireId wire, IdString net, PlaceStrength strength)
|
||||||
{
|
{
|
||||||
assert(wire != WireId());
|
assert(wire != WireId());
|
||||||
assert(wire_to_net[wire.index] == IdString());
|
assert(wire_to_net[wire.index] == IdString());
|
||||||
wire_to_net[wire.index] = net;
|
wire_to_net[wire.index] = net;
|
||||||
|
nets[net]->wires[wire].pip = PipId();
|
||||||
|
nets[net]->wires[wire].strength = strength;
|
||||||
}
|
}
|
||||||
|
|
||||||
void unbindWire(WireId wire)
|
void unbindWire(WireId wire)
|
||||||
{
|
{
|
||||||
assert(wire != WireId());
|
assert(wire != WireId());
|
||||||
assert(wire_to_net[wire.index] != IdString());
|
assert(wire_to_net[wire.index] != IdString());
|
||||||
|
nets[wire_to_net[wire.index]]->wires.erase(wire);
|
||||||
wire_to_net[wire.index] = IdString();
|
wire_to_net[wire.index] = IdString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -647,7 +660,13 @@ struct Arch : BaseCtx
|
|||||||
return wire_to_net[wire.index] == IdString();
|
return wire_to_net[wire.index] == IdString();
|
||||||
}
|
}
|
||||||
|
|
||||||
IdString getWireNet(WireId wire, bool conflicting = false) const
|
IdString getBoundWireNet(WireId wire) const
|
||||||
|
{
|
||||||
|
assert(wire != WireId());
|
||||||
|
return wire_to_net[wire.index];
|
||||||
|
}
|
||||||
|
|
||||||
|
IdString getConflictingWireNet(WireId wire) const
|
||||||
{
|
{
|
||||||
assert(wire != WireId());
|
assert(wire != WireId());
|
||||||
return wire_to_net[wire.index];
|
return wire_to_net[wire.index];
|
||||||
@ -668,14 +687,22 @@ struct Arch : BaseCtx
|
|||||||
|
|
||||||
uint32_t getPipChecksum(PipId pip) const { return pip.index; }
|
uint32_t getPipChecksum(PipId pip) const { return pip.index; }
|
||||||
|
|
||||||
void bindPip(PipId pip, IdString net)
|
void bindPip(PipId pip, IdString net, PlaceStrength strength)
|
||||||
{
|
{
|
||||||
assert(pip != PipId());
|
assert(pip != PipId());
|
||||||
assert(pip_to_net[pip.index] == IdString());
|
assert(pip_to_net[pip.index] == IdString());
|
||||||
assert(switches_locked[chip_info->pip_data[pip.index].switch_index] ==
|
assert(switches_locked[chip_info->pip_data[pip.index].switch_index] ==
|
||||||
IdString());
|
IdString());
|
||||||
|
|
||||||
pip_to_net[pip.index] = net;
|
pip_to_net[pip.index] = net;
|
||||||
switches_locked[chip_info->pip_data[pip.index].switch_index] = net;
|
switches_locked[chip_info->pip_data[pip.index].switch_index] = net;
|
||||||
|
|
||||||
|
WireId dst;
|
||||||
|
dst.index = chip_info->pip_data[pip.index].dst;
|
||||||
|
assert(wire_to_net[dst.index] == IdString());
|
||||||
|
wire_to_net[dst.index] = net;
|
||||||
|
nets[net]->wires[dst].pip = pip;
|
||||||
|
nets[net]->wires[dst].strength = strength;
|
||||||
}
|
}
|
||||||
|
|
||||||
void unbindPip(PipId pip)
|
void unbindPip(PipId pip)
|
||||||
@ -684,6 +711,13 @@ struct Arch : BaseCtx
|
|||||||
assert(pip_to_net[pip.index] != IdString());
|
assert(pip_to_net[pip.index] != IdString());
|
||||||
assert(switches_locked[chip_info->pip_data[pip.index].switch_index] !=
|
assert(switches_locked[chip_info->pip_data[pip.index].switch_index] !=
|
||||||
IdString());
|
IdString());
|
||||||
|
|
||||||
|
WireId dst;
|
||||||
|
dst.index = chip_info->pip_data[pip.index].dst;
|
||||||
|
assert(wire_to_net[dst.index] != IdString());
|
||||||
|
wire_to_net[dst.index] = IdString();
|
||||||
|
nets[pip_to_net[pip.index]]->wires.erase(dst);
|
||||||
|
|
||||||
pip_to_net[pip.index] = IdString();
|
pip_to_net[pip.index] = IdString();
|
||||||
switches_locked[chip_info->pip_data[pip.index].switch_index] =
|
switches_locked[chip_info->pip_data[pip.index].switch_index] =
|
||||||
IdString();
|
IdString();
|
||||||
@ -696,14 +730,18 @@ struct Arch : BaseCtx
|
|||||||
IdString();
|
IdString();
|
||||||
}
|
}
|
||||||
|
|
||||||
IdString getPipNet(PipId pip, bool conflicting = false) const
|
IdString getBoundPipNet(PipId pip) const
|
||||||
{
|
{
|
||||||
assert(pip != PipId());
|
assert(pip != PipId());
|
||||||
if (conflicting)
|
|
||||||
return switches_locked[chip_info->pip_data[pip.index].switch_index];
|
|
||||||
return pip_to_net[pip.index];
|
return pip_to_net[pip.index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IdString getConflictingPipNet(PipId pip) const
|
||||||
|
{
|
||||||
|
assert(pip != PipId());
|
||||||
|
return switches_locked[chip_info->pip_data[pip.index].switch_index];
|
||||||
|
}
|
||||||
|
|
||||||
AllPipRange getPips() const
|
AllPipRange getPips() const
|
||||||
{
|
{
|
||||||
AllPipRange range;
|
AllPipRange range;
|
||||||
|
@ -102,7 +102,7 @@ bool PlaceValidityChecker::isBelLocationValid(BelId bel)
|
|||||||
if (ctx->getBelType(bel) == TYPE_ICESTORM_LC) {
|
if (ctx->getBelType(bel) == TYPE_ICESTORM_LC) {
|
||||||
std::vector<const CellInfo *> cells;
|
std::vector<const CellInfo *> cells;
|
||||||
for (auto bel_other : ctx->getBelsAtSameTile(bel)) {
|
for (auto bel_other : ctx->getBelsAtSameTile(bel)) {
|
||||||
IdString cell_other = ctx->getBelCell(bel_other, false);
|
IdString cell_other = ctx->getBoundBelCell(bel_other);
|
||||||
if (cell_other != IdString()) {
|
if (cell_other != IdString()) {
|
||||||
const CellInfo *ci_other = ctx->cells[cell_other];
|
const CellInfo *ci_other = ctx->cells[cell_other];
|
||||||
cells.push_back(ci_other);
|
cells.push_back(ci_other);
|
||||||
@ -110,7 +110,7 @@ bool PlaceValidityChecker::isBelLocationValid(BelId bel)
|
|||||||
}
|
}
|
||||||
return logicCellsCompatible(ctx, cells);
|
return logicCellsCompatible(ctx, cells);
|
||||||
} else {
|
} else {
|
||||||
IdString cellId = ctx->getBelCell(bel, false);
|
IdString cellId = ctx->getBoundBelCell(bel);
|
||||||
if (cellId == IdString())
|
if (cellId == IdString())
|
||||||
return true;
|
return true;
|
||||||
else
|
else
|
||||||
@ -126,7 +126,7 @@ bool PlaceValidityChecker::isValidBelForCell(CellInfo *cell, BelId bel)
|
|||||||
std::vector<const CellInfo *> cells;
|
std::vector<const CellInfo *> cells;
|
||||||
|
|
||||||
for (auto bel_other : ctx->getBelsAtSameTile(bel)) {
|
for (auto bel_other : ctx->getBelsAtSameTile(bel)) {
|
||||||
IdString cell_other = ctx->getBelCell(bel_other, false);
|
IdString cell_other = ctx->getBoundBelCell(bel_other);
|
||||||
if (cell_other != IdString()) {
|
if (cell_other != IdString()) {
|
||||||
const CellInfo *ci_other = ctx->cells[cell_other];
|
const CellInfo *ci_other = ctx->cells[cell_other];
|
||||||
cells.push_back(ci_other);
|
cells.push_back(ci_other);
|
||||||
|
@ -464,7 +464,7 @@ void write_asc(const Context *ctx, std::ostream &out)
|
|||||||
// Write symbols
|
// Write symbols
|
||||||
// const bool write_symbols = 1;
|
// const bool write_symbols = 1;
|
||||||
for (auto wire : ctx->getWires()) {
|
for (auto wire : ctx->getWires()) {
|
||||||
IdString net = ctx->getWireNet(wire, false);
|
IdString net = ctx->getBoundWireNet(wire);
|
||||||
if (net != IdString())
|
if (net != IdString())
|
||||||
out << ".sym " << wire.index << " " << net.str(ctx) << std::endl;
|
out << ".sym " << wire.index << " " << net.str(ctx) << std::endl;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user