From 5cd2b55f1f0ad729e95f344a5e8f4c8d00400669 Mon Sep 17 00:00:00 2001 From: David Shah Date: Sun, 15 Sep 2019 19:30:56 +0100 Subject: python: Adding helper functions for netlist modification Signed-off-by: David Shah --- common/arch_pybindings_shared.h | 16 ++++++++ common/nextpnr.cc | 85 +++++++++++++++++++++++++++++++++++++++++ common/nextpnr.h | 24 +++++++++++- common/pybindings.cc | 16 ++++++++ 4 files changed, 140 insertions(+), 1 deletion(-) (limited to 'common') diff --git a/common/arch_pybindings_shared.h b/common/arch_pybindings_shared.h index b547dabf..b90e80ec 100644 --- a/common/arch_pybindings_shared.h +++ b/common/arch_pybindings_shared.h @@ -20,6 +20,22 @@ fn_wrapper_2a_v, conv_from_str>::def_wrap(ctx_cls, "constrainCellToRegion"); +fn_wrapper_1a, +conv_from_str>::def_wrap(ctx_cls, "createNet"); +fn_wrapper_3a_v, conv_from_str, +conv_from_str>::def_wrap(ctx_cls, "connectPort"); +fn_wrapper_2a_v, +conv_from_str>::def_wrap(ctx_cls, "disconnectPort"); +fn_wrapper_1a_v>::def_wrap( + ctx_cls, "ripupNet"); +fn_wrapper_1a_v>::def_wrap( + ctx_cls, "lockNetRouting"); + +fn_wrapper_2a, +conv_from_str, conv_from_str>::def_wrap(ctx_cls, "createCell"); +fn_wrapper_2a_v, conv_from_str>::def_wrap(ctx_cls, "copyBelPorts"); + fn_wrapper_1a, conv_from_str>::def_wrap(ctx_cls, "getBelType"); fn_wrapper_1a, 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 +#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 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 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 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 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>::def_wrap(ci_cls, "pins"); + fn_wrapper_1a_v>::def_wrap( + ci_cls, "addInput"); + fn_wrapper_1a_v>::def_wrap(ci_cls, "addOutput"); + fn_wrapper_1a_v>::def_wrap( + ci_cls, "addInout"); + + fn_wrapper_2a_v, + conv_from_str>::def_wrap(ci_cls, "setParam"); + fn_wrapper_1a_v>::def_wrap(ci_cls, "unsetParam"); + fn_wrapper_2a_v, + conv_from_str>::def_wrap(ci_cls, "setAttr"); + fn_wrapper_1a_v>::def_wrap(ci_cls, "unsetAttr"); + auto pi_cls = class_>("PortInfo", no_init); readwrite_wrapper, conv_from_str>::def_wrap(pi_cls, "name"); -- cgit v1.2.3