Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[EDIF] Fixes rare bus renaming collision #1065

Merged
merged 6 commits into from
Sep 20, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion src/com/xilinx/rapidwright/edif/EDIFPort.java
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,10 @@ public void exportEDIF(OutputStream os, EDIFWriteLegalNameCache<?> cache, boolea
* @throws IOException
*/
public void exportEDIFBusName(OutputStream os, EDIFWriteLegalNameCache<?> cache) throws IOException {
exportSomeEDIFName(os, getName(), cache.getEDIFRename(busName));
String busName = getBusName(false);
EDIFPort collision = parentCell.getPort(busName);
byte[] rename = collision == null ? cache.getEDIFRename(busName) : cache.getBusCollisionEDIFRename(busName);
exportSomeEDIFName(os, getName(), rename == null ? busName.getBytes(StandardCharsets.UTF_8) : rename);
}

/**
Expand Down
4 changes: 3 additions & 1 deletion src/com/xilinx/rapidwright/edif/EDIFPortInst.java
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,9 @@ public void writeEDIFExport(OutputStream os, byte[] indent, EDIFWriteLegalNameCa
}
else {
os.write(EXPORT_CONST_MEMBER);
os.write(cache.getLegalEDIFName(getPort().getBusName(true)));
String busName = getPort().getBusName(false);
EDIFPort collision = getPort().getParentCell().getPort(busName);
os.write(collision == null ? cache.getLegalEDIFName(busName) : cache.getBusCollisionEDIFRename(busName));
os.write(' ');
os.write(Integer.toString(index).getBytes(StandardCharsets.UTF_8));
os.write(')');
Expand Down
8 changes: 8 additions & 0 deletions src/com/xilinx/rapidwright/edif/EDIFWriteLegalNameCache.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,15 @@ public abstract class EDIFWriteLegalNameCache<T> {
*/
private final Map<String, byte[]>[] renames;

private final Map<String, byte[]> busCollisionRenames;

private EDIFWriteLegalNameCache(Map<String, T> usedRenames, Supplier<Map<String, byte[]>> renameSupplier) {
this.usedRenames = usedRenames;
this.renames = new Map[256];
for (int i = 0; i < renames.length; i++) {
renames[i] = renameSupplier.get();
}
this.busCollisionRenames = new HashMap<>();
}

protected abstract int getAndIncrement(String rename);
Expand Down Expand Up @@ -86,6 +89,11 @@ public byte[] getEDIFRename(String name) {
return rename;
}

public byte[] getBusCollisionEDIFRename(String name) {
return busCollisionRenames.computeIfAbsent(name,
n -> (EDIFTools.makeNameEDIFCompatible(n) + "_BUS_").getBytes(StandardCharsets.UTF_8));
}

public static EDIFWriteLegalNameCache<?> singleThreaded() {
return new EDIFWriteLegalNameCache<Integer>(new HashMap<>(), HashMap::new) {

Expand Down
32 changes: 32 additions & 0 deletions test/src/com/xilinx/rapidwright/edif/TestEDIFNetlist.java
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,38 @@ public void testBussedPortNamingCollision(@TempDir Path path) {
Assertions.assertEquals(port1.getWidth(), testPort1.getWidth());
}

@Test
public void testBussedPortReNamingCollision(@TempDir Path path) {
final EDIFNetlist origNetlist = EDIFTools.createNewNetlist("test");

EDIFCell top = origNetlist.getTopCell();

EDIFCellInst ff = top.createChildCellInst("ff", Design.getPrimitivesLibrary().getCell("FDRE"));
origNetlist.getHDIPrimitivesLibrary().addCell(ff.getCellType());

String portName = "unfortunate_name";

// Create two ports, one single-bit and another bussed with the same root name
EDIFPort port0 = top.createPort(portName + "[2:0]", EDIFDirection.INOUT, 3);
EDIFPort port1 = top.createPort(portName + "_[1:0]", EDIFDirection.INOUT, 2);

EDIFNet net0 = top.createNet("net0");
net0.createPortInst(port0, 0);
net0.createPortInst("D", ff);

EDIFNet net1 = top.createNet("net1");
net1.createPortInst(port1, 1);
net1.createPortInst("R", ff);

Path tempFile = path.resolve("test.edf");
origNetlist.exportEDIF(tempFile);

// Check using EDIFNetlistComparator
EDIFNetlist testNetlist = EDIFTools.readEdifFile(tempFile);
EDIFNetlistComparator comparer = new EDIFNetlistComparator();
Assertions.assertEquals(0, comparer.compareNetlists(origNetlist, testNetlist));
}

@Test
public void testGetIOStandard() {
final EDIFNetlist netlist = EDIFTools.createNewNetlist("test");
Expand Down
Loading