Rip out budgets

This commit is contained in:
rowanG077 2023-05-11 11:23:32 +02:00 committed by myrtle
parent 77afaf23a5
commit 914999673c
37 changed files with 16 additions and 279 deletions

View File

@ -116,7 +116,6 @@ template <typename R> struct ArchAPI : BaseCtx
virtual float getDelayNS(delay_t v) const = 0;
virtual delay_t getDelayFromNS(float ns) const = 0;
virtual uint32_t getDelayChecksum(delay_t v) const = 0;
virtual bool getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay_t &budget) const = 0;
virtual delay_t estimateDelay(WireId src, WireId dst) const = 0;
virtual BoundingBox getRouteBoundingBox(WireId src, WireId dst) const = 0;
virtual bool getArcDelayOverride(const NetInfo *net_info, const PortRef &sink, DelayQuad &delay) const = 0;

View File

@ -313,10 +313,6 @@ template <typename R> struct BaseArch : ArchAPI<R>
};
// Delay methods
virtual bool getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay_t &budget) const override
{
return false;
}
virtual bool getArcDelayOverride(const NetInfo *net_info, const PortRef &sink, DelayQuad &delay) const override
{
return false;

View File

@ -171,7 +171,6 @@ po::options_description CommandHandler::getGeneralOptions()
general.add_options()("slack_redist_iter", po::value<int>(), "number of iterations between slack redistribution");
general.add_options()("cstrweight", po::value<float>(), "placer weighting for relative constraint satisfaction");
general.add_options()("starttemp", po::value<float>(), "placer SA start temperature");
general.add_options()("placer-budgets", "use budget rather than criticality in placer timing weights");
general.add_options()("pack-only", "pack design only without placement or routing");
general.add_options()("no-route", "process design without routing");
@ -318,9 +317,6 @@ void CommandHandler::setupContext(Context *ctx)
ctx->settings[ctx->id("placer1/startTemp")] = std::to_string(vm["starttemp"].as<float>());
}
if (vm.count("placer-budgets")) {
ctx->settings[ctx->id("placer1/budgetBased")] = true;
}
if (vm.count("freq")) {
auto freq = vm["freq"].as<double>();
if (freq > 0)
@ -457,7 +453,6 @@ int CommandHandler::executeMain(std::unique_ptr<Context> ctx)
if (!ctx->pack() && !ctx->force)
log_error("Packing design failed.\n");
}
assign_budget(ctx.get());
ctx->check();
print_utilisation(ctx.get());

View File

@ -236,13 +236,11 @@ uint32_t Context::checksum() const
if (ni.driver.cell)
x = xorshift32(x + xorshift32(ni.driver.cell->name.index));
x = xorshift32(x + xorshift32(ni.driver.port.index));
x = xorshift32(x + xorshift32(getDelayChecksum(ni.driver.budget)));
for (auto &u : ni.users) {
if (u.cell)
x = xorshift32(x + xorshift32(u.cell->name.index));
x = xorshift32(x + xorshift32(u.port.index));
x = xorshift32(x + xorshift32(getDelayChecksum(u.budget)));
}
uint32_t attr_x_sum = 0;

View File

@ -75,7 +75,6 @@ struct PortRef
{
CellInfo *cell = nullptr;
IdString port;
delay_t budget = 0;
};
// minimum and maximum delay
@ -326,8 +325,6 @@ struct CriticalPath
std::pair<IdString, IdString> to;
// Segment delay
delay_t delay;
// Segment budget (routing only)
delay_t budget;
};
// Clock pair
@ -349,8 +346,6 @@ struct NetSinkTiming
std::pair<IdString, IdString> cell_port;
// Delay
delay_t delay;
// Delay budget
delay_t budget;
};
struct TimingResult

View File

@ -239,8 +239,6 @@ PYBIND11_EMBEDDED_MODULE(MODULE_NAME, m)
"cell");
readonly_wrapper<PortRef, decltype(&PortRef::port), &PortRef::port, conv_to_str<IdString>>::def_wrap(pr_cls,
"port");
readonly_wrapper<PortRef, decltype(&PortRef::budget), &PortRef::budget, pass_through<delay_t>>::def_wrap(pr_cls,
"budget");
auto pm_cls = py::class_<ContextualWrapper<PipMap &>>(m, "PipMap");
readwrite_wrapper<PipMap &, decltype(&PipMap::pip), &PipMap::pip, conv_to_str<PipId>,

View File

