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:
parent
20e595e211
commit
4a2aa6deb4
@ -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++;
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user