archapi: Use arbitrary rather than actual placement in predictDelay
This makes predictDelay be based on an arbitrary belpin pair rather than a arc of a net based on cell placement. This way 'what-if' decisions can be evaluated without actually changing placement; potentially useful for parallel placement. A new helper predictArcDelay behaves like the old predictDelay to minimise the impact on existing passes; only arches need be updated. Signed-off-by: gatecat <gatecat@ds0.me>
This commit is contained in:
parent
56d5507333
commit
ddb084e9a8
@ -110,7 +110,7 @@ template <typename R> struct ArchAPI : BaseCtx
|
|||||||
virtual typename R::GroupPipsRangeT getGroupPips(GroupId group) const = 0;
|
virtual typename R::GroupPipsRangeT getGroupPips(GroupId group) const = 0;
|
||||||
virtual typename R::GroupGroupsRangeT getGroupGroups(GroupId group) const = 0;
|
virtual typename R::GroupGroupsRangeT getGroupGroups(GroupId group) const = 0;
|
||||||
// Delay Methods
|
// Delay Methods
|
||||||
virtual delay_t predictDelay(const NetInfo *net_info, const PortRef &sink) const = 0;
|
virtual delay_t predictDelay(BelId src_bel, IdString src_pin, BelId dst_bel, IdString dst_pin) const = 0;
|
||||||
virtual delay_t getDelayEpsilon() const = 0;
|
virtual delay_t getDelayEpsilon() const = 0;
|
||||||
virtual delay_t getRipupDelayPenalty() const = 0;
|
virtual delay_t getRipupDelayPenalty() const = 0;
|
||||||
virtual float getDelayNS(delay_t v) const = 0;
|
virtual float getDelayNS(delay_t v) const = 0;
|
||||||
|
@ -90,6 +90,25 @@ WireId Context::getNetinfoSinkWire(const NetInfo *net_info, const PortRef &sink,
|
|||||||
return WireId();
|
return WireId();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delay_t Context::predictArcDelay(const NetInfo *net_info, const PortRef &sink) const
|
||||||
|
{
|
||||||
|
if (net_info->driver.cell == nullptr || net_info->driver.cell->bel == BelId() || sink.cell->bel == BelId())
|
||||||
|
return 0;
|
||||||
|
IdString driver_pin, sink_pin;
|
||||||
|
// Pick the first pin for a prediction; assume all will be similar enouhg
|
||||||
|
for (auto pin : getBelPinsForCellPin(net_info->driver.cell, net_info->driver.port)) {
|
||||||
|
driver_pin = pin;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
for (auto pin : getBelPinsForCellPin(sink.cell, sink.port)) {
|
||||||
|
sink_pin = pin;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (driver_pin == IdString() || sink_pin == IdString())
|
||||||
|
return 0;
|
||||||
|
return predictDelay(net_info->driver.cell->bel, driver_pin, sink.cell->bel, sink_pin);
|
||||||
|
}
|
||||||
|
|
||||||
delay_t Context::getNetinfoRouteDelay(const NetInfo *net_info, const PortRef &user_info) const
|
delay_t Context::getNetinfoRouteDelay(const NetInfo *net_info, const PortRef &user_info) const
|
||||||
{
|
{
|
||||||
#ifdef ARCH_ECP5
|
#ifdef ARCH_ECP5
|
||||||
@ -98,7 +117,7 @@ delay_t Context::getNetinfoRouteDelay(const NetInfo *net_info, const PortRef &us
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (net_info->wires.empty())
|
if (net_info->wires.empty())
|
||||||
return predictDelay(net_info, user_info);
|
return predictArcDelay(net_info, user_info);
|
||||||
|
|
||||||
WireId src_wire = getNetinfoSourceWire(net_info);
|
WireId src_wire = getNetinfoSourceWire(net_info);
|
||||||
if (src_wire == WireId())
|
if (src_wire == WireId())
|
||||||
@ -128,7 +147,7 @@ delay_t Context::getNetinfoRouteDelay(const NetInfo *net_info, const PortRef &us
|
|||||||
if (cursor == src_wire)
|
if (cursor == src_wire)
|
||||||
max_delay = std::max(max_delay, delay + getWireDelay(src_wire).maxDelay()); // routed
|
max_delay = std::max(max_delay, delay + getWireDelay(src_wire).maxDelay()); // routed
|
||||||
else
|
else
|
||||||
max_delay = std::max(max_delay, predictDelay(net_info, user_info)); // unrouted
|
max_delay = std::max(max_delay, predictArcDelay(net_info, user_info)); // unrouted
|
||||||
}
|
}
|
||||||
return max_delay;
|
return max_delay;
|
||||||
}
|
}
|
||||||
|
@ -51,6 +51,8 @@ struct Context : Arch, DeterministicRNG
|
|||||||
|
|
||||||
// --------------------------------------------------------------
|
// --------------------------------------------------------------
|
||||||
|
|
||||||
|
delay_t predictArcDelay(const NetInfo *net_info, const PortRef &sink) const;
|
||||||
|
|
||||||
WireId getNetinfoSourceWire(const NetInfo *net_info) const;
|
WireId getNetinfoSourceWire(const NetInfo *net_info) const;
|
||||||
SSOArray<WireId, 2> getNetinfoSinkWires(const NetInfo *net_info, const PortRef &sink) const;
|
SSOArray<WireId, 2> getNetinfoSinkWires(const NetInfo *net_info, const PortRef &sink) const;
|
||||||
size_t getNetinfoSinkWireCount(const NetInfo *net_info, const PortRef &sink) const;
|
size_t getNetinfoSinkWireCount(const NetInfo *net_info, const PortRef &sink) const;
|
||||||
|
@ -33,6 +33,8 @@
|
|||||||
#define USING_NEXTPNR_NAMESPACE
|
#define USING_NEXTPNR_NAMESPACE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define NPNR_UNUSED(x) ((void)x)
|
||||||
|
|
||||||
#if defined(__GNUC__) || defined(__clang__)
|
#if defined(__GNUC__) || defined(__clang__)
|
||||||
#define NPNR_ATTRIBUTE(...) __attribute__((__VA_ARGS__))
|
#define NPNR_ATTRIBUTE(...) __attribute__((__VA_ARGS__))
|
||||||
#define NPNR_NORETURN __attribute__((noreturn))
|
#define NPNR_NORETURN __attribute__((noreturn))
|
||||||
|
@ -50,7 +50,7 @@ wirelen_t get_net_metric(const Context *ctx, const NetInfo *net, MetricType type
|
|||||||
if (load_cell->bel == BelId())
|
if (load_cell->bel == BelId())
|
||||||
continue;
|
continue;
|
||||||
if (timing_driven) {
|
if (timing_driven) {
|
||||||
delay_t net_delay = ctx->predictDelay(net, load);
|
delay_t net_delay = ctx->predictArcDelay(net, load);
|
||||||
auto slack = load.budget - net_delay;
|
auto slack = load.budget - net_delay;
|
||||||
if (slack < 0)
|
if (slack < 0)
|
||||||
negative_slack += slack;
|
negative_slack += slack;
|
||||||
|
@ -866,11 +866,11 @@ class SAPlacer
|
|||||||
if (ctx->getPortTimingClass(net->driver.cell, net->driver.port, cc) == TMG_IGNORE)
|
if (ctx->getPortTimingClass(net->driver.cell, net->driver.port, cc) == TMG_IGNORE)
|
||||||
return 0;
|
return 0;
|
||||||
if (cfg.budgetBased) {
|
if (cfg.budgetBased) {
|
||||||
double delay = ctx->getDelayNS(ctx->predictDelay(net, net->users.at(user)));
|
double delay = ctx->getDelayNS(ctx->predictArcDelay(net, net->users.at(user)));
|
||||||
return std::min(10.0, std::exp(delay - ctx->getDelayNS(net->users.at(user).budget) / 10));
|
return std::min(10.0, std::exp(delay - ctx->getDelayNS(net->users.at(user).budget) / 10));
|
||||||
} else {
|
} else {
|
||||||
float crit = tmg.get_criticality(CellPortKey(net->users.at(user)));
|
float crit = tmg.get_criticality(CellPortKey(net->users.at(user)));
|
||||||
double delay = ctx->getDelayNS(ctx->predictDelay(net, net->users.at(user)));
|
double delay = ctx->getDelayNS(ctx->predictArcDelay(net, net->users.at(user)));
|
||||||
return delay * std::pow(crit, crit_exp);
|
return delay * std::pow(crit, crit_exp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1378,7 +1378,7 @@ void timing_analysis(Context *ctx, bool print_histogram, bool print_fmax, bool p
|
|||||||
auto driver_wire = ctx->getNetinfoSourceWire(net);
|
auto driver_wire = ctx->getNetinfoSourceWire(net);
|
||||||
auto sink_wire = ctx->getNetinfoSinkWire(net, sink_ref, 0);
|
auto sink_wire = ctx->getNetinfoSinkWire(net, sink_ref, 0);
|
||||||
log_info(" prediction: %f ns estimate: %f ns\n",
|
log_info(" prediction: %f ns estimate: %f ns\n",
|
||||||
ctx->getDelayNS(ctx->predictDelay(net, sink_ref)),
|
ctx->getDelayNS(ctx->predictArcDelay(net, sink_ref)),
|
||||||
ctx->getDelayNS(ctx->estimateDelay(driver_wire, sink_wire)));
|
ctx->getDelayNS(ctx->estimateDelay(driver_wire, sink_wire)));
|
||||||
auto cursor = sink_wire;
|
auto cursor = sink_wire;
|
||||||
delay_t delay;
|
delay_t delay;
|
||||||
|
@ -99,7 +99,7 @@ class TimingOptimiser
|
|||||||
continue;
|
continue;
|
||||||
for (auto user : net->users) {
|
for (auto user : net->users) {
|
||||||
if (user.cell == cell && user.port == port.first) {
|
if (user.cell == cell && user.port == port.first) {
|
||||||
if (ctx->predictDelay(net, user) >
|
if (ctx->predictArcDelay(net, user) >
|
||||||
1.1 * max_net_delay.at(std::make_pair(cell->name, port.first)))
|
1.1 * max_net_delay.at(std::make_pair(cell->name, port.first)))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -111,7 +111,7 @@ class TimingOptimiser
|
|||||||
BelId dstBel = user.cell->bel;
|
BelId dstBel = user.cell->bel;
|
||||||
if (dstBel == BelId())
|
if (dstBel == BelId())
|
||||||
continue;
|
continue;
|
||||||
if (ctx->predictDelay(net, user) >
|
if (ctx->predictArcDelay(net, user) >
|
||||||
1.1 * max_net_delay.at(std::make_pair(user.cell->name, user.port))) {
|
1.1 * max_net_delay.at(std::make_pair(user.cell->name, user.port))) {
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -413,7 +413,7 @@ class TimingOptimiser
|
|||||||
for (size_t j = 0; j < pn->users.size(); j++) {
|
for (size_t j = 0; j < pn->users.size(); j++) {
|
||||||
auto &usr = pn->users.at(j);
|
auto &usr = pn->users.at(j);
|
||||||
if (usr.cell == path.at(i)->cell && usr.port == path.at(i)->port) {
|
if (usr.cell == path.at(i)->cell && usr.port == path.at(i)->port) {
|
||||||
original_delay += ctx->predictDelay(pn, usr);
|
original_delay += ctx->predictArcDelay(pn, usr);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -497,7 +497,7 @@ class TimingOptimiser
|
|||||||
for (size_t j = 0; j < pn->users.size(); j++) {
|
for (size_t j = 0; j < pn->users.size(); j++) {
|
||||||
auto &usr = pn->users.at(j);
|
auto &usr = pn->users.at(j);
|
||||||
if (usr.cell == path.at(i)->cell && usr.port == path.at(i)->port) {
|
if (usr.cell == path.at(i)->cell && usr.port == path.at(i)->port) {
|
||||||
total_delay += ctx->predictDelay(pn, usr);
|
total_delay += ctx->predictArcDelay(pn, usr);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -517,7 +517,7 @@ result, and for that estimate it is considered more acceptable to return a
|
|||||||
slightly too high result and it is considered less acceptable to return a
|
slightly too high result and it is considered less acceptable to return a
|
||||||
too low result (thus "low upper bound").
|
too low result (thus "low upper bound").
|
||||||
|
|
||||||
### delay\_t predictDelay(const NetInfo \*net\_info, const PortRef &sink) const
|
### delay\_t predictDelay(BelId src_bel, IdString src_pin, BelId dst_bel, IdString dst_pin) const
|
||||||
|
|
||||||
Return a reasonably good estimate for the total `maxDelay()` delay for the
|
Return a reasonably good estimate for the total `maxDelay()` delay for the
|
||||||
given arc. This should return a low upper bound for the fastest route for that arc.
|
given arc. This should return a low upper bound for the fastest route for that arc.
|
||||||
|
@ -80,7 +80,7 @@ As nextpnr allows arbitrary constraints on bels for more advanced packer-free fl
|
|||||||
There are several routes for timing information in the placer:
|
There are several routes for timing information in the placer:
|
||||||
- sink `PortRef`s have a `budget` value annotated by calling `assign_budget` which is an estimate of the maximum delay that an arc may have
|
- sink `PortRef`s have a `budget` value annotated by calling `assign_budget` which is an estimate of the maximum delay that an arc may have
|
||||||
- sink ports can have a criticality (value between 0 and 1 where 1 is the critical path) associated with them by using `get_criticalities` and a `NetCriticalityMap`
|
- sink ports can have a criticality (value between 0 and 1 where 1 is the critical path) associated with them by using `get_criticalities` and a `NetCriticalityMap`
|
||||||
- `predictDelay` returns an estimated delay for a sink port based on placement information
|
- `predictDelay` and its derivative `predictArcDelay` returns an estimated delay for a sink port based on placement information
|
||||||
|
|
||||||
|
|
||||||
### Bel Buckets
|
### Bel Buckets
|
||||||
|
21
ecp5/arch.cc
21
ecp5/arch.cc
@ -543,26 +543,21 @@ ArcBounds Arch::getRouteBoundingBox(WireId src, WireId dst) const
|
|||||||
return bb;
|
return bb;
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
if ((src_pin == id_FCO && dst_pin == id_FCI) || dst_pin == id_FXA || dst_pin == id_FXB)
|
||||||
if ((driver.port == id_FCO && sink.port == id_FCI) || sink.port == id_FXA || sink.port == id_FXB)
|
|
||||||
return 0;
|
return 0;
|
||||||
auto driver_loc = getBelLocation(driver.cell->bel);
|
auto driver_loc = getBelLocation(src_bel);
|
||||||
auto sink_loc = getBelLocation(sink.cell->bel);
|
auto sink_loc = getBelLocation(dst_bel);
|
||||||
// Encourage use of direct interconnect
|
// Encourage use of direct interconnect
|
||||||
if (driver_loc.x == sink_loc.x && driver_loc.y == sink_loc.y) {
|
if (driver_loc.x == sink_loc.x && driver_loc.y == sink_loc.y) {
|
||||||
if ((sink.port == id_A0 || sink.port == id_A1) && (driver.port == id_F1) &&
|
if ((dst_pin == id_A0 || dst_pin == id_A1) && (src_pin == id_F1) && (driver_loc.z == 2 || driver_loc.z == 3))
|
||||||
(driver_loc.z == 2 || driver_loc.z == 3))
|
|
||||||
return 0;
|
return 0;
|
||||||
if ((sink.port == id_B0 || sink.port == id_B1) && (driver.port == id_F1) &&
|
if ((dst_pin == id_B0 || dst_pin == id_B1) && (src_pin == id_F1) && (driver_loc.z == 0 || driver_loc.z == 1))
|
||||||
(driver_loc.z == 0 || driver_loc.z == 1))
|
|
||||||
return 0;
|
return 0;
|
||||||
if ((sink.port == id_C0 || sink.port == id_C1) && (driver.port == id_F0) &&
|
if ((dst_pin == id_C0 || dst_pin == id_C1) && (src_pin == id_F0) && (driver_loc.z == 2 || driver_loc.z == 3))
|
||||||
(driver_loc.z == 2 || driver_loc.z == 3))
|
|
||||||
return 0;
|
return 0;
|
||||||
if ((sink.port == id_D0 || sink.port == id_D1) && (driver.port == id_F0) &&
|
if ((dst_pin == id_D0 || dst_pin == id_D1) && (src_pin == id_F0) && (driver_loc.z == 0 || driver_loc.z == 1))
|
||||||
(driver_loc.z == 0 || driver_loc.z == 1))
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -913,7 +913,7 @@ struct Arch : BaseArch<ArchRanges>
|
|||||||
|
|
||||||
delay_t estimateDelay(WireId src, WireId dst) const override;
|
delay_t estimateDelay(WireId src, WireId dst) const override;
|
||||||
ArcBounds getRouteBoundingBox(WireId src, WireId dst) const override;
|
ArcBounds getRouteBoundingBox(WireId src, WireId dst) const override;
|
||||||
delay_t predictDelay(const NetInfo *net_info, const PortRef &sink) const override;
|
delay_t predictDelay(BelId src_bel, IdString src_pin, BelId dst_bel, IdString dst_pin) const override;
|
||||||
delay_t getDelayEpsilon() const override { return 20; }
|
delay_t getDelayEpsilon() const override { return 20; }
|
||||||
delay_t getRipupDelayPenalty() const override;
|
delay_t getRipupDelayPenalty() const override;
|
||||||
float getDelayNS(delay_t v) const override { return v * 0.001; }
|
float getDelayNS(delay_t v) const override { return v * 0.001; }
|
||||||
|
@ -1000,14 +1000,16 @@ delay_t Arch::estimateDelay(WireId src, WireId dst) const
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
{
|
{
|
||||||
// FIXME: Implement when adding timing-driven place and route.
|
// FIXME: Implement when adding timing-driven place and route.
|
||||||
|
NPNR_UNUSED(src_pin);
|
||||||
|
NPNR_UNUSED(dst_pin);
|
||||||
int src_x, src_y;
|
int src_x, src_y;
|
||||||
get_tile_x_y(net_info->driver.cell->bel.tile, &src_x, &src_y);
|
get_tile_x_y(src_bel.tile, &src_x, &src_y);
|
||||||
|
|
||||||
int dst_x, dst_y;
|
int dst_x, dst_y;
|
||||||
get_tile_x_y(sink.cell->bel.tile, &dst_x, &dst_y);
|
get_tile_x_y(dst_bel.tile, &dst_x, &dst_y);
|
||||||
|
|
||||||
delay_t base = 30 * std::min(std::abs(dst_x - src_x), 18) + 10 * std::max(std::abs(dst_x - src_x) - 18, 0) +
|
delay_t base = 30 * std::min(std::abs(dst_x - src_x), 18) + 10 * std::max(std::abs(dst_x - src_x) - 18, 0) +
|
||||||
60 * std::min(std::abs(dst_y - src_y), 6) + 20 * std::max(std::abs(dst_y - src_y) - 6, 0) + 300;
|
60 * std::min(std::abs(dst_y - src_y), 6) + 20 * std::max(std::abs(dst_y - src_y) - 6, 0) + 300;
|
||||||
|
@ -700,7 +700,7 @@ struct Arch : ArchAPI<ArchRanges>
|
|||||||
|
|
||||||
// -------------------------------------------------
|
// -------------------------------------------------
|
||||||
delay_t estimateDelay(WireId src, WireId dst) const final;
|
delay_t estimateDelay(WireId src, WireId dst) const final;
|
||||||
delay_t predictDelay(const NetInfo *net_info, const PortRef &sink) const final;
|
delay_t predictDelay(BelId src_bel, IdString src_pin, BelId dst_bel, IdString dst_pin) const final;
|
||||||
ArcBounds getRouteBoundingBox(WireId src, WireId dst) const final;
|
ArcBounds getRouteBoundingBox(WireId src, WireId dst) const final;
|
||||||
delay_t getDelayEpsilon() const final { return 20; }
|
delay_t getDelayEpsilon() const final { return 20; }
|
||||||
delay_t getRipupDelayPenalty() const final { return 120; }
|
delay_t getRipupDelayPenalty() const final { return 120; }
|
||||||
|
@ -509,11 +509,12 @@ delay_t Arch::estimateDelay(WireId src, WireId dst) const
|
|||||||
return (dx + dy) * args.delayScale + args.delayOffset;
|
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;
|
NPNR_UNUSED(src_pin);
|
||||||
auto driver_loc = getBelLocation(driver.cell->bel);
|
NPNR_UNUSED(dst_pin);
|
||||||
auto sink_loc = getBelLocation(sink.cell->bel);
|
auto driver_loc = getBelLocation(src_bel);
|
||||||
|
auto sink_loc = getBelLocation(dst_bel);
|
||||||
|
|
||||||
int dx = abs(sink_loc.x - driver_loc.x);
|
int dx = abs(sink_loc.x - driver_loc.x);
|
||||||
int dy = abs(sink_loc.y - driver_loc.y);
|
int dy = abs(sink_loc.y - driver_loc.y);
|
||||||
|
@ -287,7 +287,7 @@ struct Arch : ArchAPI<ArchRanges>
|
|||||||
const std::vector<GroupId> &getGroupGroups(GroupId group) const override;
|
const std::vector<GroupId> &getGroupGroups(GroupId group) const override;
|
||||||
|
|
||||||
delay_t estimateDelay(WireId src, WireId dst) const override;
|
delay_t estimateDelay(WireId src, WireId dst) const override;
|
||||||
delay_t predictDelay(const NetInfo *net_info, const PortRef &sink) const override;
|
delay_t predictDelay(BelId src_bel, IdString src_pin, BelId dst_bel, IdString dst_pin) const override;
|
||||||
delay_t getDelayEpsilon() const override { return 0.001; }
|
delay_t getDelayEpsilon() const override { return 0.001; }
|
||||||
delay_t getRipupDelayPenalty() const override { return 0.015; }
|
delay_t getRipupDelayPenalty() const override { return 0.015; }
|
||||||
float getDelayNS(delay_t v) const override { return v; }
|
float getDelayNS(delay_t v) const override { return v; }
|
||||||
|
@ -1171,11 +1171,12 @@ delay_t Arch::estimateDelay(WireId src, WireId dst) const
|
|||||||
return (dx + dy) * args.delayScale + args.delayOffset;
|
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;
|
NPNR_UNUSED(src_pin);
|
||||||
auto driver_loc = getBelLocation(driver.cell->bel);
|
NPNR_UNUSED(dst_pin);
|
||||||
auto sink_loc = getBelLocation(sink.cell->bel);
|
auto driver_loc = getBelLocation(src_bel);
|
||||||
|
auto sink_loc = getBelLocation(dst_bel);
|
||||||
|
|
||||||
int dx = abs(sink_loc.x - driver_loc.x);
|
int dx = abs(sink_loc.x - driver_loc.x);
|
||||||
int dy = abs(sink_loc.y - driver_loc.y);
|
int dy = abs(sink_loc.y - driver_loc.y);
|
||||||
|
@ -419,7 +419,7 @@ struct Arch : BaseArch<ArchRanges>
|
|||||||
const std::vector<GroupId> &getGroupGroups(GroupId group) const override;
|
const std::vector<GroupId> &getGroupGroups(GroupId group) const override;
|
||||||
|
|
||||||
delay_t estimateDelay(WireId src, WireId dst) const override;
|
delay_t estimateDelay(WireId src, WireId dst) const override;
|
||||||
delay_t predictDelay(const NetInfo *net_info, const PortRef &sink) const override;
|
delay_t predictDelay(BelId src_bel, IdString src_pin, BelId dst_bel, IdString dst_pin) const override;
|
||||||
delay_t getDelayEpsilon() const override { return 0.01; }
|
delay_t getDelayEpsilon() const override { return 0.01; }
|
||||||
delay_t getRipupDelayPenalty() const override { return 0.4; }
|
delay_t getRipupDelayPenalty() const override { return 0.4; }
|
||||||
float getDelayNS(delay_t v) const override { return v; }
|
float getDelayNS(delay_t v) const override { return v; }
|
||||||
|
@ -784,7 +784,7 @@ struct Arch : BaseArch<ArchRanges>
|
|||||||
// -------------------------------------------------
|
// -------------------------------------------------
|
||||||
|
|
||||||
delay_t estimateDelay(WireId src, WireId dst) const override;
|
delay_t estimateDelay(WireId src, WireId dst) const override;
|
||||||
delay_t predictDelay(const NetInfo *net_info, const PortRef &sink) const override;
|
delay_t predictDelay(BelId src_bel, IdString src_pin, BelId dst_bel, IdString dst_pin) const override;
|
||||||
delay_t getDelayEpsilon() const override { return 20; }
|
delay_t getDelayEpsilon() const override { return 20; }
|
||||||
delay_t getRipupDelayPenalty() const override { return 200; }
|
delay_t getRipupDelayPenalty() const override { return 200; }
|
||||||
float getDelayNS(delay_t v) const override { return v * 0.001; }
|
float getDelayNS(delay_t v) const override { return v * 0.001; }
|
||||||
|
@ -188,13 +188,13 @@ delay_t Arch::estimateDelay(WireId src, WireId dst) const
|
|||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
NPNR_UNUSED(dst_pin);
|
||||||
auto driver_loc = getBelLocation(driver.cell->bel);
|
auto driver_loc = getBelLocation(src_bel);
|
||||||
auto sink_loc = getBelLocation(sink.cell->bel);
|
auto sink_loc = getBelLocation(dst_bel);
|
||||||
|
|
||||||
if (driver.port == id_COUT) {
|
if (src_pin == id_COUT) {
|
||||||
if (driver_loc.y == sink_loc.y)
|
if (driver_loc.y == sink_loc.y)
|
||||||
return 0;
|
return 0;
|
||||||
return 250;
|
return 250;
|
||||||
|
@ -387,16 +387,17 @@ delay_t Arch::estimateDelay(WireId src, WireId dst) const
|
|||||||
return (abs(dst.location.x - src.location.x) + abs(dst.location.y - src.location.y)) * (0.01 + 0.01);
|
return (abs(dst.location.x - src.location.x) + abs(dst.location.y - src.location.y)) * (0.01 + 0.01);
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
{
|
{
|
||||||
BelId src = net_info->driver.cell->bel;
|
NPNR_UNUSED(src_pin);
|
||||||
BelId dst = sink.cell->bel;
|
NPNR_UNUSED(dst_pin);
|
||||||
|
|
||||||
NPNR_ASSERT(src != BelId());
|
NPNR_ASSERT(src_bel != BelId());
|
||||||
NPNR_ASSERT(dst != BelId());
|
NPNR_ASSERT(dst_bel != BelId());
|
||||||
|
|
||||||
// TODO: Same deal applies here as with estimateDelay.
|
// TODO: Same deal applies here as with estimateDelay.
|
||||||
return (abs(dst.location.x - src.location.x) + abs(dst.location.y - src.location.y)) * (0.01 + 0.01);
|
return (abs(dst_bel.location.x - src_bel.location.x) + abs(dst_bel.location.y - src_bel.location.y)) *
|
||||||
|
(0.01 + 0.01);
|
||||||
}
|
}
|
||||||
|
|
||||||
ArcBounds Arch::getRouteBoundingBox(WireId src, WireId dst) const
|
ArcBounds Arch::getRouteBoundingBox(WireId src, WireId dst) const
|
||||||
|
@ -626,7 +626,7 @@ struct Arch : BaseArch<ArchRanges>
|
|||||||
|
|
||||||
// Delay
|
// Delay
|
||||||
delay_t estimateDelay(WireId src, WireId dst) const override;
|
delay_t estimateDelay(WireId src, WireId dst) const override;
|
||||||
delay_t predictDelay(const NetInfo *net_info, const PortRef &sink) const override;
|
delay_t predictDelay(BelId src_bel, IdString src_pin, BelId dst_bel, IdString dst_pin) const override;
|
||||||
delay_t getDelayEpsilon() const override { return 0.001; }
|
delay_t getDelayEpsilon() const override { return 0.001; }
|
||||||
delay_t getRipupDelayPenalty() const override { return 0.015; }
|
delay_t getRipupDelayPenalty() const override { return 0.015; }
|
||||||
float getDelayNS(delay_t v) const override { return v; }
|
float getDelayNS(delay_t v) const override { return v; }
|
||||||
|
@ -418,7 +418,7 @@ struct Arch : BaseArch<ArchRanges>
|
|||||||
// -------------------------------------------------
|
// -------------------------------------------------
|
||||||
|
|
||||||
delay_t estimateDelay(WireId src, WireId dst) const override;
|
delay_t estimateDelay(WireId src, WireId dst) const override;
|
||||||
delay_t predictDelay(const NetInfo *net_info, const PortRef &sink) const override;
|
delay_t predictDelay(BelId src_bel, IdString src_pin, BelId dst_bel, IdString dst_pin) const override;
|
||||||
delay_t getDelayEpsilon() const override { return 10; };
|
delay_t getDelayEpsilon() const override { return 10; };
|
||||||
delay_t getRipupDelayPenalty() const override { return 100; };
|
delay_t getRipupDelayPenalty() const override { return 100; };
|
||||||
float getDelayNS(delay_t v) const override { return float(v) / 1000.0f; };
|
float getDelayNS(delay_t v) const override { return float(v) / 1000.0f; };
|
||||||
|
@ -239,14 +239,12 @@ DelayQuad Arch::getPipDelay(PipId pip) const
|
|||||||
return DelayQuad{308};
|
return DelayQuad{308};
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
{
|
{
|
||||||
if (net_info->driver.cell == nullptr || net_info->driver.cell->bel == BelId())
|
NPNR_UNUSED(src_pin);
|
||||||
return 100;
|
NPNR_UNUSED(dst_pin);
|
||||||
if (sink.cell->bel == BelId())
|
Loc src_loc = getBelLocation(src_bel);
|
||||||
return 100;
|
Loc dst_loc = getBelLocation(dst_bel);
|
||||||
Loc src_loc = getBelLocation(net_info->driver.cell->bel);
|
|
||||||
Loc dst_loc = getBelLocation(sink.cell->bel);
|
|
||||||
return std::abs(dst_loc.y - src_loc.y) * 100 + std::abs(dst_loc.x - src_loc.x) * 100 + 100;
|
return std::abs(dst_loc.y - src_loc.y) * 100 + std::abs(dst_loc.x - src_loc.x) * 100 + 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -603,16 +603,14 @@ delay_t Arch::estimateDelay(WireId src, WireId dst) const
|
|||||||
int dist_y = std::abs(src_y - dst_y);
|
int dist_y = std::abs(src_y - dst_y);
|
||||||
return 75 * dist_x + 75 * dist_y + 250;
|
return 75 * dist_x + 75 * dist_y + 250;
|
||||||
}
|
}
|
||||||
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
|
||||||
{
|
{
|
||||||
if (net_info->driver.cell == nullptr || net_info->driver.cell->bel == BelId() || sink.cell->bel == BelId())
|
NPNR_UNUSED(src_pin);
|
||||||
|
if (dst_pin == id_FCI)
|
||||||
return 0;
|
return 0;
|
||||||
if (sink.port == id_FCI)
|
int src_x = src_bel.tile % chip_info->width, src_y = src_bel.tile / chip_info->width;
|
||||||
return 0;
|
|
||||||
int src_x = net_info->driver.cell->bel.tile % chip_info->width,
|
|
||||||
src_y = net_info->driver.cell->bel.tile / chip_info->width;
|
|
||||||
|
|
||||||
int dst_x = sink.cell->bel.tile % chip_info->width, dst_y = sink.cell->bel.tile / chip_info->width;
|
int dst_x = dst_bel.tile % chip_info->width, dst_y = dst_bel.tile / chip_info->width;
|
||||||
int dist_x = std::abs(src_x - dst_x);
|
int dist_x = std::abs(src_x - dst_x);
|
||||||
int dist_y = std::abs(src_y - dst_y);
|
int dist_y = std::abs(src_y - dst_y);
|
||||||
return 100 * dist_x + 100 * dist_y + 250;
|
return 100 * dist_x + 100 * dist_y + 250;
|
||||||
|
@ -1291,7 +1291,7 @@ struct Arch : BaseArch<ArchRanges>
|
|||||||
// -------------------------------------------------
|
// -------------------------------------------------
|
||||||
|
|
||||||
delay_t estimateDelay(WireId src, WireId dst) const override;
|
delay_t estimateDelay(WireId src, WireId dst) const override;
|
||||||
delay_t predictDelay(const NetInfo *net_info, const PortRef &sink) const override;
|
delay_t predictDelay(BelId src_bel, IdString src_pin, BelId dst_bel, IdString dst_pin) const override;
|
||||||
delay_t getDelayEpsilon() const override { return 20; }
|
delay_t getDelayEpsilon() const override { return 20; }
|
||||||
delay_t getRipupDelayPenalty() const override;
|
delay_t getRipupDelayPenalty() const override;
|
||||||
delay_t getWireRipupDelayPenalty(WireId wire) const;
|
delay_t getWireRipupDelayPenalty(WireId wire) const;
|
||||||
|
Loading…
Reference in New Issue
Block a user