Skip to content

Commit

Permalink
gowin: Himbaechel. Deal with SP BSRAM ports.
Browse files Browse the repository at this point in the history
The OCE signal in the SP(X)9B primitive is intended to control the
built-in output register. The documentation states that this port is
invalid when READ_MODE=0 is used. However, it has been experimentally
established that you cannot simply apply VCC or GND to it and forget it
- the discrepancy between the signal on this port and the signal on the
CE port leads to both skipping data reading and unnecessary reading
after CE has switched to 0.
Here we force these ports to be connected to the network, except in the
case where the user controls the OCE signal using non-constant signals.

Also:
  * All PIPs for clock spines are made inaccessible to the common router
    - in general, using these routes for signals that have not been
    processed by a special globals router is fraught with effects that
    are difficult to detect.
  * The INV primitive has been added purely to speed up development -
    this primitive is not generated by Yosys, but is almost always
    present in vendor output files.

Signed-off-by: YRabbit <[email protected]>
  • Loading branch information
yrabbit authored and gatecat committed Jan 23, 2024
1 parent 97f5c3c commit 91b0c4f
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 1 deletion.
3 changes: 3 additions & 0 deletions himbaechel/uarch/gowin/constids.inc
Original file line number Diff line number Diff line change
Expand Up @@ -934,6 +934,9 @@ X(GSR)
X(GSR0)
X(GSRI)

// inverter
X(INV)

// Oscillators
X(OSC)
X(OSCZ)
Expand Down
4 changes: 3 additions & 1 deletion himbaechel/uarch/gowin/globals.cc
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ struct GowinGlobalRouter

GowinGlobalRouter(Context *ctx) : ctx(ctx) { gwu.init(ctx); };

bool checkPipAvail(PipId pip) const { return gwu.is_global_pip(pip) || ctx->checkPipAvail(pip); };

// allow io->global, global->global and global->tile clock
bool global_pip_filter(PipId pip) const
{
Expand Down Expand Up @@ -91,7 +93,7 @@ struct GowinGlobalRouter
// Search uphill pips
for (PipId pip : ctx->getPipsUphill(cursor)) {
// Skip pip if unavailable, and not because it's already used for this net
if (!ctx->checkPipAvail(pip) && ctx->getBoundPipNet(pip) != net) {
if (!checkPipAvail(pip) && ctx->getBoundPipNet(pip) != net) {
continue;
}
WireId prev = ctx->getPipSrcWire(pip);
Expand Down
6 changes: 6 additions & 0 deletions himbaechel/uarch/gowin/gowin.cc
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ struct GowinImpl : HimbaechelAPI

bool isValidBelForCellType(IdString cell_type, BelId bel) const override;

// wires
bool checkPipAvail(PipId pip) const override;

private:
HimbaechelHelpers h;
GowinUtils gwu;
Expand Down Expand Up @@ -154,6 +157,9 @@ void GowinImpl::init(Context *ctx)
}
}

// We do not allow the use of global wires that bypass a special router.
bool GowinImpl::checkPipAvail(PipId pip) const { return !gwu.is_global_pip(pip); }

void GowinImpl::pack()
{
if (ctx->settings.count(ctx->id("cst.filename"))) {
Expand Down
15 changes: 15 additions & 0 deletions himbaechel/uarch/gowin/gowin_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,21 @@ struct GowinUtils

// wires
inline bool is_wire_type_default(IdString wire_type) { return wire_type == IdString(); }
// If wire is an important part of the global network (like SPINExx)
inline bool is_global_wire(WireId wire) const
{
return ctx->getWireName(wire)[1].in(
id_SPINE0, id_SPINE1, id_SPINE2, id_SPINE3, id_SPINE4, id_SPINE5, id_SPINE6, id_SPINE7, id_SPINE8,
id_SPINE9, id_SPINE10, id_SPINE11, id_SPINE12, id_SPINE13, id_SPINE14, id_SPINE15, id_SPINE16,
id_SPINE17, id_SPINE18, id_SPINE19, id_SPINE20, id_SPINE21, id_SPINE22, id_SPINE23, id_SPINE24,
id_SPINE25, id_SPINE26, id_SPINE27, id_SPINE28, id_SPINE29, id_SPINE30, id_SPINE31);
}

// pips
inline bool is_global_pip(PipId pip) const
{
return is_global_wire(ctx->getPipSrcWire(pip)) || is_global_wire(ctx->getPipDstWire(pip));
}

// chip dependent
bool have_SP32(void);
Expand Down
42 changes: 42 additions & 0 deletions himbaechel/uarch/gowin/pack.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1294,6 +1294,24 @@ struct GowinPacker
}
}

// If the memory is controlled by the CE, then it is logical for the OCE to
// also respond to this signal, unless the OCE is controlled separately.
void bsram_handle_sp_oce(CellInfo *ci, IdString ce_pin, IdString oce_pin)
{
const NetInfo *net = ci->getPort(oce_pin);
NPNR_ASSERT(ci->getPort(ce_pin) != nullptr);
if (net == nullptr || net->name == ctx->id("$PACKER_VCC") || net->name == ctx->id("$PACKER_GND")) {
if (net != nullptr) {
ci->disconnectPort(oce_pin);
}
ci->copyPortTo(ce_pin, ci, oce_pin);
}
if (ctx->verbose) {
log_info("%s: %s = %s = %s\n", ctx->nameOf(ci), ce_pin.c_str(ctx), oce_pin.c_str(ctx),
ctx->nameOf(ci->getPort(oce_pin)));
}
}

void pack_ROM(CellInfo *ci)
{
int default_bw = 32;
Expand Down Expand Up @@ -1512,6 +1530,8 @@ struct GowinPacker
}

int bit_width = ci->params.at(id_BIT_WIDTH).as_int64();
bsram_handle_sp_oce(ci, id_CE, id_OCE);

// XXX UG285-1.3.6_E Gowin BSRAM & SSRAM User Guide:
// For GW1N-9/GW1NR-9/GW1NS-4 series, 32/36-bit SP/SPX9 is divided into two
// SP/SPX9s, which occupy two BSRAMs.
Expand Down Expand Up @@ -1623,6 +1643,25 @@ struct GowinPacker
}
}

// ===================================
// Replace INV with LUT
// ===================================
void pack_inv(void)
{
log_info("Pack INV..\n");

for (auto &cell : ctx->cells) {
auto &ci = *cell.second;

if (ci.type == id_INV) {
ci.type = id_LUT4;
ci.renamePort(id_O, id_F);
ci.renamePort(id_I, id_I3); // use D - it's simple for INIT
ci.params[id_INIT] = Property(0x00ff);
}
}
}

// ===================================
// PLL
// ===================================
Expand Down Expand Up @@ -1700,6 +1739,9 @@ struct GowinPacker
pack_gsr();
ctx->check();

pack_inv();
ctx->check();

pack_wideluts();
ctx->check();

Expand Down

0 comments on commit 91b0c4f

Please sign in to comment.