diff options
Diffstat (limited to 'common')
-rw-r--r-- | common/arch_pybindings_shared.h | 114 | ||||
-rw-r--r-- | common/nextpnr.cc | 85 | ||||
-rw-r--r-- | common/nextpnr.h | 24 | ||||
-rw-r--r-- | common/pybindings.cc | 16 |
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"); |