Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master' into rwroute_opt
Browse files Browse the repository at this point in the history
  • Loading branch information
eddieh-xlnx committed Mar 1, 2023
2 parents c84ccd8 + d2cc9b0 commit 802eb0d
Show file tree
Hide file tree
Showing 9 changed files with 323 additions and 54 deletions.
11 changes: 10 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ cd RapidWright
```

More details here:
http://www.rapidwright.io/docs/Automatic_Install.html#automatic-install
http://www.rapidwright.io/docs/Install.html


### How to Update RapidWright to the Latest Revision
Expand All @@ -53,6 +53,15 @@ git pull
./gradlew updateJars
```

### Python Setup

```
pip install rapidwright
```

More details here:
http://www.rapidwright.io/docs/Install_RapidWright_as_a_Python_PIP_Package.html

### Development setup

RapidWright includes a git pre-commit hook that runs some quick checks before commits. After cloning the repository, the hook is not enabled by default. To enable it, run this command:
Expand Down
23 changes: 17 additions & 6 deletions src/com/xilinx/rapidwright/design/DesignTools.java
Original file line number Diff line number Diff line change
Expand Up @@ -2140,13 +2140,17 @@ public static boolean unrouteAlternativeOutputSitePin(Net net) {
* @param sitePin The site pin to query.
* @return A list of hierarchical port instances that connect to the site pin.
*/
public static ArrayList<EDIFHierPortInst> getPortInstsFromSitePinInst(SitePinInst sitePin) {
public static List<EDIFHierPortInst> getPortInstsFromSitePinInst(SitePinInst sitePin) {
SiteInst siteInst = sitePin.getSiteInst();
BELPin[] belPins = siteInst.getSiteWirePins(sitePin.getName());
ArrayList<EDIFHierPortInst> portInsts = new ArrayList<EDIFHierPortInst>();
for (BELPin belPin : belPins) {
List<EDIFHierPortInst> portInsts = new ArrayList<>();
Queue<BELPin> queue = new LinkedList<>();
queue.addAll(Arrays.asList(belPins));
while (!queue.isEmpty()) {
BELPin belPin = queue.remove();
if (belPin.isOutput() == sitePin.isOutPin()) {
if (belPin.getBEL().getBELClass() == BELClass.RBEL) {
BEL bel = belPin.getBEL();
if (bel.getBELClass() == BELClass.RBEL) {
// Routing BEL, lets look ahead/behind it
SitePIP sitePIP = siteInst.getUsedSitePIP(belPin);
if (sitePIP != null) {
Expand All @@ -2158,8 +2162,15 @@ public static ArrayList<EDIFHierPortInst> getPortInstsFromSitePinInst(SitePinIns
}
}
} else {
EDIFHierPortInst portInst = getPortInstFromBELPin(siteInst, belPin);
if (portInst != null) portInsts.add(portInst);
Cell lut = bel.isLUT() ? siteInst.getCell(bel) : null;
if (lut != null && lut.isRoutethru() && lut.getLogicalPinMapping(belPin.getName()) != null) {
BELPin opin = bel.getPin("O" + bel.getName().charAt(1));
belPins = siteInst.getSiteWirePins(opin.getSiteWireName());
queue.addAll(Arrays.asList(belPins));
} else {
EDIFHierPortInst portInst = getPortInstFromBELPin(siteInst, belPin);
if (portInst != null) portInsts.add(portInst);
}
}
}
}
Expand Down
46 changes: 43 additions & 3 deletions src/com/xilinx/rapidwright/edif/EDIFHierNet.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,14 @@
*/
package com.xilinx.rapidwright.edif;

import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Collection;
import java.util.ArrayDeque;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Queue;
import java.util.Set;

import org.jetbrains.annotations.NotNull;

Expand Down Expand Up @@ -156,6 +157,33 @@ public EDIFHierCellInst getHierarchicalInst() {
return hierarchicalInst;
}

/**
* Gets the sorted ArrayList of EDIFHierPortInsts on this net as a collection.
* @return The collection of EDIFPortInsts on this net.
*/
public Collection<EDIFHierPortInst> getPortInsts() {
Collection<EDIFPortInst> portInsts = net.getPortInsts();
Collection<EDIFHierPortInst> hierPortInsts = new ArrayList<>(portInsts.size());
for (EDIFPortInst portInst : portInsts) {
hierPortInsts.add(new EDIFHierPortInst(hierarchicalInst, portInst));
}
return hierPortInsts;
}

/**
* This returns all sources on the net, either output ports of the
* cell instances in the cell or the top level input ports.
* @return A list of EDIFHierPortInst sources.
*/
public List<EDIFHierPortInst> getSourcePortInsts(boolean includeTopLevelPorts) {
List<EDIFPortInst> portInsts = net.getSourcePortInsts(includeTopLevelPorts);
List<EDIFHierPortInst> hierPortInsts = new ArrayList<>(portInsts.size());
for (EDIFPortInst portInst : portInsts) {
hierPortInsts.add(new EDIFHierPortInst(hierarchicalInst, portInst));
}
return hierPortInsts;
}

/**
* Gets all connected leaf port instances on this hierarchical net and its aliases.
* @return The list of all leaf cell port instances connected to this hierarchical net and its
Expand All @@ -173,10 +201,22 @@ public List<EDIFHierPortInst> getLeafHierPortInsts() {
* aliases.
*/
public List<EDIFHierPortInst> getLeafHierPortInsts(boolean includeSourcePins) {
return getLeafHierPortInsts(includeSourcePins, new HashSet<>());
}

/**
* Gets all connected leaf port instances on this hierarchical net and its aliases.
* @param includeSourcePins A flag to include source pins in the result. Setting this to false
* only returns the sinks.
* @param visited An initial set of EDIFHierNet-s that have already been visited and will not
* be visited again. Pre-populating this set can be useful for blocking traversal.
* @return The list of all leaf cell port instances connected to this hierarchical net and its
* aliases.
*/
public List<EDIFHierPortInst> getLeafHierPortInsts(boolean includeSourcePins, Set<EDIFHierNet> visited) {
List<EDIFHierPortInst> leafCellPins = new ArrayList<>();
Queue<EDIFHierNet> queue = new ArrayDeque<>();
queue.add(this);
HashSet<EDIFHierNet> visited = new HashSet<>();

EDIFHierNet parentNet = null;
while (!queue.isEmpty()) {
Expand Down
3 changes: 2 additions & 1 deletion src/com/xilinx/rapidwright/edif/EDIFNet.java
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,8 @@ public void addPortInst(EDIFPortInst portInst, boolean deferSort) {
if (deferSort) {
portInsts.deferSortAdd(portInst);
} else {
portInsts.add(portInst);
boolean added = portInsts.add(portInst);
assert(added);
}
}

Expand Down
5 changes: 3 additions & 2 deletions src/com/xilinx/rapidwright/edif/EDIFNetlist.java
Original file line number Diff line number Diff line change
Expand Up @@ -1199,7 +1199,7 @@ public List<EDIFHierNet> getNetAliases(EDIFHierNet initialNet) {
// Moving up in hierarchy
if (!p.getHierarchicalInst().isTopLevelInst()) {
final EDIFHierPortInst upPort = p.getPortInParent();
if (upPort != null) {
if (upPort != null && upPort.getNet() != null) {
queue.add(upPort.getHierarchicalNet());
}
}
Expand Down Expand Up @@ -1331,7 +1331,7 @@ private void generateParentNetMap() {
// Checks if cell is primitive or black box
if (eci.getCellType().getCellInsts().size() == 0 && eci.getCellType().getNets().size() == 0) {
for (EDIFPortInst portInst : eci.getPortInsts()) {
if (portInst.isOutput()) {
if (portInst.isOutput() && portInst.getNet() != null) {
queue.add(new EDIFHierPortInst(currInst, portInst));
}
}
Expand All @@ -1342,6 +1342,7 @@ private void generateParentNetMap() {
}

for (EDIFHierPortInst pr : queue) {
assert(pr.getNet() != null);
EDIFHierNet parentNetName = pr.getHierarchicalNet();
for (EDIFHierNet alias : getNetAliases(parentNetName)) {
parentNetMap.put(alias, parentNetName);
Expand Down
107 changes: 97 additions & 10 deletions src/com/xilinx/rapidwright/edif/EDIFTools.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
import java.util.Map.Entry;
import java.util.Queue;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;

import com.xilinx.rapidwright.design.Cell;
import com.xilinx.rapidwright.design.Design;
Expand Down Expand Up @@ -143,7 +144,7 @@ public class EDIFTools {

public static final String LOAD_TCL_SUFFIX = "_load.tcl";

public static int UNIQUE_COUNT = 0;
public static final AtomicInteger UNIQUE_COUNT = new AtomicInteger();

/**
* Flag to set a feature where any .edf file that is attempted to be loaded will check if an
Expand All @@ -154,8 +155,8 @@ public class EDIFTools {
public static final boolean RW_ENABLE_EDIF_BINARY_CACHING =
System.getenv("RW_ENABLE_EDIF_BINARY_CACHING") != null;

private static String getUniqueSuffix() {
return "_rw_created" + UNIQUE_COUNT++;
public static String getUniqueSuffix() {
return "_rw_created" + UNIQUE_COUNT.getAndIncrement();
}

/**
Expand Down Expand Up @@ -467,13 +468,40 @@ else if (c == '[') {
return Math.abs(left - right) + 1;
}

private static EDIFNet createUniqueNet(EDIFCell parentCell, String netName) {
/**
* Create a unique net in the provided parent EDIFCell with the preferred provided
* name. If such a net already exists in this cell, append a unique suffix.
* @param parentCell EDIFCell in which new net is to be created.
* @param netName Preferred net name.
* @return Newly created EDIFNet.
*/
public static EDIFNet createUniqueNet(EDIFCell parentCell, String netName) {
if (parentCell.getNet(netName) != null) {
netName += getUniqueSuffix();
}
return new EDIFNet(netName, parentCell);
}

/**
* Create a unique port in the provided parent EDIFCell with the preferred provided
* name. If such a port already exists in this cell, append a unique suffix.
* This method checks for the existence of the given name as well as for its root bus,
* e.g. for portName 'foo[9]', both this exact name and 'foo' will be checked.
* @param parentCell EDIFCell in which new port is to be created.
* @param portName Preferred port name.
* @param dir EDIFDirection.
* @param width Bit width.
* @return Newly created EDIFPort.
*/
public static EDIFPort createUniquePort(EDIFCell parentCell, String portName, EDIFDirection dir, int width) {
String rootBusName = getRootBusName(portName);
if (parentCell.getPort(rootBusName) != null ||
(rootBusName != portName && parentCell.getPort(portName) != null)) {
portName += getUniqueSuffix();
}
return parentCell.createPort(portName, dir, width);
}

/**
* Connects two existing logical port insts together by creating new ports and nets on all cells
* instantiated between their levels of hierarchy. It assumes the netlist cells involved only
Expand Down Expand Up @@ -522,11 +550,7 @@ public static void connectPortInstsThruHier(EDIFHierPortInst src, EDIFHierPortIn
} else {
// no port to the parent cell above exists, create one
EDIFCell cellType = hierParentInst.getCellType();
String newPortName = newName;
if (cellType.getPort(newPortName) != null) {
newPortName += getUniqueSuffix();
}
EDIFPort port = cellType.createPort(newPortName,
EDIFPort port = createUniquePort(cellType, newName,
hierPortInst == src ? EDIFDirection.OUTPUT : EDIFDirection.INPUT, 1);

currNet.createPortInst(port);
Expand All @@ -536,7 +560,7 @@ public static void connectPortInstsThruHier(EDIFHierPortInst src, EDIFHierPortIn
// We don't need to create another net, just connect to the src's net
currNet = finalSrc.getNet();
} else {
currNet = createUniqueNet(hierParentInst.getCellType(), newName);
currNet = createUniqueNet(hierParentInst.getCellType(), port.getName());
}
outerPortInst = currNet.createPortInst(port, prevInst);
}
Expand Down Expand Up @@ -567,6 +591,69 @@ public static void connectPortInstsThruHier(EDIFHierPortInst src, EDIFHierPortIn
finalSrc.getNet().addPortInst(finalSnk.getPortInst());
}

/**
* Connects an existing logical net and logical port inst together by creating new ports and
* nets on all cells instantiated between their levels of hierarchy. This is a helper method
* on top of {@link #connectPortInstsThruHier(EDIFHierPortInst,EDIFHierPortInst,String)}
* for identifying the correct source and sink pins to be provided to this, according to
* whether the provided pin argument is an input or output pin (and finding the appropriate
* pin from the provided net).
* @param net The logical net
* @param pin The logical port inst source or sink
* @param newName A unique name to be used in creating the ports and nets
*/
public static void connectPortInstsThruHier(EDIFHierNet net, EDIFHierPortInst pin,
String newName) {
EDIFHierPortInst src;
EDIFHierPortInst snk;

EDIFHierCellInst netInst = net.getHierarchicalInst();
EDIFCell cellType = netInst.getCellType();

// FIXME: This method always punches a new port upwards
// -- what if the src/snk was in a lower part of the hierarchy?

if (pin.isOutput()) {
src = pin;

// Find an input portInst to use
snk = null;
for (EDIFHierPortInst pi : net.getPortInsts()) {
if (pi.isInput()) {
snk = pi;
break;
}
}
if (snk == null) {
// Create one if one doesn't exist
EDIFPort port = createUniquePort(cellType, newName, EDIFDirection.INPUT, 1);
net.getNet().createPortInst(port);

// EDIFTools.connectPortInstsThruHier() does not support top-level portInsts;
// need to create a port inst in the parent cell too
EDIFNet upperNet = createUniqueNet(netInst.getParent().getCellType(), port.getName());
snk = new EDIFHierPortInst(netInst.getParent(), upperNet.createPortInst(port, netInst.getInst()));
}
} else {
List<EDIFHierPortInst> sources = net.getSourcePortInsts(false);
if (!sources.isEmpty()) {
src = sources.get(0);
} else {
EDIFPort port = createUniquePort(cellType, newName, EDIFDirection.OUTPUT, 1);
net.getNet().createPortInst(port);

// EDIFTools.connectPortInstsThruHier() does not support top-level portInsts;
// need to create a port inst in the parent cell too
EDIFNet upperNet = createUniqueNet(netInst.getParent().getCellType(), port.getName());
src = new EDIFHierPortInst(netInst.getParent(), upperNet.createPortInst(port, netInst.getInst()));
}

snk = pin;
}

connectPortInstsThruHier(src, snk, newName);
}

/**
* Specialized function to connect a debug port within an EDIF netlist.
* @param topPortNet The top-level net that connects to the debug core's input port.
Expand Down
Loading

0 comments on commit 802eb0d

Please sign in to comment.