@ -90,7 +90,6 @@ static Json::array report_critical_paths(const Context *ctx)
} else if (segment.type == CriticalPath::Segment::Type::ROUTING) {
segmentJson["type"] = "routing";
segmentJson["net"] = segment.net.c_str(ctx);
segmentJson["budget"] = ctx->getDelayNS(segment.budget);
}
pathJson.push_back(segmentJson);
@ -134,8 +133,7 @@ static Json::array report_detailed_net_timings(const Context *ctx)
auto endpointJson = Json::object({{"cell", sink_timing.cell_port.first.c_str(ctx)},
{"port", sink_timing.cell_port.second.c_str(ctx)},
{"event", clock_event_name(ctx, sink_timing.clock_pair.end)},
{"delay", ctx->getDelayNS(sink_timing.delay)},
{"budget", ctx->getDelayNS(sink_timing.budget)}});
{"delay", ctx->getDelayNS(sink_timing.delay)}});
endpointsJson.push_back(endpointJson);
}
@ -194,7 +192,6 @@ Report JSON structure:
"type": <path segment type "clk-to-q", "source", "logic", "routing" or "setup">,
"net": <net name (for routing only!)>,
"delay": <segment delay [ns]>,
"budget": <segment delay budget [ns] (for routing only!)>,
}
...
]
@ -213,7 +210,6 @@ Report JSON structure:
"port": <sink cell port name>,
"event": <destination clock event name>,
"delay": <delay [ns]>,
"budget": <delay budget [ns]>,
}
...
]

View File

