Gowin. Fix non-DCS networks. (#1467)

Prohibits the use of Dynamic Clock Selection PIPs for networks where no
DCS is present.

Signed-off-by: YRabbit <rabbit@yrabbit.cyou>
This commit is contained in:
YRabbit 2025-03-20 18:07:37 +10:00 committed by GitHub
parent 06992bda0a
commit 0c01cb9e41
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 28 additions and 14 deletions

View File

@ -240,9 +240,9 @@ struct GowinCstReader
} }
}; };
static void add_sip_constraints(Context *ctx, const Extra_package_data_POD *extra)
static void add_sip_constraints(Context *ctx, const Extra_package_data_POD *extra) { {
for(auto cst : extra->cst) { for (auto cst : extra->cst) {
auto it = ctx->cells.find(IdString(cst.net)); auto it = ctx->cells.find(IdString(cst.net));
if (it == ctx->cells.end()) { if (it == ctx->cells.end()) {
log_info("Cell %s not found\n", IdString(cst.net).c_str(ctx)); log_info("Cell %s not found\n", IdString(cst.net).c_str(ctx));
@ -255,7 +255,7 @@ static void add_sip_constraints(Context *ctx, const Extra_package_data_POD *extr
} }
it->second->setAttr(IdString(ID_BEL), std::string(ctx->nameOfBel(bel))); it->second->setAttr(IdString(ID_BEL), std::string(ctx->nameOfBel(bel)));
if(cst.iostd > 0) { if (cst.iostd > 0) {
std::string attr = "&IO_TYPE="; std::string attr = "&IO_TYPE=";
attr += IdString(cst.iostd).c_str(ctx); attr += IdString(cst.iostd).c_str(ctx);
boost::algorithm::to_upper(attr); boost::algorithm::to_upper(attr);
@ -267,8 +267,9 @@ static void add_sip_constraints(Context *ctx, const Extra_package_data_POD *extr
bool gowin_apply_constraints(Context *ctx, std::istream &in) bool gowin_apply_constraints(Context *ctx, std::istream &in)
{ {
// implicit constraints from SiP pins // implicit constraints from SiP pins
if(!ctx->package_info->extra_data.is_null()) { if (!ctx->package_info->extra_data.is_null()) {
const Extra_package_data_POD *extra = reinterpret_cast<const Extra_package_data_POD *>(ctx->package_info->extra_data.get()); const Extra_package_data_POD *extra =
reinterpret_cast<const Extra_package_data_POD *>(ctx->package_info->extra_data.get());
add_sip_constraints(ctx, extra); add_sip_constraints(ctx, extra);
} }

View File

@ -44,6 +44,14 @@ struct GowinGlobalRouter
bool segment_wire_filter(PipId pip) const { return !gwu.is_segment_pip(pip); } bool segment_wire_filter(PipId pip) const { return !gwu.is_segment_pip(pip); }
bool dcs_input_filter(PipId pip) const
{
return !ctx->getWireName(ctx->getPipSrcWire(pip))[1].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);
}
// allow io->global, global->global and global->tile clock // allow io->global, global->global and global->tile clock
bool global_pip_filter(PipId pip, WireId src_wire) const bool global_pip_filter(PipId pip, WireId src_wire) const
{ {
@ -372,7 +380,7 @@ struct GowinGlobalRouter
RouteResult route_result = route_direct_net( RouteResult route_result = route_direct_net(
net, net,
[&](PipId pip, WireId src_wire) { [&](PipId pip, WireId src_wire) {
return global_DQCE_pip_filter(pip, src) && segment_wire_filter(pip); return global_DQCE_pip_filter(pip, src) && segment_wire_filter(pip) && dcs_input_filter(pip);
}, },
src); src);
if (route_result == NOT_ROUTED) { if (route_result == NOT_ROUTED) {
@ -582,11 +590,14 @@ struct GowinGlobalRouter
RouteResult route_result; RouteResult route_result;
if (driver_is_mipi(driver)) { if (driver_is_mipi(driver)) {
route_result = route_direct_net( route_result = route_direct_net(
net, [&](PipId pip, WireId src_wire) { return segment_wire_filter(pip); }, src, &path); net, [&](PipId pip, WireId src_wire) { return segment_wire_filter(pip) && dcs_input_filter(pip); },
src, &path);
} else { } else {
route_result = route_direct_net( route_result = route_direct_net(
net, net,
[&](PipId pip, WireId src_wire) { return global_pip_filter(pip, src) && segment_wire_filter(pip); }, [&](PipId pip, WireId src_wire) {
return global_pip_filter(pip, src) && segment_wire_filter(pip) && dcs_input_filter(pip);
},
src, &path); src, &path);
} }
@ -659,7 +670,7 @@ struct GowinGlobalRouter
RouteResult route_result = route_direct_net( RouteResult route_result = route_direct_net(
net, net,
[&](PipId pip, WireId src_wire) { [&](PipId pip, WireId src_wire) {
return global_pip_filter(pip, src_wire) && segment_wire_filter(pip); return global_pip_filter(pip, src_wire) && segment_wire_filter(pip) && dcs_input_filter(pip);
}, },
src); src);
if (route_result == NOT_ROUTED || route_result == ROUTED_PARTIALLY) { if (route_result == NOT_ROUTED || route_result == ROUTED_PARTIALLY) {
@ -671,8 +682,9 @@ struct GowinGlobalRouter
CellInfo *true_src_ci = net_before_buf->driver.cell; CellInfo *true_src_ci = net_before_buf->driver.cell;
src = ctx->getBelPinWire(true_src_ci->bel, net_before_buf->driver.port); src = ctx->getBelPinWire(true_src_ci->bel, net_before_buf->driver.port);
ctx->bindWire(src, net, STRENGTH_LOCKED); ctx->bindWire(src, net, STRENGTH_LOCKED);
backwards_bfs_route(net, src, dst, 1000000, false, backwards_bfs_route(net, src, dst, 1000000, false, [&](PipId pip, WireId src_wire) {
[&](PipId pip, WireId src_wire) { return segment_wire_filter(pip); }); return segment_wire_filter(pip) && dcs_input_filter(pip);
});
// remove net // remove net
buf_ci->movePortTo(id_O, true_src_ci, net_before_buf->driver.port); buf_ci->movePortTo(id_O, true_src_ci, net_before_buf->driver.port);
net_before_buf->driver.cell = nullptr; net_before_buf->driver.cell = nullptr;
@ -683,7 +695,7 @@ struct GowinGlobalRouter
void route_clk_net(NetInfo *net) void route_clk_net(NetInfo *net)
{ {
RouteResult route_result = route_direct_net(net, [&](PipId pip, WireId src_wire) { RouteResult route_result = route_direct_net(net, [&](PipId pip, WireId src_wire) {
return global_pip_filter(pip, src_wire) && segment_wire_filter(pip); return global_pip_filter(pip, src_wire) && segment_wire_filter(pip) && dcs_input_filter(pip);
}); });
if (route_result != NOT_ROUTED) { if (route_result != NOT_ROUTED) {
log_info(" '%s' net was routed using global resources %s.\n", ctx->nameOf(net), log_info(" '%s' net was routed using global resources %s.\n", ctx->nameOf(net),
@ -788,7 +800,8 @@ struct GowinGlobalRouter
log_info(" %s\n", ctx->nameOfWire(gatewire)); log_info(" %s\n", ctx->nameOfWire(gatewire));
} }
routed = backwards_bfs_route( routed = backwards_bfs_route(
ni, src_wire, gatewire, 1000000, false, [&](PipId pip, WireId src) { return true; }, &bound_pips); ni, src_wire, gatewire, 1000000, false,
[&](PipId pip, WireId src) { return dcs_input_filter(pip); }, &bound_pips);
if (routed) { if (routed) {
// bind src // bind src
if (ctx->checkWireAvail(src_wire)) { if (ctx->checkWireAvail(src_wire)) {