From 914999673cfb1d03f1751523c1381bd07d8cd5c4 Mon Sep 17 00:00:00 2001 From: rowanG077 Date: Thu, 11 May 2023 11:23:32 +0200 Subject: [PATCH] Rip out budgets --- common/kernel/arch_api.h | 1 - common/kernel/base_arch.h | 4 -- common/kernel/command.cc | 5 --- common/kernel/context.cc | 2 - common/kernel/nextpnr_types.h | 5 --- common/kernel/pybindings.cc | 2 - common/kernel/report.cc | 6 +-- common/kernel/timing.cc | 85 ++++------------------------------- common/kernel/timing.h | 4 -- common/place/place_common.cc | 2 +- common/place/placer1.cc | 26 +++-------- common/place/placer1.h | 1 - common/route/router1.cc | 1 - docs/archapi.md | 8 ---- docs/coding.md | 2 - docs/python.md | 2 - ecp5/arch.cc | 14 ------ ecp5/arch.h | 1 - fpga_interchange/arch.cc | 2 - fpga_interchange/arch.h | 1 - generic/arch.cc | 2 - generic/arch.h | 1 - gowin/arch.cc | 2 - gowin/arch.h | 1 - gui/basewindow.cc | 33 -------------- gui/basewindow.h | 3 -- gui/designwidget.cc | 2 - gui/gowin/mainwindow.cc | 5 --- gui/worker.cc | 14 ------ gui/worker.h | 4 -- himbaechel/arch.h | 4 -- ice40/arch.cc | 41 ----------------- ice40/arch.h | 1 - machxo2/arch.h | 1 - mistral/arch.cc | 2 - nexus/arch.cc | 4 -- nexus/arch.h | 1 - 37 files changed, 16 insertions(+), 279 deletions(-) diff --git a/common/kernel/arch_api.h b/common/kernel/arch_api.h index c2de19e6..0bfaaf2d 100644 --- a/common/kernel/arch_api.h +++ b/common/kernel/arch_api.h @@ -116,7 +116,6 @@ template 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; diff --git a/common/kernel/base_arch.h b/common/kernel/base_arch.h index 4da94989..a27e261d 100644 --- a/common/kernel/base_arch.h +++ b/common/kernel/base_arch.h @@ -313,10 +313,6 @@ template struct BaseArch : ArchAPI }; // 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; diff --git a/common/kernel/command.cc b/common/kernel/command.cc index 4619c00e..6e94b300 100644 --- a/common/kernel/command.cc +++ b/common/kernel/command.cc @@ -171,7 +171,6 @@ po::options_description CommandHandler::getGeneralOptions() general.add_options()("slack_redist_iter", po::value(), "number of iterations between slack redistribution"); general.add_options()("cstrweight", po::value(), "placer weighting for relative constraint satisfaction"); general.add_options()("starttemp", po::value(), "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()); } - if (vm.count("placer-budgets")) { - ctx->settings[ctx->id("placer1/budgetBased")] = true; - } if (vm.count("freq")) { auto freq = vm["freq"].as(); if (freq > 0) @@ -457,7 +453,6 @@ int CommandHandler::executeMain(std::unique_ptr ctx) if (!ctx->pack() && !ctx->force) log_error("Packing design failed.\n"); } - assign_budget(ctx.get()); ctx->check(); print_utilisation(ctx.get()); diff --git a/common/kernel/context.cc b/common/kernel/context.cc index 7048be59..b194675d 100644 --- a/common/kernel/context.cc +++ b/common/kernel/context.cc @@ -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; diff --git a/common/kernel/nextpnr_types.h b/common/kernel/nextpnr_types.h index 2a9062fd..b7f1e0b0 100644 --- a/common/kernel/nextpnr_types.h +++ b/common/kernel/nextpnr_types.h @@ -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 to; // Segment delay delay_t delay; - // Segment budget (routing only) - delay_t budget; }; // Clock pair @@ -349,8 +346,6 @@ struct NetSinkTiming std::pair cell_port; // Delay delay_t delay; - // Delay budget - delay_t budget; }; struct TimingResult diff --git a/common/kernel/pybindings.cc b/common/kernel/pybindings.cc index f738f081..cea9a8be 100644 --- a/common/kernel/pybindings.cc +++ b/common/kernel/pybindings.cc @@ -239,8 +239,6 @@ PYBIND11_EMBEDDED_MODULE(MODULE_NAME, m) "cell"); readonly_wrapper>::def_wrap(pr_cls, "port"); - readonly_wrapper>::def_wrap(pr_cls, - "budget"); auto pm_cls = py::class_>(m, "PipMap"); readwrite_wrapper, diff --git a/common/kernel/report.cc b/common/kernel/report.cc index 8f583b33..38cf9d0a 100644 --- a/common/kernel/report.cc +++ b/common/kernel/report.cc @@ -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": , "net": , "delay": , - "budget": , } ... ] @@ -213,7 +210,6 @@ Report JSON structure: "port": , "event": , "delay": , - "budget": , } ... ] diff --git a/common/kernel/timing.cc b/common/kernel/timing.cc index df159c79..6a6ac2c1 100644 --- a/common/kernel/timing.cc +++ b/common/kernel/timing.cc @@ -36,7 +36,7 @@ std::string clock_event_name(const Context *ctx, ClockDomainKey &dom) { value = ""; else value = (dom.edge == FALLING_EDGE ? "negedge " : "posedge ") + dom.clock.str(ctx); - + return value; } } // namespace @@ -501,7 +501,6 @@ void TimingAnalyser::reset_times() dp.second.hold_slack = std::numeric_limits::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::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,12 +1071,8 @@ 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); - } + auto &path_length = data.max_path_length; + path_length = std::max(path_length, net_length_plus_one); } } } @@ -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::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("target_freq") / 1e6); - } - - Timing timing(ctx, ctx->setting("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("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("auto_freq") && ctx->setting("slack_redist_iter") > 0) { - delay_t default_slack = delay_t((1.0e9 / ctx->getDelayNS(1)) / ctx->setting("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("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 diff --git a/common/kernel/timing.h b/common/kernel/timing.h index 3f47fd6e..8b85af33 100644 --- a/common/kernel/timing.h +++ b/common/kernel/timing.h @@ -143,7 +143,6 @@ struct TimingAnalyser struct PortDomainPairData { delay_t setup_slack = std::numeric_limits::max(), hold_slack = std::numeric_limits::max(); - delay_t budget = std::numeric_limits::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, diff --git a/common/place/place_common.cc b/common/place/place_common.cc index c2fc3b7d..8218b9fe 100644 --- a/common/place/place_common.cc +++ b/common/place/place_common.cc @@ -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); diff --git a/common/place/placer1.cc b/common/place/placer1.cc index e37d3daf..df52471b 100644 --- a/common/place/placer1.cc +++ b/common/place/placer1.cc @@ -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,8 +238,7 @@ class SAPlacer // Invoke timing analysis to obtain criticalities tmg.setup_only = true; - if (!cfg.budgetBased) - tmg.setup(); + tmg.setup(); // Calculate costs after initial placement setup_costs(); @@ -368,18 +365,12 @@ class SAPlacer // temp = post_legalise_temp; // diameter = std::min(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,14 +861,10 @@ 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); - } + + 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 @@ -1267,7 +1254,6 @@ Placer1Cfg::Placer1Cfg(Context *ctx) constraintWeight = ctx->setting("placer1/constraintWeight", 10); netShareWeight = ctx->setting("placer1/netShareWeight", 0); minBelsForGridPick = ctx->setting("placer1/minBelsForGridPick", 64); - budgetBased = ctx->setting("placer1/budgetBased", false); startTemp = ctx->setting("placer1/startTemp", 1); timingFanoutThresh = std::numeric_limits::max(); timing_driven = ctx->setting("timing_driven"); diff --git a/common/place/placer1.h b/common/place/placer1.h index 9dfb0b0d..7b65a1a5 100644 --- a/common/place/placer1.h +++ b/common/place/placer1.h @@ -29,7 +29,6 @@ struct Placer1Cfg Placer1Cfg(Context *ctx); float constraintWeight, netShareWeight; int minBelsForGridPick; - bool budgetBased; float startTemp; int timingFanoutThresh; bool timing_driven; diff --git a/common/route/router1.cc b/common/route/router1.cc index 0f1f0fcf..e4b29372 100644 --- a/common/route/router1.cc +++ b/common/route/router1.cc @@ -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) diff --git a/docs/archapi.md b/docs/archapi.md index 062bd946..cde69a15 100644 --- a/docs/archapi.md +++ b/docs/archapi.md @@ -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. - - diff --git a/docs/coding.md b/docs/coding.md index e25165ae..4f4c098b 100644 --- a/docs/coding.md +++ b/docs/coding.md @@ -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. - diff --git a/docs/python.md b/docs/python.md index d850300d..ea3eb9c4 100644 --- a/docs/python.md +++ b/docs/python.md @@ -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) - diff --git a/ecp5/arch.cc b/ecp5/arch.cc index 11429eb4..a0b2644c 100644 --- a/ecp5/arch.cc +++ b/ecp5/arch.cc @@ -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") { diff --git a/ecp5/arch.h b/ecp5/arch.h index 56ba3e7b..9b1061ee 100644 --- a/ecp5/arch.h +++ b/ecp5/arch.h @@ -975,7 +975,6 @@ struct Arch : BaseArch 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; // ------------------------------------------------- diff --git a/fpga_interchange/arch.cc b/fpga_interchange/arch.cc index 5af07f04..bf7e9ff1 100644 --- a/fpga_interchange/arch.cc +++ b/fpga_interchange/arch.cc @@ -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() diff --git a/fpga_interchange/arch.h b/fpga_interchange/arch.h index 74473e63..caabe6a3 100644 --- a/fpga_interchange/arch.h +++ b/fpga_interchange/arch.h @@ -707,7 +707,6 @@ struct Arch : ArchAPI 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 { diff --git a/generic/arch.cc b/generic/arch.cc index 238fb9fc..91be118a 100644 --- a/generic/arch.cc +++ b/generic/arch.cc @@ -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) diff --git a/generic/arch.h b/generic/arch.h index 40994ad0..f4977e1e 100644 --- a/generic/arch.h +++ b/generic/arch.h @@ -323,7 +323,6 @@ struct Arch : BaseArch 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; diff --git a/gowin/arch.cc b/gowin/arch.cc index 4a50a2cb..b69c6afc 100644 --- a/gowin/arch.cc +++ b/gowin/arch.cc @@ -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; diff --git a/gowin/arch.h b/gowin/arch.h index ff8905ac..ee687c26 100644 --- a/gowin/arch.h +++ b/gowin/arch.h @@ -456,7 +456,6 @@ struct Arch : BaseArch 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; diff --git a/gui/basewindow.cc b/gui/basewindow.cc index 2ebbe2b9..4ea88a13 100644 --- a/gui/basewindow.cc +++ b/gui/basewindow.cc @@ -91,7 +91,6 @@ BaseMainWindow::BaseMainWindow(std::unique_ptr 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); diff --git a/gui/basewindow.h b/gui/basewindow.h index 4e3cdcb8..053bb8e6 100644 --- a/gui/basewindow.h +++ b/gui/basewindow.h @@ -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; diff --git a/gui/designwidget.cc b/gui/designwidget.cc index 57591bbf..fb9086dd 100644 --- a/gui/designwidget.cc +++ b/gui/designwidget.cc @@ -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 diff --git a/gui/gowin/mainwindow.cc b/gui/gowin/mainwindow.cc index 8593bb4b..c7ba44ab 100644 --- a/gui/gowin/mainwindow.cc +++ b/gui/gowin/mainwindow.cc @@ -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 diff --git a/gui/worker.cc b/gui/worker.cc index dacd9e61..c71bddd3 100644 --- a/gui/worker.cc +++ b/gui/worker.cc @@ -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); diff --git a/gui/worker.h b/gui/worker.h index 176fc28a..bb78772a 100644 --- a/gui/worker.h +++ b/gui/worker.h @@ -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(); diff --git a/himbaechel/arch.h b/himbaechel/arch.h index e5a45418..9a664b17 100644 --- a/himbaechel/arch.h +++ b/himbaechel/arch.h @@ -568,10 +568,6 @@ struct Arch : BaseArch 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); diff --git a/ice40/arch.cc b/ice40/arch.cc index e977008a..28791b95 100644 --- a/ice40/arch.cc +++ b/ice40/arch.cc @@ -639,47 +639,6 @@ std::vector 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); diff --git a/ice40/arch.h b/ice40/arch.h index d80d6f64..e1009ddc 100644 --- a/ice40/arch.h +++ b/ice40/arch.h @@ -800,7 +800,6 @@ struct Arch : BaseArch 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; diff --git a/machxo2/arch.h b/machxo2/arch.h index 855b39df..4792c79d 100644 --- a/machxo2/arch.h +++ b/machxo2/arch.h @@ -903,7 +903,6 @@ struct Arch : BaseArch 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; // ------------------------------------------------- diff --git a/mistral/arch.cc b/mistral/arch.cc index 7b8adfd4..9dd2e81b 100644 --- a/mistral/arch.cc +++ b/mistral/arch.cc @@ -484,8 +484,6 @@ bool Arch::place() bool Arch::route() { - assign_budget(getCtx(), true); - lab_pre_route(); route_globals(); diff --git a/nexus/arch.cc b/nexus/arch.cc index 4818906d..e6ff2e13 100644 --- a/nexus/arch.cc +++ b/nexus/arch.cc @@ -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(); diff --git a/nexus/arch.h b/nexus/arch.h index eb3059a5..2cb8c08e 100644 --- a/nexus/arch.h +++ b/nexus/arch.h @@ -1299,7 +1299,6 @@ struct Arch : BaseArch 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