diff options
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.cc | 32 | ||||
-rw-r--r-- | ice40/arch_place.h | 4 | ||||
-rw-r--r-- | ice40/bitstream.cc | 81 | ||||
-rw-r--r-- | ice40/bitstream.h | 2 | ||||
-rw-r--r-- | ice40/cells.cc | 2 | ||||
-rw-r--r-- | ice40/cells.h | 2 | ||||
-rw-r--r-- | ice40/main.cc | 61 | ||||
-rw-r--r-- | ice40/pack.cc | 104 | ||||
-rw-r--r-- | ice40/pack.h | 2 | ||||
-rw-r--r-- | ice40/pcf.cc | 11 | ||||
-rw-r--r-- | ice40/pcf.h | 2 | ||||
-rw-r--r-- | ice40/pybindings.cc | 62 |
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 ¶m, 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); |