apicula: add support for magic sip pins (#1370)

* apicula: add support for magic sip pins

* fix nullptr check

* DDR fix by xiwang

* WIP support for setting the iostd

* add iostd
This commit is contained in:
Pepijn de Vos 2024-10-09 15:16:36 +02:00 committed by GitHub
parent d27993f019
commit 028be1462a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 75 additions and 0 deletions

View File

@ -33,6 +33,8 @@ template <typename T> struct RelPtr
const T *get() const { return reinterpret_cast<const T *>(reinterpret_cast<const char *>(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()); }

View File

@ -138,6 +138,7 @@ NPNR_PACKED_STRUCT(struct PadInfoPOD {
NPNR_PACKED_STRUCT(struct PackageInfoPOD {
int32_t name;
RelSlice<PadInfoPOD> pads;
RelPtr<uint8_t> extra_data;
});
NPNR_PACKED_STRUCT(struct TileInstPOD {

View File

@ -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 @@ class PackageInfo(BBAStruct):
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):

View File

@ -240,8 +240,38 @@ struct GowinCstReader
}
};
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()) {
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)));
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);
}
}
}
bool gowin_apply_constraints(Context *ctx, std::istream &in)
{
// implicit constraints from SiP pins
if(!ctx->package_info->extra_data.is_null()) {
const Extra_package_data_POD *extra = reinterpret_cast<const Extra_package_data_POD *>(ctx->package_info->extra_data.get());
add_sip_constraints(ctx, extra);
}
GowinCstReader reader(ctx, in);
return reader.run();
}

View File

@ -130,6 +130,18 @@ 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;
int32_t iostd;
});
NPNR_PACKED_STRUCT(struct Extra_package_data_POD {
RelSlice<Constraint_POD> cst;
});
NPNR_PACKED_STRUCT(struct Extra_chip_data_POD {
int32_t chip_flags;
Bottom_io_POD bottom_io;

View File

@ -244,6 +244,23 @@ class ChipExtraData(BBAStruct):
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, 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))
@dataclass
class PadExtraData(BBAStruct):
# Which PLL does this pad belong to.
@ -1206,6 +1223,10 @@ def create_packages(chip: Chip, db: chipdb):
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)