Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/* -*- tab-width: 4 -*-
*
* Electric(tm) VLSI Design System
*
* File: PlacementFrame.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.database.geometry.EPoint;
import com.sun.electric.database.hierarchy.Cell;
import com.sun.electric.database.topology.SteinerTree.SteinerTreePort;
import com.sun.electric.tool.Job;
import com.sun.electric.util.math.FixpTransform;
import com.sun.electric.util.math.MutableBoolean;
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;
/**
* Class to define a framework for Placement algorithms. To make Placement
* algorithms easier to write, all Placement algorithms must extend this class.
* The Placement algorithm then defines two methods:
*
* public String getAlgorithmName() returns the name of the Placement algorithm
*
* void runPlacement(List nodesToPlace, List allNetworks, String cellName, Job job)
* runs the placement on the "nodesToPlace", calling each PlacementNode's "setPlacement()"
* and "setOrientation()" methods to establish the proper placement.
*
* To avoid the complexities of the Electric database, three shadow-classes are
* defined that describe the necessary information that Placement algorithms
* want:
*
* PlacementNode is an actual node (primitive or cell instance) that is to be
* placed. PlacementPort is the connection site on the PlacementNode. Each
* PlacementNode has a list of zero or more PlacementPort objects, and each
* PlacementPort points to its "parent" PlacementNode. PlacementNetwork
* determines which PlacementPort objects will connect together. Each
* PlacementNetwork has a list of two or more PlacementPort objects that it
* connects, and each PlacementPort has a PlacementNetwork in which it resides.
*/
public abstract class PlacementFrame {
protected int numOfThreads;
protected int runtime;
private Cell originalCell;
private boolean failure = false;
private Cell redispCell = null;
private ArrayList allParameters = new ArrayList();
/**
* Method to do Placement (overridden by actual Placement algorithms).
* @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 abstract void runPlacement(List nodesToPlace, List allNetworks, String cellName, Job job);
/**
* Method to return the name of the placement algorithm (overridden by
* actual Placement algorithms).
* @return the name of the placement algorithm.
*/
public abstract String getAlgorithmName();
/**
* Method to return a list of parameters for this placement algorithm.
* @return a list of parameters for this placement algorithm.
*/
public final List getParameters() { return allParameters; }
public void setParamterValues(int threads, int runtime)
{
this.numOfThreads = threads;
this.runtime = runtime;
}
/**
* Method to set the original Electric Cell that is being placed.
* @param cell the original Electric Cell that is being placed.
*/
public void setOriginalCell(Cell cell) { originalCell = cell; }
/**
* Method to return the original Electric Cell that is being placed.
* @return the original Electric Cell that is being placed.
*/
public Cell getOriginalCell() { return originalCell; }
/**
* Method to set the cell that should be rebuilt and displayed.
* @param r the cell that should be rebuilt and displayed.
*/
public void setRedispCell(Cell r) { redispCell = r; }
/**
* Method to return the cell that should be rebuilt and displayed.
* @return the cell that should be rebuilt and displayed.
*/
public Cell getRedispCell() { return redispCell; }
/**
* Method to indicate that the placement failed, and should not be rebuilt.
* @param f true to indicate failure.
*/
public void setFailure(boolean f) { failure = f; }
/**
* Method to return whether the placement failed and should not be rebuilt.
* @return true if the placement failed and should not be rebuilt.
*/
public boolean isFailure() { return failure; }
/**
* Class to define a parameter for a placement algorithm.
*/
public class PlacementParameter {
public static final int TYPEINTEGER = 1;
public static final int TYPESTRING = 2;
public static final int TYPEDOUBLE = 3;
public static final int TYPEBOOLEAN = 4;
final String key;
private final String name;
private final String title;
final Object factoryValue;
private Object cachedValue;
private final int type;
private String[] intMeanings;
public PlacementParameter(String name, String title, int factory) {
key = getAlgorithmName() + "-" + name;
this.name = name;
this.title = title;
cachedValue = factoryValue = Integer.valueOf(factory);
type = TYPEINTEGER;
intMeanings = null;
allParameters.add(this);
}
public PlacementParameter(String name, String title, int factory, String[] meanings) {
key = getAlgorithmName() + "-" + name;
this.name = name;
this.title = title;
cachedValue = factoryValue = Integer.valueOf(factory);
type = TYPEINTEGER;
intMeanings = meanings;
allParameters.add(this);
}
public PlacementParameter(String name, String title, String factory) {
key = getAlgorithmName() + "-" + name;
this.name = name;
this.title = title;
cachedValue = factoryValue = String.valueOf(factory);
type = TYPESTRING;
intMeanings = null;
allParameters.add(this);
}
public PlacementParameter(String name, String title, double factory) {
key = getAlgorithmName() + "-" + name;
this.name = name;
this.title = title;
cachedValue = factoryValue = Double.valueOf(factory);
type = TYPEDOUBLE;
intMeanings = null;
allParameters.add(this);
}
public PlacementParameter(String name, String title, boolean factory) {
key = getAlgorithmName() + "-" + name;
this.name = name;
this.title = title;
cachedValue = factoryValue = Boolean.valueOf(factory);
type = TYPEBOOLEAN;
intMeanings = null;
allParameters.add(this);
}
public PlacementFrame getOwner() { return PlacementFrame.this; }
public String getParameterName() { return name; }
public String getName() { return title; }
public int getType() { return type; }
public int getIntValue() { return ((Integer)cachedValue).intValue(); }
public String[] getIntMeanings() { return intMeanings; }
public String getStringValue() { return (String)cachedValue; }
public double getDoubleValue() { return ((Double)cachedValue).doubleValue(); }
public boolean getBooleanValue() { return ((Boolean)cachedValue).booleanValue(); }
public void setValue(Object value) {
assert value.getClass() == factoryValue.getClass();
if (value.equals(factoryValue))
value = factoryValue;
cachedValue = value;
}
}
/**
* Class to define a node that is being placed. This is a shadow class for
* the internal Electric object "NodeInst". There are minor differences
* between PlacementNode and NodeInst, for example, PlacementNode is
* presumed to be centered in the middle, with port offsets based on that
* center, whereas the NodeInst has a cell-center that may not be in the
* middle.
*/
public abstract static class PlacementNode {
private double xPos, yPos;
private Orientation orient;
private Object userObject;
public Object getUserObject() { return userObject; }
public void setUserObject(Object obj) { userObject = obj; }
/**
* Method to return a list of PlacementPorts on this PlacementNode.
* @return a list of PlacementPorts on this PlacementNode.
*/
public abstract List getPorts();
/**
* Method to return the width of this PlacementNode.
* @return the width of this PlacementNode.
*/
public abstract double getWidth();
/**
* Method to return the height of this PlacementNode.
* @return the height of this PlacementNode.
*/
public abstract double getHeight();
/**
* Method to set the location of this PlacementNode.
* The Placement algorithm must call this method to set the final location of the PlacementNode.
* @param x the X-coordinate of the center of this PlacementNode.
* @param y the Y-coordinate of the center of this PlacementNode.
*/
public void setPlacement(double x, double y) {
xPos = x;
yPos = y;
}
/**
* Method to set the orientation (rotation and mirroring) of this PlacementNode.
* The Placement algorithm may call this method to set the final orientation of the PlacementNode.
* @param o the Orientation of this PlacementNode.
*/
public void setOrientation(Orientation o) {
orient = o;
for (PlacementPort plPort : getPorts())
plPort.computeRotatedOffset();
}
/**
* Method to return the X-coordinate of the placed location of this PlacementNode.
* This is the location that the Placement algorithm has established for this PlacementNode.
* @return the X-coordinate of the placed location of this PlacementNode.
*/
public double getPlacementX() { return xPos; }
/**
* Method to return the Y-coordinate of the placed location of this PlacementNode.
* This is the location that the Placement algorithm has established for this PlacementNode.
* @return the Y-coordinate of the placed location of this PlacementNode.
*/
public double getPlacementY() { return yPos; }
/**
* Method to return the Orientation of this PlacementNode. This is the
* Orientation that the Placement algorithm has established for this PlacementNode.
* @return the Orientation of this PlacementNode.
*/
public Orientation getPlacementOrientation() { return orient; }
/**
* Method to return the name of NodeProto of this PlacementNode.
* @return the NodeProto of this PlacementNode.
*/
public abstract String getTypeName();
}
/**
* Class to define ports on PlacementNode objects. This is a shadow class
* for the internal Electric object "PortInst".
*/
public static class PlacementPort implements SteinerTreePort
{
private EPoint location;
private double offX, offY;
private double rotatedOffX, rotatedOffY;
private PlacementNode plNode;
private PlacementNetwork plNet;
/**
* Constructor to create a PlacementPort.
* @param x the X offset of this PlacementPort from the center of its PlacementNode.
* @param y the Y offset of this PlacementPort from the center of its PlacementNode.
*/
public PlacementPort(double x, double y)
{
offX = x;
offY = y;
}
/**
* Method to set the "parent" PlacementNode on which this PlacementPort resides.
* @param pn the PlacementNode on which this PlacementPort resides.
*/
public void setPlacementNode(PlacementNode pn) { plNode = pn; }
/**
* Method to return the PlacementNode on which this PlacementPort resides.
* @return the PlacementNode on which this PlacementPort resides.
*/
public PlacementNode getPlacementNode() { return plNode; }
/**
* Method to return the PlacementNetwork on which this PlacementPort resides.
* @param pn the PlacementNetwork on which this PlacementPort resides.
*/
public void setPlacementNetwork(PlacementNetwork pn) { plNet = pn; }
/**
* Method to return the PlacementNetwork on which this PlacementPort resides.
* @return the PlacementNetwork on which this PlacementPort resides.
* If this PlacementPort does not connect to any other PlacementPort, the PlacementNetwork may be null.
*/
public PlacementNetwork getPlacementNetwork() { return plNet; }
/**
* Method to return the offset of this PlacementPort's X coordinate from the center of its PlacementNode.
* The offset is valid when no Orientation has been applied.
* @return the offset of this PlacementPort's X coordinate from the center of its PlacementNode.
*/
public double getOffX() { return offX; }
/**
* Method to return the offset of this PlacementPort's Y coordinate from the center of its PlacementNode.
* The offset is valid when no Orientation has been applied.
* @return the offset of this PlacementPort's Y coordinate from the center of its PlacementNode.
*/
public double getOffY() { return offY; }
/**
* Method to return the location of this PlacementPort.
* @return the location of this PlacementPort.
*/
public EPoint getCenter()
{
if (location == null) location = new EPoint(plNode.xPos + rotatedOffX, plNode.yPos + rotatedOffY);
return location;
}
/**
* Method to return the offset of this PlacementPort's X coordinate from the center of its PlacementNode.
* The coordinate assumes that the PlacementNode has been rotated by its Orientation.
* @return the offset of this PlacementPort's X coordinate from the center of its PlacementNode.
*/
public double getRotatedOffX() { return rotatedOffX; }
/**
* Method to return the offset of this PlacementPort's Y coordinate from the center of its PlacementNode.
* The coordinate assumes that the PlacementNode has been rotated by its Orientation.
* @return the offset of this PlacementPort's Y coordinate from the center of its PlacementNode.
*/
public double getRotatedOffY() { return rotatedOffY; }
/**
* Internal method to compute the rotated offset of this PlacementPort
* assuming that the Orientation of its PlacementNode has changed.
* TODO: why is this public? it should not be accessed!
*/
public void computeRotatedOffset() {
Orientation orient = plNode.getPlacementOrientation();
if (orient == Orientation.IDENT) {
rotatedOffX = offX;
rotatedOffY = offY;
return;
}
FixpTransform trans = orient.pureRotate();
Point2D offset = new Point2D.Double(offX, offY);
trans.transform(offset, offset);
rotatedOffX = offset.getX();
rotatedOffY = offset.getY();
}
}
/**
* Class to define networks of PlacementPort objects. This is a shadow class
* for the internal Electric object "Network", but it is simplified for
* Placement.
*/
public static class PlacementNetwork {
private List portsOnNet;
private boolean isOnRail;
/**
* Constructor to create this PlacementNetwork with a list of
* PlacementPort objects that it connects.
* @param ports a list of PlacementPort objects that it connects.
* @param isRail true if the network is on a power/ground rail.
*/
public PlacementNetwork(List ports, boolean isRail) {
portsOnNet = ports;
isOnRail = isRail;
}
/**
* Method to return the list of PlacementPort objects on this PlacementNetwork.
* @return a list of PlacementPort objects on this PlacementNetwork.
*/
public List getPortsOnNet() { return portsOnNet; }
/**
* Method to tell whether this PlacementNetwork is on a Power or Ground rail.
* @return true if this PlacementNetwork is on a Power or Ground rail.
*/
public boolean isOnRail() { return isOnRail; }
}
// ****************************************** HELPER METHODS ******************************************
/**
* Method to examine all PlacementNodes and determine the size of "standard cells".
* @param placementNodes the List of PlacementNode objects to be placed.
* @param sizeIsWidth a MutableBoolean which gets set true if the standard cells stack in columns
* (and so the size returned is the cell width) or false if the standard cells stack in rows
* (and so the size returned is the cell height). May be null if this information is not needed.
* @return the size of the standard cell.
*/
public static double getStandardCellSize(List placementNodes, MutableBoolean sizeIsWidth)
{
Map widths = new HashMap(), heights = new HashMap();
for(PlacementNode p : placementNodes)
{
double width = p.getWidth();
Double dWidth = Double.valueOf(width);
Integer numWid = widths.get(dWidth);
if (numWid == null) widths.put(dWidth, numWid = Integer.valueOf(0));
numWid = Integer.valueOf(numWid.intValue() + 1);
widths.put(dWidth, numWid);
double height = p.getHeight();
Double dHeight = Double.valueOf(height);
Integer numHei = heights.get(dHeight);
if (numHei == null) heights.put(dHeight, numHei = Integer.valueOf(0));
numHei = Integer.valueOf(numHei.intValue() + 1);
heights.put(dHeight, numHei);
}
// find the most common width or height
Double mostCommonWidth = null;
int numMostCommonWidth = 0;
for(Double g : widths.keySet())
{
Integer count = widths.get(g);
if (count.intValue() > numMostCommonWidth)
{
numMostCommonWidth = count.intValue();
mostCommonWidth = g;
}
}
Double mostCommonHeight = null;
int numMostCommonHeight = 0;
for(Double g : heights.keySet())
{
Integer count = heights.get(g);
if (count.intValue() > numMostCommonHeight)
{
numMostCommonHeight = count.intValue();
mostCommonHeight = g;
}
}
double girth;
if (numMostCommonWidth > numMostCommonHeight)
{
// standard cells seem to go in columns
if (sizeIsWidth != null) sizeIsWidth.setValue(true);
girth = mostCommonWidth.doubleValue();
} else
{
// standard cells seem to go in rows
if (sizeIsWidth != null) sizeIsWidth.setValue(false);
girth = mostCommonHeight.doubleValue();
}
return girth;
}
}