From 6eeac1cabf5b98d9bbd74c6e7022390a84af7fb3 Mon Sep 17 00:00:00 2001 From: YRabbit Date: Thu, 20 Jul 2023 12:09:14 +1000 Subject: [PATCH] gowin: Himbaechel. Use pin functions info Use information about pin functions in the clock router. Signed-off-by: YRabbit --- himbaechel/uarch/gowin/globals.cc | 18 ++++++++++++++--- himbaechel/uarch/gowin/gowin.cc | 4 ++++ himbaechel/uarch/gowin/gowin_arch_gen.py | 1 + himbaechel/uarch/gowin/gowin_utils.cc | 25 ++++++++++++++++++++++++ himbaechel/uarch/gowin/gowin_utils.h | 24 +++++++++++++++++++++++ himbaechel/uarch/gowin/pack.cc | 16 +++++++-------- 6 files changed, 77 insertions(+), 11 deletions(-) create mode 100644 himbaechel/uarch/gowin/gowin_utils.cc create mode 100644 himbaechel/uarch/gowin/gowin_utils.h diff --git a/himbaechel/uarch/gowin/globals.cc b/himbaechel/uarch/gowin/globals.cc index 52dd58ba..bb2e2b08 100644 --- a/himbaechel/uarch/gowin/globals.cc +++ b/himbaechel/uarch/gowin/globals.cc @@ -29,14 +29,16 @@ #include "globals.h" #include "gowin.h" +#include "gowin_utils.h" NEXTPNR_NAMESPACE_BEGIN struct GowinGlobalRouter { Context *ctx; + GowinUtils gwu; - GowinGlobalRouter(Context *ctx) : ctx(ctx){}; + GowinGlobalRouter(Context *ctx) : ctx(ctx) { gwu.init(ctx); }; // allow io->global, global->global and global->tile clock bool global_pip_filter(PipId pip) const @@ -157,8 +159,18 @@ struct GowinGlobalRouter bool driver_is_clksrc(const PortRef &driver) { - // XXX dedicated pins - return driver.port == id_O; + // dedicated pins + if (CellTypePort(driver) == CellTypePort(id_IBUF, id_O)) { + + NPNR_ASSERT(driver.cell->bel != BelId()); + IdStringList pin_func = gwu.get_pin_funcs(driver.cell->bel); + for (size_t i = 0; i < pin_func.size(); ++i) { + if (pin_func[i].str(ctx).rfind("GCLKT", 0) == 0) { + return true; + } + } + } + return false; } void run(void) diff --git a/himbaechel/uarch/gowin/gowin.cc b/himbaechel/uarch/gowin/gowin.cc index 5fe2a004..6c836645 100644 --- a/himbaechel/uarch/gowin/gowin.cc +++ b/himbaechel/uarch/gowin/gowin.cc @@ -12,6 +12,7 @@ #include "cst.h" #include "globals.h" #include "gowin.h" +#include "gowin_utils.h" #include "pack.h" NEXTPNR_NAMESPACE_BEGIN @@ -38,6 +39,7 @@ struct GowinImpl : HimbaechelAPI private: HimbaechelHelpers h; + GowinUtils gwu; IdString chip; IdString partno; @@ -70,6 +72,8 @@ void GowinImpl::init(Context *ctx) h.init(ctx); HimbaechelAPI::init(ctx); + gwu.init(ctx); + const ArchArgs &args = ctx->getArchArgs(); // These fields go in the header of the output JSON file and can help // gowin_pack support different architectures diff --git a/himbaechel/uarch/gowin/gowin_arch_gen.py b/himbaechel/uarch/gowin/gowin_arch_gen.py index 8a935887..824e5977 100644 --- a/himbaechel/uarch/gowin/gowin_arch_gen.py +++ b/himbaechel/uarch/gowin/gowin_arch_gen.py @@ -348,6 +348,7 @@ def create_ssram_tiletype(chip: Chip, db: chipdb, x: int, y: int, ttyp: int): tt.add_bel_pin(ff, f"WRE", "LSR2", PinType.INPUT) return (ttyp, tt) +# pinouts, packages... _tbrlre = re.compile(r"IO([TBRL])(\d+)(\w)") def create_packages(chip: Chip, db: chipdb): def ioloc_to_tile_bel(ioloc): diff --git a/himbaechel/uarch/gowin/gowin_utils.cc b/himbaechel/uarch/gowin/gowin_utils.cc new file mode 100644 index 00000000..7cc82fed --- /dev/null +++ b/himbaechel/uarch/gowin/gowin_utils.cc @@ -0,0 +1,25 @@ +#include "gowin_utils.h" + +#include "log.h" +#include "nextpnr.h" +#include "util.h" + +NEXTPNR_NAMESPACE_BEGIN + +// pin functions: GCLKT_4, SSPI_CS, READY etc +IdStringList GowinUtils::get_pin_funcs(BelId bel) +{ + IdStringList bel_name = ctx->getBelName(bel); + + const PadInfoPOD *pins = ctx->package_info->pads.get(); + size_t len = ctx->package_info->pads.ssize(); + for (size_t i = 0; i < len; i++) { + const PadInfoPOD *pin = &pins[i]; + if (IdString(pin->tile) == bel_name[0] && IdString(pin->bel) == bel_name[1]) { + return IdStringList::parse(ctx, IdString(pin->pad_function).str(ctx)); + } + } + return IdStringList(); +} + +NEXTPNR_NAMESPACE_END diff --git a/himbaechel/uarch/gowin/gowin_utils.h b/himbaechel/uarch/gowin/gowin_utils.h new file mode 100644 index 00000000..ba5b7389 --- /dev/null +++ b/himbaechel/uarch/gowin/gowin_utils.h @@ -0,0 +1,24 @@ +#ifndef GOWIN_UTILS_H +#define GOWIN_UTILS_H + +#include "idstringlist.h" +#include "nextpnr_namespaces.h" +#include "nextpnr_types.h" + +NEXTPNR_NAMESPACE_BEGIN + +struct GowinUtils +{ + Context *ctx; + + GowinUtils() {} + + void init(Context *ctx) { this->ctx = ctx; } + + // pin functions: GCLKT_4, SSPI_CS, READY etc + IdStringList get_pin_funcs(BelId bel); +}; + +NEXTPNR_NAMESPACE_END + +#endif diff --git a/himbaechel/uarch/gowin/pack.cc b/himbaechel/uarch/gowin/pack.cc index 07c84e29..79406698 100644 --- a/himbaechel/uarch/gowin/pack.cc +++ b/himbaechel/uarch/gowin/pack.cc @@ -305,8 +305,8 @@ struct GowinPacker // create ALU chain void pack_alus(void) { - static CellTypePort cell_alu_cout = CellTypePort(id_ALU, id_COUT); - static CellTypePort cell_alu_cin = CellTypePort(id_ALU, id_CIN); + const CellTypePort cell_alu_cout = CellTypePort(id_ALU, id_COUT); + const CellTypePort cell_alu_cin = CellTypePort(id_ALU, id_CIN); std::vector> new_cells; log_info("Pack ALUs...\n"); @@ -409,12 +409,12 @@ struct GowinPacker void constrain_lutffs(void) { // Constrain directly connected LUTs and FFs together to use dedicated resources - auto lut_outs = pool{{id_LUT1, id_F}, {id_LUT2, id_F}, {id_LUT3, id_F}, {id_LUT4, id_F}}; - auto dff_ins = pool{{id_DFF, id_D}, {id_DFFE, id_D}, {id_DFFN, id_D}, {id_DFFNE, id_D}, - {id_DFFS, id_D}, {id_DFFSE, id_D}, {id_DFFNS, id_D}, {id_DFFNSE, id_D}, - {id_DFFR, id_D}, {id_DFFRE, id_D}, {id_DFFNR, id_D}, {id_DFFNRE, id_D}, - {id_DFFP, id_D}, {id_DFFPE, id_D}, {id_DFFNP, id_D}, {id_DFFNPE, id_D}, - {id_DFFC, id_D}, {id_DFFCE, id_D}, {id_DFFNC, id_D}, {id_DFFNCE, id_D}}; + const pool lut_outs{{id_LUT1, id_F}, {id_LUT2, id_F}, {id_LUT3, id_F}, {id_LUT4, id_F}}; + const pool dff_ins{{id_DFF, id_D}, {id_DFFE, id_D}, {id_DFFN, id_D}, {id_DFFNE, id_D}, + {id_DFFS, id_D}, {id_DFFSE, id_D}, {id_DFFNS, id_D}, {id_DFFNSE, id_D}, + {id_DFFR, id_D}, {id_DFFRE, id_D}, {id_DFFNR, id_D}, {id_DFFNRE, id_D}, + {id_DFFP, id_D}, {id_DFFPE, id_D}, {id_DFFNP, id_D}, {id_DFFNPE, id_D}, + {id_DFFC, id_D}, {id_DFFCE, id_D}, {id_DFFNC, id_D}, {id_DFFNCE, id_D}}; int lutffs = h.constrain_cell_pairs(lut_outs, dff_ins, 1); log_info("Constrained %d LUTFF pairs.\n", lutffs);