Skip to content

Commit

Permalink
Merge pull request #623 from Xilinx/2022.2.2
Browse files Browse the repository at this point in the history
2022.2.2 Staging Branch
  • Loading branch information
clavin-xlnx authored Mar 11, 2023
2 parents dfd46ee + 6afe589 commit 891d3e6
Show file tree
Hide file tree
Showing 12 changed files with 329 additions and 18 deletions.
4 changes: 2 additions & 2 deletions .classpath
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@
<classpathentry kind="lib" path="jars/kryo-5.2.1.jar"/>
<classpathentry kind="lib" path="jars/minlog-1.3.1.jar"/>
<classpathentry kind="lib" path="jars/jython-standalone-2.7.2.jar"/>
<classpathentry kind="lib" path="jars/rapidwright-api-lib-2022.2.1.jar">
<classpathentry kind="lib" path="jars/rapidwright-api-lib-2022.2.2.jar">
<attributes>
<attribute name="javadoc_location" value="jar:platform:/resource/RapidWright/jars/rapidwright-api-lib-2022.2.1-javadoc.jar!/"/>
<attribute name="javadoc_location" value="jar:platform:/resource/RapidWright/jars/rapidwright-api-lib-2022.2.2-javadoc.jar!/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="jars/jgrapht-core-1.3.0.jar"/>
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ on:
pull_request:

env:
RAPIDWRIGHT_VERSION: v2022.2.1-beta
RAPIDWRIGHT_VERSION: v2022.2.2-beta

