I wrote up some example code (sorry its in Java, but you can port it to Python syntax pretty easily) that performs the manipulation you want. The first step is to get the logical netlist to be connected in the way you want, after that, it is just cleaning up the physical implementation to match the logical. Since you want to connect something across hierarchy, that can be a little tricky. Luckily, in RapidWright there is an API that handles the heavy lifting called EDIFTools.connectLogicalNetAcrossHierarchy() that will create all the intermediate ports and nets in between the desired source and destination (added nets in magenta):
package com.xilinx.rapidwright.examples;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import com.xilinx.rapidwright.design.Cell;
import com.xilinx.rapidwright.design.Design;
import com.xilinx.rapidwright.design.SiteInst;
import com.xilinx.rapidwright.design.SitePinInst;
import com.xilinx.rapidwright.edif.EDIFHierPortInst;
import com.xilinx.rapidwright.edif.EDIFNet;
import com.xilinx.rapidwright.edif.EDIFNetlist;
import com.xilinx.rapidwright.edif.EDIFTools;
import com.xilinx.rapidwright.router.Router;
public class OSMExample {
public static void main(String[] args) {
Design design = Design.readCheckpoint("osmlock_routed.dcp");
EDIFNetlist netlist = design.getNetlist();
// Need to flatten netlist to use connectLogicalNetAcrossHierarchy()
EDIFTools.flattenNetlist(design);
String srcPortName = "zcu104_fpx_i/FPDiv_0/inst/SelFunctionTable7/fR0_d1_reg[28]_i_1/O[1]";
String snkPortName = "zcu104_fpx_i/OSM_Array_0/inst/generate_osm_array[0].osm_inst/Q1_reg/C";
EDIFHierPortInst src = netlist.getHierPortInstFromName(srcPortName);
EDIFHierPortInst sink = netlist.getHierPortInstFromName(snkPortName);
Cell srcCell = design.getCell(src.getFullHierarchicalInstName());
Cell sinkCell = design.getCell(sink.getFullHierarchicalInstName());
// Propagate logical net minusOp[28] into the target instance of the OSM
Map<String,EDIFNet> parentInstNameToLogNetMap = new HashMap<String, EDIFNet>();
parentInstNameToLogNetMap.put(src.getHierarchicalInstName(), src.getNet());
EDIFNet dstNet = EDIFTools.connectLogicalNetAcrossHierarchy(sink.getHierarchicalInstName(),
src.getHierarchicalInstName(), parentInstNameToLogNetMap, netlist);
// Disconnect the C input and connect it to the propagated D[0] net
EDIFNet netToDisconnect = sink.getPortInst().getNet();
netToDisconnect.removePortInst(sink.getPortInst());
dstNet.addPortInst(sink.getPortInst());
// Gets the physical net and creates output pin for routing, routes intra-site net
// in source site
Net physNet = design.getNet(netlist.getParentNetName(src.getHierarchicalNetName()));
SiteInst siteInst = srcCell.getSiteInst();
SitePinInst newPin = physNet.createPin(true, "BMUX", siteInst);
siteInst.routeIntraSiteNet(physNet, srcCell.getBELPin(src), newPin.getBELPin());
// Gets the destination sink pin and updates intra-site routing accordingly
SitePinInst sinkPin = sinkCell.getSitePinFromPortInst(sink.getPortInst(), null);
sinkPin.getNet().removePin(sinkPin, true);
sinkCell.unrouteLogicalPinInSite(sink.getPortInst().getName());
sinkPin.setNet(physNet);
siteInst = sinkCell.getSiteInst();
siteInst.routeIntraSiteNet(physNet, sinkPin.getBELPin(), sinkCell.getBELPin(sink));
// Routes the inter-site net with the new pin using the RapidWright router
// (not robust in the face of high congestion, but works here)
Router rtr = new Router(design);
ArrayList<SitePinInst> sinks = new ArrayList<SitePinInst>();
sinks.add(sinkPin);
rtr.routePinsReEntrant(sinks, false);
design.writeCheckpoint("osmlock_modified.dcp");
}
}
Let me know if you have questions.