aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ice40/bitstream.cc16
-rw-r--r--ice40/chip.cc138
-rw-r--r--ice40/chip.h183
-rw-r--r--ice40/chipdb.py513
4 files changed, 578 insertions, 272 deletions
diff --git a/ice40/bitstream.cc b/ice40/bitstream.cc
index 23cd6af1..4991df5e 100644
--- a/ice40/bitstream.cc
+++ b/ice40/bitstream.cc
@@ -25,14 +25,14 @@ NEXTPNR_NAMESPACE_BEGIN
inline TileType tile_at(const Chip &chip, int x, int y)
{
- return chip.chip_info.tile_grid[y * chip.chip_info.width + x];
+ return chip.chip_info->tile_grid[y * chip.chip_info->width + x];
}
const ConfigEntryPOD &find_config(const TileInfoPOD &tile,
const std::string &name)
{
for (int i = 0; i < tile.num_config_entries; i++) {
- if (std::string(tile.entries[i].name) == name) {
+ if (std::string(tile.entries[i].name.get()) == name) {
return tile.entries[i];
}
}
@@ -99,7 +99,7 @@ void write_asc(const Design &design, std::ostream &out)
{
const Chip &chip = design.chip;
// [y][x][row][col]
- const ChipInfoPOD &ci = chip.chip_info;
+ const ChipInfoPOD &ci = *chip.chip_info;
const BitstreamInfoPOD &bi = *ci.bits_info;
std::vector<std::vector<std::vector<std::vector<int8_t>>>> config;
config.resize(ci.height);
@@ -161,7 +161,7 @@ void write_asc(const Design &design, std::ostream &out)
const BelInfoPOD &beli = ci.bel_data[bel.index];
int x = beli.x, y = beli.y, z = beli.z;
if (cell.second->type == "ICESTORM_LC") {
- TileInfoPOD &ti = bi.tiles_nonrouting[TILE_LOGIC];
+ const TileInfoPOD &ti = bi.tiles_nonrouting[TILE_LOGIC];
unsigned lut_init = get_param_or_def(cell.second, "LUT_INIT");
bool neg_clk = get_param_or_def(cell.second, "NEG_CLK");
bool dff_enable = get_param_or_def(cell.second, "DFF_ENABLE");
@@ -188,7 +188,7 @@ void write_asc(const Design &design, std::ostream &out)
if (dff_enable)
set_config(ti, config.at(y).at(x), "NegClk", neg_clk);
} else if (cell.second->type == "SB_IO") {
- TileInfoPOD &ti = bi.tiles_nonrouting[TILE_IO];
+ const TileInfoPOD &ti = bi.tiles_nonrouting[TILE_IO];
unsigned pin_type = get_param_or_def(cell.second, "PIN_TYPE");
bool neg_trigger = get_param_or_def(cell.second, "NEG_TRIGGER");
bool pullup = get_param_or_def(cell.second, "PULLUP");
@@ -261,7 +261,7 @@ void write_asc(const Design &design, std::ostream &out)
for (auto bel : chip.getBels()) {
if (chip.bel_to_cell[bel.index] == IdString() &&
chip.getBelType(bel) == TYPE_SB_IO) {
- TileInfoPOD &ti = bi.tiles_nonrouting[TILE_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;
auto ieren = get_ieren(bi, x, y, z);
@@ -280,7 +280,7 @@ void write_asc(const Design &design, std::ostream &out)
chip.getBelType(bel) == TYPE_ICESTORM_RAM) {
const BelInfoPOD &beli = ci.bel_data[bel.index];
int x = beli.x, y = beli.y;
- TileInfoPOD &ti = bi.tiles_nonrouting[TILE_RAMB];
+ const TileInfoPOD &ti = bi.tiles_nonrouting[TILE_RAMB];
if ((chip.args.type == ChipArgs::LP1K ||
chip.args.type == ChipArgs::HX1K)) {
set_config(ti, config.at(y).at(x), "RamConfig.PowerUp", true);
@@ -292,7 +292,7 @@ void write_asc(const Design &design, std::ostream &out)
for (int y = 0; y < ci.height; y++) {
for (int x = 0; x < ci.width; x++) {
TileType tile = tile_at(chip, x, y);
- TileInfoPOD &ti = bi.tiles_nonrouting[tile];
+ const TileInfoPOD &ti = bi.tiles_nonrouting[tile];
// set all ColBufCtrl bits (FIXME)
bool setColBufCtrl = true;
diff --git a/ice40/chip.cc b/ice40/chip.cc
index 1255dfc8..d92d61dd 100644
--- a/ice40/chip.cc
+++ b/ice40/chip.cc
@@ -82,38 +82,43 @@ Chip::Chip(ChipArgs args) : args(args)
{
#ifdef ICE40_HX1K_ONLY
if (args.type == ChipArgs::HX1K) {
- chip_info = chip_info_1k;
+ chip_info =
+ reinterpret_cast<RelPtr<ChipInfoPOD> *>(chipdb_blob_1k)->get();
} else {
log_error("Unsupported iCE40 chip type.\n");
}
#else
if (args.type == ChipArgs::LP384) {
- chip_info = chip_info_384;
+ chip_info =
+ reinterpret_cast<RelPtr<ChipInfoPOD> *>(chipdb_blob_384)->get();
} else if (args.type == ChipArgs::LP1K || args.type == ChipArgs::HX1K) {
- chip_info = chip_info_1k;
+ chip_info =
+ reinterpret_cast<RelPtr<ChipInfoPOD> *>(chipdb_blob_1k)->get();
} else if (args.type == ChipArgs::UP5K) {
- chip_info = chip_info_5k;
+ chip_info =
+ reinterpret_cast<RelPtr<ChipInfoPOD> *>(chipdb_blob_5k)->get();
} else if (args.type == ChipArgs::LP8K || args.type == ChipArgs::HX8K) {
- chip_info = chip_info_8k;
+ chip_info =
+ reinterpret_cast<RelPtr<ChipInfoPOD> *>(chipdb_blob_8k)->get();
} else {
log_error("Unsupported iCE40 chip type.\n");
}
#endif
package_info = nullptr;
- for (int i = 0; i < chip_info.num_packages; i++) {
- if (chip_info.packages_data[i].name == args.package) {
- package_info = &(chip_info.packages_data[i]);
+ for (int i = 0; i < chip_info->num_packages; i++) {
+ if (chip_info->packages_data[i].name.get() == args.package) {
+ package_info = &(chip_info->packages_data[i]);
break;
}
}
if (package_info == nullptr)
log_error("Unsupported package '%s'.\n", args.package.c_str());
- bel_to_cell.resize(chip_info.num_bels);
- wire_to_net.resize(chip_info.num_wires);
- pip_to_net.resize(chip_info.num_pips);
- switches_locked.resize(chip_info.num_switches);
+ bel_to_cell.resize(chip_info->num_bels);
+ wire_to_net.resize(chip_info->num_wires);
+ pip_to_net.resize(chip_info->num_pips);
+ switches_locked.resize(chip_info->num_switches);
}
// -----------------------------------------------------------------------
@@ -152,8 +157,8 @@ BelId Chip::getBelByName(IdString name) const
BelId ret;
if (bel_by_name.empty()) {
- for (int i = 0; i < chip_info.num_bels; i++)
- bel_by_name[chip_info.bel_data[i].name] = i;
+ for (int i = 0; i < chip_info->num_bels; i++)
+ bel_by_name[chip_info->bel_data[i].name.get()] = i;
}
auto it = bel_by_name.find(name);
@@ -168,16 +173,16 @@ BelRange Chip::getBelsAtSameTile(BelId bel) const
BelRange br;
assert(bel != BelId());
// This requires Bels at the same tile are consecutive
- int x = chip_info.bel_data[bel.index].x;
- int y = chip_info.bel_data[bel.index].y;
+ int x = chip_info->bel_data[bel.index].x;
+ int y = chip_info->bel_data[bel.index].y;
int start = bel.index, end = bel.index;
- while (start >= 0 && chip_info.bel_data[start].x == x &&
- chip_info.bel_data[start].y == y)
+ while (start >= 0 && chip_info->bel_data[start].x == x &&
+ chip_info->bel_data[start].y == y)
start--;
start++;
br.b.cursor = start;
- while (end < chip_info.num_bels && chip_info.bel_data[end].x == x &&
- chip_info.bel_data[end].y == y)
+ while (end < chip_info->num_bels && chip_info->bel_data[end].x == x &&
+ chip_info->bel_data[end].y == y)
end++;
br.e.cursor = end;
return br;
@@ -189,8 +194,9 @@ WireId Chip::getWireBelPin(BelId bel, PortPin pin) const
assert(bel != BelId());
- int num_bel_wires = chip_info.bel_data[bel.index].num_bel_wires;
- BelWirePOD *bel_wires = chip_info.bel_data[bel.index].bel_wires;
+ int num_bel_wires = chip_info->bel_data[bel.index].num_bel_wires;
+ const BelWirePOD *bel_wires =
+ chip_info->bel_data[bel.index].bel_wires.get();
for (int i = 0; i < num_bel_wires; i++)
if (bel_wires[i].port == pin) {
@@ -208,8 +214,8 @@ WireId Chip::getWireByName(IdString name) const
WireId ret;
if (wire_by_name.empty()) {
- for (int i = 0; i < chip_info.num_wires; i++)
- wire_by_name[chip_info.wire_data[i].name] = i;
+ for (int i = 0; i < chip_info->num_wires; i++)
+ wire_by_name[chip_info->wire_data[i].name.get()] = i;
}
auto it = wire_by_name.find(name);
@@ -226,7 +232,7 @@ PipId Chip::getPipByName(IdString name) const
PipId ret;
if (pip_by_name.empty()) {
- for (int i = 0; i < chip_info.num_pips; i++) {
+ for (int i = 0; i < chip_info->num_pips; i++) {
PipId pip;
pip.index = i;
pip_by_name[getPipName(pip)] = i;
@@ -244,15 +250,15 @@ IdString Chip::getPipName(PipId pip) const
{
assert(pip != PipId());
- int x = chip_info.pip_data[pip.index].x;
- int y = chip_info.pip_data[pip.index].y;
+ int x = chip_info->pip_data[pip.index].x;
+ int y = chip_info->pip_data[pip.index].y;
std::string src_name =
- chip_info.wire_data[chip_info.pip_data[pip.index].src].name;
+ chip_info->wire_data[chip_info->pip_data[pip.index].src].name.get();
std::replace(src_name.begin(), src_name.end(), '/', '.');
std::string dst_name =
- chip_info.wire_data[chip_info.pip_data[pip.index].dst].name;
+ chip_info->wire_data[chip_info->pip_data[pip.index].dst].name.get();
std::replace(dst_name.begin(), dst_name.end(), '/', '.');
return "X" + std::to_string(x) + "/Y" + std::to_string(y) + "/" + src_name +
@@ -264,7 +270,7 @@ IdString Chip::getPipName(PipId pip) const
BelId Chip::getPackagePinBel(const std::string &pin) const
{
for (int i = 0; i < package_info->num_pins; i++) {
- if (package_info->pins[i].name == pin) {
+ if (package_info->pins[i].name.get() == pin) {
BelId id;
id.index = package_info->pins[i].bel_index;
return id;
@@ -277,7 +283,7 @@ std::string Chip::getBelPackagePin(BelId bel) const
{
for (int i = 0; i < package_info->num_pins; i++) {
if (package_info->pins[i].bel_index == bel.index) {
- return std::string(package_info->pins[i].name);
+ return std::string(package_info->pins[i].name.get());
}
}
return "";
@@ -287,21 +293,21 @@ std::string Chip::getBelPackagePin(BelId bel) const
bool Chip::estimatePosition(BelId bel, int &x, int &y) const
{
assert(bel != BelId());
- x = chip_info.bel_data[bel.index].x;
- y = chip_info.bel_data[bel.index].y;
+ x = chip_info->bel_data[bel.index].x;
+ y = chip_info->bel_data[bel.index].y;
- return chip_info.bel_data[bel.index].type != TYPE_SB_GB;
+ return chip_info->bel_data[bel.index].type != TYPE_SB_GB;
}
delay_t Chip::estimateDelay(WireId src, WireId dst) const
{
assert(src != WireId());
- delay_t x1 = chip_info.wire_data[src.index].x;
- delay_t y1 = chip_info.wire_data[src.index].y;
+ delay_t x1 = chip_info->wire_data[src.index].x;
+ delay_t y1 = chip_info->wire_data[src.index].y;
assert(dst != WireId());
- delay_t x2 = chip_info.wire_data[dst.index].x;
- delay_t y2 = chip_info.wire_data[dst.index].y;
+ delay_t x2 = chip_info->wire_data[dst.index].x;
+ delay_t y2 = chip_info->wire_data[dst.index].y;
return fabsf(x1 - x2) + fabsf(y1 - y2);
}
@@ -312,8 +318,8 @@ std::vector<GraphicElement> Chip::getFrameGraphics() const
{
std::vector<GraphicElement> ret;
- for (int x = 0; x <= chip_info.width; x++)
- for (int y = 0; y <= chip_info.height; y++) {
+ for (int x = 0; x <= chip_info->width; x++)
+ for (int y = 0; y <= chip_info->height; y++) {
GraphicElement el;
el.type = GraphicElement::G_LINE;
el.x1 = x - 0.05, el.x2 = x + 0.05, el.y1 = y, el.y2 = y, el.z = 0;
@@ -334,44 +340,44 @@ std::vector<GraphicElement> Chip::getBelGraphics(BelId bel) const
if (bel_type == TYPE_ICESTORM_LC) {
GraphicElement el;
el.type = GraphicElement::G_BOX;
- el.x1 = chip_info.bel_data[bel.index].x + 0.1;
- el.x2 = chip_info.bel_data[bel.index].x + 0.9;
- el.y1 = chip_info.bel_data[bel.index].y + 0.10 +
- (chip_info.bel_data[bel.index].z) * (0.8 / 8);
- el.y2 = chip_info.bel_data[bel.index].y + 0.18 +
- (chip_info.bel_data[bel.index].z) * (0.8 / 8);
+ el.x1 = chip_info->bel_data[bel.index].x + 0.1;
+ el.x2 = chip_info->bel_data[bel.index].x + 0.9;
+ el.y1 = chip_info->bel_data[bel.index].y + 0.10 +
+ (chip_info->bel_data[bel.index].z) * (0.8 / 8);
+ el.y2 = chip_info->bel_data[bel.index].y + 0.18 +
+ (chip_info->bel_data[bel.index].z) * (0.8 / 8);
el.z = 0;
ret.push_back(el);
}
if (bel_type == TYPE_SB_IO) {
- if (chip_info.bel_data[bel.index].x == 0 ||
- chip_info.bel_data[bel.index].x == chip_info.width - 1) {
+ if (chip_info->bel_data[bel.index].x == 0 ||
+ chip_info->bel_data[bel.index].x == chip_info->width - 1) {
GraphicElement el;
el.type = GraphicElement::G_BOX;
- el.x1 = chip_info.bel_data[bel.index].x + 0.1;
- el.x2 = chip_info.bel_data[bel.index].x + 0.9;
- if (chip_info.bel_data[bel.index].z == 0) {
- el.y1 = chip_info.bel_data[bel.index].y + 0.10;
- el.y2 = chip_info.bel_data[bel.index].y + 0.45;
+ el.x1 = chip_info->bel_data[bel.index].x + 0.1;
+ el.x2 = chip_info->bel_data[bel.index].x + 0.9;
+ if (chip_info->bel_data[bel.index].z == 0) {
+ el.y1 = chip_info->bel_data[bel.index].y + 0.10;
+ el.y2 = chip_info->bel_data[bel.index].y + 0.45;
} else {
- el.y1 = chip_info.bel_data[bel.index].y + 0.55;
- el.y2 = chip_info.bel_data[bel.index].y + 0.90;
+ el.y1 = chip_info->bel_data[bel.index].y + 0.55;
+ el.y2 = chip_info->bel_data[bel.index].y + 0.90;
}
el.z = 0;
ret.push_back(el);
} else {
GraphicElement el;
el.type = GraphicElement::G_BOX;
- if (chip_info.bel_data[bel.index].z == 0) {
- el.x1 = chip_info.bel_data[bel.index].x + 0.10;
- el.x2 = chip_info.bel_data[bel.index].x + 0.45;
+ if (chip_info->bel_data[bel.index].z == 0) {
+ el.x1 = chip_info->bel_data[bel.index].x + 0.10;
+ el.x2 = chip_info->bel_data[bel.index].x + 0.45;
} else {
- el.x1 = chip_info.bel_data[bel.index].x + 0.55;
- el.x2 = chip_info.bel_data[bel.index].x + 0.90;
+ el.x1 = chip_info->bel_data[bel.index].x + 0.55;
+ el.x2 = chip_info->bel_data[bel.index].x + 0.90;
}
- el.y1 = chip_info.bel_data[bel.index].y + 0.1;
- el.y2 = chip_info.bel_data[bel.index].y + 0.9;
+ el.y1 = chip_info->bel_data[bel.index].y + 0.1;
+ el.y2 = chip_info->bel_data[bel.index].y + 0.9;
el.z = 0;
ret.push_back(el);
}
@@ -380,10 +386,10 @@ std::vector<GraphicElement> Chip::getBelGraphics(BelId bel) const
if (bel_type == TYPE_ICESTORM_RAM) {
GraphicElement el;
el.type = GraphicElement::G_BOX;
- el.x1 = chip_info.bel_data[bel.index].x + 0.1;
- el.x2 = chip_info.bel_data[bel.index].x + 0.9;
- el.y1 = chip_info.bel_data[bel.index].y + 0.1;
- el.y2 = chip_info.bel_data[bel.index].y + 1.9;
+ el.x1 = chip_info->bel_data[bel.index].x + 0.1;
+ el.x2 = chip_info->bel_data[bel.index].x + 0.9;
+ el.y1 = chip_info->bel_data[bel.index].y + 0.1;
+ el.y2 = chip_info->bel_data[bel.index].y + 1.9;
el.z = 0;
ret.push_back(el);
}
diff --git a/ice40/chip.h b/ice40/chip.h
index 5eeca5e9..e6bb0a08 100644
--- a/ice40/chip.h
+++ b/ice40/chip.h
@@ -72,31 +72,35 @@ PortPin portPinFromId(IdString id);
// -----------------------------------------------------------------------
-#if 0
-template <typename T>
-struct RelPtr {
- int offset;
+/**** Everything in this section must be kept in sync with chipdb.py ****/
- // RelPtr(T *ptr) : offset(reinterpret_cast<const char*>(ptr) -
- // reinterpret_cast<const char*>(this)) {}
+template <typename T> struct RelPtr
+{
+ int32_t offset;
- T&operator*() {
- return *reinterpret_cast<T*>(reinterpret_cast<char*>(this) + offset);
- }
+ // void set(const T *ptr) {
+ // offset = reinterpret_cast<const char*>(ptr) -
+ // reinterpret_cast<const char*>(this);
+ // }
- T*operator->() {
- return reinterpret_cast<T*>(reinterpret_cast<char*>(this) + offset);
+ const T *get() const
+ {
+ return reinterpret_cast<const T *>(
+ reinterpret_cast<const char *>(this) + offset);
}
+
+ const T &operator[](size_t index) const { return get()[index]; }
+
+ const T &operator*() const { return *(get()); }
+
+ const T *operator->() const { return get(); }
};
-#else
-template <typename T> using RelPtr = T *;
-#endif
struct BelWirePOD
{
int32_t wire_index;
PortPin port;
-};
+} __attribute__((packed));
struct BelInfoPOD
{
@@ -105,13 +109,14 @@ struct BelInfoPOD
int32_t num_bel_wires;
RelPtr<BelWirePOD> bel_wires;
int8_t x, y, z;
-};
+ int8_t padding_0;
+} __attribute__((packed));
struct BelPortPOD
{
int32_t bel_index;
PortPin port;
-};
+} __attribute__((packed));
struct PipInfoPOD
{
@@ -120,7 +125,7 @@ struct PipInfoPOD
int8_t x, y;
int16_t switch_mask;
int32_t switch_index;
-};
+} __attribute__((packed));
struct WireInfoPOD
{
@@ -132,23 +137,23 @@ struct WireInfoPOD
BelPortPOD bel_uphill;
RelPtr<BelPortPOD> bels_downhill;
- int8_t x, y;
-};
+ int16_t x, y;
+} __attribute__((packed));
struct PackagePinPOD
{
- const char *name;
+ RelPtr<char> name;
int32_t bel_index;
-};
+} __attribute__((packed));
struct PackageInfoPOD
{
- const char *name;
- int num_pins;
- PackagePinPOD *pins;
-};
+ RelPtr<char> name;
+ int32_t num_pins;
+ RelPtr<PackagePinPOD> pins;
+} __attribute__((packed));
-enum TileType
+enum TileType : uint32_t
{
TILE_NONE = 0,
TILE_LOGIC = 1,
@@ -160,62 +165,64 @@ enum TileType
struct ConfigBitPOD
{
int8_t row, col;
-};
+} __attribute__((packed));
struct ConfigEntryPOD
{
- const char *name;
- int num_bits;
- ConfigBitPOD *bits;
-};
+ RelPtr<char> name;
+ int32_t num_bits;
+ RelPtr<ConfigBitPOD> bits;
+} __attribute__((packed));
struct TileInfoPOD
{
int8_t cols, rows;
- int num_config_entries;
- ConfigEntryPOD *entries;
-};
+ int16_t num_config_entries;
+ RelPtr<ConfigEntryPOD> entries;
+} __attribute__((packed));
static const int max_switch_bits = 5;
struct SwitchInfoPOD
{
+ int32_t num_bits;
int8_t x, y;
- int num_bits;
ConfigBitPOD cbits[max_switch_bits];
-};
+} __attribute__((packed));
struct IerenInfoPOD
{
int8_t iox, ioy, ioz;
int8_t ierx, iery, ierz;
-};
+} __attribute__((packed));
struct BitstreamInfoPOD
{
- int num_switches, num_ierens;
- TileInfoPOD *tiles_nonrouting;
- SwitchInfoPOD *switches;
- IerenInfoPOD *ierens;
-};
+ int32_t num_switches, num_ierens;
+ RelPtr<TileInfoPOD> tiles_nonrouting;
+ RelPtr<SwitchInfoPOD> switches;
+ RelPtr<IerenInfoPOD> ierens;
+} __attribute__((packed));
struct ChipInfoPOD
{
- int width, height;
- int num_bels, num_wires, num_pips;
- int num_switches, num_packages;
- BelInfoPOD *bel_data;
- WireInfoPOD *wire_data;
- PipInfoPOD *pip_data;
- TileType *tile_grid;
- BitstreamInfoPOD *bits_info;
- PackageInfoPOD *packages_data;
-};
+ int32_t width, height;
+ int32_t num_bels, num_wires, num_pips;
+ int32_t num_switches, num_packages;
+ RelPtr<BelInfoPOD> bel_data;
+ RelPtr<WireInfoPOD> wire_data;
+ RelPtr<PipInfoPOD> pip_data;
+ RelPtr<TileType> tile_grid;
+ RelPtr<BitstreamInfoPOD> bits_info;
+ RelPtr<PackageInfoPOD> packages_data;
+} __attribute__((packed));
+
+extern uint8_t chipdb_blob_384[];
+extern uint8_t chipdb_blob_1k[];
+extern uint8_t chipdb_blob_5k[];
+extern uint8_t chipdb_blob_8k[];
-extern ChipInfoPOD chip_info_384;
-extern ChipInfoPOD chip_info_1k;
-extern ChipInfoPOD chip_info_5k;
-extern ChipInfoPOD chip_info_8k;
+/************************ End of chipdb section. ************************/
// -----------------------------------------------------------------------
@@ -329,7 +336,7 @@ struct BelRange
struct BelPinIterator
{
- BelPortPOD *ptr = nullptr;
+ const BelPortPOD *ptr = nullptr;
void operator++() { ptr++; }
bool operator!=(const BelPinIterator &other) const
@@ -411,7 +418,7 @@ struct AllPipRange
struct PipIterator
{
- int *cursor = nullptr;
+ const int *cursor = nullptr;
void operator++() { cursor++; }
bool operator!=(const PipIterator &other) const
@@ -453,8 +460,8 @@ struct ChipArgs
struct Chip
{
- ChipInfoPOD chip_info;
- PackageInfoPOD *package_info;
+ const ChipInfoPOD *chip_info;
+ const PackageInfoPOD *package_info;
mutable std::unordered_map<IdString, int> bel_by_name;
mutable std::unordered_map<IdString, int> wire_by_name;
@@ -476,7 +483,7 @@ struct Chip
IdString getBelName(BelId bel) const
{
assert(bel != BelId());
- return chip_info.bel_data[bel.index].name;
+ return chip_info->bel_data[bel.index].name.get();
}
void bindBel(BelId bel, IdString cell)
@@ -509,7 +516,7 @@ struct Chip
{
BelRange range;
range.b.cursor = 0;
- range.e.cursor = chip_info.num_bels;
+ range.e.cursor = chip_info->num_bels;
return range;
}
@@ -532,7 +539,7 @@ struct Chip
BelType getBelType(BelId bel) const
{
assert(bel != BelId());
- return chip_info.bel_data[bel.index].type;
+ return chip_info->bel_data[bel.index].type;
}
WireId getWireBelPin(BelId bel, PortPin pin) const;
@@ -542,10 +549,10 @@ struct Chip
BelPin ret;
assert(wire != WireId());
- if (chip_info.wire_data[wire.index].bel_uphill.bel_index >= 0) {
+ if (chip_info->wire_data[wire.index].bel_uphill.bel_index >= 0) {
ret.bel.index =
- chip_info.wire_data[wire.index].bel_uphill.bel_index;
- ret.pin = chip_info.wire_data[wire.index].bel_uphill.port;
+ chip_info->wire_data[wire.index].bel_uphill.bel_index;
+ ret.pin = chip_info->wire_data[wire.index].bel_uphill.port;
}
return ret;
@@ -555,9 +562,9 @@ struct Chip
{
BelPinRange range;
assert(wire != WireId());
- range.b.ptr = chip_info.wire_data[wire.index].bels_downhill;
- range.e.ptr =
- range.b.ptr + chip_info.wire_data[wire.index].num_bels_downhill;
+ range.b.ptr = chip_info->wire_data[wire.index].bels_downhill.get();
+ range.e.ptr = range.b.ptr +
+ chip_info->wire_data[wire.index].num_bels_downhill;
return range;
}
@@ -568,7 +575,7 @@ struct Chip
IdString getWireName(WireId wire) const
{
assert(wire != WireId());
- return chip_info.wire_data[wire.index].name;
+ return chip_info->wire_data[wire.index].name.get();
}
void bindWire(WireId wire, IdString net)
@@ -601,7 +608,7 @@ struct Chip
{
WireRange range;
range.b.cursor = 0;
- range.e.cursor = chip_info.num_wires;
+ range.e.cursor = chip_info->num_wires;
return range;
}
@@ -614,20 +621,20 @@ struct Chip
{
assert(pip != PipId());
assert(pip_to_net[pip.index] == IdString());
- assert(switches_locked[chip_info.pip_data[pip.index].switch_index] ==
+ assert(switches_locked[chip_info->pip_data[pip.index].switch_index] ==
IdString());
pip_to_net[pip.index] = net;
- switches_locked[chip_info.pip_data[pip.index].switch_index] = net;
+ switches_locked[chip_info->pip_data[pip.index].switch_index] = net;
}
void unbindPip(PipId pip)
{
assert(pip != PipId());
assert(pip_to_net[pip.index] != IdString());
- assert(switches_locked[chip_info.pip_data[pip.index].switch_index] !=
+ assert(switches_locked[chip_info->pip_data[pip.index].switch_index] !=
IdString());
pip_to_net[pip.index] = IdString();
- switches_locked[chip_info.pip_data[pip.index].switch_index] =
+ switches_locked[chip_info->pip_data[pip.index].switch_index] =
IdString();
}
@@ -635,11 +642,11 @@ struct Chip
{
assert(pip != PipId());
if (args.type == ChipArgs::UP5K) {
- int x = chip_info.pip_data[pip.index].x;
- if (x == 0 || x == (chip_info.width - 1))
+ int x = chip_info->pip_data[pip.index].x;
+ if (x == 0 || x == (chip_info->width - 1))
return false;
}
- return switches_locked[chip_info.pip_data[pip.index].switch_index] ==
+ return switches_locked[chip_info->pip_data[pip.index].switch_index] ==
IdString();
}
@@ -647,7 +654,7 @@ struct Chip
{
assert(pip != PipId());
if (conflicting)
- return switches_locked[chip_info.pip_data[pip.index].switch_index];
+ return switches_locked[chip_info->pip_data[pip.index].switch_index];
return pip_to_net[pip.index];
}
@@ -655,7 +662,7 @@ struct Chip
{
AllPipRange range;
range.b.cursor = 0;
- range.e.cursor = chip_info.num_pips;
+ range.e.cursor = chip_info->num_pips;
return range;
}
@@ -663,7 +670,7 @@ struct Chip
{
WireId wire;
assert(pip != PipId());
- wire.index = chip_info.pip_data[pip.index].src;
+ wire.index = chip_info->pip_data[pip.index].src;
return wire;
}
@@ -671,7 +678,7 @@ struct Chip
{
WireId wire;
assert(pip != PipId());
- wire.index = chip_info.pip_data[pip.index].dst;
+ wire.index = chip_info->pip_data[pip.index].dst;
return wire;
}
@@ -679,7 +686,7 @@ struct Chip
{
DelayInfo delay;
assert(pip != PipId());
- delay.delay = chip_info.pip_data[pip.index].delay;
+ delay.delay = chip_info->pip_data[pip.index].delay;
return delay;
}
@@ -687,9 +694,9 @@ struct Chip
{
PipRange range;
assert(wire != WireId());
- range.b.cursor = chip_info.wire_data[wire.index].pips_downhill;
+ 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.b.cursor + chip_info->wire_data[wire.index].num_downhill;
return range;
}
@@ -697,9 +704,9 @@ struct Chip
{
PipRange range;
assert(wire != WireId());
- range.b.cursor = chip_info.wire_data[wire.index].pips_uphill;
+ 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.b.cursor + chip_info->wire_data[wire.index].num_uphill;
return range;
}
diff --git a/ice40/chipdb.py b/ice40/chipdb.py
index f8fe8b5d..eccda6f1 100644
--- a/ice40/chipdb.py
+++ b/ice40/chipdb.py
@@ -4,6 +4,9 @@ import sys
import re
import textwrap
+endianness = "le"
+compact_output = True
+
dev_name = None
dev_width = None
dev_height = None
@@ -39,6 +42,32 @@ tile_bits = [[] for _ in range(num_tile_types)]
cbit_re = re.compile(r'B(\d+)\[(\d+)\]')
+portpins = dict()
+beltypes = dict()
+tiletypes = dict()
+
+with open("ice40/portpins.inc") as f:
+ for line in f:
+ line = line.replace("(", " ")
+ line = line.replace(")", " ")
+ line = line.split()
+ if len(line) == 0:
+ continue
+ assert len(line) == 2
+ assert line[0] == "X"
+ idx = len(portpins) + 1
+ portpins[line[1]] = idx
+
+beltypes["ICESTORM_LC"] = 1
+beltypes["ICESTORM_RAM"] = 2
+beltypes["SB_IO"] = 3
+beltypes["SB_GB"] = 4
+
+tiletypes["NONE"] = 0
+tiletypes["LOGIC"] = 1
+tiletypes["IO"] = 2
+tiletypes["RAMB"] = 3
+tiletypes["RAMT"] = 4
def maj_wire_name(name):
if re.match(r"lutff_\d/(in|out)", name[2]):
@@ -344,83 +373,284 @@ elif dev_name == "384":
add_bel_gb( 3, 0, 5)
add_bel_gb( 3, 9, 4)
-print('#include "nextpnr.h"')
-print('namespace {')
-print('USING_NEXTPNR_NAMESPACE')
+class BinaryBlobAssembler:
+ def __init__(self, cname, endianness, ctype = "unsigned char"):
+ assert endianness in ["le", "be"]
+ self.cname = cname
+ self.ctype = ctype
+ self.endianness = endianness
+ self.finalized = False
+ self.data = bytearray()
+ self.comments = dict()
+ self.labels = dict()
+ self.exports = set()
+ self.labels_byaddr = dict()
+ self.ltypes_byaddr = dict()
+ self.strings = dict()
+ self.refs = dict()
+
+ def l(self, name, ltype = None, export = False):
+ assert not self.finalized
+ assert name not in self.labels
+ assert len(self.data) not in self.labels_byaddr
+ self.labels[name] = len(self.data)
+ if ltype is not None:
+ self.ltypes_byaddr[len(self.data)] = ltype
+ self.labels_byaddr[len(self.data)] = name
+ if export:
+ assert ltype is not None
+ self.exports.add(len(self.data))
+
+ def r(self, name, comment):
+ assert not self.finalized
+ assert len(self.data) % 4 == 0
+ assert len(self.data) not in self.refs
+ if name is not None:
+ self.refs[len(self.data)] = (name, comment)
+ self.data.append(0)
+ self.data.append(0)
+ self.data.append(0)
+ self.data.append(0)
+ if (name is None) and (comment is not None):
+ self.comments[len(self.data)] = comment + " (null reference)"
+
+ def s(self, s, comment):
+ assert not self.finalized
+ if s not in self.strings:
+ index = len(self.strings)
+ self.strings[s] = index
+ else:
+ index = self.strings[s]
+ self.r("str%d" % index, '%s: "%s"' % (comment, s))
+
+ def u8(self, v, comment):
+ assert not self.finalized
+ self.data.append(v)
+ if comment is not None:
+ self.comments[len(self.data)] = comment
+
+ def u16(self, v, comment):
+ assert not self.finalized
+ assert len(self.data) % 2 == 0
+ if self.endianness == "le":
+ self.data.append(v & 255)
+ self.data.append((v >> 8) & 255)
+ elif self.endianness == "be":
+ self.data.append((v >> 8) & 255)
+ self.data.append(v & 255)
+ else:
+ assert 0
+ if comment is not None:
+ self.comments[len(self.data)] = comment
+
+ def u32(self, v, comment):
+ assert not self.finalized
+ assert len(self.data) % 4 == 0
+ if self.endianness == "le":
+ self.data.append(v & 255)
+ self.data.append((v >> 8) & 255)
+ self.data.append((v >> 16) & 255)
+ self.data.append((v >> 24) & 255)
+ elif self.endianness == "be":
+ self.data.append((v >> 24) & 255)
+ self.data.append((v >> 16) & 255)
+ self.data.append((v >> 8) & 255)
+ self.data.append(v & 255)
+ else:
+ assert 0
+ if comment is not None:
+ self.comments[len(self.data)] = comment
+
+ def finalize(self):
+ assert not self.finalized
+ for s, index in self.strings.items():
+ self.l("str%d" % index, "char")
+ for c in s:
+ self.data.append(ord(c))
+ self.data.append(0)
+ self.finalized = True
+ cursor = 0
+ while cursor < len(self.data):
+ if cursor in self.refs:
+ v = self.labels[self.refs[cursor][0]] - cursor
+ if self.endianness == "le":
+ self.data[cursor+0] = (v & 255)
+ self.data[cursor+1] = ((v >> 8) & 255)
+ self.data[cursor+2] = ((v >> 16) & 255)
+ self.data[cursor+3] = ((v >> 24) & 255)
+ elif self.endianness == "be":
+ self.data[cursor+0] = ((v >> 24) & 255)
+ self.data[cursor+1] = ((v >> 16) & 255)
+ self.data[cursor+2] = ((v >> 8) & 255)
+ self.data[cursor+3] = (v & 255)
+ else:
+ assert 0
+ cursor += 4
+ else:
+ cursor += 1
+
+ def write_verbose_c(self, f):
+ assert self.finalized
+ print("%s %s[%d] = {" % (self.ctype, self.cname, len(self.data)), file=f)
+ cursor = 0
+ bytecnt = 0
+ while cursor < len(self.data):
+ if cursor in self.comments:
+ if bytecnt == 0:
+ print(" ", end="", file=f)
+ print(" // %s" % self.comments[cursor], file=f)
+ bytecnt = 0
+ if cursor in self.labels_byaddr:
+ if bytecnt != 0:
+ print(file=f)
+ if cursor in self.exports:
+ print("#define %s ((%s*)(%s+%d))" % (self.labels_byaddr[cursor], self.ltypes_byaddr[cursor], self.cname, cursor), file=f)
+ else:
+ print(" // [%d] %s" % (cursor, self.labels_byaddr[cursor]), file=f)
+ bytecnt = 0
+ if cursor in self.refs:
+ if bytecnt != 0:
+ print(file=f)
+ print(" ", end="", file=f)
+ print(" %-4s" % ("%d," % self.data[cursor+0]), end="", file=f)
+ print(" %-4s" % ("%d," % self.data[cursor+1]), end="", file=f)
+ print(" %-4s" % ("%d," % self.data[cursor+2]), end="", file=f)
+ print(" %-4s" % ("%d," % self.data[cursor+3]), end="", file=f)
+ print(" // [%d] %s (reference to %s)" % (cursor, self.refs[cursor][1], self.refs[cursor][0]), file=f)
+ bytecnt = 0
+ cursor += 4
+ else:
+ if bytecnt == 0:
+ print(" ", end="", file=f)
+ print(" %-4s" % ("%d," % self.data[cursor]), end=("" if bytecnt < 15 else "\n"), file=f)
+ bytecnt = (bytecnt + 1) & 15
+ cursor += 1
+ if bytecnt != 0:
+ print(file=f)
+ print("};", file=f)
+
+ def write_compact_c(self, f):
+ assert self.finalized
+ print("%s %s[%d] = {" % (self.ctype, self.cname, len(self.data)), file=f)
+ column = 0
+ for v in self.data:
+ if column == 0:
+ print(" ", end="", file=f)
+ column += 2
+ s = "%d," % v
+ print(s, end="", file=f)
+ column += len(s)
+ if column > 75:
+ print(file=f)
+ column = 0
+ if column != 0:
+ print(file=f)
+ for cursor in self.exports:
+ print("#define %s ((%s*)(%s+%d))" % (self.labels_byaddr[cursor], self.ltypes_byaddr[cursor], self.cname, cursor), file=f)
+ print("};", file=f)
+
+bba = BinaryBlobAssembler("chipdb_blob_%s" % dev_name, endianness, "uint8_t")
+bba.r("chip_info_%s" % dev_name, "chip_info")
index = 0
-print("static BelWirePOD bel_wires[] = {")
for bel in range(len(bel_name)):
- print("#define bel_wires_%d (bel_wires+%d)" % (bel, index))
+ bba.l("bel_wires_%d" % bel, "BelWirePOD")
for i in range(len(bel_wires[bel])):
- print(" {%d, PIN_%s}," % bel_wires[bel][i])
+ bba.u32(bel_wires[bel][i][0], "wire_index")
+ bba.u32(portpins[bel_wires[bel][i][1]], "port")
index += 1
-print("};")
-print("static BelInfoPOD bel_data_%s[%d] = {" % (dev_name, len(bel_name)))
+bba.l("bel_data_%s" % dev_name, "BelInfoPOD")
for bel in range(len(bel_name)):
- print(" {\"%s\", TYPE_%s, %d, bel_wires_%d, %d, %d, %d}%s" % (bel_name[bel], bel_type[bel],
- len(bel_wires[bel]), bel, bel_pos[bel][0], bel_pos[bel][1], bel_pos[bel][2],
- "," if bel+1 < len(bel_name) else ""))
-print("};")
+ bba.s(bel_name[bel], "name")
+ bba.u32(beltypes[bel_type[bel]], "type")
+ bba.u32(len(bel_wires[bel]), "num_bel_wires")
+ bba.r("bel_wires_%d" % bel, "bel_wires")
+ bba.u8(bel_pos[bel][0], "x")
+ bba.u8(bel_pos[bel][1], "y")
+ bba.u8(bel_pos[bel][2], "z")
+ bba.u8(0, "padding")
wireinfo = list()
pipinfo = list()
pipcache = dict()
-uppips_array = list()
-downpips_array = list()
-downbels_array = list()
-
for wire in range(num_wires):
if wire in wire_uphill:
pips = list()
for src in wire_uphill[wire]:
if (src, wire) not in pipcache:
pipcache[(src, wire)] = len(pipinfo)
- pipinfo.append(" {%d, %d, 1.0, %d, %d, %d, %d}" % (src, wire, pip_xy[(src, wire)][0], pip_xy[(src, wire)][1], pip_xy[(src, wire)][2], pip_xy[(src, wire)][3]))
- pips.append("%d" % pipcache[(src, wire)])
+ pi = dict()
+ pi["src"] = src
+ pi["dst"] = wire
+ pi["delay"] = 1
+ pi["x"] = pip_xy[(src, wire)][0]
+ pi["y"] = pip_xy[(src, wire)][1]
+ pi["switch_mask"] = pip_xy[(src, wire)][2]
+ pi["switch_index"] = pip_xy[(src, wire)][3]
+ pipinfo.append(pi)
+ pips.append(pipcache[(src, wire)])
num_uphill = len(pips)
list_uphill = "wire%d_uppips" % wire
- print("#define wire%d_uppips (wire_uppips+%d)" % (wire, len(uppips_array)))
- uppips_array += pips
+ bba.l(list_uphill, "int32_t")
+ for p in pips:
+ bba.u32(p, None)
else:
num_uphill = 0
- list_uphill = "nullptr"
+ list_uphill = None
if wire in wire_downhill:
pips = list()
for dst in wire_downhill[wire]:
if (wire, dst) not in pipcache:
pipcache[(wire, dst)] = len(pipinfo)
- pipinfo.append(" {%d, %d, 1.0, %d, %d, %d, %d}" % (wire, dst, pip_xy[(wire, dst)][0], pip_xy[(wire, dst)][1], pip_xy[(wire, dst)][2], pip_xy[(wire, dst)][3]))
- pips.append("%d" % pipcache[(wire, dst)])
+ pi = dict()
+ pi["src"] = wire
+ pi["dst"] = dst
+ pi["delay"] = 1
+ pi["x"] = pip_xy[(wire, dst)][0]
+ pi["y"] = pip_xy[(wire, dst)][1]
+ pi["switch_mask"] = pip_xy[(wire, dst)][2]
+ pi["switch_index"] = pip_xy[(wire, dst)][3]
+ pipinfo.append(pi)
+ pips.append(pipcache[(wire, dst)])
num_downhill = len(pips)
list_downhill = "wire%d_downpips" % wire
- print("#define wire%d_downpips (wire_downpips+%d)" % (wire, len(downpips_array)))
- downpips_array += pips
+ bba.l(list_downhill, "int32_t")
+ for p in pips:
+ bba.u32(p, None)
else:
num_downhill = 0
- list_downhill = "nullptr"
+ list_downhill = None
if wire in wire_downhill_belports:
num_bels_downhill = len(wire_downhill_belports[wire])
-
- print("#define wire%d_downbels (wire_downbels+%d)" % (wire, len(downbels_array)))
- downbels_array += ["{%d, PIN_%s}" % it for it in wire_downhill_belports[wire]]
+ bba.l("wire%d_downbels" % wire, "BelPortPOD")
+ for belport in wire_downhill_belports[wire]:
+ bba.u32(belport[0], "bel_index")
+ bba.u32(portpins[belport[1]], "port")
else:
num_bels_downhill = 0
- info = " {"
- info += "\"X%d/Y%d/%s\", " % wire_names_r[wire]
- info += "%d, %d, %s, %s, %d, " % (num_uphill, num_downhill, list_uphill, list_downhill, num_bels_downhill)
+ info = dict()
+ info["name"] = "X%d/Y%d/%s" % wire_names_r[wire]
+
+ info["num_uphill"] = num_uphill
+ info["list_uphill"] = list_uphill
+
+ info["num_downhill"] = num_downhill
+ info["list_downhill"] = list_downhill
+
+ info["num_bels_downhill"] = num_bels_downhill
+ info["list_bels_downhill"] = ("wire%d_downbels" % wire) if num_bels_downhill > 0 else None
if wire in wire_uphill_belport:
- info += "{%d, PIN_%s}, " % wire_uphill_belport[wire]
+ info["uphill_bel"] = wire_uphill_belport[wire][0]
+ info["uphill_pin"] = portpins[wire_uphill_belport[wire][1]]
else:
- info += "{-1, PIN_NONE}, "
-
- info += ("wire%d_downbels, " % wire) if num_bels_downhill > 0 else "nullptr, "
+ info["uphill_bel"] = -1
+ info["uphill_pin"] = 0
avg_x, avg_y = 0, 0
if wire in wire_xy:
@@ -430,22 +660,11 @@ for wire in range(num_wires):
avg_x /= len(wire_xy[wire])
avg_y /= len(wire_xy[wire])
- info += "%d, %d}" % (round(avg_x), round(avg_y))
+ info["x"] = int(round(avg_x))
+ info["y"] = int(round(avg_y))
wireinfo.append(info)
-print("static int wire_uppips[] = {")
-print(" " + "\n ".join(textwrap.wrap(", ".join(uppips_array))))
-print("};");
-
-print("static int wire_downpips[] = {")
-print(" " + "\n ".join(textwrap.wrap(", ".join(downpips_array))))
-print("};");
-
-print("static BelPortPOD wire_downbels[] = {")
-print(" " + "\n ".join(textwrap.wrap(", ".join(downbels_array))))
-print("};");
-
packageinfo = []
for package in packages:
@@ -456,19 +675,20 @@ for package in packages:
pinname, x, y, z = pin
pin_bel = "X%d/Y%d/io%d" % (x, y, z)
bel_idx = bel_name.index(pin_bel)
- pins_info.append('{"%s", %d}' % (pinname, bel_idx))
- print("static PackagePinPOD package_%s_pins[%d] = {" % (safename, len(pins_info)))
- print(" " + ",\n ".join(pins_info))
- print("};")
- packageinfo.append('{"%s", %d, package_%s_pins}' % (name, len(pins_info), safename))
+ pins_info.append((pinname, bel_idx))
+ bba.l("package_%s_pins" % safename, "PackagePinPOD")
+ for pi in pins_info:
+ bba.s(pi[0], "name")
+ bba.u32(pi[1], "bel_index")
+ packageinfo.append((name, len(pins_info), "package_%s_pins" % safename))
tilegrid = []
for y in range(dev_height):
for x in range(dev_width):
if (x, y) in tiles:
- tilegrid.append("TILE_%s" % (tiles[x, y].upper()))
+ tilegrid.append(tiles[x, y].upper())
else:
- tilegrid.append("TILE_NONE")
+ tilegrid.append("NONE")
tileinfo = []
for t in range(num_tile_types):
@@ -476,72 +696,145 @@ for t in range(num_tile_types):
for cb in tile_bits[t]:
name, bits = cb
safename = re.sub("[^A-Za-z0-9]", "_", name)
- bits_list = ["{%d, %d}" % _ for _ in bits]
- print("static ConfigBitPOD tile%d_%s_bits[%d] = {%s};" % (t, safename, len(bits_list), ", ".join(bits_list)))
- centries_info.append('{"%s", %d, tile%d_%s_bits}' % (name, len(bits_list), t, safename))
- print("static ConfigEntryPOD tile%d_config[%d] = {" % (t, len(centries_info)))
- print(" " + ",\n ".join(centries_info))
- print("};")
- tileinfo.append("{%d, %d, %d, tile%d_config}" % (tile_sizes[t][0], tile_sizes[t][1], len(centries_info), t))
+ bba.l("tile%d_%s_bits" % (t, safename), "ConfigBitPOD")
+ for row, col in bits:
+ bba.u8(row, "row")
+ bba.u8(col, "col")
+ if len(bits) == 0:
+ bba.u32(0, "padding")
+ elif len(bits) % 2 == 1:
+ bba.u16(0, "padding")
+ centries_info.append((name, len(bits), t, safename))
+ bba.l("tile%d_config" % t, "ConfigEntryPOD")
+ for name, num_bits, t, safename in centries_info:
+ bba.s(name, "name")
+ bba.u32(num_bits, "num_bits")
+ bba.r("tile%d_%s_bits" % (t, safename), "num_bits")
+ if len(centries_info) == 0:
+ bba.u32(0, "padding")
+ ti = dict()
+ ti["cols"] = tile_sizes[t][0]
+ ti["rows"] = tile_sizes[t][1]
+ ti["num_entries"] = len(centries_info)
+ ti["entries"] = "tile%d_config" % t
+ tileinfo.append(ti)
+
+bba.l("wire_data_%s" % dev_name, "WireInfoPOD")
+for info in wireinfo:
+ bba.s(info["name"], "name")
+ bba.u32(info["num_uphill"], "num_uphill")
+ bba.u32(info["num_downhill"], "num_downhill")
+ bba.r(info["list_uphill"], "pips_uphill")
+ bba.r(info["list_downhill"], "pips_downhill")
+ bba.u32(info["num_bels_downhill"], "num_bels_downhill")
+ bba.u32(info["uphill_bel"], "bel_uphill.bel_index")
+ bba.u32(info["uphill_pin"], "bel_uphill.port")
+ bba.r(info["list_bels_downhill"], "bels_downhill")
+ bba.u16(info["x"], "x")
+ bba.u16(info["y"], "y")
+
+bba.l("pip_data_%s" % dev_name, "PipInfoPOD")
+for info in pipinfo:
+ bba.u32(info["src"], "src")
+ bba.u32(info["dst"], "dst")
+ bba.u32(info["delay"], "delay")
+ bba.u8(info["x"], "x")
+ bba.u8(info["y"], "y")
+ bba.u16(info["switch_mask"], "switch_mask")
+ bba.u32(info["switch_index"], "switch_index")
switchinfo = []
-switchid = 0
for switch in switches:
dst, x, y, bits = switch
bitlist = []
for b in bits:
m = cbit_re.match(b)
assert m
- bitlist.append("{%d, %d}" % (int(m.group(1)), int(m.group(2))))
- cbits = ", ".join(bitlist)
- switchinfo.append("{%d, %d, %d, {%s}}" % (x, y, len(bits), cbits))
- switchid += 1
-
-iereninfo = []
-for ieren in ierens:
- iereninfo.append("{%d, %d, %d, %d, %d, %d}" % ieren)
-
-print("static WireInfoPOD wire_data_%s[%d] = {" % (dev_name, num_wires))
-print(" " + ",\n ".join(wireinfo))
-print("};")
-
-print("static PipInfoPOD pip_data_%s[%d] = {" % (dev_name, len(pipinfo)))
-print(" " + ",\n ".join(pipinfo))
-print("};")
-
-print("static SwitchInfoPOD switch_data_%s[%d] = {" % (dev_name, len(switchinfo)))
-print(" " + ",\n ".join(switchinfo))
-print("};")
-
-print("static TileInfoPOD tile_data_%s[%d] = {" % (dev_name, num_tile_types))
-print(" " + ",\n ".join(tileinfo))
-print("};")
-
-print("static IerenInfoPOD ieren_data_%s[%d] = {" % (dev_name, len(iereninfo)))
-print(" " + ",\n ".join(iereninfo))
-print("};")
-
-
-print("static BitstreamInfoPOD bits_info_%s = {" % dev_name)
-print(" %d, %d, tile_data_%s, switch_data_%s, ieren_data_%s" % (len(switchinfo), len(iereninfo), dev_name, dev_name, dev_name))
-print("};")
-
-print("static TileType tile_grid_%s[%d] = {" % (dev_name, len(tilegrid)))
-print(" " + ",\n ".join(tilegrid))
-print("};")
+ bitlist.append((int(m.group(1)), int(m.group(2))))
+ si = dict()
+ si["x"] = x
+ si["y"] = y
+ si["bits"] = bitlist
+ switchinfo.append(si)
+
+bba.l("switch_data_%s" % dev_name, "SwitchInfoPOD")
+for info in switchinfo:
+ bba.u32(len(info["bits"]), "num_bits")
+ bba.u8(info["x"], "x")
+ bba.u8(info["y"], "y")
+ for i in range(5):
+ if i < len(info["bits"]):
+ bba.u8(info["bits"][i][0], "row<%d>" % i)
+ bba.u8(info["bits"][i][1], "col<%d>" % i)
+ else:
+ bba.u8(0, "row<%d> (unused)" % i)
+ bba.u8(0, "col<%d> (unused)" % i)
+bba.l("tile_data_%s" % dev_name, "TileInfoPOD")
+for info in tileinfo:
+ bba.u8(info["cols"], "cols")
+ bba.u8(info["rows"], "rows")
+ bba.u16(info["num_entries"], "num_entries")
+ bba.r(info["entries"], "entries")
-print("static PackageInfoPOD package_info_%s[%d] = {" % (dev_name, len(packageinfo)))
-print(" " + ",\n ".join(packageinfo))
-print("};")
+bba.l("ieren_data_%s" % dev_name, "IerenInfoPOD")
+for ieren in ierens:
+ bba.u8(ieren[0], "iox")
+ bba.u8(ieren[1], "ioy")
+ bba.u8(ieren[2], "ioz")
+ bba.u8(ieren[3], "ierx")
+ bba.u8(ieren[4], "iery")
+ bba.u8(ieren[5], "ierz")
+
+if len(ierens) % 2 == 1:
+ bba.u16(0, "padding")
+
+bba.l("bits_info_%s" % dev_name, "BitstreamInfoPOD")
+bba.u32(len(switchinfo), "num_switches")
+bba.u32(len(ierens), "num_ierens")
+bba.r("tile_data_%s" % dev_name, "tiles_nonrouting")
+bba.r("switch_data_%s" % dev_name, "switches")
+bba.r("ieren_data_%s" % dev_name, "ierens")
+
+bba.l("tile_grid_%s" % dev_name, "TileType")
+for t in tilegrid:
+ bba.u32(tiletypes[t], "tiletype")
+
+bba.l("package_info_%s" % dev_name, "PackageInfoPOD")
+for info in packageinfo:
+ bba.s(info[0], "name")
+ bba.u32(info[1], "num_pins")
+ bba.r(info[2], "pins")
+
+bba.l("chip_info_%s" % dev_name)
+bba.u32(dev_width, "dev_width")
+bba.u32(dev_height, "dev_height")
+bba.u32(len(bel_name), "num_bels")
+bba.u32(num_wires, "num_wires")
+bba.u32(len(pipinfo), "num_pips")
+bba.u32(len(switchinfo), "num_switches")
+bba.u32(len(packageinfo), "num_packages")
+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("package_info_%s" % dev_name, "packages_data")
+
+bba.finalize()
-print('}')
+print('#include "nextpnr.h"')
print('NEXTPNR_NAMESPACE_BEGIN')
-print("ChipInfoPOD chip_info_%s = {" % dev_name)
-print(" %d, %d, %d, %d, %d, %d, %d," % (dev_width, dev_height, len(bel_name), num_wires, len(pipinfo), len(switchinfo), len(packageinfo)))
-print(" bel_data_%s, wire_data_%s, pip_data_%s," % (dev_name, dev_name, dev_name))
-print(" tile_grid_%s, &bits_info_%s, package_info_%s" % (dev_name, dev_name, dev_name))
-print("};")
+if compact_output:
+ bba.write_compact_c(sys.stdout)
+else:
+ bba.write_verbose_c(sys.stdout)
+
+# print("ChipInfoPOD chip_info_%s = {" % dev_name)
+# print(" %d, %d, %d, %d, %d, %d, %d," % (dev_width, dev_height, len(bel_name), num_wires, len(pipinfo), len(switchinfo), len(packageinfo)))
+# print(" bel_data, wire_data_%s, pip_data_%s," % (dev_name, dev_name))
+# print(" tile_grid_%s, bits_info_%s, package_info_%s" % (dev_name, dev_name, dev_name))
+# print("};")
print('NEXTPNR_NAMESPACE_END')