diff options
Diffstat (limited to 'gowin/arch.cc')
-rw-r--r-- | gowin/arch.cc | 98 |
1 files changed, 63 insertions, 35 deletions
diff --git a/gowin/arch.cc b/gowin/arch.cc index f43cc00a..88b9f42f 100644 --- a/gowin/arch.cc +++ b/gowin/arch.cc @@ -1098,16 +1098,33 @@ void Arch::addMuxBels(const DatabasePOD *db, int row, int col) } } -void Arch::add_plla_ports(BelsPOD const *bel, IdString belname, int row, int col) +void Arch::add_pllvr_ports(DatabasePOD const *db, BelsPOD const *bel, IdString belname, int row, int col) { IdString portname; - for (int pid : {ID_CLKIN, ID_CLKFB, ID_FBDSEL0, ID_FBDSEL1, ID_FBDSEL2, ID_FBDSEL3, ID_FBDSEL4, ID_FBDSEL5, - ID_IDSEL0, ID_IDSEL1, ID_IDSEL2, ID_IDSEL3, ID_IDSEL4, ID_IDSEL5, ID_ODSEL0, ID_ODSEL1, - ID_ODSEL2, ID_ODSEL3, ID_ODSEL4, ID_PSDA0, ID_PSDA1, ID_PSDA2, ID_PSDA3, ID_DUTYDA0, - ID_DUTYDA1, ID_DUTYDA2, ID_DUTYDA3, ID_FDLY0, ID_FDLY1, ID_FDLY2, ID_FDLY3}) { + for (int pid : + {ID_CLKIN, ID_CLKFB, ID_FBDSEL0, ID_FBDSEL1, ID_FBDSEL2, ID_FBDSEL3, ID_FBDSEL4, ID_FBDSEL5, ID_IDSEL0, + ID_IDSEL1, ID_IDSEL2, ID_IDSEL3, ID_IDSEL4, ID_IDSEL5, ID_ODSEL0, ID_ODSEL1, ID_ODSEL2, ID_ODSEL3, + ID_ODSEL4, ID_ODSEL5, ID_VREN, ID_PSDA0, ID_PSDA1, ID_PSDA2, ID_PSDA3, ID_DUTYDA0, ID_DUTYDA1, + ID_DUTYDA2, ID_DUTYDA3, ID_FDLY0, ID_FDLY1, ID_FDLY2, ID_FDLY3, ID_RESET, ID_RESET_P}) { portname = IdString(pairLookup(bel->ports.get(), bel->num_ports, pid)->src_id); - addBelInput(belname, IdString(pid), idf("R%dC%d_%s", row + 1, col + 1, portname.c_str(this))); + IdString wire = idf("R%dC%d_%s", row + 1, col + 1, portname.c_str(this)); + if (wires.count(wire) == 0) { + GlobalAliasPOD alias; + alias.dest_col = col; + alias.dest_row = row; + alias.dest_id = portname.hash(); + auto alias_src = genericLookup(db->aliases.get(), db->num_aliases, alias, aliasCompare); + NPNR_ASSERT(alias_src != nullptr); + int srcrow = alias_src->src_row; + int srccol = alias_src->src_col; + IdString srcid = IdString(alias_src->src_id); + wire = wireToGlobal(srcrow, srccol, db, srcid); + if (wires.count(wire) == 0) { + addWire(wire, srcid, srccol, srcrow); + } + } + addBelInput(belname, IdString(pid), wire); } for (int pid : {ID_LOCK, ID_CLKOUT, ID_CLKOUTP, ID_CLKOUTD, ID_CLKOUTD3}) { portname = IdString(pairLookup(bel->ports.get(), bel->num_ports, pid)->src_id); @@ -1115,16 +1132,23 @@ void Arch::add_plla_ports(BelsPOD const *bel, IdString belname, int row, int col } } -void Arch::add_pllvr_ports(DatabasePOD const *db, BelsPOD const *bel, IdString belname, int row, int col) +void Arch::add_rpll_ports(DatabasePOD const *db, BelsPOD const *bel, IdString belname, int row, int col) { IdString portname; for (int pid : - {ID_CLKIN, ID_CLKFB, ID_FBDSEL0, ID_FBDSEL1, ID_FBDSEL2, ID_FBDSEL3, ID_FBDSEL4, ID_FBDSEL5, ID_IDSEL0, - ID_IDSEL1, ID_IDSEL2, ID_IDSEL3, ID_IDSEL4, ID_IDSEL5, ID_ODSEL0, ID_ODSEL1, ID_ODSEL2, ID_ODSEL3, - ID_ODSEL4, ID_ODSEL5, ID_VREN, ID_PSDA0, ID_PSDA1, ID_PSDA2, ID_PSDA3, ID_DUTYDA0, ID_DUTYDA1, - ID_DUTYDA2, ID_DUTYDA3, ID_FDLY0, ID_FDLY1, ID_FDLY2, ID_FDLY3, ID_RESET, ID_RESET_P}) { - portname = IdString(pairLookup(bel->ports.get(), bel->num_ports, pid)->src_id); + {ID_CLKIN, ID_CLKFB, ID_FBDSEL0, ID_FBDSEL1, ID_FBDSEL2, ID_FBDSEL3, ID_FBDSEL4, ID_FBDSEL5, ID_IDSEL0, + ID_IDSEL1, ID_IDSEL2, ID_IDSEL3, ID_IDSEL4, ID_IDSEL5, ID_ODSEL0, ID_ODSEL1, ID_ODSEL2, ID_ODSEL3, + ID_ODSEL4, ID_ODSEL5, ID_PSDA0, ID_PSDA1, ID_PSDA2, ID_PSDA3, ID_DUTYDA0, ID_DUTYDA1, ID_DUTYDA2, + ID_DUTYDA3, ID_FDLY0, ID_FDLY1, ID_FDLY2, ID_FDLY3, ID_RESET, ID_RESET_P}) { + const PairPOD *port = pairLookup(bel->ports.get(), bel->num_ports, pid); + // old base + if (port == nullptr) { + log_warning("When building nextpnr, obsolete old apicula bases were used. Probably not working properly " + "with PLL.\n"); + return; + } + portname = IdString(port->src_id); IdString wire = idf("R%dC%d_%s", row + 1, col + 1, portname.c_str(this)); if (wires.count(wire) == 0) { GlobalAliasPOD alias; @@ -1137,20 +1161,39 @@ void Arch::add_pllvr_ports(DatabasePOD const *db, BelsPOD const *bel, IdString b int srccol = alias_src->src_col; IdString srcid = IdString(alias_src->src_id); wire = wireToGlobal(srcrow, srccol, db, srcid); - // addWire(wire, portname, srccol, srcrow); + if (wires.count(wire) == 0) { + addWire(wire, srcid, srccol, srcrow); + } } addBelInput(belname, IdString(pid), wire); } for (int pid : {ID_LOCK, ID_CLKOUT, ID_CLKOUTP, ID_CLKOUTD, ID_CLKOUTD3}) { portname = IdString(pairLookup(bel->ports.get(), bel->num_ports, pid)->src_id); - addBelOutput(belname, IdString(pid), idf("R%dC%d_%s", row + 1, col + 1, portname.c_str(this))); + IdString wire = idf("R%dC%d_%s", row + 1, col + 1, portname.c_str(this)); + if (wires.count(wire) == 0) { + GlobalAliasPOD alias; + alias.dest_col = col; + alias.dest_row = row; + alias.dest_id = portname.hash(); + auto alias_src = genericLookup(db->aliases.get(), db->num_aliases, alias, aliasCompare); + NPNR_ASSERT(alias_src != nullptr); + int srcrow = alias_src->src_row; + int srccol = alias_src->src_col; + IdString srcid = IdString(alias_src->src_id); + wire = wireToGlobal(srcrow, srccol, db, srcid); + if (wires.count(wire) == 0) { + addWire(wire, srcid, srccol, srcrow); + } + } + addBelOutput(belname, IdString(pid), wire); } } + Arch::Arch(ArchArgs args) : args(args) { family = args.family; - max_clock = 5; + max_clock = 6; if (family == "GW1NZ-1") { max_clock = 3; } @@ -1312,24 +1355,9 @@ Arch::Arch(ArchArgs args) : args(args) add_pllvr_ports(db, bel, belname, row, col); break; case ID_RPLLA: - snprintf(buf, 32, "R%dC%d_RPLLA", row + 1, col + 1); - belname = id(buf); - addBel(belname, id_RPLLA, Loc(col, row, BelZ::pll_z), false); - add_plla_ports(bel, belname, row, col); - break; - case ID_RPLLB: - snprintf(buf, 32, "R%dC%d_RPLLB", row + 1, col + 1); - belname = id(buf); - addBel(belname, id_RPLLB, Loc(col, row, BelZ::pll_z), false); - portname = IdString(pairLookup(bel->ports.get(), bel->num_ports, ID_RESET)->src_id); - snprintf(buf, 32, "R%dC%d_%s", row + 1, col + 1, portname.c_str(this)); - addBelInput(belname, id_RESET, id(buf)); - portname = IdString(pairLookup(bel->ports.get(), bel->num_ports, ID_RESET_P)->src_id); - snprintf(buf, 32, "R%dC%d_%s", row + 1, col + 1, portname.c_str(this)); - addBelInput(belname, id_RESET_P, id(buf)); - portname = IdString(pairLookup(bel->ports.get(), bel->num_ports, ID_ODSEL5)->src_id); - snprintf(buf, 32, "R%dC%d_%s", row + 1, col + 1, portname.c_str(this)); - addBelInput(belname, id_ODSEL5, id(buf)); + belname = idf("R%dC%d_rPLL", row + 1, col + 1); + addBel(belname, id_rPLL, Loc(col, row, BelZ::pll_z), false); + add_rpll_ports(db, bel, belname, row, col); break; case ID_BUFS7: z++; /* fall-through*/ @@ -2086,7 +2114,7 @@ void Arch::fix_pll_nets(Context *ctx) { for (auto &cell : ctx->cells) { CellInfo *ci = cell.second.get(); - if (ci->type != id_RPLLA && ci->type != id_PLLVR) { + if (ci->type != id_rPLL && ci->type != id_PLLVR) { continue; } // *** CLKIN @@ -2101,7 +2129,7 @@ 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_RPLLA) { + if (ci->type == id_rPLL) { ci->disconnectPort(id_CLKIN); ci->setParam(id_INSEL, Property("CLKIN0")); break; |