aboutsummaryrefslogtreecommitdiffstats
path: root/gowin/arch.cc
diff options
context:
space:
mode:
authorYRabbit <rabbit@yrabbit.cyou>2022-11-10 19:14:41 +1000
committerYRabbit <rabbit@yrabbit.cyou>2022-11-10 19:14:41 +1000
commita84ded4793ce66b0f4854349c929afae334d1e56 (patch)
tree53451f52123c43d3c6cf0f49c73f46627263b21e /gowin/arch.cc
parentac17c36bec5b0ae8d57b66f825acb6f21f2ca323 (diff)
downloadnextpnr-a84ded4793ce66b0f4854349c929afae334d1e56.tar.gz
nextpnr-a84ded4793ce66b0f4854349c929afae334d1e56.tar.bz2
nextpnr-a84ded4793ce66b0f4854349c929afae334d1e56.zip
gowin: add initial PLL support
The rPLL primitive for the simplest chip (GW1N-1) in the family is processed. All parameters of the primitive are passed on to gowin_pack, and general-purpose wires are used for routing outputs of the primitive. Compatible with older versions of apicula, but in this case will refuse to place the new primitive. Signed-off-by: YRabbit <rabbit@yrabbit.cyou>
Diffstat (limited to 'gowin/arch.cc')
-rw-r--r--gowin/arch.cc40
1 files changed, 40 insertions, 0 deletions
diff --git a/gowin/arch.cc b/gowin/arch.cc
index f00dfb0a..54e38c0f 100644
--- a/gowin/arch.cc
+++ b/gowin/arch.cc
@@ -1071,6 +1071,26 @@ void Arch::addMuxBels(const DatabasePOD *db, int row, int col)
}
}
+void Arch::add_plla_ports(BelsPOD const *bel, IdString belname, int row, int col)
+{
+ IdString portname;
+ char buf[40];
+
+ 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}) {
+ portname = IdString(pairLookup(bel->ports.get(), bel->num_ports, pid)->src_id);
+ snprintf(buf, 32, "R%dC%d_%s", row + 1, col + 1, portname.c_str(this));
+ addBelInput(belname, IdString(pid), id(buf));
+ }
+ 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);
+ snprintf(buf, 32, "R%dC%d_%s", row + 1, col + 1, portname.c_str(this));
+ addBelOutput(belname, IdString(pid), id(buf));
+ }
+}
+
Arch::Arch(ArchArgs args) : args(args)
{
family = args.family;
@@ -1222,6 +1242,26 @@ Arch::Arch(ArchArgs args) : args(args)
bool dff = true;
bool oddrc = false;
switch (static_cast<ConstIds>(bel->type_id)) {
+ 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));
+ break;
case ID_BUFS7:
z++; /* fall-through*/
case ID_BUFS6: