// Handle each group of sinks separately, allocating TIEOFF to those sinks according
// to priority
for(PinSorter ps : pinSwitchMatrixMap.values()){
ssLoop : for(StaticSink ss : ps.useTIEOFF){
Instance inst = updateTIEOFF(ss.switchMatrixSink.tile, ss.pin.getNet(), true);
if(dev.getFamilyType().equals(FamilyType.VIRTEX5)){
String[] fanWireNames = null;
if((fanWireNames = fanBounceMap.get(we.getWireName(ss.switchMatrixSink.wire))) != null){
Node nn = new Node(inst.getTile(), we.getWireEnum(fanWireNames[0]), null, 0);
for(String fanWireName : fanWireNames){
nn.setWire(we.getWireEnum(fanWireName));
boolean reservedWire = addReservedGNDVCCNode(nn, ss.pin);
if(reservedWire){
break;
}
if(!reservedWire && fanWireName.equals(fanWireNames[fanWireNames.length-1])){
ps.useSLICE.add(ss);
continue ssLoop;
}
}
}
}
// Find the correct net corresponding to this TIEOFF if it exists
Net matchingNet = null;
for(Net net : inst.getNetList()){
if(net.getType().equals(ss.pin.getNet().getType()) && !net.getSource().getName().equals("KEEP1")){
matchingNet = net;
break;
}
}
if(matchingNet == null){
matchingNet = createNewNet(ss.pin.getNet(), ss.pin);
finalStaticNets.add(matchingNet);
inst.addToNetList(matchingNet);
createAndAddPin(matchingNet, inst, true);
}
else{
matchingNet.addPin(ss.pin);
ss.pin.getInstance().addToNetList(matchingNet);
}
}
for(StaticSink ss : ps.attemptTIEOFF){
Instance inst = updateTIEOFF(ss.switchMatrixSink.tile, ss.pin.getNet(), false);
// Special case with CLK pins BRAMs on Virtex5 devices, when competing for FANs against GND Nets
if(dev.getFamilyType().equals(FamilyType.VIRTEX5)){
int switchBoxSink = ss.switchMatrixSink.wire;
if(we.getWireName(ss.switchMatrixSink.getWire()).startsWith("BYP_B")){
Node nn = new Node(inst.getTile(), we.getWireEnum(we.getWireName(switchBoxSink).replace("_B","")), null, 0);
if(!addReservedGNDVCCNode(nn, ss.pin)){
// we need to use a SLICE
ps.useSLICE.add(ss);
continue;
}
}
else if(switchBoxSink == v5ctrlWires[0] || switchBoxSink == v5ctrlWires[1] || switchBoxSink == v5ctrlWires[2] || switchBoxSink == v5ctrlWires[3]){
Node nn = new Node(inst.getTile(), we.getWireEnum(we.getWireName(switchBoxSink).replace("_B","")), null, 0);
if(!addReservedGNDVCCNode(nn, ss.pin)){
// we need to use a SLICE
ps.useSLICE.add(ss);
continue;
}
}else if(ss.pin.getInstance().getPrimitiveSite().getType().equals(PrimitiveType.DSP48E) && ss.pin.getName().contains("CEP")){
Node nn = new Node(inst.getTile(), we.getWireEnum("CTRL1"), null, 0);
if(!addReservedGNDVCCNode(nn, ss.pin)){
// we need to use a SLICE
ps.useSLICE.add(ss);
continue;
}
}
else if(ss.pin.getName().contains("ENBL")){
Node nn = new Node(inst.getTile(), we.getWireEnum("CTRL2"), null, 0);
if(!addReservedGNDVCCNode(nn, ss.pin)){
// we need to use a SLICE
ps.useSLICE.add(ss);
continue;
}
}
}
Net matchingNet = null;
// Find the correct net corresponding to this TIEOFF if it exists
for(Net net : inst.getNetList()){
if(net.getType().equals(ss.pin.getNet().getType()) && !net.getSource().getName().equals("HARD1")){
matchingNet = net;
break;
}
}
if(matchingNet == null){
matchingNet = createNewNet(ss.pin.getNet(), ss.pin);
finalStaticNets.add(matchingNet);
inst.addToNetList(matchingNet);
createAndAddPin(matchingNet, inst, false);
}
else{
matchingNet.addPin(ss.pin);
ss.pin.getInstance().addToNetList(matchingNet);
}
}
if(ps.useSLICE.size() > 0){
ArrayList<Pin> gnds = new ArrayList<Pin>();
ArrayList<Pin> vccs = new ArrayList<Pin>();
for(StaticSink ss : ps.useSLICE){
if(ss.pin.getNet().getType().equals(NetType.GND)){
gnds.add(ss.pin);
}
else if(ss.pin.getNet().getType().equals(NetType.VCC)){
vccs.add(ss.pin);
}
}
if(gnds.size() > 0){
// Create the new net
Net newNet = createNewNet(NetType.GND, gnds);
finalStaticNets.add(newNet);
// Create new instance of SLICE primitive to get source
Instance currInst = findClosestAvailableSLICE(ps.useSLICE.get(0).switchMatrixSink.tile, NetType.GND);
if(currStaticSourcePin != null){
currInst.addToNetList(newNet);
newNet.addPin(currStaticSourcePin);
}
else{
router.design.addInstance(currInst);
currInst.addToNetList(newNet);
Pin source = new Pin(true, slicePin, currInst);
newNet.addPin(source);
}
}
if(vccs.size() > 0){
// Create the new net
Net newNet = createNewNet(NetType.VCC, vccs);
finalStaticNets.add(newNet);
// Create new instance of SLICE primitive to get source
Instance currInst = findClosestAvailableSLICE(ps.useSLICE.get(0).switchMatrixSink.tile, NetType.VCC);
if(currStaticSourcePin != null){
currInst.addToNetList(newNet);
newNet.addPin(currStaticSourcePin);
}
else{
router.design.addInstance(currInst);
currInst.addToNetList(newNet);
Pin source = new Pin(true, slicePin, currInst);
newNet.addPin(source);
}
}
}