Skip to content

Commit e15fe6d

Browse files
committed
Adding a test
Signed-off-by: Chris Lavin <[email protected]>
1 parent 9dedc2a commit e15fe6d

File tree

3 files changed

+64
-4
lines changed

3 files changed

+64
-4
lines changed

src/com/xilinx/rapidwright/design/tools/InlineFlopTools.java

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
import com.xilinx.rapidwright.design.Unisim;
4040
import com.xilinx.rapidwright.design.blocks.PBlock;
4141
import com.xilinx.rapidwright.device.BEL;
42+
import com.xilinx.rapidwright.device.Series;
4243
import com.xilinx.rapidwright.device.Site;
4344
import com.xilinx.rapidwright.eco.ECOPlacementHelper;
4445
import com.xilinx.rapidwright.edif.EDIFCell;
@@ -63,21 +64,24 @@ public class InlineFlopTools {
6364
private static final String PBLOCK_OPT = "--pblock";
6465
private static final String REMOVE_FLOPS_OPT = "--remove_flops";
6566

66-
private static final String INLINE_SUFFIX = "_rw_inline_flop";
67+
public static final String INLINE_SUFFIX = "_rw_inline_flop";
6768

6869
/**
6970
* Add flip flops inline on all the top-level ports of an out-of-context design.
7071
* This is useful for placed out-of-context kernels prior to routing so that
7172
* after the flops have been placed, the router is forced to route connections
7273
* of each of the ports to each of the flops. This can help alleviate congestion
73-
* when the kernels are placed/relocated in context.
74+
* when the kernels are placed/relocated in context. Note this assumes the
75+
* design is not implemented as in most contexts it will be placed and routed
76+
* immediately following this modification.
7477
*
7578
* @param design The design to modify
7679
* @param clkNet Name of the clock net to use on which to add the flops
7780
* @param keepOut The pblock used to contain the kernel and the added flops will
7881
* not be placed inside this area.
7982
*/
8083
public static void createAndPlaceFlopsInlineOnTopPorts(Design design, String clkNet, PBlock keepOut) {
84+
assert (design.getSiteInsts().size() == 0);
8185
EDIFCell top = design.getTopEDIFCell();
8286
Site start = keepOut.getAllSites("SLICE").iterator().next(); // TODO this is a bit wasteful
8387
boolean exclude = true;
@@ -89,6 +93,10 @@ public static void createAndPlaceFlopsInlineOnTopPorts(Design design, String clk
8993
Set<SiteInst> siteInstsToRoute = new HashSet<>();
9094

9195
for (EDIFPort port : top.getPorts()) {
96+
// Don't flop the clock net
97+
if (port.getName().equals(clkNet)) {
98+
continue;
99+
}
92100
if (port.isBus()) {
93101
for (int i : port.getBitBlastedIndicies()) {
94102
EDIFPortInst inst = port.getInternalPortInstFromIndex(i);
@@ -160,6 +168,7 @@ public static void removeInlineFlops(Design design) {
160168
Net vcc = design.getVccNet();
161169
Set<SitePinInst> vccPins = new HashSet<>();
162170
pinsToRemove.put(vcc, vccPins);
171+
String[] staticPins = new String[] { "CKEN1", design.getSeries() == Series.Versal ? "RST" : "SRST1" };
163172
for (EDIFCellInst inst : design.getTopEDIFCell().getCellInsts()) {
164173
if (inst.getName().endsWith(INLINE_SUFFIX)) {
165174
Cell flop = design.getCell(inst.getName());
@@ -169,8 +178,11 @@ public static void removeInlineFlops(Design design) {
169178
for (SitePinInst pin : si.getSitePinInsts()) {
170179
pinsToRemove.computeIfAbsent(pin.getNet(), p -> new HashSet<>()).add(pin);
171180
}
172-
vccPins.add(vcc.createPin("CKEN1", si));
173-
vccPins.add(vcc.createPin("RST", si));
181+
for (String staticPin : staticPins) {
182+
if (si.getSitePinInst(staticPin) == null) {
183+
vccPins.add(vcc.createPin(staticPin, si));
184+
}
185+
}
174186

175187
cellsToRemove.add(inst);
176188
}
@@ -217,6 +229,7 @@ public static void removeInlineFlops(Design design) {
217229
}
218230

219231
top.removeCellInst(c);
232+
design.removeCell(c.getName());
220233
}
221234

222235
}

src/com/xilinx/rapidwright/util/VivadoTools.java

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,45 @@ public static ReportRouteStatusResult routeDesignAndGetStatus(Design design, Pat
388388
return routeDesignAndGetStatus(dcp, workdir, encrypted);
389389
}
390390

391+
/**
392+
* Run Vivado's `place_design` and `route_design` command on the design provided
393+
* and get the `report_route_status` results. Note: this method does not
394+
* preserve the routed output from Vivado.
395+
*
396+
* @param design The design to route and report on.
397+
* @param workdir Directory to work within.
398+
* @return The results of `report_route_status`.
399+
*/
400+
public static ReportRouteStatusResult placeAndRouteDesignAndGetStatus(Design design, Path workdir) {
401+
boolean encrypted = !design.getNetlist().getEncryptedCells().isEmpty();
402+
Path dcp = workdir.resolve("placeAndRouteDesignAndGetStatus.dcp");
403+
design.writeCheckpoint(dcp);
404+
return placeAndRouteDesignAndGetStatus(dcp, workdir, encrypted);
405+
}
406+
407+
/**
408+
* Run Vivado's `place_design` and `route_design` command on the provided DCP
409+
* path and return the `report_route_status` results. Note: this method does not
410+
* preserve the routed output from Vivado.
411+
*
412+
* @param dcp Path to DCP to route and report on.
413+
* @param workdir Directory to work within.
414+
* @param encrypted Indicates whether DCP contains encrypted EDIF cells.
415+
* @return The results of `report_route_status`.
416+
*/
417+
public static ReportRouteStatusResult placeAndRouteDesignAndGetStatus(Path dcp, Path workdir, boolean encrypted) {
418+
final Path outputLog = workdir.resolve("outputLog.log");
419+
420+
StringBuilder sb = new StringBuilder();
421+
sb.append(createTclDCPLoadCommand(dcp, encrypted));
422+
sb.append(PLACE_DESIGN + "; ");
423+
sb.append(ROUTE_DESIGN + "; ");
424+
sb.append(REPORT_ROUTE_STATUS + "; ");
425+
426+
List<String> log = VivadoTools.runTcl(outputLog, sb.toString(), true);
427+
return new ReportRouteStatusResult(log);
428+
}
429+
391430
/**
392431
* Run Vivado's `route_design` command on the provided DCP path and return the
393432
* `report_route_status` results. Note: this method does not preserve the routed

test/shared/com/xilinx/rapidwright/util/VivadoToolsHelper.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,4 +60,12 @@ public static void assertRoutedSuccessfullyByVivado(Design design, Path dir) {
6060
ReportRouteStatusResult rrs = VivadoTools.routeDesignAndGetStatus(design, dir);
6161
Assertions.assertTrue(rrs.isFullyRouted());
6262
}
63+
64+
public static void assertCanBeFullyPlacedAndRoutedByVivado(Design design, Path dir) {
65+
if (!FileTools.isVivadoOnPath()) {
66+
return;
67+
}
68+
ReportRouteStatusResult rrs = VivadoTools.placeAndRouteDesignAndGetStatus(design, dir);
69+
Assertions.assertTrue(rrs.isFullyRouted());
70+
}
6371
}

0 commit comments

Comments
 (0)