Skip to content

Commit c2bfa8b

Browse files
authored
Merge pull request #1292 from Xilinx/2025.1.3
2025.1.3
2 parents d65a9c7 + 583c4f3 commit c2bfa8b

File tree

21 files changed

+859
-182
lines changed

21 files changed

+859
-182
lines changed

.classpath

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,9 @@
3333
<classpathentry kind="lib" path="jars/kryo-5.2.1.jar"/>
3434
<classpathentry kind="lib" path="jars/minlog-1.3.1.jar"/>
3535
<classpathentry kind="lib" path="jars/jython-standalone-2.7.2.jar"/>
36-
<classpathentry kind="lib" path="jars/rapidwright-api-lib-2025.1.1.jar">
36+
<classpathentry kind="lib" path="jars/rapidwright-api-lib-2025.1.3.jar">
3737
<attributes>
38-
<attribute name="javadoc_location" value="jar:platform:/resource/RapidWright/jars/rapidwright-api-lib-2025.1.1-javadoc.jar!/"/>
38+
<attribute name="javadoc_location" value="jar:platform:/resource/RapidWright/jars/rapidwright-api-lib-2025.1.3-javadoc.jar!/"/>
3939
</attributes>
4040
</classpathentry>
4141
<classpathentry kind="lib" path="jars/jgrapht-core-1.3.0.jar"/>

.github/workflows/build.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ on:
55
pull_request:
66

77
env:
8-
RAPIDWRIGHT_VERSION: v2025.1.1-beta
8+
RAPIDWRIGHT_VERSION: v2025.1.3-beta
99

1010
jobs:
1111
build:

