From 1ce187ab5abea414457696944fdd96d5610ee8ad Mon Sep 17 00:00:00 2001 From: YRabbit Date: Mon, 5 Jan 2026 20:27:43 +1000 Subject: [PATCH] Gowin. BUGFIX. BSRAM SP separation. (#1622) * Gowin. BUGFIX. BSRAM SP separation. The new SP cell must inherit the byte size - 8 or 9 bits. Signed-off-by: YRabbit * Gowin. Byte Enables processing in SP. Single Port with a data width of 32/36 is internally configured as Dual Port with 16/18. Even and odd words are processed separately by ports A and B. With the advent of byte enable support, it became necessary to switch these signals differently. Signed-off-by: YRabbit --------- Signed-off-by: YRabbit --- himbaechel/uarch/gowin/pack.cc | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/himbaechel/uarch/gowin/pack.cc b/himbaechel/uarch/gowin/pack.cc index 44e519b0..730f297e 100644 --- a/himbaechel/uarch/gowin/pack.cc +++ b/himbaechel/uarch/gowin/pack.cc @@ -2800,7 +2800,7 @@ struct GowinPacker NetInfo *vcc_net = ctx->nets.at(ctx->id("$PACKER_VCC")).get(); NetInfo *vss_net = ctx->nets.at(ctx->id("$PACKER_GND")).get(); - IdString cell_type = id_SP; + IdString cell_type = bw == 32 ? id_SP : id_SPX9; IdString name = ctx->idf("%s_AUX", ctx->nameOf(ci)); auto sp_cell = gwu.create_cell(name, cell_type); @@ -2889,6 +2889,7 @@ struct GowinPacker } NetInfo *vcc_net = ctx->nets.at(ctx->id("$PACKER_VCC")).get(); + NetInfo *gnd_net = ctx->nets.at(ctx->id("$PACKER_GND")).get(); for (int i = 0; i < 3; ++i) { ci->renamePort(ctx->idf("BLKSEL[%d]", i), ctx->idf("BLKSEL%d", i)); if (bit_width == 32 || bit_width == 36) { @@ -2899,7 +2900,19 @@ struct GowinPacker for (int i = 0; i < 14; ++i) { ci->renamePort(ctx->idf("AD[%d]", i), ctx->idf("AD%d", i)); if (bit_width == 32 || bit_width == 36) { - ci->copyPortTo(ctx->idf("AD%d", i), ci, ctx->idf("ADB%d", i)); + // Since we are dividing 32/36 bits into two parts between + // ports A and B, the ‘Byte Enables’ require special + // separation. + if (i < 4) { + if (i > 1) { + ci->movePortTo(ctx->idf("AD%d", i), ci, ctx->idf("ADB%d", i - 2)); + ci->connectPort(ctx->idf("AD%d", i), gnd_net); + ci->addInput(ctx->idf("ADB%d", i)); + ci->connectPort(ctx->idf("ADB%d", i), gnd_net); + } + } else { + ci->copyPortTo(ctx->idf("AD%d", i), ci, ctx->idf("ADB%d", i)); + } } } if (bit_width == 32 || bit_width == 36) { @@ -2908,6 +2921,8 @@ struct GowinPacker ci->copyPortTo(id_CE, ci, id_CEB); ci->copyPortTo(id_RESET, ci, id_RESETB); ci->copyPortTo(id_WRE, ci, id_WREB); + ci->disconnectPort(ctx->id("AD4")); + ci->connectPort(ctx->id("AD4"), gnd_net); ci->disconnectPort(ctx->id("ADB4")); ci->connectPort(ctx->id("ADB4"), vcc_net); }