diff options
author | Miodrag Milanovic <mmicko@gmail.com> | 2019-12-28 13:54:06 +0100 |
---|---|---|
committer | Miodrag Milanovic <mmicko@gmail.com> | 2019-12-28 13:54:06 +0100 |
commit | 796d6489953927105d3b0ed22308f29676b168fa (patch) | |
tree | bc0f470642c0943713c441aa7c3e9e310cb23ccc /ice40 | |
parent | 50f87a6024859d197eefa8de0b0b616b1e03e239 (diff) | |
parent | 0d43aff2682d91817ea4a1fb5dff6e169ae9a659 (diff) | |
download | nextpnr-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.cc | 4 | ||||
-rw-r--r-- | ice40/arch_pybindings.cc | 2 | ||||
-rw-r--r-- | ice40/archdefs.h | 4 | ||||
-rw-r--r-- | ice40/bitstream.cc | 3 | ||||
-rw-r--r-- | ice40/cells.cc | 26 | ||||
-rw-r--r-- | ice40/family.cmake | 27 | ||||
-rw-r--r-- | ice40/main.cc | 1 | ||||
-rw-r--r-- | ice40/pack.cc | 21 |
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(); |