RELEASE_NOTES.TXT

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,27 @@
1+
============= RapidWright 2025.1.3-beta released on 2025-10-02 ================
2+
Notes:
3+
- [RWRoute] Versal fixes for clocking, static nets and general routing (#1280)
4+
- [DesignTools] createCeClkOfRoutethruFFToVCC() to handle AND2B1L/OR2L (#1286)
5+
- [TestBELPin] Test that BELPin.getConnectedSitePin() thru IMRs (#1285)
6+
- Adds RW_COPY_EDNS_ON_DCP_WRITE and adds helper to extract EDNs (#1288)
7+
- Move Site.getIntTile() -> DeviceTools.getIntTile() and fix for Versal (#1287)
8+
- Cannot close the zip file (refactor?) (#1289)
9+
- Cleanup gradle 9 warnings and Java linting warnings for Java 17 (#1277)
10+
- [DesignTools] Handles VCC/GND connections properly in populateBlackBox() (#1278)
11+
- rc2 and tests for removing alternate SPIs (#1276)
12+
- [TimingGraph] Improving Report Timing Example; add some APIs (#1273)
13+
- Propagates EDN files when loading RapidWright-generated DCPs
14+
- [BELPin] getConnectedSitePin() to punch thru IMRs
15+
- Site.getIntTile() to call DeviceTools.getIntTile(Site)
16+
- Fix SitePinInst removal for alternate pins
17+
- Address unplaced modules when getting BELPins
18+
19+
API Additions:
20+
21+
============= RapidWright 2025.1.2-beta released on 2025-10-02 ================
22+
The rapidwright-api-lib jar got corrupted on Maven Central so this release version
23+
had to be abandoned. Please use 2025.1.3 instead.
24+
125
============= RapidWright 2025.1.1-beta released on 2025-08-13 ================
226
Notes:
327
- Unisim Primitive Mappings Updates for Versal (#1271)

build.gradle

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ plugins {
77
id 'java'
88
id 'maven-publish'
99
id 'signing'
10-
id 'org.jreleaser' version '1.19.0'
10+
// JReleaser adds at least an extra 20 seconds to setup time
11+
// id 'org.jreleaser' version '1.20.0' // Uncomment for release
1112
}
1213

1314
apply from: 'common.gradle'
@@ -211,24 +212,24 @@ publishing {
211212
}
212213
}
213214

214-
// TODO - The next release of jreleaser will resolve a Gradle 9 warning. Once we can update, to 1.20.0, we can restore this section (only used for releases)
215-
// jreleaser {
216-
// signing {
217-
// active = "ALWAYS"
218-
// armored = true
219-
// }
220-
// deploy {
221-
// maven {
222-
// mavenCentral {
223-
// sonatype {
224-
// active = 'ALWAYS'
225-
// url = 'https://central.sonatype.com/api/v1/publisher'
226-
// stagingRepository('build/staging-deploy')
227-
// }
228-
// }
229-
// }
230-
// }
231-
// }
215+
/* Uncomment for release
216+
jreleaser {
217+
signing {
218+
active = "ALWAYS"
219+
armored = true
220+
}
221+
deploy {
222+
maven {
223+
mavenCentral {
224+
sonatype {
225+
active = 'ALWAYS'
226+
url = 'https://central.sonatype.com/api/v1/publisher'
227+
stagingRepository('build/staging-deploy')
228+
}
229+
}
230+
}
231+
}
232+
}*/
232233

233234
task testPython(type:Test) {
234235
group = "verification"

src/com/xilinx/rapidwright/design/DesignTools.java

Lines changed: 119 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1018,19 +1018,20 @@ public static void postBlackBoxCleanup(String hierCellName, Design design, boole
10181018
// updated.
10191019
for (EDIFPortInst portInst : inst.getInst().getPortInsts()) {
10201020
EDIFNet net = portInst.getNet();
1021-
EDIFHierNet netName = new EDIFHierNet(parentInst, net);
1022-
EDIFHierNet parentNetName = netlist.getParentNet(netName);
1023-
Net parentNet = design.getNet(parentNetName.getHierarchicalNetName());
1024-
if (parentNet == null) {
1025-
if (net.isVCC()) {
1026-
parentNet = design.getVccNet();
1027-
} else if (net.isGND()) {
1028-
parentNet = design.getGndNet();
1029-
} else {
1030-
parentNet = new Net(parentNetName);
1021+
EDIFHierNet hierNet = new EDIFHierNet(parentInst, net);
1022+
Net parentNet;
1023+
if (net.isGND()) {
1024+
parentNet = design.getGndNet();
1025+
} else if (net.isVCC()) {
1026+
parentNet = design.getVccNet();
1027+
} else {
1028+
EDIFHierNet parentHierName = netlist.getParentNet(hierNet);
1029+
parentNet = design.getNet(parentHierName.getHierarchicalNetName());
1030+
if (parentNet == null) {
1031+
parentNet = new Net(parentHierName);
10311032
}
10321033
}
1033-
for (EDIFHierNet netAlias : netlist.getNetAliases(netName)) {
1034+
for (EDIFHierNet netAlias : netlist.getNetAliases(hierNet)) {
10341035
if (parentNet.getName().equals(netAlias.getHierarchicalNetName())) continue;
10351036
Net alias = design.getNet(netAlias.getHierarchicalNetName());
10361037
if (alias != null) {
@@ -2204,6 +2205,7 @@ public static boolean placeCell(Cell c, Design design) {
22042205
* @return The list of pins that were created or an empty list if none were created.
22052206
*/
22062207
public static List<SitePinInst> createMissingSitePinInsts(Design design, Net net) {
2208+
boolean isVersal = design.getSeries() == Series.Versal;
22072209
EDIFNetlist n = design.getNetlist();
22082210
List<EDIFHierPortInst> physPins = n.getPhysicalPins(net);
22092211
if (physPins == null) {
@@ -2279,7 +2281,12 @@ public static List<SitePinInst> createMissingSitePinInsts(Design design, Net net
22792281
// Use the net attached to the phys pin
22802282
Net siteWireNet = si.getNetFromSiteWire(belPin.getSiteWireName());
22812283
if (siteWireNet == null) {
2282-
continue;
2284+
if (isVersal && net.isStaticNet() && bel.isLUT()) {
2285+
siteWireNet = net;
2286+
si.routeIntraSiteNet(net, belPin, belPin);
2287+
} else {
2288+
continue;
2289+
}
22832290
}
22842291
if (siteWireNet != net && !siteWireNet.isStaticNet()) {
22852292
if (parentEhn == null) {
@@ -3328,6 +3335,14 @@ public static void makePhysNetNamesConsistent(Design design) {
33283335
continue;
33293336
}
33303337

3338+
// Check to make sure net is not improperly categorized
3339+
EDIFNet srcNetAlias = parentHierNet.getNet();
3340+
if (srcNetAlias.isGND()) {
3341+
parentPhysNet = design.getGndNet();
3342+
} else if (srcNetAlias.isVCC()) {
3343+
parentPhysNet = design.getVccNet();
3344+
}
3345+
33313346
if (!hierNet.equals(parentHierNet)) {
33323347
String parentNetName = parentHierNet.getNet().getName();
33333348
// Assume that a net named <const1> or <const0> is always a VCC or GND net
@@ -3361,24 +3376,34 @@ public static void createPossiblePinsToStaticNets(Design design) {
33613376
createCeSrRstPinsToVCC(design);
33623377
}
33633378

3379+
/**
3380+
* Examines a design for FFs configured as routethrus or as AND2B1L/OR2L functionality, ensuring that the CE pins of
3381+
* the used BELs are connected via the correct intra-site routing to VCC and their CLK pins are connected to
3382+
* GND (which is supplied via inversion from VCC).
3383+
* @param design Design to be processed.
3384+
*/
33643385
public static void createCeClkOfRoutethruFFToVCC(Design design) {
3365-
if (design.getSeries() == Series.Versal) {
3366-
// Versal have OUTMUX[A-H][12]-es for bypassing FFs
3367-
return;
3368-
}
3386+
boolean isVersal = (design.getSeries() == Series.Versal);
33693387
Net vcc = design.getVccNet();
33703388
Net gnd = design.getGndNet();
33713389
for (SiteInst si : design.getSiteInsts()) {
33723390
if (!Utils.isSLICE(si)) {
33733391
continue;
33743392
}
33753393
for (Cell cell : si.getCells()) {
3376-
if (!cell.isFFRoutethruCell()) {
3394+
BEL bel = cell.getBEL();
3395+
if (bel == null || !bel.isFF() || bel.isAnyIMR()) {
33773396
continue;
33783397
}
33793398

3380-
BEL bel = cell.getBEL();
3381-
if (bel == null) {
3399+
String cellType = cell.getType();
3400+
if (cellType.equals("AND2B1L") || cellType.equals("OR2L")) {
3401+
// pass
3402+
} else if (cell.isFFRoutethruCell()) {
3403+
// Versal have OUTMUX[A-H][12]-es for bypassing FFs
3404+
assert(!isVersal);
3405+
// pass
3406+
} else {
33823407
continue;
33833408
}
33843409

@@ -3393,6 +3418,13 @@ public static void createCeClkOfRoutethruFFToVCC(Design design) {
33933418
// ...and GND at CLK
33943419
BELPin clkInput = bel.getPin("CLK");
33953420
BELPin clkInvOut = clkInput.getSourcePin();
3421+
if (isVersal) {
3422+
// On Versal only, punch through the FF_CLK_MOD
3423+
assert(clkInvOut.getBEL().isSliceFFClkMod());
3424+
assert(clkInvOut.getName().equals("CLK_OUT"));
3425+
clkInvOut = clkInvOut.getBEL().getPin("CLK").getSourcePin();
3426+
}
3427+
assert(clkInvOut.getBELName().matches("CLK[12]?INV"));
33963428
si.routeIntraSiteNet(gnd, clkInvOut, clkInput);
33973429
BELPin clkInvIn = clkInvOut.getBEL().getPin(0);
33983430
String clkInputSitePinName = clkInvIn.getConnectedSitePinName();
@@ -3442,7 +3474,8 @@ public static void createA1A6ToStaticNets(Design design) {
34423474
String pinName = belName.charAt(0) + "1";
34433475
SitePinInst spi = si.getSitePinInst(pinName);
34443476
if (spi == null) {
3445-
vccNet.createPin(pinName, si);
3477+
spi = vccNet.createPin(pinName, si);
3478+
si.routeIntraSiteNet(vccNet, spi.getBELPin(), bel.getPin("A1"));
34463479
} else {
34473480
assert(spi.getNet().isVCCNet());
34483481
}
@@ -3465,8 +3498,9 @@ public static void createA1A6ToStaticNets(Design design) {
34653498
String pinName = belName.charAt(0) + "1";
34663499
SitePinInst spi = si.getSitePinInst(pinName);
34673500
if (spi == null) {
3468-
vccNet.createPin(pinName, si);
3501+
spi = vccNet.createPin(pinName, si);
34693502
}
3503+
si.routeIntraSiteNet(vccNet, spi.getBELPin(), lut6Bel.getPin("A1"));
34703504

34713505
// SRL16Es that have been transformed from SRLC32E require GND on their A6 pin
34723506
if ("SRLC32E".equals(cell.getPropertyValueString("XILINX_LEGACY_PRIM"))) {
@@ -4623,4 +4657,68 @@ public static void replaceEncryptedCells(Design design, List<Path> netlists) {
46234657
n.removeUnusedCellsFromAllWorkLibraries();
46244658
n.setEncryptedCells(netlists.stream().map(Object::toString).collect(Collectors.toList()));
46254659
}
4660+
4661+
public static void updateVersalXPHYPinsForDMC(Design design) {
4662+
// Check for XPHY BEL pin remapping needs (DMC remappings)
4663+
for (Cell cell : design.getCells()) {
4664+
if (!cell.getType().equals("XPHY"))
4665+
continue;
4666+
for (EDIFHierPortInst portInst : cell.getEDIFHierCellInst().getHierPortInsts()) {
4667+
if (portInst.isInput()) {
4668+
EDIFCell srcType = null;
4669+
for (EDIFHierPortInst src : portInst.getHierarchicalNet()
4670+
.getLeafHierPortInsts(true, false)) {
4671+
srcType = src.getPortInst().getCellInst().getCellType();
4672+
}
4673+
4674+
// If we are being driven by the memory controller, switch BEL pins to DMC
4675+
// inputs
4676+
if (srcType.getName().startsWith("DDRMC") || srcType.getName().equals("XPLL")) {
4677+
String belPin = cell.getPhysicalPinMapping(portInst.getPortInst().getName());
4678+
BELPin newBELPin = cell.getBEL().getPin("DMC_" + belPin);
4679+
if (newBELPin != null) {
4680+
String logPin = cell.removePinMapping(belPin);
4681+
cell.addPinMapping(newBELPin.getName(), logPin);
4682+
4683+
// update site routing and site pin
4684+
SiteInst si = cell.getSiteInst();
4685+
BELPin oldBELPin = cell.getBEL().getPin(belPin);
4686+
Net net = si.getNetFromSiteWire(oldBELPin.getSiteWireName());
4687+
SitePinInst sink = si.getSitePinInst(oldBELPin.getSourcePin().getName());
4688+
net.removePin(sink);
4689+
String newSitePinName = newBELPin.getSourcePin().getName();
4690+
if (si.getSite().getPinIndex(newSitePinName) == -1) {
4691+
throw new RuntimeException("ERROR");
4692+
}
4693+
net.createPin(newSitePinName, si);
4694+
}
4695+
}
4696+
} else {
4697+
assert (portInst.isOutput());
4698+
EDIFCell snkType = null;
4699+
for (EDIFHierPortInst snk : portInst.getHierarchicalNet()
4700+
.getLeafHierPortInsts(false, true)) {
4701+
snkType = snk.getPortInst().getCellInst().getCellType();
4702+
}
4703+
4704+
// If we are driving the memory controller, make sure we use the DMC pins
4705+
if (snkType.getName().startsWith("DDRMC")) {
4706+
BELPin belPin = cell.getBELPin(portInst);
4707+
BELPin dmcBELPin = cell.getBEL().getPin("DMC_" + belPin.getName());
4708+
if (dmcBELPin != null) {
4709+
// Ensure we only use site pin on the DMC output
4710+
SiteInst si = cell.getSiteInst();
4711+
Net net = si.getNetFromSiteWire(belPin.getSiteWireName());
4712+
if (net != null) {
4713+
net = si.getNetFromSiteWire(belPin.getSiteWireName());
4714+
assert (belPin.getSiteConns().size() == 1);
4715+
BELPin siteBELPin = belPin.getSiteConns().get(0);
4716+
net.removePin(si.getSitePinInst(siteBELPin.getName()));
4717+
}
4718+
}
4719+
}
4720+
}
4721+
}
4722+
}
4723+
}
46264724
}

src/com/xilinx/rapidwright/device/IntentCode.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,8 @@ public boolean isUltraScaleClockDistribution() {
170170
public boolean isVersalClocking() {
171171
return NODE_GLOBAL_HDISTR == this || NODE_GLOBAL_HDISTR_LOCAL == this || NODE_GLOBAL_HROUTE_HSR == this ||
172172
NODE_GLOBAL_VDISTR == this || NODE_GLOBAL_VDISTR_LVL2 == this || NODE_GLOBAL_VROUTE == this ||
173-
NODE_GLOBAL_GCLK == this || NODE_GLOBAL_LEAF == this || NODE_GLOBAL_BUFG == this;
173+
NODE_GLOBAL_GCLK == this || NODE_GLOBAL_LEAF == this || NODE_GLOBAL_BUFG == this
174+
|| NODE_GLOBAL_HROUTE == this;
174175
}
175176

176177
private static final int SERIES7_START_IDX = 23;

src/com/xilinx/rapidwright/edif/EDIFTools.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
import com.xilinx.rapidwright.tests.CodePerfTracker;
6262
import com.xilinx.rapidwright.util.FileTools;
6363
import com.xilinx.rapidwright.util.Pair;
64+
import com.xilinx.rapidwright.util.Params;
6465

6566

6667
/**
@@ -1008,6 +1009,18 @@ public static List<String> getEDNFiles(Path parent) {
10081009
return Collections.emptyList();
10091010
}
10101011

1012+
public static List<String> getEDNFilesFromDCPLoadTclScript(Path tclFileName) {
1013+
List<String> ednFiles = new ArrayList<>();
1014+
for (String line : FileTools.getLinesFromTextFile(tclFileName.toString())) {
1015+
if (line.startsWith("read_edif")) {
1016+
int start = line.indexOf('{');
1017+
int end = line.lastIndexOf('}');
1018+
ednFiles.add(line.subSequence(start + 1, end).toString());
1019+
}
1020+
}
1021+
return ednFiles;
1022+
}
1023+
10111024
public static Path getEDIFParentDir(Path edifFileName) {
10121025
Path parent = edifFileName == null ? null : edifFileName.getParent();
10131026
return parent == null ? Paths.get(System.getProperty("user.dir")) : parent;
@@ -1106,6 +1119,23 @@ public static void writeEDIFFile(OutputStream out, String dcpFileName, EDIFNetli
11061119
public static void writeTclLoadScriptForPartialEncryptedDesigns(EDIFNetlist edif,
11071120
Path dcpFileName, String partName) {
11081121
ArrayList<String> lines = new ArrayList<String>();
1122+
if (Params.RW_COPY_EDNS_ON_DCP_WRITE && edif.getEncryptedCells().size() > 0) {
1123+
Path destDir = dcpFileName.getParent();
1124+
System.out.println("INFO: Copying *.edn files to: " + destDir);
1125+
List<String> newLocs = new ArrayList<>();
1126+
for (String cellName : edif.getEncryptedCells()) {
1127+
Path src = Paths.get(cellName);
1128+
String dst = destDir.resolve(src.getFileName()).toString();
1129+
if (!FileTools.copyFile(src.toString(), dst)) {
1130+
System.err.println("WARNING: Failed to copy " + src + " to " + dst);
1131+
newLocs.add(src.toString());
1132+
} else {
1133+
newLocs.add(dst);
1134+
}
1135+
}
1136+
edif.setEncryptedCells(newLocs);
1137+
}
1138+
11091139
for (String cellName : edif.getEncryptedCells()) {
11101140
if (cellName.endsWith(".edn") || cellName.endsWith(".edf")) {
11111141
lines.add(EDIFNetlist.READ_EDIF_CMD + " {" + cellName + "}");

0 commit comments

Comments
 (0)