From c312cb3adfe00525aea0bccb9096164998e655d9 Mon Sep 17 00:00:00 2001 From: YRabbit Date: Sun, 14 Jul 2024 18:57:07 +1000 Subject: [PATCH] Gowin. Fix GW2A-18(c) DCS and DQCE We filter out PIPs from these chips that bypass DCS. Signed-off-by: YRabbit --- himbaechel/uarch/gowin/constids.inc | 32 +++++++++++++++++ himbaechel/uarch/gowin/globals.cc | 53 +++++++++++++++++++++++++---- 2 files changed, 78 insertions(+), 7 deletions(-) diff --git a/himbaechel/uarch/gowin/constids.inc b/himbaechel/uarch/gowin/constids.inc index 5aeac7489c..4eb7badf25 100644 --- a/himbaechel/uarch/gowin/constids.inc +++ b/himbaechel/uarch/gowin/constids.inc @@ -1085,6 +1085,38 @@ X(LOCK) X(AD) X(DI) 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 X(CLKOUTPS) diff --git a/himbaechel/uarch/gowin/globals.cc b/himbaechel/uarch/gowin/globals.cc index 011e2f371f..48a45d26c4 100644 --- a/himbaechel/uarch/gowin/globals.cc +++ b/himbaechel/uarch/gowin/globals.cc @@ -48,7 +48,6 @@ struct GowinGlobalRouter 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); }; - WireId src, dst; src = ctx->getPipSrcWire(pip); dst = ctx->getPipDstWire(pip); @@ -70,6 +69,40 @@ struct GowinGlobalRouter 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 { auto is_local = [&](IdString wire_type) { @@ -233,7 +266,7 @@ struct GowinGlobalRouter 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; src = aux_src == WireId() ? ctx->getNetinfoSourceWire(net) : aux_src; @@ -254,14 +287,20 @@ struct GowinGlobalRouter ctx->nameOf(usr.port)); } bool bfs_res; - if (DCS_pip_only) { + if (DCS_pips) { bfs_res = backwards_bfs_route(net, src, dst, 1000000, false, [&](PipId pip) { return (is_relaxed_sink(usr) || global_DCS_pip_filter(pip)); }); } else { - bfs_res = backwards_bfs_route(net, src, dst, 1000000, false, [&](PipId pip) { - return (is_relaxed_sink(usr) || global_pip_filter(pip)); - }); + 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 { + bfs_res = backwards_bfs_route(net, src, dst, 1000000, false, [&](PipId pip) { + return (is_relaxed_sink(usr) || global_pip_filter(pip)); + }); + } } if (bfs_res) { routed = routed == ROUTED_PARTIALLY ? routed : ROUTED_ALL; @@ -296,7 +335,7 @@ struct GowinGlobalRouter 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) { log_error("Can't route the %s network.\n", ctx->nameOf(net)); }