mirror of https://github.com/YosysHQ/nextpnr.git
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:
parent
06992bda0a
commit
0c01cb9e41
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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)) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue