Merge branch 'master' of gitlab.com:SymbioticEDA/nextpnr into q3k/pll

This commit is contained in:
Sergiusz Bazanski 2018-07-24 15:54:03 +01:00
commit b31e95f82c
26 changed files with 197 additions and 174 deletions

2
.gitignore vendored
View File

@ -25,3 +25,5 @@ build/
/Testing/*
CTestTestfile.cmake
install_manifest.txt
/bbasm
/ImportExecutables.cmake

View File

@ -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)

12
bba/bba.cmake Normal file
View File

@ -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)

15
bba/main.cc Normal file
View File

@ -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;
}

View File

@ -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;

View File

@ -147,6 +147,7 @@ struct GraphicElement
{
G_NONE,
G_LINE,
G_ARROW,
G_BOX,
G_CIRCLE,
G_LABEL

View File

@ -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)))));

View File

@ -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;

View File

@ -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);
}

View File

@ -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));

View File

@ -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; }

View File

@ -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();

View File

@ -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 {

View File

@ -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);

View File

@ -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);

View File

@ -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; }

View File

@ -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) {

View File

@ -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;
}

View File

@ -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; }

View File

@ -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();

View File

@ -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");

View File

@ -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")

View File

@ -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_DB}
COMMAND ${PYTHON_EXECUTABLE} ${DB_PY} -c -p ${DEV_PORTS_INC} -g ${DEV_GFXH} ${DEV_TXT_DB} > ${DEV_CC_DB}.new
COMMAND mv ${DEV_CC_DB}.new ${DEV_CC_DB}
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 bbasm < ${DEV_CC_BBA_DB} > ${DEV_CC_DB}.new
COMMAND mv ${DEV_CC_DB}.new ${DEV_CC_DB}
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>)

View File

@ -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) {

View File

@ -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);

View File

@ -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);