aboutsummaryrefslogtreecommitdiffstats
path: root/ice40
diff options
context:
space:
mode:
authorMiodrag Milanovic <mmicko@gmail.com>2019-12-28 13:54:06 +0100
committerMiodrag Milanovic <mmicko@gmail.com>2019-12-28 13:54:06 +0100
commit796d6489953927105d3b0ed22308f29676b168fa (patch)
treebc0f470642c0943713c441aa7c3e9e310cb23ccc /ice40
parent50f87a6024859d197eefa8de0b0b616b1e03e239 (diff)
parent0d43aff2682d91817ea4a1fb5dff6e169ae9a659 (diff)
downloadnextpnr-796d6489953927105d3b0ed22308f29676b168fa.tar.gz
nextpnr-796d6489953927105d3b0ed22308f29676b168fa.tar.bz2
nextpnr-796d6489953927105d3b0ed22308f29676b168fa.zip
Merge remote-tracking branch 'origin/master' into mmicko/ecp5_gui
Diffstat (limited to 'ice40')
-rw-r--r--ice40/arch.cc4
-rw-r--r--ice40/arch_pybindings.cc2
-rw-r--r--ice40/archdefs.h4
-rw-r--r--ice40/bitstream.cc3
-rw-r--r--ice40/cells.cc26
-rw-r--r--ice40/family.cmake27
-rw-r--r--ice40/main.cc1
-rw-r--r--ice40/pack.cc21
8 files changed, 58 insertions, 30 deletions
diff --git a/ice40/arch.cc b/ice40/arch.cc
index cc50cb68..0f8e5969 100644
--- a/ice40/arch.cc
+++ b/ice40/arch.cc
@@ -1245,7 +1245,11 @@ void Arch::assignCellInfo(CellInfo *cell)
}
}
+#ifdef WITH_HEAP
+const std::string Arch::defaultPlacer = "heap";
+#else
const std::string Arch::defaultPlacer = "sa";
+#endif
const std::vector<std::string> Arch::availablePlacers = {"sa",
#ifdef WITH_HEAP
diff --git a/ice40/arch_pybindings.cc b/ice40/arch_pybindings.cc
index cef7c58f..e2022091 100644
--- a/ice40/arch_pybindings.cc
+++ b/ice40/arch_pybindings.cc
@@ -59,6 +59,7 @@ void arch_wrap_python()
typedef std::unordered_map<IdString, std::unique_ptr<CellInfo>> CellMap;
typedef std::unordered_map<IdString, std::unique_ptr<NetInfo>> NetMap;
+ typedef std::unordered_map<IdString, HierarchicalCell> HierarchyMap;
typedef std::unordered_map<IdString, IdString> AliasMap;
auto belpin_cls = class_<ContextualWrapper<BelPin>>("BelPin", no_init);
@@ -75,6 +76,7 @@ void arch_wrap_python()
WRAP_MAP_UPTR(CellMap, "IdCellMap");
WRAP_MAP_UPTR(NetMap, "IdNetMap");
+ WRAP_MAP(HierarchyMap, wrap_context<HierarchicalCell &>, "HierarchyMap");
}
NEXTPNR_NAMESPACE_END
diff --git a/ice40/archdefs.h b/ice40/archdefs.h
index 89591af5..e95953f1 100644
--- a/ice40/archdefs.h
+++ b/ice40/archdefs.h
@@ -48,6 +48,9 @@ struct DelayInfo
// -----------------------------------------------------------------------
+// https://bugreports.qt.io/browse/QTBUG-80789
+
+#ifndef Q_MOC_RUN
enum ConstIds
{
ID_NONE
@@ -59,6 +62,7 @@ enum ConstIds
#define X(t) static constexpr auto id_##t = IdString(ID_##t);
#include "constids.inc"
#undef X
+#endif
struct BelId
{
diff --git a/ice40/bitstream.cc b/ice40/bitstream.cc
index 7149f127..9586b8ff 100644
--- a/ice40/bitstream.cc
+++ b/ice40/bitstream.cc
@@ -159,6 +159,9 @@ void configure_extra_cell(chipconfig_t &config, const Context *ctx, CellInfo *ce
if (string_style) {
// Lattice's weird string style params, not sure if
// prefixes other than 0b should be supported, only 0b features in docs
+ if (cell->params.count(ctx->id(p.first)) && !cell->params.at(ctx->id(p.first)).is_string)
+ log_error("expected configuration string starting with '0b' for parameter '%s' on cell '%s'\n",
+ p.first.c_str(), cell->name.c_str(ctx));
std::string raw = get_param_str_or_def(cell, ctx->id(p.first), "0b0");
if (raw.substr(0, 2) != "0b")
log_error("expected configuration string starting with '0b' for parameter '%s' on cell '%s'\n",
diff --git a/ice40/cells.cc b/ice40/cells.cc
index c4e93d5b..f1901c43 100644
--- a/ice40/cells.cc
+++ b/ice40/cells.cc
@@ -69,7 +69,7 @@ std::unique_ptr<CellInfo> create_ice_cell(Context *ctx, IdString type, std::stri
new_cell->params[ctx->id("PIN_TYPE")] = Property(0, 6);
new_cell->params[ctx->id("PULLUP")] = Property::State::S0;
new_cell->params[ctx->id("NEG_TRIGGER")] = Property::State::S0;
- new_cell->params[ctx->id("IOSTANDARD")] = Property("SB_LVCMOS");
+ new_cell->params[ctx->id("IO_STANDARD")] = Property("SB_LVCMOS");
add_port(ctx, new_cell.get(), "PACKAGE_PIN", PORT_INOUT);
@@ -346,6 +346,8 @@ std::unique_ptr<CellInfo> create_ice_cell(Context *ctx, IdString type, std::stri
void lut_to_lc(const Context *ctx, CellInfo *lut, CellInfo *lc, bool no_dff)
{
+ if (lc->hierpath == IdString())
+ lc->hierpath = lut->hierpath;
lc->params[ctx->id("LUT_INIT")] = lut->params[ctx->id("LUT_INIT")].extract(0, 16, Property::State::S0);
replace_port(lut, ctx->id("I0"), lc, ctx->id("I0"));
replace_port(lut, ctx->id("I1"), lc, ctx->id("I1"));
@@ -359,6 +361,8 @@ void lut_to_lc(const Context *ctx, CellInfo *lut, CellInfo *lc, bool no_dff)
void dff_to_lc(const Context *ctx, CellInfo *dff, CellInfo *lc, bool pass_thru_lut)
{
+ if (lc->hierpath == IdString())
+ lc->hierpath = dff->hierpath;
lc->params[ctx->id("DFF_ENABLE")] = Property::State::S1;
std::string config = dff->type.str(ctx).substr(6);
auto citer = config.begin();
@@ -426,7 +430,25 @@ void nxio_to_sb(Context *ctx, CellInfo *nxio, CellInfo *sbio, std::unordered_set
} else {
NPNR_ASSERT(false);
}
- NetInfo *donet = sbio->ports.at(ctx->id("D_OUT_0")).net;
+ NetInfo *donet = sbio->ports.at(ctx->id("D_OUT_0")).net, *dinet = sbio->ports.at(ctx->id("D_IN_0")).net;
+
+ // Rename I/O nets to avoid conflicts
+ if (donet != nullptr && donet->name == nxio->name)
+ rename_net(ctx, donet, ctx->id(donet->name.str(ctx) + "$SB_IO_OUT"));
+ if (dinet != nullptr && dinet->name == nxio->name)
+ rename_net(ctx, dinet, ctx->id(dinet->name.str(ctx) + "$SB_IO_IN"));
+
+ // Create a new top port net for accurate IO timing analysis and simulation netlists
+ if (ctx->ports.count(nxio->name)) {
+ IdString tn_netname = nxio->name;
+ NPNR_ASSERT(!ctx->nets.count(tn_netname));
+ std::unique_ptr<NetInfo> toplevel_net{new NetInfo};
+ toplevel_net->name = tn_netname;
+ connect_port(ctx, toplevel_net.get(), sbio, ctx->id("PACKAGE_PIN"));
+ ctx->ports[nxio->name].net = toplevel_net.get();
+ ctx->nets[tn_netname] = std::move(toplevel_net);
+ }
+
CellInfo *tbuf = net_driven_by(
ctx, donet, [](const Context *ctx, const CellInfo *cell) { return cell->type == ctx->id("$_TBUF_"); },
ctx->id("Y"));
diff --git a/ice40/family.cmake b/ice40/family.cmake
index f22883fb..2859f456 100644
--- a/ice40/family.cmake
+++ b/ice40/family.cmake
@@ -40,14 +40,6 @@ if (NOT EXTERNAL_CHIPDB)
set(DEV_CC_DB ${CMAKE_CURRENT_BINARY_DIR}/ice40/chipdbs/chipdb-${dev}.bin)
set(DEV_CONSTIDS_INC ${CMAKE_CURRENT_SOURCE_DIR}/ice40/constids.inc)
set(DEV_GFXH ${CMAKE_CURRENT_SOURCE_DIR}/ice40/gfx.h)
- add_custom_command(OUTPUT ${DEV_CC_BBA_DB}
- COMMAND ${PYTHON_EXECUTABLE} ${DB_PY} -p ${DEV_CONSTIDS_INC} -g ${DEV_GFXH} ${OPT_FAST} ${OPT_SLOW} ${DEV_TXT_DB} > ${DEV_CC_BBA_DB}
- DEPENDS ${DEV_CONSTIDS_INC} ${DEV_GFXH} ${DEV_TXT_DB} ${DB_PY} ${PREV_DEV_CC_BBA_DB}
- )
- add_custom_command(OUTPUT ${DEV_CC_DB}
- COMMAND bbasm ${BBASM_ENDIAN_FLAG} ${DEV_CC_BBA_DB} ${DEV_CC_DB}
- DEPENDS bbasm ${DEV_CC_BBA_DB}
- )
if(PREGENERATED_BBA_PATH)
add_custom_command(OUTPUT ${DEV_CC_DB}
@@ -92,6 +84,7 @@ if (NOT EXTERNAL_CHIPDB)
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_BINARY_DIR}/ice40/chipdbs/chipdb-${dev}.cc)
+ set(DEV_BIN_DB ${CMAKE_CURRENT_BINARY_DIR}/ice40/chipdbs/chipdb-${dev}.bin)
set(DEV_CONSTIDS_INC ${CMAKE_CURRENT_SOURCE_DIR}/ice40/constids.inc)
set(DEV_GFXH ${CMAKE_CURRENT_SOURCE_DIR}/ice40/gfx.h)
if(PREGENERATED_BBA_PATH)
@@ -105,11 +98,19 @@ if (NOT EXTERNAL_CHIPDB)
COMMAND mv ${DEV_CC_BBA_DB}.new ${DEV_CC_BBA_DB}
DEPENDS ${DEV_CONSTIDS_INC} ${DEV_GFXH} ${DEV_TXT_DB} ${DB_PY} ${PREV_DEV_CC_BBA_DB}
)
- add_custom_command(OUTPUT ${DEV_CC_DB}
- COMMAND bbasm --c ${BBASM_ENDIAN_FLAG} ${DEV_CC_BBA_DB} ${DEV_CC_DB}.new
- COMMAND mv ${DEV_CC_DB}.new ${DEV_CC_DB}
- DEPENDS bbasm ${DEV_CC_BBA_DB}
- )
+ if(USE_C_EMBED)
+ add_custom_command(OUTPUT ${DEV_CC_DB}
+ COMMAND bbasm --e ${BBASM_ENDIAN_FLAG} ${DEV_CC_BBA_DB} ${DEV_CC_DB}.new ${DEV_BIN_DB}
+ COMMAND mv ${DEV_CC_DB}.new ${DEV_CC_DB}
+ DEPENDS bbasm ${DEV_CC_BBA_DB}
+ )
+ else()
+ add_custom_command(OUTPUT ${DEV_CC_DB}
+ COMMAND bbasm --c ${BBASM_ENDIAN_FLAG} ${DEV_CC_BBA_DB} ${DEV_CC_DB}.new
+ COMMAND mv ${DEV_CC_DB}.new ${DEV_CC_DB}
+ DEPENDS bbasm ${DEV_CC_BBA_DB}
+ )
+ endif()
endif()
if (SERIALIZE_CHIPDB)
set(PREV_DEV_CC_BBA_DB ${DEV_CC_BBA_DB})
diff --git a/ice40/main.cc b/ice40/main.cc
index 5a5fa0c7..3b512a5a 100644
--- a/ice40/main.cc
+++ b/ice40/main.cc
@@ -24,7 +24,6 @@
#include "bitstream.h"
#include "command.h"
#include "design_utils.h"
-#include "jsonparse.h"
#include "log.h"
#include "pcf.h"
#include "timing.h"
diff --git a/ice40/pack.cc b/ice40/pack.cc
index a1eba411..5b13e9ee 100644
--- a/ice40/pack.cc
+++ b/ice40/pack.cc
@@ -459,7 +459,6 @@ static void pack_io(Context *ctx)
{
std::unordered_set<IdString> packed_cells;
std::unordered_set<IdString> delete_nets;
-
std::vector<std::unique_ptr<CellInfo>> new_cells;
log_info("Packing IOs..\n");
@@ -478,8 +477,7 @@ static void pack_io(Context *ctx)
rgb = net->driver.cell;
}
if (sb != nullptr) {
- // Trivial case, SB_IO used. Just destroy the net and the
- // iobuf
+ // Trivial case, SB_IO used. Just destroy the iobuf
log_info("%s feeds SB_IO %s, removing %s %s.\n", ci->name.c_str(ctx), sb->name.c_str(ctx),
ci->type.c_str(ctx), ci->name.c_str(ctx));
NetInfo *net = sb->ports.at(ctx->id("PACKAGE_PIN")).net;
@@ -490,7 +488,6 @@ static void pack_io(Context *ctx)
sb->type.c_str(ctx), sb->name.c_str(ctx));
if (net != nullptr) {
-
if (net->clkconstr != nullptr) {
if (sb->ports.count(id_D_IN_0)) {
NetInfo *din0_net = sb->ports.at(id_D_IN_0).net;
@@ -509,15 +506,6 @@ static void pack_io(Context *ctx)
}
}
}
-
- delete_nets.insert(net->name);
- sb->ports.at(ctx->id("PACKAGE_PIN")).net = nullptr;
- }
- if (ci->type == ctx->id("$nextpnr_iobuf")) {
- NetInfo *net2 = ci->ports.at(ctx->id("I")).net;
- if (net2 != nullptr) {
- delete_nets.insert(net2->name);
- }
}
} else if (rgb != nullptr) {
log_info("%s use by SB_RGBA_DRV/SB_RGB_DRV %s, not creating SB_IO\n", ci->name.c_str(ctx),
@@ -533,11 +521,15 @@ static void pack_io(Context *ctx)
new_cells.push_back(std::move(ice_cell));
sb = new_cells.back().get();
}
+ for (auto port : ci->ports)
+ disconnect_port(ctx, ci, port.first);
packed_cells.insert(ci->name);
std::copy(ci->attrs.begin(), ci->attrs.end(), std::inserter(sb->attrs, sb->attrs.begin()));
} else if (is_sb_io(ctx, ci) || is_sb_gb_io(ctx, ci)) {
NetInfo *net = ci->ports.at(ctx->id("PACKAGE_PIN")).net;
- if ((net != nullptr) && (net->users.size() > 1))
+ if ((net != nullptr) && ((net->users.size() > 2) ||
+ (net->driver.cell != nullptr &&
+ net->driver.cell->type == ctx->id("$nextpnr_obuf") && net->users.size() > 1)))
log_error("PACKAGE_PIN of %s '%s' connected to more than a single top level IO.\n", ci->type.c_str(ctx),
ci->name.c_str(ctx));
}
@@ -1495,6 +1487,7 @@ bool Arch::pack()
promote_globals(ctx);
ctx->assignArchInfo();
constrain_chains(ctx);
+ ctx->fixupHierarchy();
ctx->assignArchInfo();
ctx->settings[ctx->id("pack")] = 1;
archInfoToAttributes();