diff options
-rw-r--r-- | ice40/bitstream.cc | 16 | ||||
-rw-r--r-- | ice40/chip.cc | 138 | ||||
-rw-r--r-- | ice40/chip.h | 183 | ||||
-rw-r--r-- | ice40/chipdb.py | 513 |
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') |