Merge pull request #553 from YosysHQ/rel-slice
Switch from RelPtr to RelSlice
This commit is contained in:
commit
b671d8f59d
@ -59,7 +59,7 @@ RUN set -e -x ;\
|
||||
cd /usr/local/src ;\
|
||||
git clone --recursive https://github.com/daveshah1/prjoxide.git ;\
|
||||
cd prjoxide ;\
|
||||
git reset --hard 72dbb7973f31a30c3b9d18f3bac97caaea9a7f33 ;\
|
||||
git reset --hard a73e1629f2ec6618e492047577912d8d50115708 ;\
|
||||
cd libprjoxide ;\
|
||||
PATH=$PATH:$HOME/.cargo/bin cargo install --path prjoxide
|
||||
|
||||
|
42
common/relptr.h
Normal file
42
common/relptr.h
Normal file
@ -0,0 +1,42 @@
|
||||
// This is intended to be included inside arch.h only.
|
||||
|
||||
template <typename T> struct RelPtr
|
||||
{
|
||||
int32_t offset;
|
||||
|
||||
const T *get() const { return reinterpret_cast<const T *>(reinterpret_cast<const char *>(this) + offset); }
|
||||
|
||||
const T &operator[](size_t index) const { return get()[index]; }
|
||||
|
||||
const T &operator*() const { return *(get()); }
|
||||
|
||||
const T *operator->() const { return get(); }
|
||||
|
||||
RelPtr(const RelPtr &) = delete;
|
||||
RelPtr &operator=(const RelPtr &) = delete;
|
||||
};
|
||||
|
||||
NPNR_PACKED_STRUCT(template <typename T> struct RelSlice {
|
||||
int32_t offset;
|
||||
uint32_t length;
|
||||
|
||||
const T *get() const { return reinterpret_cast<const T *>(reinterpret_cast<const char *>(this) + offset); }
|
||||
|
||||
const T &operator[](size_t index) const
|
||||
{
|
||||
NPNR_ASSERT(index < length);
|
||||
return get()[index];
|
||||
}
|
||||
|
||||
const T *begin() const { return get(); }
|
||||
const T *end() const { return get() + length; }
|
||||
|
||||
const size_t size() const { return length; }
|
||||
|
||||
const T &operator*() const { return *(get()); }
|
||||
|
||||
const T *operator->() const { return get(); }
|
||||
|
||||
RelSlice(const RelSlice &) = delete;
|
||||
RelSlice &operator=(const RelSlice &) = delete;
|
||||
});
|
120
ecp5/arch.cc
120
ecp5/arch.cc
@ -87,8 +87,8 @@ std::vector<std::string> Arch::getSupportedPackages(ArchArgs::ArchArgsTypes chip
|
||||
{
|
||||
const ChipInfoPOD *chip_info = get_chip_info(chip);
|
||||
std::vector<std::string> packages;
|
||||
for (int i = 0; i < chip_info->num_packages; i++)
|
||||
packages.push_back(chip_info->package_info[i].name.get());
|
||||
for (auto &pkg : chip_info->package_info)
|
||||
packages.push_back(pkg.name.get());
|
||||
return packages;
|
||||
}
|
||||
|
||||
@ -104,9 +104,9 @@ Arch::Arch(ArchArgs args) : args(args)
|
||||
"maintainer)!\n");
|
||||
|
||||
package_info = nullptr;
|
||||
for (int i = 0; i < chip_info->num_packages; i++) {
|
||||
if (args.package == chip_info->package_info[i].name.get()) {
|
||||
package_info = &(chip_info->package_info[i]);
|
||||
for (auto &pkg : chip_info->package_info) {
|
||||
if (args.package == pkg.name.get()) {
|
||||
package_info = &pkg;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -207,7 +207,7 @@ BelId Arch::getBelByName(IdString name) const
|
||||
std::tie(loc.x, loc.y, basename) = split_identifier_name(name.str(this));
|
||||
ret.location = loc;
|
||||
const LocationTypePOD *loci = locInfo(ret);
|
||||
for (int i = 0; i < loci->num_bels; i++) {
|
||||
for (int i = 0; i < int(loci->bel_data.size()); i++) {
|
||||
if (std::strcmp(loci->bel_data[i].name.get(), basename.c_str()) == 0) {
|
||||
ret.index = i;
|
||||
break;
|
||||
@ -225,7 +225,7 @@ BelRange Arch::getBelsByTile(int x, int y) const
|
||||
br.b.cursor_tile = y * chip_info->width + x;
|
||||
br.e.cursor_tile = y * chip_info->width + x;
|
||||
br.b.cursor_index = 0;
|
||||
br.e.cursor_index = chip_info->locations[chip_info->location_type[br.b.cursor_tile]].num_bels - 1;
|
||||
br.e.cursor_index = int(chip_info->locations[chip_info->location_type[br.b.cursor_tile]].bel_data.size()) - 1;
|
||||
br.b.chip = chip_info;
|
||||
br.e.chip = chip_info;
|
||||
if (br.e.cursor_index == -1)
|
||||
@ -241,12 +241,10 @@ WireId Arch::getBelPinWire(BelId bel, IdString pin) const
|
||||
|
||||
NPNR_ASSERT(bel != BelId());
|
||||
|
||||
int num_bel_wires = locInfo(bel)->bel_data[bel.index].num_bel_wires;
|
||||
const BelWirePOD *bel_wires = locInfo(bel)->bel_data[bel.index].bel_wires.get();
|
||||
for (int i = 0; i < num_bel_wires; i++)
|
||||
if (bel_wires[i].port == pin.index) {
|
||||
ret.location = bel.location + bel_wires[i].rel_wire_loc;
|
||||
ret.index = bel_wires[i].wire_index;
|
||||
for (auto &bw : locInfo(bel)->bel_data[bel.index].bel_wires)
|
||||
if (bw.port == pin.index) {
|
||||
ret.location = bel.location + bw.rel_wire_loc;
|
||||
ret.index = bw.wire_index;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -257,12 +255,9 @@ PortType Arch::getBelPinType(BelId bel, IdString pin) const
|
||||
{
|
||||
NPNR_ASSERT(bel != BelId());
|
||||
|
||||
int num_bel_wires = locInfo(bel)->bel_data[bel.index].num_bel_wires;
|
||||
const BelWirePOD *bel_wires = locInfo(bel)->bel_data[bel.index].bel_wires.get();
|
||||
|
||||
for (int i = 0; i < num_bel_wires; i++)
|
||||
if (bel_wires[i].port == pin.index)
|
||||
return PortType(bel_wires[i].type);
|
||||
for (auto &bw : locInfo(bel)->bel_data[bel.index].bel_wires)
|
||||
if (bw.port == pin.index)
|
||||
return PortType(bw.type);
|
||||
|
||||
return PORT_INOUT;
|
||||
}
|
||||
@ -281,7 +276,7 @@ WireId Arch::getWireByName(IdString name) const
|
||||
std::tie(loc.x, loc.y, basename) = split_identifier_name(name.str(this));
|
||||
ret.location = loc;
|
||||
const LocationTypePOD *loci = locInfo(ret);
|
||||
for (int i = 0; i < loci->num_wires; i++) {
|
||||
for (int i = 0; i < int(loci->wire_data.size()); i++) {
|
||||
if (std::strcmp(loci->wire_data[i].name.get(), basename.c_str()) == 0) {
|
||||
ret.index = i;
|
||||
ret.location = loc;
|
||||
@ -309,7 +304,7 @@ PipId Arch::getPipByName(IdString name) const
|
||||
std::tie(loc.x, loc.y, basename) = split_identifier_name(name.str(this));
|
||||
ret.location = loc;
|
||||
const LocationTypePOD *loci = locInfo(ret);
|
||||
for (int i = 0; i < loci->num_pips; i++) {
|
||||
for (int i = 0; i < int(loci->pip_data.size()); i++) {
|
||||
PipId curr;
|
||||
curr.location = loc;
|
||||
curr.index = i;
|
||||
@ -340,11 +335,11 @@ IdString Arch::getPipName(PipId pip) const
|
||||
|
||||
BelId Arch::getPackagePinBel(const std::string &pin) const
|
||||
{
|
||||
for (int i = 0; i < package_info->num_pins; i++) {
|
||||
if (package_info->pin_data[i].name.get() == pin) {
|
||||
for (auto &ppin : package_info->pin_data) {
|
||||
if (ppin.name.get() == pin) {
|
||||
BelId bel;
|
||||
bel.location = package_info->pin_data[i].abs_loc;
|
||||
bel.index = package_info->pin_data[i].bel_index;
|
||||
bel.location = ppin.abs_loc;
|
||||
bel.index = ppin.bel_index;
|
||||
return bel;
|
||||
}
|
||||
}
|
||||
@ -353,10 +348,9 @@ BelId Arch::getPackagePinBel(const std::string &pin) const
|
||||
|
||||
std::string Arch::getBelPackagePin(BelId bel) const
|
||||
{
|
||||
for (int i = 0; i < package_info->num_pins; i++) {
|
||||
if (Location(package_info->pin_data[i].abs_loc) == bel.location &&
|
||||
package_info->pin_data[i].bel_index == bel.index) {
|
||||
return package_info->pin_data[i].name.get();
|
||||
for (auto &ppin : package_info->pin_data) {
|
||||
if (Location(ppin.abs_loc) == bel.location && ppin.bel_index == bel.index) {
|
||||
return ppin.name.get();
|
||||
}
|
||||
}
|
||||
return "";
|
||||
@ -364,9 +358,9 @@ std::string Arch::getBelPackagePin(BelId bel) const
|
||||
|
||||
int Arch::getPioBelBank(BelId bel) const
|
||||
{
|
||||
for (int i = 0; i < chip_info->num_pios; i++) {
|
||||
if (Location(chip_info->pio_info[i].abs_loc) == bel.location && chip_info->pio_info[i].bel_index == bel.index) {
|
||||
return chip_info->pio_info[i].bank;
|
||||
for (auto &pio : chip_info->pio_info) {
|
||||
if (Location(pio.abs_loc) == bel.location && pio.bel_index == bel.index) {
|
||||
return pio.bank;
|
||||
}
|
||||
}
|
||||
NPNR_ASSERT_FALSE("failed to find PIO");
|
||||
@ -374,9 +368,9 @@ int Arch::getPioBelBank(BelId bel) const
|
||||
|
||||
std::string Arch::getPioFunctionName(BelId bel) const
|
||||
{
|
||||
for (int i = 0; i < chip_info->num_pios; i++) {
|
||||
if (Location(chip_info->pio_info[i].abs_loc) == bel.location && chip_info->pio_info[i].bel_index == bel.index) {
|
||||
const char *func = chip_info->pio_info[i].function_name.get();
|
||||
for (auto &pio : chip_info->pio_info) {
|
||||
if (Location(pio.abs_loc) == bel.location && pio.bel_index == bel.index) {
|
||||
const char *func = pio.function_name.get();
|
||||
if (func == nullptr)
|
||||
return "";
|
||||
else
|
||||
@ -388,12 +382,12 @@ std::string Arch::getPioFunctionName(BelId bel) const
|
||||
|
||||
BelId Arch::getPioByFunctionName(const std::string &name) const
|
||||
{
|
||||
for (int i = 0; i < chip_info->num_pios; i++) {
|
||||
const char *func = chip_info->pio_info[i].function_name.get();
|
||||
for (auto &pio : chip_info->pio_info) {
|
||||
const char *func = pio.function_name.get();
|
||||
if (func != nullptr && func == name) {
|
||||
BelId bel;
|
||||
bel.location = chip_info->pio_info[i].abs_loc;
|
||||
bel.index = chip_info->pio_info[i].bel_index;
|
||||
bel.location = pio.abs_loc;
|
||||
bel.index = pio.bel_index;
|
||||
return bel;
|
||||
}
|
||||
}
|
||||
@ -405,12 +399,9 @@ std::vector<IdString> Arch::getBelPins(BelId bel) const
|
||||
std::vector<IdString> ret;
|
||||
NPNR_ASSERT(bel != BelId());
|
||||
|
||||
int num_bel_wires = locInfo(bel)->bel_data[bel.index].num_bel_wires;
|
||||
const BelWirePOD *bel_wires = locInfo(bel)->bel_data[bel.index].bel_wires.get();
|
||||
|
||||
for (int i = 0; i < num_bel_wires; i++) {
|
||||
for (auto &bw : locInfo(bel)->bel_data[bel.index].bel_wires) {
|
||||
IdString id;
|
||||
id.index = bel_wires[i].port;
|
||||
id.index = bw.port;
|
||||
ret.push_back(id);
|
||||
}
|
||||
|
||||
@ -422,7 +413,7 @@ BelId Arch::getBelByLocation(Loc loc) const
|
||||
if (loc.x >= chip_info->width || loc.y >= chip_info->height)
|
||||
return BelId();
|
||||
const LocationTypePOD &locI = chip_info->locations[chip_info->location_type[loc.y * chip_info->width + loc.x]];
|
||||
for (int i = 0; i < locI.num_bels; i++) {
|
||||
for (int i = 0; i < int(locI.bel_data.size()); i++) {
|
||||
if (locI.bel_data[i].z == loc.z) {
|
||||
BelId bi;
|
||||
bi.location.x = loc.x;
|
||||
@ -438,7 +429,7 @@ BelId Arch::getBelByLocation(Loc loc) const
|
||||
|
||||
delay_t Arch::estimateDelay(WireId src, WireId dst) const
|
||||
{
|
||||
int num_uh = locInfo(dst)->wire_data[dst.index].num_uphill;
|
||||
int num_uh = locInfo(dst)->wire_data[dst.index].pips_uphill.size();
|
||||
if (num_uh < 6) {
|
||||
for (auto uh : getPipsUphill(dst)) {
|
||||
if (getPipSrcWire(uh) == src)
|
||||
@ -451,13 +442,13 @@ delay_t Arch::estimateDelay(WireId src, WireId dst) const
|
||||
if (w == gsrclk_wire) {
|
||||
auto phys_wire = getPipSrcWire(*(getPipsUphill(w).begin()));
|
||||
return std::make_pair(int(phys_wire.location.x), int(phys_wire.location.y));
|
||||
} else if (wire.num_bel_pins > 0) {
|
||||
} else if (wire.bel_pins.size() > 0) {
|
||||
return std::make_pair(w.location.x + wire.bel_pins[0].rel_bel_loc.x,
|
||||
w.location.y + wire.bel_pins[0].rel_bel_loc.y);
|
||||
} else if (wire.num_downhill > 0) {
|
||||
} else if (wire.pips_downhill.size() > 0) {
|
||||
return std::make_pair(w.location.x + wire.pips_downhill[0].rel_loc.x,
|
||||
w.location.y + wire.pips_downhill[0].rel_loc.y);
|
||||
} else if (wire.num_uphill > 0) {
|
||||
} else if (wire.pips_uphill.size() > 0) {
|
||||
return std::make_pair(w.location.x + wire.pips_uphill[0].rel_loc.x,
|
||||
w.location.y + wire.pips_uphill[0].rel_loc.y);
|
||||
} else {
|
||||
@ -500,13 +491,13 @@ ArcBounds Arch::getRouteBoundingBox(WireId src, WireId dst) const
|
||||
if (w == gsrclk_wire) {
|
||||
auto phys_wire = getPipSrcWire(*(getPipsUphill(w).begin()));
|
||||
return std::make_pair(int(phys_wire.location.x), int(phys_wire.location.y));
|
||||
} else if (wire.num_bel_pins > 0) {
|
||||
} else if (wire.bel_pins.size() > 0) {
|
||||
return std::make_pair(w.location.x + wire.bel_pins[0].rel_bel_loc.x,
|
||||
w.location.y + wire.bel_pins[0].rel_bel_loc.y);
|
||||
} else if (wire.num_downhill > 0) {
|
||||
} else if (wire.pips_downhill.size() > 0) {
|
||||
return std::make_pair(w.location.x + wire.pips_downhill[0].rel_loc.x,
|
||||
w.location.y + wire.pips_downhill[0].rel_loc.y);
|
||||
} else if (wire.num_uphill > 0) {
|
||||
} else if (wire.pips_uphill.size() > 0) {
|
||||
return std::make_pair(w.location.x + wire.pips_uphill[0].rel_loc.x,
|
||||
w.location.y + wire.pips_uphill[0].rel_loc.y);
|
||||
} else {
|
||||
@ -763,11 +754,9 @@ bool Arch::getDelayFromTimingDatabase(IdString tctype, IdString from, IdString t
|
||||
delay = fnd_dk->second.second;
|
||||
return fnd_dk->second.first;
|
||||
}
|
||||
for (int i = 0; i < speed_grade->num_cell_timings; i++) {
|
||||
const auto &tc = speed_grade->cell_timings[i];
|
||||
for (auto &tc : speed_grade->cell_timings) {
|
||||
if (tc.cell_type == tctype.index) {
|
||||
for (int j = 0; j < tc.num_prop_delays; j++) {
|
||||
const auto &dly = tc.prop_delays[j];
|
||||
for (auto &dly : tc.prop_delays) {
|
||||
if (dly.from_port == from.index && dly.to_port == to.index) {
|
||||
delay.max_delay = dly.max_delay;
|
||||
delay.min_delay = dly.min_delay;
|
||||
@ -785,11 +774,9 @@ bool Arch::getDelayFromTimingDatabase(IdString tctype, IdString from, IdString t
|
||||
void Arch::getSetupHoldFromTimingDatabase(IdString tctype, IdString clock, IdString port, DelayInfo &setup,
|
||||
DelayInfo &hold) const
|
||||
{
|
||||
for (int i = 0; i < speed_grade->num_cell_timings; i++) {
|
||||
const auto &tc = speed_grade->cell_timings[i];
|
||||
for (auto &tc : speed_grade->cell_timings) {
|
||||
if (tc.cell_type == tctype.index) {
|
||||
for (int j = 0; j < tc.num_setup_holds; j++) {
|
||||
const auto &sh = tc.setup_holds[j];
|
||||
for (auto &sh : tc.setup_holds) {
|
||||
if (sh.clock_port == clock.index && sh.sig_port == port.index) {
|
||||
setup.max_delay = sh.max_setup;
|
||||
setup.min_delay = sh.min_setup;
|
||||
@ -1165,9 +1152,8 @@ std::vector<std::pair<std::string, std::string>> Arch::getTilesAtLocation(int ro
|
||||
{
|
||||
std::vector<std::pair<std::string, std::string>> ret;
|
||||
auto &tileloc = chip_info->tile_info[row * chip_info->width + col];
|
||||
for (int i = 0; i < tileloc.num_tiles; i++) {
|
||||
ret.push_back(std::make_pair(tileloc.tile_names[i].name.get(),
|
||||
chip_info->tiletype_names[tileloc.tile_names[i].type_idx].get()));
|
||||
for (auto &tn : tileloc.tile_names) {
|
||||
ret.push_back(std::make_pair(tn.name.get(), chip_info->tiletype_names[tn.type_idx].get()));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -1180,9 +1166,9 @@ GlobalInfoPOD Arch::globalInfoAtLoc(Location loc)
|
||||
|
||||
bool Arch::getPIODQSGroup(BelId pio, bool &dqsright, int &dqsrow)
|
||||
{
|
||||
for (int i = 0; i < chip_info->num_pios; i++) {
|
||||
if (Location(chip_info->pio_info[i].abs_loc) == pio.location && chip_info->pio_info[i].bel_index == pio.index) {
|
||||
int dqs = chip_info->pio_info[i].dqsgroup;
|
||||
for (auto &ppio : chip_info->pio_info) {
|
||||
if (Location(ppio.abs_loc) == pio.location && ppio.bel_index == pio.index) {
|
||||
int dqs = ppio.dqsgroup;
|
||||
if (dqs == -1)
|
||||
return false;
|
||||
else {
|
||||
@ -1200,7 +1186,7 @@ BelId Arch::getDQSBUF(bool dqsright, int dqsrow)
|
||||
BelId bel;
|
||||
bel.location.y = dqsrow;
|
||||
bel.location.x = (dqsright ? (chip_info->width - 1) : 0);
|
||||
for (int i = 0; i < locInfo(bel)->num_bels; i++) {
|
||||
for (int i = 0; i < int(locInfo(bel)->bel_data.size()); i++) {
|
||||
auto &bd = locInfo(bel)->bel_data[i];
|
||||
if (bd.type == id_DQSBUFM.index) {
|
||||
bel.index = i;
|
||||
|
117
ecp5/arch.h
117
ecp5/arch.h
@ -29,26 +29,7 @@ NEXTPNR_NAMESPACE_BEGIN
|
||||
|
||||
/**** Everything in this section must be kept in sync with chipdb.py ****/
|
||||
|
||||
template <typename T> struct RelPtr
|
||||
{
|
||||
int32_t offset;
|
||||
|
||||
// void set(const T *ptr) {
|
||||
// offset = reinterpret_cast<const char*>(ptr) -
|
||||
// reinterpret_cast<const char*>(this);
|
||||
// }
|
||||
|
||||
const T *get() const { return reinterpret_cast<const T *>(reinterpret_cast<const char *>(this) + offset); }
|
||||
|
||||
const T &operator[](size_t index) const { return get()[index]; }
|
||||
|
||||
const T &operator*() const { return *(get()); }
|
||||
|
||||
const T *operator->() const { return get(); }
|
||||
|
||||
RelPtr(const RelPtr &) = delete;
|
||||
RelPtr &operator=(const RelPtr &) = delete;
|
||||
};
|
||||
#include "relptr.h"
|
||||
|
||||
NPNR_PACKED_STRUCT(struct BelWirePOD {
|
||||
LocationPOD rel_wire_loc;
|
||||
@ -61,8 +42,7 @@ NPNR_PACKED_STRUCT(struct BelInfoPOD {
|
||||
RelPtr<char> name;
|
||||
int32_t type;
|
||||
int32_t z;
|
||||
int32_t num_bel_wires;
|
||||
RelPtr<BelWirePOD> bel_wires;
|
||||
RelSlice<BelWirePOD> bel_wires;
|
||||
});
|
||||
|
||||
NPNR_PACKED_STRUCT(struct BelPortPOD {
|
||||
@ -89,18 +69,14 @@ NPNR_PACKED_STRUCT(struct WireInfoPOD {
|
||||
RelPtr<char> name;
|
||||
int32_t type;
|
||||
int32_t tile_wire;
|
||||
int32_t num_uphill, num_downhill;
|
||||
RelPtr<PipLocatorPOD> pips_uphill, pips_downhill;
|
||||
|
||||
int32_t num_bel_pins;
|
||||
RelPtr<BelPortPOD> bel_pins;
|
||||
RelSlice<PipLocatorPOD> pips_uphill, pips_downhill;
|
||||
RelSlice<BelPortPOD> bel_pins;
|
||||
});
|
||||
|
||||
NPNR_PACKED_STRUCT(struct LocationTypePOD {
|
||||
int32_t num_bels, num_wires, num_pips;
|
||||
RelPtr<BelInfoPOD> bel_data;
|
||||
RelPtr<WireInfoPOD> wire_data;
|
||||
RelPtr<PipInfoPOD> pip_data;
|
||||
RelSlice<BelInfoPOD> bel_data;
|
||||
RelSlice<WireInfoPOD> wire_data;
|
||||
RelSlice<PipInfoPOD> pip_data;
|
||||
});
|
||||
|
||||
NPNR_PACKED_STRUCT(struct PIOInfoPOD {
|
||||
@ -119,8 +95,7 @@ NPNR_PACKED_STRUCT(struct PackagePinPOD {
|
||||
|
||||
NPNR_PACKED_STRUCT(struct PackageInfoPOD {
|
||||
RelPtr<char> name;
|
||||
int32_t num_pins;
|
||||
RelPtr<PackagePinPOD> pin_data;
|
||||
RelSlice<PackagePinPOD> pin_data;
|
||||
});
|
||||
|
||||
NPNR_PACKED_STRUCT(struct TileNamePOD {
|
||||
@ -129,10 +104,7 @@ NPNR_PACKED_STRUCT(struct TileNamePOD {
|
||||
int16_t padding;
|
||||
});
|
||||
|
||||
NPNR_PACKED_STRUCT(struct TileInfoPOD {
|
||||
int32_t num_tiles;
|
||||
RelPtr<TileNamePOD> tile_names;
|
||||
});
|
||||
NPNR_PACKED_STRUCT(struct TileInfoPOD { RelSlice<TileNamePOD> tile_names; });
|
||||
|
||||
enum TapDirection : int8_t
|
||||
{
|
||||
@ -174,10 +146,8 @@ NPNR_PACKED_STRUCT(struct CellSetupHoldPOD {
|
||||
|
||||
NPNR_PACKED_STRUCT(struct CellTimingPOD {
|
||||
int32_t cell_type;
|
||||
int32_t num_prop_delays;
|
||||
int32_t num_setup_holds;
|
||||
RelPtr<CellPropDelayPOD> prop_delays;
|
||||
RelPtr<CellSetupHoldPOD> setup_holds;
|
||||
RelSlice<CellPropDelayPOD> prop_delays;
|
||||
RelSlice<CellSetupHoldPOD> setup_holds;
|
||||
});
|
||||
|
||||
NPNR_PACKED_STRUCT(struct PipDelayPOD {
|
||||
@ -188,26 +158,22 @@ NPNR_PACKED_STRUCT(struct PipDelayPOD {
|
||||
});
|
||||
|
||||
NPNR_PACKED_STRUCT(struct SpeedGradePOD {
|
||||
int32_t num_cell_timings;
|
||||
int32_t num_pip_classes;
|
||||
RelPtr<CellTimingPOD> cell_timings;
|
||||
RelPtr<PipDelayPOD> pip_classes;
|
||||
RelSlice<CellTimingPOD> cell_timings;
|
||||
RelSlice<PipDelayPOD> pip_classes;
|
||||
});
|
||||
|
||||
NPNR_PACKED_STRUCT(struct ChipInfoPOD {
|
||||
int32_t width, height;
|
||||
int32_t num_tiles;
|
||||
int32_t num_location_types;
|
||||
int32_t num_packages, num_pios;
|
||||
int32_t const_id_count;
|
||||
RelPtr<LocationTypePOD> locations;
|
||||
RelPtr<int32_t> location_type;
|
||||
RelPtr<GlobalInfoPOD> location_glbinfo;
|
||||
RelPtr<RelPtr<char>> tiletype_names;
|
||||
RelPtr<PackageInfoPOD> package_info;
|
||||
RelPtr<PIOInfoPOD> pio_info;
|
||||
RelPtr<TileInfoPOD> tile_info;
|
||||
RelPtr<SpeedGradePOD> speed_grades;
|
||||
RelSlice<LocationTypePOD> locations;
|
||||
RelSlice<int32_t> location_type;
|
||||
RelSlice<GlobalInfoPOD> location_glbinfo;
|
||||
RelSlice<RelPtr<char>> tiletype_names;
|
||||
RelSlice<PackageInfoPOD> package_info;
|
||||
RelSlice<PIOInfoPOD> pio_info;
|
||||
RelSlice<TileInfoPOD> tile_info;
|
||||
RelSlice<SpeedGradePOD> speed_grades;
|
||||
});
|
||||
|
||||
/************************ End of chipdb section. ************************/
|
||||
@ -222,7 +188,7 @@ struct BelIterator
|
||||
{
|
||||
cursor_index++;
|
||||
while (cursor_tile < chip->num_tiles &&
|
||||
cursor_index >= chip->locations[chip->location_type[cursor_tile]].num_bels) {
|
||||
cursor_index >= int(chip->locations[chip->location_type[cursor_tile]].bel_data.size())) {
|
||||
cursor_index = 0;
|
||||
cursor_tile++;
|
||||
}
|
||||
@ -300,7 +266,7 @@ struct WireIterator
|
||||
{
|
||||
cursor_index++;
|
||||
while (cursor_tile < chip->num_tiles &&
|
||||
cursor_index >= chip->locations[chip->location_type[cursor_tile]].num_wires) {
|
||||
cursor_index >= int(chip->locations[chip->location_type[cursor_tile]].wire_data.size())) {
|
||||
cursor_index = 0;
|
||||
cursor_tile++;
|
||||
}
|
||||
@ -352,7 +318,7 @@ struct AllPipIterator
|
||||
{
|
||||
cursor_index++;
|
||||
while (cursor_tile < chip->num_tiles &&
|
||||
cursor_index >= chip->locations[chip->location_type[cursor_tile]].num_pips) {
|
||||
cursor_index >= int(chip->locations[chip->location_type[cursor_tile]].pip_data.size())) {
|
||||
cursor_index = 0;
|
||||
cursor_tile++;
|
||||
}
|
||||
@ -617,9 +583,9 @@ struct Arch : BaseCtx
|
||||
{
|
||||
BelPinRange range;
|
||||
NPNR_ASSERT(wire != WireId());
|
||||
range.b.ptr = locInfo(wire)->wire_data[wire.index].bel_pins.get();
|
||||
range.b.ptr = locInfo(wire)->wire_data[wire.index].bel_pins.begin();
|
||||
range.b.wire_loc = wire.location;
|
||||
range.e.ptr = range.b.ptr + locInfo(wire)->wire_data[wire.index].num_bel_pins;
|
||||
range.e.ptr = locInfo(wire)->wire_data[wire.index].bel_pins.end();
|
||||
range.e.wire_loc = wire.location;
|
||||
return range;
|
||||
}
|
||||
@ -735,7 +701,7 @@ struct Arch : BaseCtx
|
||||
{
|
||||
WireId wireId;
|
||||
wireId.location = loc;
|
||||
for (int i = 0; i < locInfo(wireId)->num_wires; i++) {
|
||||
for (int i = 0; i < int(locInfo(wireId)->wire_data.size()); i++) {
|
||||
if (locInfo(wireId)->wire_data[i].name.get() == basename) {
|
||||
wireId.index = i;
|
||||
return wireId;
|
||||
@ -857,7 +823,6 @@ struct Arch : BaseCtx
|
||||
auto fnd_fanout = wire_fanout.find(getPipSrcWire(pip));
|
||||
if (fnd_fanout != wire_fanout.end())
|
||||
fanout = fnd_fanout->second;
|
||||
NPNR_ASSERT(locInfo(pip)->pip_data[pip.index].timing_class < speed_grade->num_pip_classes);
|
||||
delay.min_delay =
|
||||
speed_grade->pip_classes[locInfo(pip)->pip_data[pip.index].timing_class].min_base_delay +
|
||||
fanout * speed_grade->pip_classes[locInfo(pip)->pip_data[pip.index].timing_class].min_fanout_adder;
|
||||
@ -873,7 +838,7 @@ struct Arch : BaseCtx
|
||||
NPNR_ASSERT(wire != WireId());
|
||||
range.b.cursor = locInfo(wire)->wire_data[wire.index].pips_downhill.get();
|
||||
range.b.wire_loc = wire.location;
|
||||
range.e.cursor = range.b.cursor + locInfo(wire)->wire_data[wire.index].num_downhill;
|
||||
range.e.cursor = range.b.cursor + locInfo(wire)->wire_data[wire.index].pips_downhill.size();
|
||||
range.e.wire_loc = wire.location;
|
||||
return range;
|
||||
}
|
||||
@ -884,7 +849,7 @@ struct Arch : BaseCtx
|
||||
NPNR_ASSERT(wire != WireId());
|
||||
range.b.cursor = locInfo(wire)->wire_data[wire.index].pips_uphill.get();
|
||||
range.b.wire_loc = wire.location;
|
||||
range.e.cursor = range.b.cursor + locInfo(wire)->wire_data[wire.index].num_uphill;
|
||||
range.e.cursor = range.b.cursor + locInfo(wire)->wire_data[wire.index].pips_uphill.size();
|
||||
range.e.wire_loc = wire.location;
|
||||
return range;
|
||||
}
|
||||
@ -892,9 +857,9 @@ struct Arch : BaseCtx
|
||||
std::string getPipTilename(PipId pip) const
|
||||
{
|
||||
auto &tileloc = chip_info->tile_info[pip.location.y * chip_info->width + pip.location.x];
|
||||
for (int i = 0; i < tileloc.num_tiles; i++) {
|
||||
if (tileloc.tile_names[i].type_idx == locInfo(pip)->pip_data[pip.index].tile_type)
|
||||
return tileloc.tile_names[i].name.get();
|
||||
for (auto &tn : tileloc.tile_names) {
|
||||
if (tn.type_idx == locInfo(pip)->pip_data[pip.index].tile_type)
|
||||
return tn.name.get();
|
||||
}
|
||||
NPNR_ASSERT_FALSE("failed to find Pip tile");
|
||||
}
|
||||
@ -999,9 +964,9 @@ struct Arch : BaseCtx
|
||||
std::string getTileByTypeAndLocation(int row, int col, std::string type) const
|
||||
{
|
||||
auto &tileloc = chip_info->tile_info[row * chip_info->width + col];
|
||||
for (int i = 0; i < tileloc.num_tiles; i++) {
|
||||
if (chip_info->tiletype_names[tileloc.tile_names[i].type_idx].get() == type)
|
||||
return tileloc.tile_names[i].name.get();
|
||||
for (auto &tn : tileloc.tile_names) {
|
||||
if (chip_info->tiletype_names[tn.type_idx].get() == type)
|
||||
return tn.name.get();
|
||||
}
|
||||
NPNR_ASSERT_FALSE_STR("no tile at (" + std::to_string(col) + ", " + std::to_string(row) + ") with type " +
|
||||
type);
|
||||
@ -1010,9 +975,9 @@ struct Arch : BaseCtx
|
||||
std::string getTileByTypeAndLocation(int row, int col, const std::set<std::string> &type) const
|
||||
{
|
||||
auto &tileloc = chip_info->tile_info[row * chip_info->width + col];
|
||||
for (int i = 0; i < tileloc.num_tiles; i++) {
|
||||
if (type.count(chip_info->tiletype_names[tileloc.tile_names[i].type_idx].get()))
|
||||
return tileloc.tile_names[i].name.get();
|
||||
for (auto &tn : tileloc.tile_names) {
|
||||
if (type.count(chip_info->tiletype_names[tn.type_idx].get()))
|
||||
return tn.name.get();
|
||||
}
|
||||
NPNR_ASSERT_FALSE_STR("no tile at (" + std::to_string(col) + ", " + std::to_string(row) + ") with type in set");
|
||||
}
|
||||
@ -1021,9 +986,9 @@ struct Arch : BaseCtx
|
||||
{
|
||||
for (int i = 0; i < chip_info->height * chip_info->width; i++) {
|
||||
auto &tileloc = chip_info->tile_info[i];
|
||||
for (int j = 0; j < tileloc.num_tiles; j++)
|
||||
if (chip_info->tiletype_names[tileloc.tile_names[j].type_idx].get() == type)
|
||||
return tileloc.tile_names[j].name.get();
|
||||
for (auto &tn : tileloc.tile_names)
|
||||
if (chip_info->tiletype_names[tn.type_idx].get() == type)
|
||||
return tn.name.get();
|
||||
}
|
||||
NPNR_ASSERT_FALSE_STR("no tile with type " + type);
|
||||
}
|
||||
|
@ -184,6 +184,13 @@ class BinaryBlobAssembler:
|
||||
else:
|
||||
print("ref %s %s" % (name, comment))
|
||||
|
||||
def r_slice(self, name, length, comment):
|
||||
if comment is None:
|
||||
print("ref %s" % (name,))
|
||||
else:
|
||||
print("ref %s %s" % (name, comment))
|
||||
print ("u32 %d" % (length, ))
|
||||
|
||||
def s(self, s, comment):
|
||||
assert "|" not in s
|
||||
print("str |%s| %s" % (s, comment))
|
||||
@ -445,12 +452,9 @@ def write_database(dev_name, chip, ddrg, endianness):
|
||||
bba.u32(gfx_wire_ids["TILE_WIRE_" + ddrg.to_str(wire.name)], "tile_wire")
|
||||
else:
|
||||
bba.u32(0, "tile_wire")
|
||||
bba.u32(len(wire.arcsUphill), "num_uphill")
|
||||
bba.u32(len(wire.arcsDownhill), "num_downhill")
|
||||
bba.r("loc%d_wire%d_uppips" % (idx, wire_idx) if len(wire.arcsUphill) > 0 else None, "pips_uphill")
|
||||
bba.r("loc%d_wire%d_downpips" % (idx, wire_idx) if len(wire.arcsDownhill) > 0 else None, "pips_downhill")
|
||||
bba.u32(len(wire.belPins), "num_bel_pins")
|
||||
bba.r("loc%d_wire%d_belpins" % (idx, wire_idx) if len(wire.belPins) > 0 else None, "bel_pins")
|
||||
bba.r_slice("loc%d_wire%d_uppips" % (idx, wire_idx) if len(wire.arcsUphill) > 0 else None, len(wire.arcsUphill), "pips_uphill")
|
||||
bba.r_slice("loc%d_wire%d_downpips" % (idx, wire_idx) if len(wire.arcsDownhill) > 0 else None, len(wire.arcsDownhill), "pips_downhill")
|
||||
bba.r_slice("loc%d_wire%d_belpins" % (idx, wire_idx) if len(wire.belPins) > 0 else None, len(wire.belPins), "bel_pins")
|
||||
|
||||
if len(loctype.bels) > 0:
|
||||
for bel_idx in range(len(loctype.bels)):
|
||||
@ -467,18 +471,14 @@ def write_database(dev_name, chip, ddrg, endianness):
|
||||
bba.s(ddrg.to_str(bel.name), "name")
|
||||
bba.u32(constids[ddrg.to_str(bel.type)], "type")
|
||||
bba.u32(bel.z, "z")
|
||||
bba.u32(len(bel.wires), "num_bel_wires")
|
||||
bba.r("loc%d_bel%d_wires" % (idx, bel_idx), "bel_wires")
|
||||
bba.r_slice("loc%d_bel%d_wires" % (idx, bel_idx), len(bel.wires), "bel_wires")
|
||||
|
||||
bba.l("locations", "LocationTypePOD")
|
||||
for idx in range(len(loctypes)):
|
||||
loctype = ddrg.locationTypes[loctypes[idx]]
|
||||
bba.u32(len(loctype.bels), "num_bels")
|
||||
bba.u32(len(loctype.wires), "num_wires")
|
||||
bba.u32(len(loctype.arcs), "num_pips")
|
||||
bba.r("loc%d_bels" % idx if len(loctype.bels) > 0 else None, "bel_data")
|
||||
bba.r("loc%d_wires" % idx if len(loctype.wires) > 0 else None, "wire_data")
|
||||
bba.r("loc%d_pips" % idx if len(loctype.arcs) > 0 else None, "pips_data")
|
||||
bba.r_slice("loc%d_bels" % idx if len(loctype.bels) > 0 else None, len(loctype.bels), "bel_data")
|
||||
bba.r_slice("loc%d_wires" % idx if len(loctype.wires) > 0 else None, len(loctype.wires), "wire_data")
|
||||
bba.r_slice("loc%d_pips" % idx if len(loctype.arcs) > 0 else None, len(loctype.arcs), "pips_data")
|
||||
|
||||
for y in range(0, max_row+1):
|
||||
for x in range(0, max_col+1):
|
||||
@ -491,8 +491,7 @@ def write_database(dev_name, chip, ddrg, endianness):
|
||||
bba.l("tiles_info", "TileInfoPOD")
|
||||
for y in range(0, max_row+1):
|
||||
for x in range(0, max_col+1):
|
||||
bba.u32(len(chip.get_tiles_by_position(y, x)), "num_tiles")
|
||||
bba.r("tile_info_%d_%d" % (x, y), "tile_names")
|
||||
bba.r_slice("tile_info_%d_%d" % (x, y), len(chip.get_tiles_by_position(y, x)), "tile_names")
|
||||
|
||||
bba.l("location_types", "int32_t")
|
||||
for y in range(0, max_row+1):
|
||||
@ -519,8 +518,7 @@ def write_database(dev_name, chip, ddrg, endianness):
|
||||
bba.l("package_data", "PackageInfoPOD")
|
||||
for package, pkgdata in sorted(packages.items()):
|
||||
bba.s(package, "name")
|
||||
bba.u32(len(pkgdata), "num_pins")
|
||||
bba.r("package_data_%s" % package, "pin_data")
|
||||
bba.r_slice("package_data_%s" % package, len(pkgdata), "pin_data")
|
||||
|
||||
bba.l("pio_info", "PIOInfoPOD")
|
||||
for pin in pindata:
|
||||
@ -563,10 +561,8 @@ def write_database(dev_name, chip, ddrg, endianness):
|
||||
for cell in speed_grade_cells[grade]:
|
||||
celltype, delays, setupholds = cell
|
||||
bba.u32(celltype, "cell_type")
|
||||
bba.u32(len(delays), "num_delays")
|
||||
bba.u32(len(setupholds), "num_setup_hold")
|
||||
bba.r("cell_%d_delays_%s" % (celltype, grade) if len(delays) > 0 else None, "delays")
|
||||
bba.r("cell_%d_setupholds_%s" % (celltype, grade) if len(delays) > 0 else None, "setupholds")
|
||||
bba.r_slice("cell_%d_delays_%s" % (celltype, grade) if len(delays) > 0 else None, len(delays), "delays")
|
||||
bba.r_slice("cell_%d_setupholds_%s" % (celltype, grade) if len(delays) > 0 else None, len(setupholds), "setupholds")
|
||||
bba.l("pip_timing_data_%s" % grade)
|
||||
for pipclass in speed_grade_pips[grade]:
|
||||
min_delay, max_delay, min_fanout, max_fanout = pipclass
|
||||
@ -576,28 +572,23 @@ def write_database(dev_name, chip, ddrg, endianness):
|
||||
bba.u32(max_fanout, "max_fanout")
|
||||
bba.l("speed_grade_data")
|
||||
for grade in speed_grade_names:
|
||||
bba.u32(len(speed_grade_cells[grade]), "num_cell_timings")
|
||||
bba.u32(len(speed_grade_pips[grade]), "num_pip_classes")
|
||||
bba.r("cell_timing_data_%s" % grade, "cell_timings")
|
||||
bba.r("pip_timing_data_%s" % grade, "pip_classes")
|
||||
bba.r_slice("cell_timing_data_%s" % grade, len(speed_grade_cells[grade]), "cell_timings")
|
||||
bba.r_slice("pip_timing_data_%s" % grade, len(speed_grade_pips[grade]), "pip_classes")
|
||||
|
||||
bba.l("chip_info")
|
||||
bba.u32(max_col + 1, "width")
|
||||
bba.u32(max_row + 1, "height")
|
||||
bba.u32((max_col + 1) * (max_row + 1), "num_tiles")
|
||||
bba.u32(len(location_types), "num_location_types")
|
||||
bba.u32(len(packages), "num_packages")
|
||||
bba.u32(len(pindata), "num_pios")
|
||||
bba.u32(const_id_count, "const_id_count")
|
||||
|
||||
bba.r("locations", "locations")
|
||||
bba.r("location_types", "location_type")
|
||||
bba.r("location_glbinfo", "location_glbinfo")
|
||||
bba.r("tiletype_names", "tiletype_names")
|
||||
bba.r("package_data", "package_info")
|
||||
bba.r("pio_info", "pio_info")
|
||||
bba.r("tiles_info", "tile_info")
|
||||
bba.r("speed_grade_data", "speed_grades")
|
||||
bba.r_slice("locations", len(loctypes), "locations")
|
||||
bba.r_slice("location_types", (max_col + 1) * (max_row + 1), "location_type")
|
||||
bba.r_slice("location_glbinfo", (max_col + 1) * (max_row + 1), "location_glbinfo")
|
||||
bba.r_slice("tiletype_names", len(tiletype_names), "tiletype_names")
|
||||
bba.r_slice("package_data", len(packages), "package_info")
|
||||
bba.r_slice("pio_info", len(pindata), "pio_info")
|
||||
bba.r_slice("tiles_info", (max_col + 1) * (max_row + 1), "tile_info")
|
||||
bba.r_slice("speed_grade_data", len(speed_grade_names), "speed_grades")
|
||||
|
||||
bba.pop()
|
||||
return bba
|
||||
|
@ -306,7 +306,7 @@ void DesignWidget::newContext(Context *ctx)
|
||||
{
|
||||
TreeModel::ElementXYRoot<WireId>::ElementMap wireMap;
|
||||
#ifdef ARCH_ICE40
|
||||
for (int i = 0; i < ctx->chip_info->num_wires; i++) {
|
||||
for (int i = 0; i < int(ctx->chip_info->wire_data.size()); i++) {
|
||||
const auto wire = &ctx->chip_info->wire_data[i];
|
||||
WireId wireid;
|
||||
wireid.index = i;
|
||||
|
@ -73,8 +73,8 @@ std::vector<std::string> Arch::getSupportedPackages(ArchArgs::ArchArgsTypes chip
|
||||
{
|
||||
const ChipInfoPOD *chip_info = get_chip_info(chip);
|
||||
std::vector<std::string> packages;
|
||||
for (int i = 0; i < chip_info->num_packages; i++) {
|
||||
std::string name = chip_info->packages_data[i].name.get();
|
||||
for (auto &pkg : chip_info->packages_data) {
|
||||
std::string name = pkg.name.get();
|
||||
if (chip == ArchArgs::LP4K || chip == ArchArgs::HX4K) {
|
||||
if (name.find(":4k") != std::string::npos)
|
||||
name = name.substr(0, name.size() - 3);
|
||||
@ -101,19 +101,19 @@ Arch::Arch(ArchArgs args) : args(args)
|
||||
if (args.type == ArchArgs::LP4K || args.type == ArchArgs::HX4K)
|
||||
package_name += ":4k";
|
||||
|
||||
for (int i = 0; i < chip_info->num_packages; i++) {
|
||||
if (chip_info->packages_data[i].name.get() == package_name) {
|
||||
package_info = &(chip_info->packages_data[i]);
|
||||
for (auto &pkg : chip_info->packages_data) {
|
||||
if (pkg.name.get() == package_name) {
|
||||
package_info = &pkg;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (package_info == nullptr)
|
||||
log_error("Unsupported package '%s'.\n", args.package.c_str());
|
||||
|
||||
bel_carry.resize(chip_info->num_bels);
|
||||
bel_to_cell.resize(chip_info->num_bels);
|
||||
wire_to_net.resize(chip_info->num_wires);
|
||||
pip_to_net.resize(chip_info->num_pips);
|
||||
bel_carry.resize(chip_info->bel_data.size());
|
||||
bel_to_cell.resize(chip_info->bel_data.size());
|
||||
wire_to_net.resize(chip_info->wire_data.size());
|
||||
pip_to_net.resize(chip_info->pip_data.size());
|
||||
switches_locked.resize(chip_info->num_switches);
|
||||
}
|
||||
|
||||
@ -188,7 +188,7 @@ BelId Arch::getBelByName(IdString name) const
|
||||
BelId ret;
|
||||
|
||||
if (bel_by_name.empty()) {
|
||||
for (int i = 0; i < chip_info->num_bels; i++)
|
||||
for (size_t i = 0; i < chip_info->bel_data.size(); i++)
|
||||
bel_by_name[id(chip_info->bel_data[i].name.get())] = i;
|
||||
}
|
||||
|
||||
@ -204,7 +204,7 @@ BelId Arch::getBelByLocation(Loc loc) const
|
||||
BelId bel;
|
||||
|
||||
if (bel_by_loc.empty()) {
|
||||
for (int i = 0; i < chip_info->num_bels; i++) {
|
||||
for (size_t i = 0; i < chip_info->bel_data.size(); i++) {
|
||||
BelId b;
|
||||
b.index = i;
|
||||
bel_by_loc[getBelLocation(b)] = i;
|
||||
@ -232,7 +232,7 @@ BelRange Arch::getBelsByTile(int x, int y) const
|
||||
br.e.cursor = br.b.cursor;
|
||||
|
||||
if (br.e.cursor != -1) {
|
||||
while (br.e.cursor < chip_info->num_bels && chip_info->bel_data[br.e.cursor].x == x &&
|
||||
while (br.e.cursor < int(chip_info->bel_data.size()) && chip_info->bel_data[br.e.cursor].x == x &&
|
||||
chip_info->bel_data[br.e.cursor].y == y)
|
||||
br.e.cursor++;
|
||||
}
|
||||
@ -244,7 +244,7 @@ PortType Arch::getBelPinType(BelId bel, IdString pin) const
|
||||
{
|
||||
NPNR_ASSERT(bel != BelId());
|
||||
|
||||
int num_bel_wires = chip_info->bel_data[bel.index].num_bel_wires;
|
||||
int num_bel_wires = chip_info->bel_data[bel.index].bel_wires.size();
|
||||
const BelWirePOD *bel_wires = chip_info->bel_data[bel.index].bel_wires.get();
|
||||
|
||||
if (num_bel_wires < 7) {
|
||||
@ -283,7 +283,7 @@ WireId Arch::getBelPinWire(BelId bel, IdString pin) const
|
||||
|
||||
NPNR_ASSERT(bel != BelId());
|
||||
|
||||
int num_bel_wires = chip_info->bel_data[bel.index].num_bel_wires;
|
||||
int num_bel_wires = chip_info->bel_data[bel.index].bel_wires.size();
|
||||
const BelWirePOD *bel_wires = chip_info->bel_data[bel.index].bel_wires.get();
|
||||
|
||||
if (num_bel_wires < 7) {
|
||||
@ -317,11 +317,8 @@ std::vector<IdString> Arch::getBelPins(BelId bel) const
|
||||
|
||||
NPNR_ASSERT(bel != BelId());
|
||||
|
||||
int num_bel_wires = chip_info->bel_data[bel.index].num_bel_wires;
|
||||
const BelWirePOD *bel_wires = chip_info->bel_data[bel.index].bel_wires.get();
|
||||
|
||||
for (int i = 0; i < num_bel_wires; i++)
|
||||
ret.push_back(IdString(bel_wires[i].port));
|
||||
for (auto &w : chip_info->bel_data[bel.index].bel_wires)
|
||||
ret.push_back(IdString(w.port));
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -329,17 +326,17 @@ std::vector<IdString> Arch::getBelPins(BelId bel) const
|
||||
bool Arch::isBelLocked(BelId bel) const
|
||||
{
|
||||
const BelConfigPOD *bel_config = nullptr;
|
||||
for (int i = 0; i < chip_info->num_belcfgs; i++) {
|
||||
if (chip_info->bel_config[i].bel_index == bel.index) {
|
||||
bel_config = &chip_info->bel_config[i];
|
||||
for (auto &bel_cfg : chip_info->bel_config) {
|
||||
if (bel_cfg.bel_index == bel.index) {
|
||||
bel_config = &bel_cfg;
|
||||
break;
|
||||
}
|
||||
}
|
||||
NPNR_ASSERT(bel_config != nullptr);
|
||||
for (int i = 0; i < bel_config->num_entries; i++) {
|
||||
if (strcmp("LOCKED", bel_config->entries[i].cbit_name.get()))
|
||||
for (auto &entry : bel_config->entries) {
|
||||
if (strcmp("LOCKED", entry.cbit_name.get()))
|
||||
continue;
|
||||
if ("LOCKED_" + archArgs().package == bel_config->entries[i].entry_name.get())
|
||||
if ("LOCKED_" + archArgs().package == entry.entry_name.get())
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -352,7 +349,7 @@ WireId Arch::getWireByName(IdString name) const
|
||||
WireId ret;
|
||||
|
||||
if (wire_by_name.empty()) {
|
||||
for (int i = 0; i < chip_info->num_wires; i++)
|
||||
for (int i = 0; i < int(chip_info->wire_data.size()); i++)
|
||||
wire_by_name[id(chip_info->wire_data[i].name.get())] = i;
|
||||
}
|
||||
|
||||
@ -430,7 +427,7 @@ PipId Arch::getPipByName(IdString name) const
|
||||
PipId ret;
|
||||
|
||||
if (pip_by_name.empty()) {
|
||||
for (int i = 0; i < chip_info->num_pips; i++) {
|
||||
for (int i = 0; i < int(chip_info->pip_data.size()); i++) {
|
||||
PipId pip;
|
||||
pip.index = i;
|
||||
pip_by_name[getPipName(pip)] = i;
|
||||
@ -479,10 +476,10 @@ std::vector<std::pair<IdString, std::string>> Arch::getPipAttrs(PipId pip) const
|
||||
|
||||
BelId Arch::getPackagePinBel(const std::string &pin) const
|
||||
{
|
||||
for (int i = 0; i < package_info->num_pins; i++) {
|
||||
if (package_info->pins[i].name.get() == pin) {
|
||||
for (auto &ppin : package_info->pins) {
|
||||
if (ppin.name.get() == pin) {
|
||||
BelId id;
|
||||
id.index = package_info->pins[i].bel_index;
|
||||
id.index = ppin.bel_index;
|
||||
return id;
|
||||
}
|
||||
}
|
||||
@ -491,9 +488,9 @@ BelId Arch::getPackagePinBel(const std::string &pin) const
|
||||
|
||||
std::string Arch::getBelPackagePin(BelId bel) const
|
||||
{
|
||||
for (int i = 0; i < package_info->num_pins; i++) {
|
||||
if (package_info->pins[i].bel_index == bel.index) {
|
||||
return std::string(package_info->pins[i].name.get());
|
||||
for (auto &ppin : package_info->pins) {
|
||||
if (ppin.bel_index == bel.index) {
|
||||
return std::string(ppin.name.get());
|
||||
}
|
||||
}
|
||||
return "";
|
||||
@ -826,7 +823,7 @@ std::vector<GraphicElement> Arch::getDecalGraphics(DecalId decal) const
|
||||
}
|
||||
|
||||
if (decal.type == DecalId::TYPE_WIRE) {
|
||||
int n = chip_info->wire_data[decal.index].num_segments;
|
||||
int n = chip_info->wire_data[decal.index].segments.size();
|
||||
const WireSegmentPOD *p = chip_info->wire_data[decal.index].segments.get();
|
||||
|
||||
GraphicElement::style_t style = decal.active ? GraphicElement::STYLE_ACTIVE : GraphicElement::STYLE_INACTIVE;
|
||||
@ -951,11 +948,9 @@ bool Arch::getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort
|
||||
|
||||
bool Arch::getCellDelayInternal(const CellInfo *cell, IdString fromPort, IdString toPort, DelayInfo &delay) const
|
||||
{
|
||||
for (int i = 0; i < chip_info->num_timing_cells; i++) {
|
||||
const auto &tc = chip_info->cell_timing[i];
|
||||
for (auto &tc : chip_info->cell_timing) {
|
||||
if (tc.type == cell->type.index) {
|
||||
for (int j = 0; j < tc.num_paths; j++) {
|
||||
const auto &path = tc.path_delays[j];
|
||||
for (auto &path : tc.path_delays) {
|
||||
if (path.from_port == fromPort.index && path.to_port == toPort.index) {
|
||||
if (fast_part)
|
||||
delay.delay = path.fast_delay;
|
||||
|
90
ice40/arch.h
90
ice40/arch.h
@ -25,26 +25,7 @@ NEXTPNR_NAMESPACE_BEGIN
|
||||
|
||||
/**** Everything in this section must be kept in sync with chipdb.py ****/
|
||||
|
||||
template <typename T> struct RelPtr
|
||||
{
|
||||
int32_t offset;
|
||||
|
||||
// void set(const T *ptr) {
|
||||
// offset = reinterpret_cast<const char*>(ptr) -
|
||||
// reinterpret_cast<const char*>(this);
|
||||
// }
|
||||
|
||||
const T *get() const { return reinterpret_cast<const T *>(reinterpret_cast<const char *>(this) + offset); }
|
||||
|
||||
const T &operator[](size_t index) const { return get()[index]; }
|
||||
|
||||
const T &operator*() const { return *(get()); }
|
||||
|
||||
const T *operator->() const { return get(); }
|
||||
|
||||
RelPtr(const RelPtr &) = delete;
|
||||
RelPtr &operator=(const RelPtr &) = delete;
|
||||
};
|
||||
#include "relptr.h"
|
||||
|
||||
NPNR_PACKED_STRUCT(struct BelWirePOD {
|
||||
int32_t port;
|
||||
@ -55,8 +36,7 @@ NPNR_PACKED_STRUCT(struct BelWirePOD {
|
||||
NPNR_PACKED_STRUCT(struct BelInfoPOD {
|
||||
RelPtr<char> name;
|
||||
int32_t type;
|
||||
int32_t num_bel_wires;
|
||||
RelPtr<BelWirePOD> bel_wires;
|
||||
RelSlice<BelWirePOD> bel_wires;
|
||||
int8_t x, y, z;
|
||||
int8_t padding_0;
|
||||
});
|
||||
@ -111,14 +91,11 @@ NPNR_PACKED_STRUCT(struct WireInfoPOD {
|
||||
};
|
||||
|
||||
RelPtr<char> name;
|
||||
int32_t num_uphill, num_downhill;
|
||||
RelPtr<int32_t> pips_uphill, pips_downhill;
|
||||
RelSlice<int32_t> pips_uphill, pips_downhill;
|
||||
|
||||
int32_t num_bel_pins;
|
||||
RelPtr<BelPortPOD> bel_pins;
|
||||
RelSlice<BelPortPOD> bel_pins;
|
||||
|
||||
int32_t num_segments;
|
||||
RelPtr<WireSegmentPOD> segments;
|
||||
RelSlice<WireSegmentPOD> segments;
|
||||
|
||||
int32_t fast_delay;
|
||||
int32_t slow_delay;
|
||||
@ -134,8 +111,7 @@ NPNR_PACKED_STRUCT(struct PackagePinPOD {
|
||||
|
||||
NPNR_PACKED_STRUCT(struct PackageInfoPOD {
|
||||
RelPtr<char> name;
|
||||
int32_t num_pins;
|
||||
RelPtr<PackagePinPOD> pins;
|
||||
RelSlice<PackagePinPOD> pins;
|
||||
});
|
||||
|
||||
enum TileType : uint32_t
|
||||
@ -156,14 +132,13 @@ NPNR_PACKED_STRUCT(struct ConfigBitPOD { int8_t row, col; });
|
||||
|
||||
NPNR_PACKED_STRUCT(struct ConfigEntryPOD {
|
||||
RelPtr<char> name;
|
||||
int32_t num_bits;
|
||||
RelPtr<ConfigBitPOD> bits;
|
||||
RelSlice<ConfigBitPOD> bits;
|
||||
});
|
||||
|
||||
NPNR_PACKED_STRUCT(struct TileInfoPOD {
|
||||
int8_t cols, rows;
|
||||
int16_t num_config_entries;
|
||||
RelPtr<ConfigEntryPOD> entries;
|
||||
int16_t padding;
|
||||
RelSlice<ConfigEntryPOD> entries;
|
||||
});
|
||||
|
||||
static const int max_switch_bits = 5;
|
||||
@ -181,10 +156,9 @@ NPNR_PACKED_STRUCT(struct IerenInfoPOD {
|
||||
});
|
||||
|
||||
NPNR_PACKED_STRUCT(struct BitstreamInfoPOD {
|
||||
int32_t num_switches, num_ierens;
|
||||
RelPtr<TileInfoPOD> tiles_nonrouting;
|
||||
RelPtr<SwitchInfoPOD> switches;
|
||||
RelPtr<IerenInfoPOD> ierens;
|
||||
RelSlice<TileInfoPOD> tiles_nonrouting;
|
||||
RelSlice<SwitchInfoPOD> switches;
|
||||
RelSlice<IerenInfoPOD> ierens;
|
||||
});
|
||||
|
||||
NPNR_PACKED_STRUCT(struct BelConfigEntryPOD {
|
||||
@ -198,8 +172,7 @@ NPNR_PACKED_STRUCT(struct BelConfigEntryPOD {
|
||||
// for extra cells where this mapping is non-trivial
|
||||
NPNR_PACKED_STRUCT(struct BelConfigPOD {
|
||||
int32_t bel_index;
|
||||
int32_t num_entries;
|
||||
RelPtr<BelConfigEntryPOD> entries;
|
||||
RelSlice<BelConfigEntryPOD> entries;
|
||||
});
|
||||
|
||||
NPNR_PACKED_STRUCT(struct CellPathDelayPOD {
|
||||
@ -211,8 +184,7 @@ NPNR_PACKED_STRUCT(struct CellPathDelayPOD {
|
||||
|
||||
NPNR_PACKED_STRUCT(struct CellTimingPOD {
|
||||
int32_t type;
|
||||
int32_t num_paths;
|
||||
RelPtr<CellPathDelayPOD> path_delays;
|
||||
RelSlice<CellPathDelayPOD> path_delays;
|
||||
});
|
||||
|
||||
NPNR_PACKED_STRUCT(struct GlobalNetworkInfoPOD {
|
||||
@ -232,19 +204,17 @@ NPNR_PACKED_STRUCT(struct GlobalNetworkInfoPOD {
|
||||
|
||||
NPNR_PACKED_STRUCT(struct ChipInfoPOD {
|
||||
int32_t width, height;
|
||||
int32_t num_bels, num_wires, num_pips;
|
||||
int32_t num_switches, num_belcfgs, num_packages;
|
||||
int32_t num_timing_cells, num_global_networks;
|
||||
RelPtr<BelInfoPOD> bel_data;
|
||||
RelPtr<WireInfoPOD> wire_data;
|
||||
RelPtr<PipInfoPOD> pip_data;
|
||||
RelPtr<TileType> tile_grid;
|
||||
uint32_t num_switches;
|
||||
RelSlice<BelInfoPOD> bel_data;
|
||||
RelSlice<WireInfoPOD> wire_data;
|
||||
RelSlice<PipInfoPOD> pip_data;
|
||||
RelSlice<TileType> tile_grid;
|
||||
RelPtr<BitstreamInfoPOD> bits_info;
|
||||
RelPtr<BelConfigPOD> bel_config;
|
||||
RelPtr<PackageInfoPOD> packages_data;
|
||||
RelPtr<CellTimingPOD> cell_timing;
|
||||
RelPtr<GlobalNetworkInfoPOD> global_network_info;
|
||||
RelPtr<RelPtr<char>> tile_wire_names;
|
||||
RelSlice<BelConfigPOD> bel_config;
|
||||
RelSlice<PackageInfoPOD> packages_data;
|
||||
RelSlice<CellTimingPOD> cell_timing;
|
||||
RelSlice<GlobalNetworkInfoPOD> global_network_info;
|
||||
RelSlice<RelPtr<char>> tile_wire_names;
|
||||
});
|
||||
|
||||
/************************ End of chipdb section. ************************/
|
||||
@ -495,7 +465,7 @@ struct Arch : BaseCtx
|
||||
{
|
||||
BelRange range;
|
||||
range.b.cursor = 0;
|
||||
range.e.cursor = chip_info->num_bels;
|
||||
range.e.cursor = chip_info->bel_data.size();
|
||||
return range;
|
||||
}
|
||||
|
||||
@ -609,7 +579,7 @@ struct Arch : BaseCtx
|
||||
BelPinRange range;
|
||||
NPNR_ASSERT(wire != WireId());
|
||||
range.b.ptr = chip_info->wire_data[wire.index].bel_pins.get();
|
||||
range.e.ptr = range.b.ptr + chip_info->wire_data[wire.index].num_bel_pins;
|
||||
range.e.ptr = range.b.ptr + chip_info->wire_data[wire.index].bel_pins.size();
|
||||
return range;
|
||||
}
|
||||
|
||||
@ -617,7 +587,7 @@ struct Arch : BaseCtx
|
||||
{
|
||||
WireRange range;
|
||||
range.b.cursor = 0;
|
||||
range.e.cursor = chip_info->num_wires;
|
||||
range.e.cursor = chip_info->wire_data.size();
|
||||
return range;
|
||||
}
|
||||
|
||||
@ -720,7 +690,7 @@ struct Arch : BaseCtx
|
||||
{
|
||||
AllPipRange range;
|
||||
range.b.cursor = 0;
|
||||
range.e.cursor = chip_info->num_pips;
|
||||
range.e.cursor = chip_info->pip_data.size();
|
||||
return range;
|
||||
}
|
||||
|
||||
@ -772,7 +742,7 @@ struct Arch : BaseCtx
|
||||
PipRange range;
|
||||
NPNR_ASSERT(wire != WireId());
|
||||
range.b.cursor = chip_info->wire_data[wire.index].pips_downhill.get();
|
||||
range.e.cursor = range.b.cursor + chip_info->wire_data[wire.index].num_downhill;
|
||||
range.e.cursor = range.b.cursor + chip_info->wire_data[wire.index].pips_downhill.size();
|
||||
return range;
|
||||
}
|
||||
|
||||
@ -781,7 +751,7 @@ struct Arch : BaseCtx
|
||||
PipRange range;
|
||||
NPNR_ASSERT(wire != WireId());
|
||||
range.b.cursor = chip_info->wire_data[wire.index].pips_uphill.get();
|
||||
range.e.cursor = range.b.cursor + chip_info->wire_data[wire.index].num_uphill;
|
||||
range.e.cursor = range.b.cursor + chip_info->wire_data[wire.index].pips_uphill.size();
|
||||
return range;
|
||||
}
|
||||
|
||||
|
@ -34,9 +34,9 @@ inline TileType tile_at(const Context *ctx, int x, int y)
|
||||
|
||||
const ConfigEntryPOD &find_config(const TileInfoPOD &tile, const std::string &name)
|
||||
{
|
||||
for (int i = 0; i < tile.num_config_entries; i++) {
|
||||
if (std::string(tile.entries[i].name.get()) == name) {
|
||||
return tile.entries[i];
|
||||
for (auto &entry : tile.entries) {
|
||||
if (std::string(entry.name.get()) == name) {
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
NPNR_ASSERT_FALSE_STR("unable to find config bit " + name);
|
||||
@ -44,8 +44,7 @@ const ConfigEntryPOD &find_config(const TileInfoPOD &tile, const std::string &na
|
||||
|
||||
std::tuple<int8_t, int8_t, int8_t> get_ieren(const BitstreamInfoPOD &bi, int8_t x, int8_t y, int8_t z)
|
||||
{
|
||||
for (int i = 0; i < bi.num_ierens; i++) {
|
||||
auto ie = bi.ierens[i];
|
||||
for (auto &ie : bi.ierens) {
|
||||
if (ie.iox == x && ie.ioy == y && ie.ioz == z) {
|
||||
return std::make_tuple(ie.ierx, ie.iery, ie.ierz);
|
||||
}
|
||||
@ -59,8 +58,8 @@ bool get_config(const TileInfoPOD &ti, std::vector<std::vector<int8_t>> &tile_cf
|
||||
{
|
||||
const ConfigEntryPOD &cfg = find_config(ti, name);
|
||||
if (index == -1) {
|
||||
for (int i = 0; i < cfg.num_bits; i++) {
|
||||
return tile_cfg.at(cfg.bits[i].row).at(cfg.bits[i].col);
|
||||
for (auto &bit : cfg.bits) {
|
||||
return tile_cfg.at(bit.row).at(bit.col);
|
||||
}
|
||||
} else {
|
||||
return tile_cfg.at(cfg.bits[index].row).at(cfg.bits[index].col);
|
||||
@ -73,8 +72,8 @@ void set_config(const TileInfoPOD &ti, std::vector<std::vector<int8_t>> &tile_cf
|
||||
{
|
||||
const ConfigEntryPOD &cfg = find_config(ti, name);
|
||||
if (index == -1) {
|
||||
for (int i = 0; i < cfg.num_bits; i++) {
|
||||
int8_t &cbit = tile_cfg.at(cfg.bits[i].row).at(cfg.bits[i].col);
|
||||
for (auto &bit : cfg.bits) {
|
||||
int8_t &cbit = tile_cfg.at(bit.row).at(bit.col);
|
||||
if (cbit && !value)
|
||||
log_error("clearing already set config bit %s\n", name.c_str());
|
||||
cbit = value;
|
||||
@ -124,9 +123,9 @@ char get_hexdigit(int i) { return std::string("0123456789ABCDEF").at(i); }
|
||||
|
||||
static const BelConfigPOD &get_ec_config(const ChipInfoPOD *chip, BelId bel)
|
||||
{
|
||||
for (int i = 0; i < chip->num_belcfgs; i++) {
|
||||
if (chip->bel_config[i].bel_index == bel.index)
|
||||
return chip->bel_config[i];
|
||||
for (auto &cfg : chip->bel_config) {
|
||||
if (cfg.bel_index == bel.index)
|
||||
return cfg;
|
||||
}
|
||||
NPNR_ASSERT_FALSE("failed to find bel config");
|
||||
}
|
||||
@ -135,8 +134,7 @@ typedef std::vector<std::vector<std::vector<std::vector<int8_t>>>> chipconfig_t;
|
||||
|
||||
static bool has_ec_cbit(const BelConfigPOD &cell_cbits, std::string name)
|
||||
{
|
||||
for (int i = 0; i < cell_cbits.num_entries; i++) {
|
||||
const auto &cbit = cell_cbits.entries[i];
|
||||
for (auto &cbit : cell_cbits.entries) {
|
||||
if (cbit.entry_name.get() == name)
|
||||
return true;
|
||||
}
|
||||
@ -148,8 +146,7 @@ static void set_ec_cbit(chipconfig_t &config, const Context *ctx, const BelConfi
|
||||
{
|
||||
const ChipInfoPOD *chip = ctx->chip_info;
|
||||
|
||||
for (int i = 0; i < cell_cbits.num_entries; i++) {
|
||||
const auto &cbit = cell_cbits.entries[i];
|
||||
for (auto &cbit : cell_cbits.entries) {
|
||||
if (cbit.entry_name.get() == name) {
|
||||
const auto &ti = chip->bits_info->tiles_nonrouting[tile_at(ctx, cbit.x, cbit.y)];
|
||||
set_config(ti, config.at(cbit.y).at(cbit.x), prefix + cbit.cbit_name.get(), value);
|
||||
@ -605,11 +602,9 @@ void write_asc(const Context *ctx, std::ostream &out)
|
||||
} else if (cell.second->type == ctx->id("SB_GB")) {
|
||||
if (cell.second->gbInfo.forPadIn) {
|
||||
Loc gb_loc = ctx->getBelLocation(bel);
|
||||
for (int i = 0; i < ci.num_global_networks; i++) {
|
||||
if ((gb_loc.x == ci.global_network_info[i].gb_x) && (gb_loc.y == ci.global_network_info[i].gb_y)) {
|
||||
extra_bits.push_back(std::make_tuple(ci.global_network_info[i].pi_eb_bank,
|
||||
ci.global_network_info[i].pi_eb_x,
|
||||
ci.global_network_info[i].pi_eb_y));
|
||||
for (auto &glb : ci.global_network_info) {
|
||||
if ((gb_loc.x == glb.gb_x) && (gb_loc.y == glb.gb_y)) {
|
||||
extra_bits.push_back(std::make_tuple(glb.pi_eb_bank, glb.pi_eb_x, glb.pi_eb_y));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1077,6 +1077,13 @@ class BinaryBlobAssembler:
|
||||
else:
|
||||
print("ref %s %s" % (name, comment))
|
||||
|
||||
def r_slice(self, name, length, comment):
|
||||
if comment is None:
|
||||
print("ref %s" % (name,))
|
||||
else:
|
||||
print("ref %s %s" % (name, comment))
|
||||
print ("u32 %d" % (length, ))
|
||||
|
||||
def s(self, s, comment):
|
||||
assert "|" not in s
|
||||
print("str |%s| %s" % (s, comment))
|
||||
@ -1135,8 +1142,7 @@ bba.l("bel_data_%s" % dev_name, "BelInfoPOD")
|
||||
for bel in range(len(bel_name)):
|
||||
bba.s(bel_name[bel], "name")
|
||||
bba.u32(constids[bel_type[bel]], "type")
|
||||
bba.u32(len(bel_wires[bel]), "num_bel_wires")
|
||||
bba.r("bel_wires_%d" % bel, "bel_wires")
|
||||
bba.r_slice("bel_wires_%d" % bel, len(bel_wires[bel]), "bel_wires")
|
||||
bba.u8(bel_pos[bel][0], "x")
|
||||
bba.u8(bel_pos[bel][1], "y")
|
||||
bba.u8(bel_pos[bel][2], "z")
|
||||
@ -1292,8 +1298,7 @@ for t in range(num_tile_types):
|
||||
bba.l("tile%d_config" % t, "ConfigEntryPOD")
|
||||
for name, num_bits, t, safename in centries_info:
|
||||
bba.s(name, "name")
|
||||
bba.u32(num_bits, "num_bits")
|
||||
bba.r("tile%d_%s_bits" % (t, safename), "num_bits")
|
||||
bba.r_slice("tile%d_%s_bits" % (t, safename), num_bits, "num_bits")
|
||||
if len(centries_info) == 0:
|
||||
bba.u32(0, "padding")
|
||||
ti = dict()
|
||||
@ -1306,22 +1311,19 @@ for t in range(num_tile_types):
|
||||
bba.l("wire_data_%s" % dev_name, "WireInfoPOD")
|
||||
for wire, info in enumerate(wireinfo):
|
||||
bba.s(info["name"], "name")
|
||||
bba.u32(info["num_uphill"], "num_uphill")
|
||||
bba.u32(info["num_downhill"], "num_downhill")
|
||||
bba.r(info["list_uphill"], "pips_uphill")
|
||||
bba.r(info["list_downhill"], "pips_downhill")
|
||||
bba.u32(info["num_bel_pins"], "num_bel_pins")
|
||||
bba.r(info["list_bel_pins"], "bel_pins")
|
||||
bba.r_slice(info["list_uphill"], info["num_uphill"], "pips_uphill")
|
||||
bba.r_slice(info["list_downhill"], info["num_downhill"], "pips_downhill")
|
||||
bba.r_slice(info["list_bel_pins"], info["num_bel_pins"], "bel_pins")
|
||||
|
||||
num_segments = 0
|
||||
for segs in wire_segments[wire].values():
|
||||
num_segments += len(segs)
|
||||
bba.u32(num_segments, "num_segments")
|
||||
|
||||
if num_segments:
|
||||
bba.r("wire_segments_%d" % wire, "segments")
|
||||
bba.r_slice("wire_segments_%d" % wire, num_segments, "segments")
|
||||
else:
|
||||
bba.u32(0, "segments")
|
||||
bba.u32(0, "segments_len")
|
||||
|
||||
bba.u32(wiredelay(wire, fast_timings), "fast_delay")
|
||||
bba.u32(wiredelay(wire, slow_timings), "slow_delay")
|
||||
@ -1402,8 +1404,8 @@ bba.l("tile_data_%s" % dev_name, "TileInfoPOD")
|
||||
for info in tileinfo:
|
||||
bba.u8(info["cols"], "cols")
|
||||
bba.u8(info["rows"], "rows")
|
||||
bba.u16(info["num_entries"], "num_entries")
|
||||
bba.r(info["entries"], "entries")
|
||||
bba.u16(0, "padding")
|
||||
bba.r_slice(info["entries"], info["num_entries"], "entries")
|
||||
|
||||
bba.l("ieren_data_%s" % dev_name, "IerenInfoPOD")
|
||||
for ieren in ierens:
|
||||
@ -1418,11 +1420,9 @@ if len(ierens) % 2 == 1:
|
||||
bba.u16(0, "padding")
|
||||
|
||||
bba.l("bits_info_%s" % dev_name, "BitstreamInfoPOD")
|
||||
bba.u32(len(switchinfo), "num_switches")
|
||||
bba.u32(len(ierens), "num_ierens")
|
||||
bba.r("tile_data_%s" % dev_name, "tiles_nonrouting")
|
||||
bba.r("switch_data_%s" % dev_name, "switches")
|
||||
bba.r("ieren_data_%s" % dev_name, "ierens")
|
||||
bba.r_slice("tile_data_%s" % dev_name, len(tileinfo), "tiles_nonrouting")
|
||||
bba.r_slice("switch_data_%s" % dev_name, len(switchinfo), "switches")
|
||||
bba.r_slice("ieren_data_%s" % dev_name, len(ierens), "ierens")
|
||||
|
||||
bba.l("tile_grid_%s" % dev_name, "TileType")
|
||||
for t in tilegrid:
|
||||
@ -1442,14 +1442,12 @@ if len(extra_cell_config) > 0:
|
||||
bba.l("bel_config_%s" % dev_name, "BelConfigPOD")
|
||||
for bel_idx, entries in sorted(extra_cell_config.items()):
|
||||
bba.u32(bel_idx, "bel_index")
|
||||
bba.u32(len(entries), "num_entries")
|
||||
bba.r("bel%d_config_entries" % bel_idx if len(entries) > 0 else None, "entries")
|
||||
bba.r_slice("bel%d_config_entries" % bel_idx if len(entries) > 0 else None, len(entries), "entries")
|
||||
|
||||
bba.l("package_info_%s" % dev_name, "PackageInfoPOD")
|
||||
for info in packageinfo:
|
||||
bba.s(info[0], "name")
|
||||
bba.u32(info[1], "num_pins")
|
||||
bba.r(info[2], "pins")
|
||||
bba.r_slice(info[2], info[1], "pins")
|
||||
|
||||
for cell, timings in sorted(cell_timings.items()):
|
||||
beltype = constids[cell]
|
||||
@ -1465,8 +1463,7 @@ bba.l("cell_timings_%s" % dev_name, "CellTimingPOD")
|
||||
for cell, timings in sorted(cell_timings.items()):
|
||||
beltype = constids[cell]
|
||||
bba.u32(beltype, "type")
|
||||
bba.u32(len(timings), "num_paths")
|
||||
bba.r("cell_paths_%d" % beltype, "path_delays")
|
||||
bba.r_slice("cell_paths_%d" % beltype, len(timings), "path_delays")
|
||||
|
||||
bba.l("global_network_info_%s" % dev_name, "GlobalNetworkInfoPOD")
|
||||
for i in range(len(glbinfo)):
|
||||
@ -1479,23 +1476,16 @@ for i in range(len(glbinfo)):
|
||||
bba.l("chip_info_%s" % dev_name)
|
||||
bba.u32(dev_width, "dev_width")
|
||||
bba.u32(dev_height, "dev_height")
|
||||
bba.u32(len(bel_name), "num_bels")
|
||||
bba.u32(num_wires, "num_wires")
|
||||
bba.u32(len(pipinfo), "num_pips")
|
||||
bba.u32(len(switchinfo), "num_switches")
|
||||
bba.u32(len(extra_cell_config), "num_belcfgs")
|
||||
bba.u32(len(packageinfo), "num_packages")
|
||||
bba.u32(len(cell_timings), "num_timing_cells")
|
||||
bba.u32(len(glbinfo), "num_global_networks")
|
||||
bba.r("bel_data_%s" % dev_name, "bel_data")
|
||||
bba.r("wire_data_%s" % dev_name, "wire_data")
|
||||
bba.r("pip_data_%s" % dev_name, "pip_data")
|
||||
bba.r("tile_grid_%s" % dev_name, "tile_grid")
|
||||
bba.r_slice("bel_data_%s" % dev_name, len(bel_name), "bel_data")
|
||||
bba.r_slice("wire_data_%s" % dev_name, num_wires, "wire_data")
|
||||
bba.r_slice("pip_data_%s" % dev_name, len(pipinfo), "pip_data")
|
||||
bba.r_slice("tile_grid_%s" % dev_name, len(tilegrid), "tile_grid")
|
||||
bba.r("bits_info_%s" % dev_name, "bits_info")
|
||||
bba.r("bel_config_%s" % dev_name if len(extra_cell_config) > 0 else None, "bel_config")
|
||||
bba.r("package_info_%s" % dev_name, "packages_data")
|
||||
bba.r("cell_timings_%s" % dev_name, "cell_timing")
|
||||
bba.r("global_network_info_%s" % dev_name, "global_network_info")
|
||||
bba.r("tile_wire_names", "tile_wire_names")
|
||||
bba.r_slice("bel_config_%s" % dev_name if len(extra_cell_config) > 0 else None, len(extra_cell_config), "bel_config")
|
||||
bba.r_slice("package_info_%s" % dev_name, len(packageinfo), "packages_data")
|
||||
bba.r_slice("cell_timings_%s" % dev_name, len(cell_timings), "cell_timing")
|
||||
bba.r_slice("global_network_info_%s" % dev_name, len(glbinfo), "global_network_info")
|
||||
bba.r_slice("tile_wire_names", len(gfx_wire_names), "tile_wire_names")
|
||||
|
||||
bba.pop()
|
||||
|
@ -29,7 +29,7 @@ void ice40DelayFuzzerMain(Context *ctx)
|
||||
{
|
||||
std::vector<WireId> srcWires, dstWires;
|
||||
|
||||
for (int i = 0; i < ctx->chip_info->num_wires; i++) {
|
||||
for (int i = 0; i < int(ctx->chip_info->wire_data.size()); i++) {
|
||||
WireId wire;
|
||||
wire.index = i;
|
||||
|
||||
|
@ -1357,14 +1357,11 @@ void pack_plls(Context *ctx)
|
||||
auto feedback_path = packed->params[ctx->id("FEEDBACK_PATH")].is_string
|
||||
? packed->params[ctx->id("FEEDBACK_PATH")].as_string()
|
||||
: std::to_string(packed->params[ctx->id("FEEDBACK_PATH")].as_int64());
|
||||
std::string fbp_value =
|
||||
feedback_path == "DELAY"
|
||||
? "0"
|
||||
: feedback_path == "SIMPLE"
|
||||
? "1"
|
||||
: feedback_path == "PHASE_AND_DELAY"
|
||||
? "2"
|
||||
: feedback_path == "EXTERNAL" ? "6" : std::string(feedback_path);
|
||||
std::string fbp_value = feedback_path == "DELAY" ? "0"
|
||||
: feedback_path == "SIMPLE" ? "1"
|
||||
: feedback_path == "PHASE_AND_DELAY" ? "2"
|
||||
: feedback_path == "EXTERNAL" ? "6"
|
||||
: std::string(feedback_path);
|
||||
if (!std::all_of(fbp_value.begin(), fbp_value.end(), isdigit))
|
||||
log_error("PLL '%s' has unsupported FEEDBACK_PATH value '%s'\n", ci->name.c_str(ctx),
|
||||
feedback_path.c_str());
|
||||
|
@ -102,8 +102,7 @@ Arch::Arch(ArchArgs args) : args(args)
|
||||
}
|
||||
// Set up chip_info
|
||||
chip_info = nullptr;
|
||||
for (size_t i = 0; i < db->num_chips; i++) {
|
||||
auto &chip = db->chips[i];
|
||||
for (auto &chip : db->chips) {
|
||||
if (chip.device_name.get() == device) {
|
||||
chip_info = &chip;
|
||||
break;
|
||||
@ -112,18 +111,18 @@ Arch::Arch(ArchArgs args) : args(args)
|
||||
if (!chip_info)
|
||||
log_error("Unknown device '%s'.\n", device.c_str());
|
||||
// Set up bba IdStrings
|
||||
for (size_t i = 0; i < db->ids->num_bba_ids; i++) {
|
||||
for (size_t i = 0; i < db->ids->bba_id_strs.size(); i++) {
|
||||
IdString::initialize_add(this, db->ids->bba_id_strs[i].get(), uint32_t(i) + db->ids->num_file_ids);
|
||||
}
|
||||
// Set up validity structures
|
||||
tileStatus.resize(chip_info->num_tiles);
|
||||
for (size_t i = 0; i < chip_info->num_tiles; i++) {
|
||||
tileStatus[i].boundcells.resize(db->loctypes[chip_info->grid[i].loc_type].num_bels);
|
||||
tileStatus.resize(chip_info->grid.size());
|
||||
for (size_t i = 0; i < chip_info->grid.size(); i++) {
|
||||
tileStatus[i].boundcells.resize(db->loctypes[chip_info->grid[i].loc_type].bels.size());
|
||||
}
|
||||
// This structure is needed for a fast getBelByLocation because bels can have an offset
|
||||
for (size_t i = 0; i < chip_info->num_tiles; i++) {
|
||||
for (size_t i = 0; i < chip_info->grid.size(); i++) {
|
||||
auto &loc = db->loctypes[chip_info->grid[i].loc_type];
|
||||
for (unsigned j = 0; j < loc.num_bels; j++) {
|
||||
for (unsigned j = 0; j < loc.bels.size(); j++) {
|
||||
auto &bel = loc.bels[j];
|
||||
int rel_bel_tile;
|
||||
if (!rel_tile(i, bel.rel_x, bel.rel_y, rel_bel_tile))
|
||||
@ -138,7 +137,7 @@ Arch::Arch(ArchArgs args) : args(args)
|
||||
init_cell_pin_data();
|
||||
// Validate and set up package
|
||||
package_idx = -1;
|
||||
for (size_t i = 0; i < chip_info->num_packages; i++) {
|
||||
for (size_t i = 0; i < chip_info->packages.size(); i++) {
|
||||
if (package == chip_info->packages[i].short_name.get()) {
|
||||
package_idx = i;
|
||||
break;
|
||||
@ -146,9 +145,9 @@ Arch::Arch(ArchArgs args) : args(args)
|
||||
}
|
||||
if (package_idx == -1) {
|
||||
std::string all_packages = "";
|
||||
for (size_t i = 0; i < chip_info->num_packages; i++) {
|
||||
for (auto &pkg : chip_info->packages) {
|
||||
all_packages += " ";
|
||||
all_packages += chip_info->packages[i].short_name.get();
|
||||
all_packages += pkg.short_name.get();
|
||||
}
|
||||
log_error("Unknown package '%s'. Available package options:%s\n", package.c_str(), all_packages.c_str());
|
||||
}
|
||||
@ -164,8 +163,7 @@ Arch::Arch(ArchArgs args) : args(args)
|
||||
speed = "12";
|
||||
|
||||
speed_grade = nullptr;
|
||||
for (size_t i = 0; i < db->num_speed_grades; i++) {
|
||||
auto &sg = db->speed_grades[i];
|
||||
for (auto &sg : db->speed_grades) {
|
||||
if (sg.name.get() == speed) {
|
||||
speed_grade = &sg;
|
||||
break;
|
||||
@ -191,7 +189,7 @@ BelId Arch::getBelByName(IdString name) const
|
||||
NPNR_ASSERT(y >= 0 && y < chip_info->height);
|
||||
auto &tile = db->loctypes[chip_info->grid[y * chip_info->width + x].loc_type];
|
||||
IdString bn = id(belname);
|
||||
for (size_t i = 0; i < tile.num_bels; i++) {
|
||||
for (size_t i = 0; i < tile.bels.size(); i++) {
|
||||
if (tile.bels[i].name == bn.index) {
|
||||
BelId ret;
|
||||
ret.tile = y * chip_info->width + x;
|
||||
@ -214,7 +212,7 @@ std::vector<BelId> Arch::getBelsByTile(int x, int y) const
|
||||
WireId Arch::getBelPinWire(BelId bel, IdString pin) const
|
||||
{
|
||||
// Binary search on wire IdString, by ID
|
||||
int num_bel_wires = bel_data(bel).num_ports;
|
||||
int num_bel_wires = bel_data(bel).ports.size();
|
||||
const BelWirePOD *bel_ports = bel_data(bel).ports.get();
|
||||
|
||||
if (num_bel_wires < 7) {
|
||||
@ -243,7 +241,7 @@ WireId Arch::getBelPinWire(BelId bel, IdString pin) const
|
||||
PortType Arch::getBelPinType(BelId bel, IdString pin) const
|
||||
{
|
||||
// Binary search on wire IdString, by ID
|
||||
int num_bel_wires = bel_data(bel).num_ports;
|
||||
int num_bel_wires = bel_data(bel).ports.size();
|
||||
const BelWirePOD *bel_ports = bel_data(bel).ports.get();
|
||||
|
||||
if (num_bel_wires < 7) {
|
||||
@ -272,10 +270,8 @@ PortType Arch::getBelPinType(BelId bel, IdString pin) const
|
||||
std::vector<IdString> Arch::getBelPins(BelId bel) const
|
||||
{
|
||||
std::vector<IdString> ret;
|
||||
int num_bel_wires = bel_data(bel).num_ports;
|
||||
const BelWirePOD *bel_ports = bel_data(bel).ports.get();
|
||||
for (int i = 0; i < num_bel_wires; i++)
|
||||
ret.push_back(IdString(bel_ports[i].port));
|
||||
for (auto &p : bel_data(bel).ports)
|
||||
ret.push_back(IdString(p.port));
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -305,7 +301,7 @@ WireId Arch::getWireByName(IdString name) const
|
||||
NPNR_ASSERT(y >= 0 && y < chip_info->height);
|
||||
auto &tile = db->loctypes[chip_info->grid[y * chip_info->width + x].loc_type];
|
||||
IdString wn = id(wirename);
|
||||
for (size_t i = 0; i < tile.num_wires; i++) {
|
||||
for (size_t i = 0; i < tile.wires.size(); i++) {
|
||||
if (tile.wires[i].name == wn.index) {
|
||||
WireId ret;
|
||||
ret.tile = y * chip_info->width + x;
|
||||
@ -754,10 +750,9 @@ void Arch::set_cell_pinmux(CellInfo *cell, IdString pin, CellPinMux state)
|
||||
|
||||
const PadInfoPOD *Arch::get_pkg_pin_data(const std::string &pin) const
|
||||
{
|
||||
for (size_t i = 0; i < chip_info->num_pads; i++) {
|
||||
const PadInfoPOD *pad = &(chip_info->pads[i]);
|
||||
if (pin == pad->pins[package_idx].get())
|
||||
return pad;
|
||||
for (auto &pad : chip_info->pads) {
|
||||
if (pin == pad.pins[package_idx].get())
|
||||
return &pad;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
@ -814,10 +809,9 @@ const PadInfoPOD *Arch::get_bel_pad(BelId bel) const
|
||||
return nullptr;
|
||||
}
|
||||
// Lookup in the list of pads
|
||||
for (size_t i = 0; i < chip_info->num_pads; i++) {
|
||||
const PadInfoPOD *pad = &(chip_info->pads[i]);
|
||||
if (pad->side == side && pad->offset == offset && pad->pio_index == loc.z)
|
||||
return pad;
|
||||
for (auto &pad : chip_info->pads) {
|
||||
if (pad.side == side && pad.offset == offset && pad.pio_index == loc.z)
|
||||
return &pad;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
@ -825,10 +819,10 @@ const PadInfoPOD *Arch::get_bel_pad(BelId bel) const
|
||||
std::string Arch::get_pad_functions(const PadInfoPOD *pad) const
|
||||
{
|
||||
std::string s;
|
||||
for (size_t i = 0; i < pad->num_funcs; i++) {
|
||||
for (auto f : pad->func_strs) {
|
||||
if (!s.empty())
|
||||
s += '/';
|
||||
s += IdString(pad->func_strs[i]).str(this);
|
||||
s += IdString(f).str(this);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
@ -872,7 +866,7 @@ bool Arch::is_dsp_cell(const CellInfo *cell) const
|
||||
int Arch::get_cell_timing_idx(IdString cell_type, IdString cell_variant) const
|
||||
{
|
||||
return db_binary_search(
|
||||
speed_grade->cell_types.get(), speed_grade->num_cell_types,
|
||||
speed_grade->cell_types.get(), speed_grade->cell_types.size(),
|
||||
[](const CellTimingPOD &ct) { return std::make_pair(ct.cell_type, ct.cell_variant); },
|
||||
std::make_pair(cell_type.index, cell_variant.index));
|
||||
}
|
||||
@ -882,7 +876,7 @@ bool Arch::lookup_cell_delay(int type_idx, IdString from_port, IdString to_port,
|
||||
NPNR_ASSERT(type_idx != -1);
|
||||
const auto &ct = speed_grade->cell_types[type_idx];
|
||||
int dly_idx = db_binary_search(
|
||||
ct.prop_delays.get(), ct.num_prop_delays,
|
||||
ct.prop_delays.get(), ct.prop_delays.size(),
|
||||
[](const CellPropDelayPOD &pd) { return std::make_pair(pd.to_port, pd.from_port); },
|
||||
std::make_pair(to_port.index, from_port.index));
|
||||
if (dly_idx == -1)
|
||||
@ -898,7 +892,7 @@ void Arch::lookup_cell_setuphold(int type_idx, IdString from_port, IdString cloc
|
||||
NPNR_ASSERT(type_idx != -1);
|
||||
const auto &ct = speed_grade->cell_types[type_idx];
|
||||
int dly_idx = db_binary_search(
|
||||
ct.setup_holds.get(), ct.num_setup_holds,
|
||||
ct.setup_holds.get(), ct.setup_holds.size(),
|
||||
[](const CellSetupHoldPOD &sh) { return std::make_pair(sh.sig_port, sh.clock_port); },
|
||||
std::make_pair(from_port.index, clock.index));
|
||||
NPNR_ASSERT(dly_idx != -1);
|
||||
@ -914,7 +908,7 @@ void Arch::lookup_cell_setuphold_clock(int type_idx, IdString from_port, IdStrin
|
||||
NPNR_ASSERT(type_idx != -1);
|
||||
const auto &ct = speed_grade->cell_types[type_idx];
|
||||
int dly_idx = db_binary_search(
|
||||
ct.setup_holds.get(), ct.num_setup_holds, [](const CellSetupHoldPOD &sh) { return sh.sig_port; },
|
||||
ct.setup_holds.get(), ct.setup_holds.size(), [](const CellSetupHoldPOD &sh) { return sh.sig_port; },
|
||||
from_port.index);
|
||||
NPNR_ASSERT(dly_idx != -1);
|
||||
clock = IdString(ct.setup_holds[dly_idx].clock_port);
|
||||
@ -928,7 +922,7 @@ void Arch::lookup_cell_clock_out(int type_idx, IdString to_port, IdString &clock
|
||||
NPNR_ASSERT(type_idx != -1);
|
||||
const auto &ct = speed_grade->cell_types[type_idx];
|
||||
int dly_idx = db_binary_search(
|
||||
ct.prop_delays.get(), ct.num_prop_delays, [](const CellPropDelayPOD &pd) { return pd.to_port; },
|
||||
ct.prop_delays.get(), ct.prop_delays.size(), [](const CellPropDelayPOD &pd) { return pd.to_port; },
|
||||
to_port.index);
|
||||
NPNR_ASSERT(dly_idx != -1);
|
||||
clock = ct.prop_delays[dly_idx].from_port;
|
||||
@ -942,7 +936,7 @@ TimingPortClass Arch::lookup_port_type(int type_idx, IdString port, PortType dir
|
||||
const auto &ct = speed_grade->cell_types[type_idx];
|
||||
// If a setup-hold entry exists, then this is a register input
|
||||
int sh_idx = db_binary_search(
|
||||
ct.setup_holds.get(), ct.num_setup_holds,
|
||||
ct.setup_holds.get(), ct.setup_holds.size(),
|
||||
[](const CellSetupHoldPOD &sh) { return std::make_pair(sh.sig_port, sh.clock_port); },
|
||||
std::make_pair(port.index, clock.index));
|
||||
return (sh_idx != -1) ? TMG_REGISTER_INPUT : TMG_COMB_INPUT;
|
||||
|
158
nexus/arch.h
158
nexus/arch.h
@ -28,23 +28,7 @@
|
||||
|
||||
NEXTPNR_NAMESPACE_BEGIN
|
||||
|
||||
template <typename T> struct RelPtr
|
||||
{
|
||||
int32_t offset;
|
||||
|
||||
// void set(const T *ptr) {
|
||||
// offset = reinterpret_cast<const char*>(ptr) -
|
||||
// reinterpret_cast<const char*>(this);
|
||||
// }
|
||||
|
||||
const T *get() const { return reinterpret_cast<const T *>(reinterpret_cast<const char *>(this) + offset); }
|
||||
|
||||
const T &operator[](size_t index) const { return get()[index]; }
|
||||
|
||||
const T &operator*() const { return *(get()); }
|
||||
|
||||
const T *operator->() const { return get(); }
|
||||
};
|
||||
#include "relptr.h"
|
||||
|
||||
/*
|
||||
Fully deduplicated database
|
||||
@ -73,12 +57,11 @@ NPNR_PACKED_STRUCT(struct BelWirePOD {
|
||||
});
|
||||
|
||||
NPNR_PACKED_STRUCT(struct BelInfoPOD {
|
||||
int32_t name; // bel name in tile IdString
|
||||
int32_t type; // bel type IdString
|
||||
int16_t rel_x, rel_y; // bel location relative to parent
|
||||
int32_t z; // bel location absolute Z
|
||||
RelPtr<BelWirePOD> ports; // ports, sorted by name IdString
|
||||
int32_t num_ports; // number of ports
|
||||
int32_t name; // bel name in tile IdString
|
||||
int32_t type; // bel type IdString
|
||||
int16_t rel_x, rel_y; // bel location relative to parent
|
||||
int32_t z; // bel location absolute Z
|
||||
RelSlice<BelWirePOD> ports; // ports, sorted by name IdString
|
||||
});
|
||||
|
||||
NPNR_PACKED_STRUCT(struct BelPinPOD {
|
||||
@ -94,10 +77,9 @@ enum TileWireFlags : uint32_t
|
||||
NPNR_PACKED_STRUCT(struct LocWireInfoPOD {
|
||||
int32_t name; // wire name in tile IdString
|
||||
uint32_t flags;
|
||||
int32_t num_uphill, num_downhill, num_bpins;
|
||||
// Note this pip lists exclude neighbourhood pips
|
||||
RelPtr<int32_t> pips_uh, pips_dh; // list of uphill/downhill pip indices in tile
|
||||
RelPtr<BelPinPOD> bel_pins;
|
||||
RelSlice<int32_t> pips_uh, pips_dh; // list of uphill/downhill pip indices in tile
|
||||
RelSlice<BelPinPOD> bel_pins;
|
||||
});
|
||||
|
||||
enum PipFlags
|
||||
@ -137,19 +119,15 @@ NPNR_PACKED_STRUCT(struct RelWireInfoPOD {
|
||||
uint8_t arc_flags;
|
||||
});
|
||||
|
||||
NPNR_PACKED_STRUCT(struct WireNeighboursInfoPOD {
|
||||
uint32_t num_nwires;
|
||||
RelPtr<RelWireInfoPOD> neigh_wires;
|
||||
});
|
||||
NPNR_PACKED_STRUCT(struct WireNeighboursInfoPOD { RelSlice<RelWireInfoPOD> neigh_wires; });
|
||||
|
||||
NPNR_PACKED_STRUCT(struct LocNeighourhoodPOD { RelPtr<WireNeighboursInfoPOD> wire_neighbours; });
|
||||
NPNR_PACKED_STRUCT(struct LocNeighourhoodPOD { RelSlice<WireNeighboursInfoPOD> wire_neighbours; });
|
||||
|
||||
NPNR_PACKED_STRUCT(struct LocTypePOD {
|
||||
uint32_t num_bels, num_wires, num_pips, num_nhtypes;
|
||||
RelPtr<BelInfoPOD> bels;
|
||||
RelPtr<LocWireInfoPOD> wires;
|
||||
RelPtr<PipInfoPOD> pips;
|
||||
RelPtr<LocNeighourhoodPOD> neighbourhoods;
|
||||
RelSlice<BelInfoPOD> bels;
|
||||
RelSlice<LocWireInfoPOD> wires;
|
||||
RelSlice<PipInfoPOD> pips;
|
||||
RelSlice<LocNeighourhoodPOD> neighbourhoods;
|
||||
});
|
||||
|
||||
// A physical (bitstream) tile; of which there may be more than
|
||||
@ -180,8 +158,8 @@ NPNR_PACKED_STRUCT(struct GridLocationPOD {
|
||||
uint32_t loc_type;
|
||||
uint32_t loc_flags;
|
||||
uint16_t neighbourhood_type;
|
||||
uint16_t num_phys_tiles;
|
||||
RelPtr<PhysicalTileInfoPOD> phys_tiles;
|
||||
uint16_t padding;
|
||||
RelSlice<PhysicalTileInfoPOD> phys_tiles;
|
||||
});
|
||||
|
||||
enum PioSide : uint8_t
|
||||
@ -216,12 +194,10 @@ NPNR_PACKED_STRUCT(struct PadInfoPOD {
|
||||
|
||||
int8_t vref_index; // VREF index in bank, or -1 if N/A
|
||||
|
||||
uint16_t num_funcs; // length of special function list
|
||||
uint16_t padding; // padding for alignment
|
||||
int16_t padding;
|
||||
|
||||
RelPtr<uint32_t> func_strs; // list of special function IdStrings
|
||||
|
||||
RelPtr<RelPtr<char>> pins; // package index --> package pin name
|
||||
RelSlice<uint32_t> func_strs; // list of special function IdStrings
|
||||
RelSlice<RelPtr<char>> pins; // package index --> package pin name
|
||||
});
|
||||
|
||||
NPNR_PACKED_STRUCT(struct GlobalBranchInfoPOD {
|
||||
@ -243,34 +219,28 @@ NPNR_PACKED_STRUCT(struct GlobalSpineInfoPOD {
|
||||
NPNR_PACKED_STRUCT(struct GlobalHrowInfoPOD {
|
||||
uint16_t hrow_col;
|
||||
uint16_t padding;
|
||||
uint32_t num_spine_cols;
|
||||
RelPtr<uint32_t> spine_cols;
|
||||
RelSlice<uint32_t> spine_cols;
|
||||
});
|
||||
|
||||
NPNR_PACKED_STRUCT(struct GlobalInfoPOD {
|
||||
uint32_t num_branches, num_spines, num_hrows;
|
||||
RelPtr<GlobalBranchInfoPOD> branches;
|
||||
RelPtr<GlobalSpineInfoPOD> spines;
|
||||
RelPtr<GlobalHrowInfoPOD> hrows;
|
||||
RelSlice<GlobalBranchInfoPOD> branches;
|
||||
RelSlice<GlobalSpineInfoPOD> spines;
|
||||
RelSlice<GlobalHrowInfoPOD> hrows;
|
||||
});
|
||||
|
||||
NPNR_PACKED_STRUCT(struct ChipInfoPOD {
|
||||
RelPtr<char> device_name;
|
||||
uint16_t width;
|
||||
uint16_t height;
|
||||
uint32_t num_tiles;
|
||||
uint32_t num_pads;
|
||||
uint32_t num_packages;
|
||||
RelPtr<GridLocationPOD> grid;
|
||||
RelSlice<GridLocationPOD> grid;
|
||||
RelPtr<GlobalInfoPOD> globals;
|
||||
RelPtr<PadInfoPOD> pads;
|
||||
RelPtr<PackageInfoPOD> packages;
|
||||
RelSlice<PadInfoPOD> pads;
|
||||
RelSlice<PackageInfoPOD> packages;
|
||||
});
|
||||
|
||||
NPNR_PACKED_STRUCT(struct IdStringDBPOD {
|
||||
uint32_t num_file_ids; // number of IDs loaded from constids.inc
|
||||
uint32_t num_bba_ids; // number of IDs in BBA file
|
||||
RelPtr<RelPtr<char>> bba_id_strs;
|
||||
uint32_t num_file_ids;
|
||||
RelSlice<RelPtr<char>> bba_id_strs;
|
||||
});
|
||||
|
||||
// Timing structures are generally sorted using IdString indices as keys for fast binary searches
|
||||
@ -298,10 +268,8 @@ NPNR_PACKED_STRUCT(struct CellSetupHoldPOD {
|
||||
NPNR_PACKED_STRUCT(struct CellTimingPOD {
|
||||
int32_t cell_type;
|
||||
int32_t cell_variant;
|
||||
int32_t num_prop_delays;
|
||||
int32_t num_setup_holds;
|
||||
RelPtr<CellPropDelayPOD> prop_delays;
|
||||
RelPtr<CellSetupHoldPOD> setup_holds;
|
||||
RelSlice<CellPropDelayPOD> prop_delays;
|
||||
RelSlice<CellSetupHoldPOD> setup_holds;
|
||||
});
|
||||
|
||||
NPNR_PACKED_STRUCT(struct PipTimingPOD {
|
||||
@ -314,21 +282,16 @@ NPNR_PACKED_STRUCT(struct PipTimingPOD {
|
||||
|
||||
NPNR_PACKED_STRUCT(struct SpeedGradePOD {
|
||||
RelPtr<char> name;
|
||||
int32_t num_cell_types;
|
||||
int32_t num_pip_classes;
|
||||
RelPtr<CellTimingPOD> cell_types;
|
||||
RelPtr<PipTimingPOD> pip_classes;
|
||||
RelSlice<CellTimingPOD> cell_types;
|
||||
RelSlice<PipTimingPOD> pip_classes;
|
||||
});
|
||||
|
||||
NPNR_PACKED_STRUCT(struct DatabasePOD {
|
||||
uint32_t version;
|
||||
uint32_t num_chips;
|
||||
uint32_t num_loctypes;
|
||||
uint32_t num_speed_grades;
|
||||
RelPtr<char> family;
|
||||
RelPtr<ChipInfoPOD> chips;
|
||||
RelPtr<LocTypePOD> loctypes;
|
||||
RelPtr<SpeedGradePOD> speed_grades;
|
||||
RelSlice<ChipInfoPOD> chips;
|
||||
RelSlice<LocTypePOD> loctypes;
|
||||
RelSlice<SpeedGradePOD> speed_grades;
|
||||
RelPtr<IdStringDBPOD> ids;
|
||||
});
|
||||
|
||||
@ -376,8 +339,7 @@ inline bool chip_rel_tile(const ChipInfoPOD *chip, int32_t base, int16_t rel_x,
|
||||
inline int32_t chip_tile_from_xy(const ChipInfoPOD *chip, int32_t x, int32_t y) { return y * chip->width + x; }
|
||||
inline bool chip_get_branch_loc(const ChipInfoPOD *chip, int32_t x, int32_t &branch_x)
|
||||
{
|
||||
for (int i = 0; i < int(chip->globals->num_branches); i++) {
|
||||
auto &b = chip->globals->branches[i];
|
||||
for (auto &b : chip->globals->branches) {
|
||||
if (x >= b.from_col && x <= b.to_col) {
|
||||
branch_x = b.branch_col;
|
||||
return true;
|
||||
@ -388,8 +350,7 @@ inline bool chip_get_branch_loc(const ChipInfoPOD *chip, int32_t x, int32_t &bra
|
||||
inline bool chip_get_spine_loc(const ChipInfoPOD *chip, int32_t x, int32_t y, int32_t &spine_x, int32_t &spine_y)
|
||||
{
|
||||
bool y_found = false;
|
||||
for (int i = 0; i < int(chip->globals->num_spines); i++) {
|
||||
auto &s = chip->globals->spines[i];
|
||||
for (auto &s : chip->globals->spines) {
|
||||
if (y >= s.from_row && y <= s.to_row) {
|
||||
spine_y = s.spine_row;
|
||||
y_found = true;
|
||||
@ -398,10 +359,8 @@ inline bool chip_get_spine_loc(const ChipInfoPOD *chip, int32_t x, int32_t y, in
|
||||
}
|
||||
if (!y_found)
|
||||
return false;
|
||||
for (int i = 0; i < int(chip->globals->num_hrows); i++) {
|
||||
auto &hr = chip->globals->hrows[i];
|
||||
for (int j = 0; j < int(hr.num_spine_cols); j++) {
|
||||
int32_t sc = hr.spine_cols[j];
|
||||
for (auto &hr : chip->globals->hrows) {
|
||||
for (int32_t sc : hr.spine_cols) {
|
||||
if (std::abs(sc - x) < 3) {
|
||||
spine_x = sc;
|
||||
return true;
|
||||
@ -413,8 +372,7 @@ inline bool chip_get_spine_loc(const ChipInfoPOD *chip, int32_t x, int32_t y, in
|
||||
inline bool chip_get_hrow_loc(const ChipInfoPOD *chip, int32_t x, int32_t y, int32_t &hrow_x, int32_t &hrow_y)
|
||||
{
|
||||
bool y_found = false;
|
||||
for (int i = 0; i < int(chip->globals->num_spines); i++) {
|
||||
auto &s = chip->globals->spines[i];
|
||||
for (auto &s : chip->globals->spines) {
|
||||
if (std::abs(y - s.spine_row) < 3) {
|
||||
hrow_y = s.spine_row;
|
||||
y_found = true;
|
||||
@ -423,10 +381,8 @@ inline bool chip_get_hrow_loc(const ChipInfoPOD *chip, int32_t x, int32_t y, int
|
||||
}
|
||||
if (!y_found)
|
||||
return false;
|
||||
for (int i = 0; i < int(chip->globals->num_hrows); i++) {
|
||||
auto &hr = chip->globals->hrows[i];
|
||||
for (int j = 0; j < int(hr.num_spine_cols); j++) {
|
||||
int32_t sc = hr.spine_cols[j];
|
||||
for (auto &hr : chip->globals->hrows) {
|
||||
for (int32_t sc : hr.spine_cols) {
|
||||
if (std::abs(sc - x) < 3) {
|
||||
hrow_x = hr.hrow_col;
|
||||
return true;
|
||||
@ -487,8 +443,7 @@ inline WireId chip_canonical_wire(const DatabasePOD *db, const ChipInfoPOD *chip
|
||||
// Not primary; find the primary location which forms the canonical ID
|
||||
auto &nd = chip_nh_data(db, chip, wire);
|
||||
auto &wn = nd.wire_neighbours[index];
|
||||
for (size_t i = 0; i < wn.num_nwires; i++) {
|
||||
auto &nw = wn.neigh_wires[i];
|
||||
for (auto &nw : wn.neigh_wires) {
|
||||
if (nw.arc_flags & LOGICAL_TO_PRIMARY) {
|
||||
if (chip_rel_loc_tile(chip, tile, nw, wire.tile)) {
|
||||
wire.index = nw.wire_index;
|
||||
@ -507,8 +462,7 @@ inline bool chip_wire_is_primary(const DatabasePOD *db, const ChipInfoPOD *chip,
|
||||
// Not primary; find the primary location which forms the canonical ID
|
||||
auto &nd = chip_nh_data(db, chip, wire);
|
||||
auto &wn = nd.wire_neighbours[index];
|
||||
for (size_t i = 0; i < wn.num_nwires; i++) {
|
||||
auto &nw = wn.neigh_wires[i];
|
||||
for (auto &nw : wn.neigh_wires) {
|
||||
if (nw.arc_flags & LOGICAL_TO_PRIMARY) {
|
||||
if (chip_rel_loc_tile(chip, tile, nw, wire.tile)) {
|
||||
return false;
|
||||
@ -531,8 +485,8 @@ struct BelIterator
|
||||
BelIterator operator++()
|
||||
{
|
||||
cursor_index++;
|
||||
while (cursor_tile < int(chip->num_tiles) &&
|
||||
cursor_index >= int(db->loctypes[chip->grid[cursor_tile].loc_type].num_bels)) {
|
||||
while (cursor_tile < int(chip->grid.size()) &&
|
||||
cursor_index >= int(db->loctypes[chip->grid[cursor_tile].loc_type].bels.size())) {
|
||||
cursor_index = 0;
|
||||
cursor_tile++;
|
||||
}
|
||||
@ -585,12 +539,12 @@ struct WireIterator
|
||||
// Iterate over nodes first, then tile wires that aren't nodes
|
||||
do {
|
||||
cursor_index++;
|
||||
while (cursor_tile < int(chip->num_tiles) &&
|
||||
cursor_index >= int(db->loctypes[chip->grid[cursor_tile].loc_type].num_wires)) {
|
||||
while (cursor_tile < int(chip->grid.size()) &&
|
||||
cursor_index >= int(db->loctypes[chip->grid[cursor_tile].loc_type].wires.size())) {
|
||||
cursor_index = 0;
|
||||
cursor_tile++;
|
||||
}
|
||||
} while (cursor_tile < int(chip->num_tiles) && !chip_wire_is_primary(db, chip, cursor_tile, cursor_index));
|
||||
} while (cursor_tile < int(chip->grid.size()) && !chip_wire_is_primary(db, chip, cursor_tile, cursor_index));
|
||||
|
||||
return *this;
|
||||
}
|
||||
@ -641,7 +595,7 @@ struct NeighWireIterator
|
||||
int32_t tile;
|
||||
do
|
||||
cursor++;
|
||||
while (cursor < int(wn.num_nwires) &&
|
||||
while (cursor < int(wn.neigh_wires.size()) &&
|
||||
((wn.neigh_wires[cursor].arc_flags & LOGICAL_TO_PRIMARY) ||
|
||||
!chip_rel_tile(chip, baseWire.tile, wn.neigh_wires[cursor].rel_x, wn.neigh_wires[cursor].rel_y, tile)));
|
||||
}
|
||||
@ -683,8 +637,8 @@ struct AllPipIterator
|
||||
AllPipIterator operator++()
|
||||
{
|
||||
cursor_index++;
|
||||
while (cursor_tile < int(chip->num_tiles) &&
|
||||
cursor_index >= int(db->loctypes[chip->grid[cursor_tile].loc_type].num_pips)) {
|
||||
while (cursor_tile < int(chip->grid.size()) &&
|
||||
cursor_index >= int(db->loctypes[chip->grid[cursor_tile].loc_type].pips.size())) {
|
||||
cursor_index = 0;
|
||||
cursor_tile++;
|
||||
}
|
||||
@ -741,7 +695,7 @@ struct UpDownhillPipIterator
|
||||
break;
|
||||
WireId w = *twi;
|
||||
auto &tile = db->loctypes[chip->grid[w.tile].loc_type];
|
||||
if (cursor < int(uphill ? tile.wires[w.index].num_uphill : tile.wires[w.index].num_downhill))
|
||||
if (cursor < int(uphill ? tile.wires[w.index].pips_uh.size() : tile.wires[w.index].pips_dh.size()))
|
||||
break;
|
||||
++twi;
|
||||
cursor = 0;
|
||||
@ -780,7 +734,7 @@ struct WireBelPinIterator
|
||||
while (true) {
|
||||
if (!(twi != twi_end))
|
||||
break;
|
||||
if (cursor < chip_wire_data(db, chip, *twi).num_bpins)
|
||||
if (cursor < int(chip_wire_data(db, chip, *twi).bel_pins.size()))
|
||||
break;
|
||||
++twi;
|
||||
cursor = 0;
|
||||
@ -1176,7 +1130,7 @@ struct Arch : BaseCtx
|
||||
++range.b; //-1 and then ++ deals with the case of no wires in the first tile
|
||||
range.e.chip = chip_info;
|
||||
range.e.db = db;
|
||||
range.e.cursor_tile = chip_info->num_tiles;
|
||||
range.e.cursor_tile = chip_info->grid.size();
|
||||
range.e.cursor_index = 0;
|
||||
return range;
|
||||
}
|
||||
@ -1485,7 +1439,7 @@ struct Arch : BaseCtx
|
||||
range.e.chip = chip_info;
|
||||
range.e.db = db;
|
||||
range.e.baseWire = wire;
|
||||
range.e.cursor = nh_data(wire).wire_neighbours[wire.index].num_nwires;
|
||||
range.e.cursor = nh_data(wire).wire_neighbours[wire.index].neigh_wires.size();
|
||||
return range;
|
||||
}
|
||||
|
||||
|
@ -1 +1 @@
|
||||
9
|
||||
10
|
||||
|
@ -150,9 +150,9 @@ struct NexusFasmWriter
|
||||
const PhysicalTileInfoPOD &tile_by_type_and_loc(int loc, IdString type)
|
||||
{
|
||||
auto &ploc = ctx->chip_info->grid[loc];
|
||||
for (int i = 0; i < ploc.num_phys_tiles; i++) {
|
||||
if (ploc.phys_tiles[i].tiletype == type.index)
|
||||
return ploc.phys_tiles[i];
|
||||
for (auto &pt : ploc.phys_tiles) {
|
||||
if (pt.tiletype == type.index)
|
||||
return pt;
|
||||
}
|
||||
log_error("No tile of type %s found at location R%dC%d", ctx->nameOf(type), loc / ctx->chip_info->width,
|
||||
loc % ctx->chip_info->width);
|
||||
@ -161,7 +161,7 @@ struct NexusFasmWriter
|
||||
const PhysicalTileInfoPOD &tile_at_loc(int loc)
|
||||
{
|
||||
auto &ploc = ctx->chip_info->grid[loc];
|
||||
NPNR_ASSERT(ploc.num_phys_tiles == 1);
|
||||
NPNR_ASSERT(ploc.phys_tiles.size() == 1);
|
||||
return ploc.phys_tiles[0];
|
||||
}
|
||||
// Escape an internal prjoxide name for FASM by replacing : with __
|
||||
@ -186,7 +186,7 @@ struct NexusFasmWriter
|
||||
{
|
||||
int r = bel.tile / ctx->chip_info->width;
|
||||
int c = bel.tile % ctx->chip_info->width;
|
||||
auto bel_data = ctx->bel_data(bel);
|
||||
auto &bel_data = ctx->bel_data(bel);
|
||||
r += bel_data.rel_y;
|
||||
c += bel_data.rel_x;
|
||||
std::string s = stringf("R%dC%d_%s", r, c, ctx->nameOf(ctx->bel_data(bel).name));
|
||||
|
Loading…
Reference in New Issue
Block a user