GOWIN. Fix dual port CE-OCE.

We are fixing a hardware error - in BYPASS mode, dual port bsram
requires synchronization of CE and OCE signals for some data widths.

We are also getting rid of port renaming in the loop, but not all of
them yet.

Signed-off-by: YRabbit <rabbit@yrabbit.cyou>
This commit is contained in:
YRabbit 2026-03-06 08:40:20 +10:00 committed by myrtle
parent 4ace8952d3
commit 111f085d64
6 changed files with 33 additions and 14 deletions

View File

@ -226,6 +226,7 @@ NPNR_PACKED_STRUCT(struct Extra_chip_data_POD {
static constexpr int32_t NEED_CFGPINS_INVERSION = 4096;
static constexpr int32_t HAS_I2CCFG = 8192;
static constexpr int32_t HAS_5A_DSP = 16384;
static constexpr int32_t NEED_BSRAM_DP_CE_FIX = 32768;
});
} // namespace

View File

@ -34,6 +34,7 @@ CHIP_NEED_SDP_FIX = 0x800
CHIP_NEED_CFGPINS_INVERSION = 0x1000
CHIP_HAS_I2CCFG = 0x2000
CHIP_HAS_5A_DSP = 0x4000
CHIP_NEED_BSRAM_DP_CE_FIX = 0x8000
# Tile flags
TILE_I3C_CAPABLE_IO = 0x1
@ -1768,6 +1769,8 @@ def main():
chip_flags |= CHIP_NEED_SP_FIX;
if "NEED_BSRAM_OUTREG_FIX" in db.chip_flags:
chip_flags |= CHIP_NEED_BSRAM_OUTREG_FIX;
if "NEED_BSRAM_DP_CE_FIX" in db.chip_flags:
chip_flags |= CHIP_NEED_BSRAM_DP_CE_FIX;
if "NEED_BLKSEL_FIX" in db.chip_flags:
chip_flags |= CHIP_NEED_BLKSEL_FIX;
if "HAS_BANDGAP" in db.chip_flags:

View File

@ -449,6 +449,12 @@ bool GowinUtils::need_BSRAM_OUTREG_fix(void)
return extra->chip_flags & Extra_chip_data_POD::NEED_BSRAM_OUTREG_FIX;
}
bool GowinUtils::need_BSRAM_DP_CE_fix(void)
{
const Extra_chip_data_POD *extra = reinterpret_cast<const Extra_chip_data_POD *>(ctx->chip_info->extra_data.get());
return extra->chip_flags & Extra_chip_data_POD::NEED_BSRAM_DP_CE_FIX;
}
bool GowinUtils::need_BSRAM_RESET_fix(void)
{
const Extra_chip_data_POD *extra = reinterpret_cast<const Extra_chip_data_POD *>(ctx->chip_info->extra_data.get());

View File

@ -110,6 +110,7 @@ struct GowinUtils
bool need_SP_fix(void);
bool need_SDP_fix(void);
bool need_BSRAM_OUTREG_fix(void);
bool need_BSRAM_DP_CE_fix(void);
bool need_BSRAM_RESET_fix(void);
bool need_BLKSEL_fix(void);
bool has_PLL_HCLK(void);

View File

@ -197,7 +197,7 @@ void GowinPacker::pack_adc(void)
auto &ci = *cell.second;
if (is_adc(&ci)) {
gwu.remove_brackets(&ci);
gwu.remove_brackets(&ci);
}
}
}
@ -265,7 +265,7 @@ void GowinPacker::pack_dlldly(void)
log_info(" pack %s to use clock pin at %s\n", ctx->nameOf(ci), ctx->nameOfBel(io_bel));
}
ctx->bindBel(dlldly_bel, ci, STRENGTH_LOCKED);
gwu.remove_brackets(ci);
gwu.remove_brackets(ci);
}
}
@ -439,7 +439,7 @@ void GowinPacker::pack_userflash(bool have_emcu)
ci.addInput(id_INUSEN);
ci.connectPort(id_INUSEN, ctx->nets.at(ctx->id("$PACKER_GND")).get());
}
gwu.remove_brackets(&ci);
gwu.remove_brackets(&ci);
if (have_emcu) {
continue;
@ -505,7 +505,7 @@ void GowinPacker::pack_emcu_and_flash(void)
}
have_emcu = true;
gwu.remove_brackets(&ci);
gwu.remove_brackets(&ci);
// The flash data bus is connected directly to the CPU so just disconnect these networks
// also other non-switched networks

View File

@ -475,16 +475,6 @@ void GowinPacker::pack_DPB(CellInfo *ci)
default_bw = 18;
}
for (int i = 0; i < 14; ++i) {
ci->renamePort(ctx->idf("ADA[%d]", i), ctx->idf("ADA%d", i));
ci->renamePort(ctx->idf("ADB[%d]", i), ctx->idf("ADB%d", i));
}
for (int i = 0; i < 3; ++i) {
ci->renamePort(ctx->idf("BLKSELA[%d]", i), ctx->idf("BLKSELA%d", i));
ci->renamePort(ctx->idf("BLKSELB[%d]", i), ctx->idf("BLKSELB%d", i));
}
if (!ci->params.count(id_BIT_WIDTH_0)) {
ci->setParam(id_BIT_WIDTH_0, Property(default_bw, 32));
}
@ -492,12 +482,30 @@ void GowinPacker::pack_DPB(CellInfo *ci)
bsram_rename_ports(ci, bit_width, "DIA[%d]", "DIA%d");
bsram_rename_ports(ci, bit_width, "DOA[%d]", "DOA%d");
// In BYPASS mode, the OCE signal is dictated by CE.
if (gwu.need_BSRAM_DP_CE_fix()) {
if (bit_width <= 9) {
ci->disconnectPort(id_OCEA);
ci->copyPortTo(id_CEA, ci, id_OCEA);
}
}
if (!ci->params.count(id_BIT_WIDTH_1)) {
ci->setParam(id_BIT_WIDTH_1, Property(default_bw, 32));
}
bit_width = ci->params.at(id_BIT_WIDTH_1).as_int64();
bsram_rename_ports(ci, bit_width, "DIB[%d]", "DIB%d");
bsram_rename_ports(ci, bit_width, "DOB[%d]", "DOB%d");
// In BYPASS mode, the OCE signal is dictated by CE.
if (gwu.need_BSRAM_DP_CE_fix()) {
if (bit_width <= 9) {
ci->disconnectPort(id_OCEB);
ci->copyPortTo(id_CEB, ci, id_OCEB);
}
}
gwu.remove_brackets(ci);
}
void GowinPacker::divide_sp(CellInfo *ci, std::vector<std::unique_ptr<CellInfo>> &new_cells)