Fixes for ECP5 partial bitstream demo Signed-off-by: David Shah <dave@ds0.me>
diff --git a/common/nextpnr.cc b/common/nextpnr.cc index ab4601a..2597842 100644 --- a/common/nextpnr.cc +++ b/common/nextpnr.cc
@@ -19,6 +19,7 @@ #include "nextpnr.h" #include <boost/algorithm/string.hpp> +#include "design_utils.h" #include "log.h" NEXTPNR_NAMESPACE_BEGIN @@ -185,6 +186,10 @@ return p; } +void CellInfo::setParam(IdString name, std::string value) { params[name] = Property::from_string(value); } + +void CellInfo::setAttr(IdString name, std::string value) { attrs[name] = Property::from_string(value); } + void BaseCtx::addConstraint(std::unique_ptr<TimingConstraint> constr) { for (auto fromObj : constr->from) @@ -497,6 +502,14 @@ } region[name] = std::move(new_region); } + +void BaseCtx::makeConnection(IdString netname, IdString cellname, IdString portname) +{ + NetInfo *net = nets[netname].get(); + CellInfo *cell = cells[cellname].get(); + connect_port(getCtx(), net, cell, portname); +} + void BaseCtx::addBelToRegion(IdString name, BelId bel) { region[name]->bels.insert(bel); } void BaseCtx::constrainCellToRegion(IdString cell, IdString region_name) {
diff --git a/common/nextpnr.h b/common/nextpnr.h index 177048b..2358ad7 100644 --- a/common/nextpnr.h +++ b/common/nextpnr.h
@@ -402,6 +402,8 @@ TimingConstrObjectId tmg_id; Region *region = nullptr; + + void connectTo(CellInfo *cell, IdString port); }; enum PortType @@ -445,6 +447,10 @@ Region *region = nullptr; TimingConstrObjectId tmg_id; + + // For Python bindings + void setParam(IdString name, std::string value); + void setAttr(IdString name, std::string value); }; enum TimingPortClass @@ -746,6 +752,7 @@ void createRectangularRegion(IdString name, int x0, int y0, int x1, int y1); void addBelToRegion(IdString name, BelId bel); void constrainCellToRegion(IdString cell, IdString region_name); + void makeConnection(IdString netname, IdString cellname, IdString portname); // Workaround for lack of wrappable constructors DecalXY constructDecalXY(DecalId decal, float x, float y);
diff --git a/common/pybindings.cc b/common/pybindings.cc index 3f2cb81..c6228d8 100644 --- a/common/pybindings.cc +++ b/common/pybindings.cc
@@ -159,6 +159,10 @@ pass_through<PlaceStrength>>::def_wrap(ci_cls, "belStrength"); readonly_wrapper<CellInfo &, decltype(&CellInfo::pins), &CellInfo::pins, wrap_context<PinMap &>>::def_wrap(ci_cls, "pins"); + fn_wrapper_2a_v<CellInfo &, decltype(&CellInfo::setParam), &CellInfo::setParam, conv_from_str<IdString>, + pass_through<std::string>>::def_wrap(ci_cls, "setParam"); + fn_wrapper_2a_v<CellInfo &, decltype(&CellInfo::setAttr), &CellInfo::setAttr, conv_from_str<IdString>, + pass_through<std::string>>::def_wrap(ci_cls, "setAttr"); auto pi_cls = class_<ContextualWrapper<PortInfo &>>("PortInfo", no_init); readwrite_wrapper<PortInfo &, decltype(&PortInfo::name), &PortInfo::name, conv_to_str<IdString>,
diff --git a/common/router1.cc b/common/router1.cc index 02c817c..a88bae6 100644 --- a/common/router1.cc +++ b/common/router1.cc
@@ -400,7 +400,7 @@ dst_to_arc[dst_wire] = arc; - if (net_info->wires.count(src_wire) == 0) { + if (net_info->wires.count(dst_wire) == 0) { arc_queue_insert(arc, src_wire, dst_wire); continue; }
diff --git a/ecp5/arch_pybindings.cc b/ecp5/arch_pybindings.cc index 18d2111..0a86e8e 100644 --- a/ecp5/arch_pybindings.cc +++ b/ecp5/arch_pybindings.cc
@@ -141,6 +141,8 @@ fn_wrapper_2a_v<Context, decltype(&Context::constrainCellToRegion), &Context::constrainCellToRegion, conv_from_str<IdString>, conv_from_str<IdString>>::def_wrap(ctx_cls, "constrainCellToRegion"); + fn_wrapper_3a_v<Context, decltype(&Context::makeConnection), &Context::makeConnection, conv_from_str<IdString>, + conv_from_str<IdString>, conv_from_str<IdString>>::def_wrap(ctx_cls, "makeConnection"); WRAP_RANGE(Bel, conv_to_str<BelId>); WRAP_RANGE(Wire, conv_to_str<WireId>); WRAP_RANGE(AllPip, conv_to_str<PipId>);
diff --git a/ecp5/globals.cc b/ecp5/globals.cc index bc5c66d..b6691f9 100644 --- a/ecp5/globals.cc +++ b/ecp5/globals.cc
@@ -435,7 +435,8 @@ log_info("Promoting globals...\n"); auto clocks = get_clocks(); for (auto clock : clocks) { - bool is_noglobal = bool_or_default(clock->attrs, ctx->id("noglobal"), false); + bool is_noglobal = bool_or_default(clock->attrs, ctx->id("noglobal"), false) || + bool_or_default(clock->attrs, ctx->id("ECP5_IS_GLOBAL"), false); if (is_noglobal) continue; log_info(" promoting clock net %s to global network\n", clock->name.c_str(ctx)); @@ -461,6 +462,8 @@ CellInfo *ci = cell.second; if (ci->type == id_DCCA) { NetInfo *clock = ci->ports.at(id_CLKO).net; + if (!clock->wires.empty()) + continue; NPNR_ASSERT(clock != nullptr); bool drives_fabric = std::any_of(clock->users.begin(), clock->users.end(), [this](const PortRef &port) { return !is_clock_port(port); });