Closed trharoldsen closed 3 years ago
I'm having trouble reproducing the issue. Can you provide a test case or modify the code below to trigger the issue?
Design design = new Design("testcase","xc7s25csga324");
EDIFCell top = design.getNetlist().getTopCell();
Cell lut1 = design.createAndPlaceCell("test_SLICE_X11Y46_D5LUT", Unisim.LUT1, "SLICE_X11Y46/D5LUT");
Net driverNet = design.createNet("driver_net");
Net failingNet = design.createNet("failing_net");
driverNet.connect(lut1, "I0");
failingNet.connect(lut1, "O");
driverNet.getLogicalNet().createPortInst(top.createPort("dummyIn", EDIFDirection.INPUT, 1));
failingNet.getLogicalNet().createPortInst(top.createPort("dummyOut", EDIFDirection.OUTPUT, 1));
driverNet.createPin(false, "D5", lut1.getSiteInst());
design.getVccNet().addPin(new SitePinInst("D6", lut1.getSiteInst()));
failingNet.createPin(false, "DMUX", lut1.getSiteInst());
lut1.getSiteInst().routeSite();
design.writeCheckpoint(design.getName() +".dcp");
I haven't quite been able to create a duplicate example though I'm working on it. In the process, I've discovered an oddity while working with your example above.
First, your DMUX is being created as an input instead of an output. Fixing them, looking through the data structures, the above code causes two version of the DMUX SitePinInst to be created. One instance resides in fields on the Net. The other resides in fields on the SiteInst. The objects reference the same pin, but are two different objects.
I notice what appears to be a bug here as the instance related to the Net contains a reference back to the Net but the instance related to the SiteInst does not have this reference back to the Net.
I'm checking the out this difference to determine to see if this is the source of this other error I'm seeing.
Below if the code with the DMUX output issue fixed.
Design design = new Design("testcase","xc7s25csga324");
EDIFCell top = design.getNetlist().getTopCell();
Cell lut1 = design.createAndPlaceCell("test_SLICE_X11Y46_D5LUT", Unisim.LUT1, "SLICE_X11Y46/D5LUT");
Net driverNet = design.createNet("driver_net");
Net failingNet = design.createNet("failing_net");
driverNet.connect(lut1, "I0");
failingNet.connect(lut1, "O");
driverNet.getLogicalNet().createPortInst(top.createPort("dummyIn", EDIFDirection.INPUT, 1));
failingNet.getLogicalNet().createPortInst(top.createPort("dummyOut", EDIFDirection.OUTPUT, 1));
driverNet.createPin(false, "D5", lut1.getSiteInst());
design.getVccNet().addPin(new SitePinInst("D6", lut1.getSiteInst()));
failingNet.createPin(false, "DMUX", lut1.getSiteInst());
lut1.getSiteInst().routeSite();
design.writeCheckpoint(design.getName() +".dcp");
Found a failing minimal example by removing disconnecting the output to a top level port and replacing it with a connection to another LUT. The previous noted issue with the pin instance not referencing the connected net did not appear to have an effect on this particular error.
Design design2 = new Design("testcase","xc7s25csga324");
EDIFCell top = design2.getNetlist().getTopCell();
Cell lut1 = design2.createAndPlaceCell("test_SLICE_X7Y46_D5LUT", Unisim.LUT1, "SLICE_X7Y46/D5LUT");
Cell lut2 = design2.createAndPlaceCell("test_SLICE_X11Y46_D6LUT", Unisim.LUT1, "SLICE_X11Y46/D6LUT"); // added
Net driverNet = design2.createNet("driver_net");
Net failingNet = design2.createNet("failing_net");
driverNet.connect(lut1, "I0");
failingNet.connect(lut1, "O");
failingNet.connect(lut2, "I0"); // added
driverNet.getLogicalNet().createPortInst(top.createPort("dummyIn", EDIFDirection.INPUT, 1));
// failingNet.getLogicalNet().createPortInst(top.createPort("dummyOut", EDIFDirection.OUTPUT, 1));
driverNet.createPin(false, "D5", lut1.getSiteInst());
design2.getVccNet().addPin(new SitePinInst("D6", lut1.getSiteInst()));
failingNet.createPin(true, "DMUX", lut1.getSiteInst());
failingNet.createPin(true, "D6", lut2.getSiteInst()); // added
lut1.getSiteInst().getSitePinInst("DMUX").setNet(failingNet);
lut1.getSiteInst().routeSite();
design2.writeCheckpoint(design2.getName() +".dcp");
Thanks @trharoldsen, I had a copy/paste typo for the output pin. That createPin()
method should probably be deprecated and replaced with a version that doesn't require you to specify the direction as it can be determined by the pin name on the SiteInst
. You've also correctly pointed out that createPin()
isn't checking if the pin already exists on the SiteInst
and so it creates a duplicate. It turns out the pin was already created in Net.connect()
when attaching the output of the LUT.
From your updated code, I was able to track down the issue in the site router. It was handling a special case that I have fixed internally and will be in the next release. This issue seems to be Series 7 specific and was getting hung up on the D5FF which doesn't route out of the site directly. To work around the issue, you can also route the nets within the site directly, for example:
si.routeIntraSiteNet(failingNet, lut1.getBEL().getPin("O5"), si.getBEL("DMUX").getPin("DMUX"));
This will avoid the error until the release is made (hopefully next week).
The 2020.2.5 release should fix this issue.
Working with Spartan 7, I have a site instance that fails when I call
routeSite
on it.The site is routing the D5LUT out through the DMUX output.
D5 -> [D5LUT] -> DMUX
Doing some debugging, this particular net seems to be the failing point. Digging a little further, it looks like the code is trying to route through the DFFMUX instead of the DOUTMUX.
I've included what I believe are the relevant pieces of information but the site below.
driver_net drives the D5LUT; failing_net comes out of the D5LUT.O output pin and out through the DMUX.