nexus: Switch from RelPtr to RelSlice
This replaces RelPtrs and a separate length field with a Rust-style slice containing both a pointer and a length; with bounds checking always enforced. Thus iterating over these structures is both cleaner and safer. Signed-off-by: D. Shah <dave@ds0.me>
This commit is contained in:
parent
dc46d84c35
commit
e049d5f2fc
@ -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
|
||||
|
||||
|
@ -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;
|
||||
|
162
nexus/arch.h
162
nexus/arch.h
@ -46,6 +46,28 @@ template <typename T> struct RelPtr
|
||||
const T *operator->() const { return get(); }
|
||||
};
|
||||
|
||||
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(); }
|
||||
});
|
||||
|
||||
/*
|
||||
Fully deduplicated database
|
||||
|
||||
@ -73,12 +95,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 +115,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 +157,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 +196,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 +232,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 +257,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 +306,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 +320,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 +377,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 +388,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 +397,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 +410,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 +419,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 +481,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 +500,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 +523,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 +577,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 +633,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 +675,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 +733,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 +772,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 +1168,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 +1477,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 __
|
||||
|
Loading…
Reference in New Issue
Block a user