![JAR search and dependency download from the Maven repository](/logo.png)
com.sun.electric.tool.placement.PlacementMinCut Maven / Gradle / Ivy
/* -*- tab-width: 4 -*-
*
* Electric(tm) VLSI Design System
*
* File: PlacementMinCut.java
*
* Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
*
* Electric(tm) is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* Electric(tm) is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Electric(tm); see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, Mass 02111-1307, USA.
*/
package com.sun.electric.tool.placement;
import com.sun.electric.tool.Job;
import com.sun.electric.util.math.MutableInteger;
import com.sun.electric.util.math.Orientation;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Placement algorithm to do Min-Cut placement.
*/
public class PlacementMinCut extends PlacementFrame
{
private final double PADDING = 5;
private final boolean DEBUG = false;
private Map> connectivityMap;
/**
* Method to return the name of this placement algorithm.
* @return the name of this placement algorithm.
*/
public String getAlgorithmName() { return "Min-Cut"; }
/**
* Method to do Min-Cut Placement.
* @param nodesToPlace a list of all nodes that are to be placed.
* @param allNetworks a list of all networks that connect the nodes.
* @param cellName the name of the cell being placed.
* @param job the Job (for testing abort).
*/
protected void runPlacement(List nodesToPlace, List allNetworks, String cellName, Job job)
{
// build the connectivity map with the number of connections between any two PlacementNodes
connectivityMap = new HashMap>();
for(PlacementNetwork plNet : allNetworks)
{
// add all combinations of the nodes on this net to the connectivity map
List portsInNetwork = plNet.getPortsOnNet();
for(int i=0; i singletons = new ArrayList();
Partition topPart = new Partition(0);
for(PlacementNode plNode : nodesToPlace)
{
boolean connected = false;
for(PlacementPort plPort : plNode.getPorts())
{
PlacementNetwork net = plPort.getPlacementNetwork();
if (net == null) continue;
for(PlacementPort otherPort : net.getPortsOnNet())
{
if (otherPort.getPlacementNode() != plNode) { connected = true; break; }
}
if (connected) break;
}
if (connected) topPart.allNodes.add(plNode); else
singletons.add(plNode);
}
// // determine standard cell size
// double scSize = getStandardCellSize(nodesToPlace, null);
// double macroSize = scSize * scSize * 100;
// System.out.println("Standard cell size is " + scSize + " so macro cells are " + macroSize + " square units or more");
// build list of partitions to organize
List partitionsToOrganize = new ArrayList();
partitionsToOrganize.add(topPart);
// iteratively go through list and organize them
while (partitionsToOrganize.size() > 0)
{
// get partition
Partition part = partitionsToOrganize.get(0);
partitionsToOrganize.remove(0);
if (part.allNodes.size() <= 2) continue;
// split the partition randomly
part.splitRandomly();
if (DEBUG)
{
System.out.print("INITIAL NODES IN GROUP 1:");
for(PlacementNode plNode : part.part1.allNodes) System.out.print(" "+plNode);
System.out.println();
System.out.print("INITIAL NODES IN GROUP 2:");
for(PlacementNode plNode : part.part2.allNodes) System.out.print(" "+plNode);
System.out.println();
}
// organize the two halves properly
part.organize();
if (DEBUG)
{
System.out.print("FINAL NODES IN GROUP 1:");
for(PlacementNode plNode : part.part1.allNodes) System.out.print(" "+plNode);
System.out.println();
System.out.print("FINAL NODES IN GROUP 2:");
for(PlacementNode plNode : part.part2.allNodes) System.out.print(" "+plNode);
System.out.println();
}
if (part.part1.allNodes.size() > 2) partitionsToOrganize.add(part.part1);
if (part.part2.allNodes.size() > 2) partitionsToOrganize.add(part.part2);
}
Point2D lastOffset = placePartitions(topPart, new Point2D.Double(0, 0));
double x = lastOffset.getX(), y = lastOffset.getY();
for(PlacementNode plNode : singletons)
{
plNode.setPlacement(x, y);
x += PADDING;
}
}
private Point2D placePartitions(Partition part, Point2D offset)
{
String indent = "";
if (DEBUG)
{
for(int i=0; i properOrientation = findOrientations(part.allNodes);
for(PlacementNode plNode : part.allNodes)
{
Orientation or = properOrientation.get(plNode);
if (or != null)
plNode.setOrientation(or);
}
off = new Point2D.Double(widestX, widestY);
}
if (DEBUG) System.out.println(indent+"NEW OFFSET ("+off.getX()+","+off.getY()+")");
return off;
}
private static class OrientationConnection
{
PlacementPort thisPP;
PlacementNode otherPN;
PlacementPort otherPP;
}
/**
* Method to find the ideal orientation for all of the nodes at the bottom point.
* @param allNodes a List of PlacementNodes that have location, but not ideal orientation.
* @return a Map assigning orientation to each of the PlacementNodes in the list.
*/
private Map findOrientations(List allNodes)
{
Map properOrientation = new HashMap();
if (allNodes.size() > 1)
{
//boolean debug = currentCellName.equals("spiceHier{sch}");
//if (debug) System.out.println("FINDING ORIENTATIONS FOR PARTITION WITH "+allNodes.size()+" NODES");
Map> allPossibilities = new HashMap>();
for(PlacementNode plNode : allNodes)
{
// create a List of OrientationConnection objects for this NodeInst
List oc = new ArrayList();
allPossibilities.put(plNode, oc);
}
// add all of the connections to other nodes in the partition
for(PlacementNode plNode : allNodes)
{
List oc = allPossibilities.get(plNode);
for(PlacementPort plPort : plNode.getPorts())
{
PlacementNetwork plNet = plPort.getPlacementNetwork();
if (plNet == null) continue;
for(PlacementPort otherPlPort : plNet.getPortsOnNet())
{
PlacementNode otherPlNode = otherPlPort.getPlacementNode();
if (otherPlNode == plNode) continue;
if (allPossibilities.get(otherPlNode) == null) continue;
OrientationConnection orc = new OrientationConnection();
orc.thisPP = plPort;
orc.otherPN = otherPlNode;
orc.otherPP = otherPlPort;
oc.add(orc);
}
}
}
// now find the optimal orientation choice for each NodeInst
Orientation [] standardEight = new Orientation[] {Orientation.IDENT, Orientation.R, Orientation.RR, Orientation.RRR,
Orientation.X, Orientation.XR, Orientation.XRR, Orientation.XRRR};
// if (allNodes.size() == 2)
// {
// // try all combinations of the two
// PlacementNode plNode1 = allNodes.get(0);
// PlacementNode plNode2 = allNodes.get(1);
// List oc = allPossibilities.get(plNode1);
// Orientation betterOrientation1 = null;
// Orientation betterOrientation2 = null;
// double bestDist = Double.MAX_VALUE;
// for(int i=0; i oc = allPossibilities.get(plNode);
double bestDist = Double.MAX_VALUE;
Orientation betterOrientation = null;
for(int i=0; i destMap = connectivityMap.get(plNode1);
if (destMap == null) return 0;
MutableInteger mi = destMap.get(plNode2);
if (mi == null) return 0;
return mi.intValue();
}
/**
* Method to build the connectivity map by adding a connection between two PlacementNodes.
* This method is usually called twice with the PlacementNodes in both orders because
* the mapping is not symmetric.
* @param plNode1 the first PlacementNode.
* @param plNode2 the second PlacementNode.
*/
private void incrementMap(PlacementNode plNode1, PlacementNode plNode2)
{
Map destMap = connectivityMap.get(plNode1);
if (destMap == null)
connectivityMap.put(plNode1, destMap = new HashMap());
MutableInteger mi = destMap.get(plNode2);
if (mi == null) destMap.put(plNode2, mi = new MutableInteger(0));
mi.increment();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy