Skip to content

Commit

Permalink
apicula: add support for magic sip pins (#1370)
Browse files Browse the repository at this point in the history
* apicula: add support for magic sip pins

* fix nullptr check

* DDR fix by xiwang

* WIP support for setting the iostd

* add iostd
  • Loading branch information
pepijndevos authored Oct 9, 2024
1 parent d27993f commit 028be14
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 0 deletions.
2 changes: 2 additions & 0 deletions common/kernel/relptr.h
Original file line number Diff line number Diff line change
Expand Up @@ -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()); }
Expand Down
1 change: 1 addition & 0 deletions himbaechel/chipdb.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
9 changes: 9 additions & 0 deletions himbaechel/himbaechel_dbgen/chip.py
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand All @@ -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):
Expand Down
30 changes: 30 additions & 0 deletions himbaechel/uarch/gowin/cst.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
Expand Down
12 changes: 12 additions & 0 deletions himbaechel/uarch/gowin/gowin.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
21 changes: 21 additions & 0 deletions himbaechel/uarch/gowin/gowin_arch_gen.py
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,23 @@ 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, 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.
Expand Down Expand Up @@ -1206,6 +1223,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)
Expand Down

0 comments on commit 028be14

Please sign in to comment.