aboutsummaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/arch_pybindings_shared.h114
-rw-r--r--common/nextpnr.cc85
-rw-r--r--common/nextpnr.h24
-rw-r--r--common/pybindings.cc16
4 files changed, 238 insertions, 1 deletions
diff --git a/common/arch_pybindings_shared.h b/common/arch_pybindings_shared.h
new file mode 100644
index 00000000..b90e80ec
--- /dev/null
+++ b/common/arch_pybindings_shared.h
@@ -0,0 +1,114 @@
+// Common Python bindings #included by all arches
+
+readonly_wrapper<Context, decltype(&Context::cells), &Context::cells, wrap_context<CellMap &>>::def_wrap(ctx_cls,
+"cells");
+readonly_wrapper<Context, decltype(&Context::nets), &Context::nets, wrap_context<NetMap &>>::def_wrap(ctx_cls,
+"nets");
+readonly_wrapper<Context, decltype(&Context::net_aliases), &Context::net_aliases,
+ wrap_context<AliasMap &>>::def_wrap(ctx_cls, "net_aliases");
+
+fn_wrapper_1a<Context, decltype(&Context::getNetByAlias), &Context::getNetByAlias, deref_and_wrap<NetInfo>,
+conv_from_str<IdString>>::def_wrap(ctx_cls, "getNetByAlias");
+fn_wrapper_2a_v<Context, decltype(&Context::addClock), &Context::addClock, conv_from_str<IdString>,
+pass_through<float>>::def_wrap(ctx_cls, "addClock");
+fn_wrapper_5a_v<Context, decltype(&Context::createRectangularRegion), &Context::createRectangularRegion,
+ conv_from_str<IdString>, pass_through<int>, pass_through<int>, pass_through<int>,
+pass_through<int>>::def_wrap(ctx_cls, "createRectangularRegion");
+fn_wrapper_2a_v<Context, decltype(&Context::addBelToRegion), &Context::addBelToRegion, conv_from_str<IdString>,
+conv_from_str<BelId>>::def_wrap(ctx_cls, "addBelToRegion");
+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_1a<Context, decltype(&Context::createNet), &Context::createNet, deref_and_wrap<NetInfo>,
+conv_from_str<IdString>>::def_wrap(ctx_cls, "createNet");
+fn_wrapper_3a_v<Context, decltype(&Context::connectPort), &Context::connectPort, conv_from_str<IdString>, conv_from_str<IdString>,
+conv_from_str<IdString>>::def_wrap(ctx_cls, "connectPort");
+fn_wrapper_2a_v<Context, decltype(&Context::disconnectPort), &Context::disconnectPort, conv_from_str<IdString>,
+conv_from_str<IdString>>::def_wrap(ctx_cls, "disconnectPort");
+fn_wrapper_1a_v<Context, decltype(&Context::ripupNet), &Context::ripupNet, conv_from_str<IdString>>::def_wrap(
+ ctx_cls, "ripupNet");
+fn_wrapper_1a_v<Context, decltype(&Context::lockNetRouting), &Context::lockNetRouting, conv_from_str<IdString>>::def_wrap(
+ ctx_cls, "lockNetRouting");
+
+fn_wrapper_2a<Context, decltype(&Context::createCell), &Context::createCell, deref_and_wrap<CellInfo>,
+conv_from_str<IdString>, conv_from_str<IdString>>::def_wrap(ctx_cls, "createCell");
+fn_wrapper_2a_v<Context, decltype(&Context::copyBelPorts), &Context::copyBelPorts,
+conv_from_str<IdString>, conv_from_str<BelId>>::def_wrap(ctx_cls, "copyBelPorts");
+
+fn_wrapper_1a<Context, decltype(&Context::getBelType), &Context::getBelType, conv_to_str<IdString>,
+conv_from_str<BelId>>::def_wrap(ctx_cls, "getBelType");
+fn_wrapper_1a<Context, decltype(&Context::checkBelAvail), &Context::checkBelAvail, pass_through<bool>,
+conv_from_str<BelId>>::def_wrap(ctx_cls, "checkBelAvail");
+fn_wrapper_1a<Context, decltype(&Context::getBelChecksum), &Context::getBelChecksum, pass_through<uint32_t>,
+conv_from_str<BelId>>::def_wrap(ctx_cls, "getBelChecksum");
+fn_wrapper_3a_v<Context, decltype(&Context::bindBel), &Context::bindBel, conv_from_str<BelId>,
+addr_and_unwrap<CellInfo>, pass_through<PlaceStrength>>::def_wrap(ctx_cls, "bindBel");
+fn_wrapper_1a_v<Context, decltype(&Context::unbindBel), &Context::unbindBel, conv_from_str<BelId>>::def_wrap(
+ ctx_cls, "unbindBel");
+fn_wrapper_1a<Context, decltype(&Context::getBoundBelCell), &Context::getBoundBelCell, deref_and_wrap<CellInfo>,
+conv_from_str<BelId>>::def_wrap(ctx_cls, "getBoundBelCell");
+fn_wrapper_1a<Context, decltype(&Context::getConflictingBelCell), &Context::getConflictingBelCell,
+ deref_and_wrap<CellInfo>, 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_2a<Context, decltype(&Context::getBelPinWire), &Context::getBelPinWire, conv_to_str<WireId>,
+conv_from_str<BelId>, conv_from_str<IdString>>::def_wrap(ctx_cls, "getBelPinWire");
+fn_wrapper_1a<Context, decltype(&Context::getWireBelPins), &Context::getWireBelPins, wrap_context<BelPinRange>,
+conv_from_str<WireId>>::def_wrap(ctx_cls, "getWireBelPins");
+
+fn_wrapper_1a<Context, decltype(&Context::getWireChecksum), &Context::getWireChecksum, pass_through<uint32_t>,
+conv_from_str<WireId>>::def_wrap(ctx_cls, "getWireChecksum");
+fn_wrapper_3a_v<Context, decltype(&Context::bindWire), &Context::bindWire, conv_from_str<WireId>,
+addr_and_unwrap<NetInfo>, pass_through<PlaceStrength>>::def_wrap(ctx_cls, "bindWire");
+fn_wrapper_1a_v<Context, decltype(&Context::unbindWire), &Context::unbindWire, conv_from_str<WireId>>::def_wrap(
+ ctx_cls, "unbindWire");
+fn_wrapper_1a<Context, decltype(&Context::checkWireAvail), &Context::checkWireAvail, pass_through<bool>,
+conv_from_str<WireId>>::def_wrap(ctx_cls, "checkWireAvail");
+fn_wrapper_1a<Context, decltype(&Context::getBoundWireNet), &Context::getBoundWireNet, deref_and_wrap<NetInfo>,
+conv_from_str<WireId>>::def_wrap(ctx_cls, "getBoundWireNet");
+fn_wrapper_1a<Context, decltype(&Context::getConflictingWireNet), &Context::getConflictingWireNet,
+ deref_and_wrap<NetInfo>, conv_from_str<WireId>>::def_wrap(ctx_cls, "getConflictingWireNet");
+
+fn_wrapper_0a<Context, decltype(&Context::getWires), &Context::getWires, wrap_context<WireRange>>::def_wrap(
+ ctx_cls, "getWires");
+
+fn_wrapper_0a<Context, decltype(&Context::getPips), &Context::getPips, wrap_context<AllPipRange>>::def_wrap(
+ ctx_cls, "getPips");
+fn_wrapper_1a<Context, decltype(&Context::getPipChecksum), &Context::getPipChecksum, pass_through<uint32_t>,
+conv_from_str<PipId>>::def_wrap(ctx_cls, "getPipChecksum");
+fn_wrapper_3a_v<Context, decltype(&Context::bindPip), &Context::bindPip, conv_from_str<PipId>,
+addr_and_unwrap<NetInfo>, pass_through<PlaceStrength>>::def_wrap(ctx_cls, "bindPip");
+fn_wrapper_1a_v<Context, decltype(&Context::unbindPip), &Context::unbindPip, conv_from_str<PipId>>::def_wrap(
+ ctx_cls, "unbindPip");
+fn_wrapper_1a<Context, decltype(&Context::checkPipAvail), &Context::checkPipAvail, pass_through<bool>,
+conv_from_str<PipId>>::def_wrap(ctx_cls, "checkPipAvail");
+fn_wrapper_1a<Context, decltype(&Context::getBoundPipNet), &Context::getBoundPipNet, deref_and_wrap<NetInfo>,
+conv_from_str<PipId>>::def_wrap(ctx_cls, "getBoundPipNet");
+fn_wrapper_1a<Context, decltype(&Context::getConflictingPipNet), &Context::getConflictingPipNet,
+ deref_and_wrap<NetInfo>, conv_from_str<PipId>>::def_wrap(ctx_cls, "getConflictingPipNet");
+
+fn_wrapper_1a<Context, decltype(&Context::getPipsDownhill), &Context::getPipsDownhill, wrap_context<PipRange>,
+conv_from_str<WireId>>::def_wrap(ctx_cls, "getPipsDownhill");
+fn_wrapper_1a<Context, decltype(&Context::getPipsUphill), &Context::getPipsUphill, wrap_context<PipRange>,
+conv_from_str<WireId>>::def_wrap(ctx_cls, "getPipsUphill");
+fn_wrapper_1a<Context, decltype(&Context::getWireAliases), &Context::getWireAliases, wrap_context<PipRange>,
+conv_from_str<WireId>>::def_wrap(ctx_cls, "getWireAliases");
+
+fn_wrapper_1a<Context, decltype(&Context::getPipSrcWire), &Context::getPipSrcWire, conv_to_str<WireId>,
+conv_from_str<PipId>>::def_wrap(ctx_cls, "getPipSrcWire");
+fn_wrapper_1a<Context, decltype(&Context::getPipDstWire), &Context::getPipDstWire, conv_to_str<WireId>,
+conv_from_str<PipId>>::def_wrap(ctx_cls, "getPipDstWire");
+fn_wrapper_1a<Context, decltype(&Context::getPipDelay), &Context::getPipDelay, pass_through<DelayInfo>,
+conv_from_str<PipId>>::def_wrap(ctx_cls, "getPipDelay");
+
+fn_wrapper_1a<Context, decltype(&Context::getPackagePinBel), &Context::getPackagePinBel, conv_to_str<BelId>,
+pass_through<std::string>>::def_wrap(ctx_cls, "getPackagePinBel");
+fn_wrapper_1a<Context, decltype(&Context::getBelPackagePin), &Context::getBelPackagePin, pass_through<std::string>,
+conv_from_str<BelId>>::def_wrap(ctx_cls, "getBelPackagePin");
+
+fn_wrapper_0a<Context, decltype(&Context::getChipName), &Context::getChipName, pass_through<std::string>>::def_wrap(
+ ctx_cls, "getChipName");
+fn_wrapper_0a<Context, decltype(&Context::archId), &Context::archId, conv_to_str<IdString>>::def_wrap(ctx_cls,
+"archId");
diff --git a/common/nextpnr.cc b/common/nextpnr.cc
index d73c0c02..933f124c 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
@@ -144,6 +145,27 @@ Property::Property(const std::string &strval) : is_string(true), str(strval), in
Property::Property(State bit) : is_string(false), str(std::string("") + char(bit)), intval(bit == S1) {}
+void CellInfo::addInput(IdString name)
+{
+ ports[name].name = name;
+ ports[name].type = PORT_IN;
+}
+void CellInfo::addOutput(IdString name)
+{
+ ports[name].name = name;
+ ports[name].type = PORT_OUT;
+}
+void CellInfo::addInout(IdString name)
+{
+ ports[name].name = name;
+ ports[name].type = PORT_INOUT;
+}
+
+void CellInfo::setParam(IdString name, Property value) { params[name] = value; }
+void CellInfo::unsetParam(IdString name) { params.erase(name); }
+void CellInfo::setAttr(IdString name, Property value) { attrs[name] = value; }
+void CellInfo::unsetAttr(IdString name) { attrs.erase(name); }
+
std::string Property::to_string() const
{
if (is_string) {
@@ -638,4 +660,67 @@ void BaseCtx::attributesToArchInfo()
getCtx()->assignArchInfo();
}
+NetInfo *BaseCtx::createNet(IdString name)
+{
+ NPNR_ASSERT(!nets.count(name));
+ NPNR_ASSERT(!net_aliases.count(name));
+ std::unique_ptr<NetInfo> net{new NetInfo};
+ net->name = name;
+ net_aliases[name] = name;
+ NetInfo *ptr = net.get();
+ nets[name] = std::move(net);
+ refreshUi();
+ return ptr;
+}
+
+void BaseCtx::connectPort(IdString net, IdString cell, IdString port)
+{
+ NetInfo *net_info = getNetByAlias(net);
+ CellInfo *cell_info = cells.at(cell).get();
+ connect_port(getCtx(), net_info, cell_info, port);
+}
+
+void BaseCtx::disconnectPort(IdString cell, IdString port)
+{
+ CellInfo *cell_info = cells.at(cell).get();
+ disconnect_port(getCtx(), cell_info, port);
+}
+
+void BaseCtx::ripupNet(IdString name)
+{
+ NetInfo *net_info = getNetByAlias(name);
+ std::vector<WireId> to_unbind;
+ for (auto &wire : net_info->wires)
+ to_unbind.push_back(wire.first);
+ for (auto &unbind : to_unbind)
+ getCtx()->unbindWire(unbind);
+}
+void BaseCtx::lockNetRouting(IdString name)
+{
+ NetInfo *net_info = getNetByAlias(name);
+ for (auto &wire : net_info->wires)
+ wire.second.strength = STRENGTH_USER;
+}
+
+CellInfo *BaseCtx::createCell(IdString name, IdString type)
+{
+ NPNR_ASSERT(!cells.count(name));
+ std::unique_ptr<CellInfo> cell{new CellInfo};
+ cell->name = name;
+ cell->type = type;
+ CellInfo *ptr = cell.get();
+ cells[name] = std::move(cell);
+ refreshUi();
+ return ptr;
+}
+
+void BaseCtx::copyBelPorts(IdString cell, BelId bel)
+{
+ CellInfo *cell_info = cells.at(cell).get();
+ for (auto pin : getCtx()->getBelPins(bel)) {
+ cell_info->ports[pin].name = pin;
+ cell_info->ports[pin].type = getCtx()->getBelPinType(bel, pin);
+ }
+}
+
NEXTPNR_NAMESPACE_END
diff --git a/common/nextpnr.h b/common/nextpnr.h
index 4f9f7f23..bae828f6 100644
--- a/common/nextpnr.h
+++ b/common/nextpnr.h
@@ -445,6 +445,15 @@ struct CellInfo : ArchCellInfo
Region *region = nullptr;
TimingConstrObjectId tmg_id;
+
+ void addInput(IdString name);
+ void addOutput(IdString name);
+ void addInout(IdString name);
+
+ void setParam(IdString name, Property value);
+ void unsetParam(IdString name);
+ void setAttr(IdString name, Property value);
+ void unsetAttr(IdString name);
};
enum TimingPortClass
@@ -741,7 +750,10 @@ struct BaseCtx
TimingConstrObjectId timingCellObject(CellInfo *cell);
TimingConstrObjectId timingPortObject(CellInfo *cell, IdString port);
- NetInfo *getNetByAlias(IdString alias) const { return nets.at(net_aliases.at(alias)).get(); }
+ NetInfo *getNetByAlias(IdString alias) const
+ {
+ return nets.count(alias) ? nets.at(alias).get() : nets.at(net_aliases.at(alias)).get();
+ }
void addConstraint(std::unique_ptr<TimingConstraint> constr);
void removeConstraint(IdString constrName);
@@ -752,6 +764,16 @@ struct BaseCtx
void addBelToRegion(IdString name, BelId bel);
void constrainCellToRegion(IdString cell, IdString region_name);
+ // Helper functions for Python bindings
+ NetInfo *createNet(IdString name);
+ void connectPort(IdString net, IdString cell, IdString port);
+ void disconnectPort(IdString cell, IdString port);
+ void ripupNet(IdString name);
+ void lockNetRouting(IdString name);
+
+ CellInfo *createCell(IdString name, IdString type);
+ void copyBelPorts(IdString cell, BelId bel);
+
// 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 3f2cb811..03979233 100644
--- a/common/pybindings.cc
+++ b/common/pybindings.cc
@@ -160,6 +160,22 @@ BOOST_PYTHON_MODULE(MODULE_NAME)
readonly_wrapper<CellInfo &, decltype(&CellInfo::pins), &CellInfo::pins, wrap_context<PinMap &>>::def_wrap(ci_cls,
"pins");
+ fn_wrapper_1a_v<CellInfo &, decltype(&CellInfo::addInput), &CellInfo::addInput, conv_from_str<IdString>>::def_wrap(
+ ci_cls, "addInput");
+ fn_wrapper_1a_v<CellInfo &, decltype(&CellInfo::addOutput), &CellInfo::addOutput,
+ conv_from_str<IdString>>::def_wrap(ci_cls, "addOutput");
+ fn_wrapper_1a_v<CellInfo &, decltype(&CellInfo::addInout), &CellInfo::addInout, conv_from_str<IdString>>::def_wrap(
+ ci_cls, "addInout");
+
+ fn_wrapper_2a_v<CellInfo &, decltype(&CellInfo::setParam), &CellInfo::setParam, conv_from_str<IdString>,
+ conv_from_str<Property>>::def_wrap(ci_cls, "setParam");
+ fn_wrapper_1a_v<CellInfo &, decltype(&CellInfo::unsetParam), &CellInfo::unsetParam,
+ conv_from_str<IdString>>::def_wrap(ci_cls, "unsetParam");
+ fn_wrapper_2a_v<CellInfo &, decltype(&CellInfo::setAttr), &CellInfo::setAttr, conv_from_str<IdString>,
+ conv_from_str<Property>>::def_wrap(ci_cls, "setAttr");
+ fn_wrapper_1a_v<CellInfo &, decltype(&CellInfo::unsetAttr), &CellInfo::unsetAttr,
+ conv_from_str<IdString>>::def_wrap(ci_cls, "unsetAttr");
+
auto pi_cls = class_<ContextualWrapper<PortInfo &>>("PortInfo", no_init);
readwrite_wrapper<PortInfo &, decltype(&PortInfo::name), &PortInfo::name, conv_to_str<IdString>,
conv_from_str<IdString>>::def_wrap(pi_cls, "name");