gowin: Add PLL support for the GW1NR-9 chip

And also unified the fixing of PLL to bels: the point is that PLL being
at a certain location has the possibility to use a direct implicit wire
to the clock source, but once we decide to use this direct wire, the PLL
can no longer be moved.

Signed-off-by: YRabbit <rabbit@yrabbit.cyou>
This commit is contained in:
YRabbit 2023-01-30 12:49:57 +10:00
parent f80b871dd5
commit 6a1212a1e1
3 changed files with 56 additions and 46 deletions

View File

@ -2108,6 +2108,47 @@ bool Arch::is_GCLKT_iob(const CellInfo *cell)
return false;
}
void Arch::bind_pll_to_bel(CellInfo *ci, int loc)
{
BelId bel;
switch (ci->type.hash()) {
case ID_PLLVR:
bel = loc == PLL::left ? id("R1C28_PLLVR") : id("R1C37_PLLVR");
break;
case ID_rPLL:
if (family == "GW1N-1" || family == "GW1NZ-1") {
if (loc == PLL::left) {
return;
}
bel = id("R1C18_rPLL");
break;
}
if (family == "GW1NR-9C" || family == "GW1NR-9") {
bel = loc == PLL::left ? id("R10C1_rPLL") : id("R10C47_rPLL");
break;
}
break;
default:
return;
}
if (checkBelAvail(bel) || ci->belStrength != STRENGTH_LOCKED) {
if (ci->bel == bel) {
unbindBel(bel);
} else {
if (!checkBelAvail(bel) && ci->belStrength != STRENGTH_LOCKED) {
CellInfo *other_ci = getBoundBelCell(bel);
unbindBel(bel);
BelId our_bel = ci->bel;
unbindBel(our_bel);
bindBel(our_bel, other_ci, STRENGTH_LOCKED);
}
}
ci->disconnectPort(id_CLKIN);
ci->setParam(id_INSEL, Property("CLKIN0"));
bindBel(bel, ci, STRENGTH_LOCKED);
}
}
// If the PLL input can be connected using a direct wire, then do so,
// bypassing conventional routing.
void Arch::fix_pll_nets(Context *ctx)
@ -2129,54 +2170,13 @@ void Arch::fix_pll_nets(Context *ctx)
break;
}
if (net_driven_by(ctx, net, is_RPLL_T_IN_iob, id_O) != nullptr) {
if (ci->type == id_rPLL) {
ci->disconnectPort(id_CLKIN);
ci->setParam(id_INSEL, Property("CLKIN0"));
bind_pll_to_bel(ci, PLL::right);
break;
}
BelId bel = id("R1C37_PLLVR");
if (ci->type == id_PLLVR) {
if (checkBelAvail(bel) || ci->belStrength != STRENGTH_LOCKED) {
if (ci->bel == bel) {
unbindBel(bel);
} else {
if (!checkBelAvail(bel) && ci->belStrength != STRENGTH_LOCKED) {
CellInfo *other_ci = getBoundBelCell(bel);
unbindBel(bel);
BelId our_bel = ci->bel;
unbindBel(our_bel);
bindBel(our_bel, other_ci, STRENGTH_LOCKED);
}
}
ci->disconnectPort(id_CLKIN);
ci->setParam(id_INSEL, Property("CLKIN0"));
bindBel(bel, ci, STRENGTH_LOCKED);
break;
}
}
}
if (net_driven_by(ctx, net, is_LPLL_T_IN_iob, id_O) != nullptr) {
BelId bel = id("R1C28_PLLVR");
if (ci->type == id_PLLVR) {
if (checkBelAvail(bel) || ci->belStrength != STRENGTH_LOCKED) {
if (ci->bel == bel) {
unbindBel(bel);
} else {
if (!checkBelAvail(bel) && ci->belStrength != STRENGTH_LOCKED) {
CellInfo *other_ci = getBoundBelCell(bel);
unbindBel(bel);
BelId our_bel = ci->bel;
unbindBel(our_bel);
bindBel(our_bel, other_ci, STRENGTH_LOCKED);
}
}
ci->disconnectPort(id_CLKIN);
ci->setParam(id_INSEL, Property("CLKIN0"));
bindBel(bel, ci, STRENGTH_LOCKED);
bind_pll_to_bel(ci, PLL::left);
break;
}
}
}
// XXX do special bels (HCLK etc)
// This is general routing through CLK0 pip
ci->setParam(id_INSEL, Property("CLKIN1"));

View File

@ -482,6 +482,7 @@ struct Arch : BaseArch<ArchRanges>
void add_rpll_ports(DatabasePOD const *db, BelsPOD const *bel, IdString belname, int row, int col);
void fix_pll_nets(Context *ctx);
bool is_GCLKT_iob(const CellInfo *cell);
void bind_pll_to_bel(CellInfo *ci, int loc);
GowinGlobalRouter globals_router;
void mark_gowin_globals(Context *ctx);
@ -530,6 +531,14 @@ enum
};
}
namespace PLL { // fixed PLL locations
enum
{
left = 0,
right = 1
};
}
NEXTPNR_NAMESPACE_END
#endif /* GOWIN_ARCH_H */

View File

@ -1043,7 +1043,8 @@ static void pack_plls(Context *ctx)
switch (ci->type.hash()) {
case ID_rPLL: {
if (parm_device == "GW1N-1" || parm_device == "GW1NZ-1" || parm_device == "GW1NR-9C") {
if (parm_device == "GW1N-1" || parm_device == "GW1NZ-1" || parm_device == "GW1NR-9C" ||
parm_device == "GW1NR-9") {
pll_disable_unused_ports(ctx, ci);
// A cell
std::unique_ptr<CellInfo> cell = create_generic_cell(ctx, id_rPLL, ci->name.str(ctx) + "$rpll");