ecp5: Working on global router
Signed-off-by: David Shah <davey1576@gmail.com>
This commit is contained in:
parent
d43138b022
commit
bc10a5646d
@ -28,6 +28,21 @@
|
|||||||
|
|
||||||
NEXTPNR_NAMESPACE_BEGIN
|
NEXTPNR_NAMESPACE_BEGIN
|
||||||
|
|
||||||
|
static std::string get_quad_name(GlobalQuadrant quad)
|
||||||
|
{
|
||||||
|
switch (quad) {
|
||||||
|
case QUAD_UL:
|
||||||
|
return "UL";
|
||||||
|
case QUAD_UR:
|
||||||
|
return "UR";
|
||||||
|
case QUAD_LL:
|
||||||
|
return "LL";
|
||||||
|
case QUAD_LR:
|
||||||
|
return "LR";
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
class Ecp5GlobalRouter
|
class Ecp5GlobalRouter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -142,6 +157,79 @@ class Ecp5GlobalRouter
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool is_global_io(CellInfo *io, std::string &glb_name)
|
||||||
|
{
|
||||||
|
std::string func_name = ctx->getPioFunctionName(io->bel);
|
||||||
|
if (func_name.substr(0, 5) == "PCLKT") {
|
||||||
|
func_name.erase(func_name.find('_'), 1);
|
||||||
|
glb_name = "G_" + func_name;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
WireId get_global_wire(GlobalQuadrant quad, int network)
|
||||||
|
{
|
||||||
|
return ctx->getWireByLocAndBasename(Location(0, 0), get_quad_name(quad) + "PCLK" + std::to_string(network));
|
||||||
|
}
|
||||||
|
|
||||||
|
void simple_router(IdString net, WireId src, WireId dst)
|
||||||
|
{
|
||||||
|
std::queue<WireId> visit;
|
||||||
|
std::unordered_map<WireId, PipId> backtrace;
|
||||||
|
visit.push(src);
|
||||||
|
WireId cursor;
|
||||||
|
while (true) {
|
||||||
|
if (visit.empty() || visit.size() > 50000) {
|
||||||
|
log_error("cannot route global from %s to %s.\n", ctx->getWireName(src).c_str(ctx),
|
||||||
|
ctx->getWireName(dst).c_str(ctx));
|
||||||
|
}
|
||||||
|
cursor = visit.back();
|
||||||
|
visit.pop();
|
||||||
|
IdString bound = ctx->getBoundWireNet(cursor);
|
||||||
|
if (bound == net) {
|
||||||
|
break;
|
||||||
|
} else if (bound != IdString()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (cursor == dst)
|
||||||
|
break;
|
||||||
|
for (auto dh : ctx->getPipsDownhill(cursor)) {
|
||||||
|
WireId pipDst = ctx->getPipDstWire(dh);
|
||||||
|
if (backtrace.count(pipDst))
|
||||||
|
continue;
|
||||||
|
backtrace[pipDst] = dh;
|
||||||
|
visit.push(pipDst);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (true) {
|
||||||
|
auto fnd = backtrace.find(cursor);
|
||||||
|
if (fnd == backtrace.end())
|
||||||
|
break;
|
||||||
|
ctx->bindPip(fnd->second, net, STRENGTH_LOCKED);
|
||||||
|
cursor = ctx->getPipSrcWire(fnd->second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void route_onto_global(NetInfo *net, int network)
|
||||||
|
{
|
||||||
|
WireId glb_src;
|
||||||
|
if (net->driver.cell->type == ctx->id("TRELLIS_IO")) {
|
||||||
|
std::string ioglb;
|
||||||
|
if (!is_global_io(net->driver.cell, ioglb))
|
||||||
|
goto non_dedicated;
|
||||||
|
glb_src = ctx->getWireByLocAndBasename(Location(0, 0), ioglb);
|
||||||
|
}
|
||||||
|
for (int quad = QUAD_UL; quad < QUAD_LR + 1; quad++) {
|
||||||
|
WireId glb_dst = get_global_wire(GlobalQuadrant(quad), network);
|
||||||
|
simple_router(net->name, glb_src, glb_dst);
|
||||||
|
}
|
||||||
|
if (false) {
|
||||||
|
non_dedicated:
|
||||||
|
log_error("FIXME: currenly global networks can only be driven by dedicated global input pins");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Context *ctx;
|
Context *ctx;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user