ice40: 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
e049d5f2fc
commit
c10238de8c
@ -306,7 +306,7 @@ void DesignWidget::newContext(Context *ctx)
|
|||||||
{
|
{
|
||||||
TreeModel::ElementXYRoot<WireId>::ElementMap wireMap;
|
TreeModel::ElementXYRoot<WireId>::ElementMap wireMap;
|
||||||
#ifdef ARCH_ICE40
|
#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];
|
const auto wire = &ctx->chip_info->wire_data[i];
|
||||||
WireId wireid;
|
WireId wireid;
|
||||||
wireid.index = i;
|
wireid.index = i;
|
||||||
|
@ -73,8 +73,8 @@ std::vector<std::string> Arch::getSupportedPackages(ArchArgs::ArchArgsTypes chip
|
|||||||
{
|
{
|
||||||
const ChipInfoPOD *chip_info = get_chip_info(chip);
|
const ChipInfoPOD *chip_info = get_chip_info(chip);
|
||||||
std::vector<std::string> packages;
|
std::vector<std::string> packages;
|
||||||
for (int i = 0; i < chip_info->num_packages; i++) {
|
for (auto &pkg : chip_info->packages_data) {
|
||||||
std::string name = chip_info->packages_data[i].name.get();
|
std::string name = pkg.name.get();
|
||||||
if (chip == ArchArgs::LP4K || chip == ArchArgs::HX4K) {
|
if (chip == ArchArgs::LP4K || chip == ArchArgs::HX4K) {
|
||||||
if (name.find(":4k") != std::string::npos)
|
if (name.find(":4k") != std::string::npos)
|
||||||
name = name.substr(0, name.size() - 3);
|
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)
|
if (args.type == ArchArgs::LP4K || args.type == ArchArgs::HX4K)
|
||||||
package_name += ":4k";
|
package_name += ":4k";
|
||||||
|
|
||||||
for (int i = 0; i < chip_info->num_packages; i++) {
|
for (auto &pkg : chip_info->packages_data) {
|
||||||
if (chip_info->packages_data[i].name.get() == package_name) {
|
if (pkg.name.get() == package_name) {
|
||||||
package_info = &(chip_info->packages_data[i]);
|
package_info = &pkg;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (package_info == nullptr)
|
if (package_info == nullptr)
|
||||||
log_error("Unsupported package '%s'.\n", args.package.c_str());
|
log_error("Unsupported package '%s'.\n", args.package.c_str());
|
||||||
|
|
||||||
bel_carry.resize(chip_info->num_bels);
|
bel_carry.resize(chip_info->bel_data.size());
|
||||||
bel_to_cell.resize(chip_info->num_bels);
|
bel_to_cell.resize(chip_info->bel_data.size());
|
||||||
wire_to_net.resize(chip_info->num_wires);
|
wire_to_net.resize(chip_info->wire_data.size());
|
||||||
pip_to_net.resize(chip_info->num_pips);
|
pip_to_net.resize(chip_info->pip_data.size());
|
||||||
switches_locked.resize(chip_info->num_switches);
|
switches_locked.resize(chip_info->num_switches);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -188,7 +188,7 @@ BelId Arch::getBelByName(IdString name) const
|
|||||||
BelId ret;
|
BelId ret;
|
||||||
|
|
||||||
if (bel_by_name.empty()) {
|
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;
|
bel_by_name[id(chip_info->bel_data[i].name.get())] = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -204,7 +204,7 @@ BelId Arch::getBelByLocation(Loc loc) const
|
|||||||
BelId bel;
|
BelId bel;
|
||||||
|
|
||||||
if (bel_by_loc.empty()) {
|
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;
|
BelId b;
|
||||||
b.index = i;
|
b.index = i;
|
||||||
bel_by_loc[getBelLocation(b)] = 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;
|
br.e.cursor = br.b.cursor;
|
||||||
|
|
||||||
if (br.e.cursor != -1) {
|
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)
|
chip_info->bel_data[br.e.cursor].y == y)
|
||||||
br.e.cursor++;
|
br.e.cursor++;
|
||||||
}
|
}
|
||||||
@ -244,7 +244,7 @@ PortType Arch::getBelPinType(BelId bel, IdString pin) const
|
|||||||
{
|
{
|
||||||
NPNR_ASSERT(bel != BelId());
|
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();
|
const BelWirePOD *bel_wires = chip_info->bel_data[bel.index].bel_wires.get();
|
||||||
|
|
||||||
if (num_bel_wires < 7) {
|
if (num_bel_wires < 7) {
|
||||||
@ -283,7 +283,7 @@ WireId Arch::getBelPinWire(BelId bel, IdString pin) const
|
|||||||
|
|
||||||
NPNR_ASSERT(bel != BelId());
|
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();
|
const BelWirePOD *bel_wires = chip_info->bel_data[bel.index].bel_wires.get();
|
||||||
|
|
||||||
if (num_bel_wires < 7) {
|
if (num_bel_wires < 7) {
|
||||||
@ -317,11 +317,8 @@ std::vector<IdString> Arch::getBelPins(BelId bel) const
|
|||||||
|
|
||||||
NPNR_ASSERT(bel != BelId());
|
NPNR_ASSERT(bel != BelId());
|
||||||
|
|
||||||
int num_bel_wires = chip_info->bel_data[bel.index].num_bel_wires;
|
for (auto &w : chip_info->bel_data[bel.index].bel_wires)
|
||||||
const BelWirePOD *bel_wires = chip_info->bel_data[bel.index].bel_wires.get();
|
ret.push_back(IdString(w.port));
|
||||||
|
|
||||||
for (int i = 0; i < num_bel_wires; i++)
|
|
||||||
ret.push_back(IdString(bel_wires[i].port));
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -329,17 +326,17 @@ std::vector<IdString> Arch::getBelPins(BelId bel) const
|
|||||||
bool Arch::isBelLocked(BelId bel) const
|
bool Arch::isBelLocked(BelId bel) const
|
||||||
{
|
{
|
||||||
const BelConfigPOD *bel_config = nullptr;
|
const BelConfigPOD *bel_config = nullptr;
|
||||||
for (int i = 0; i < chip_info->num_belcfgs; i++) {
|
for (auto &bel_cfg : chip_info->bel_config) {
|
||||||
if (chip_info->bel_config[i].bel_index == bel.index) {
|
if (bel_cfg.bel_index == bel.index) {
|
||||||
bel_config = &chip_info->bel_config[i];
|
bel_config = &bel_cfg;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NPNR_ASSERT(bel_config != nullptr);
|
NPNR_ASSERT(bel_config != nullptr);
|
||||||
for (int i = 0; i < bel_config->num_entries; i++) {
|
for (auto &entry : bel_config->entries) {
|
||||||
if (strcmp("LOCKED", bel_config->entries[i].cbit_name.get()))
|
if (strcmp("LOCKED", entry.cbit_name.get()))
|
||||||
continue;
|
continue;
|
||||||
if ("LOCKED_" + archArgs().package == bel_config->entries[i].entry_name.get())
|
if ("LOCKED_" + archArgs().package == entry.entry_name.get())
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -352,7 +349,7 @@ WireId Arch::getWireByName(IdString name) const
|
|||||||
WireId ret;
|
WireId ret;
|
||||||
|
|
||||||
if (wire_by_name.empty()) {
|
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;
|
wire_by_name[id(chip_info->wire_data[i].name.get())] = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -430,7 +427,7 @@ PipId Arch::getPipByName(IdString name) const
|
|||||||
PipId ret;
|
PipId ret;
|
||||||
|
|
||||||
if (pip_by_name.empty()) {
|
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;
|
PipId pip;
|
||||||
pip.index = i;
|
pip.index = i;
|
||||||
pip_by_name[getPipName(pip)] = 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
|
BelId Arch::getPackagePinBel(const std::string &pin) const
|
||||||
{
|
{
|
||||||
for (int i = 0; i < package_info->num_pins; i++) {
|
for (auto &ppin : package_info->pins) {
|
||||||
if (package_info->pins[i].name.get() == pin) {
|
if (ppin.name.get() == pin) {
|
||||||
BelId id;
|
BelId id;
|
||||||
id.index = package_info->pins[i].bel_index;
|
id.index = ppin.bel_index;
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -491,9 +488,9 @@ BelId Arch::getPackagePinBel(const std::string &pin) const
|
|||||||
|
|
||||||
std::string Arch::getBelPackagePin(BelId bel) const
|
std::string Arch::getBelPackagePin(BelId bel) const
|
||||||
{
|
{
|
||||||
for (int i = 0; i < package_info->num_pins; i++) {
|
for (auto &ppin : package_info->pins) {
|
||||||
if (package_info->pins[i].bel_index == bel.index) {
|
if (ppin.bel_index == bel.index) {
|
||||||
return std::string(package_info->pins[i].name.get());
|
return std::string(ppin.name.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
@ -826,7 +823,7 @@ std::vector<GraphicElement> Arch::getDecalGraphics(DecalId decal) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (decal.type == DecalId::TYPE_WIRE) {
|
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();
|
const WireSegmentPOD *p = chip_info->wire_data[decal.index].segments.get();
|
||||||
|
|
||||||
GraphicElement::style_t style = decal.active ? GraphicElement::STYLE_ACTIVE : GraphicElement::STYLE_INACTIVE;
|
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
|
bool Arch::getCellDelayInternal(const CellInfo *cell, IdString fromPort, IdString toPort, DelayInfo &delay) const
|
||||||
{
|
{
|
||||||
for (int i = 0; i < chip_info->num_timing_cells; i++) {
|
for (auto &tc : chip_info->cell_timing) {
|
||||||
const auto &tc = chip_info->cell_timing[i];
|
|
||||||
if (tc.type == cell->type.index) {
|
if (tc.type == cell->type.index) {
|
||||||
for (int j = 0; j < tc.num_paths; j++) {
|
for (auto &path : tc.path_delays) {
|
||||||
const auto &path = tc.path_delays[j];
|
|
||||||
if (path.from_port == fromPort.index && path.to_port == toPort.index) {
|
if (path.from_port == fromPort.index && path.to_port == toPort.index) {
|
||||||
if (fast_part)
|
if (fast_part)
|
||||||
delay.delay = path.fast_delay;
|
delay.delay = path.fast_delay;
|
||||||
|
91
ice40/arch.h
91
ice40/arch.h
@ -46,6 +46,28 @@ template <typename T> struct RelPtr
|
|||||||
RelPtr &operator=(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(); }
|
||||||
|
});
|
||||||
|
|
||||||
NPNR_PACKED_STRUCT(struct BelWirePOD {
|
NPNR_PACKED_STRUCT(struct BelWirePOD {
|
||||||
int32_t port;
|
int32_t port;
|
||||||
int32_t type;
|
int32_t type;
|
||||||
@ -55,8 +77,7 @@ NPNR_PACKED_STRUCT(struct BelWirePOD {
|
|||||||
NPNR_PACKED_STRUCT(struct BelInfoPOD {
|
NPNR_PACKED_STRUCT(struct BelInfoPOD {
|
||||||
RelPtr<char> name;
|
RelPtr<char> name;
|
||||||
int32_t type;
|
int32_t type;
|
||||||
int32_t num_bel_wires;
|
RelSlice<BelWirePOD> bel_wires;
|
||||||
RelPtr<BelWirePOD> bel_wires;
|
|
||||||
int8_t x, y, z;
|
int8_t x, y, z;
|
||||||
int8_t padding_0;
|
int8_t padding_0;
|
||||||
});
|
});
|
||||||
@ -111,14 +132,11 @@ NPNR_PACKED_STRUCT(struct WireInfoPOD {
|
|||||||
};
|
};
|
||||||
|
|
||||||
RelPtr<char> name;
|
RelPtr<char> name;
|
||||||
int32_t num_uphill, num_downhill;
|
RelSlice<int32_t> pips_uphill, pips_downhill;
|
||||||
RelPtr<int32_t> pips_uphill, pips_downhill;
|
|
||||||
|
|
||||||
int32_t num_bel_pins;
|
RelSlice<BelPortPOD> bel_pins;
|
||||||
RelPtr<BelPortPOD> bel_pins;
|
|
||||||
|
|
||||||
int32_t num_segments;
|
RelSlice<WireSegmentPOD> segments;
|
||||||
RelPtr<WireSegmentPOD> segments;
|
|
||||||
|
|
||||||
int32_t fast_delay;
|
int32_t fast_delay;
|
||||||
int32_t slow_delay;
|
int32_t slow_delay;
|
||||||
@ -134,8 +152,7 @@ NPNR_PACKED_STRUCT(struct PackagePinPOD {
|
|||||||
|
|
||||||
NPNR_PACKED_STRUCT(struct PackageInfoPOD {
|
NPNR_PACKED_STRUCT(struct PackageInfoPOD {
|
||||||
RelPtr<char> name;
|
RelPtr<char> name;
|
||||||
int32_t num_pins;
|
RelSlice<PackagePinPOD> pins;
|
||||||
RelPtr<PackagePinPOD> pins;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
enum TileType : uint32_t
|
enum TileType : uint32_t
|
||||||
@ -156,14 +173,13 @@ NPNR_PACKED_STRUCT(struct ConfigBitPOD { int8_t row, col; });
|
|||||||
|
|
||||||
NPNR_PACKED_STRUCT(struct ConfigEntryPOD {
|
NPNR_PACKED_STRUCT(struct ConfigEntryPOD {
|
||||||
RelPtr<char> name;
|
RelPtr<char> name;
|
||||||
int32_t num_bits;
|
RelSlice<ConfigBitPOD> bits;
|
||||||
RelPtr<ConfigBitPOD> bits;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
NPNR_PACKED_STRUCT(struct TileInfoPOD {
|
NPNR_PACKED_STRUCT(struct TileInfoPOD {
|
||||||
int8_t cols, rows;
|
int8_t cols, rows;
|
||||||
int16_t num_config_entries;
|
int16_t padding;
|
||||||
RelPtr<ConfigEntryPOD> entries;
|
RelSlice<ConfigEntryPOD> entries;
|
||||||
});
|
});
|
||||||
|
|
||||||
static const int max_switch_bits = 5;
|
static const int max_switch_bits = 5;
|
||||||
@ -181,10 +197,9 @@ NPNR_PACKED_STRUCT(struct IerenInfoPOD {
|
|||||||
});
|
});
|
||||||
|
|
||||||
NPNR_PACKED_STRUCT(struct BitstreamInfoPOD {
|
NPNR_PACKED_STRUCT(struct BitstreamInfoPOD {
|
||||||
int32_t num_switches, num_ierens;
|
RelSlice<TileInfoPOD> tiles_nonrouting;
|
||||||
RelPtr<TileInfoPOD> tiles_nonrouting;
|
RelSlice<SwitchInfoPOD> switches;
|
||||||
RelPtr<SwitchInfoPOD> switches;
|
RelSlice<IerenInfoPOD> ierens;
|
||||||
RelPtr<IerenInfoPOD> ierens;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
NPNR_PACKED_STRUCT(struct BelConfigEntryPOD {
|
NPNR_PACKED_STRUCT(struct BelConfigEntryPOD {
|
||||||
@ -198,8 +213,7 @@ NPNR_PACKED_STRUCT(struct BelConfigEntryPOD {
|
|||||||
// for extra cells where this mapping is non-trivial
|
// for extra cells where this mapping is non-trivial
|
||||||
NPNR_PACKED_STRUCT(struct BelConfigPOD {
|
NPNR_PACKED_STRUCT(struct BelConfigPOD {
|
||||||
int32_t bel_index;
|
int32_t bel_index;
|
||||||
int32_t num_entries;
|
RelSlice<BelConfigEntryPOD> entries;
|
||||||
RelPtr<BelConfigEntryPOD> entries;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
NPNR_PACKED_STRUCT(struct CellPathDelayPOD {
|
NPNR_PACKED_STRUCT(struct CellPathDelayPOD {
|
||||||
@ -211,8 +225,7 @@ NPNR_PACKED_STRUCT(struct CellPathDelayPOD {
|
|||||||
|
|
||||||
NPNR_PACKED_STRUCT(struct CellTimingPOD {
|
NPNR_PACKED_STRUCT(struct CellTimingPOD {
|
||||||
int32_t type;
|
int32_t type;
|
||||||
int32_t num_paths;
|
RelSlice<CellPathDelayPOD> path_delays;
|
||||||
RelPtr<CellPathDelayPOD> path_delays;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
NPNR_PACKED_STRUCT(struct GlobalNetworkInfoPOD {
|
NPNR_PACKED_STRUCT(struct GlobalNetworkInfoPOD {
|
||||||
@ -232,19 +245,17 @@ NPNR_PACKED_STRUCT(struct GlobalNetworkInfoPOD {
|
|||||||
|
|
||||||
NPNR_PACKED_STRUCT(struct ChipInfoPOD {
|
NPNR_PACKED_STRUCT(struct ChipInfoPOD {
|
||||||
int32_t width, height;
|
int32_t width, height;
|
||||||
int32_t num_bels, num_wires, num_pips;
|
uint32_t num_switches;
|
||||||
int32_t num_switches, num_belcfgs, num_packages;
|
RelSlice<BelInfoPOD> bel_data;
|
||||||
int32_t num_timing_cells, num_global_networks;
|
RelSlice<WireInfoPOD> wire_data;
|
||||||
RelPtr<BelInfoPOD> bel_data;
|
RelSlice<PipInfoPOD> pip_data;
|
||||||
RelPtr<WireInfoPOD> wire_data;
|
RelSlice<TileType> tile_grid;
|
||||||
RelPtr<PipInfoPOD> pip_data;
|
|
||||||
RelPtr<TileType> tile_grid;
|
|
||||||
RelPtr<BitstreamInfoPOD> bits_info;
|
RelPtr<BitstreamInfoPOD> bits_info;
|
||||||
RelPtr<BelConfigPOD> bel_config;
|
RelSlice<BelConfigPOD> bel_config;
|
||||||
RelPtr<PackageInfoPOD> packages_data;
|
RelSlice<PackageInfoPOD> packages_data;
|
||||||
RelPtr<CellTimingPOD> cell_timing;
|
RelSlice<CellTimingPOD> cell_timing;
|
||||||
RelPtr<GlobalNetworkInfoPOD> global_network_info;
|
RelSlice<GlobalNetworkInfoPOD> global_network_info;
|
||||||
RelPtr<RelPtr<char>> tile_wire_names;
|
RelSlice<RelPtr<char>> tile_wire_names;
|
||||||
});
|
});
|
||||||
|
|
||||||
/************************ End of chipdb section. ************************/
|
/************************ End of chipdb section. ************************/
|
||||||
@ -495,7 +506,7 @@ struct Arch : BaseCtx
|
|||||||
{
|
{
|
||||||
BelRange range;
|
BelRange range;
|
||||||
range.b.cursor = 0;
|
range.b.cursor = 0;
|
||||||
range.e.cursor = chip_info->num_bels;
|
range.e.cursor = chip_info->bel_data.size();
|
||||||
return range;
|
return range;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -609,7 +620,7 @@ struct Arch : BaseCtx
|
|||||||
BelPinRange range;
|
BelPinRange range;
|
||||||
NPNR_ASSERT(wire != WireId());
|
NPNR_ASSERT(wire != WireId());
|
||||||
range.b.ptr = chip_info->wire_data[wire.index].bel_pins.get();
|
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;
|
return range;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -617,7 +628,7 @@ struct Arch : BaseCtx
|
|||||||
{
|
{
|
||||||
WireRange range;
|
WireRange range;
|
||||||
range.b.cursor = 0;
|
range.b.cursor = 0;
|
||||||
range.e.cursor = chip_info->num_wires;
|
range.e.cursor = chip_info->wire_data.size();
|
||||||
return range;
|
return range;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -720,7 +731,7 @@ struct Arch : BaseCtx
|
|||||||
{
|
{
|
||||||
AllPipRange range;
|
AllPipRange range;
|
||||||
range.b.cursor = 0;
|
range.b.cursor = 0;
|
||||||
range.e.cursor = chip_info->num_pips;
|
range.e.cursor = chip_info->pip_data.size();
|
||||||
return range;
|
return range;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -772,7 +783,7 @@ struct Arch : BaseCtx
|
|||||||
PipRange range;
|
PipRange range;
|
||||||
NPNR_ASSERT(wire != WireId());
|
NPNR_ASSERT(wire != WireId());
|
||||||
range.b.cursor = chip_info->wire_data[wire.index].pips_downhill.get();
|
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;
|
return range;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -781,7 +792,7 @@ struct Arch : BaseCtx
|
|||||||
PipRange range;
|
PipRange range;
|
||||||
NPNR_ASSERT(wire != WireId());
|
NPNR_ASSERT(wire != WireId());
|
||||||
range.b.cursor = chip_info->wire_data[wire.index].pips_uphill.get();
|
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;
|
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)
|
const ConfigEntryPOD &find_config(const TileInfoPOD &tile, const std::string &name)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < tile.num_config_entries; i++) {
|
for (auto &entry : tile.entries) {
|
||||||
if (std::string(tile.entries[i].name.get()) == name) {
|
if (std::string(entry.name.get()) == name) {
|
||||||
return tile.entries[i];
|
return entry;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NPNR_ASSERT_FALSE_STR("unable to find config bit " + name);
|
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)
|
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++) {
|
for (auto &ie : bi.ierens) {
|
||||||
auto ie = bi.ierens[i];
|
|
||||||
if (ie.iox == x && ie.ioy == y && ie.ioz == z) {
|
if (ie.iox == x && ie.ioy == y && ie.ioz == z) {
|
||||||
return std::make_tuple(ie.ierx, ie.iery, ie.ierz);
|
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);
|
const ConfigEntryPOD &cfg = find_config(ti, name);
|
||||||
if (index == -1) {
|
if (index == -1) {
|
||||||
for (int i = 0; i < cfg.num_bits; i++) {
|
for (auto &bit : cfg.bits) {
|
||||||
return tile_cfg.at(cfg.bits[i].row).at(cfg.bits[i].col);
|
return tile_cfg.at(bit.row).at(bit.col);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return tile_cfg.at(cfg.bits[index].row).at(cfg.bits[index].col);
|
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);
|
const ConfigEntryPOD &cfg = find_config(ti, name);
|
||||||
if (index == -1) {
|
if (index == -1) {
|
||||||
for (int i = 0; i < cfg.num_bits; i++) {
|
for (auto &bit : cfg.bits) {
|
||||||
int8_t &cbit = tile_cfg.at(cfg.bits[i].row).at(cfg.bits[i].col);
|
int8_t &cbit = tile_cfg.at(bit.row).at(bit.col);
|
||||||
if (cbit && !value)
|
if (cbit && !value)
|
||||||
log_error("clearing already set config bit %s\n", name.c_str());
|
log_error("clearing already set config bit %s\n", name.c_str());
|
||||||
cbit = value;
|
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)
|
static const BelConfigPOD &get_ec_config(const ChipInfoPOD *chip, BelId bel)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < chip->num_belcfgs; i++) {
|
for (auto &cfg : chip->bel_config) {
|
||||||
if (chip->bel_config[i].bel_index == bel.index)
|
if (cfg.bel_index == bel.index)
|
||||||
return chip->bel_config[i];
|
return cfg;
|
||||||
}
|
}
|
||||||
NPNR_ASSERT_FALSE("failed to find bel config");
|
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)
|
static bool has_ec_cbit(const BelConfigPOD &cell_cbits, std::string name)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < cell_cbits.num_entries; i++) {
|
for (auto &cbit : cell_cbits.entries) {
|
||||||
const auto &cbit = cell_cbits.entries[i];
|
|
||||||
if (cbit.entry_name.get() == name)
|
if (cbit.entry_name.get() == name)
|
||||||
return true;
|
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;
|
const ChipInfoPOD *chip = ctx->chip_info;
|
||||||
|
|
||||||
for (int i = 0; i < cell_cbits.num_entries; i++) {
|
for (auto &cbit : cell_cbits.entries) {
|
||||||
const auto &cbit = cell_cbits.entries[i];
|
|
||||||
if (cbit.entry_name.get() == name) {
|
if (cbit.entry_name.get() == name) {
|
||||||
const auto &ti = chip->bits_info->tiles_nonrouting[tile_at(ctx, cbit.x, cbit.y)];
|
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);
|
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")) {
|
} else if (cell.second->type == ctx->id("SB_GB")) {
|
||||||
if (cell.second->gbInfo.forPadIn) {
|
if (cell.second->gbInfo.forPadIn) {
|
||||||
Loc gb_loc = ctx->getBelLocation(bel);
|
Loc gb_loc = ctx->getBelLocation(bel);
|
||||||
for (int i = 0; i < ci.num_global_networks; i++) {
|
for (auto &glb : ci.global_network_info) {
|
||||||
if ((gb_loc.x == ci.global_network_info[i].gb_x) && (gb_loc.y == ci.global_network_info[i].gb_y)) {
|
if ((gb_loc.x == glb.gb_x) && (gb_loc.y == glb.gb_y)) {
|
||||||
extra_bits.push_back(std::make_tuple(ci.global_network_info[i].pi_eb_bank,
|
extra_bits.push_back(std::make_tuple(glb.pi_eb_bank, glb.pi_eb_x, glb.pi_eb_y));
|
||||||
ci.global_network_info[i].pi_eb_x,
|
|
||||||
ci.global_network_info[i].pi_eb_y));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1077,6 +1077,13 @@ class BinaryBlobAssembler:
|
|||||||
else:
|
else:
|
||||||
print("ref %s %s" % (name, comment))
|
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):
|
def s(self, s, comment):
|
||||||
assert "|" not in s
|
assert "|" not in s
|
||||||
print("str |%s| %s" % (s, comment))
|
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)):
|
for bel in range(len(bel_name)):
|
||||||
bba.s(bel_name[bel], "name")
|
bba.s(bel_name[bel], "name")
|
||||||
bba.u32(constids[bel_type[bel]], "type")
|
bba.u32(constids[bel_type[bel]], "type")
|
||||||
bba.u32(len(bel_wires[bel]), "num_bel_wires")
|
bba.r_slice("bel_wires_%d" % bel, len(bel_wires[bel]), "bel_wires")
|
||||||
bba.r("bel_wires_%d" % bel, "bel_wires")
|
|
||||||
bba.u8(bel_pos[bel][0], "x")
|
bba.u8(bel_pos[bel][0], "x")
|
||||||
bba.u8(bel_pos[bel][1], "y")
|
bba.u8(bel_pos[bel][1], "y")
|
||||||
bba.u8(bel_pos[bel][2], "z")
|
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")
|
bba.l("tile%d_config" % t, "ConfigEntryPOD")
|
||||||
for name, num_bits, t, safename in centries_info:
|
for name, num_bits, t, safename in centries_info:
|
||||||
bba.s(name, "name")
|
bba.s(name, "name")
|
||||||
bba.u32(num_bits, "num_bits")
|
bba.r_slice("tile%d_%s_bits" % (t, safename), num_bits, "num_bits")
|
||||||
bba.r("tile%d_%s_bits" % (t, safename), "num_bits")
|
|
||||||
if len(centries_info) == 0:
|
if len(centries_info) == 0:
|
||||||
bba.u32(0, "padding")
|
bba.u32(0, "padding")
|
||||||
ti = dict()
|
ti = dict()
|
||||||
@ -1306,22 +1311,19 @@ for t in range(num_tile_types):
|
|||||||
bba.l("wire_data_%s" % dev_name, "WireInfoPOD")
|
bba.l("wire_data_%s" % dev_name, "WireInfoPOD")
|
||||||
for wire, info in enumerate(wireinfo):
|
for wire, info in enumerate(wireinfo):
|
||||||
bba.s(info["name"], "name")
|
bba.s(info["name"], "name")
|
||||||
bba.u32(info["num_uphill"], "num_uphill")
|
bba.r_slice(info["list_uphill"], info["num_uphill"], "pips_uphill")
|
||||||
bba.u32(info["num_downhill"], "num_downhill")
|
bba.r_slice(info["list_downhill"], info["num_downhill"], "pips_downhill")
|
||||||
bba.r(info["list_uphill"], "pips_uphill")
|
bba.r_slice(info["list_bel_pins"], info["num_bel_pins"], "bel_pins")
|
||||||
bba.r(info["list_downhill"], "pips_downhill")
|
|
||||||
bba.u32(info["num_bel_pins"], "num_bel_pins")
|
|
||||||
bba.r(info["list_bel_pins"], "bel_pins")
|
|
||||||
|
|
||||||
num_segments = 0
|
num_segments = 0
|
||||||
for segs in wire_segments[wire].values():
|
for segs in wire_segments[wire].values():
|
||||||
num_segments += len(segs)
|
num_segments += len(segs)
|
||||||
bba.u32(num_segments, "num_segments")
|
|
||||||
|
|
||||||
if num_segments:
|
if num_segments:
|
||||||
bba.r("wire_segments_%d" % wire, "segments")
|
bba.r_slice("wire_segments_%d" % wire, num_segments, "segments")
|
||||||
else:
|
else:
|
||||||
bba.u32(0, "segments")
|
bba.u32(0, "segments")
|
||||||
|
bba.u32(0, "segments_len")
|
||||||
|
|
||||||
bba.u32(wiredelay(wire, fast_timings), "fast_delay")
|
bba.u32(wiredelay(wire, fast_timings), "fast_delay")
|
||||||
bba.u32(wiredelay(wire, slow_timings), "slow_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:
|
for info in tileinfo:
|
||||||
bba.u8(info["cols"], "cols")
|
bba.u8(info["cols"], "cols")
|
||||||
bba.u8(info["rows"], "rows")
|
bba.u8(info["rows"], "rows")
|
||||||
bba.u16(info["num_entries"], "num_entries")
|
bba.u16(0, "padding")
|
||||||
bba.r(info["entries"], "entries")
|
bba.r_slice(info["entries"], info["num_entries"], "entries")
|
||||||
|
|
||||||
bba.l("ieren_data_%s" % dev_name, "IerenInfoPOD")
|
bba.l("ieren_data_%s" % dev_name, "IerenInfoPOD")
|
||||||
for ieren in ierens:
|
for ieren in ierens:
|
||||||
@ -1418,11 +1420,9 @@ if len(ierens) % 2 == 1:
|
|||||||
bba.u16(0, "padding")
|
bba.u16(0, "padding")
|
||||||
|
|
||||||
bba.l("bits_info_%s" % dev_name, "BitstreamInfoPOD")
|
bba.l("bits_info_%s" % dev_name, "BitstreamInfoPOD")
|
||||||
bba.u32(len(switchinfo), "num_switches")
|
bba.r_slice("tile_data_%s" % dev_name, len(tileinfo), "tiles_nonrouting")
|
||||||
bba.u32(len(ierens), "num_ierens")
|
bba.r_slice("switch_data_%s" % dev_name, len(switchinfo), "switches")
|
||||||
bba.r("tile_data_%s" % dev_name, "tiles_nonrouting")
|
bba.r_slice("ieren_data_%s" % dev_name, len(ierens), "ierens")
|
||||||
bba.r("switch_data_%s" % dev_name, "switches")
|
|
||||||
bba.r("ieren_data_%s" % dev_name, "ierens")
|
|
||||||
|
|
||||||
bba.l("tile_grid_%s" % dev_name, "TileType")
|
bba.l("tile_grid_%s" % dev_name, "TileType")
|
||||||
for t in tilegrid:
|
for t in tilegrid:
|
||||||
@ -1442,14 +1442,12 @@ if len(extra_cell_config) > 0:
|
|||||||
bba.l("bel_config_%s" % dev_name, "BelConfigPOD")
|
bba.l("bel_config_%s" % dev_name, "BelConfigPOD")
|
||||||
for bel_idx, entries in sorted(extra_cell_config.items()):
|
for bel_idx, entries in sorted(extra_cell_config.items()):
|
||||||
bba.u32(bel_idx, "bel_index")
|
bba.u32(bel_idx, "bel_index")
|
||||||
bba.u32(len(entries), "num_entries")
|
bba.r_slice("bel%d_config_entries" % bel_idx if len(entries) > 0 else None, len(entries), "entries")
|
||||||
bba.r("bel%d_config_entries" % bel_idx if len(entries) > 0 else None, "entries")
|
|
||||||
|
|
||||||
bba.l("package_info_%s" % dev_name, "PackageInfoPOD")
|
bba.l("package_info_%s" % dev_name, "PackageInfoPOD")
|
||||||
for info in packageinfo:
|
for info in packageinfo:
|
||||||
bba.s(info[0], "name")
|
bba.s(info[0], "name")
|
||||||
bba.u32(info[1], "num_pins")
|
bba.r_slice(info[2], info[1], "pins")
|
||||||
bba.r(info[2], "pins")
|
|
||||||
|
|
||||||
for cell, timings in sorted(cell_timings.items()):
|
for cell, timings in sorted(cell_timings.items()):
|
||||||
beltype = constids[cell]
|
beltype = constids[cell]
|
||||||
@ -1465,8 +1463,7 @@ bba.l("cell_timings_%s" % dev_name, "CellTimingPOD")
|
|||||||
for cell, timings in sorted(cell_timings.items()):
|
for cell, timings in sorted(cell_timings.items()):
|
||||||
beltype = constids[cell]
|
beltype = constids[cell]
|
||||||
bba.u32(beltype, "type")
|
bba.u32(beltype, "type")
|
||||||
bba.u32(len(timings), "num_paths")
|
bba.r_slice("cell_paths_%d" % beltype, len(timings), "path_delays")
|
||||||
bba.r("cell_paths_%d" % beltype, "path_delays")
|
|
||||||
|
|
||||||
bba.l("global_network_info_%s" % dev_name, "GlobalNetworkInfoPOD")
|
bba.l("global_network_info_%s" % dev_name, "GlobalNetworkInfoPOD")
|
||||||
for i in range(len(glbinfo)):
|
for i in range(len(glbinfo)):
|
||||||
@ -1479,23 +1476,16 @@ for i in range(len(glbinfo)):
|
|||||||
bba.l("chip_info_%s" % dev_name)
|
bba.l("chip_info_%s" % dev_name)
|
||||||
bba.u32(dev_width, "dev_width")
|
bba.u32(dev_width, "dev_width")
|
||||||
bba.u32(dev_height, "dev_height")
|
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(switchinfo), "num_switches")
|
||||||
bba.u32(len(extra_cell_config), "num_belcfgs")
|
bba.r_slice("bel_data_%s" % dev_name, len(bel_name), "bel_data")
|
||||||
bba.u32(len(packageinfo), "num_packages")
|
bba.r_slice("wire_data_%s" % dev_name, num_wires, "wire_data")
|
||||||
bba.u32(len(cell_timings), "num_timing_cells")
|
bba.r_slice("pip_data_%s" % dev_name, len(pipinfo), "pip_data")
|
||||||
bba.u32(len(glbinfo), "num_global_networks")
|
bba.r_slice("tile_grid_%s" % dev_name, len(tilegrid), "tile_grid")
|
||||||
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("bits_info_%s" % dev_name, "bits_info")
|
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_slice("bel_config_%s" % dev_name if len(extra_cell_config) > 0 else None, len(extra_cell_config), "bel_config")
|
||||||
bba.r("package_info_%s" % dev_name, "packages_data")
|
bba.r_slice("package_info_%s" % dev_name, len(packageinfo), "packages_data")
|
||||||
bba.r("cell_timings_%s" % dev_name, "cell_timing")
|
bba.r_slice("cell_timings_%s" % dev_name, len(cell_timings), "cell_timing")
|
||||||
bba.r("global_network_info_%s" % dev_name, "global_network_info")
|
bba.r_slice("global_network_info_%s" % dev_name, len(glbinfo), "global_network_info")
|
||||||
bba.r("tile_wire_names", "tile_wire_names")
|
bba.r_slice("tile_wire_names", len(gfx_wire_names), "tile_wire_names")
|
||||||
|
|
||||||
bba.pop()
|
bba.pop()
|
||||||
|
@ -29,7 +29,7 @@ void ice40DelayFuzzerMain(Context *ctx)
|
|||||||
{
|
{
|
||||||
std::vector<WireId> srcWires, dstWires;
|
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;
|
WireId wire;
|
||||||
wire.index = i;
|
wire.index = i;
|
||||||
|
|
||||||
|
@ -1357,14 +1357,11 @@ void pack_plls(Context *ctx)
|
|||||||
auto feedback_path = packed->params[ctx->id("FEEDBACK_PATH")].is_string
|
auto feedback_path = packed->params[ctx->id("FEEDBACK_PATH")].is_string
|
||||||
? packed->params[ctx->id("FEEDBACK_PATH")].as_string()
|
? packed->params[ctx->id("FEEDBACK_PATH")].as_string()
|
||||||
: std::to_string(packed->params[ctx->id("FEEDBACK_PATH")].as_int64());
|
: std::to_string(packed->params[ctx->id("FEEDBACK_PATH")].as_int64());
|
||||||
std::string fbp_value =
|
std::string fbp_value = feedback_path == "DELAY" ? "0"
|
||||||
feedback_path == "DELAY"
|
: feedback_path == "SIMPLE" ? "1"
|
||||||
? "0"
|
: feedback_path == "PHASE_AND_DELAY" ? "2"
|
||||||
: feedback_path == "SIMPLE"
|
: feedback_path == "EXTERNAL" ? "6"
|
||||||
? "1"
|
: std::string(feedback_path);
|
||||||
: 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))
|
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),
|
log_error("PLL '%s' has unsupported FEEDBACK_PATH value '%s'\n", ci->name.c_str(ctx),
|
||||||
feedback_path.c_str());
|
feedback_path.c_str());
|
||||||
|
Loading…
Reference in New Issue
Block a user