Gowin. Fix GW2A-18(c) DCS and DQCE

We filter out PIPs from these chips that bypass DCS.

Signed-off-by: YRabbit <rabbit@yrabbit.cyou>
This commit is contained in:
YRabbit 2024-07-14 18:57:07 +10:00 committed by myrtle
parent 10a5a44b81
commit 11d335c7ce
2 changed files with 78 additions and 7 deletions

View File

@ -1085,6 +1085,38 @@ X(LOCK)
X(AD) X(AD)
X(DI) X(DI)
X(DO) X(DO)
X(P16A)
X(P16B)
X(P16C)
X(P16D)
X(P17A)
X(P17B)
X(P17C)
X(P17D)
X(P26A)
X(P26B)
X(P26C)
X(P26D)
X(P27A)
X(P27B)
X(P27C)
X(P27D)
X(P36A)
X(P36B)
X(P36C)
X(P36D)
X(P37A)
X(P37B)
X(P37C)
X(P37D)
X(P46A)
X(P46B)
X(P46C)
X(P46D)
X(P47A)
X(P47B)
X(P47C)
X(P47D)
// PLL parameters // PLL parameters
X(CLKOUTPS) X(CLKOUTPS)

View File

@ -48,7 +48,6 @@ struct GowinGlobalRouter
auto is_local = [&](IdString wire_type) { auto is_local = [&](IdString wire_type) {
return !wire_type.in(id_GLOBAL_CLK, id_IO_O, id_IO_I, id_PLL_O, id_PLL_I, id_TILE_CLK); return !wire_type.in(id_GLOBAL_CLK, id_IO_O, id_IO_I, id_PLL_O, id_PLL_I, id_TILE_CLK);
}; };
WireId src, dst; WireId src, dst;
src = ctx->getPipSrcWire(pip); src = ctx->getPipSrcWire(pip);
dst = ctx->getPipDstWire(pip); dst = ctx->getPipDstWire(pip);
@ -70,6 +69,40 @@ struct GowinGlobalRouter
return res; return res;
} }
bool global_DQCE_pip_filter(PipId pip) const
{
auto is_local = [&](IdString wire_type) {
return !wire_type.in(id_GLOBAL_CLK, id_IO_O, id_IO_I, id_PLL_O, id_PLL_I, id_TILE_CLK);
};
auto is_dcs_input = [&](IdString wire_name) {
return wire_name.in(id_P16A, id_P16B, id_P16C, id_P16D, id_P17A, id_P17B, id_P17C, id_P17D, id_P26A,
id_P26B, id_P26C, id_P26D, id_P27A, id_P27B, id_P27C, id_P27D, id_P36A, id_P36B,
id_P36C, id_P36D, id_P37A, id_P37B, id_P37C, id_P37D, id_P46A, id_P46B, id_P46C,
id_P46D, id_P47A, id_P47B, id_P47C, id_P47D);
};
WireId src, dst;
src = ctx->getPipSrcWire(pip);
dst = ctx->getPipDstWire(pip);
IdString src_name = ctx->getWireName(dst)[1];
IdString dst_name = ctx->getWireName(dst)[1];
bool not_dsc_pip = dst_name != id_CLKOUT && !is_dcs_input(src_name);
IdString src_type = ctx->getWireType(src);
IdString dst_type = ctx->getWireType(dst);
bool src_valid = not_dsc_pip && src_type.in(id_GLOBAL_CLK, id_IO_O, id_PLL_O, id_HCLK);
bool dst_valid = not_dsc_pip && dst_type.in(id_GLOBAL_CLK, id_TILE_CLK, id_PLL_I, id_IO_I, id_HCLK);
bool res = (src_valid && dst_valid) || (src_valid && is_local(dst_type)) || (is_local(src_type) && dst_valid);
if (ctx->debug && false /*&& res*/) {
log_info("%s <- %s [%s <- %s]\n", ctx->getWireName(ctx->getPipDstWire(pip)).str(ctx).c_str(),
ctx->getWireName(ctx->getPipSrcWire(pip)).str(ctx).c_str(), dst_type.c_str(ctx),
src_type.c_str(ctx));
log_info("res:%d, src_valid:%d, dst_valid:%d, src local:%d, dst local:%d\n", res, src_valid, dst_valid,
is_local(src_type), is_local(dst_type));
}
return res;
}
bool global_DCS_pip_filter(PipId pip) const bool global_DCS_pip_filter(PipId pip) const
{ {
auto is_local = [&](IdString wire_type) { auto is_local = [&](IdString wire_type) {
@ -233,7 +266,7 @@ struct GowinGlobalRouter
ROUTED_ALL ROUTED_ALL
}; };
RouteResult route_direct_net(NetInfo *net, WireId aux_src = WireId(), bool DCS_pip_only = false) RouteResult route_direct_net(NetInfo *net, WireId aux_src = WireId(), bool DCS_pips = false, bool DQCE_pips = false)
{ {
WireId src; WireId src;
src = aux_src == WireId() ? ctx->getNetinfoSourceWire(net) : aux_src; src = aux_src == WireId() ? ctx->getNetinfoSourceWire(net) : aux_src;
@ -254,15 +287,21 @@ struct GowinGlobalRouter
ctx->nameOf(usr.port)); ctx->nameOf(usr.port));
} }
bool bfs_res; bool bfs_res;
if (DCS_pip_only) { if (DCS_pips) {
bfs_res = backwards_bfs_route(net, src, dst, 1000000, false, [&](PipId pip) { bfs_res = backwards_bfs_route(net, src, dst, 1000000, false, [&](PipId pip) {
return (is_relaxed_sink(usr) || global_DCS_pip_filter(pip)); return (is_relaxed_sink(usr) || global_DCS_pip_filter(pip));
}); });
} else {
if (DQCE_pips) {
bfs_res = backwards_bfs_route(net, src, dst, 1000000, false, [&](PipId pip) {
return (is_relaxed_sink(usr) || global_DQCE_pip_filter(pip));
});
} else { } else {
bfs_res = backwards_bfs_route(net, src, dst, 1000000, false, [&](PipId pip) { bfs_res = backwards_bfs_route(net, src, dst, 1000000, false, [&](PipId pip) {
return (is_relaxed_sink(usr) || global_pip_filter(pip)); return (is_relaxed_sink(usr) || global_pip_filter(pip));
}); });
} }
}
if (bfs_res) { if (bfs_res) {
routed = routed == ROUTED_PARTIALLY ? routed : ROUTED_ALL; routed = routed == ROUTED_PARTIALLY ? routed : ROUTED_ALL;
} else { } else {
@ -296,7 +335,7 @@ struct GowinGlobalRouter
src = ctx->getBelPinWire(driver.cell->bel, driver.port); src = ctx->getBelPinWire(driver.cell->bel, driver.port);
} }
RouteResult route_result = route_direct_net(net, src); RouteResult route_result = route_direct_net(net, src, false, true);
if (route_result == NOT_ROUTED) { if (route_result == NOT_ROUTED) {
log_error("Can't route the %s network.\n", ctx->nameOf(net)); log_error("Can't route the %s network.\n", ctx->nameOf(net));
} }