From 4a2aa6deb49b70ed69f386898bcde7a6b2572618 Mon Sep 17 00:00:00 2001 From: YRabbit Date: Sat, 12 Mar 2022 23:05:42 +1000 Subject: gowin: Add the Global Set/Reset primitive GSR is added automatically if it was not instantiated by the user explicitly. Compatible with old apicula bases, the functionality does not work, but the crash does not happen --- just a warning. Signed-off-by: YRabbit --- gowin/arch.cc | 8 ++++++++ gowin/cells.cc | 2 ++ gowin/constids.inc | 5 +++++ gowin/pack.cc | 36 ++++++++++++++++++++++++++++++++++++ 4 files changed, 51 insertions(+) diff --git a/gowin/arch.cc b/gowin/arch.cc index e6ee8267..22874810 100644 --- a/gowin/arch.cc +++ b/gowin/arch.cc @@ -991,6 +991,14 @@ Arch::Arch(ArchArgs args) : args(args) int z = 0; bool dff = true; switch (static_cast(bel->type_id)) { + case ID_GSR0: + snprintf(buf, 32, "R%dC%d_GSR0", row + 1, col + 1); + belname = id(buf); + addBel(belname, id_GSR, Loc(col, row, 0), false); + portname = IdString(pairLookup(bel->ports.get(), bel->num_ports, ID_GSRI)->src_id); + snprintf(buf, 32, "R%dC%d_%s", row + 1, col + 1, portname.c_str(this)); + addBelInput(belname, id_GSRI, id(buf)); + break; // fall through the ++ case ID_LUT7: z++; diff --git a/gowin/cells.cc b/gowin/cells.cc index d862458c..8e450b51 100644 --- a/gowin/cells.cc +++ b/gowin/cells.cc @@ -63,6 +63,8 @@ std::unique_ptr create_generic_cell(Context *ctx, IdString type, std:: new_cell->addInput(id_I); new_cell->addInput(id_OEN); new_cell->addOutput(id_O); + } else if (type == id_GSR) { + new_cell->addInput(id_GSRI); } else { log_error("unable to create generic cell of type %s\n", type.c_str(ctx)); } diff --git a/gowin/constids.inc b/gowin/constids.inc index 3e72340a..d32a987d 100644 --- a/gowin/constids.inc +++ b/gowin/constids.inc @@ -739,6 +739,11 @@ X(IOBUF) X(TBUF) X(TLVDS_OBUF) +// global set/reset +X(GSR) +X(GSR0) +X(GSRI) + // primitive attributes X(INIT) X(FF_USED) diff --git a/gowin/pack.cc b/gowin/pack.cc index c17a20c7..24daee31 100644 --- a/gowin/pack.cc +++ b/gowin/pack.cc @@ -660,6 +660,41 @@ static void pack_constants(Context *ctx) } } +// Pack global set-reset +static void pack_gsr(Context *ctx) +{ + log_info("Packing GSR..\n"); + + bool user_gsr = false; + 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 (ci->type == id_GSR) { + user_gsr = true; + break; + } + } + if (!user_gsr) { + // XXX + bool have_gsr_bel = false; + for (auto bi : ctx->bels) { + if (bi.second.type == id_GSR) { + have_gsr_bel = true; + break; + } + } + if (have_gsr_bel) { + // make default GSR + std::unique_ptr gsr_cell = create_generic_cell(ctx, id_GSR, "GSR"); + gsr_cell->connectPort(id_GSRI, ctx->nets[ctx->id("$PACKER_VCC_NET")].get()); + ctx->cells[gsr_cell->name] = std::move(gsr_cell); + } else { + log_info("No GSR in the chip base\n"); + } + } +} + static bool is_nextpnr_iob(const Context *ctx, CellInfo *cell) { return cell->type == ctx->id("$nextpnr_ibuf") || cell->type == ctx->id("$nextpnr_obuf") || @@ -857,6 +892,7 @@ bool Arch::pack() try { log_break(); pack_constants(ctx); + pack_gsr(ctx); pack_io(ctx); pack_diff_io(ctx); pack_wideluts(ctx); -- cgit v1.2.3