aboutsummaryrefslogtreecommitdiffstats
path: root/ice40
diff options
context:
space:
mode:
Diffstat (limited to 'ice40')
-rw-r--r--ice40/arch.cc (renamed from ice40/chip.cc)56
-rw-r--r--ice40/arch.h (renamed from ice40/chip.h)18
-rw-r--r--ice40/arch_place.cc32
-rw-r--r--ice40/arch_place.h4
-rw-r--r--ice40/bitstream.cc81
-rw-r--r--ice40/bitstream.h2
-rw-r--r--ice40/cells.cc2
-rw-r--r--ice40/cells.h2
-rw-r--r--ice40/main.cc61
-rw-r--r--ice40/pack.cc104
-rw-r--r--ice40/pack.h2
-rw-r--r--ice40/pcf.cc11
-rw-r--r--ice40/pcf.h2
-rw-r--r--ice40/pybindings.cc62
14 files changed, 217 insertions, 222 deletions
diff --git a/ice40/chip.cc b/ice40/arch.cc
index 7074070e..b269a3e3 100644
--- a/ice40/chip.cc
+++ b/ice40/arch.cc
@@ -78,10 +78,10 @@ PortPin portPinFromId(IdString id)
// -----------------------------------------------------------------------
-Chip::Chip(ChipArgs args) : args(args)
+Arch::Arch(ArchArgs args) : args(args)
{
#ifdef ICE40_HX1K_ONLY
- if (args.type == ChipArgs::HX1K) {
+ if (args.type == ArchArgs::HX1K) {
chip_info =
reinterpret_cast<const RelPtr<ChipInfoPOD> *>(chipdb_blob_1k)
->get();
@@ -89,19 +89,19 @@ Chip::Chip(ChipArgs args) : args(args)
log_error("Unsupported iCE40 chip type.\n");
}
#else
- if (args.type == ChipArgs::LP384) {
+ if (args.type == ArchArgs::LP384) {
chip_info =
reinterpret_cast<const RelPtr<ChipInfoPOD> *>(chipdb_blob_384)
->get();
- } else if (args.type == ChipArgs::LP1K || args.type == ChipArgs::HX1K) {
+ } else if (args.type == ArchArgs::LP1K || args.type == ArchArgs::HX1K) {
chip_info =
reinterpret_cast<const RelPtr<ChipInfoPOD> *>(chipdb_blob_1k)
->get();
- } else if (args.type == ChipArgs::UP5K) {
+ } else if (args.type == ArchArgs::UP5K) {
chip_info =
reinterpret_cast<const RelPtr<ChipInfoPOD> *>(chipdb_blob_5k)
->get();
- } else if (args.type == ChipArgs::LP8K || args.type == ChipArgs::HX8K) {
+ } else if (args.type == ArchArgs::LP8K || args.type == ArchArgs::HX8K) {
chip_info =
reinterpret_cast<const RelPtr<ChipInfoPOD> *>(chipdb_blob_8k)
->get();
@@ -128,26 +128,26 @@ Chip::Chip(ChipArgs args) : args(args)
// -----------------------------------------------------------------------
-std::string Chip::getChipName()
+std::string Arch::getChipName()
{
#ifdef ICE40_HX1K_ONLY
- if (args.type == ChipArgs::HX1K) {
+ if (args.type == ArchArgs::HX1K) {
return "Lattice LP1K";
} else {
log_error("Unsupported iCE40 chip type.\n");
}
#else
- if (args.type == ChipArgs::LP384) {
+ if (args.type == ArchArgs::LP384) {
return "Lattice LP384";
- } else if (args.type == ChipArgs::LP1K) {
+ } else if (args.type == ArchArgs::LP1K) {
return "Lattice LP1K";
- } else if (args.type == ChipArgs::HX1K) {
+ } else if (args.type == ArchArgs::HX1K) {
return "Lattice HX1K";
- } else if (args.type == ChipArgs::UP5K) {
+ } else if (args.type == ArchArgs::UP5K) {
return "Lattice UP5K";
- } else if (args.type == ChipArgs::LP8K) {
+ } else if (args.type == ArchArgs::LP8K) {
return "Lattice LP8K";
- } else if (args.type == ChipArgs::HX8K) {
+ } else if (args.type == ArchArgs::HX8K) {
return "Lattice HX8K";
} else {
log_error("Unknown chip\n");
@@ -157,7 +157,7 @@ std::string Chip::getChipName()
// -----------------------------------------------------------------------
-BelId Chip::getBelByName(IdString name) const
+BelId Arch::getBelByName(IdString name) const
{
BelId ret;
@@ -173,7 +173,7 @@ BelId Chip::getBelByName(IdString name) const
return ret;
}
-BelRange Chip::getBelsAtSameTile(BelId bel) const
+BelRange Arch::getBelsAtSameTile(BelId bel) const
{
BelRange br;
assert(bel != BelId());
@@ -193,7 +193,7 @@ BelRange Chip::getBelsAtSameTile(BelId bel) const
return br;
}
-WireId Chip::getWireBelPin(BelId bel, PortPin pin) const
+WireId Arch::getWireBelPin(BelId bel, PortPin pin) const
{
WireId ret;
@@ -214,7 +214,7 @@ WireId Chip::getWireBelPin(BelId bel, PortPin pin) const
// -----------------------------------------------------------------------
-WireId Chip::getWireByName(IdString name) const
+WireId Arch::getWireByName(IdString name) const
{
WireId ret;
@@ -232,7 +232,7 @@ WireId Chip::getWireByName(IdString name) const
// -----------------------------------------------------------------------
-PipId Chip::getPipByName(IdString name) const
+PipId Arch::getPipByName(IdString name) const
{
PipId ret;
@@ -251,7 +251,7 @@ PipId Chip::getPipByName(IdString name) const
return ret;
}
-IdString Chip::getPipName(PipId pip) const
+IdString Arch::getPipName(PipId pip) const
{
assert(pip != PipId());
@@ -272,7 +272,7 @@ IdString Chip::getPipName(PipId pip) const
// -----------------------------------------------------------------------
-BelId Chip::getPackagePinBel(const std::string &pin) const
+BelId Arch::getPackagePinBel(const std::string &pin) const
{
for (int i = 0; i < package_info->num_pins; i++) {
if (package_info->pins[i].name.get() == pin) {
@@ -284,7 +284,7 @@ BelId Chip::getPackagePinBel(const std::string &pin) const
return BelId();
}
-std::string Chip::getBelPackagePin(BelId bel) const
+std::string Arch::getBelPackagePin(BelId bel) const
{
for (int i = 0; i < package_info->num_pins; i++) {
if (package_info->pins[i].bel_index == bel.index) {
@@ -295,7 +295,7 @@ std::string Chip::getBelPackagePin(BelId bel) const
}
// -----------------------------------------------------------------------
-bool Chip::estimatePosition(BelId bel, int &x, int &y) const
+bool Arch::estimatePosition(BelId bel, int &x, int &y) const
{
assert(bel != BelId());
x = chip_info->bel_data[bel.index].x;
@@ -304,7 +304,7 @@ bool Chip::estimatePosition(BelId bel, int &x, int &y) const
return chip_info->bel_data[bel.index].type != TYPE_SB_GB;
}
-delay_t Chip::estimateDelay(WireId src, WireId dst) const
+delay_t Arch::estimateDelay(WireId src, WireId dst) const
{
assert(src != WireId());
delay_t x1 = chip_info->wire_data[src.index].x;
@@ -319,7 +319,7 @@ delay_t Chip::estimateDelay(WireId src, WireId dst) const
// -----------------------------------------------------------------------
-std::vector<GraphicElement> Chip::getFrameGraphics() const
+std::vector<GraphicElement> Arch::getFrameGraphics() const
{
std::vector<GraphicElement> ret;
@@ -336,7 +336,7 @@ std::vector<GraphicElement> Chip::getFrameGraphics() const
return ret;
}
-std::vector<GraphicElement> Chip::getBelGraphics(BelId bel) const
+std::vector<GraphicElement> Arch::getBelGraphics(BelId bel) const
{
std::vector<GraphicElement> ret;
@@ -402,14 +402,14 @@ std::vector<GraphicElement> Chip::getBelGraphics(BelId bel) const
return ret;
}
-std::vector<GraphicElement> Chip::getWireGraphics(WireId wire) const
+std::vector<GraphicElement> Arch::getWireGraphics(WireId wire) const
{
std::vector<GraphicElement> ret;
// FIXME
return ret;
}
-std::vector<GraphicElement> Chip::getPipGraphics(PipId pip) const
+std::vector<GraphicElement> Arch::getPipGraphics(PipId pip) const
{
std::vector<GraphicElement> ret;
// FIXME
diff --git a/ice40/chip.h b/ice40/arch.h
index d3eb7c70..9e811ba9 100644
--- a/ice40/chip.h
+++ b/ice40/arch.h
@@ -21,7 +21,7 @@
#define CHIP_H
#ifndef NEXTPNR_H
-#error Include "chip.h" via "nextpnr.h" only.
+#error Include "arch.h" via "nextpnr.h" only.
#endif
NEXTPNR_NAMESPACE_BEGIN
@@ -443,7 +443,7 @@ struct PipRange
// -----------------------------------------------------------------------
-struct ChipArgs
+struct ArchArgs
{
enum
{
@@ -458,7 +458,7 @@ struct ChipArgs
std::string package;
};
-struct Chip
+struct Arch
{
const ChipInfoPOD *chip_info;
const PackageInfoPOD *package_info;
@@ -471,13 +471,14 @@ struct Chip
std::vector<IdString> wire_to_net;
std::vector<IdString> pip_to_net;
std::vector<IdString> switches_locked;
- Chip(ChipArgs args);
- ChipArgs args;
- // -------------------------------------------------
+ ArchArgs args;
+ Arch(ArchArgs args);
std::string getChipName();
+ // -------------------------------------------------
+
BelId getBelByName(IdString name) const;
IdString getBelName(BelId bel) const
@@ -641,7 +642,7 @@ struct Chip
bool checkPipAvail(PipId pip) const
{
assert(pip != PipId());
- if (args.type == ChipArgs::UP5K) {
+ if (args.type == ArchArgs::UP5K) {
int x = chip_info->pip_data[pip.index].x;
if (x == 0 || x == (chip_info->width - 1))
return false;
@@ -746,8 +747,7 @@ NEXTPNR_NAMESPACE_END
namespace std {
template <> struct hash<NEXTPNR_NAMESPACE_PREFIX BelType>
{
- std::size_t operator()(NEXTPNR_NAMESPACE_PREFIX BelType bt) const
- noexcept
+ std::size_t operator()(NEXTPNR_NAMESPACE_PREFIX BelType bt) const noexcept
{
return std::hash<int>()(int(bt));
}
diff --git a/ice40/arch_place.cc b/ice40/arch_place.cc
index 3205fb6e..faa6b187 100644
--- a/ice40/arch_place.cc
+++ b/ice40/arch_place.cc
@@ -88,40 +88,38 @@ static bool logicCellsCompatible(const std::vector<const CellInfo *> &cells)
return locals.size() <= 32;
}
-bool isBelLocationValid(Design *design, BelId bel)
+bool isBelLocationValid(Context *ctx, BelId bel)
{
- const Chip &chip = design->chip;
- if (chip.getBelType(bel) == TYPE_ICESTORM_LC) {
+ if (ctx->getBelType(bel) == TYPE_ICESTORM_LC) {
std::vector<const CellInfo *> cells;
- for (auto bel_other : chip.getBelsAtSameTile(bel)) {
- IdString cell_other = chip.getBelCell(bel_other, false);
+ for (auto bel_other : ctx->getBelsAtSameTile(bel)) {
+ IdString cell_other = ctx->getBelCell(bel_other, false);
if (cell_other != IdString()) {
- const CellInfo *ci_other = design->cells[cell_other];
+ const CellInfo *ci_other = ctx->cells[cell_other];
cells.push_back(ci_other);
}
}
return logicCellsCompatible(cells);
} else {
- IdString cellId = chip.getBelCell(bel, false);
+ IdString cellId = ctx->getBelCell(bel, false);
if (cellId == IdString())
return true;
else
- return isValidBelForCell(design, design->cells.at(cellId), bel);
+ return isValidBelForCell(ctx, ctx->cells.at(cellId), bel);
}
}
-bool isValidBelForCell(Design *design, CellInfo *cell, BelId bel)
+bool isValidBelForCell(Context *ctx, CellInfo *cell, BelId bel)
{
- const Chip &chip = design->chip;
if (cell->type == "ICESTORM_LC") {
- assert(chip.getBelType(bel) == TYPE_ICESTORM_LC);
+ assert(ctx->getBelType(bel) == TYPE_ICESTORM_LC);
std::vector<const CellInfo *> cells;
- for (auto bel_other : chip.getBelsAtSameTile(bel)) {
- IdString cell_other = chip.getBelCell(bel_other, false);
+ for (auto bel_other : ctx->getBelsAtSameTile(bel)) {
+ IdString cell_other = ctx->getBelCell(bel_other, false);
if (cell_other != IdString()) {
- const CellInfo *ci_other = design->cells[cell_other];
+ const CellInfo *ci_other = ctx->cells[cell_other];
cells.push_back(ci_other);
}
}
@@ -129,7 +127,7 @@ bool isValidBelForCell(Design *design, CellInfo *cell, BelId bel)
cells.push_back(cell);
return logicCellsCompatible(cells);
} else if (cell->type == "SB_IO") {
- return design->chip.getBelPackagePin(bel) != "";
+ return ctx->getBelPackagePin(bel) != "";
} else if (cell->type == "SB_GB") {
bool is_reset = false, is_cen = false;
assert(cell->ports.at("GLOBAL_BUFFER_OUTPUT").net != nullptr);
@@ -139,8 +137,8 @@ bool isValidBelForCell(Design *design, CellInfo *cell, BelId bel)
if (is_enable_port(user))
is_cen = true;
}
- IdString glb_net = chip.getWireName(
- chip.getWireBelPin(bel, PIN_GLOBAL_BUFFER_OUTPUT));
+ IdString glb_net = ctx->getWireName(
+ ctx->getWireBelPin(bel, PIN_GLOBAL_BUFFER_OUTPUT));
int glb_id = std::stoi(std::string("") + glb_net.str().back());
if (is_reset && is_cen)
return false;
diff --git a/ice40/arch_place.h b/ice40/arch_place.h
index 5cd14809..3d05ed7a 100644
--- a/ice40/arch_place.h
+++ b/ice40/arch_place.h
@@ -29,10 +29,10 @@ NEXTPNR_NAMESPACE_BEGIN
// Whether or not a given cell can be placed at a given Bel
// This is not intended for Bel type checks, but finer-grained constraints
// such as conflicting set/reset signals, etc
-bool isValidBelForCell(Design *design, CellInfo *cell, BelId bel);
+bool isValidBelForCell(Context *ctx, CellInfo *cell, BelId bel);
// Return true whether all Bels at a given location are valid
-bool isBelLocationValid(Design *design, BelId bel);
+bool isBelLocationValid(Context *ctx, BelId bel);
NEXTPNR_NAMESPACE_END
diff --git a/ice40/bitstream.cc b/ice40/bitstream.cc
index 4991df5e..8b28842c 100644
--- a/ice40/bitstream.cc
+++ b/ice40/bitstream.cc
@@ -23,9 +23,9 @@
NEXTPNR_NAMESPACE_BEGIN
-inline TileType tile_at(const Chip &chip, int x, int y)
+inline TileType tile_at(const Context *ctx, int x, int y)
{
- return chip.chip_info->tile_grid[y * chip.chip_info->width + x];
+ return ctx->chip_info->tile_grid[y * ctx->chip_info->width + x];
}
const ConfigEntryPOD &find_config(const TileInfoPOD &tile,
@@ -95,18 +95,17 @@ std::string get_param_str_or_def(const CellInfo *cell, const std::string &param,
char get_hexdigit(int i) { return std::string("0123456789ABCDEF").at(i); }
-void write_asc(const Design &design, std::ostream &out)
+void write_asc(const Context *ctx, std::ostream &out)
{
- const Chip &chip = design.chip;
// [y][x][row][col]
- const ChipInfoPOD &ci = *chip.chip_info;
+ const ChipInfoPOD &ci = *ctx->chip_info;
const BitstreamInfoPOD &bi = *ci.bits_info;
std::vector<std::vector<std::vector<std::vector<int8_t>>>> config;
config.resize(ci.height);
for (int y = 0; y < ci.height; y++) {
config.at(y).resize(ci.width);
for (int x = 0; x < ci.width; x++) {
- TileType tile = tile_at(chip, x, y);
+ TileType tile = tile_at(ctx, x, y);
int rows = bi.tiles_nonrouting[tile].rows;
int cols = bi.tiles_nonrouting[tile].cols;
config.at(y).at(x).resize(rows, std::vector<int8_t>(cols));
@@ -114,27 +113,27 @@ void write_asc(const Design &design, std::ostream &out)
}
out << ".comment from next-pnr" << std::endl;
- switch (chip.args.type) {
- case ChipArgs::LP384:
+ switch (ctx->args.type) {
+ case ArchArgs::LP384:
out << ".device 384" << std::endl;
break;
- case ChipArgs::HX1K:
- case ChipArgs::LP1K:
+ case ArchArgs::HX1K:
+ case ArchArgs::LP1K:
out << ".device 1k" << std::endl;
break;
- case ChipArgs::HX8K:
- case ChipArgs::LP8K:
+ case ArchArgs::HX8K:
+ case ArchArgs::LP8K:
out << ".device 8k" << std::endl;
break;
- case ChipArgs::UP5K:
+ case ArchArgs::UP5K:
out << ".device 5k" << std::endl;
break;
default:
assert(false);
}
// Set pips
- for (auto pip : chip.getPips()) {
- if (chip.pip_to_net[pip.index] != IdString()) {
+ for (auto pip : ctx->getPips()) {
+ if (ctx->pip_to_net[pip.index] != IdString()) {
const PipInfoPOD &pi = ci.pip_data[pip.index];
const SwitchInfoPOD &swi = bi.switches[pi.switch_index];
for (int i = 0; i < swi.num_bits; i++) {
@@ -151,7 +150,7 @@ void write_asc(const Design &design, std::ostream &out)
}
}
// Set logic cell config
- for (auto cell : design.cells) {
+ for (auto cell : ctx->cells) {
BelId bel = cell.second->bel;
if (bel == BelId()) {
std::cout << "Found unplaced cell " << cell.first
@@ -206,15 +205,15 @@ void write_asc(const Design &design, std::ostream &out)
assert(iez != -1);
bool input_en = false;
- if ((chip.wire_to_net[chip.getWireBelPin(bel, PIN_D_IN_0).index] !=
+ if ((ctx->wire_to_net[ctx->getWireBelPin(bel, PIN_D_IN_0).index] !=
IdString()) ||
- (chip.wire_to_net[chip.getWireBelPin(bel, PIN_D_IN_1).index] !=
+ (ctx->wire_to_net[ctx->getWireBelPin(bel, PIN_D_IN_1).index] !=
IdString())) {
input_en = true;
}
- if (chip.args.type == ChipArgs::LP1K ||
- chip.args.type == ChipArgs::HX1K) {
+ if (ctx->args.type == ArchArgs::LP1K ||
+ ctx->args.type == ArchArgs::HX1K) {
set_config(ti, config.at(iey).at(iex),
"IoCtrl.IE_" + std::to_string(iez), !input_en);
set_config(ti, config.at(iey).at(iex),
@@ -232,8 +231,8 @@ void write_asc(const Design &design, std::ostream &out)
int x = beli.x, y = beli.y;
const TileInfoPOD &ti_ramt = bi.tiles_nonrouting[TILE_RAMT];
const TileInfoPOD &ti_ramb = bi.tiles_nonrouting[TILE_RAMB];
- if (!(chip.args.type == ChipArgs::LP1K ||
- chip.args.type == ChipArgs::HX1K)) {
+ if (!(ctx->args.type == ArchArgs::LP1K ||
+ ctx->args.type == ArchArgs::HX1K)) {
set_config(ti_ramb, config.at(y).at(x), "RamConfig.PowerUp",
true);
}
@@ -258,9 +257,9 @@ void write_asc(const Design &design, std::ostream &out)
}
}
// Set config bits in unused IO and RAM
- for (auto bel : chip.getBels()) {
- if (chip.bel_to_cell[bel.index] == IdString() &&
- chip.getBelType(bel) == TYPE_SB_IO) {
+ for (auto bel : ctx->getBels()) {
+ if (ctx->bel_to_cell[bel.index] == IdString() &&
+ ctx->getBelType(bel) == TYPE_SB_IO) {
const TileInfoPOD &ti = bi.tiles_nonrouting[TILE_IO];
const BelInfoPOD &beli = ci.bel_data[bel.index];
int x = beli.x, y = beli.y, z = beli.z;
@@ -268,21 +267,21 @@ void write_asc(const Design &design, std::ostream &out)
int iex, iey, iez;
std::tie(iex, iey, iez) = ieren;
if (iez != -1) {
- if (chip.args.type == ChipArgs::LP1K ||
- chip.args.type == ChipArgs::HX1K) {
+ if (ctx->args.type == ArchArgs::LP1K ||
+ ctx->args.type == ArchArgs::HX1K) {
set_config(ti, config.at(iey).at(iex),
"IoCtrl.IE_" + std::to_string(iez), true);
set_config(ti, config.at(iey).at(iex),
"IoCtrl.REN_" + std::to_string(iez), false);
}
}
- } else if (chip.bel_to_cell[bel.index] == IdString() &&
- chip.getBelType(bel) == TYPE_ICESTORM_RAM) {
+ } else if (ctx->bel_to_cell[bel.index] == IdString() &&
+ ctx->getBelType(bel) == TYPE_ICESTORM_RAM) {
const BelInfoPOD &beli = ci.bel_data[bel.index];
int x = beli.x, y = beli.y;
const TileInfoPOD &ti = bi.tiles_nonrouting[TILE_RAMB];
- if ((chip.args.type == ChipArgs::LP1K ||
- chip.args.type == ChipArgs::HX1K)) {
+ if ((ctx->args.type == ArchArgs::LP1K ||
+ ctx->args.type == ArchArgs::HX1K)) {
set_config(ti, config.at(y).at(x), "RamConfig.PowerUp", true);
}
}
@@ -291,22 +290,22 @@ void write_asc(const Design &design, std::ostream &out)
// Set other config bits
for (int y = 0; y < ci.height; y++) {
for (int x = 0; x < ci.width; x++) {
- TileType tile = tile_at(chip, x, y);
+ TileType tile = tile_at(ctx, x, y);
const TileInfoPOD &ti = bi.tiles_nonrouting[tile];
// set all ColBufCtrl bits (FIXME)
bool setColBufCtrl = true;
- if (chip.args.type == ChipArgs::LP1K ||
- chip.args.type == ChipArgs::HX1K) {
+ if (ctx->args.type == ArchArgs::LP1K ||
+ ctx->args.type == ArchArgs::HX1K) {
if (tile == TILE_RAMB || tile == TILE_RAMT) {
setColBufCtrl = (y == 3 || y == 5 || y == 11 || y == 13);
} else {
setColBufCtrl = (y == 4 || y == 5 || y == 12 || y == 13);
}
- } else if (chip.args.type == ChipArgs::LP8K ||
- chip.args.type == ChipArgs::HX8K) {
+ } else if (ctx->args.type == ArchArgs::LP8K ||
+ ctx->args.type == ArchArgs::HX8K) {
setColBufCtrl = (y == 8 || y == 9 || y == 24 || y == 25);
- } else if (chip.args.type == ChipArgs::UP5K) {
+ } else if (ctx->args.type == ArchArgs::UP5K) {
if (tile == TILE_LOGIC) {
setColBufCtrl = (y == 4 || y == 5 || y == 14 || y == 15 ||
y == 26 || y == 27);
@@ -338,7 +337,7 @@ void write_asc(const Design &design, std::ostream &out)
// Write config out
for (int y = 0; y < ci.height; y++) {
for (int x = 0; x < ci.width; x++) {
- TileType tile = tile_at(chip, x, y);
+ TileType tile = tile_at(ctx, x, y);
if (tile == TILE_NONE)
continue;
switch (tile) {
@@ -372,7 +371,7 @@ void write_asc(const Design &design, std::ostream &out)
}
// Write RAM init data
- for (auto cell : design.cells) {
+ for (auto cell : ctx->cells) {
if (cell.second->bel != BelId()) {
if (cell.second->type == "ICESTORM_RAM") {
const BelInfoPOD &beli = ci.bel_data[cell.second->bel.index];
@@ -402,8 +401,8 @@ void write_asc(const Design &design, std::ostream &out)
// Write symbols
const bool write_symbols = 1;
- for (auto wire : chip.getWires()) {
- IdString net = chip.getWireNet(wire, false);
+ for (auto wire : ctx->getWires()) {
+ IdString net = ctx->getWireNet(wire, false);
if (net != IdString())
out << ".sym " << wire.index << " " << net << std::endl;
}
diff --git a/ice40/bitstream.h b/ice40/bitstream.h
index 0e2a4aa9..4dcb79bc 100644
--- a/ice40/bitstream.h
+++ b/ice40/bitstream.h
@@ -26,7 +26,7 @@
NEXTPNR_NAMESPACE_BEGIN
-void write_asc(const Design &design, std::ostream &out);
+void write_asc(const Context *ctx, std::ostream &out);
NEXTPNR_NAMESPACE_END
diff --git a/ice40/cells.cc b/ice40/cells.cc
index fb264051..16cbd68d 100644
--- a/ice40/cells.cc
+++ b/ice40/cells.cc
@@ -29,7 +29,7 @@ static void add_port(CellInfo *cell, IdString name, PortType dir)
cell->ports[name] = PortInfo{name, nullptr, dir};
}
-CellInfo *create_ice_cell(Design *design, IdString type, IdString name)
+CellInfo *create_ice_cell(Context *ctx, IdString type, IdString name)
{
static int auto_idx = 0;
CellInfo *new_cell = new CellInfo();
diff --git a/ice40/cells.h b/ice40/cells.h
index 45e81fd1..5bea420d 100644
--- a/ice40/cells.h
+++ b/ice40/cells.h
@@ -27,7 +27,7 @@ NEXTPNR_NAMESPACE_BEGIN
// Create a standard iCE40 cell and return it
// Name will be automatically assigned if not specified
-CellInfo *create_ice_cell(Design *design, IdString type,
+CellInfo *create_ice_cell(Context *ctx, IdString type,
IdString name = IdString());
// Return true if a cell is a LUT
diff --git a/ice40/main.cc b/ice40/main.cc
index c43bffa7..02dfe038 100644
--- a/ice40/main.cc
+++ b/ice40/main.cc
@@ -134,56 +134,56 @@ int main(int argc, char *argv[])
verbose = true;
}
- ChipArgs chipArgs;
+ ArchArgs chipArgs;
if (vm.count("lp384")) {
- if (chipArgs.type != ChipArgs::NONE)
+ if (chipArgs.type != ArchArgs::NONE)
goto help;
- chipArgs.type = ChipArgs::LP384;
+ chipArgs.type = ArchArgs::LP384;
chipArgs.package = "qn32";
}
if (vm.count("lp1k")) {
- if (chipArgs.type != ChipArgs::NONE)
+ if (chipArgs.type != ArchArgs::NONE)
goto help;
- chipArgs.type = ChipArgs::LP1K;
+ chipArgs.type = ArchArgs::LP1K;
chipArgs.package = "tq144";
}
if (vm.count("lp8k")) {
- if (chipArgs.type != ChipArgs::NONE)
+ if (chipArgs.type != ArchArgs::NONE)
goto help;
- chipArgs.type = ChipArgs::LP8K;
+ chipArgs.type = ArchArgs::LP8K;
chipArgs.package = "ct256";
}
if (vm.count("hx1k")) {
- if (chipArgs.type != ChipArgs::NONE)
+ if (chipArgs.type != ArchArgs::NONE)
goto help;
- chipArgs.type = ChipArgs::HX1K;
+ chipArgs.type = ArchArgs::HX1K;
chipArgs.package = "tq144";
}
if (vm.count("hx8k")) {
- if (chipArgs.type != ChipArgs::NONE)
+ if (chipArgs.type != ArchArgs::NONE)
goto help;
- chipArgs.type = ChipArgs::HX8K;
+ chipArgs.type = ArchArgs::HX8K;
chipArgs.package = "ct256";
}
if (vm.count("up5k")) {
- if (chipArgs.type != ChipArgs::NONE)
+ if (chipArgs.type != ArchArgs::NONE)
goto help;
- chipArgs.type = ChipArgs::UP5K;
+ chipArgs.type = ArchArgs::UP5K;
chipArgs.package = "sg48";
}
- if (chipArgs.type == ChipArgs::NONE) {
- chipArgs.type = ChipArgs::HX1K;
+ if (chipArgs.type == ArchArgs::NONE) {
+ chipArgs.type = ArchArgs::HX1K;
chipArgs.package = "tq144";
}
#ifdef ICE40_HX1K_ONLY
- if (chipArgs.type != ChipArgs::HX1K) {
+ if (chipArgs.type != ArchArgs::HX1K) {
std::cout << "This version of nextpnr-ice40 is built with HX1K-support "
"only.\n";
return 1;
@@ -193,21 +193,20 @@ int main(int argc, char *argv[])
if (vm.count("package"))
chipArgs.package = vm["package"].as<std::string>();
- Design design(chipArgs);
+ Context ctx(chipArgs);
init_python(argv[0]);
- python_export_global("design", design);
- python_export_global("chip", design.chip);
+ python_export_global("ctx", ctx);
if (vm.count("svg")) {
std::cout << "<svg xmlns=\"http://www.w3.org/2000/svg\" "
"xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n";
- for (auto bel : design.chip.getBels()) {
- std::cout << "<!-- " << design.chip.getBelName(bel) << " -->\n";
- for (auto &el : design.chip.getBelGraphics(bel))
+ for (auto bel : ctx.getBels()) {
+ std::cout << "<!-- " << ctx.getBelName(bel) << " -->\n";
+ for (auto &el : ctx.getBelGraphics(bel))
svg_dump_el(el);
}
std::cout << "<!-- Frame -->\n";
- for (auto &el : design.chip.getFrameGraphics())
+ for (auto &el : ctx.getFrameGraphics())
svg_dump_el(el);
std::cout << "</svg>\n";
}
@@ -216,15 +215,15 @@ int main(int argc, char *argv[])
std::string filename = vm["json"].as<std::string>();
std::istream *f = new std::ifstream(filename);
- parse_json_file(f, filename, &design);
+ parse_json_file(f, filename, &ctx);
if (vm.count("pcf")) {
std::ifstream pcf(vm["pcf"].as<std::string>());
- apply_pcf(&design, pcf);
+ apply_pcf(&ctx, pcf);
}
- pack_design(&design);
- print_utilisation(&design);
+ pack_design(&ctx);
+ print_utilisation(&ctx);
int seed = 1;
if (vm.count("seed")) {
@@ -234,15 +233,15 @@ int main(int argc, char *argv[])
}
if (!vm.count("pack-only")) {
- place_design_sa(&design, seed);
- route_design(&design, verbose);
+ place_design_sa(&ctx, seed);
+ route_design(&ctx, verbose);
}
}
if (vm.count("asc")) {
std::string filename = vm["asc"].as<std::string>();
std::ofstream f(filename);
- write_asc(design, f);
+ write_asc(&ctx, f);
}
if (vm.count("run")) {
@@ -254,7 +253,7 @@ int main(int argc, char *argv[])
if (vm.count("gui")) {
QApplication a(argc, argv);
- MainWindow w(&design);
+ MainWindow w(&ctx);
w.show();
rc = a.exec();
diff --git a/ice40/pack.cc b/ice40/pack.cc
index 3e852a91..7cdfc643 100644
--- a/ice40/pack.cc
+++ b/ice40/pack.cc
@@ -28,19 +28,19 @@
NEXTPNR_NAMESPACE_BEGIN
// Pack LUTs and LUT-FF pairs
-static void pack_lut_lutffs(Design *design)
+static void pack_lut_lutffs(Context *ctx)
{
log_info("Packing LUT-FFs..\n");
std::unordered_set<IdString> packed_cells;
std::vector<CellInfo *> new_cells;
- for (auto cell : design->cells) {
+ for (auto cell : ctx->cells) {
CellInfo *ci = cell.second;
log_info("cell '%s' is of type '%s'\n", ci->name.c_str(),
ci->type.c_str());
if (is_lut(ci)) {
- CellInfo *packed = create_ice_cell(design, "ICESTORM_LC",
- ci->name.str() + "_LC");
+ CellInfo *packed =
+ create_ice_cell(ctx, "ICESTORM_LC", ci->name.str() + "_LC");
std::copy(ci->attrs.begin(), ci->attrs.end(),
std::inserter(packed->attrs, packed->attrs.begin()));
packed_cells.insert(ci->name);
@@ -62,7 +62,7 @@ static void pack_lut_lutffs(Design *design)
} else {
lut_to_lc(ci, packed, false);
dff_to_lc(dff, packed, false);
- design->nets.erase(o->name);
+ ctx->nets.erase(o->name);
if (dff_bel != dff->attrs.end())
packed->attrs["BEL"] = dff_bel->second;
packed_cells.insert(dff->name);
@@ -77,25 +77,25 @@ static void pack_lut_lutffs(Design *design)
}
}
for (auto pcell : packed_cells) {
- design->cells.erase(pcell);
+ ctx->cells.erase(pcell);
}
for (auto ncell : new_cells) {
- design->cells[ncell->name] = ncell;
+ ctx->cells[ncell->name] = ncell;
}
}
// Pack FFs not packed as LUTFFs
-static void pack_nonlut_ffs(Design *design)
+static void pack_nonlut_ffs(Context *ctx)
{
log_info("Packing non-LUT FFs..\n");
std::unordered_set<IdString> packed_cells;
std::vector<CellInfo *> new_cells;
- for (auto cell : design->cells) {
+ for (auto cell : ctx->cells) {
CellInfo *ci = cell.second;
if (is_ff(ci)) {
- CellInfo *packed = create_ice_cell(design, "ICESTORM_LC",
+ CellInfo *packed = create_ice_cell(ctx, "ICESTORM_LC",
ci->name.str() + "_DFFLC");
std::copy(ci->attrs.begin(), ci->attrs.end(),
std::inserter(packed->attrs, packed->attrs.begin()));
@@ -107,25 +107,25 @@ static void pack_nonlut_ffs(Design *design)
}
}
for (auto pcell : packed_cells) {
- design->cells.erase(pcell);
+ ctx->cells.erase(pcell);
}
for (auto ncell : new_cells) {
- design->cells[ncell->name] = ncell;
+ ctx->cells[ncell->name] = ncell;
}
}
// "Pack" RAMs
-static void pack_ram(Design *design)
+static void pack_ram(Context *ctx)
{
log_info("Packing RAMs..\n");
std::unordered_set<IdString> packed_cells;
std::vector<CellInfo *> new_cells;
- for (auto cell : design->cells) {
+ for (auto cell : ctx->cells) {
CellInfo *ci = cell.second;
if (is_ram(ci)) {
- CellInfo *packed = create_ice_cell(design, "ICESTORM_RAM",
+ CellInfo *packed = create_ice_cell(ctx, "ICESTORM_RAM",
ci->name.str() + "_RAM");
packed_cells.insert(ci->name);
new_cells.push_back(packed);
@@ -153,10 +153,10 @@ static void pack_ram(Design *design)
}
for (auto pcell : packed_cells) {
- design->cells.erase(pcell);
+ ctx->cells.erase(pcell);
}
for (auto ncell : new_cells) {
- design->cells[ncell->name] = ncell;
+ ctx->cells[ncell->name] = ncell;
}
}
@@ -180,18 +180,18 @@ static void set_net_constant(NetInfo *orig, NetInfo *constnet, bool constval)
}
// Pack constants (simple implementation)
-static void pack_constants(Design *design)
+static void pack_constants(Context *ctx)
{
log_info("Packing constants..\n");
- CellInfo *gnd_cell = create_ice_cell(design, "ICESTORM_LC", "$PACKER_GND");
+ CellInfo *gnd_cell = create_ice_cell(ctx, "ICESTORM_LC", "$PACKER_GND");
gnd_cell->params["LUT_INIT"] = "0";
NetInfo *gnd_net = new NetInfo;
gnd_net->name = "$PACKER_GND_NET";
gnd_net->driver.cell = gnd_cell;
gnd_net->driver.port = "O";
- CellInfo *vcc_cell = create_ice_cell(design, "ICESTORM_LC", "$PACKER_VCC");
+ CellInfo *vcc_cell = create_ice_cell(ctx, "ICESTORM_LC", "$PACKER_VCC");
vcc_cell->params["LUT_INIT"] = "1";
NetInfo *vcc_net = new NetInfo;
vcc_net->name = "$PACKER_VCC_NET";
@@ -200,24 +200,24 @@ static void pack_constants(Design *design)
std::vector<IdString> dead_nets;
- for (auto net : design->nets) {
+ for (auto net : ctx->nets) {
NetInfo *ni = net.second;
if (ni->driver.cell != nullptr && ni->driver.cell->type == "GND") {
set_net_constant(ni, gnd_net, false);
- design->cells[gnd_cell->name] = gnd_cell;
- design->nets[gnd_net->name] = gnd_net;
+ ctx->cells[gnd_cell->name] = gnd_cell;
+ ctx->nets[gnd_net->name] = gnd_net;
dead_nets.push_back(net.first);
} else if (ni->driver.cell != nullptr &&
ni->driver.cell->type == "VCC") {
set_net_constant(ni, vcc_net, true);
- design->cells[vcc_cell->name] = vcc_cell;
- design->nets[vcc_net->name] = vcc_net;
+ ctx->cells[vcc_cell->name] = vcc_cell;
+ ctx->nets[vcc_net->name] = vcc_net;
dead_nets.push_back(net.first);
}
}
for (auto dn : dead_nets)
- design->nets.erase(dn);
+ ctx->nets.erase(dn);
}
static bool is_nextpnr_iob(CellInfo *cell)
@@ -227,14 +227,14 @@ static bool is_nextpnr_iob(CellInfo *cell)
}
// Pack IO buffers
-static void pack_io(Design *design)
+static void pack_io(Context *ctx)
{
std::unordered_set<IdString> packed_cells;
std::vector<CellInfo *> new_cells;
log_info("Packing IOs..\n");
- for (auto cell : design->cells) {
+ for (auto cell : ctx->cells) {
CellInfo *ci = cell.second;
if (is_nextpnr_iob(ci)) {
CellInfo *sb = nullptr;
@@ -254,12 +254,12 @@ static void pack_io(Design *design)
ci->name.c_str());
NetInfo *net = sb->ports.at("PACKAGE_PIN").net;
if (net != nullptr) {
- design->nets.erase(net->name);
+ ctx->nets.erase(net->name);
sb->ports.at("PACKAGE_PIN").net = nullptr;
}
} else {
// Create a SB_IO buffer
- sb = create_ice_cell(design, "SB_IO");
+ sb = create_ice_cell(ctx, "SB_IO");
nxio_to_sb(ci, sb);
new_cells.push_back(sb);
}
@@ -269,19 +269,19 @@ static void pack_io(Design *design)
}
}
for (auto pcell : packed_cells) {
- design->cells.erase(pcell);
+ ctx->cells.erase(pcell);
}
for (auto ncell : new_cells) {
- design->cells[ncell->name] = ncell;
+ ctx->cells[ncell->name] = ncell;
}
}
-static void insert_global(Design *design, NetInfo *net, bool is_reset,
+static void insert_global(Context *ctx, NetInfo *net, bool is_reset,
bool is_cen)
{
std::string glb_name = net->name.str() + std::string("_$glb_") +
(is_reset ? "sr" : (is_cen ? "ce" : "clk"));
- CellInfo *gb = create_ice_cell(design, "SB_GB", "$gbuf_" + glb_name);
+ CellInfo *gb = create_ice_cell(ctx, "SB_GB", "$gbuf_" + glb_name);
gb->ports["USER_SIGNAL_TO_GLOBAL_BUFFER"].net = net;
PortRef pr;
pr.cell = gb;
@@ -293,7 +293,7 @@ static void insert_global(Design *design, NetInfo *net, bool is_reset,
NetInfo *glbnet = new NetInfo();
glbnet->name = glb_name;
glbnet->driver = pr;
- design->nets[glbnet->name] = glbnet;
+ ctx->nets[glbnet->name] = glbnet;
gb->ports["GLOBAL_BUFFER_OUTPUT"].net = glbnet;
std::vector<PortRef> keep_users;
for (auto user : net->users) {
@@ -306,16 +306,16 @@ static void insert_global(Design *design, NetInfo *net, bool is_reset,
}
}
net->users = keep_users;
- design->cells[gb->name] = gb;
+ ctx->cells[gb->name] = gb;
}
// Simple global promoter (clock only)
-static void promote_globals(Design *design)
+static void promote_globals(Context *ctx)
{
log_info("Promoting globals..\n");
std::unordered_map<IdString, int> clock_count, reset_count, cen_count;
- for (auto net : design->nets) {
+ for (auto net : ctx->nets) {
NetInfo *ni = net.second;
if (ni->driver.cell != nullptr && !is_global_net(ni)) {
clock_count[net.first] = 0;
@@ -334,7 +334,7 @@ static void promote_globals(Design *design)
}
int prom_globals = 0, prom_resets = 0, prom_cens = 0;
int gbs_available = 8;
- for (auto cell : design->cells)
+ for (auto cell : ctx->cells)
if (is_gbuf(cell.second))
--gbs_available;
while (prom_globals < gbs_available) {
@@ -358,24 +358,24 @@ static void promote_globals(Design *design)
return a.second < b.second;
});
if (global_reset->second > global_clock->second && prom_resets < 4) {
- NetInfo *rstnet = design->nets[global_reset->first];
- insert_global(design, rstnet, true, false);
+ NetInfo *rstnet = ctx->nets[global_reset->first];
+ insert_global(ctx, rstnet, true, false);
++prom_globals;
++prom_resets;
clock_count.erase(rstnet->name);
reset_count.erase(rstnet->name);
cen_count.erase(rstnet->name);
} else if (global_cen->second > global_clock->second && prom_cens < 4) {
- NetInfo *cennet = design->nets[global_cen->first];
- insert_global(design, cennet, false, true);
+ NetInfo *cennet = ctx->nets[global_cen->first];
+ insert_global(ctx, cennet, false, true);
++prom_globals;
++prom_cens;
clock_count.erase(cennet->name);
reset_count.erase(cennet->name);
cen_count.erase(cennet->name);
} else if (global_clock->second != 0) {
- NetInfo *clknet = design->nets[global_clock->first];
- insert_global(design, clknet, false, false);
+ NetInfo *clknet = ctx->nets[global_clock->first];
+ insert_global(ctx, clknet, false, false);
++prom_globals;
clock_count.erase(clknet->name);
reset_count.erase(clknet->name);
@@ -387,14 +387,14 @@ static void promote_globals(Design *design)
}
// Main pack function
-void pack_design(Design *design)
+void pack_design(Context *ctx)
{
- pack_constants(design);
- promote_globals(design);
- pack_io(design);
- pack_lut_lutffs(design);
- pack_nonlut_ffs(design);
- pack_ram(design);
+ pack_constants(ctx);
+ promote_globals(ctx);
+ pack_io(ctx);
+ pack_lut_lutffs(ctx);
+ pack_nonlut_ffs(ctx);
+ pack_ram(ctx);
}
NEXTPNR_NAMESPACE_END
diff --git a/ice40/pack.h b/ice40/pack.h
index 60f22ef3..5495c986 100644
--- a/ice40/pack.h
+++ b/ice40/pack.h
@@ -25,7 +25,7 @@
NEXTPNR_NAMESPACE_BEGIN
-void pack_design(Design *design);
+void pack_design(Context *ctx);
NEXTPNR_NAMESPACE_END
diff --git a/ice40/pcf.cc b/ice40/pcf.cc
index 3bef962f..756aba4a 100644
--- a/ice40/pcf.cc
+++ b/ice40/pcf.cc
@@ -27,7 +27,7 @@ NEXTPNR_NAMESPACE_BEGIN
// Read a w
// Apply PCF constraints to a pre-packing design
-void apply_pcf(Design *design, std::istream &in)
+void apply_pcf(Context *ctx, std::istream &in)
{
if (!in)
log_error("failed to open PCF file");
@@ -50,16 +50,15 @@ void apply_pcf(Design *design, std::istream &in)
args_end++;
std::string cell = words.at(args_end);
std::string pin = words.at(args_end + 1);
- auto fnd_cell = design->cells.find(cell);
- if (fnd_cell == design->cells.end()) {
+ auto fnd_cell = ctx->cells.find(cell);
+ if (fnd_cell == ctx->cells.end()) {
log_warning("unmatched pcf constraint %s\n", cell.c_str());
} else {
- BelId pin_bel = design->chip.getPackagePinBel(pin);
+ BelId pin_bel = ctx->getPackagePinBel(pin);
if (pin_bel == BelId())
log_error("package does not have a pin named %s\n",
pin.c_str());
- fnd_cell->second->attrs["BEL"] =
- design->chip.getBelName(pin_bel).str();
+ fnd_cell->second->attrs["BEL"] = ctx->getBelName(pin_bel).str();
log_info("constrained '%s' to bel '%s'\n", cell.c_str(),
fnd_cell->second->attrs["BEL"].c_str());
}
diff --git a/ice40/pcf.h b/ice40/pcf.h
index ec2f4923..e0816075 100644
--- a/ice40/pcf.h
+++ b/ice40/pcf.h
@@ -27,7 +27,7 @@
NEXTPNR_NAMESPACE_BEGIN
// Apply PCF constraints to a pre-packing design
-void apply_pcf(Design *design, std::istream &in);
+void apply_pcf(Context *ctx, std::istream &in);
NEXTPNR_NAMESPACE_END
diff --git a/ice40/pybindings.cc b/ice40/pybindings.cc
index c161949b..6ce35583 100644
--- a/ice40/pybindings.cc
+++ b/ice40/pybindings.cc
@@ -25,16 +25,16 @@ NEXTPNR_NAMESPACE_BEGIN
void arch_wrap_python()
{
- class_<ChipArgs>("ChipArgs").def_readwrite("type", &ChipArgs::type);
+ class_<ArchArgs>("ArchArgs").def_readwrite("type", &ArchArgs::type);
- enum_<decltype(std::declval<ChipArgs>().type)>("iCE40Type")
- .value("NONE", ChipArgs::NONE)
- .value("LP384", ChipArgs::LP384)
- .value("LP1K", ChipArgs::LP1K)
- .value("LP8K", ChipArgs::LP8K)
- .value("HX1K", ChipArgs::HX1K)
- .value("HX8K", ChipArgs::HX8K)
- .value("UP5K", ChipArgs::UP5K)
+ enum_<decltype(std::declval<ArchArgs>().type)>("iCE40Type")
+ .value("NONE", ArchArgs::NONE)
+ .value("LP384", ArchArgs::LP384)
+ .value("LP1K", ArchArgs::LP1K)
+ .value("LP8K", ArchArgs::LP8K)
+ .value("HX1K", ArchArgs::HX1K)
+ .value("HX8K", ArchArgs::HX8K)
+ .value("UP5K", ArchArgs::UP5K)
.export_values();
class_<BelId>("BelId").def_readwrite("index", &BelId::index);
@@ -53,28 +53,28 @@ void arch_wrap_python()
;
#undef X
- class_<Chip>("Chip", init<ChipArgs>())
- .def("getBelByName", &Chip::getBelByName)
- .def("getWireByName", &Chip::getWireByName)
- .def("getBelName", &Chip::getBelName)
- .def("getWireName", &Chip::getWireName)
- .def("getBels", &Chip::getBels)
- .def("getBelType", &Chip::getBelType)
- .def("getWireBelPin", &Chip::getWireBelPin)
- .def("getBelPinUphill", &Chip::getBelPinUphill)
- .def("getBelPinsDownhill", &Chip::getBelPinsDownhill)
- .def("getWires", &Chip::getWires)
- .def("getPipByName", &Chip::getPipByName)
- .def("getPipName", &Chip::getPipName)
- .def("getPips", &Chip::getPips)
- .def("getPipSrcWire", &Chip::getPipSrcWire)
- .def("getPipDstWire", &Chip::getPipDstWire)
- .def("getPipDelay", &Chip::getPipDelay)
- .def("getPipsDownhill", &Chip::getPipsDownhill)
- .def("getPipsUphill", &Chip::getPipsUphill)
- .def("getWireAliases", &Chip::getWireAliases)
- .def("estimatePosition", &Chip::estimatePosition)
- .def("estimateDelay", &Chip::estimateDelay);
+ class_<Arch>("Arch", init<ArchArgs>())
+ .def("getBelByName", &Arch::getBelByName)
+ .def("getWireByName", &Arch::getWireByName)
+ .def("getBelName", &Arch::getBelName)
+ .def("getWireName", &Arch::getWireName)
+ .def("getBels", &Arch::getBels)
+ .def("getBelType", &Arch::getBelType)
+ .def("getWireBelPin", &Arch::getWireBelPin)
+ .def("getBelPinUphill", &Arch::getBelPinUphill)
+ .def("getBelPinsDownhill", &Arch::getBelPinsDownhill)
+ .def("getWires", &Arch::getWires)
+ .def("getPipByName", &Arch::getPipByName)
+ .def("getPipName", &Arch::getPipName)
+ .def("getPips", &Arch::getPips)
+ .def("getPipSrcWire", &Arch::getPipSrcWire)
+ .def("getPipDstWire", &Arch::getPipDstWire)
+ .def("getPipDelay", &Arch::getPipDelay)
+ .def("getPipsDownhill", &Arch::getPipsDownhill)
+ .def("getPipsUphill", &Arch::getPipsUphill)
+ .def("getWireAliases", &Arch::getWireAliases)
+ .def("estimatePosition", &Arch::estimatePosition)
+ .def("estimateDelay", &Arch::estimateDelay);
WRAP_RANGE(Bel);
WRAP_RANGE(BelPin);