aboutsummaryrefslogtreecommitdiffstats
path: root/gowin/pack.cc
diff options
context:
space:
mode:
authormyrtle <gatecat@ds0.me>2022-11-11 10:28:19 +0100
committerGitHub <noreply@github.com>2022-11-11 10:28:19 +0100
commit1aa9cda77a29daa454d6ac05ab345044668042ee (patch)
treeb2a42851c2a40e76eb09e660dfea0e3c8bafdde4 /gowin/pack.cc
parent79cb2f9e20341c7e162ed9a08163087d0f158461 (diff)
parent9013b2de5020ea94fd34b04cbb255b4bad8cbfab (diff)
downloadnextpnr-1aa9cda77a29daa454d6ac05ab345044668042ee.tar.gz
nextpnr-1aa9cda77a29daa454d6ac05ab345044668042ee.tar.bz2
nextpnr-1aa9cda77a29daa454d6ac05ab345044668042ee.zip
Merge pull request #1040 from yrabbit/pll-stage0
gowin: add initial PLL support
Diffstat (limited to 'gowin/pack.cc')
-rw-r--r--gowin/pack.cc72
1 files changed, 72 insertions, 0 deletions
diff --git a/gowin/pack.cc b/gowin/pack.cc
index d978ac40..5260dda5 100644
--- a/gowin/pack.cc
+++ b/gowin/pack.cc
@@ -986,6 +986,77 @@ static void pack_diff_io(Context *ctx)
}
}
+static bool is_pll(const Context *ctx, const CellInfo *cell)
+{
+ switch (cell->type.hash()) {
+ case ID_rPLL:
+ return true;
+ default:
+ return false;
+ }
+}
+
+// Pack PLLs
+static void pack_plls(Context *ctx)
+{
+ pool<IdString> packed_cells;
+ pool<IdString> delete_nets;
+
+ std::vector<std::unique_ptr<CellInfo>> new_cells;
+ log_info("Packing PLLs..\n");
+
+ for (auto &cell : ctx->cells) {
+ CellInfo *ci = cell.second.get();
+ if (ctx->verbose)
+ log_info("cell '%s' is of type '%s'\n", ctx->nameOf(ci), ci->type.c_str(ctx));
+ if (is_pll(ctx, ci)) {
+ std::string parm_device = str_or_default(ci->params, id_DEVICE, "GW1N-1");
+ if (parm_device != ctx->device) {
+ log_error("Wrong PLL device:%s vs %s\n", parm_device.c_str(), ctx->device.c_str());
+ continue;
+ }
+
+ switch (ci->type.hash()) {
+ case ID_rPLL: {
+ if (parm_device == "GW1N-1") {
+ // B half
+ std::unique_ptr<CellInfo> cell = create_generic_cell(ctx, id_RPLLB, ci->name.str(ctx) + "$rpllb");
+ reconnect_rpllb(ctx, ci, cell.get());
+ new_cells.push_back(std::move(cell));
+ auto pllb_cell = new_cells.back().get();
+ // A half
+ cell = create_generic_cell(ctx, id_RPLLA, ci->name.str(ctx) + "$rplla");
+ reconnect_rplla(ctx, ci, cell.get());
+ new_cells.push_back(std::move(cell));
+ auto plla_cell = new_cells.back().get();
+
+ // need params for gowin_pack
+ for (auto &parm : ci->params) {
+ plla_cell->setParam(parm.first, parm.second);
+ pllb_cell->setParam(parm.first, parm.second);
+ }
+ packed_cells.insert(ci->name);
+ } else {
+ log_error("PLL isn't supported for %s\n", ctx->device.c_str());
+ }
+ } break;
+ default:
+ break;
+ }
+ }
+ }
+
+ for (auto pcell : packed_cells) {
+ ctx->cells.erase(pcell);
+ }
+ for (auto dnet : delete_nets) {
+ ctx->nets.erase(dnet);
+ }
+ for (auto &ncell : new_cells) {
+ ctx->cells[ncell->name] = std::move(ncell);
+ }
+}
+
// Pack IO buffers
static void pack_io(Context *ctx)
{
@@ -1108,6 +1179,7 @@ bool Arch::pack()
pack_alus(ctx);
pack_lut_lutffs(ctx);
pack_nonlut_ffs(ctx);
+ pack_plls(ctx);
post_pack(ctx);
ctx->settings[id_pack] = 1;
ctx->assignArchInfo();