aboutsummaryrefslogtreecommitdiffstats
path: root/gowin/arch.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gowin/arch.cc')
-rw-r--r--gowin/arch.cc98
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;