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 <rabbit@yrabbit.cyou>
This commit is contained in:
YRabbit 2022-03-12 23:05:42 +10:00
parent 20e595e211
commit 4a2aa6deb4
4 changed files with 51 additions and 0 deletions

View File

@ -991,6 +991,14 @@ Arch::Arch(ArchArgs args) : args(args)
int z = 0;
bool dff = true;
switch (static_cast<ConstIds>(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++;

View File

@ -63,6 +63,8 @@ std::unique_ptr<CellInfo> 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));
}

View File

@ -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)

View File

@ -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<CellInfo> 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);