diff --git a/himbaechel/uarch/gowin/gowin.h b/himbaechel/uarch/gowin/gowin.h index 5d79eb30..62e236b6 100644 --- a/himbaechel/uarch/gowin/gowin.h +++ b/himbaechel/uarch/gowin/gowin.h @@ -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 diff --git a/himbaechel/uarch/gowin/gowin_arch_gen.py b/himbaechel/uarch/gowin/gowin_arch_gen.py index 3c1f5aff..648d45e4 100644 --- a/himbaechel/uarch/gowin/gowin_arch_gen.py +++ b/himbaechel/uarch/gowin/gowin_arch_gen.py @@ -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: diff --git a/himbaechel/uarch/gowin/gowin_utils.cc b/himbaechel/uarch/gowin/gowin_utils.cc index 371e3365..5b675c61 100644 --- a/himbaechel/uarch/gowin/gowin_utils.cc +++ b/himbaechel/uarch/gowin/gowin_utils.cc @@ -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(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(ctx->chip_info->extra_data.get()); diff --git a/himbaechel/uarch/gowin/gowin_utils.h b/himbaechel/uarch/gowin/gowin_utils.h index aebae06d..6e960855 100644 --- a/himbaechel/uarch/gowin/gowin_utils.h +++ b/himbaechel/uarch/gowin/gowin_utils.h @@ -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); diff --git a/himbaechel/uarch/gowin/pack.cc b/himbaechel/uarch/gowin/pack.cc index 03502bd8..ab2327a6 100644 --- a/himbaechel/uarch/gowin/pack.cc +++ b/himbaechel/uarch/gowin/pack.cc @@ -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 diff --git a/himbaechel/uarch/gowin/pack_bsram.cc b/himbaechel/uarch/gowin/pack_bsram.cc index 59b8ceeb..1e3ad5d4 100644 --- a/himbaechel/uarch/gowin/pack_bsram.cc +++ b/himbaechel/uarch/gowin/pack_bsram.cc @@ -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> &new_cells)