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:
parent
d27993f019
commit
028be1462a
@ -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()); }
|
||||
|
@ -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 {
|
||||
|
@ -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):
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user