From 832275cb7579ee1147afb5092f9b0c86f39c5582 Mon Sep 17 00:00:00 2001 From: Pepijn de Vos Date: Fri, 20 Sep 2024 18:01:44 +0200 Subject: [PATCH 1/5] apicula: add support for magic sip pins --- himbaechel/chipdb.h | 1 + himbaechel/himbaechel_dbgen/chip.py | 9 +++++++++ himbaechel/uarch/gowin/cst.cc | 23 +++++++++++++++++++++++ himbaechel/uarch/gowin/gowin.h | 11 +++++++++++ himbaechel/uarch/gowin/gowin_arch_gen.py | 20 ++++++++++++++++++++ 5 files changed, 64 insertions(+) diff --git a/himbaechel/chipdb.h b/himbaechel/chipdb.h index 2ac7f60b42..17430ac4c2 100644 --- a/himbaechel/chipdb.h +++ b/himbaechel/chipdb.h @@ -138,6 +138,7 @@ NPNR_PACKED_STRUCT(struct PadInfoPOD { NPNR_PACKED_STRUCT(struct PackageInfoPOD { int32_t name; RelSlice pads; + RelPtr extra_data; }); NPNR_PACKED_STRUCT(struct TileInstPOD { diff --git a/himbaechel/himbaechel_dbgen/chip.py b/himbaechel/himbaechel_dbgen/chip.py index 19aa8914d6..8650813d93 100644 --- a/himbaechel/himbaechel_dbgen/chip.py +++ b/himbaechel/himbaechel_dbgen/chip.py @@ -411,6 +411,7 @@ class PackageInfo(BBAStruct): strs: StringPool name: IdString pads: list[int] = field(default_factory=list) + extra_data: object = None def create_pad(self, package_pin: str, tile: str, bel: str, pad_function: str, pad_bank: int, flags: int = 0): pad = PadInfo(package_pin = self.strs.id(package_pin), tile = self.strs.id(tile), bel = self.strs.id(bel), @@ -424,10 +425,18 @@ def serialise_lists(self, context: str, bba: BBAWriter): bba.label(f"{context}_pads") for i, pad in enumerate(self.pads): pad.serialise(f"{context}_pad{i}", bba) + if self.extra_data is not None: + self.extra_data.serialise_lists(f"{context}_extra_data", bba) + bba.label(f"{context}_extra_data") + self.extra_data.serialise(f"{context}_extra_data", bba) def serialise(self, context: str, bba: BBAWriter): bba.u32(self.name.index) bba.slice(f"{context}_pads", len(self.pads)) + if self.extra_data is not None: + bba.ref(f"{context}_extra_data") + else: + bba.u32(0) class TimingValue(BBAStruct): def __init__(self, fast_min=0, fast_max=None, slow_min=None, slow_max=None): diff --git a/himbaechel/uarch/gowin/cst.cc b/himbaechel/uarch/gowin/cst.cc index 310e1406f2..26f1ac7ae3 100644 --- a/himbaechel/uarch/gowin/cst.cc +++ b/himbaechel/uarch/gowin/cst.cc @@ -240,8 +240,31 @@ struct GowinCstReader } }; + +void add_sip_constraints(Context *ctx, const Extra_package_data_POD *extra) { + for(auto cst : extra->cst) { + auto it = ctx->cells.find(IdString(cst.net)); + if (it == ctx->cells.end()) { + log_info("Cell %s not found\n", IdString(cst.net).c_str(ctx)); + continue; + } + Loc loc = Loc(cst.col, cst.row, cst.bel); + BelId bel = ctx->getBelByLocation(loc); + if (bel == BelId()) { + log_error("Pin not found.\n"); + } + it->second->setAttr(IdString(ID_BEL), std::string(ctx->nameOfBel(bel))); + } +} + bool gowin_apply_constraints(Context *ctx, std::istream &in) { + // implicit constraints from SiP pins + const Extra_package_data_POD *extra = reinterpret_cast(ctx->package_info->extra_data.get()); + if(extra != nullptr) { + add_sip_constraints(ctx, extra); + } + GowinCstReader reader(ctx, in); return reader.run(); } diff --git a/himbaechel/uarch/gowin/gowin.h b/himbaechel/uarch/gowin/gowin.h index 1588b27b91..174feb530d 100644 --- a/himbaechel/uarch/gowin/gowin.h +++ b/himbaechel/uarch/gowin/gowin.h @@ -130,6 +130,17 @@ NPNR_PACKED_STRUCT(struct Wire_bel_POD { int32_t side; }); +NPNR_PACKED_STRUCT(struct Constraint_POD { + int32_t net; + int32_t row; + int32_t col; + int32_t bel; +}); + +NPNR_PACKED_STRUCT(struct Extra_package_data_POD { + RelSlice cst; +}); + NPNR_PACKED_STRUCT(struct Extra_chip_data_POD { int32_t chip_flags; Bottom_io_POD bottom_io; diff --git a/himbaechel/uarch/gowin/gowin_arch_gen.py b/himbaechel/uarch/gowin/gowin_arch_gen.py index 7daed96354..6a71ad8b1a 100644 --- a/himbaechel/uarch/gowin/gowin_arch_gen.py +++ b/himbaechel/uarch/gowin/gowin_arch_gen.py @@ -244,6 +244,22 @@ def serialise(self, context: str, bba: BBAWriter): bba.slice(f"{context}_dcs_bels", len(self.dcs_bels)) bba.slice(f"{context}_dhcen_bels", len(self.dhcen_bels)) +@dataclass +class PackageExtraData(BBAStruct): + strs: StringPool + cst: list + + def serialise_lists(self, context: str, bba: BBAWriter): + bba.label(f"{context}_constraints") + for (net, row, col, bel) in self.cst: + bba.u32(self.strs.id(net).index) + bba.u32(row) + bba.u32(col) + bba.u32(ord(bel[0])-ord('A')+IOBA_Z) + + def serialise(self, context: str, bba: BBAWriter): + bba.slice(f"{context}_constraints", len(self.cst)) + @dataclass class PadExtraData(BBAStruct): # Which PLL does this pad belong to. @@ -1206,6 +1222,10 @@ def ioloc_to_tile_bel(ioloc): continue created_pkgs.add(partno) pkg = chip.create_package(partno) + + if variant in db.sip_cst and pkgname in db.sip_cst[variant]: + pkg.extra_data = PackageExtraData(chip.strs, db.sip_cst[variant][pkgname]) + for pinno, pininfo in db.pinout[variant][pkgname].items(): io_loc, cfgs = pininfo tile, bel = ioloc_to_tile_bel(io_loc) From 31a7e22aa6cb68bd36de3e4ccbc3da3484dfee67 Mon Sep 17 00:00:00 2001 From: Pepijn de Vos Date: Mon, 23 Sep 2024 13:54:55 +0200 Subject: [PATCH 2/5] fix nullptr check --- common/kernel/relptr.h | 2 ++ himbaechel/uarch/gowin/cst.cc | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/common/kernel/relptr.h b/common/kernel/relptr.h index f0f45b7d03..4a98dd682b 100644 --- a/common/kernel/relptr.h +++ b/common/kernel/relptr.h @@ -33,6 +33,8 @@ template struct RelPtr const T *get() const { return reinterpret_cast(reinterpret_cast(this) + offset); } + bool is_null() const { return offset == 0; } + const T &operator[](std::size_t index) const { return get()[index]; } const T &operator*() const { return *(get()); } diff --git a/himbaechel/uarch/gowin/cst.cc b/himbaechel/uarch/gowin/cst.cc index 26f1ac7ae3..f6ee1378b5 100644 --- a/himbaechel/uarch/gowin/cst.cc +++ b/himbaechel/uarch/gowin/cst.cc @@ -241,7 +241,7 @@ struct GowinCstReader }; -void add_sip_constraints(Context *ctx, const Extra_package_data_POD *extra) { +static void add_sip_constraints(Context *ctx, const Extra_package_data_POD *extra) { for(auto cst : extra->cst) { auto it = ctx->cells.find(IdString(cst.net)); if (it == ctx->cells.end()) { @@ -260,8 +260,8 @@ void add_sip_constraints(Context *ctx, const Extra_package_data_POD *extra) { bool gowin_apply_constraints(Context *ctx, std::istream &in) { // implicit constraints from SiP pins - const Extra_package_data_POD *extra = reinterpret_cast(ctx->package_info->extra_data.get()); - if(extra != nullptr) { + if(!ctx->package_info->extra_data.is_null()) { + const Extra_package_data_POD *extra = reinterpret_cast(ctx->package_info->extra_data.get()); add_sip_constraints(ctx, extra); } From bcab74cc1405fd6589cc444b9fd6f7354c1f2eb4 Mon Sep 17 00:00:00 2001 From: Pepijn de Vos Date: Wed, 2 Oct 2024 11:30:51 +0200 Subject: [PATCH 3/5] DDR fix by xiwang --- himbaechel/uarch/gowin/gowin_utils.h | 14 ++++++++++++++ himbaechel/uarch/gowin/pack.cc | 4 ++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/himbaechel/uarch/gowin/gowin_utils.h b/himbaechel/uarch/gowin/gowin_utils.h index f9276c10e9..71f60f8c99 100644 --- a/himbaechel/uarch/gowin/gowin_utils.h +++ b/himbaechel/uarch/gowin/gowin_utils.h @@ -1,6 +1,7 @@ #ifndef GOWIN_UTILS_H #define GOWIN_UTILS_H +#include "design_utils.h" #include "idstringlist.h" #include "nextpnr_namespaces.h" #include "nextpnr_types.h" @@ -37,6 +38,19 @@ struct GowinUtils BelId get_dcs_bel(IdString spine_name); BelId get_dhcen_bel(WireId hclkin_wire, IdString &side); + // ports + inline bool port_used(CellInfo *cell, IdString port_name) + { + if (!nextpnr_himbaechel::port_used(cell, port_name)) { + return false; + } + NetInfo *ni = cell->ports.at(port_name).net; + if (ni->driver.cell == nullptr) { + return false; + } + return ni->users.entries() != 0; + } + // BSRAM bool has_SP32(void); bool need_SP_fix(void); diff --git a/himbaechel/uarch/gowin/pack.cc b/himbaechel/uarch/gowin/pack.cc index 78389d7fd7..f774bbc32b 100644 --- a/himbaechel/uarch/gowin/pack.cc +++ b/himbaechel/uarch/gowin/pack.cc @@ -454,7 +454,7 @@ struct GowinPacker } // if Q1 is connected then disconnect it too - if (port_used(&ci, tx_port)) { + if (gwu.port_used(&ci, tx_port)) { NPNR_ASSERT(out_iob == net_only_drives(ctx, ci.ports.at(tx_port).net, is_iob, id_OEN, true)); nets_to_remove.push_back(ci.getPort(tx_port)->name); out_iob->disconnectPort(id_OEN); @@ -3160,7 +3160,7 @@ struct GowinPacker // add invertor int lut_idx = 0; auto add_inv = [&](IdString port, PortType port_type) { - if (!port_used(&ci, port)) { + if (!gwu.port_used(&ci, port)) { return; } From 6d9095ead85827de00d954780e21fd837c228d73 Mon Sep 17 00:00:00 2001 From: Pepijn de Vos Date: Wed, 2 Oct 2024 15:32:05 +0200 Subject: [PATCH 4/5] WIP support for setting the iostd --- himbaechel/uarch/gowin/gowin.h | 1 + himbaechel/uarch/gowin/gowin_arch_gen.py | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/himbaechel/uarch/gowin/gowin.h b/himbaechel/uarch/gowin/gowin.h index 174feb530d..001c1cfb07 100644 --- a/himbaechel/uarch/gowin/gowin.h +++ b/himbaechel/uarch/gowin/gowin.h @@ -135,6 +135,7 @@ NPNR_PACKED_STRUCT(struct Constraint_POD { int32_t row; int32_t col; int32_t bel; + int32_t iostd; }); NPNR_PACKED_STRUCT(struct Extra_package_data_POD { diff --git a/himbaechel/uarch/gowin/gowin_arch_gen.py b/himbaechel/uarch/gowin/gowin_arch_gen.py index 6a71ad8b1a..473efa21a9 100644 --- a/himbaechel/uarch/gowin/gowin_arch_gen.py +++ b/himbaechel/uarch/gowin/gowin_arch_gen.py @@ -251,11 +251,12 @@ class PackageExtraData(BBAStruct): def serialise_lists(self, context: str, bba: BBAWriter): bba.label(f"{context}_constraints") - for (net, row, col, bel) in self.cst: + for (net, row, col, bel, iostd) in self.cst: bba.u32(self.strs.id(net).index) bba.u32(row) bba.u32(col) bba.u32(ord(bel[0])-ord('A')+IOBA_Z) + bba.u32(self.strs.id(iostd).index if iostd else 0) def serialise(self, context: str, bba: BBAWriter): bba.slice(f"{context}_constraints", len(self.cst)) From 8bc42ce53b1b78750ac1ae9b1992dbb2c15a819b Mon Sep 17 00:00:00 2001 From: Pepijn de Vos Date: Wed, 9 Oct 2024 13:22:32 +0200 Subject: [PATCH 5/5] add iostd --- himbaechel/uarch/gowin/cst.cc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/himbaechel/uarch/gowin/cst.cc b/himbaechel/uarch/gowin/cst.cc index f6ee1378b5..a22c64eaf0 100644 --- a/himbaechel/uarch/gowin/cst.cc +++ b/himbaechel/uarch/gowin/cst.cc @@ -254,6 +254,13 @@ static void add_sip_constraints(Context *ctx, const Extra_package_data_POD *extr log_error("Pin not found.\n"); } it->second->setAttr(IdString(ID_BEL), std::string(ctx->nameOfBel(bel))); + + if(cst.iostd > 0) { + std::string attr = "&IO_TYPE="; + attr += IdString(cst.iostd).c_str(ctx); + boost::algorithm::to_upper(attr); + it->second->setAttr(ctx->id(attr), 1); + } } }