ArchDevice struct and use c++ string compare

This commit is contained in:
Miodrag Milanovic 2023-05-22 10:39:41 +02:00
parent 97d4e7c1a5
commit ccf9d00d82
6 changed files with 159 additions and 149 deletions

View File

@ -51,8 +51,13 @@ void IdString::initialize_arch(const BaseCtx *ctx)
// --------------------------------------------------------------- // ---------------------------------------------------------------
static void get_chip_info(std::string device, const DeviceInfoPOD **device_info, const ChipInfoPOD **chip_info, const PackageInfoPOD **package_info, bool is_equal(const std::string& a, const std::string& b)
const char **device_name, const char **package_name, Arch::ArchTypes *type, Arch::SpeedGrade *speed) {
return std::equal(a.begin(), a.end(), b.begin(), b.end(),
[](char a, char b) { return tolower(a) == tolower(b); });
}
static void get_chip_info(std::string device, ArchDevice *selected_device)
{ {
std::stringstream ss(available_devices); std::stringstream ss(available_devices);
std::string name; std::string name;
@ -69,42 +74,44 @@ static void get_chip_info(std::string device, const DeviceInfoPOD **device_info,
std::string devname = stringf("%s-%d%s%s", chip.name.get(), speedgrade.speed, std::string devname = stringf("%s-%d%s%s", chip.name.get(), speedgrade.speed,
pkg.short_name.get(), rating.suffix.get()); pkg.short_name.get(), rating.suffix.get());
if (device == devname) { if (device == devname) {
*device_info = &dev; selected_device->device_info = &dev;
*chip_info = db_ptr->get(); selected_device->chip_info = db_ptr->get();
*package_info = nullptr; selected_device->package_info = nullptr;
*package_name = pkg.name.get(); selected_device->package_name = pkg.name.get();
*device_name = chip.name.get(); selected_device->device_name = chip.name.get();
*type = Arch::ArchTypes::NONE; selected_device->type = ArchDevice::NONE;
if (strcmp(*device_name,"LFE5U-12F")==0 || strcmp(*device_name,"LAE5U-12F")==0) std::string device_name = chip.name.get();
*type = Arch::ArchTypes::LFE5U_12F; if ((device_name == "LFE5U-12F")|| (device_name == "LAE5U-12F"))
else if (strcmp(*device_name,"LFE5U-25F")==0) selected_device->type = ArchDevice::LFE5U_12F;
*type = Arch::ArchTypes::LFE5U_25F; else if (device_name == "LFE5U-25F")
else if (strcmp(*device_name,"LFE5U-45F")==0) selected_device->type = ArchDevice::LFE5U_25F;
*type = Arch::ArchTypes::LFE5U_45F; else if (device_name == "LFE5U-45F")
else if (strcmp(*device_name,"LFE5U-85F")==0) selected_device->type = ArchDevice::LFE5U_45F;
*type = Arch::ArchTypes::LFE5U_85F; else if (device_name == "LFE5U-85F")
else if (strcmp(*device_name,"LFE5UM-25F")==0 || strcmp(*device_name,"LAE5UM-25F")==0) selected_device->type = ArchDevice::LFE5U_85F;
*type = Arch::ArchTypes::LFE5UM_25F; else if ((device_name == "LFE5UM-25F") || (device_name == "LAE5UM-25F"))
else if (strcmp(*device_name,"LFE5UM-45F")==0 || strcmp(*device_name,"LAE5UM-45F")==0) selected_device->type = ArchDevice::LFE5UM_25F;
*type = Arch::ArchTypes::LFE5UM_45F; else if ((device_name == "LFE5UM-45F") || (device_name == "LAE5UM-45F"))
else if (strcmp(*device_name,"LFE5UM-85F")==0 || strcmp(*device_name,"LAE5UM-85F")==0) selected_device->type = ArchDevice::LFE5UM_45F;
*type = Arch::ArchTypes::LFE5UM_85F; else if ((device_name == "LFE5UM-85F") || (device_name == "LAE5UM-85F"))
else if (strcmp(*device_name,"LFE5UM5G-25F")==0) selected_device->type = ArchDevice::LFE5UM_85F;
*type = Arch::ArchTypes::LFE5UM5G_25F; else if (device_name == "LFE5UM5G-25F")
else if (strcmp(*device_name,"LFE5UM5G-45F")==0) selected_device->type = ArchDevice::LFE5UM5G_25F;
*type = Arch::ArchTypes::LFE5UM5G_45F; else if (device_name == "LFE5UM5G-45F")
else if (strcmp(*device_name,"LFE5UM5G-85F")==0) selected_device->type = ArchDevice::LFE5UM5G_45F;
*type = Arch::ArchTypes::LFE5UM5G_85F; else if (device_name == "LFE5UM5G-85F")
selected_device->type = ArchDevice::LFE5UM5G_85F;
else else
log_error("Unsupported device '%s'.\n", *device_name); log_error("Unsupported device '%s'.\n", device_name.c_str());
*speed = Arch::SpeedGrade(speedgrade.speed - 6); selected_device->speed = ArchDevice::SpeedGrade(speedgrade.speed - 6);
if (strstr(*device_name,"LFE5UM5G")) { if (device_name.rfind("LFE5UM5G")==0) {
*speed = Arch::SPEED_8_5G; selected_device->speed = ArchDevice::SPEED_8_5G;
} }
selected_device->speed_grade = &(selected_device->chip_info->speed_grades[selected_device->speed]);
for (auto &pi : db_ptr->get()->package_info) { for (auto &pi : db_ptr->get()->package_info) {
if (strcasecmp(pkg.name.get(),pi.name.get())==0) { if (is_equal(pkg.name.get(),pi.name.get())) {
*package_info = π selected_device->package_info = π
break; break;
} }
} }
@ -122,24 +129,23 @@ static void get_chip_info(std::string device, const DeviceInfoPOD **device_info,
Arch::Arch(ArchArgs args) : args(args) Arch::Arch(ArchArgs args) : args(args)
{ {
get_chip_info(args.device, &device_info, &chip_info, &package_info, &device_name, &package_name, &type, &speed); get_chip_info(args.device, &device);
if (chip_info == nullptr) if (device.chip_info == nullptr)
log_error("Unsupported device '%s'.\n", args.device.c_str()); log_error("Unsupported device '%s'.\n", args.device.c_str());
if (chip_info->const_id_count != DB_CONST_ID_COUNT) if (device.chip_info->const_id_count != DB_CONST_ID_COUNT)
log_error("Chip database 'bba' and nextpnr code are out of sync; please rebuild (or contact distribution " log_error("Chip database 'bba' and nextpnr code are out of sync; please rebuild (or contact distribution "
"maintainer)!\n"); "maintainer)!\n");
speed_grade = &(chip_info->speed_grades[speed]); if (!device.package_info)
if (!package_info) log_error("Unsupported package '%s' for '%s'.\n", device.package_name, getChipName().c_str());
log_error("Unsupported package '%s' for '%s'.\n", package_name, getChipName().c_str());
tile_status.resize(chip_info->num_tiles); tile_status.resize(device.chip_info->num_tiles);
for (int i = 0; i < chip_info->num_tiles; i++) { for (int i = 0; i < device.chip_info->num_tiles; i++) {
auto &ts = tile_status.at(i); auto &ts = tile_status.at(i);
auto &tile_data = chip_info->tile_info[i]; auto &tile_data = device.chip_info->tile_info[i];
ts.boundcells.resize(chip_info->locations[chip_info->location_type[i]].bel_data.size(), nullptr); ts.boundcells.resize(device.chip_info->locations[device.chip_info->location_type[i]].bel_data.size(), nullptr);
for (auto &name : tile_data.tile_names) { for (auto &name : tile_data.tile_names) {
if (strcmp(chip_info->tiletype_names[name.type_idx].get(), "PLC2") == 0) { if (strcmp(device.chip_info->tiletype_names[name.type_idx].get(), "PLC2") == 0) {
// Is a logic tile // Is a logic tile
ts.lts = new LogicTileStatus(); ts.lts = new LogicTileStatus();
break; break;
@ -150,44 +156,44 @@ Arch::Arch(ArchArgs args) : args(args)
BaseArch::init_cell_types(); BaseArch::init_cell_types();
BaseArch::init_bel_buckets(); BaseArch::init_bel_buckets();
for (int i = 0; i < chip_info->width; i++) for (int i = 0; i < device.chip_info->width; i++)
x_ids.push_back(idf("X%d", i)); x_ids.push_back(idf("X%d", i));
for (int i = 0; i < chip_info->height; i++) for (int i = 0; i < device.chip_info->height; i++)
y_ids.push_back(idf("Y%d", i)); y_ids.push_back(idf("Y%d", i));
for (int i = 0; i < chip_info->width; i++) { for (int i = 0; i < device.chip_info->width; i++) {
IdString x_id = idf("X%d", i); IdString x_id = idf("X%d", i);
x_ids.push_back(x_id); x_ids.push_back(x_id);
id_to_x[x_id] = i; id_to_x[x_id] = i;
} }
for (int i = 0; i < chip_info->height; i++) { for (int i = 0; i < device.chip_info->height; i++) {
IdString y_id = idf("Y%d", i); IdString y_id = idf("Y%d", i);
y_ids.push_back(y_id); y_ids.push_back(y_id);
id_to_y[y_id] = i; id_to_y[y_id] = i;
} }
wire_tile_vecidx.resize(chip_info->num_tiles, -1); wire_tile_vecidx.resize(device.chip_info->num_tiles, -1);
int n_wires = 0; int n_wires = 0;
for (auto e : getWires()) { for (auto e : getWires()) {
if (e.index == 0) { if (e.index == 0) {
wire_tile_vecidx.at(e.location.y * chip_info->width + e.location.x) = n_wires; wire_tile_vecidx.at(e.location.y * device.chip_info->width + e.location.x) = n_wires;
} }
n_wires++; n_wires++;
} }
wire2net.resize(n_wires, nullptr); wire2net.resize(n_wires, nullptr);
wire_fanout.resize(n_wires, 0); wire_fanout.resize(n_wires, 0);
pip_tile_vecidx.resize(chip_info->num_tiles, -1); pip_tile_vecidx.resize(device.chip_info->num_tiles, -1);
int n_pips = 0; int n_pips = 0;
for (auto e : getPips()) { for (auto e : getPips()) {
if (e.index == 0) { if (e.index == 0) {
pip_tile_vecidx.at(e.location.y * chip_info->width + e.location.x) = n_pips; pip_tile_vecidx.at(e.location.y * device.chip_info->width + e.location.x) = n_pips;
} }
n_pips++; n_pips++;
} }
pip2net.resize(n_pips, nullptr); pip2net.resize(n_pips, nullptr);
lutperm_allowed.resize(chip_info->width * chip_info->height * 4); lutperm_allowed.resize(device.chip_info->width * device.chip_info->height * 4);
} }
void Arch::list_devices() void Arch::list_devices()
@ -245,12 +251,12 @@ BelRange Arch::getBelsByTile(int x, int y) const
{ {
BelRange br; BelRange br;
br.b.cursor_tile = y * chip_info->width + x; br.b.cursor_tile = y * device.chip_info->width + x;
br.e.cursor_tile = y * chip_info->width + x; br.e.cursor_tile = y * device.chip_info->width + x;
br.b.cursor_index = 0; br.b.cursor_index = 0;
br.e.cursor_index = chip_info->locations[chip_info->location_type[br.b.cursor_tile]].bel_data.ssize() - 1; br.e.cursor_index = device.chip_info->locations[device.chip_info->location_type[br.b.cursor_tile]].bel_data.ssize() - 1;
br.b.chip = chip_info; br.b.chip = device.chip_info;
br.e.chip = chip_info; br.e.chip = device.chip_info;
if (br.e.cursor_index == -1) if (br.e.cursor_index == -1)
++br.e.cursor_index; ++br.e.cursor_index;
else else
@ -353,7 +359,7 @@ IdStringList Arch::getPipName(PipId pip) const
BelId Arch::get_package_pin_bel(const std::string &pin) const BelId Arch::get_package_pin_bel(const std::string &pin) const
{ {
for (auto &ppin : package_info->pin_data) { for (auto &ppin : device.package_info->pin_data) {
if (ppin.name.get() == pin) { if (ppin.name.get() == pin) {
BelId bel; BelId bel;
bel.location = ppin.abs_loc; bel.location = ppin.abs_loc;
@ -366,7 +372,7 @@ BelId Arch::get_package_pin_bel(const std::string &pin) const
std::string Arch::get_bel_package_pin(BelId bel) const std::string Arch::get_bel_package_pin(BelId bel) const
{ {
for (auto &ppin : package_info->pin_data) { for (auto &ppin : device.package_info->pin_data) {
if (Location(ppin.abs_loc) == bel.location && ppin.bel_index == bel.index) { if (Location(ppin.abs_loc) == bel.location && ppin.bel_index == bel.index) {
return ppin.name.get(); return ppin.name.get();
} }
@ -376,7 +382,7 @@ std::string Arch::get_bel_package_pin(BelId bel) const
int Arch::get_pio_bel_bank(BelId bel) const int Arch::get_pio_bel_bank(BelId bel) const
{ {
for (auto &pio : chip_info->pio_info) { for (auto &pio : device.chip_info->pio_info) {
if (Location(pio.abs_loc) == bel.location && pio.bel_index == bel.index) { if (Location(pio.abs_loc) == bel.location && pio.bel_index == bel.index) {
return pio.bank; return pio.bank;
} }
@ -386,7 +392,7 @@ int Arch::get_pio_bel_bank(BelId bel) const
std::string Arch::get_pio_function_name(BelId bel) const std::string Arch::get_pio_function_name(BelId bel) const
{ {
for (auto &pio : chip_info->pio_info) { for (auto &pio : device.chip_info->pio_info) {
if (Location(pio.abs_loc) == bel.location && pio.bel_index == bel.index) { if (Location(pio.abs_loc) == bel.location && pio.bel_index == bel.index) {
const char *func = pio.function_name.get(); const char *func = pio.function_name.get();
if (func == nullptr) if (func == nullptr)
@ -400,7 +406,7 @@ std::string Arch::get_pio_function_name(BelId bel) const
BelId Arch::get_pio_by_function_name(const std::string &name) const BelId Arch::get_pio_by_function_name(const std::string &name) const
{ {
for (auto &pio : chip_info->pio_info) { for (auto &pio : device.chip_info->pio_info) {
const char *func = pio.function_name.get(); const char *func = pio.function_name.get();
if (func != nullptr && func == name) { if (func != nullptr && func == name) {
BelId bel; BelId bel;
@ -428,9 +434,9 @@ std::vector<IdString> Arch::getBelPins(BelId bel) const
BelId Arch::getBelByLocation(Loc loc) const BelId Arch::getBelByLocation(Loc loc) const
{ {
if (loc.x >= chip_info->width || loc.y >= chip_info->height) if (loc.x >= device.chip_info->width || loc.y >= device.chip_info->height)
return BelId(); return BelId();
const LocationTypePOD &locI = chip_info->locations[chip_info->location_type[loc.y * chip_info->width + loc.x]]; const LocationTypePOD &locI = device.chip_info->locations[device.chip_info->location_type[loc.y * device.chip_info->width + loc.x]];
for (int i = 0; i < locI.bel_data.ssize(); i++) { for (int i = 0; i < locI.bel_data.ssize(); i++) {
if (locI.bel_data[i].z == loc.z) { if (locI.bel_data[i].z == loc.z) {
BelId bi; BelId bi;
@ -484,7 +490,7 @@ delay_t Arch::estimateDelay(WireId src, WireId dst) const
int dx = abs(src_loc.first - dst_loc.first), dy = abs(src_loc.second - dst_loc.second); int dx = abs(src_loc.first - dst_loc.first), dy = abs(src_loc.second - dst_loc.second);
return (120 - 22 * speed) * return (120 - 22 * device.speed) *
(6 + std::max(dx - 5, 0) + std::max(dy - 5, 0) + 2 * (std::min(dx, 5) + std::min(dy, 5))); (6 + std::max(dx - 5, 0) + std::max(dy - 5, 0) + 2 * (std::min(dx, 5) + std::min(dy, 5)));
} }
@ -562,7 +568,7 @@ delay_t Arch::predictDelay(BelId src_bel, IdString src_pin, BelId dst_bel, IdStr
int dx = abs(driver_loc.x - sink_loc.x), dy = abs(driver_loc.y - sink_loc.y); int dx = abs(driver_loc.x - sink_loc.x), dy = abs(driver_loc.y - sink_loc.y);
return (120 - 22 * speed) * return (120 - 22 * device.speed) *
(3 + std::max(dx - 5, 0) + std::max(dy - 5, 0) + 2 * (std::min(dx, 5) + std::min(dy, 5))); (3 + std::max(dx - 5, 0) + std::max(dy - 5, 0) + 2 * (std::min(dx, 5) + std::min(dy, 5)));
} }
@ -685,7 +691,7 @@ std::vector<GraphicElement> Arch::getDecalGraphics(DecalId decal) const
int y = decal.location.y; int y = decal.location.y;
GraphicElement::style_t style = decal.active ? GraphicElement::STYLE_ACTIVE : GraphicElement::STYLE_INACTIVE; GraphicElement::style_t style = decal.active ? GraphicElement::STYLE_ACTIVE : GraphicElement::STYLE_INACTIVE;
GfxTileWireId tilewire = GfxTileWireId(loc_info(wire)->wire_data[wire.index].tile_wire); GfxTileWireId tilewire = GfxTileWireId(loc_info(wire)->wire_data[wire.index].tile_wire);
gfxTileWire(ret, x, y, chip_info->width, chip_info->height, wire_type, tilewire, style); gfxTileWire(ret, x, y, device.chip_info->width, device.chip_info->height, wire_type, tilewire, style);
} else if (decal.type == DecalId::TYPE_PIP) { } else if (decal.type == DecalId::TYPE_PIP) {
PipId pip; PipId pip;
pip.index = decal.z; pip.index = decal.z;
@ -697,7 +703,7 @@ std::vector<GraphicElement> Arch::getDecalGraphics(DecalId decal) const
GfxTileWireId src_id = GfxTileWireId(loc_info(src_wire)->wire_data[src_wire.index].tile_wire); GfxTileWireId src_id = GfxTileWireId(loc_info(src_wire)->wire_data[src_wire.index].tile_wire);
GfxTileWireId dst_id = GfxTileWireId(loc_info(dst_wire)->wire_data[dst_wire.index].tile_wire); GfxTileWireId dst_id = GfxTileWireId(loc_info(dst_wire)->wire_data[dst_wire.index].tile_wire);
GraphicElement::style_t style = decal.active ? GraphicElement::STYLE_ACTIVE : GraphicElement::STYLE_HIDDEN; GraphicElement::style_t style = decal.active ? GraphicElement::STYLE_ACTIVE : GraphicElement::STYLE_HIDDEN;
gfxTilePip(ret, x, y, chip_info->width, chip_info->height, src_wire, getWireType(src_wire), src_id, dst_wire, gfxTilePip(ret, x, y, device.chip_info->width, device.chip_info->height, src_wire, getWireType(src_wire), src_id, dst_wire,
getWireType(dst_wire), dst_id, style); getWireType(dst_wire), dst_id, style);
} else if (decal.type == DecalId::TYPE_BEL) { } else if (decal.type == DecalId::TYPE_BEL) {
BelId bel; BelId bel;
@ -708,7 +714,7 @@ std::vector<GraphicElement> Arch::getDecalGraphics(DecalId decal) const
int y = decal.location.y; int y = decal.location.y;
int z = loc_info(bel)->bel_data[bel.index].z; int z = loc_info(bel)->bel_data[bel.index].z;
GraphicElement::style_t style = decal.active ? GraphicElement::STYLE_ACTIVE : GraphicElement::STYLE_INACTIVE; GraphicElement::style_t style = decal.active ? GraphicElement::STYLE_ACTIVE : GraphicElement::STYLE_INACTIVE;
gfxTileBel(ret, x, y, z, chip_info->width, chip_info->height, bel_type, style); gfxTileBel(ret, x, y, z, device.chip_info->width, device.chip_info->height, bel_type, style);
} }
return ret; return ret;
@ -763,7 +769,7 @@ bool Arch::get_delay_from_tmg_db(IdString tctype, IdString from, IdString to, De
delay = fnd_dk->second.second; delay = fnd_dk->second.second;
return fnd_dk->second.first; return fnd_dk->second.first;
} }
for (auto &tc : speed_grade->cell_timings) { for (auto &tc : device.speed_grade->cell_timings) {
if (tc.cell_type == tctype.index) { if (tc.cell_type == tctype.index) {
for (auto &dly : tc.prop_delays) { for (auto &dly : tc.prop_delays) {
if (dly.from_port == from.index && dly.to_port == to.index) { if (dly.from_port == from.index && dly.to_port == to.index) {
@ -782,7 +788,7 @@ bool Arch::get_delay_from_tmg_db(IdString tctype, IdString from, IdString to, De
void Arch::get_setuphold_from_tmg_db(IdString tctype, IdString clock, IdString port, DelayPair &setup, void Arch::get_setuphold_from_tmg_db(IdString tctype, IdString clock, IdString port, DelayPair &setup,
DelayPair &hold) const DelayPair &hold) const
{ {
for (auto &tc : speed_grade->cell_timings) { for (auto &tc : device.speed_grade->cell_timings) {
if (tc.cell_type == tctype.index) { if (tc.cell_type == tctype.index) {
for (auto &sh : tc.setup_holds) { for (auto &sh : tc.setup_holds) {
if (sh.clock_port == clock.index && sh.sig_port == port.index) { if (sh.clock_port == clock.index && sh.sig_port == port.index) {
@ -1172,22 +1178,22 @@ TimingClockingInfo Arch::getPortClockingInfo(const CellInfo *cell, IdString port
std::vector<std::pair<std::string, std::string>> Arch::get_tiles_at_loc(int row, int col) std::vector<std::pair<std::string, std::string>> Arch::get_tiles_at_loc(int row, int col)
{ {
std::vector<std::pair<std::string, std::string>> ret; std::vector<std::pair<std::string, std::string>> ret;
auto &tileloc = chip_info->tile_info[row * chip_info->width + col]; auto &tileloc = device.chip_info->tile_info[row * device.chip_info->width + col];
for (auto &tn : tileloc.tile_names) { for (auto &tn : tileloc.tile_names) {
ret.push_back(std::make_pair(tn.name.get(), chip_info->tiletype_names[tn.type_idx].get())); ret.push_back(std::make_pair(tn.name.get(), device.chip_info->tiletype_names[tn.type_idx].get()));
} }
return ret; return ret;
} }
GlobalInfoPOD Arch::global_info_at_loc(Location loc) GlobalInfoPOD Arch::global_info_at_loc(Location loc)
{ {
int locidx = loc.y * chip_info->width + loc.x; int locidx = loc.y * device.chip_info->width + loc.x;
return chip_info->location_glbinfo[locidx]; return device.chip_info->location_glbinfo[locidx];
} }
bool Arch::get_pio_dqs_group(BelId pio, bool &dqsright, int &dqsrow) bool Arch::get_pio_dqs_group(BelId pio, bool &dqsright, int &dqsrow)
{ {
for (auto &ppio : chip_info->pio_info) { for (auto &ppio : device.chip_info->pio_info) {
if (Location(ppio.abs_loc) == pio.location && ppio.bel_index == pio.index) { if (Location(ppio.abs_loc) == pio.location && ppio.bel_index == pio.index) {
int dqs = ppio.dqsgroup; int dqs = ppio.dqsgroup;
if (dqs == -1) if (dqs == -1)
@ -1206,7 +1212,7 @@ BelId Arch::get_dqsbuf(bool dqsright, int dqsrow)
{ {
BelId bel; BelId bel;
bel.location.y = dqsrow; bel.location.y = dqsrow;
bel.location.x = (dqsright ? (chip_info->width - 1) : 0); bel.location.x = (dqsright ? (device.chip_info->width - 1) : 0);
for (int i = 0; i < loc_info(bel)->bel_data.ssize(); i++) { for (int i = 0; i < loc_info(bel)->bel_data.ssize(); i++) {
auto &bd = loc_info(bel)->bel_data[i]; auto &bd = loc_info(bel)->bel_data[i];
if (bd.type == id_DQSBUFM.index) { if (bd.type == id_DQSBUFM.index) {
@ -1259,8 +1265,8 @@ std::vector<GroupId> Arch::getGroups() const
{ {
std::vector<GroupId> ret; std::vector<GroupId> ret;
for (int y = 1; y < chip_info->height - 1; y++) { for (int y = 1; y < device.chip_info->height - 1; y++) {
for (int x = 1; x < chip_info->width - 1; x++) { for (int x = 1; x < device.chip_info->width - 1; x++) {
GroupId group; GroupId group;
group.type = GroupId::TYPE_SWITCHBOX; group.type = GroupId::TYPE_SWITCHBOX;
group.location.x = x; group.location.x = x;

View File

@ -446,8 +446,7 @@ struct ArchRanges : BaseArchRanges
using AllPipsRangeT = AllPipRange; using AllPipsRangeT = AllPipRange;
}; };
struct Arch : BaseArch<ArchRanges> struct ArchDevice {
{
const DeviceInfoPOD *device_info; const DeviceInfoPOD *device_info;
const ChipInfoPOD *chip_info; const ChipInfoPOD *chip_info;
const PackageInfoPOD *package_info; const PackageInfoPOD *package_info;
@ -476,6 +475,11 @@ struct Arch : BaseArch<ArchRanges>
SPEED_8, SPEED_8,
SPEED_8_5G, SPEED_8_5G,
} speed = SPEED_6; } speed = SPEED_6;
};
struct Arch : BaseArch<ArchRanges>
{
ArchDevice device;
mutable dict<IdStringList, PipId> pip_by_name; mutable dict<IdStringList, PipId> pip_by_name;
@ -551,8 +555,8 @@ struct Arch : BaseArch<ArchRanges>
static const int max_loc_bels = 32; static const int max_loc_bels = 32;
int getGridDimX() const override { return chip_info->width; }; int getGridDimX() const override { return device.chip_info->width; };
int getGridDimY() const override { return chip_info->height; }; int getGridDimY() const override { return device.chip_info->height; };
int getTileBelDimZ(int, int) const override { return max_loc_bels; }; int getTileBelDimZ(int, int) const override { return max_loc_bels; };
int getTilePipDimZ(int, int) const override { return 1; }; int getTilePipDimZ(int, int) const override { return 1; };
char getNameDelimiter() const override { return '/'; } char getNameDelimiter() const override { return '/'; }
@ -563,12 +567,12 @@ struct Arch : BaseArch<ArchRanges>
template <typename Id> const LocationTypePOD *loc_info(Id &id) const template <typename Id> const LocationTypePOD *loc_info(Id &id) const
{ {
return &(chip_info->locations[chip_info->location_type[id.location.y * chip_info->width + id.location.x]]); return &(device.chip_info->locations[device.chip_info->location_type[id.location.y * device.chip_info->width + id.location.x]]);
} }
template <typename Id> inline int tile_index(Id id) const template <typename Id> inline int tile_index(Id id) const
{ {
return id.location.y * chip_info->width + id.location.x; return id.location.y * device.chip_info->width + id.location.x;
} }
IdStringList getBelName(BelId bel) const override IdStringList getBelName(BelId bel) const override
@ -584,7 +588,7 @@ struct Arch : BaseArch<ArchRanges>
int get_slice_index(int x, int y, int slice) const int get_slice_index(int x, int y, int slice) const
{ {
NPNR_ASSERT(slice >= 0 && slice < 4); NPNR_ASSERT(slice >= 0 && slice < 4);
return (y * chip_info->width + x) * 4 + slice; return (y * device.chip_info->width + x) * 4 + slice;
} }
void update_bel(BelId bel, CellInfo *old_cell, CellInfo *new_cell) void update_bel(BelId bel, CellInfo *old_cell, CellInfo *new_cell)
@ -675,11 +679,11 @@ struct Arch : BaseArch<ArchRanges>
BelRange range; BelRange range;
range.b.cursor_tile = 0; range.b.cursor_tile = 0;
range.b.cursor_index = -1; range.b.cursor_index = -1;
range.b.chip = chip_info; range.b.chip = device.chip_info;
++range.b; //-1 and then ++ deals with the case of no Bels in the first tile ++range.b; //-1 and then ++ deals with the case of no Bels in the first tile
range.e.cursor_tile = chip_info->width * chip_info->height; range.e.cursor_tile = device.chip_info->width * device.chip_info->height;
range.e.cursor_index = 0; range.e.cursor_index = 0;
range.e.chip = chip_info; range.e.chip = device.chip_info;
return range; return range;
} }
@ -732,7 +736,7 @@ struct Arch : BaseArch<ArchRanges>
uint32_t get_wire_vecidx(const WireId &e) const uint32_t get_wire_vecidx(const WireId &e) const
{ {
uint32_t tile = e.location.y * chip_info->width + e.location.x; uint32_t tile = e.location.y * device.chip_info->width + e.location.x;
int32_t base = wire_tile_vecidx.at(tile); int32_t base = wire_tile_vecidx.at(tile);
NPNR_ASSERT(base != -1); NPNR_ASSERT(base != -1);
int32_t i = base + e.index; int32_t i = base + e.index;
@ -779,11 +783,11 @@ struct Arch : BaseArch<ArchRanges>
WireRange range; WireRange range;
range.b.cursor_tile = 0; range.b.cursor_tile = 0;
range.b.cursor_index = -1; range.b.cursor_index = -1;
range.b.chip = chip_info; range.b.chip = device.chip_info;
++range.b; //-1 and then ++ deals with the case of no wries in the first tile ++range.b; //-1 and then ++ deals with the case of no wries in the first tile
range.e.cursor_tile = chip_info->width * chip_info->height; range.e.cursor_tile = device.chip_info->width * device.chip_info->height;
range.e.cursor_index = 0; range.e.cursor_index = 0;
range.e.chip = chip_info; range.e.chip = device.chip_info;
return range; return range;
} }
@ -811,7 +815,7 @@ struct Arch : BaseArch<ArchRanges>
uint32_t get_pip_vecidx(const PipId &e) const uint32_t get_pip_vecidx(const PipId &e) const
{ {
uint32_t tile = e.location.y * chip_info->width + e.location.x; uint32_t tile = e.location.y * device.chip_info->width + e.location.x;
int32_t base = pip_tile_vecidx.at(tile); int32_t base = pip_tile_vecidx.at(tile);
NPNR_ASSERT(base != -1); NPNR_ASSERT(base != -1);
int32_t i = base + e.index; int32_t i = base + e.index;
@ -884,11 +888,11 @@ struct Arch : BaseArch<ArchRanges>
AllPipRange range; AllPipRange range;
range.b.cursor_tile = 0; range.b.cursor_tile = 0;
range.b.cursor_index = -1; range.b.cursor_index = -1;
range.b.chip = chip_info; range.b.chip = device.chip_info;
++range.b; //-1 and then ++ deals with the case of no wries in the first tile ++range.b; //-1 and then ++ deals with the case of no wries in the first tile
range.e.cursor_tile = chip_info->width * chip_info->height; range.e.cursor_tile = device.chip_info->width * device.chip_info->height;
range.e.cursor_index = 0; range.e.cursor_index = 0;
range.e.chip = chip_info; range.e.chip = device.chip_info;
return range; return range;
} }
@ -915,11 +919,11 @@ struct Arch : BaseArch<ArchRanges>
NPNR_ASSERT(pip != PipId()); NPNR_ASSERT(pip != PipId());
int fanout = wire_fanout[get_wire_vecidx(getPipSrcWire(pip))]; int fanout = wire_fanout[get_wire_vecidx(getPipSrcWire(pip))];
delay_t min_dly = delay_t min_dly =
speed_grade->pip_classes[loc_info(pip)->pip_data[pip.index].timing_class].min_base_delay + device.speed_grade->pip_classes[loc_info(pip)->pip_data[pip.index].timing_class].min_base_delay +
fanout * speed_grade->pip_classes[loc_info(pip)->pip_data[pip.index].timing_class].min_fanout_adder; fanout * device.speed_grade->pip_classes[loc_info(pip)->pip_data[pip.index].timing_class].min_fanout_adder;
delay_t max_dly = delay_t max_dly =
speed_grade->pip_classes[loc_info(pip)->pip_data[pip.index].timing_class].max_base_delay + device.speed_grade->pip_classes[loc_info(pip)->pip_data[pip.index].timing_class].max_base_delay +
fanout * speed_grade->pip_classes[loc_info(pip)->pip_data[pip.index].timing_class].max_fanout_adder; fanout * device.speed_grade->pip_classes[loc_info(pip)->pip_data[pip.index].timing_class].max_fanout_adder;
return DelayQuad(min_dly, max_dly); return DelayQuad(min_dly, max_dly);
} }
@ -947,7 +951,7 @@ struct Arch : BaseArch<ArchRanges>
std::string get_pip_tilename(PipId pip) const std::string get_pip_tilename(PipId pip) const
{ {
auto &tileloc = chip_info->tile_info[pip.location.y * chip_info->width + pip.location.x]; auto &tileloc = device.chip_info->tile_info[pip.location.y * device.chip_info->width + pip.location.x];
for (auto &tn : tileloc.tile_names) { for (auto &tn : tileloc.tile_names) {
if (tn.type_idx == loc_info(pip)->pip_data[pip.index].tile_type) if (tn.type_idx == loc_info(pip)->pip_data[pip.index].tile_type)
return tn.name.get(); return tn.name.get();
@ -957,7 +961,7 @@ struct Arch : BaseArch<ArchRanges>
std::string get_pip_tiletype(PipId pip) const std::string get_pip_tiletype(PipId pip) const
{ {
return chip_info->tiletype_names[loc_info(pip)->pip_data[pip.index].tile_type].get(); return device.chip_info->tiletype_names[loc_info(pip)->pip_data[pip.index].tile_type].get();
} }
Loc getPipLocation(PipId pip) const override Loc getPipLocation(PipId pip) const override
@ -1046,9 +1050,9 @@ struct Arch : BaseArch<ArchRanges>
std::vector<std::pair<std::string, std::string>> get_tiles_at_loc(int row, int col); std::vector<std::pair<std::string, std::string>> get_tiles_at_loc(int row, int col);
std::string get_tile_by_type_loc(int row, int col, std::string type) const std::string get_tile_by_type_loc(int row, int col, std::string type) const
{ {
auto &tileloc = chip_info->tile_info[row * chip_info->width + col]; auto &tileloc = device.chip_info->tile_info[row * device.chip_info->width + col];
for (auto &tn : tileloc.tile_names) { for (auto &tn : tileloc.tile_names) {
if (chip_info->tiletype_names[tn.type_idx].get() == type) if (device.chip_info->tiletype_names[tn.type_idx].get() == type)
return tn.name.get(); return tn.name.get();
} }
NPNR_ASSERT_FALSE_STR("no tile at (" + std::to_string(col) + ", " + std::to_string(row) + ") with type " + NPNR_ASSERT_FALSE_STR("no tile at (" + std::to_string(col) + ", " + std::to_string(row) + ") with type " +
@ -1057,9 +1061,9 @@ struct Arch : BaseArch<ArchRanges>
std::string get_tile_by_type_loc(int row, int col, const std::set<std::string> &type) const std::string get_tile_by_type_loc(int row, int col, const std::set<std::string> &type) const
{ {
auto &tileloc = chip_info->tile_info[row * chip_info->width + col]; auto &tileloc = device.chip_info->tile_info[row * device.chip_info->width + col];
for (auto &tn : tileloc.tile_names) { for (auto &tn : tileloc.tile_names) {
if (type.count(chip_info->tiletype_names[tn.type_idx].get())) if (type.count(device.chip_info->tiletype_names[tn.type_idx].get()))
return tn.name.get(); return tn.name.get();
} }
NPNR_ASSERT_FALSE_STR("no tile at (" + std::to_string(col) + ", " + std::to_string(row) + ") with type in set"); NPNR_ASSERT_FALSE_STR("no tile at (" + std::to_string(col) + ", " + std::to_string(row) + ") with type in set");
@ -1067,10 +1071,10 @@ struct Arch : BaseArch<ArchRanges>
std::string get_tile_by_type(std::string type) const std::string get_tile_by_type(std::string type) const
{ {
for (int i = 0; i < chip_info->height * chip_info->width; i++) { for (int i = 0; i < device.chip_info->height * device.chip_info->width; i++) {
auto &tileloc = chip_info->tile_info[i]; auto &tileloc = device.chip_info->tile_info[i];
for (auto &tn : tileloc.tile_names) for (auto &tn : tileloc.tile_names)
if (chip_info->tiletype_names[tn.type_idx].get() == type) if (device.chip_info->tiletype_names[tn.type_idx].get() == type)
return tn.name.get(); return tn.name.get();
} }
NPNR_ASSERT_FALSE_STR("no tile with type " + type); NPNR_ASSERT_FALSE_STR("no tile with type " + type);

View File

@ -188,8 +188,8 @@ bool Arch::isBelLocationValid(BelId bel, bool explain_invalid) const
if (cell == nullptr) { if (cell == nullptr) {
return true; return true;
} else if (cell->type.in(id_DCUA, id_EXTREFB, id_PCSCLKDIV)) { } else if (cell->type.in(id_DCUA, id_EXTREFB, id_PCSCLKDIV)) {
return type != Arch::ArchTypes::LFE5U_25F && type != Arch::ArchTypes::LFE5U_45F && return device.type != ArchDevice::LFE5U_25F && device.type != ArchDevice::LFE5U_45F &&
type != Arch::ArchTypes::LFE5U_85F; device.type != ArchDevice::LFE5U_85F;
} else if (cell->type.in(id_MULT18X18D, id_ALU54B)) { } else if (cell->type.in(id_MULT18X18D, id_ALU54B)) {
return is_dsp_location_valid(cell); return is_dsp_location_valid(cell);
} else { } else {

View File

@ -195,7 +195,7 @@ struct ECP5Bitgen
} else { } else {
NPNR_ASSERT_FALSE("bad PIO location"); NPNR_ASSERT_FALSE("bad PIO location");
} }
} else if (bel.location.y == ctx->chip_info->height - 1) { } else if (bel.location.y == ctx->device.chip_info->height - 1) {
if (pio_name == "PIOA") { if (pio_name == "PIOA") {
return ctx->get_tile_by_type_loc(bel.location.y, bel.location.x, pioa_b); return ctx->get_tile_by_type_loc(bel.location.y, bel.location.x, pioa_b);
} else if (pio_name == "PIOB") { } else if (pio_name == "PIOB") {
@ -205,7 +205,7 @@ struct ECP5Bitgen
} }
} else if (bel.location.x == 0) { } else if (bel.location.x == 0) {
return ctx->get_tile_by_type_loc(bel.location.y + 1, bel.location.x, pioabcd_l); return ctx->get_tile_by_type_loc(bel.location.y + 1, bel.location.x, pioabcd_l);
} else if (bel.location.x == ctx->chip_info->width - 1) { } else if (bel.location.x == ctx->device.chip_info->width - 1) {
return ctx->get_tile_by_type_loc(bel.location.y + 1, bel.location.x, pioabcd_r); return ctx->get_tile_by_type_loc(bel.location.y + 1, bel.location.x, pioabcd_r);
} else { } else {
NPNR_ASSERT_FALSE("bad PIO location"); NPNR_ASSERT_FALSE("bad PIO location");
@ -232,7 +232,7 @@ struct ECP5Bitgen
} else { } else {
NPNR_ASSERT_FALSE("bad PIO location"); NPNR_ASSERT_FALSE("bad PIO location");
} }
} else if (bel.location.y == ctx->chip_info->height - 1) { } else if (bel.location.y == ctx->device.chip_info->height - 1) {
if (pio_name == "PIOA") { if (pio_name == "PIOA") {
return ctx->get_tile_by_type_loc(bel.location.y, bel.location.x, pica_b); return ctx->get_tile_by_type_loc(bel.location.y, bel.location.x, pica_b);
} else if (pio_name == "PIOB") { } else if (pio_name == "PIOB") {
@ -248,7 +248,7 @@ struct ECP5Bitgen
} else { } else {
NPNR_ASSERT_FALSE("bad PIO location"); NPNR_ASSERT_FALSE("bad PIO location");
} }
} else if (bel.location.x == ctx->chip_info->width - 1) { } else if (bel.location.x == ctx->device.chip_info->width - 1) {
if (pio_name == "PIOA" || pio_name == "PIOB") { if (pio_name == "PIOA" || pio_name == "PIOB") {
return ctx->get_tile_by_type_loc(bel.location.y, bel.location.x, picab_r); return ctx->get_tile_by_type_loc(bel.location.y, bel.location.x, picab_r);
} else if (pio_name == "PIOC" || pio_name == "PIOD") { } else if (pio_name == "PIOC" || pio_name == "PIOD") {
@ -443,8 +443,8 @@ struct ECP5Bitgen
void fix_tile_names() void fix_tile_names()
{ {
// Remove the V prefix/suffix on certain tiles if device is a SERDES variant // Remove the V prefix/suffix on certain tiles if device is a SERDES variant
if (ctx->type == Arch::ArchTypes::LFE5U_12F || ctx->type == Arch::ArchTypes::LFE5U_25F || if (ctx->device.type == ArchDevice::LFE5U_12F || ctx->device.type == ArchDevice::LFE5U_25F ||
ctx->type == Arch::ArchTypes::LFE5U_45F || ctx->type == Arch::ArchTypes::LFE5U_85F) { ctx->device.type == ArchDevice::LFE5U_45F || ctx->device.type == ArchDevice::LFE5U_85F) {
std::map<std::string, std::string> tiletype_xform; std::map<std::string, std::string> tiletype_xform;
for (const auto &tile : cc.tiles) { for (const auto &tile : cc.tiles) {
std::string newname = tile.first; std::string newname = tile.first;
@ -1370,35 +1370,35 @@ struct ECP5Bitgen
} }
config_file >> cc; config_file >> cc;
} else { } else {
switch (ctx->type) { switch (ctx->device.type) {
case Arch::ArchTypes::LFE5U_12F: case ArchDevice::LFE5U_12F:
BaseConfigs::config_empty_lfe5u_25f(cc); BaseConfigs::config_empty_lfe5u_25f(cc);
break; break;
case Arch::ArchTypes::LFE5U_25F: case ArchDevice::LFE5U_25F:
BaseConfigs::config_empty_lfe5u_25f(cc); BaseConfigs::config_empty_lfe5u_25f(cc);
break; break;
case Arch::ArchTypes::LFE5U_45F: case ArchDevice::LFE5U_45F:
BaseConfigs::config_empty_lfe5u_45f(cc); BaseConfigs::config_empty_lfe5u_45f(cc);
break; break;
case Arch::ArchTypes::LFE5U_85F: case ArchDevice::LFE5U_85F:
BaseConfigs::config_empty_lfe5u_85f(cc); BaseConfigs::config_empty_lfe5u_85f(cc);
break; break;
case Arch::ArchTypes::LFE5UM_25F: case ArchDevice::LFE5UM_25F:
BaseConfigs::config_empty_lfe5um_25f(cc); BaseConfigs::config_empty_lfe5um_25f(cc);
break; break;
case Arch::ArchTypes::LFE5UM_45F: case ArchDevice::LFE5UM_45F:
BaseConfigs::config_empty_lfe5um_45f(cc); BaseConfigs::config_empty_lfe5um_45f(cc);
break; break;
case Arch::ArchTypes::LFE5UM_85F: case ArchDevice::LFE5UM_85F:
BaseConfigs::config_empty_lfe5um_85f(cc); BaseConfigs::config_empty_lfe5um_85f(cc);
break; break;
case Arch::ArchTypes::LFE5UM5G_25F: case ArchDevice::LFE5UM5G_25F:
BaseConfigs::config_empty_lfe5um5g_25f(cc); BaseConfigs::config_empty_lfe5um5g_25f(cc);
break; break;
case Arch::ArchTypes::LFE5UM5G_45F: case ArchDevice::LFE5UM5G_45F:
BaseConfigs::config_empty_lfe5um5g_45f(cc); BaseConfigs::config_empty_lfe5um5g_45f(cc);
break; break;
case Arch::ArchTypes::LFE5UM5G_85F: case ArchDevice::LFE5UM5G_85F:
BaseConfigs::config_empty_lfe5um5g_85f(cc); BaseConfigs::config_empty_lfe5um5g_85f(cc);
break; break;
default: default:
@ -1406,8 +1406,8 @@ struct ECP5Bitgen
} }
} }
cc.chip_name = ctx->device_info->name.get(); cc.chip_name = ctx->device.device_info->name.get();
cc.chip_variant = ctx->device_name; cc.chip_variant = ctx->device.device_name;
cc.metadata.push_back("Part: " + ctx->getChipName()); cc.metadata.push_back("Part: " + ctx->getChipName());
// Clear out DCU tieoffs in base config if DCU used // Clear out DCU tieoffs in base config if DCU used
@ -1551,8 +1551,8 @@ struct ECP5Bitgen
Loc loc = ctx->getBelLocation(ci->bel); Loc loc = ctx->getBelLocation(ci->bel);
bool u = loc.y<15, r = loc.x> 15; bool u = loc.y<15, r = loc.x> 15;
std::string tiletype = fmt_str("DDRDLL_" << (u ? 'U' : 'L') << (r ? 'R' : 'L')); std::string tiletype = fmt_str("DDRDLL_" << (u ? 'U' : 'L') << (r ? 'R' : 'L'));
if ((ctx->type == Arch::ArchTypes::LFE5U_12F || ctx->type == Arch::ArchTypes::LFE5U_25F || if ((ctx->device.type == ArchDevice::LFE5U_12F || ctx->device.type == ArchDevice::LFE5U_25F ||
ctx->type == Arch::ArchTypes::LFE5UM_25F || ctx->type == Arch::ArchTypes::LFE5UM5G_25F) && ctx->device.type == ArchDevice::LFE5UM_25F || ctx->device.type == ArchDevice::LFE5UM5G_25F) &&
u) u)
tiletype += "A"; tiletype += "A";
std::string tile = ctx->get_tile_by_type(tiletype); std::string tile = ctx->get_tile_by_type(tiletype);

View File

@ -582,7 +582,7 @@ class Ecp5Packer
BelId pinBel = ctx->get_package_pin_bel(pin); BelId pinBel = ctx->get_package_pin_bel(pin);
if (pinBel == BelId()) { if (pinBel == BelId()) {
log_error("IO pin '%s' constrained to pin '%s', which does not exist for package '%s'.\n", log_error("IO pin '%s' constrained to pin '%s', which does not exist for package '%s'.\n",
trio->name.c_str(ctx), pin.c_str(), ctx->package_name); trio->name.c_str(ctx), pin.c_str(), ctx->device.package_name);
} else { } else {
log_info("pin '%s' constrained to Bel '%s'.\n", trio->name.c_str(ctx), log_info("pin '%s' constrained to Bel '%s'.\n", trio->name.c_str(ctx),
ctx->nameOfBel(pinBel)); ctx->nameOfBel(pinBel));
@ -665,7 +665,7 @@ class Ecp5Packer
{ {
bool start_of_chain = true; bool start_of_chain = true;
std::vector<CellChain> chains; std::vector<CellChain> chains;
const int max_length = (ctx->chip_info->width - 4) * 4 - 2; const int max_length = (ctx->device.chip_info->width - 4) * 4 - 2;
auto curr_cell = carryc.cells.begin(); auto curr_cell = carryc.cells.begin();
while (curr_cell != carryc.cells.end()) { while (curr_cell != carryc.cells.end()) {
CellInfo *cell = *curr_cell; CellInfo *cell = *curr_cell;
@ -1323,19 +1323,19 @@ class Ecp5Packer
if (ci->attrs.count(id_LOC)) { if (ci->attrs.count(id_LOC)) {
std::string loc = ci->attrs.at(id_LOC).as_string(); std::string loc = ci->attrs.at(id_LOC).as_string();
if (loc == "DCU0" && if (loc == "DCU0" &&
(ctx->type == Arch::ArchTypes::LFE5UM_25F || ctx->type == Arch::ArchTypes::LFE5UM5G_25F)) (ctx->device.type == ArchDevice::LFE5UM_25F || ctx->device.type == ArchDevice::LFE5UM5G_25F))
ci->attrs[id_BEL] = std::string("X42/Y50/DCU"); ci->attrs[id_BEL] = std::string("X42/Y50/DCU");
else if (loc == "DCU0" && else if (loc == "DCU0" &&
(ctx->type == Arch::ArchTypes::LFE5UM_45F || ctx->type == Arch::ArchTypes::LFE5UM5G_45F)) (ctx->device.type == ArchDevice::LFE5UM_45F || ctx->device.type == ArchDevice::LFE5UM5G_45F))
ci->attrs[id_BEL] = std::string("X42/Y71/DCU"); ci->attrs[id_BEL] = std::string("X42/Y71/DCU");
else if (loc == "DCU1" && else if (loc == "DCU1" &&
(ctx->type == Arch::ArchTypes::LFE5UM_45F || ctx->type == Arch::ArchTypes::LFE5UM5G_45F)) (ctx->device.type == ArchDevice::LFE5UM_45F || ctx->device.type == ArchDevice::LFE5UM5G_45F))
ci->attrs[id_BEL] = std::string("X69/Y71/DCU"); ci->attrs[id_BEL] = std::string("X69/Y71/DCU");
else if (loc == "DCU0" && else if (loc == "DCU0" &&
(ctx->type == Arch::ArchTypes::LFE5UM_85F || ctx->type == Arch::ArchTypes::LFE5UM5G_85F)) (ctx->device.type == ArchDevice::LFE5UM_85F || ctx->device.type == ArchDevice::LFE5UM5G_85F))
ci->attrs[id_BEL] = std::string("X46/Y95/DCU"); ci->attrs[id_BEL] = std::string("X46/Y95/DCU");
else if (loc == "DCU1" && else if (loc == "DCU1" &&
(ctx->type == Arch::ArchTypes::LFE5UM_85F || ctx->type == Arch::ArchTypes::LFE5UM5G_85F)) (ctx->device.type == ArchDevice::LFE5UM_85F || ctx->device.type == ArchDevice::LFE5UM5G_85F))
ci->attrs[id_BEL] = std::string("X71/Y95/DCU"); ci->attrs[id_BEL] = std::string("X71/Y95/DCU");
else else
log_error("no DCU location '%s' in device '%s'\n", loc.c_str(), ctx->getChipName().c_str()); log_error("no DCU location '%s' in device '%s'\n", loc.c_str(), ctx->getChipName().c_str());
@ -1378,19 +1378,19 @@ class Ecp5Packer
if (ci->attrs.count(id_LOC)) { if (ci->attrs.count(id_LOC)) {
std::string loc = ci->attrs.at(id_LOC).as_string(); std::string loc = ci->attrs.at(id_LOC).as_string();
if (loc == "EXTREF0" && if (loc == "EXTREF0" &&
(ctx->type == Arch::ArchTypes::LFE5UM_25F || ctx->type == Arch::ArchTypes::LFE5UM5G_25F)) (ctx->device.type == ArchDevice::LFE5UM_25F || ctx->device.type == ArchDevice::LFE5UM5G_25F))
loc_bel = std::string("X42/Y50/EXTREF"); loc_bel = std::string("X42/Y50/EXTREF");
else if (loc == "EXTREF0" && else if (loc == "EXTREF0" &&
(ctx->type == Arch::ArchTypes::LFE5UM_45F || ctx->type == Arch::ArchTypes::LFE5UM5G_45F)) (ctx->device.type == ArchDevice::LFE5UM_45F || ctx->device.type == ArchDevice::LFE5UM5G_45F))
loc_bel = std::string("X42/Y71/EXTREF"); loc_bel = std::string("X42/Y71/EXTREF");
else if (loc == "EXTREF1" && else if (loc == "EXTREF1" &&
(ctx->type == Arch::ArchTypes::LFE5UM_45F || ctx->type == Arch::ArchTypes::LFE5UM5G_45F)) (ctx->device.type == ArchDevice::LFE5UM_45F || ctx->device.type == ArchDevice::LFE5UM5G_45F))
loc_bel = std::string("X69/Y71/EXTREF"); loc_bel = std::string("X69/Y71/EXTREF");
else if (loc == "EXTREF0" && else if (loc == "EXTREF0" &&
(ctx->type == Arch::ArchTypes::LFE5UM_85F || ctx->type == Arch::ArchTypes::LFE5UM5G_85F)) (ctx->device.type == ArchDevice::LFE5UM_85F || ctx->device.type == ArchDevice::LFE5UM5G_85F))
loc_bel = std::string("X46/Y95/EXTREF"); loc_bel = std::string("X46/Y95/EXTREF");
else if (loc == "EXTREF1" && else if (loc == "EXTREF1" &&
(ctx->type == Arch::ArchTypes::LFE5UM_85F || ctx->type == Arch::ArchTypes::LFE5UM5G_85F)) (ctx->device.type == ArchDevice::LFE5UM_85F || ctx->device.type == ArchDevice::LFE5UM5G_85F))
loc_bel = std::string("X71/Y95/EXTREF"); loc_bel = std::string("X71/Y95/EXTREF");
} }
if (refo == nullptr) if (refo == nullptr)
@ -1859,7 +1859,7 @@ class Ecp5Packer
log_info("IOLOGIC component %s connected to PIO Bel %s\n", curr->name.c_str(ctx), ctx->nameOfBel(bel)); log_info("IOLOGIC component %s connected to PIO Bel %s\n", curr->name.c_str(ctx), ctx->nameOfBel(bel));
Loc loc = ctx->getBelLocation(bel); Loc loc = ctx->getBelLocation(bel);
bool s = false; bool s = false;
if (loc.y == 0 || loc.y == (ctx->chip_info->height - 1)) if (loc.y == 0 || loc.y == (ctx->device.chip_info->height - 1))
s = true; s = true;
std::unique_ptr<CellInfo> iol = std::unique_ptr<CellInfo> iol =
create_ecp5_cell(ctx, s ? id_SIOLOGIC : id_IOLOGIC, pio->name.str(ctx) + "$IOL"); create_ecp5_cell(ctx, s ? id_SIOLOGIC : id_IOLOGIC, pio->name.str(ctx) + "$IOL");

View File

@ -49,7 +49,7 @@ MainWindow::~MainWindow() {}
void MainWindow::newContext(Context *ctx) void MainWindow::newContext(Context *ctx)
{ {
std::string title = "nextpnr-ecp5 - " + std::string(ctx->device_name) + " (" + std::string(ctx->package_name) + std::string title = "nextpnr-ecp5 - " + std::string(ctx->device.device_name) + " (" + std::string(ctx->device.package_name) +
") - Part : " + ctx->getChipName(); ") - Part : " + ctx->getChipName();
setWindowTitle(title.c_str()); setWindowTitle(title.c_str());
} }