Merge pull request #391 from YosysHQ/router2-upstream
Upstreaming router2
This commit is contained in:
commit
1ceffbe0bc
@ -132,6 +132,12 @@ po::options_description CommandHandler::getGeneralOptions()
|
|||||||
"; default: " + Arch::defaultPlacer)
|
"; default: " + Arch::defaultPlacer)
|
||||||
.c_str());
|
.c_str());
|
||||||
|
|
||||||
|
general.add_options()(
|
||||||
|
"router", po::value<std::string>(),
|
||||||
|
std::string("router algorithm to use; available: " + boost::algorithm::join(Arch::availableRouters, ", ") +
|
||||||
|
"; default: " + Arch::defaultPlacer)
|
||||||
|
.c_str());
|
||||||
|
|
||||||
general.add_options()("slack_redist_iter", po::value<int>(), "number of iterations between slack redistribution");
|
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()("cstrweight", po::value<float>(), "placer weighting for relative constraint satisfaction");
|
||||||
general.add_options()("starttemp", po::value<float>(), "placer SA start temperature");
|
general.add_options()("starttemp", po::value<float>(), "placer SA start temperature");
|
||||||
@ -214,6 +220,15 @@ void CommandHandler::setupContext(Context *ctx)
|
|||||||
ctx->settings[ctx->id("placer")] = placer;
|
ctx->settings[ctx->id("placer")] = placer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (vm.count("router")) {
|
||||||
|
std::string router = vm["router"].as<std::string>();
|
||||||
|
if (std::find(Arch::availableRouters.begin(), Arch::availableRouters.end(), router) ==
|
||||||
|
Arch::availableRouters.end())
|
||||||
|
log_error("Router algorithm '%s' is not supported (available options: %s)\n", router.c_str(),
|
||||||
|
boost::algorithm::join(Arch::availableRouters, ", ").c_str());
|
||||||
|
ctx->settings[ctx->id("router")] = router;
|
||||||
|
}
|
||||||
|
|
||||||
if (vm.count("cstrweight")) {
|
if (vm.count("cstrweight")) {
|
||||||
ctx->settings[ctx->id("placer1/constraintWeight")] = std::to_string(vm["cstrweight"].as<float>());
|
ctx->settings[ctx->id("placer1/constraintWeight")] = std::to_string(vm["cstrweight"].as<float>());
|
||||||
}
|
}
|
||||||
@ -244,6 +259,8 @@ void CommandHandler::setupContext(Context *ctx)
|
|||||||
ctx->settings[ctx->id("auto_freq")] = false;
|
ctx->settings[ctx->id("auto_freq")] = false;
|
||||||
if (ctx->settings.find(ctx->id("placer")) == ctx->settings.end())
|
if (ctx->settings.find(ctx->id("placer")) == ctx->settings.end())
|
||||||
ctx->settings[ctx->id("placer")] = Arch::defaultPlacer;
|
ctx->settings[ctx->id("placer")] = Arch::defaultPlacer;
|
||||||
|
if (ctx->settings.find(ctx->id("router")) == ctx->settings.end())
|
||||||
|
ctx->settings[ctx->id("router")] = Arch::defaultRouter;
|
||||||
|
|
||||||
ctx->settings[ctx->id("arch.name")] = std::string(ctx->archId().c_str(ctx));
|
ctx->settings[ctx->id("arch.name")] = std::string(ctx->archId().c_str(ctx));
|
||||||
ctx->settings[ctx->id("arch.type")] = std::string(ctx->archArgsToId(ctx->archArgs()).c_str(ctx));
|
ctx->settings[ctx->id("arch.type")] = std::string(ctx->archArgsToId(ctx->archArgs()).c_str(ctx));
|
||||||
|
@ -199,6 +199,28 @@ struct Loc
|
|||||||
bool operator!=(const Loc &other) const { return (x != other.x) || (y != other.y) || (z != other.z); }
|
bool operator!=(const Loc &other) const { return (x != other.x) || (y != other.y) || (z != other.z); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ArcBounds
|
||||||
|
{
|
||||||
|
int x0 = -1, y0 = -1, x1 = -1, y1 = -1;
|
||||||
|
|
||||||
|
ArcBounds() {}
|
||||||
|
ArcBounds(int x0, int y0, int x1, int y1) : x0(x0), y0(y0), x1(x1), y1(y1){};
|
||||||
|
|
||||||
|
int distance(Loc loc) const
|
||||||
|
{
|
||||||
|
int dist = 0;
|
||||||
|
if (loc.x < x0)
|
||||||
|
dist += x0 - loc.x;
|
||||||
|
if (loc.x > x1)
|
||||||
|
dist += loc.x - x1;
|
||||||
|
if (loc.y < y0)
|
||||||
|
dist += y0 - loc.y;
|
||||||
|
if (loc.y > y1)
|
||||||
|
dist += loc.y - y1;
|
||||||
|
return dist;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
struct TimingConstrObjectId
|
struct TimingConstrObjectId
|
||||||
{
|
{
|
||||||
int32_t index = -1;
|
int32_t index = -1;
|
||||||
|
@ -609,9 +609,10 @@ class SAPlacer
|
|||||||
std::vector<std::pair<CellInfo *, BelId>> dest_bels;
|
std::vector<std::pair<CellInfo *, BelId>> dest_bels;
|
||||||
double delta = 0;
|
double delta = 0;
|
||||||
moveChange.reset(this);
|
moveChange.reset(this);
|
||||||
|
#if 0
|
||||||
if (ctx->debug)
|
if (ctx->debug)
|
||||||
log_info("finding cells for chain swap %s\n", cell->name.c_str(ctx));
|
log_info("finding cells for chain swap %s\n", cell->name.c_str(ctx));
|
||||||
|
#endif
|
||||||
Loc baseLoc = ctx->getBelLocation(cell->bel);
|
Loc baseLoc = ctx->getBelLocation(cell->bel);
|
||||||
discover_chain(baseLoc, cell, cell_rel);
|
discover_chain(baseLoc, cell, cell_rel);
|
||||||
Loc newBaseLoc = ctx->getBelLocation(newBase);
|
Loc newBaseLoc = ctx->getBelLocation(newBase);
|
||||||
@ -634,8 +635,10 @@ class SAPlacer
|
|||||||
return false;
|
return false;
|
||||||
dest_bels.emplace_back(std::make_pair(cr.first, targetBel));
|
dest_bels.emplace_back(std::make_pair(cr.first, targetBel));
|
||||||
}
|
}
|
||||||
|
#if 0
|
||||||
if (ctx->debug)
|
if (ctx->debug)
|
||||||
log_info("trying chain swap %s\n", cell->name.c_str(ctx));
|
log_info("trying chain swap %s\n", cell->name.c_str(ctx));
|
||||||
|
#endif
|
||||||
// <cell, oldBel>
|
// <cell, oldBel>
|
||||||
for (const auto &db : dest_bels) {
|
for (const auto &db : dest_bels) {
|
||||||
BelId oldBel = swap_cell_bels(db.first, db.second);
|
BelId oldBel = swap_cell_bels(db.first, db.second);
|
||||||
@ -661,8 +664,10 @@ class SAPlacer
|
|||||||
// SA acceptance criterea
|
// SA acceptance criterea
|
||||||
if (delta < 0 || (temp > 1e-9 && (ctx->rng() / float(0x3fffffff)) <= std::exp(-delta / temp))) {
|
if (delta < 0 || (temp > 1e-9 && (ctx->rng() / float(0x3fffffff)) <= std::exp(-delta / temp))) {
|
||||||
n_accept++;
|
n_accept++;
|
||||||
|
#if 0
|
||||||
if (ctx->debug)
|
if (ctx->debug)
|
||||||
log_info("accepted chain swap %s\n", cell->name.c_str(ctx));
|
log_info("accepted chain swap %s\n", cell->name.c_str(ctx));
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
goto swap_fail;
|
goto swap_fail;
|
||||||
}
|
}
|
||||||
|
@ -837,7 +837,7 @@ bool router1(Context *ctx, const Router1Cfg &cfg)
|
|||||||
std::chrono::duration<float>(rend - rstart).count());
|
std::chrono::duration<float>(rend - rstart).count());
|
||||||
log_info("Routing complete.\n");
|
log_info("Routing complete.\n");
|
||||||
ctx->yield();
|
ctx->yield();
|
||||||
log_info("Route time %.02fs\n", std::chrono::duration<float>(rend - rstart).count());
|
log_info("Router1 time %.02fs\n", std::chrono::duration<float>(rend - rstart).count());
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
router.check();
|
router.check();
|
||||||
|
1132
common/router2.cc
Normal file
1132
common/router2.cc
Normal file
File diff suppressed because it is too large
Load Diff
56
common/router2.h
Normal file
56
common/router2.h
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* nextpnr -- Next Generation Place and Route
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 David Shah <dave@ds0.me>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "nextpnr.h"
|
||||||
|
|
||||||
|
NEXTPNR_NAMESPACE_BEGIN
|
||||||
|
|
||||||
|
struct Router2Cfg
|
||||||
|
{
|
||||||
|
Router2Cfg(Context *ctx);
|
||||||
|
|
||||||
|
// Maximum iterations for backwards routing attempt
|
||||||
|
int backwards_max_iter;
|
||||||
|
// Maximum iterations for backwards routing attempt for global nets
|
||||||
|
int global_backwards_max_iter;
|
||||||
|
// Padding added to bounding boxes to account for imperfect routing,
|
||||||
|
// congestion, etc
|
||||||
|
int bb_margin_x, bb_margin_y;
|
||||||
|
// Cost factor added to input pin wires; effectively reduces the
|
||||||
|
// benefit of sharing interconnect
|
||||||
|
float ipin_cost_adder;
|
||||||
|
// Cost factor for "bias" towards center location of net
|
||||||
|
float bias_cost_factor;
|
||||||
|
// Starting current and historical congestion cost factor
|
||||||
|
float init_curr_cong_weight, hist_cong_weight;
|
||||||
|
// Current congestion cost multiplier
|
||||||
|
float curr_cong_mult;
|
||||||
|
|
||||||
|
// Weight given to delay estimate in A*. Higher values
|
||||||
|
// mean faster and more directed routing, at the risk
|
||||||
|
// of choosing a less congestion/delay-optimal route
|
||||||
|
float estimate_weight;
|
||||||
|
|
||||||
|
// Print additional performance profiling information
|
||||||
|
bool perf_profile = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
void router2(Context *ctx, const Router2Cfg &cfg);
|
||||||
|
|
||||||
|
NEXTPNR_NAMESPACE_END
|
@ -237,6 +237,13 @@ Get a list of all wires on the device.
|
|||||||
|
|
||||||
Get a list of all bel pins attached to a given wire.
|
Get a list of all bel pins attached to a given wire.
|
||||||
|
|
||||||
|
### ArcBounds getRouteBoundingBox(WireId src, WireId dst) const
|
||||||
|
|
||||||
|
Get the bounding box required to route an arc, assuming an uncongested
|
||||||
|
chip. There may be significant performance impacts if routing regularly
|
||||||
|
exceeds these bounds by more than a small margin; so an over-estimate
|
||||||
|
of the bounds is almost always better than an under-estimate.
|
||||||
|
|
||||||
Pip Methods
|
Pip Methods
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
@ -500,4 +507,14 @@ Name of the default placement algorithm for the architecture, if
|
|||||||
### static const std::vector\<std::string\> availablePlacers
|
### static const std::vector\<std::string\> availablePlacers
|
||||||
|
|
||||||
Name of available placer algorithms for the architecture, used
|
Name of available placer algorithms for the architecture, used
|
||||||
to provide help for and validate `--placer`.
|
to provide help for and validate `--placer`.
|
||||||
|
|
||||||
|
### static const std::string defaultRouter
|
||||||
|
|
||||||
|
Name of the default router algorithm for the architecture, if
|
||||||
|
`--router` isn't specified on the command line.
|
||||||
|
|
||||||
|
### static const std::vector\<std::string\> availableRouters
|
||||||
|
|
||||||
|
Name of available router algorithms for the architecture, used
|
||||||
|
to provide help for and validate `--router`.
|
68
ecp5/arch.cc
68
ecp5/arch.cc
@ -30,6 +30,7 @@
|
|||||||
#include "placer1.h"
|
#include "placer1.h"
|
||||||
#include "placer_heap.h"
|
#include "placer_heap.h"
|
||||||
#include "router1.h"
|
#include "router1.h"
|
||||||
|
#include "router2.h"
|
||||||
#include "timing.h"
|
#include "timing.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
@ -492,6 +493,57 @@ delay_t Arch::estimateDelay(WireId src, WireId dst) const
|
|||||||
(6 + std::max(dx - 5, 0) + std::max(dy - 5, 0) + 2 * (std::min(dx, 5) + std::min(dy, 5)));
|
(6 + std::max(dx - 5, 0) + std::max(dy - 5, 0) + 2 * (std::min(dx, 5) + std::min(dy, 5)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ArcBounds Arch::getRouteBoundingBox(WireId src, WireId dst) const
|
||||||
|
{
|
||||||
|
ArcBounds bb;
|
||||||
|
|
||||||
|
bb.x0 = src.location.x;
|
||||||
|
bb.y0 = src.location.y;
|
||||||
|
bb.x1 = src.location.x;
|
||||||
|
bb.y1 = src.location.y;
|
||||||
|
|
||||||
|
auto extend = [&](int x, int y) {
|
||||||
|
bb.x0 = std::min(bb.x0, x);
|
||||||
|
bb.x1 = std::max(bb.x1, x);
|
||||||
|
bb.y0 = std::min(bb.y0, y);
|
||||||
|
bb.y1 = std::max(bb.y1, y);
|
||||||
|
};
|
||||||
|
|
||||||
|
auto est_location = [&](WireId w) -> std::pair<int, int> {
|
||||||
|
const auto &wire = locInfo(w)->wire_data[w.index];
|
||||||
|
if (w == gsrclk_wire) {
|
||||||
|
auto phys_wire = getPipSrcWire(*(getPipsUphill(w).begin()));
|
||||||
|
return std::make_pair(int(phys_wire.location.x), int(phys_wire.location.y));
|
||||||
|
} else if (wire.num_bel_pins > 0) {
|
||||||
|
return std::make_pair(w.location.x + wire.bel_pins[0].rel_bel_loc.x,
|
||||||
|
w.location.y + wire.bel_pins[0].rel_bel_loc.y);
|
||||||
|
} else if (wire.num_downhill > 0) {
|
||||||
|
return std::make_pair(w.location.x + wire.pips_downhill[0].rel_loc.x,
|
||||||
|
w.location.y + wire.pips_downhill[0].rel_loc.y);
|
||||||
|
} else if (wire.num_uphill > 0) {
|
||||||
|
return std::make_pair(w.location.x + wire.pips_uphill[0].rel_loc.x,
|
||||||
|
w.location.y + wire.pips_uphill[0].rel_loc.y);
|
||||||
|
} else {
|
||||||
|
return std::make_pair(int(w.location.x), int(w.location.y));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
auto src_loc = est_location(src);
|
||||||
|
extend(src_loc.first, src_loc.second);
|
||||||
|
if (wire_loc_overrides.count(src)) {
|
||||||
|
extend(wire_loc_overrides.at(src).first, wire_loc_overrides.at(src).second);
|
||||||
|
}
|
||||||
|
std::pair<int, int> dst_loc;
|
||||||
|
extend(dst.location.x, dst.location.y);
|
||||||
|
if (wire_loc_overrides.count(dst)) {
|
||||||
|
dst_loc = wire_loc_overrides.at(dst);
|
||||||
|
} else {
|
||||||
|
dst_loc = est_location(dst);
|
||||||
|
}
|
||||||
|
extend(dst_loc.first, dst_loc.second);
|
||||||
|
return bb;
|
||||||
|
}
|
||||||
|
|
||||||
delay_t Arch::predictDelay(const NetInfo *net_info, const PortRef &sink) const
|
delay_t Arch::predictDelay(const NetInfo *net_info, const PortRef &sink) const
|
||||||
{
|
{
|
||||||
const auto &driver = net_info->driver;
|
const auto &driver = net_info->driver;
|
||||||
@ -569,12 +621,23 @@ bool Arch::place()
|
|||||||
|
|
||||||
bool Arch::route()
|
bool Arch::route()
|
||||||
{
|
{
|
||||||
|
std::string router = str_or_default(settings, id("router"), defaultRouter);
|
||||||
|
|
||||||
setupWireLocations();
|
setupWireLocations();
|
||||||
route_ecp5_globals(getCtx());
|
route_ecp5_globals(getCtx());
|
||||||
assignArchInfo();
|
assignArchInfo();
|
||||||
assign_budget(getCtx(), true);
|
assign_budget(getCtx(), true);
|
||||||
|
|
||||||
bool result = router1(getCtx(), Router1Cfg(getCtx()));
|
bool result;
|
||||||
|
if (router == "router1") {
|
||||||
|
result = router1(getCtx(), Router1Cfg(getCtx()));
|
||||||
|
} else if (router == "router2") {
|
||||||
|
router2(getCtx(), Router2Cfg(getCtx()));
|
||||||
|
result = true;
|
||||||
|
} else {
|
||||||
|
log_error("ECP5 architecture does not support router '%s'\n", router.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
std::vector<std::pair<WireId, int>> fanout_vector;
|
std::vector<std::pair<WireId, int>> fanout_vector;
|
||||||
std::copy(wire_fanout.begin(), wire_fanout.end(), std::back_inserter(fanout_vector));
|
std::copy(wire_fanout.begin(), wire_fanout.end(), std::back_inserter(fanout_vector));
|
||||||
@ -1121,6 +1184,9 @@ const std::vector<std::string> Arch::availablePlacers = {"sa",
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const std::string Arch::defaultRouter = "router1";
|
||||||
|
const std::vector<std::string> Arch::availableRouters = {"router1", "router2"};
|
||||||
|
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
|
|
||||||
GroupId Arch::getGroupByName(IdString name) const
|
GroupId Arch::getGroupByName(IdString name) const
|
||||||
|
@ -948,6 +948,7 @@ struct Arch : BaseCtx
|
|||||||
// -------------------------------------------------
|
// -------------------------------------------------
|
||||||
|
|
||||||
delay_t estimateDelay(WireId src, WireId dst) const;
|
delay_t estimateDelay(WireId src, WireId dst) const;
|
||||||
|
ArcBounds getRouteBoundingBox(WireId src, WireId dst) const;
|
||||||
delay_t predictDelay(const NetInfo *net_info, const PortRef &sink) const;
|
delay_t predictDelay(const NetInfo *net_info, const PortRef &sink) const;
|
||||||
delay_t getDelayEpsilon() const { return 20; }
|
delay_t getDelayEpsilon() const { return 20; }
|
||||||
delay_t getRipupDelayPenalty() const;
|
delay_t getRipupDelayPenalty() const;
|
||||||
@ -1065,6 +1066,8 @@ struct Arch : BaseCtx
|
|||||||
|
|
||||||
static const std::string defaultPlacer;
|
static const std::string defaultPlacer;
|
||||||
static const std::vector<std::string> availablePlacers;
|
static const std::vector<std::string> availablePlacers;
|
||||||
|
static const std::string defaultRouter;
|
||||||
|
static const std::vector<std::string> availableRouters;
|
||||||
};
|
};
|
||||||
|
|
||||||
NEXTPNR_NAMESPACE_END
|
NEXTPNR_NAMESPACE_END
|
||||||
|
@ -203,17 +203,26 @@ void Arch::setupWireLocations()
|
|||||||
CellInfo *ci = cell.second;
|
CellInfo *ci = cell.second;
|
||||||
if (ci->bel == BelId())
|
if (ci->bel == BelId())
|
||||||
continue;
|
continue;
|
||||||
if (ci->type == id_MULT18X18D || ci->type == id_DCUA) {
|
if (ci->type == id_MULT18X18D || ci->type == id_DCUA || ci->type == id_DDRDLL || ci->type == id_DQSBUFM ||
|
||||||
|
ci->type == id_EHXPLLL) {
|
||||||
for (auto &port : ci->ports) {
|
for (auto &port : ci->ports) {
|
||||||
if (port.second.type != PORT_IN || port.second.net == nullptr)
|
if (port.second.net == nullptr)
|
||||||
continue;
|
continue;
|
||||||
WireId pw = getBelPinWire(ci->bel, port.first);
|
WireId pw = getBelPinWire(ci->bel, port.first);
|
||||||
if (pw == WireId())
|
if (pw == WireId())
|
||||||
continue;
|
continue;
|
||||||
for (auto uh : getPipsUphill(pw)) {
|
if (port.second.type == PORT_OUT) {
|
||||||
WireId pip_src = getPipSrcWire(uh);
|
for (auto dh : getPipsDownhill(pw)) {
|
||||||
wire_loc_overrides[pw] = std::make_pair(pip_src.location.x, pip_src.location.y);
|
WireId pip_dst = getPipDstWire(dh);
|
||||||
break;
|
wire_loc_overrides[pw] = std::make_pair(pip_dst.location.x, pip_dst.location.y);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (auto uh : getPipsUphill(pw)) {
|
||||||
|
WireId pip_src = getPipSrcWire(uh);
|
||||||
|
wire_loc_overrides[pw] = std::make_pair(pip_src.location.x, pip_src.location.y);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#include "placer1.h"
|
#include "placer1.h"
|
||||||
#include "placer_heap.h"
|
#include "placer_heap.h"
|
||||||
#include "router1.h"
|
#include "router1.h"
|
||||||
|
#include "router2.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
NEXTPNR_NAMESPACE_BEGIN
|
NEXTPNR_NAMESPACE_BEGIN
|
||||||
@ -514,6 +515,30 @@ delay_t Arch::predictDelay(const NetInfo *net_info, const PortRef &sink) const
|
|||||||
|
|
||||||
bool Arch::getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay_t &budget) const { return false; }
|
bool Arch::getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay_t &budget) const { return false; }
|
||||||
|
|
||||||
|
ArcBounds Arch::getRouteBoundingBox(WireId src, WireId dst) const
|
||||||
|
{
|
||||||
|
ArcBounds bb;
|
||||||
|
|
||||||
|
int src_x = wires.at(src).x;
|
||||||
|
int src_y = wires.at(src).y;
|
||||||
|
int dst_x = wires.at(dst).x;
|
||||||
|
int dst_y = wires.at(dst).y;
|
||||||
|
|
||||||
|
bb.x0 = src_x;
|
||||||
|
bb.y0 = src_y;
|
||||||
|
bb.x1 = src_x;
|
||||||
|
bb.y1 = src_y;
|
||||||
|
|
||||||
|
auto extend = [&](int x, int y) {
|
||||||
|
bb.x0 = std::min(bb.x0, x);
|
||||||
|
bb.x1 = std::max(bb.x1, x);
|
||||||
|
bb.y0 = std::min(bb.y0, y);
|
||||||
|
bb.y1 = std::max(bb.y1, y);
|
||||||
|
};
|
||||||
|
extend(dst_x, dst_y);
|
||||||
|
return bb;
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------
|
// ---------------------------------------------------------------
|
||||||
|
|
||||||
bool Arch::place()
|
bool Arch::place()
|
||||||
@ -553,10 +578,19 @@ bool Arch::place()
|
|||||||
|
|
||||||
bool Arch::route()
|
bool Arch::route()
|
||||||
{
|
{
|
||||||
bool retVal = router1(getCtx(), Router1Cfg(getCtx()));
|
std::string router = str_or_default(settings, id("router"), defaultRouter);
|
||||||
|
bool result;
|
||||||
|
if (router == "router1") {
|
||||||
|
result = router1(getCtx(), Router1Cfg(getCtx()));
|
||||||
|
} else if (router == "router2") {
|
||||||
|
router2(getCtx(), Router2Cfg(getCtx()));
|
||||||
|
result = true;
|
||||||
|
} else {
|
||||||
|
log_error("iCE40 architecture does not support router '%s'\n", router.c_str());
|
||||||
|
}
|
||||||
getCtx()->settings[getCtx()->id("route")] = 1;
|
getCtx()->settings[getCtx()->id("route")] = 1;
|
||||||
archInfoToAttributes();
|
archInfoToAttributes();
|
||||||
return retVal;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------
|
// ---------------------------------------------------------------
|
||||||
@ -653,6 +687,10 @@ const std::vector<std::string> Arch::availablePlacers = {"sa",
|
|||||||
"heap"
|
"heap"
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const std::string Arch::defaultRouter = "router1";
|
||||||
|
const std::vector<std::string> Arch::availableRouters = {"router1", "router2"};
|
||||||
|
|
||||||
void Arch::assignArchInfo()
|
void Arch::assignArchInfo()
|
||||||
{
|
{
|
||||||
for (auto &cell : getCtx()->cells) {
|
for (auto &cell : getCtx()->cells) {
|
||||||
|
@ -267,6 +267,8 @@ struct Arch : BaseCtx
|
|||||||
uint32_t getDelayChecksum(delay_t v) const { return 0; }
|
uint32_t getDelayChecksum(delay_t v) const { return 0; }
|
||||||
bool getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay_t &budget) const;
|
bool getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay_t &budget) const;
|
||||||
|
|
||||||
|
ArcBounds getRouteBoundingBox(WireId src, WireId dst) const;
|
||||||
|
|
||||||
bool pack();
|
bool pack();
|
||||||
bool place();
|
bool place();
|
||||||
bool route();
|
bool route();
|
||||||
@ -288,6 +290,8 @@ struct Arch : BaseCtx
|
|||||||
|
|
||||||
static const std::string defaultPlacer;
|
static const std::string defaultPlacer;
|
||||||
static const std::vector<std::string> availablePlacers;
|
static const std::vector<std::string> availablePlacers;
|
||||||
|
static const std::string defaultRouter;
|
||||||
|
static const std::vector<std::string> availableRouters;
|
||||||
|
|
||||||
// ---------------------------------------------------------------
|
// ---------------------------------------------------------------
|
||||||
// Internal usage
|
// Internal usage
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
#include "placer1.h"
|
#include "placer1.h"
|
||||||
#include "placer_heap.h"
|
#include "placer_heap.h"
|
||||||
#include "router1.h"
|
#include "router1.h"
|
||||||
|
#include "router2.h"
|
||||||
#include "timing_opt.h"
|
#include "timing_opt.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
NEXTPNR_NAMESPACE_BEGIN
|
NEXTPNR_NAMESPACE_BEGIN
|
||||||
@ -696,10 +697,19 @@ bool Arch::place()
|
|||||||
|
|
||||||
bool Arch::route()
|
bool Arch::route()
|
||||||
{
|
{
|
||||||
bool retVal = router1(getCtx(), Router1Cfg(getCtx()));
|
std::string router = str_or_default(settings, id("router"), defaultRouter);
|
||||||
|
bool result;
|
||||||
|
if (router == "router1") {
|
||||||
|
result = router1(getCtx(), Router1Cfg(getCtx()));
|
||||||
|
} else if (router == "router2") {
|
||||||
|
router2(getCtx(), Router2Cfg(getCtx()));
|
||||||
|
result = true;
|
||||||
|
} else {
|
||||||
|
log_error("iCE40 architecture does not support router '%s'\n", router.c_str());
|
||||||
|
}
|
||||||
getCtx()->settings[getCtx()->id("route")] = 1;
|
getCtx()->settings[getCtx()->id("route")] = 1;
|
||||||
archInfoToAttributes();
|
archInfoToAttributes();
|
||||||
return retVal;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
@ -1245,6 +1255,30 @@ void Arch::assignCellInfo(CellInfo *cell)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ArcBounds Arch::getRouteBoundingBox(WireId src, WireId dst) const
|
||||||
|
{
|
||||||
|
ArcBounds bb;
|
||||||
|
|
||||||
|
int src_x = chip_info->wire_data[src.index].x;
|
||||||
|
int src_y = chip_info->wire_data[src.index].y;
|
||||||
|
int dst_x = chip_info->wire_data[dst.index].x;
|
||||||
|
int dst_y = chip_info->wire_data[dst.index].y;
|
||||||
|
|
||||||
|
bb.x0 = src_x;
|
||||||
|
bb.y0 = src_y;
|
||||||
|
bb.x1 = src_x;
|
||||||
|
bb.y1 = src_y;
|
||||||
|
|
||||||
|
auto extend = [&](int x, int y) {
|
||||||
|
bb.x0 = std::min(bb.x0, x);
|
||||||
|
bb.x1 = std::max(bb.x1, x);
|
||||||
|
bb.y0 = std::min(bb.y0, y);
|
||||||
|
bb.y1 = std::max(bb.y1, y);
|
||||||
|
};
|
||||||
|
extend(dst_x, dst_y);
|
||||||
|
return bb;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef WITH_HEAP
|
#ifdef WITH_HEAP
|
||||||
const std::string Arch::defaultPlacer = "heap";
|
const std::string Arch::defaultPlacer = "heap";
|
||||||
#else
|
#else
|
||||||
@ -1257,4 +1291,7 @@ const std::vector<std::string> Arch::availablePlacers = {"sa",
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const std::string Arch::defaultRouter = "router1";
|
||||||
|
const std::vector<std::string> Arch::availableRouters = {"router1", "router2"};
|
||||||
|
|
||||||
NEXTPNR_NAMESPACE_END
|
NEXTPNR_NAMESPACE_END
|
||||||
|
@ -826,6 +826,8 @@ struct Arch : BaseCtx
|
|||||||
uint32_t getDelayChecksum(delay_t v) const { return v; }
|
uint32_t getDelayChecksum(delay_t v) const { return v; }
|
||||||
bool getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay_t &budget) const;
|
bool getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay_t &budget) const;
|
||||||
|
|
||||||
|
ArcBounds getRouteBoundingBox(WireId src, WireId dst) const;
|
||||||
|
|
||||||
// -------------------------------------------------
|
// -------------------------------------------------
|
||||||
|
|
||||||
bool pack();
|
bool pack();
|
||||||
@ -900,6 +902,8 @@ struct Arch : BaseCtx
|
|||||||
|
|
||||||
static const std::string defaultPlacer;
|
static const std::string defaultPlacer;
|
||||||
static const std::vector<std::string> availablePlacers;
|
static const std::vector<std::string> availablePlacers;
|
||||||
|
static const std::string defaultRouter;
|
||||||
|
static const std::vector<std::string> availableRouters;
|
||||||
};
|
};
|
||||||
|
|
||||||
void ice40DelayFuzzerMain(Context *ctx);
|
void ice40DelayFuzzerMain(Context *ctx);
|
||||||
|
Loading…
Reference in New Issue
Block a user