@ -501,7 +501,6 @@ void TimingAnalyser::reset_times()
dp.second.hold_slack = std::numeric_limits<delay_t>::max();
dp.second.max_path_length = 0;
dp.second.criticality = 0;
dp.second.budget = 0;
}
port.second.worst_crit = 0;
port.second.worst_setup_slack = std::numeric_limits<delay_t>::max();
@ -1060,7 +1059,6 @@ struct Timing
if (portClass == TMG_ENDPOINT || portClass == TMG_IGNORE || portClass == TMG_CLOCK_INPUT) {
// Skip
} else {
auto budget_override = ctx->getBudgetOverride(net, usr, net_delay);
// Iterate over all output ports on the same cell as the sink
for (auto port : usr.cell->ports) {
if (port.second.type != PORT_OUT || !port.second.net)
@ -1073,9 +1071,6 @@ struct Timing
auto &data = net_data[port.second.net][start_clk];
auto &arrival = data.max_arrival;
arrival = std::max(arrival, usr_arrival + comb_delay.maxDelay());
if (!budget_override) { // Do not increment path length if budget overridden since it
// doesn't
// require a share of the slack
auto &path_length = data.max_path_length;
path_length = std::max(path_length, net_length_plus_one);
}
@ -1083,7 +1078,6 @@ struct Timing
}
}
}
}
dict<ClockPair, std::pair<delay_t, NetInfo *>> crit_nets;
@ -1102,7 +1096,6 @@ struct Timing
auto &net_min_remaining_budget = nd.min_remaining_budget;
for (auto &usr : net->users) {
auto net_delay = net_delays ? ctx->getNetinfoRouteDelay(net, usr) : delay_t();
auto budget_override = ctx->getBudgetOverride(net, usr, net_delay);
int port_clocks;
TimingPortClass portClass = ctx->getPortTimingClass(usr.cell, usr.port, port_clocks);
if (portClass == TMG_REGISTER_INPUT || portClass == TMG_ENDPOINT) {
@ -1133,8 +1126,7 @@ struct Timing
auto path_budget = period - endpoint_arrival;
if (update) {
auto budget_share = budget_override ? 0 : path_budget / net_length_plus_one;
usr.budget = std::min(usr.budget, net_delay + budget_share);
auto budget_share = path_budget / net_length_plus_one;
net_min_remaining_budget =
std::min(net_min_remaining_budget, path_budget - budget_share);
}
@ -1156,7 +1148,6 @@ struct Timing
sink_timing.clock_pair = clockPair;
sink_timing.cell_port = std::make_pair(usr.cell->name, usr.port);
sink_timing.delay = endpoint_arrival;
sink_timing.budget = period;
(*detailed_net_timings)[net->name].push_back(sink_timing);
}
@ -1196,8 +1187,7 @@ struct Timing
net_data.at(port.second.net).count(startdomain.first)) {
auto path_budget =
net_data.at(port.second.net).at(startdomain.first).min_remaining_budget;
auto budget_share = budget_override ? 0 : path_budget / net_length_plus_one;
usr.budget = std::min(usr.budget, net_delay + budget_share);
auto budget_share = path_budget / net_length_plus_one;
net_min_remaining_budget =
std::min(net_min_remaining_budget, path_budget - budget_share);
}
@ -1265,64 +1255,8 @@ struct Timing
}
return min_slack;
}
void assign_budget()
{
// Clear delays to a very high value first
for (auto &net : ctx->nets) {
for (auto &usr : net.second->users) {
usr.budget = std::numeric_limits<delay_t>::max();
}
}
walk_paths();
}
};
void assign_budget(Context *ctx, bool quiet)
{
if (!quiet) {
log_break();
log_info("Annotating ports with timing budgets for target frequency %.2f MHz\n",
ctx->setting<float>("target_freq") / 1e6);
}
Timing timing(ctx, ctx->setting<int>("slack_redist_iter") > 0 /* net_delays */, true /* update */);
timing.assign_budget();
if (!quiet || ctx->verbose) {
for (auto &net : ctx->nets) {
for (auto &user : net.second->users) {
// Post-update check
if (!ctx->setting<bool>("auto_freq") && user.budget < 0)
log_info("port %s.%s, connected to net '%s', has negative "
"timing budget of %fns\n",
user.cell->name.c_str(ctx), user.port.c_str(ctx), net.first.c_str(ctx),
ctx->getDelayNS(user.budget));
else if (ctx->debug)
log_info("port %s.%s, connected to net '%s', has "
"timing budget of %fns\n",
user.cell->name.c_str(ctx), user.port.c_str(ctx), net.first.c_str(ctx),
ctx->getDelayNS(user.budget));
}
}
}
// For slack redistribution, if user has not specified a frequency dynamically adjust the target frequency to be the
// currently achieved maximum
if (ctx->setting<bool>("auto_freq") && ctx->setting<int>("slack_redist_iter") > 0) {
delay_t default_slack = delay_t((1.0e9 / ctx->getDelayNS(1)) / ctx->setting<float>("target_freq"));
ctx->settings[ctx->id("target_freq")] =
std::to_string(1.0e9 / ctx->getDelayNS(default_slack - timing.min_slack));
if (ctx->verbose)
log_info("minimum slack for this assign = %.2f ns, target Fmax for next "
"update = %.2f MHz\n",
ctx->getDelayNS(timing.min_slack), ctx->setting<float>("target_freq") / 1e6);
}
if (!quiet)
log_info("Checksum: 0x%08x\n", ctx->checksum());
}
CriticalPath build_critical_path_report(Context *ctx, ClockPair &clocks, const PortRefVector &crit_path)
{
@ -1378,7 +1312,6 @@ CriticalPath build_critical_path_report(Context *ctx, ClockPair &clocks, const P
}
seg_logic.delay = comb_delay.maxDelay();
seg_logic.budget = 0;
seg_logic.from = std::make_pair(last_cell->name, last_port);
seg_logic.to = std::make_pair(driver_cell->name, driver.port);
seg_logic.net = IdString();
@ -1389,7 +1322,6 @@ CriticalPath build_critical_path_report(Context *ctx, ClockPair &clocks, const P
CriticalPath::Segment seg_route;
seg_route.type = CriticalPath::Segment::Type::ROUTING;
seg_route.delay = net_delay;
seg_route.budget = sink->budget;
seg_route.from = std::make_pair(driver_cell->name, driver.port);
seg_route.to = std::make_pair(sink_cell->name, sink->port);
seg_route.net = net->name;
@ -1408,7 +1340,6 @@ CriticalPath build_critical_path_report(Context *ctx, ClockPair &clocks, const P
CriticalPath::Segment seg_logic;
seg_logic.type = CriticalPath::Segment::Type::SETUP;
seg_logic.delay = setup;
seg_logic.budget = 0;
seg_logic.from = std::make_pair(last_cell->name, last_port);
seg_logic.to = seg_logic.from;
seg_logic.net = IdString();
@ -1582,8 +1513,8 @@ void timing_analysis(Context *ctx, bool print_histogram, bool print_fmax, bool p
auto driver_loc = ctx->getBelLocation(driver->bel);
auto sink_loc = ctx->getBelLocation(sink->bel);
log_info("%4.1f %4.1f Net %s budget %f ns (%d,%d) -> (%d,%d)\n", ctx->getDelayNS(segment.delay),
ctx->getDelayNS(total), segment.net.c_str(ctx), ctx->getDelayNS(segment.budget),
log_info("%4.1f %4.1f Net %s (%d,%d) -> (%d,%d)\n", ctx->getDelayNS(segment.delay),
ctx->getDelayNS(total), segment.net.c_str(ctx),
driver_loc.x, driver_loc.y, sink_loc.x, sink_loc.y);
log_info(" Sink %s.%s\n", segment.to.first.c_str(ctx), segment.to.second.c_str(ctx));
@ -1594,7 +1525,6 @@ void timing_analysis(Context *ctx, bool print_histogram, bool print_fmax, bool p
PortRef sink_ref;
sink_ref.cell = sink.get();
sink_ref.port = segment.to.second;
sink_ref.budget = segment.budget;
auto driver_wire = ctx->getNetinfoSourceWire(net);
auto sink_wire = ctx->getNetinfoSinkWire(net, sink_ref, 0);
@ -1842,6 +1772,7 @@ void timing_analysis(Context *ctx, bool print_histogram, bool print_fmax, bool p
results.detailed_net_timings = std::move(detailed_net_timings);
}
}
NEXTPNR_NAMESPACE_END

View File

@ -143,7 +143,6 @@ struct TimingAnalyser
struct PortDomainPairData
{
delay_t setup_slack = std::numeric_limits<delay_t>::max(), hold_slack = std::numeric_limits<delay_t>::max();
delay_t budget = std::numeric_limits<delay_t>::max();
int max_path_length = 0;
float criticality = 0;
};
@ -231,9 +230,6 @@ struct TimingAnalyser
Context *ctx;
};
// Evenly redistribute the total path slack amongst all sinks on each path
void assign_budget(Context *ctx, bool quiet = false);
// Perform timing analysis and print out the fmax, and optionally the
// critical path
void timing_analysis(Context *ctx, bool slack_histogram = true, bool print_fmax = true, bool print_path = false,

View File

@ -51,7 +51,7 @@ wirelen_t get_net_metric(const Context *ctx, const NetInfo *net, MetricType type
continue;
if (timing_driven) {
delay_t net_delay = ctx->predictArcDelay(net, load);
auto slack = load.budget - net_delay;
auto slack = -net_delay;
if (slack < 0)
negative_slack += slack;
worst_slack = std::min(slack, worst_slack);

View File

@ -211,8 +211,6 @@ class SAPlacer
if ((placed_cells - constr_placed_cells) % 500 != 0)
log_info(" initial placement placed %d/%d cells\n", int(placed_cells - constr_placed_cells),
int(autoplaced.size()));
if (cfg.budgetBased && cfg.slack_redist_iter > 0)
assign_budget(ctx);
ctx->yield();
auto iplace_end = std::chrono::high_resolution_clock::now();
log_info("Initial placement time %.02fs\n",
@ -240,7 +238,6 @@ class SAPlacer
// Invoke timing analysis to obtain criticalities
tmg.setup_only = true;
if (!cfg.budgetBased)
tmg.setup();
// Calculate costs after initial placement
@ -368,18 +365,12 @@ class SAPlacer
// temp = post_legalise_temp;
// diameter = std::min<int>(M, diameter * post_legalise_dia_scale);
ctx->shuffle(autoplaced);
// Legalisation is a big change so force a slack redistribution here
if (cfg.slack_redist_iter > 0 && cfg.budgetBased)
assign_budget(ctx, true /* quiet */);
}
require_legal = false;
} else if (cfg.budgetBased && cfg.slack_redist_iter > 0 && iter % cfg.slack_redist_iter == 0) {
assign_budget(ctx, true /* quiet */);
}
// Invoke timing analysis to obtain criticalities
if (!cfg.budgetBased && cfg.timing_driven)
if (cfg.timing_driven)
tmg.run();
// Need to rebuild costs after criticalities change
setup_costs();
@ -870,15 +861,11 @@ class SAPlacer
return 0;
if (ctx->getPortTimingClass(net->driver.cell, net->driver.port, cc) == TMG_IGNORE)
return 0;
if (cfg.budgetBased) {
double delay = ctx->getDelayNS(ctx->predictArcDelay(net, user));
return std::min(10.0, std::exp(delay - ctx->getDelayNS(user.budget) / 10));
} else {
float crit = tmg.get_criticality(CellPortKey(user));
double delay = ctx->getDelayNS(ctx->predictArcDelay(net, user));
return delay * std::pow(crit, crit_exp);
}
}
// Set up the cost maps
void setup_costs()
@ -1267,7 +1254,6 @@ Placer1Cfg::Placer1Cfg(Context *ctx)
constraintWeight = ctx->setting<float>("placer1/constraintWeight", 10);
netShareWeight = ctx->setting<float>("placer1/netShareWeight", 0);
minBelsForGridPick = ctx->setting<int>("placer1/minBelsForGridPick", 64);
budgetBased = ctx->setting<bool>("placer1/budgetBased", false);
startTemp = ctx->setting<float>("placer1/startTemp", 1);
timingFanoutThresh = std::numeric_limits<int>::max();
timing_driven = ctx->setting<bool>("timing_driven");

View File

@ -29,7 +29,6 @@ struct Placer1Cfg
Placer1Cfg(Context *ctx);
float constraintWeight, netShareWeight;
int minBelsForGridPick;
bool budgetBased;
float startTemp;
int timingFanoutThresh;
bool timing_driven;

View File

@ -730,7 +730,6 @@ struct Router1
log(" final route delay: %8.2f\n", ctx->getDelayNS(visited[dst_wire].delay));
log(" final route penalty: %8.2f\n", ctx->getDelayNS(visited[dst_wire].penalty));
log(" final route bonus: %8.2f\n", ctx->getDelayNS(visited[dst_wire].bonus));
log(" arc budget: %12.2f\n", ctx->getDelayNS(net_info->users[user_idx].budget));
}
// bind resulting route (and maybe unroute other nets)

View File

@ -545,12 +545,6 @@ Convert a real-world delay in nanoseconds to a `delay_t`.
Convert a `delay_t` to an integer for checksum calculations.
### bool getBudgetOverride(const NetInfo \*net\_info, const PortRef &sink, delay\_t &budget) const
Overwrite or modify (in-place) the timing budget for a given arc. Returns a bool to indicate whether this was done.
*BaseArch default: returns false*
### bool getArcDelayOverride(const NetInfo \*net_info, const PortRef &sink, DelayQuad &delay) const
This allows an arch to provide a more precise method for calculating the delay for a routed arc than
@ -763,5 +757,3 @@ Returns `true` if the cell **must** be placed according to the cluster; for exam
Gets an exact placement of the cluster, with the root cell placed on or near `root_bel` (and always within the same tile). Returns false if no placement is viable, otherwise returns `true` and populates `placement` with a list of cells inside the cluster and bels they should be placed at.
This approach of allowing architectures to define cluster placements enables easier handling of irregular fabrics than requiring strict and constant x, y and z offsets.

View File

@ -78,7 +78,6 @@ Placers might want to create their own indices of bels (for example, bels by typ
As nextpnr allows arbitrary constraints on bels for more advanced packer-free flows and complex real-world architectures; placements must be checked for legality using `isBelLocationValid` (after placement) and the placement rejected if invalid. For analytical placement algorithms; after creating a spread-out AP solution the legality of placing each cell needs to be checked. In practice, the cost of this is fairly low as the architecture should ensure these functions are as fast as possible.
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 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` and its derivative `predictArcDelay` returns an estimated delay for a sink port based on placement information
@ -98,4 +97,3 @@ together, see the "cellGroups" field.
The job of the router is to ensure that the `wires` map for each net contains a complete routing tree; populated using the Arch functions to bind wires and pips. The ripup invariants in the [FAQ](faq.md) are important to bear in mind; as there may be complex constraints on the usage of wires and pips in some architectures.
`estimateDelay` is intended for use as an A* metric to guide routing.

View File

@ -38,7 +38,6 @@ There is a dictionary `ctx.nets` that provides access to all of the nets in a de
A `PortRef` has three fields:
- `cell`: a reference to the cell the port is on
- `port`: the name of the port
- `budget`: the timing budget of the port
### Accessing cells
@ -84,4 +83,3 @@ The value given to `setParam` and `setAttr` should be a string of `[01xz]*` for
## Constraints
See the [constraints documentation](constraints.md)

View File

@ -582,19 +582,6 @@ delay_t Arch::predictDelay(BelId src_bel, IdString src_pin, BelId dst_bel, IdStr
(3 + std::max(dx - 5, 0) + std::max(dy - 5, 0) + 2 * (std::min(dx, 5) + std::min(dy, 5)));
}
bool Arch::getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay_t &budget) const
{
if (net_info->driver.port == id_FCO && sink.port == id_FCI) {
budget = 0;
return true;
} else if (sink.port.in(id_FXA, id_FXB)) {
budget = 0;
return true;
} else {
return false;
}
}
delay_t Arch::getRipupDelayPenalty() const { return 400; }
// -----------------------------------------------------------------------
@ -653,7 +640,6 @@ bool Arch::route()
setup_wire_locations();
route_ecp5_globals(getCtx());
assignArchInfo();
assign_budget(getCtx(), true);
bool result;
if (router == "router1") {

View File

@ -975,7 +975,6 @@ struct Arch : BaseArch<ArchRanges>
float getDelayNS(delay_t v) const override { return v * 0.001; }
delay_t getDelayFromNS(float ns) const override { return delay_t(ns * 1000); }
uint32_t getDelayChecksum(delay_t v) const override { return v; }
bool getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay_t &budget) const override;
// -------------------------------------------------

View File

@ -763,8 +763,6 @@ BoundingBox Arch::getRouteBoundingBox(WireId src, WireId dst) const
return {x0, y0, x1, y1};
}
bool Arch::getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay_t &budget) const { return false; }
// -----------------------------------------------------------------------
bool Arch::pack()

View File

@ -707,7 +707,6 @@ struct Arch : ArchAPI<ArchRanges>
float getDelayNS(delay_t v) const final { return v * 0.001; }
delay_t getDelayFromNS(float ns) const final { return delay_t(ns * 1000); }
uint32_t getDelayChecksum(delay_t v) const final { return v; }
bool getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay_t &budget) const final;
bool getArcDelayOverride(const NetInfo *net_info, const PortRef &sink, DelayQuad &delay) const final
{

View File

@ -561,8 +561,6 @@ delay_t Arch::predictDelay(BelId src_bel, IdString src_pin, BelId dst_bel, IdStr
return (dx + dy) * args.delayScale + args.delayOffset;
}
bool Arch::getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay_t &budget) const { return false; }
BoundingBox Arch::getRouteBoundingBox(WireId src, WireId dst) const
{
if (uarch)

View File

@ -323,7 +323,6 @@ struct Arch : BaseArch<ArchRanges>
delay_t getDelayFromNS(float ns) const override { return ns; }
uint32_t getDelayChecksum(delay_t v) const override { return 0; }
bool getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay_t &budget) const override;
BoundingBox getRouteBoundingBox(WireId src, WireId dst) const override;

View File

@ -2150,8 +2150,6 @@ delay_t Arch::predictDelay(BelId src_bel, IdString src_pin, BelId dst_bel, IdStr
return (dx + dy) * args.delayScale + args.delayOffset;
}
bool Arch::getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay_t &budget) const { return false; }
BoundingBox Arch::getRouteBoundingBox(WireId src, WireId dst) const
{
BoundingBox bb;

View File

@ -456,7 +456,6 @@ struct Arch : BaseArch<ArchRanges>
delay_t getDelayFromNS(float ns) const override { return ns; }
uint32_t getDelayChecksum(delay_t v) const override { return 0; }
bool getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay_t &budget) const override;
BoundingBox getRouteBoundingBox(WireId src, WireId dst) const override;

View File

@ -91,7 +91,6 @@ BaseMainWindow::BaseMainWindow(std::unique_ptr<Context> context, CommandHandler
// Connect Worker
connect(task, &TaskManager::log, this, &BaseMainWindow::writeInfo);
connect(task, &TaskManager::pack_finished, this, &BaseMainWindow::pack_finished);
connect(task, &TaskManager::budget_finish, this, &BaseMainWindow::budget_finish);
connect(task, &TaskManager::place_finished, this, &BaseMainWindow::place_finished);
connect(task, &TaskManager::route_finished, this, &BaseMainWindow::route_finished);
connect(task, &TaskManager::taskCanceled, this, &BaseMainWindow::taskCanceled);
@ -178,12 +177,6 @@ void BaseMainWindow::createMenusAndBars()
actionPack->setEnabled(false);
connect(actionPack, &QAction::triggered, task, &TaskManager::pack);
actionAssignBudget = new QAction("Assign Budget", this);
actionAssignBudget->setIcon(QIcon(":/icons/resources/time_add.png"));
actionAssignBudget->setStatusTip("Assign timing budget for current design");
actionAssignBudget->setEnabled(false);
connect(actionAssignBudget, &QAction::triggered, this, &BaseMainWindow::budget);
actionPlace = new QAction("Place", this);
actionPlace->setIcon(QIcon(":/icons/resources/place.png"));
actionPlace->setStatusTip("Place current design");
@ -307,7 +300,6 @@ void BaseMainWindow::createMenusAndBars()
// Add Design menu actions
menuDesign->addAction(actionPack);
menuDesign->addAction(actionAssignBudget);
menuDesign->addAction(actionPlace);
menuDesign->addAction(actionRoute);
menuDesign->addSeparator();
@ -324,7 +316,6 @@ void BaseMainWindow::createMenusAndBars()
mainActionBar->addAction(actionSaveJSON);
mainActionBar->addSeparator();
mainActionBar->addAction(actionPack);
mainActionBar->addAction(actionAssignBudget);
mainActionBar->addAction(actionPlace);
mainActionBar->addAction(actionRoute);
mainActionBar->addAction(actionExecutePy);
@ -471,17 +462,6 @@ void BaseMainWindow::pack_finished(bool status)
}
}
void BaseMainWindow::budget_finish(bool status)
{
disableActions();
if (status) {
log("Assigning timing budget successful.\n");
updateActions();
} else {
log("Assigning timing budget failed.\n");
}
}
void BaseMainWindow::place_finished(bool status)
{
disableActions();
@ -524,24 +504,12 @@ void BaseMainWindow::taskPaused()
actionStop->setEnabled(true);
}
void BaseMainWindow::budget()
{
bool ok;
double freq = QInputDialog::getDouble(this, "Assign timing budget", "Frequency [MHz]:", 50, 0, 250, 2, &ok);
if (ok) {
freq *= 1e6;
timing_driven = true;
Q_EMIT task->budget(freq);
}
}
void BaseMainWindow::place() { Q_EMIT task->place(timing_driven); }
void BaseMainWindow::disableActions()
{
actionLoadJSON->setEnabled(true);
actionPack->setEnabled(false);
actionAssignBudget->setEnabled(false);
actionPlace->setEnabled(false);
actionRoute->setEnabled(false);
@ -559,7 +527,6 @@ void BaseMainWindow::updateActions()
if (ctx->settings.find(ctx->id("pack")) == ctx->settings.end())
actionPack->setEnabled(true);
else if (ctx->settings.find(ctx->id("place")) == ctx->settings.end()) {
actionAssignBudget->setEnabled(true);
actionPlace->setEnabled(true);
} else if (ctx->settings.find(ctx->id("route")) == ctx->settings.end())
actionRoute->setEnabled(true);

View File

@ -69,13 +69,11 @@ class BaseMainWindow : public QMainWindow
void open_json();
void save_json();
void budget();
void place();
void execute_python();
void pack_finished(bool status);
void budget_finish(bool status);
void place_finished(bool status);
void route_finished(bool status);
@ -120,7 +118,6 @@ class BaseMainWindow : public QMainWindow
QAction *actionSaveJSON;
QAction *actionPack;
QAction *actionAssignBudget;
QAction *actionPlace;
QAction *actionRoute;

View File

@ -751,7 +751,6 @@ void DesignWidget::onSelectionChanged(int num, const QItemSelection &, const QIt
QtProperty *driverItem = addSubGroup(topItem, "Driver");
addProperty(driverItem, QVariant::String, "Port", net->driver.port.c_str(ctx));
addProperty(driverItem, QVariant::Double, "Budget", net->driver.budget);
if (net->driver.cell)
addProperty(driverItem, QVariant::String, "Cell", net->driver.cell->name.c_str(ctx), ElementType::CELL);
else
@ -762,7 +761,6 @@ void DesignWidget::onSelectionChanged(int num, const QItemSelection &, const QIt
QtProperty *portItem = addSubGroup(usersItem, item.port.c_str(ctx));
addProperty(portItem, QVariant::String, "Port", item.port.c_str(ctx));
addProperty(portItem, QVariant::Double, "Budget", item.budget);
if (item.cell)
addProperty(portItem, QVariant::String, "Cell", item.cell->name.c_str(ctx), ElementType::CELL);
else

View File

@ -74,9 +74,6 @@ void MainWindow::createMenu()
menuDesign->addSeparator();
menuDesign->addAction(actionLoadCST);
// XXX
actionAssignBudget->setEnabled(false);
}
void MainWindow::new_proj() {}
@ -102,7 +99,5 @@ void MainWindow::onUpdateActions()
if (ctx->settings.find(ctx->id("pack")) != ctx->settings.end()) {
actionLoadCST->setEnabled(false);
}
// XXX
actionAssignBudget->setEnabled(false);
}
NEXTPNR_NAMESPACE_END

View File

@ -64,18 +64,6 @@ void Worker::pack()
}
}
void Worker::budget(double freq)
{
Q_EMIT taskStarted();
try {
ctx->settings[ctx->id("target_freq")] = std::to_string(freq);
assign_budget(ctx);
Q_EMIT budget_finish(true);
} catch (WorkerInterruptionRequested) {
Q_EMIT taskCanceled();
}
}
void Worker::place(bool timing_driven)
{
Q_EMIT taskStarted();
@ -105,7 +93,6 @@ TaskManager::TaskManager() : toTerminate(false), toPause(false)
connect(&workerThread, &QThread::finished, worker, &QObject::deleteLater);
connect(this, &TaskManager::pack, worker, &Worker::pack);
connect(this, &TaskManager::budget, worker, &Worker::budget);
connect(this, &TaskManager::place, worker, &Worker::place);
connect(this, &TaskManager::route, worker, &Worker::route);
@ -113,7 +100,6 @@ TaskManager::TaskManager() : toTerminate(false), toPause(false)
connect(worker, &Worker::log, this, &TaskManager::info);
connect(worker, &Worker::pack_finished, this, &TaskManager::pack_finished);
connect(worker, &Worker::budget_finish, this, &TaskManager::budget_finish);
connect(worker, &Worker::place_finished, this, &TaskManager::place_finished);
connect(worker, &Worker::route_finished, this, &TaskManager::route_finished);

View File

@ -36,13 +36,11 @@ class Worker : public QObject
public Q_SLOTS:
void newContext(Context *);
void pack();
void budget(double freq);
void place(bool timing_driven);
void route();
Q_SIGNALS:
void log(const std::string &text);
void pack_finished(bool status);
void budget_finish(bool status);
void place_finished(bool status);
void route_finished(bool status);
void taskCanceled();
@ -73,14 +71,12 @@ class TaskManager : public QObject
void contextChanged(Context *ctx);
void terminate();
void pack();
void budget(double freq);
void place(bool timing_driven);
void route();
// redirected signals
void log(const std::string &text);
void pack_finished(bool status);
void budget_finish(bool status);
void place_finished(bool status);
void route_finished(bool status);
void taskCanceled();

View File

@ -568,10 +568,6 @@ struct Arch : BaseArch<ArchRanges>
float getDelayNS(delay_t v) const override { return v * 0.001; }
delay_t getDelayFromNS(float ns) const override { return delay_t(ns * 1000); }
uint32_t getDelayChecksum(delay_t v) const override { return v; }
bool getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay_t &budget) const override
{
return false;
}
BoundingBox getRouteBoundingBox(WireId src, WireId dst) const override
{
return uarch->getRouteBoundingBox(src, dst);

View File

@ -639,47 +639,6 @@ std::vector<GroupId> Arch::getGroupGroups(GroupId group) const
// -----------------------------------------------------------------------
bool Arch::getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay_t &budget) const
{
const auto &driver = net_info->driver;
if (driver.port == id_COUT) {
NPNR_ASSERT(sink.port.in(id_CIN, id_I3));
NPNR_ASSERT(driver.cell->constr_abs_z);
bool cin = sink.port == id_CIN;
bool same_y = driver.cell->constr_z < 7;
if (cin && same_y)
budget = 0;
else {
switch (args.type) {
case ArchArgs::HX8K:
case ArchArgs::HX4K:
case ArchArgs::HX1K:
budget = cin ? 190 : (same_y ? 260 : 560);
break;
case ArchArgs::LP384:
case ArchArgs::LP1K:
case ArchArgs::LP4K:
case ArchArgs::LP8K:
budget = cin ? 290 : (same_y ? 380 : 670);
break;
case ArchArgs::UP3K:
case ArchArgs::UP5K:
case ArchArgs::U1K:
case ArchArgs::U2K:
case ArchArgs::U4K:
budget = cin ? 560 : (same_y ? 660 : 1220);
break;
default:
log_error("Unsupported iCE40 chip type.\n");
}
}
return true;
}
return false;
}
// -----------------------------------------------------------------------
bool Arch::place()
{
std::string placer = str_or_default(settings, id_placer, defaultPlacer);

View File

@ -800,7 +800,6 @@ struct Arch : BaseArch<ArchRanges>
float getDelayNS(delay_t v) const override { return v * 0.001; }
delay_t getDelayFromNS(float ns) const override { return delay_t(ns * 1000); }
uint32_t getDelayChecksum(delay_t v) const override { return v; }
bool getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay_t &budget) const override;
BoundingBox getRouteBoundingBox(WireId src, WireId dst) const override;

View File

@ -903,7 +903,6 @@ struct Arch : BaseArch<ArchRanges>
float getDelayNS(delay_t v) const override { return v; }
delay_t getDelayFromNS(float ns) const override { return ns; }
uint32_t getDelayChecksum(delay_t v) const override { return v; }
// bool getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay_t &budget) const override;
// -------------------------------------------------

View File

@ -484,8 +484,6 @@ bool Arch::place()
bool Arch::route()
{
assign_budget(getCtx(), true);
lab_pre_route();
route_globals();

View File

@ -700,8 +700,6 @@ delay_t Arch::predictDelay(BelId src_bel, IdString src_pin, BelId dst_bel, IdStr
return 100 * dist_x + 100 * dist_y + 250;
}
bool Arch::getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay_t &budget) const { return false; }
BoundingBox Arch::getRouteBoundingBox(WireId src, WireId dst) const
{
BoundingBox bb;
@ -811,8 +809,6 @@ float router2_base_cost(Context *ctx, WireId wire, PipId pip, float crit_weight)
bool Arch::route()
{
assign_budget(getCtx(), true);
pre_routing();
route_globals();

View File

@ -1299,7 +1299,6 @@ struct Arch : BaseArch<ArchRanges>
float getDelayNS(delay_t v) const override { return v * 0.001; }
delay_t getDelayFromNS(float ns) const override { return delay_t(ns * 1000); }
uint32_t getDelayChecksum(delay_t v) const override { return v; }
bool getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay_t &budget) const override;
BoundingBox getRouteBoundingBox(WireId src, WireId dst) const override;
// for better DSP bounding boxes