diff options
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | CMakeLists.txt | 2 | ||||
-rw-r--r-- | bba/bba.cmake | 12 | ||||
-rw-r--r-- | bba/main.cc | 15 | ||||
-rw-r--r-- | common/archcheck.cc | 5 | ||||
-rw-r--r-- | common/nextpnr.h | 1 | ||||
-rw-r--r-- | common/place_common.cc | 22 | ||||
-rw-r--r-- | common/placer1.cc | 26 | ||||
-rw-r--r-- | common/timing.cc | 3 | ||||
-rw-r--r-- | ecp5/arch.cc | 46 | ||||
-rw-r--r-- | ecp5/arch.h | 3 | ||||
-rw-r--r-- | ecp5/arch_place.cc | 7 | ||||
-rw-r--r-- | ecp5/bitstream.cc | 43 | ||||
-rw-r--r-- | ecp5/main.cc | 4 | ||||
-rw-r--r-- | generic/arch.cc | 40 | ||||
-rw-r--r-- | generic/arch.h | 3 | ||||
-rw-r--r-- | gui/fpgaviewwidget.cc | 6 | ||||
-rw-r--r-- | ice40/arch.cc | 40 | ||||
-rw-r--r-- | ice40/arch.h | 7 | ||||
-rw-r--r-- | ice40/arch_place.cc | 7 | ||||
-rw-r--r-- | ice40/arch_pybindings.cc | 2 | ||||
-rw-r--r-- | ice40/chipdb.py | 38 | ||||
-rw-r--r-- | ice40/family.cmake | 21 | ||||
-rw-r--r-- | ice40/gfx.cc | 2 | ||||
-rw-r--r-- | ice40/pack.cc | 4 | ||||
-rw-r--r-- | ice40/place_legaliser.cc | 8 |
26 files changed, 196 insertions, 173 deletions
@@ -25,3 +25,5 @@ build/ /Testing/* CTestTestfile.cmake install_manifest.txt +/bbasm +/ImportExecutables.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index c8ee6805..55e57763 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -167,6 +167,8 @@ if(MINGW) add_definitions("-Wa,-mbig-obj") endif(MINGW) +include(bba/bba.cmake) + foreach (family ${ARCH}) message(STATUS "Configuring architecture : ${family}") string(TOUPPER ${family} ufamily) diff --git a/bba/bba.cmake b/bba/bba.cmake new file mode 100644 index 00000000..4bb9ea0e --- /dev/null +++ b/bba/bba.cmake @@ -0,0 +1,12 @@ +IF(CMAKE_CROSSCOMPILING) + SET(IMPORT_EXECUTABLES "IMPORTFILE-NOTFOUND" CACHE FILEPATH "Point it to the export file from a native build") + INCLUDE(${IMPORT_EXECUTABLES}) +ENDIF(CMAKE_CROSSCOMPILING) + +IF(NOT CMAKE_CROSSCOMPILING) + ADD_EXECUTABLE(bbasm bba/main.cc) +ENDIF(NOT CMAKE_CROSSCOMPILING) + +IF(NOT CMAKE_CROSSCOMPILING) + EXPORT(TARGETS bbasm FILE ${CMAKE_BINARY_DIR}/ImportExecutables.cmake ) +ENDIF(NOT CMAKE_CROSSCOMPILING) diff --git a/bba/main.cc b/bba/main.cc new file mode 100644 index 00000000..42b79504 --- /dev/null +++ b/bba/main.cc @@ -0,0 +1,15 @@ +#include <unistd.h> +#include <assert.h> +int main() +{ + char buffer[512]; + int i, j; + while (1) { + i = read(0, buffer, 512); + if (i == 0) break; + assert(i > 0); + j = write(1, buffer, i); + assert(i == j); + } + return 0; +} diff --git a/common/archcheck.cc b/common/archcheck.cc index 5c4ef26c..5059066d 100644 --- a/common/archcheck.cc +++ b/common/archcheck.cc @@ -17,8 +17,8 @@ * */ -#include "nextpnr.h" #include "log.h" +#include "nextpnr.h" #if 0 #define dbg(...) log(__VA_ARGS__) @@ -84,8 +84,7 @@ void archcheck_locs(const Context *ctx) log_info("Checking all locations..\n"); for (int x = 0; x < ctx->getGridDimX(); x++) - for (int y = 0; y < ctx->getGridDimY(); y++) - { + for (int y = 0; y < ctx->getGridDimY(); y++) { dbg("> %d %d\n", x, y); std::unordered_set<int> usedz; diff --git a/common/nextpnr.h b/common/nextpnr.h index 021772fe..3ba4f3b3 100644 --- a/common/nextpnr.h +++ b/common/nextpnr.h @@ -147,6 +147,7 @@ struct GraphicElement { G_NONE, G_LINE, + G_ARROW, G_BOX, G_CIRCLE, G_LABEL diff --git a/common/place_common.cc b/common/place_common.cc index 95b7b2aa..5673c847 100644 --- a/common/place_common.cc +++ b/common/place_common.cc @@ -28,19 +28,20 @@ NEXTPNR_NAMESPACE_BEGIN wirelen_t get_net_metric(const Context *ctx, const NetInfo *net, MetricType type, float &tns) { wirelen_t wirelength = 0; - int driver_x, driver_y; + Loc driver_loc; bool driver_gb; CellInfo *driver_cell = net->driver.cell; if (!driver_cell) return 0; if (driver_cell->bel == BelId()) return 0; - ctx->estimatePosition(driver_cell->bel, driver_x, driver_y, driver_gb); + driver_gb = ctx->getBelGlobalBuf(driver_cell->bel); + driver_loc = ctx->getBelLocation(driver_cell->bel); WireId drv_wire = ctx->getBelPinWire(driver_cell->bel, ctx->portPinFromId(net->driver.port)); if (driver_gb) return 0; float worst_slack = 1000; - int xmin = driver_x, xmax = driver_x, ymin = driver_y, ymax = driver_y; + int xmin = driver_loc.x, xmax = driver_loc.x, ymin = driver_loc.y, ymax = driver_loc.y; for (auto load : net->users) { if (load.cell == nullptr) continue; @@ -56,15 +57,14 @@ wirelen_t get_net_metric(const Context *ctx, const NetInfo *net, MetricType type worst_slack = std::min(slack, worst_slack); } - int load_x, load_y; - bool load_gb; - ctx->estimatePosition(load_cell->bel, load_x, load_y, load_gb); - if (load_gb) + if (ctx->getBelGlobalBuf(load_cell->bel)) continue; - xmin = std::min(xmin, load_x); - ymin = std::min(ymin, load_y); - xmax = std::max(xmax, load_x); - ymax = std::max(ymax, load_y); + Loc load_loc = ctx->getBelLocation(load_cell->bel); + + xmin = std::min(xmin, load_loc.x); + ymin = std::min(ymin, load_loc.y); + xmax = std::max(xmax, load_loc.x); + ymax = std::max(ymax, load_loc.y); } if (ctx->timing_driven && type == MetricType::COST) { wirelength = wirelen_t((((ymax - ymin) + (xmax - xmin)) * std::min(5.0, (1.0 + std::exp(-worst_slack / 5))))); diff --git a/common/placer1.cc b/common/placer1.cc index 025c7c15..f713fb88 100644 --- a/common/placer1.cc +++ b/common/placer1.cc @@ -50,9 +50,7 @@ class SAPlacer { int num_bel_types = 0; for (auto bel : ctx->getBels()) { - int x, y; - bool gb; - ctx->estimatePosition(bel, x, y, gb); + Loc loc = ctx->getBelLocation(bel); BelType type = ctx->getBelType(bel); int type_idx; if (bel_types.find(type) == bel_types.end()) { @@ -63,13 +61,13 @@ class SAPlacer } if (int(fast_bels.size()) < type_idx + 1) fast_bels.resize(type_idx + 1); - if (int(fast_bels.at(type_idx).size()) < (x + 1)) - fast_bels.at(type_idx).resize(x + 1); - if (int(fast_bels.at(type_idx).at(x).size()) < (y + 1)) - fast_bels.at(type_idx).at(x).resize(y + 1); - max_x = std::max(max_x, x); - max_y = std::max(max_y, y); - fast_bels.at(type_idx).at(x).at(y).push_back(bel); + if (int(fast_bels.at(type_idx).size()) < (loc.x + 1)) + fast_bels.at(type_idx).resize(loc.x + 1); + if (int(fast_bels.at(type_idx).at(loc.x).size()) < (loc.y + 1)) + fast_bels.at(type_idx).at(loc.x).resize(loc.y + 1); + max_x = std::max(max_x, loc.x); + max_y = std::max(max_y, loc.y); + fast_bels.at(type_idx).at(loc.x).at(loc.y).push_back(bel); } diameter = std::max(max_x, max_y) + 1; } @@ -404,12 +402,10 @@ class SAPlacer BelId random_bel_for_cell(CellInfo *cell) { BelType targetType = ctx->belTypeFromId(cell->type); - int x, y; - bool gb; - ctx->estimatePosition(cell->bel, x, y, gb); + Loc curr_loc = ctx->getBelLocation(cell->bel); while (true) { - int nx = ctx->rng(2 * diameter + 1) + std::max(x - diameter, 0); - int ny = ctx->rng(2 * diameter + 1) + std::max(y - diameter, 0); + int nx = ctx->rng(2 * diameter + 1) + std::max(curr_loc.x - diameter, 0); + int ny = ctx->rng(2 * diameter + 1) + std::max(curr_loc.y - diameter, 0); int beltype_idx = bel_types.at(targetType); if (nx >= int(fast_bels.at(beltype_idx).size())) continue; diff --git a/common/timing.cc b/common/timing.cc index 3a48935f..d91dea20 100644 --- a/common/timing.cc +++ b/common/timing.cc @@ -88,6 +88,9 @@ void assign_budget(Context *ctx) IdString clock_domain = ctx->getPortClock(cell.second.get(), port.first); if (clock_domain != IdString()) { delay_t slack = delay_t(1.0e12 / ctx->target_freq); // TODO: clock constraints + delay_t clkToQ; + if (ctx->getCellDelay(cell.second.get(), clock_domain, port.first, clkToQ)) + slack -= clkToQ; if (port.second.net) follow_net(ctx, port.second.net, 0, slack); } diff --git a/ecp5/arch.cc b/ecp5/arch.cc index 7d67dd0c..5507d1e3 100644 --- a/ecp5/arch.cc +++ b/ecp5/arch.cc @@ -192,17 +192,20 @@ BelId Arch::getBelByName(IdString name) const return ret; } -BelRange Arch::getBelsAtSameTile(BelId bel) const +BelRange Arch::getBelsByTile(int x, int y) const { BelRange br; - NPNR_ASSERT(bel != BelId()); - br.b.cursor_tile = bel.location.y * chip_info->width + bel.location.x; - br.e.cursor_tile = bel.location.y * chip_info->width + bel.location.x; + + br.b.cursor_tile = y * chip_info->width + x; + br.e.cursor_tile = y * chip_info->width + x; br.b.cursor_index = 0; - br.e.cursor_index = locInfo(bel)->num_bels - 1; + br.e.cursor_index = chip_info->locations[chip_info->location_type[br.b.cursor_tile]].num_bels - 1; br.b.chip = chip_info; br.e.chip = chip_info; - ++br.e; + if (br.e.cursor_index == -1) + ++br.e.cursor_index; + else + ++br.e; return br; } @@ -278,6 +281,7 @@ PipId Arch::getPipByName(IdString name) const Location loc; std::string basename; std::tie(loc.x, loc.y, basename) = split_identifier_name(name.str(this)); + ret.location = loc; const LocationTypePOD *loci = locInfo(ret); for (int i = 0; i < loci->num_pips; i++) { PipId curr; @@ -285,6 +289,8 @@ PipId Arch::getPipByName(IdString name) const curr.index = i; pip_by_name[getPipName(curr)] = curr; } + if (pip_by_name.find(name) == pip_by_name.end()) + NPNR_ASSERT_FALSE_STR("no pip named " + name.str(this)); return pip_by_name[name]; } @@ -399,36 +405,8 @@ BelId Arch::getBelByLocation(Loc loc) const return BelId(); } -BelRange Arch::getBelsByTile(int x, int y) const -{ - BelRange br; - - int num_bels = 0; - - if (x < chip_info->width && y < chip_info->height) { - const LocationTypePOD &locI = chip_info->locations[chip_info->location_type[y * chip_info->width + x]]; - num_bels = locI.num_bels; - } - - br.b.cursor_tile = y * chip_info->width + x; - br.e.cursor_tile = y * chip_info->width + x; - br.b.cursor_index = 0; - br.e.cursor_index = num_bels - 1; - br.b.chip = chip_info; - br.e.chip = chip_info; - ++br.e; - return br; -} - // ----------------------------------------------------------------------- -void Arch::estimatePosition(BelId bel, int &x, int &y, bool &gb) const -{ - x = bel.location.x; - y = bel.location.y; - gb = false; -} - delay_t Arch::estimateDelay(WireId src, WireId dst) const { return 200 * (abs(src.location.x - dst.location.x) + abs(src.location.y - dst.location.y)); diff --git a/ecp5/arch.h b/ecp5/arch.h index ce2b90c3..4400db5e 100644 --- a/ecp5/arch.h +++ b/ecp5/arch.h @@ -482,8 +482,6 @@ struct Arch : BaseCtx return range; } - BelRange getBelsAtSameTile(BelId bel) const; - BelType getBelType(BelId bel) const { NPNR_ASSERT(bel != BelId()); @@ -752,7 +750,6 @@ struct Arch : BaseCtx // ------------------------------------------------- - void estimatePosition(BelId bel, int &x, int &y, bool &gb) const; delay_t estimateDelay(WireId src, WireId dst) const; delay_t getDelayEpsilon() const { return 20; } delay_t getRipupDelayPenalty() const { return 200; } diff --git a/ecp5/arch_place.cc b/ecp5/arch_place.cc index 22ebab67..84432043 100644 --- a/ecp5/arch_place.cc +++ b/ecp5/arch_place.cc @@ -66,7 +66,8 @@ bool Arch::isBelLocationValid(BelId bel) const { if (getBelType(bel) == TYPE_TRELLIS_SLICE) { std::vector<const CellInfo *> bel_cells; - for (auto bel_other : getBelsAtSameTile(bel)) { + Loc bel_loc = getBelLocation(bel); + for (auto bel_other : getBelsByTile(bel_loc.x, bel_loc.y)) { IdString cell_other = getBoundBelCell(bel_other); if (cell_other != IdString()) { const CellInfo *ci_other = cells.at(cell_other).get(); @@ -89,8 +90,8 @@ bool Arch::isValidBelForCell(CellInfo *cell, BelId bel) const NPNR_ASSERT(getBelType(bel) == TYPE_TRELLIS_SLICE); std::vector<const CellInfo *> bel_cells; - - for (auto bel_other : getBelsAtSameTile(bel)) { + Loc bel_loc = getBelLocation(bel); + for (auto bel_other : getBelsByTile(bel_loc.x, bel_loc.y)) { IdString cell_other = getBoundBelCell(bel_other); if (cell_other != IdString() && bel_other != bel) { const CellInfo *ci_other = cells.at(cell_other).get(); diff --git a/ecp5/bitstream.cc b/ecp5/bitstream.cc index 19ddb9f9..c2218762 100644 --- a/ecp5/bitstream.cc +++ b/ecp5/bitstream.cc @@ -30,6 +30,7 @@ #include <fstream> #include <streambuf> +#include "io.h" #include "log.h" #include "util.h" @@ -182,12 +183,34 @@ void write_bitstream(Context *ctx, std::string base_config_file, std::string tex } } } + // Find bank voltages + std::unordered_map<int, IOVoltage> bankVcc; + for (auto &cell : ctx->cells) { + CellInfo *ci = cell.second.get(); + if (ci->bel != BelId() && ci->type == ctx->id("TRELLIS_IO")) { + int bank = ctx->getPioBelBank(ci->bel); + std::string iotype = str_or_default(ci->attrs, ctx->id("IO_TYPE"), "LVCMOS33"); + IOVoltage vcc = get_vccio(ioType_from_str(iotype)); + if (bankVcc.find(bank) != bankVcc.end()) { + // TODO: strong and weak constraints + if (bankVcc[bank] != vcc) { + log_error("Error processing '%s': incompatible IO voltages %s and %s on bank %d.", + cell.first.c_str(ctx), iovoltage_to_str(bankVcc[bank]).c_str(), + iovoltage_to_str(vcc).c_str(), bank); + } + } else { + bankVcc[bank] = vcc; + } + } + } - // Set all bankref tiles to 3.3V (TODO) + // Set all bankref tiles to appropriate VccIO for (const auto &tile : empty_chip.tiles) { std::string type = tile.second->info.type; if (type.find("BANKREF") != std::string::npos && type != "BANKREF8") { - cc.tiles[tile.first].add_enum("BANK.VCCIO", "3V3"); + int bank = std::stoi(type.substr(7)); + if (bankVcc.find(bank) != bankVcc.end()) + cc.tiles[tile.first].add_enum("BANK.VCCIO", iovoltage_to_str(bankVcc[bank])); } } @@ -235,6 +258,20 @@ void write_bitstream(Context *ctx, std::string base_config_file, std::string tex std::string pic_tile = get_pic_tile(ctx, empty_chip, bel); cc.tiles[pio_tile].add_enum(pio + ".BASE_TYPE", dir + "_" + iotype); cc.tiles[pic_tile].add_enum(pio + ".BASE_TYPE", dir + "_" + iotype); + if (is_differential(ioType_from_str(iotype))) { + // Explicitly disable other pair + std::string other; + if (pio == "PIOA") + other = "PIOB"; + else if (pio == "PIOC") + other = "PIOD"; + else + log_error("cannot place differential IO at location %s\n", pio.c_str()); + cc.tiles[pio_tile].add_enum(other + ".BASE_TYPE", "_NONE_"); + cc.tiles[pic_tile].add_enum(other + ".BASE_TYPE", "_NONE_"); + cc.tiles[pio_tile].add_enum(other + ".PULLMODE", "NONE"); + cc.tiles[pio_tile].add_enum(pio + ".PULLMODE", "NONE"); + } if (dir != "INPUT" && (ci->ports.find(ctx->id("T")) == ci->ports.end() || ci->ports.at(ctx->id("T")).net == nullptr)) { // Tie tristate low if unconnected for outputs or bidir @@ -247,7 +284,7 @@ void write_bitstream(Context *ctx, std::string base_config_file, std::string tex std::string cib_wirename = ctx->locInfo(cib_wire)->wire_data[cib_wire.index].name.get(); cc.tiles[cib_tile].add_enum("CIB." + cib_wirename + "MUX", "0"); } - if (dir == "INPUT") { + if (dir == "INPUT" && !is_differential(ioType_from_str(iotype))) { cc.tiles[pio_tile].add_enum(pio + ".HYSTERESIS", "ON"); } } else { diff --git a/ecp5/main.cc b/ecp5/main.cc index 5a4a900a..90096855 100644 --- a/ecp5/main.cc +++ b/ecp5/main.cc @@ -63,6 +63,7 @@ int main(int argc, char *argv[]) #ifndef NO_GUI options.add_options()("gui", "start gui"); #endif + options.add_options()("test", "check architecture database integrity"); options.add_options()("25k", "set device type to LFE5U-25F"); options.add_options()("45k", "set device type to LFE5U-45F"); @@ -148,6 +149,9 @@ int main(int argc, char *argv[]) if (vm.count("no-tmdriv")) ctx->timing_driven = false; + if (vm.count("test")) + ctx->archcheck(); + #ifndef NO_GUI if (vm.count("gui")) { Application a(argc, argv); diff --git a/generic/arch.cc b/generic/arch.cc index 0fff2e4c..ac79ebea 100644 --- a/generic/arch.cc +++ b/generic/arch.cc @@ -77,18 +77,18 @@ void Arch::addBel(IdString name, IdString type, Loc loc, bool gb) bel_ids.push_back(name); bel_by_loc[loc] = name; - if (bels_by_tile.size() <= loc.x) + if (int(bels_by_tile.size()) <= loc.x) bels_by_tile.resize(loc.x + 1); - if (bels_by_tile[loc.x].size() <= loc.y) + if (int(bels_by_tile[loc.x].size()) <= loc.y) bels_by_tile[loc.x].resize(loc.y + 1); bels_by_tile[loc.x][loc.y].push_back(name); - if (tileDimZ.size() <= loc.x) + if (int(tileDimZ.size()) <= loc.x) tileDimZ.resize(loc.x + 1); - if (tileDimZ[loc.x].size() <= loc.y) + if (int(tileDimZ[loc.x].size()) <= loc.y) tileDimZ[loc.x].resize(loc.y + 1); gridDimX = std::max(gridDimX, loc.x + 1); @@ -193,6 +193,30 @@ BelId Arch::getBelByName(IdString name) const IdString Arch::getBelName(BelId bel) const { return bel; } +Loc Arch::getBelLocation(BelId bel) const +{ + auto &info = bels.at(bel); + return Loc(info.x, info.y, info.z); +} + +BelId Arch::getBelByLocation(Loc loc) const +{ + auto it = bel_by_loc.find(loc); + if (it != bel_by_loc.end()) + return it->second; + return BelId(); +} + +const std::vector<BelId> &Arch::getBelsByTile(int x, int y) const +{ + return bels_by_tile.at(x).at(y); +} + +bool Arch::getBelGlobalBuf(BelId bel) const +{ + return bels.at(bel).gb; +} + uint32_t Arch::getBelChecksum(BelId bel) const { // FIXME @@ -234,6 +258,7 @@ std::vector<PortPin> Arch::getBelPins(BelId bel) const std::vector<PortPin> ret; for (auto &it : bels.at(bel).pins) ret.push_back(it.first); + return ret; } // --------------------------------------------------------------- @@ -368,13 +393,6 @@ const std::vector<GroupId> &Arch::getGroupGroups(GroupId group) const { return g // --------------------------------------------------------------- -void Arch::estimatePosition(BelId bel, int &x, int &y, bool &gb) const -{ - x = bels.at(bel).x; - y = bels.at(bel).y; - gb = bels.at(bel).gb; -} - delay_t Arch::estimateDelay(WireId src, WireId dst) const { const WireInfo &s = wires.at(src); diff --git a/generic/arch.h b/generic/arch.h index 61e6b033..97ed1ac2 100644 --- a/generic/arch.h +++ b/generic/arch.h @@ -141,7 +141,7 @@ struct Arch : BaseCtx IdString getBelName(BelId bel) const; Loc getBelLocation(BelId bel) const; BelId getBelByLocation(Loc loc) const; - std::vector<BelId> getBelsByTile(int x, int y) const; + const std::vector<BelId> &getBelsByTile(int x, int y) const; bool getBelGlobalBuf(BelId bel) const; uint32_t getBelChecksum(BelId bel) const; void bindBel(BelId bel, IdString cell, PlaceStrength strength); @@ -191,7 +191,6 @@ struct Arch : BaseCtx const std::vector<PipId> &getGroupPips(GroupId group) const; const std::vector<GroupId> &getGroupGroups(GroupId group) const; - void estimatePosition(BelId bel, int &x, int &y, bool &gb) const; delay_t estimateDelay(WireId src, WireId dst) const; delay_t getDelayEpsilon() const { return 0.01; } delay_t getRipupDelayPenalty() const { return 1.0; } diff --git a/gui/fpgaviewwidget.cc b/gui/fpgaviewwidget.cc index e21af678..7ccb3445 100644 --- a/gui/fpgaviewwidget.cc +++ b/gui/fpgaviewwidget.cc @@ -246,7 +246,7 @@ FPGAViewWidget::FPGAViewWidget(QWidget *parent) { colors_.background = QColor("#000000"); colors_.grid = QColor("#333"); - colors_.frame = QColor("#d0d0d0"); + colors_.frame = QColor("#808080"); colors_.hidden = QColor("#606060"); colors_.inactive = QColor("#303030"); colors_.active = QColor("#f0f0f0"); @@ -327,7 +327,7 @@ void FPGAViewWidget::drawDecal(LineShaderData &out, const DecalXY &decal) line.build(out); } - if (el.type == GraphicElement::G_LINE) { + if (el.type == GraphicElement::G_LINE || el.type == GraphicElement::G_ARROW) { PolyLine(offsetX + scale * el.x1, offsetY + scale * el.y1, offsetX + scale * el.x2, offsetY + scale * el.y2) .build(out); } @@ -360,7 +360,7 @@ void FPGAViewWidget::drawDecal(LineShaderData out[], const DecalXY &decal) } } - if (el.type == GraphicElement::G_LINE) { + if (el.type == GraphicElement::G_LINE || el.type == GraphicElement::G_ARROW) { auto line = PolyLine(offsetX + scale * el.x1, offsetY + scale * el.y1, offsetX + scale * el.x2, offsetY + scale * el.y2); switch (el.style) { diff --git a/ice40/arch.cc b/ice40/arch.cc index 5c632faa..1d7e9546 100644 --- a/ice40/arch.cc +++ b/ice40/arch.cc @@ -292,23 +292,6 @@ BelRange Arch::getBelsByTile(int x, int y) const return br; } -BelRange Arch::getBelsAtSameTile(BelId bel) const -{ - BelRange br; - NPNR_ASSERT(bel != BelId()); - 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) - 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) - end++; - br.e.cursor = end; - return br; -} - PortType Arch::getBelPinType(BelId bel, PortPin pin) const { NPNR_ASSERT(bel != BelId()); @@ -484,14 +467,6 @@ std::vector<GroupId> Arch::getGroupGroups(GroupId group) const // ----------------------------------------------------------------------- -void Arch::estimatePosition(BelId bel, int &x, int &y, bool &gb) const -{ - NPNR_ASSERT(bel != BelId()); - x = chip_info->bel_data[bel.index].x; - y = chip_info->bel_data[bel.index].y; - gb = chip_info->bel_data[bel.index].type == TYPE_SB_GB; -} - delay_t Arch::estimateDelay(WireId src, WireId dst) const { NPNR_ASSERT(src != WireId()); @@ -735,6 +710,14 @@ bool Arch::getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort } else if (fromPort == id("I2") && toPort == id("COUT")) { delay = 230; return true; + } else if (fromPort == id("CLK") && toPort == id("O")) { + delay = 540; + return true; + } + } else if (cell->type == id("ICESTORM_RAM")) { + if (fromPort == id("RCLK")) { + delay = 2140; + return true; } } return false; @@ -745,6 +728,11 @@ IdString Arch::getPortClock(const CellInfo *cell, IdString port) const if (cell->type == id("ICESTORM_LC") && bool_or_default(cell->params, id("DFF_ENABLE"))) { if (port != id("LO") && port != id("CIN") && port != id("COUT")) return id("CLK"); + } else if (cell->type == id("ICESTORM_RAM")) { + if (port.str(this)[0] == 'R') + return id("RCLK"); + else + return id("WCLK"); } return IdString(); } @@ -753,6 +741,8 @@ bool Arch::isClockPort(const CellInfo *cell, IdString port) const { if (cell->type == id("ICESTORM_LC") && port == id("CLK")) return true; + if (cell->type == id("ICESTORM_RAM") && (port == id("RCLK") || (port == id("WCLK")))) + return true; return false; } diff --git a/ice40/arch.h b/ice40/arch.h index f0060d48..3aec25a2 100644 --- a/ice40/arch.h +++ b/ice40/arch.h @@ -83,10 +83,6 @@ NPNR_PACKED_STRUCT(struct WireInfoPOD { int32_t num_uphill, num_downhill; RelPtr<int32_t> pips_uphill, pips_downhill; - int32_t num_bels_uphill, num_bels_downhill; - RelPtr<BelPortPOD> bels_uphill; - RelPtr<BelPortPOD> bels_downhill; - int32_t num_bel_pins; RelPtr<BelPortPOD> bel_pins; @@ -453,8 +449,6 @@ struct Arch : BaseCtx bool getBelGlobalBuf(BelId bel) const { return chip_info->bel_data[bel.index].type == TYPE_SB_GB; } - BelRange getBelsAtSameTile(BelId bel) const NPNR_DEPRECATED; - BelType getBelType(BelId bel) const { NPNR_ASSERT(bel != BelId()); @@ -685,7 +679,6 @@ struct Arch : BaseCtx // ------------------------------------------------- - void estimatePosition(BelId bel, int &x, int &y, bool &gb) const NPNR_DEPRECATED; delay_t estimateDelay(WireId src, WireId dst) const; delay_t getDelayEpsilon() const { return 20; } delay_t getRipupDelayPenalty() const { return 200; } diff --git a/ice40/arch_place.cc b/ice40/arch_place.cc index 16cc757e..59e1807d 100644 --- a/ice40/arch_place.cc +++ b/ice40/arch_place.cc @@ -72,7 +72,8 @@ bool Arch::isBelLocationValid(BelId bel) const { if (getBelType(bel) == TYPE_ICESTORM_LC) { std::vector<const CellInfo *> bel_cells; - for (auto bel_other : getBelsAtSameTile(bel)) { + Loc bel_loc = getBelLocation(bel); + for (auto bel_other : getBelsByTile(bel_loc.x, bel_loc.y)) { IdString cell_other = getBoundBelCell(bel_other); if (cell_other != IdString()) { const CellInfo *ci_other = cells.at(cell_other).get(); @@ -95,8 +96,8 @@ bool Arch::isValidBelForCell(CellInfo *cell, BelId bel) const NPNR_ASSERT(getBelType(bel) == TYPE_ICESTORM_LC); std::vector<const CellInfo *> bel_cells; - - for (auto bel_other : getBelsAtSameTile(bel)) { + Loc bel_loc = getBelLocation(bel); + for (auto bel_other : getBelsByTile(bel_loc.x, bel_loc.y)) { IdString cell_other = getBoundBelCell(bel_other); if (cell_other != IdString() && bel_other != bel) { const CellInfo *ci_other = cells.at(cell_other).get(); diff --git a/ice40/arch_pybindings.cc b/ice40/arch_pybindings.cc index 246d0f57..98164e87 100644 --- a/ice40/arch_pybindings.cc +++ b/ice40/arch_pybindings.cc @@ -79,8 +79,6 @@ void arch_wrap_python() conv_to_str<IdString>, conv_from_str<BelId>>::def_wrap(ctx_cls, "getConflictingBelCell"); fn_wrapper_0a<Context, decltype(&Context::getBels), &Context::getBels, wrap_context<BelRange>>::def_wrap(ctx_cls, "getBels"); - fn_wrapper_1a<Context, decltype(&Context::getBelsAtSameTile), &Context::getBelsAtSameTile, wrap_context<BelRange>, - conv_from_str<BelId>>::def_wrap(ctx_cls, "getBelsAtSameTile"); fn_wrapper_2a<Context, decltype(&Context::getBelPinWire), &Context::getBelPinWire, conv_to_str<WireId>, conv_from_str<BelId>, conv_from_str<PortPin>>::def_wrap(ctx_cls, "getBelPinWire"); diff --git a/ice40/chipdb.py b/ice40/chipdb.py index 63d90b45..108197c1 100644 --- a/ice40/chipdb.py +++ b/ice40/chipdb.py @@ -41,8 +41,6 @@ extra_cells = dict() extra_cell_config = dict() packages = list() -wire_uphill_belports = dict() -wire_downhill_belports = dict() wire_belports = dict() wire_names = dict() @@ -453,18 +451,12 @@ for i in range(8): add_wire(0, 0, "padin_%d" % i) def add_bel_input(bel, wire, port): - if wire not in wire_downhill_belports: - wire_downhill_belports[wire] = set() - wire_downhill_belports[wire].add((bel, port)) if wire not in wire_belports: wire_belports[wire] = set() wire_belports[wire].add((bel, port)) bel_wires[bel].append((wire, port, 0)) def add_bel_output(bel, wire, port): - if wire not in wire_uphill_belports: - wire_uphill_belports[wire] = set() - wire_uphill_belports[wire].add((bel, port)) if wire not in wire_belports: wire_belports[wire] = set() wire_belports[wire].add((bel, port)) @@ -672,7 +664,7 @@ for tile_xy, tile_type in sorted(tiles.items()): add_bel_ec(ec) for ec in sorted(extra_cells.keys()): - if ec[1] == 0 and ec[2] == 0: + if ec[1] in (0, dev_width - 1) and ec[2] in (0, dev_height - 1): add_bel_ec(ec) class BinaryBlobAssembler: @@ -1011,24 +1003,6 @@ for wire in range(num_wires): num_downhill = 0 list_downhill = None - if wire in wire_uphill_belports: - num_bels_uphill = len(wire_uphill_belports[wire]) - bba.l("wire%d_upbels" % wire, "BelPortPOD") - for belport in sorted(wire_uphill_belports[wire]): - bba.u32(belport[0], "bel_index") - bba.u32(portpins[belport[1]], "port") - else: - num_bels_uphill = 0 - - if wire in wire_downhill_belports: - num_bels_downhill = len(wire_downhill_belports[wire]) - bba.l("wire%d_downbels" % wire, "BelPortPOD") - for belport in sorted(wire_downhill_belports[wire]): - bba.u32(belport[0], "bel_index") - bba.u32(portpins[belport[1]], "port") - else: - num_bels_downhill = 0 - if wire in wire_belports: num_bel_pins = len(wire_belports[wire]) bba.l("wire%d_bels" % wire, "BelPortPOD") @@ -1047,12 +1021,6 @@ for wire in range(num_wires): 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 - - info["num_bels_uphill"] = num_bels_uphill - info["list_bels_uphill"] = ("wire%d_upbels" % wire) if num_bels_uphill > 0 else None - info["num_bel_pins"] = num_bel_pins info["list_bel_pins"] = ("wire%d_bels" % wire) if num_bel_pins > 0 else None @@ -1130,10 +1098,6 @@ for wire, info in enumerate(wireinfo): 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_uphill"], "num_bels_uphill") - bba.u32(info["num_bels_downhill"], "num_bels_downhill") - bba.r(info["list_bels_uphill"], "bels_uphill") - bba.r(info["list_bels_downhill"], "bels_downhill") bba.u32(info["num_bel_pins"], "num_bel_pins") bba.r(info["list_bel_pins"], "bel_pins") bba.u32(len(wire_segments[wire]), "num_segments") diff --git a/ice40/family.cmake b/ice40/family.cmake index 9af06f82..95cdf331 100644 --- a/ice40/family.cmake +++ b/ice40/family.cmake @@ -19,13 +19,18 @@ if (MSVC) set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/ice40/resources/chipdb.rc PROPERTIES LANGUAGE RC) foreach (dev ${devices}) set(DEV_TXT_DB ${ICEBOX_ROOT}/chipdb-${dev}.txt) + set(DEV_CC_BBA_DB ${CMAKE_CURRENT_SOURCE_DIR}/ice40/chipdbs/chipdb-${dev}.bba) set(DEV_CC_DB ${CMAKE_CURRENT_SOURCE_DIR}/ice40/chipdbs/chipdb-${dev}.bin) set(DEV_PORTS_INC ${CMAKE_CURRENT_SOURCE_DIR}/ice40/portpins.inc) set(DEV_GFXH ${CMAKE_CURRENT_SOURCE_DIR}/ice40/gfx.h) - add_custom_command(OUTPUT ${DEV_CC_DB} - COMMAND ${PYTHON_EXECUTABLE} ${DB_PY} -b -p ${DEV_PORTS_INC} -g ${DEV_GFXH} ${DEV_TXT_DB} > ${DEV_CC_DB} + add_custom_command(OUTPUT ${DEV_CC_BBA_DB} + COMMAND ${PYTHON_EXECUTABLE} ${DB_PY} -b -p ${DEV_PORTS_INC} -g ${DEV_GFXH} ${DEV_TXT_DB} > ${DEV_CC_BBA_DB} DEPENDS ${DEV_TXT_DB} ${DB_PY} ) + add_custom_command(OUTPUT ${DEV_CC_DB} + COMMAND bbasm < ${DEV_CC_BBA_DB} > ${DEV_CC_DB} + DEPENDS bbasm ${DEV_CC_BBA_DB} + ) target_sources(ice40_chipdb PRIVATE ${DEV_CC_DB}) set_source_files_properties(${DEV_CC_DB} PROPERTIES HEADER_FILE_ONLY TRUE) foreach (target ${family_targets}) @@ -36,14 +41,20 @@ else() target_compile_options(ice40_chipdb PRIVATE -g0 -O0 -w) foreach (dev ${devices}) set(DEV_TXT_DB ${ICEBOX_ROOT}/chipdb-${dev}.txt) + set(DEV_CC_BBA_DB ${CMAKE_CURRENT_SOURCE_DIR}/ice40/chipdbs/chipdb-${dev}.bba) set(DEV_CC_DB ${CMAKE_CURRENT_SOURCE_DIR}/ice40/chipdbs/chipdb-${dev}.cc) set(DEV_PORTS_INC ${CMAKE_CURRENT_SOURCE_DIR}/ice40/portpins.inc) set(DEV_GFXH ${CMAKE_CURRENT_SOURCE_DIR}/ice40/gfx.h) + add_custom_command(OUTPUT ${DEV_CC_BBA_DB} + COMMAND ${PYTHON_EXECUTABLE} ${DB_PY} -c -p ${DEV_PORTS_INC} -g ${DEV_GFXH} ${DEV_TXT_DB} > ${DEV_CC_BBA_DB}.new + COMMAND mv ${DEV_CC_BBA_DB}.new ${DEV_CC_BBA_DB} + DEPENDS ${DEV_TXT_DB} ${DB_PY} + ) add_custom_command(OUTPUT ${DEV_CC_DB} - COMMAND ${PYTHON_EXECUTABLE} ${DB_PY} -c -p ${DEV_PORTS_INC} -g ${DEV_GFXH} ${DEV_TXT_DB} > ${DEV_CC_DB}.new + COMMAND bbasm < ${DEV_CC_BBA_DB} > ${DEV_CC_DB}.new COMMAND mv ${DEV_CC_DB}.new ${DEV_CC_DB} - DEPENDS ${DEV_TXT_DB} ${DB_PY} - ) + DEPENDS bbasm ${DEV_CC_BBA_DB} + ) target_sources(ice40_chipdb PRIVATE ${DEV_CC_DB}) foreach (target ${family_targets}) target_sources(${target} PRIVATE $<TARGET_OBJECTS:ice40_chipdb>) diff --git a/ice40/gfx.cc b/ice40/gfx.cc index f6ed789f..1b01cbd8 100644 --- a/ice40/gfx.cc +++ b/ice40/gfx.cc @@ -647,7 +647,7 @@ void pipGfx(std::vector<GraphicElement> &g, int x, int y, float x1, float y1, fl float ty = 0.5 * (y1 + y2); GraphicElement el; - el.type = GraphicElement::G_LINE; + el.type = GraphicElement::G_ARROW; el.style = style; if (fabsf(x1 - swx1) < 0.001 && fabsf(x2 - swx1) < 0.001) { diff --git a/ice40/pack.cc b/ice40/pack.cc index 03b33190..b1e7380e 100644 --- a/ice40/pack.cc +++ b/ice40/pack.cc @@ -312,6 +312,10 @@ static void set_net_constant(const Context *ctx, NetInfo *orig, NetInfo *constne (user.port != ctx->id("CLK") && ((constval && user.port == ctx->id("CE")) || (!constval && user.port != ctx->id("CE"))))) { uc->ports[user.port].net = nullptr; + } else if (is_ram(ctx, uc) && !constval && user.port != ctx->id("RCLK") && user.port != ctx->id("RCLKN") && + user.port != ctx->id("WCLK") && user.port != ctx->id("WCLKN") && user.port != ctx->id("RCLKE") && + user.port != ctx->id("WCLKE")) { + uc->ports[user.port].net = nullptr; } else { uc->ports[user.port].net = constnet; constnet->users.push_back(user); diff --git a/ice40/place_legaliser.cc b/ice40/place_legaliser.cc index 2aefb839..ebc2b865 100644 --- a/ice40/place_legaliser.cc +++ b/ice40/place_legaliser.cc @@ -75,11 +75,9 @@ static void get_chain_midpoint(const Context *ctx, const CellChain &chain, float for (auto cell : chain.cells) { if (cell->bel == BelId()) continue; - int bel_x, bel_y; - bool bel_gb; - ctx->estimatePosition(cell->bel, bel_x, bel_y, bel_gb); - total_x += bel_x; - total_y += bel_y; + Loc bel_loc = ctx->getBelLocation(cell->bel); + total_x += bel_loc.x; + total_y += bel_loc.y; N++; } NPNR_ASSERT(N > 0); |