jobs:
build:
Expand Down
12 changes: 12 additions & 0 deletions RELEASE_NOTES.TXT
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
============= RapidWright 2022.2.2-beta released on 2023-03-10 ================
Notes:
- Includes new API to ensure all downloaded/generated dependant files are present in RapidWright install (#613)
- Change in Cell.hashCode() and Cell.equals() behavior such that it now distinguishes routethru cells (#624), see Issue #611
- Fixes an issue with isFF() (#622)
- Resolves issue with Cells and Nets that contain backslashes not being properly loaded (#612)
- Fix for parsing gzipped EDIF files in parallel (#619)
- Fix for EDIF export bussed names that collide with bitty names (#616)

- API Additions:
- com.xilinx.rapidwright.device.Device "public void ensureDeviceCacheFileIsGenerated()"

============= RapidWright 2022.2.1-beta released on 2023-01-19 ================
Notes:
- Preserves hwdef information in DCP (#597)
Expand Down
3 changes: 2 additions & 1 deletion src/com/xilinx/rapidwright/design/tools/RelocationTools.java
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,8 @@ public static boolean relocate(Design design,
boolean error = false;
for (SiteInst si : siteInsts) {
for (Cell c : si.getCells()) {
if (!c.isLocked() && !cells.contains(c) && !c.getType().equals(PhysNetlistWriter.PORT)) {
if (!c.isLocked() && !c.isRoutethru() && !cells.contains(c)
&& !c.getType().equals(PhysNetlistWriter.PORT)) {
System.out.println("ERROR: Failed to relocate SiteInst '" + si.getName()
+ "' as it contains Cells both inside and outside of '" + instanceName + "'");
error = true;
Expand Down
16 changes: 8 additions & 8 deletions src/com/xilinx/rapidwright/router/RouteThruHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
package com.xilinx.rapidwright.router;

import java.io.File;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map.Entry;
Expand Down Expand Up @@ -53,11 +54,10 @@ public class RouteThruHelper {

private Device device;

private static String getSerializedFileName(Device device) {
String folderName = FileTools.getRapidWrightPath() + File.separator
+ FileTools.ROUTETHRU_FOLDER_NAME;
FileTools.makeDirs(folderName);
return folderName + File.separator + device.getName() + ".rt";
public static String getSerializedFileName(String deviceName) {
String fileName = FileTools.getRapidWrightResourceFileName(FileTools.getRouteThruFileName(deviceName));
FileTools.makeDirs(Paths.get(fileName).getParent().toString());
return fileName;
}

public RouteThruHelper(Device device) {
Expand All @@ -66,7 +66,7 @@ public RouteThruHelper(Device device) {
}

private void writeFile() {
try (Output out = FileTools.getKryoOutputStream(getSerializedFileName(device))) {
try (Output out = FileTools.getKryoOutputStream(getSerializedFileName(device.getName()))) {
out.writeInt(routeThrus.size());
for (Entry<TileTypeEnum, HashSet<Integer>> e : routeThrus.entrySet()) {
out.writeString(e.getKey().toString());
Expand All @@ -80,7 +80,7 @@ private void writeFile() {

private void readFile() {
routeThrus = new HashMap<TileTypeEnum, HashSet<Integer>>();
try (Input in = FileTools.getKryoInputStream(getSerializedFileName(device))) {
try (Input in = FileTools.getKryoInputStream(getSerializedFileName(device.getName()))) {
int count = in.readInt();
for (int i=0; i < count; i++) {
TileTypeEnum type = TileTypeEnum.valueOf(in.readString());
Expand All @@ -95,7 +95,7 @@ private void readFile() {
}

private void init() {
String serializedFileName = getSerializedFileName(device);
String serializedFileName = getSerializedFileName(device.getName());
routeThrus = new HashMap<TileTypeEnum,HashSet<Integer>>();
if (new File(serializedFileName).exists()) {
readFile();
Expand Down
98 changes: 93 additions & 5 deletions src/com/xilinx/rapidwright/util/FileTools.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,9 @@
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.zip.DeflaterOutputStream;
Expand All @@ -82,6 +84,7 @@
import com.xilinx.rapidwright.device.FamilyType;
import com.xilinx.rapidwright.device.Part;
import com.xilinx.rapidwright.device.PartNameTools;
import com.xilinx.rapidwright.router.RouteThruHelper;
import com.xilinx.rapidwright.timing.TimingModel;

/**
Expand Down Expand Up @@ -141,7 +144,7 @@ public class FileTools {
/** Base URL for download data files */
public static final String RAPIDWRIGHT_DATA_URL = "http://data.rapidwright.io/";
/** Suffix added to data file names to capture md5 status */
public static String MD5_DATA_FILE_SUFFIX = ".md5";
public static final String MD5_DATA_FILE_SUFFIX = ".md5";

private static boolean OVERRIDE_DATA_FILE_DOWNLOAD = false;

Expand Down Expand Up @@ -898,10 +901,85 @@ public static void forceUpdateAllDataFiles() {
}

/**
* Downloads the specified data file and version according to {@link #DATA_VERSION_FILE}. This
* will overwrite any existing file locally of the same name. This also validates the download
* is correct by calculating the md5sum of the downloaded file and comparing it to the expected
* one in {@link #DATA_VERSION_FILE}.
* Downloads and generates all potential data files to make this RapidWright
* installation static friendly. After running this method, RapidWright should
* not download any files, create any new directories or generate any new files.
* This is useful when a single RapidWright installation will be used by
* multiple processes simultaneously and/or when RapidWright needs to reside in
* a read-only space.
*
* @param devices The set of devices intended to be used for this installation
* (this simply saves download and generation time).
*/
public static void ensureDataFilesAreStaticInstallFriendly(String... devices) {
System.out.println("Download data files to " + getRapidWrightPath());
// Download all non-device data files
for (String fileName : DataVersions.dataVersionMap.keySet()) {
if (fileName.contains("data/devices")) continue;
downloadDataFile(fileName);
}

// Download all requested device data files and generate associated cache files
for (String deviceName : devices) {
Device device = Device.getDevice(deviceName);
device.ensureDeviceCacheFileIsGenerated();
new RouteThruHelper(device);
Device.releaseDeviceReferences();
}
}

/**
* Downloads and generates all potential data files to make this RapidWright
* installation static friendly. After running this method, RapidWright should
* not download any files, create any new directories or generate any new files.
* This is useful when a single RapidWright installation will be used by
* multiple processes simultaneously and/or when RapidWright needs to reside in
* a read-only space. This method will download all devices files and generate
* all cache files for each device.
*/
public static void ensureDataFilesAreStaticInstallFriendly() {
Set<String> devices = new HashSet<>();
for (Part p : PartNameTools.getParts()) {
devices.add(p.getDevice());
}
ensureDataFilesAreStaticInstallFriendly(devices.toArray(new String[devices.size()]));
}

/**
* Gets the list of all relative dependent data files given the set of devices
* provided.
*
* @param devices The list of devices to be used to compile the list of needed
* data files.
* @return The list of all necessary data files to operate RapidWright
* independently from downloads or generating cache files.
*/
public static List<String> getAllDependentDataFiles(String... devices) {
List<String> expectedFiles = new ArrayList<>();
for (String dataFile : new String[] { CELL_PIN_DEFAULTS_FILE_NAME, PART_DUMP_FILE_NAME,
PART_DB_PATH, UNISIM_DATA_FILE_NAME }) {
expectedFiles.add(dataFile);
expectedFiles.add(dataFile + MD5_DATA_FILE_SUFFIX);
}

for (String deviceName : devices) {
Part part = PartNameTools.getPart(deviceName);
String devResName = getDeviceResourceSuffix(part);
expectedFiles.add(devResName + DEVICE_FILE_SUFFIX);
expectedFiles.add(devResName + DEVICE_FILE_SUFFIX + MD5_DATA_FILE_SUFFIX);
expectedFiles.add(devResName + DEVICE_CACHE_FILE_SUFFIX);
expectedFiles.add(getRouteThruFileName(deviceName));
}
return expectedFiles;
}

/**
* Downloads the specified data file and version according to
* {@link #DATA_VERSION_FILE}. This will overwrite any existing file locally of
* the same name. This also validates the download is correct by calculating the
* md5sum of the downloaded file and comparing it to the expected one in
* {@link #DATA_VERSION_FILE}.
*
* @param fileName Name of the data file to download
* @return The md5 checksum of the downloaded file
*/
Expand Down Expand Up @@ -1076,6 +1154,16 @@ public static String getDeviceResourceCache(Part part) {
return getDeviceResourceSuffix(part) + DEVICE_CACHE_FILE_SUFFIX;
}

/**
* Gets the relative routethru file name for the given device.
*
* @param deviceName Name of the device
* @return Relative routethru data file name for the given device.
*/
public static String getRouteThruFileName(String deviceName) {
return ROUTETHRU_FOLDER_NAME + File.separator + deviceName + ".rt";
}

/**
* Checks for all device files present in the current RapidWright family path and returns
* a list of strings of those part names available to be used by the tool within the specified family.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Copyright (c) 2023, Advanced Micro Devices, Inc.
* All rights reserved.
*
* Author: Chris Lavin, AMD AEAI CTO Group.
*
* This file is part of RapidWright.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

package com.xilinx.rapidwright.support;

import org.junit.jupiter.params.converter.ArgumentConversionException;
import org.junit.jupiter.params.converter.SimpleArgumentConverter;

/**
* Used for converting comma separated String[] definitions in JUnit's CsvSource
* parameterized tests
*
*/
public class StringArrayConverter extends SimpleArgumentConverter {

@Override
protected Object convert(Object arg0, Class<?> arg1) throws ArgumentConversionException {
if (arg0 instanceof String && String[].class.isAssignableFrom(arg1)) {
String value = (String) arg0;
return value.split("\\s*,\\s*");
}
throw new RuntimeException("ERROR: Unrecognized parameter '"+arg0
+"', could not be converted to a String[].");
}
}
60 changes: 60 additions & 0 deletions test/src/com/xilinx/rapidwright/design/TestDesign.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,14 @@
import java.util.Arrays;
import java.util.HashSet;

import com.xilinx.rapidwright.edif.EDIFHierCellInst;
import com.xilinx.rapidwright.edif.EDIFHierNet;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Assumptions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import org.junit.jupiter.params.provider.ValueSource;

import com.xilinx.rapidwright.device.BEL;
Expand Down Expand Up @@ -247,4 +250,61 @@ public void testCopyCell() {
Design d2 = new Design("test2", d.getPartName());
Assertions.assertNotNull(d2.copyCell(orig, "copy"));
}

/**
* Input description: (synthesized out of context)
* module top(input a, b,
* input \this.is.an\.escaped\.net\.identifier ,
* output o);
*
* wire \this.is.another\\.escaped\$net\+&!identifier ;
*
* (* DONT_TOUCH="true" *)
* LUT2 \this.is.an\.escaped\.cell\.identifier (.O(\this.is.another\\.escaped\$net\+&!identifier ), .I0(\this.is.an\.escaped\.net\.identifier ), .I1(a));
*
* (* DONT_TOUCH="true" *)
* LUT2 \this.is.another\\.escaped\$cell\+&!identifier (.O(o), .I0(\this.is.another\\.escaped\$net\+&!identifier ), .I1(b));
*
* endmodule
*/
@ParameterizedTest
@CsvSource({
"design_with_backslash_2022.2.dcp",
"design_with_backslash_2022.1.dcp",
"design_with_backslash_2021.2.dcp",
})
public void testDesignWithBackslash(String dcp, @TempDir Path tempDir) {
Design design = RapidWrightDCP.loadDCP(dcp);
testDesignWithBackslashHelper(design);

if (dcp.endsWith("_2021.2.dcp") || dcp.endsWith("_2022.1.dcp")) {
final Path rapidWrightDcp = tempDir.resolve("rapidwright.dcp");
design.writeCheckpoint(rapidWrightDcp);
design = Design.readCheckpoint(rapidWrightDcp);
testDesignWithBackslashHelper(design);
}
}

private static void testDesignWithBackslashHelper(Design design) {
for (String cellName : Arrays.asList("this.is.an\\.escaped\\.cell\\.identifier",
"this.is.another\\\\.escaped\\$cell\\+&!identifier")) {
EDIFHierCellInst ehci = design.getNetlist().getHierCellInstFromName(cellName);
Assertions.assertNotNull(ehci);
Cell c = design.getCell(cellName);
Assertions.assertNotNull(c);
Assertions.assertEquals(ehci.getFullHierarchicalInstName(), c.getName());
}
Assertions.assertEquals(design.getCells().size(), 2);

for (String netName : Arrays.asList("this.is.an\\.escaped\\.net\\.identifier",
"this.is.another\\\\.escaped\\$net\\+&!identifier")) {
EDIFHierNet ehn = design.getNetlist().getHierNetFromName(netName);
Assertions.assertNotNull(ehn);
Net n = design.getNet(netName);
Assertions.assertNotNull(n);
Assertions.assertEquals(ehn.getHierarchicalNetName(), n.getName());
}
final int extraNets = 5; // {a, b, o, GLOBAL_USEDNET, GLOBAL_LOGIC0}
Assertions.assertEquals(design.getNets().size(), 2 + extraNets);
}
}
18 changes: 18 additions & 0 deletions test/src/com/xilinx/rapidwright/device/TestBEL.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,22 @@ public void testCanInvert(String siteName, String belName) {
Assertions.assertTrue(b.canInvert());

}

@ParameterizedTest
@CsvSource({
"xc7z020clg400-1,SLICE_X10Y10",
"xcku040-ffva1156-2-e,SLICE_X10Y10",
"xcau10p-ffvb676-1-i,SLICE_X10Y10",
"xcve1752-vsva2197-1LP-i-S,SLICE_X40Y0"
})
public void testIsFF(String deviceName, String siteName) {
Device d = Device.getDevice(deviceName);

Site s = d.getSite(siteName);
for (BEL bel : s.getBELs()) {
if (bel.isFF()) {
Assertions.assertEquals(bel.getBELClass(), BELClass.BEL);
}
}
}
}
11 changes: 11 additions & 0 deletions test/src/com/xilinx/rapidwright/device/TestNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -64,5 +64,16 @@ public void testNullNode() {
PIP p = d.getPIP("BLI_LS_CORE_X90Y335/BLI_LS_CORE_R180.HSR_GRP1_A_BLI_LOGIC_OUTS0->>BLI_GRP1_A_BLI_LOGIC_OUTS0");
Assertions.assertNull(p.getStartNode());
}

@Test
public void testUphillNodeIsInvalid() {
// link_design -part [lindex [get_parts xcvu440*] 0]
// get_nodes -uphill -of [get_nodes INT_INT_INTERFACE_XIPHY_FT_X157Y688/LOGIC_OUTS_R0]
// WARNING: [Vivado 12-2683] No nodes matched 'get_nodes -uphill -of [get_nodes INT_INT_INTERFACE_XIPHY_FT_X157Y688/LOGIC_OUTS_R0]'
Device d = Device.getDevice("xcvu440");
Node n = d.getNode("INT_INT_INTERFACE_XIPHY_FT_X157Y688/LOGIC_OUTS_R0");
Assertions.assertNotNull(n);
Assertions.assertTrue(n.getAllUphillNodes().isEmpty());
}
}

Loading

0 comments on commit 891d3e6

Please sign in to comment.