Skip to content

Commit

Permalink
[EDIF] EDIFNetlist.collapseMacroUnisims() to not clobber cell (#675)
Browse files Browse the repository at this point in the history
* Fix collapse macro collision, plus optimize

Signed-off-by: Eddie Hung <[email protected]>

* Test for collapseMacroUnisims() does not collide

Signed-off-by: Eddie Hung <[email protected]>

* EDIFNetlist.getHDIPrimitive() to deep copy too

Signed-off-by: Eddie Hung <[email protected]>

* Fix EDIFNetlist.getHDIPrimitive()

Signed-off-by: Eddie Hung <[email protected]>

* Another EDIFNetlist.getHDIPrimitive() fix

Signed-off-by: Eddie Hung <[email protected]>

---------

Signed-off-by: Eddie Hung <[email protected]>
  • Loading branch information
eddieh-xlnx authored May 23, 2023
1 parent 31ba049 commit 993f4ad
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 35 deletions.
72 changes: 48 additions & 24 deletions src/com/xilinx/rapidwright/edif/EDIFNetlist.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
Expand Down Expand Up @@ -256,9 +257,9 @@ public EDIFCell getHDIPrimitive(Unisim unisim) {
EDIFLibrary lib = getHDIPrimitivesLibrary();
EDIFCell cell = lib.getCell(unisim.name());
if (cell == null) {
cell = Design.getUnisimCell(unisim);
cell = new EDIFCell(lib, Design.getUnisimCell(unisim), unisim.name());
}
return lib.addCell(cell);
return cell;
}

public EDIFLibrary getWorkLibrary() {
Expand Down Expand Up @@ -1639,29 +1640,26 @@ public void expandMacroUnisims(Series series) {
throw new RuntimeException("failed to find cell macro "+cellName+", we are in "+lib.getName());
}
primsToRemoveOnCollapse.add(cellName);
EDIFCell copy = new EDIFCell(netlistPrims, macro, cellName);
if (copy.getCellInsts().size() > 0) {
for (EDIFCellInst copyInst : copy.getCellInsts()) {
EDIFCell primCell = netlistPrims.getCell(copyInst.getCellType().getName());
if (primCell == null) {
primCell = new EDIFCell(netlistPrims, copyInst.getCellType());
primsToRemoveOnCollapse.add(copyInst.getCellType().getName());
}
copyInst.setCellType(primCell);
newCell = new EDIFCell(netlistPrims, macro, cellName);
for (EDIFCellInst childInst : newCell.getCellInsts()) {
EDIFCell primCell = netlistPrims.getCell(childInst.getCellType().getName());
if (primCell == null) {
primCell = new EDIFCell(netlistPrims, childInst.getCellType());
primsToRemoveOnCollapse.add(childInst.getCellType().getName());
}
childInst.setCellType(primCell);
}
newCell = copy;
}
assert(newCell == netlistPrims.getCell(cellName));
inst.setCellType(newCell);
for (EDIFCellInst childInst : newCell.getCellInsts()) {
// Check if we already have a copy
EDIFCell existingCellType = netlistPrims.getCell(childInst.getCellName());
if (existingCellType == null) {
existingCellType = new EDIFCell(netlistPrims, childInst.getCellType());
primsToRemoveOnCollapse.add(existingCellType.getName());
}
childInst.setCellType(existingCellType);
}
}
}
}
for (EDIFCell cell : lib.getCells()) {
for (EDIFNet net : cell.getNets()) {
for (EDIFPortInst portInst : net.getPortInsts()) {
EDIFCell parent = portInst.getPort().getParentCell();
assert (parent.getLibrary().getCell(parent.getName()) == parent);
}
}
}
Expand All @@ -1679,15 +1677,41 @@ public void collapseMacroUnisims(Series series) {
ArrayList<EDIFCell> reinsert = new ArrayList<EDIFCell>();
Map<String, Pair<String, EnumSet<IOStandard>>> seriesMacroCollapseExceptionMap =
macroCollapseExceptionMap.getOrDefault(series, Collections.emptyMap());
Map<EDIFCell, EDIFCell> updateCellTypes = new IdentityHashMap<>();
for (EDIFCell cell : prims.getCells()) {
if (macros.containsCell(cell.getName())) {
cell.makePrimitive();
if (seriesMacroCollapseExceptionMap.containsKey(cell.getName())) {
cell.rename(seriesMacroCollapseExceptionMap.get(cell.getName()).getFirst());
reinsert.add(cell);
Pair<String, EnumSet<IOStandard>> exception = seriesMacroCollapseExceptionMap.get(cell.getName());
if (exception != null) {
EDIFCell existingCell = prims.getCell(exception.getFirst());
if (existingCell != null) {
// Existing cell (e.g. OBUFDS) already exists/used in primitives library
// thus cannot simply rename it (e.g. from OBUFDS_DUAL_BUF)
updateCellTypes.put(cell, existingCell);
} else {
cell.rename(exception.getFirst());
reinsert.add(cell);
}
}
}
}

if (!updateCellTypes.isEmpty()) {
// Update all cell references
for (EDIFLibrary lib : getLibraries()) {
if (lib.isHDIPrimitivesLibrary())
continue;
for (EDIFCell cell : new ArrayList<>(lib.getCells())) {
for (EDIFCellInst inst : cell.getCellInsts()) {
EDIFCell newCellType = updateCellTypes.get(inst.getCellType());
if (newCellType != null) {
inst.setCellType(newCellType);
}
}
}
}
}

for (EDIFCell cell : reinsert) {
prims.removeCell(cell);
prims.addCell(cell);
Expand Down
63 changes: 52 additions & 11 deletions test/src/com/xilinx/rapidwright/edif/TestEDIFNetlist.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import java.util.Map;
import java.util.Set;

import com.xilinx.rapidwright.design.Unisim;
import com.xilinx.rapidwright.device.Series;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
Expand Down Expand Up @@ -91,17 +92,57 @@ void testMacroExpansionException(@TempDir Path tempDir) {
Design loadAgain = Design.readCheckpoint(outputDCP);
Assertions.assertTrue(loadAgain.getNetlist().getHDIPrimitivesLibrary().containsCell("OBUFTDS"));

final Part part2 = PartNameTools.getPart(Device.KCU105);
Design testDesign2 = createSamplePrimitiveDesign("OBUFDS", part2);
testDesign2.getNetlist().expandMacroUnisims(part.getSeries());
Assertions.assertTrue(testDesign2.getNetlist().getHDIPrimitivesLibrary().containsCell("OBUFDS_DUAL_BUF"));
testDesign2.getNetlist().collapseMacroUnisims(part.getSeries());
Assertions.assertTrue(testDesign2.getNetlist().getHDIPrimitivesLibrary().containsCell("OBUFDS"));
Assertions.assertFalse(testDesign2.getNetlist().getHDIPrimitivesLibrary().containsCell("OBUFDS_DUAL_BUF"));
Design testDesign2 = createSamplePrimitiveDesign("OBUFDS", part);
EDIFNetlist testNetlist2 = testDesign2.getNetlist();

testNetlist2.expandMacroUnisims(part.getSeries());

Assertions.assertTrue(testNetlist2.getHDIPrimitivesLibrary().containsCell("OBUFDS_DUAL_BUF"));

testNetlist2.collapseMacroUnisims(part.getSeries());

Assertions.assertTrue(testNetlist2.getHDIPrimitivesLibrary().containsCell("OBUFDS"));
Assertions.assertFalse(testNetlist2.getHDIPrimitivesLibrary().containsCell("OBUFDS_DUAL_BUF"));
testDesign2.getTopEDIFCell().getCellInst("testOBUFDS").addProperty("IOStandard", IOStandard.LVCMOS12.name());
testDesign2.getNetlist().expandMacroUnisims(part.getSeries());
Assertions.assertTrue(testDesign2.getNetlist().getHDIPrimitivesLibrary().containsCell("OBUFDS"));
Assertions.assertFalse(testDesign2.getNetlist().getHDIPrimitivesLibrary().containsCell("OBUFDS_DUAL_BUF"));

testNetlist2.expandMacroUnisims(part.getSeries());

Assertions.assertTrue(testNetlist2.getHDIPrimitivesLibrary().containsCell("OBUFDS"));
Assertions.assertFalse(testNetlist2.getHDIPrimitivesLibrary().containsCell("OBUFDS_DUAL_BUF"));
}

@Test
void testMacroExpansionWithAndWithoutException() {
final Part part = PartNameTools.getPart(PART_NAME);
Design testDesign = createSamplePrimitiveDesign("OBUFDS", part);

EDIFNetlist testNetlist = testDesign.getNetlist();
testNetlist.setDevice(testDesign.getDevice());

EDIFCellInst wontBeExpanded = testDesign.getTopEDIFCell().getCellInst("testOBUFDS");
wontBeExpanded.addProperty("IOStandard", IOStandard.LVCMOS12.name());
EDIFCellInst willBeExpanded = testNetlist.getTopCell().createChildCellInst("willBeExpanded", testNetlist.getHDIPrimitive(Unisim.OBUFDS));

testNetlist.expandMacroUnisims(part.getSeries());

EDIFCell obufdsCell = testNetlist.getHDIPrimitivesLibrary().getCell("OBUFDS");
EDIFCell obufdsDualBufCell = testNetlist.getHDIPrimitivesLibrary().getCell("OBUFDS_DUAL_BUF");

Assertions.assertSame(obufdsCell, wontBeExpanded.getCellType());
Assertions.assertSame(obufdsDualBufCell, willBeExpanded.getCellType());

testNetlist.collapseMacroUnisims(part.getSeries());

Assertions.assertSame(obufdsCell, testNetlist.getHDIPrimitivesLibrary().getCell("OBUFDS"));
Assertions.assertFalse(testNetlist.getHDIPrimitivesLibrary().containsCell("OBUFDS_DUAL_BUF"));

Assertions.assertSame(obufdsCell, wontBeExpanded.getCellType());
Assertions.assertSame(obufdsCell, willBeExpanded.getCellType());

testNetlist.expandMacroUnisims(part.getSeries());

Assertions.assertNotSame(obufdsCell, testNetlist.getHDIPrimitivesLibrary().getCell("OBUFDS"));
Assertions.assertNotSame(obufdsDualBufCell, testNetlist.getHDIPrimitivesLibrary().getCell("OBUFDS_DUAL_BUF"));
}

@Test
Expand Down Expand Up @@ -446,7 +487,7 @@ public void testExpandMacroUnisimsExceptionWithFallbackIOStandard(String standar

EDIFCell top = netlist.getTopCell();
EDIFPort port = top.createPort("O", EDIFDirection.OUTPUT, 1);
EDIFCellInst obufds = top.createChildCellInst("obuf", Design.getPrimitivesLibrary().getCell("OBUFDS"));
EDIFCellInst obufds = top.createChildCellInst("obuf", netlist.getHDIPrimitive(Unisim.OBUFDS));
netlist.getHDIPrimitivesLibrary().addCell(obufds.getCellType());
EDIFNet net = top.createNet("O");
new EDIFPortInst(port, net);
Expand Down

0 comments on commit 993f4ad

Please sign in to comment.