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 4 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
16 changes: 15 additions & 1 deletion src/com/xilinx/rapidwright/edif/EDIFPort.java
Original file line number Diff line number Diff line change
Expand Up @@ -291,9 +291,23 @@ 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));
exportSomeEDIFName(os, getName(), getBusEDIFRename(cache));
}

/**
* Handles bus name collisions with single bit ports (same root name) to avoid
* EDIF export name legalization collisions.
*
* @param cache The current EDIF name legalization cache
* @return The legalize EDIF bus name for this port
*/
protected byte[] getBusEDIFRename(EDIFWriteLegalNameCache<?> cache) {
String busName = getBusName(false);
boolean collision = parentCell.getPortMap().containsKey(busName);
byte[] rename = collision ? cache.getBusCollisionEDIFRename(busName) : cache.getEDIFRename(busName);
return rename == null ? busName.getBytes(StandardCharsets.UTF_8) : rename;
}

/**
* @return the parentCell
*/
Expand Down
2 changes: 1 addition & 1 deletion src/com/xilinx/rapidwright/edif/EDIFPortInst.java
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ public void writeEDIFExport(OutputStream os, byte[] indent, EDIFWriteLegalNameCa
}
else {
os.write(EXPORT_CONST_MEMBER);
os.write(cache.getLegalEDIFName(getPort().getBusName(true)));
os.write(getPort().getBusEDIFRename(cache));
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
7 changes: 6 additions & 1 deletion src/com/xilinx/rapidwright/examples/MultGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,12 @@ public static PBlock createMult(Design d, Site origin, int width, String designN
for (int i=0; i < port.getWidth(); i++) {
EDIFNet net = top.createNet(port.getBusName() + (port.getWidth() > 1 ? "[" + i + "]" : ""));
int ii = port.getWidth() - 1 - i;
net.createPortInst(port.getBusName(), ii, inst);
if (port.isBus()) {
net.createPortInst(port.getBusName(), ii, inst);
} else {
net.createPortInst(port, inst);
}

Net physNet = d.createNet(inst + "/" + net.getName());

// Correct differences in physical pin names
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 bussed ports with a common root name, one having a trailing '_' underscore
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