From dfb701b5abe3d576d4410ee2a016d26c7dbe54c4 Mon Sep 17 00:00:00 2001 From: YRabbit Date: Mon, 7 Aug 2023 18:20:08 +1000 Subject: [PATCH] gowin: Himbaechel. Add OSER8 Signed-off-by: YRabbit --- himbaechel/uarch/gowin/constids.inc | 1 + himbaechel/uarch/gowin/gowin.cc | 10 +++--- himbaechel/uarch/gowin/gowin.h | 54 ++++++++++++++++------------- himbaechel/uarch/gowin/pack.cc | 37 ++++++++++++++++++-- 4 files changed, 70 insertions(+), 32 deletions(-) diff --git a/himbaechel/uarch/gowin/constids.inc b/himbaechel/uarch/gowin/constids.inc index 883961ed..ec5116ba 100644 --- a/himbaechel/uarch/gowin/constids.inc +++ b/himbaechel/uarch/gowin/constids.inc @@ -1062,6 +1062,7 @@ X(GOWIN_VCC) X(PLL) X(BOTTOM_IO_PORT_A) X(BOTTOM_IO_PORT_B) +X(IOLOGIC_DUMMY) // wire types X(GLOBAL_CLK) diff --git a/himbaechel/uarch/gowin/gowin.cc b/himbaechel/uarch/gowin/gowin.cc index cebefa89..538dc294 100644 --- a/himbaechel/uarch/gowin/gowin.cc +++ b/himbaechel/uarch/gowin/gowin.cc @@ -185,7 +185,7 @@ void GowinImpl::postRoute() ci->setAttr(id_IOLOGIC_FCLK, Property("UNKNOWN")); const NetInfo *h_net = ci->getPort(id_FCLK); if (h_net) { - for (auto const &user : h_net->users) { + for (auto &user : h_net->users) { if (user.port != id_FCLK) { continue; } @@ -195,7 +195,7 @@ void GowinImpl::postRoute() PipId up_pip = h_net->wires.at(ctx->getNetinfoSinkWire(h_net, user, 0)).pip; IdString up_wire_name = ctx->getWireName(ctx->getPipSrcWire(up_pip))[1]; if (up_wire_name.in(id_HCLK_OUT0, id_HCLK_OUT1, id_HCLK_OUT2, id_HCLK_OUT3)) { - ci->setAttr(id_IOLOGIC_FCLK, Property(up_wire_name.str(ctx))); + user.cell->setAttr(id_IOLOGIC_FCLK, Property(up_wire_name.str(ctx))); } if (ctx->debug) { log_info("HCLK user cell:%s, port:%s, wire:%s, pip:%s, up wire:%s\n", @@ -402,8 +402,7 @@ void GowinImpl::notifyBelChange(BelId bel, CellInfo *cell) // OSER8 took both IOLOGIC bels in the tile if (cell->type == id_OSER8) { Loc loc = ctx->getBelLocation(bel); - loc.z = BelZ::IOLOGICA_Z + (1 - (loc.z - BelZ::IOLOGICA_Z)); - inactive_bels.insert(ctx->getBelByLocation(loc)); + inactive_bels.insert(ctx->getBelByLocation(get_pair_iologic_bel(loc))); } } else { // the unbind is about to happen @@ -411,8 +410,7 @@ void GowinImpl::notifyBelChange(BelId bel, CellInfo *cell) // OSER8 took both IOLOGIC bels in the tile if (ci->type == id_OSER8) { Loc loc = ctx->getBelLocation(bel); - loc.z = BelZ::IOLOGICA_Z + (1 - (loc.z - BelZ::IOLOGICA_Z)); - inactive_bels.erase(ctx->getBelByLocation(loc)); + inactive_bels.erase(ctx->getBelByLocation(get_pair_iologic_bel(loc))); } } } diff --git a/himbaechel/uarch/gowin/gowin.h b/himbaechel/uarch/gowin/gowin.h index 4051b075..66da2d4e 100644 --- a/himbaechel/uarch/gowin/gowin.h +++ b/himbaechel/uarch/gowin/gowin.h @@ -5,6 +5,31 @@ NEXTPNR_NAMESPACE_BEGIN +// Bels Z ranges. It is desirable that these numbers be synchronized with the chipdb generator +namespace BelZ { +enum +{ + LUT0_Z = 0, + LUT7_Z = 14, + MUX20_Z = 16, + MUX21_Z = 18, + MUX23_Z = 22, + MUX27_Z = 29, + ALU0_Z = 30, // :35, 6 ALU + RAMW_Z = 36, // RAM16SDP4 + + IOBA_Z = 50, + IOBB_Z = 51, // +IOBC...IOBL + + IOLOGICA_Z = 70, + + PLL_Z = 275, + GSR_Z = 276, + VCC_Z = 277, + VSS_Z = 278 +}; +} + namespace BelFlags { static constexpr uint32_t FLAG_SIMPLE_IO = 0x100; } @@ -93,32 +118,13 @@ inline bool is_simple_io_bel(const ChipInfoPOD *chip, BelId bel) return chip_bel_info(chip, bel).flags & BelFlags::FLAG_SIMPLE_IO; } -} // namespace - -// Bels Z ranges. It is desirable that these numbers be synchronized with the chipdb generator -namespace BelZ { -enum +inline Loc get_pair_iologic_bel(Loc loc) { - LUT0_Z = 0, - LUT7_Z = 14, - MUX20_Z = 16, - MUX21_Z = 18, - MUX23_Z = 22, - MUX27_Z = 29, - ALU0_Z = 30, // :35, 6 ALU - RAMW_Z = 36, // RAM16SDP4 - - IOBA_Z = 50, - IOBB_Z = 51, // +IOBC...IOBL - - IOLOGICA_Z = 70, - - PLL_Z = 275, - GSR_Z = 276, - VCC_Z = 277, - VSS_Z = 278 -}; + loc.z = BelZ::IOLOGICA_Z + (1 - (loc.z - BelZ::IOLOGICA_Z)); + return loc; } +} // namespace + NEXTPNR_NAMESPACE_END #endif diff --git a/himbaechel/uarch/gowin/pack.cc b/himbaechel/uarch/gowin/pack.cc index 922134b0..f6d6f07f 100644 --- a/himbaechel/uarch/gowin/pack.cc +++ b/himbaechel/uarch/gowin/pack.cc @@ -82,7 +82,6 @@ struct GowinPacker } }; - log_info("cnd:%d\n", cnd); IdString wire_a_net = get_bottom_io_wire_a_net(ctx->chip_info, cnd); connect_io_wire(id_BOTTOM_IO_PORT_A, wire_a_net); @@ -381,6 +380,40 @@ struct GowinPacker make_iob_nets(*out_iob); } + IdString create_aux_iologic_name(IdString main_name, int idx = 0) + { + std::string sfx(""); + if (idx) { + sfx = std::to_string(idx); + } + return ctx->id(main_name.str(ctx) + std::string("_aux") + sfx); + } + + BelId get_aux_iologic_bel(const CellInfo &ci) + { + return ctx->getBelByLocation(get_pair_iologic_bel(ctx->getBelLocation(ci.bel))); + } + + void create_aux_iologic_cells(CellInfo &ci) + { + if (ci.type.in(id_ODDR, id_ODDRC, id_OSER4)) { + return; + } + IdString aux_name = create_aux_iologic_name(ci.name); + BelId bel = get_aux_iologic_bel(ci); + ctx->createCell(aux_name, id_IOLOGIC_DUMMY); + CellInfo *aux = ctx->cells[aux_name].get(); + aux->addInput(id_PCLK); + ci.copyPortTo(id_PCLK, ctx->cells.at(aux_name).get(), id_PCLK); + aux->addInput(id_FCLK); + ci.copyPortTo(id_FCLK, ctx->cells.at(aux_name).get(), id_FCLK); + aux->addInput(id_RESET); + ci.copyPortTo(id_RESET, ctx->cells.at(aux_name).get(), id_RESET); + ctx->cells.at(aux_name)->setParam(ctx->id("OUTMODE"), Property("DDRENABLE")); + ctx->cells.at(aux_name)->setAttr(ctx->id("IOLOGIC_TYPE"), Property("DUMMY")); + ctx->bindBel(bel, aux, PlaceStrength::STRENGTH_LOCKED); + } + void pack_iologic() { log_info("Pack IO logic...\n"); @@ -396,6 +429,7 @@ struct GowinPacker } if (ci.type.in(id_ODDR, id_ODDRC, id_OSER4, id_OSER8)) { pack_bi_output_iol(ci, cells_to_remove, nets_to_remove); + create_aux_iologic_cells(ci); continue; } } @@ -407,7 +441,6 @@ struct GowinPacker ctx->nets.erase(net); } } - // =================================== // Constant nets // ===================================