/* -*- tab-width: 4 -*-
*
* Electric(tm) VLSI Design System
*
* File: Generic.java
*
* Copyright (c) 2003 Sun Microsystems and Static Free Software
*
* 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.technology.technologies;
import com.sun.electric.database.ImmutableNodeInst;
import com.sun.electric.database.geometry.EGraphics;
import com.sun.electric.database.geometry.Poly;
import com.sun.electric.database.id.IdManager;
import com.sun.electric.database.prototype.PortCharacteristic;
import com.sun.electric.database.topology.NodeInst;
import com.sun.electric.database.variable.Variable;
import com.sun.electric.technology.AbstractShapeBuilder;
import com.sun.electric.technology.ArcProto;
import com.sun.electric.technology.EdgeH;
import com.sun.electric.technology.EdgeV;
import com.sun.electric.technology.Foundry;
import com.sun.electric.technology.Layer;
import com.sun.electric.technology.PrimitiveNode;
import com.sun.electric.technology.PrimitivePort;
import com.sun.electric.technology.SizeOffset;
import com.sun.electric.technology.TechFactory;
import com.sun.electric.technology.TechPool;
import com.sun.electric.technology.Technology;
import java.awt.Color;
import java.util.Collections;
import java.util.Iterator;
/**
* This is the Generic technology.
*/
public class Generic extends Technology
{
/** the Generic Technology object. */ public static Generic tech() { return TechPool.getThreadTechPool().getGeneric(); }
/** the Universal Layer. */ private final Layer universalLay;
/** the Glyph Layer. */ public final Layer glyphLay;
/** the DRC exclusion Layer. */ public final Layer drcLay;
/** the AFG exclusion Layer. */ public final Layer afgLay;
/** the Universal Pin node, which connects to every type of arc. */
public final PrimitiveNode universalPinNode;
/** the Invisible Pin node, which connects to every type of arc and produces no layout. */
public final PrimitiveNode invisiblePinNode;
/** the Unrouted Pin node, for making bends in unrouted arc paths. */
public final PrimitiveNode unroutedPinNode;
/** the Cell-Center node, used for defining the origin of the cell's coordinate space. */
public final PrimitiveNode cellCenterNode;
/** the Port-definition node, used in technology editing to define node ports. */
public final PrimitiveNode portNode;
/** the DRC exclusion node, all design-rule errors covered by this node are ignored. */
public final PrimitiveNode drcNode;
/** the AFG exclusion node, tells auto-fill generator to ignore the area. */
public final PrimitiveNode afgNode;
/** the Essential-bounds node, used (in pairs) to define the important area of a cell. */
public final PrimitiveNode essentialBoundsNode;
/** the Simulation-Probe node, used for highlighting the state of a network. */
public final PrimitiveNode simProbeNode;
/** the Universal arc, connects to any node. */
public final ArcProto universal_arc;
/** the Invisible arc, connects to any node and produces no layout. */
public final ArcProto invisible_arc;
/** the Unrouted arc, connects to any node and specifies desired routing topology. */
public final ArcProto unrouted_arc;
private final PrimitivePort univPinPort, invisPinPort, simProbePort;
// -------------------- private and protected methods ------------------------
public static Generic newInstance(IdManager idManager) {
Generic generic = new Generic(idManager);
generic.setup();
return generic;
}
private Generic(IdManager idManager)
{
super(idManager, null, TechFactory.getGenericFactory(), Collections.<TechFactory.Param,Object>emptyMap(), Foundry.Type.NONE, 0);
setTechShortName("Generic");
setTechDesc("Useful primitives");
setNonStandard();
setFactoryScale(1000, false); // in nanometers: really 1 micron
//**************************************** LAYERS ****************************************
/** Universal layer */
universalLay = Layer.newInstance(this, "Universal",
new EGraphics(false, false, null, 0, 0,0,0,1.0,true,
new int[] {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}));
/** Invisible layer */
Layer invisible_lay = Layer.newInstance(this, "Invisible",
new EGraphics(false, false, null, 0, 180,180,180,1.0,true,
new int[] {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}));
/** Unrouted layer */
Layer unrouted_lay = Layer.newInstance(this, "Unrouted",
new EGraphics(false, false, null, 0, 100,100,100,1.0,true,
new int[] {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}));
/** Glyph layer */
glyphLay = Layer.newInstance(this, "Glyph",
new EGraphics(false, false, null, 0, 0,0,0,1.0,true,
new int[] {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}));
/** DRC layer */
drcLay = Layer.newInstance(this, "DRC",
new EGraphics(false, false, null, 0, 255,190,6,1.0,true,
new int[] {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}));
/** AFG layer */
afgLay = Layer.newInstance(this, "AFG",
new EGraphics(false, false, null, 0, 255,6,190,1.0,true,
new int[] {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}));
/** Simulation Probe layer */
Layer simprobe_lay = Layer.newInstance(this, "Sim-Probe",
new EGraphics(false, false, null, 0, 0,255,0,1.0,true,
new int[] {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}));
// The layer functions
universalLay.setFunction(Layer.Function.UNKNOWN); // Universal
invisible_lay.setFunction(Layer.Function.UNKNOWN, Layer.Function.NONELEC); // Invisible
unrouted_lay.setFunction(Layer.Function.UNKNOWN); // Unrouted
glyphLay.setFunction(Layer.Function.ART, Layer.Function.NONELEC); // Glyph
drcLay.setFunction(Layer.Function.ART, Layer.Function.NONELEC); // DRC
afgLay.setFunction(Layer.Function.ART, Layer.Function.NONELEC); // AFG
simprobe_lay.setFunction(Layer.Function.ART, Layer.Function.NONELEC); // Sim probe
//**************************************** ARCS ****************************************
/** Universal arc */
universal_arc = newArcProto("Universal", 0, 0.0, ArcProto.Function.UNKNOWN,
new Technology.ArcLayer(universalLay, 0, Poly.Type.FILLED)
);
universal_arc.setFactoryFixedAngle(true);
universal_arc.setFactoryAngleIncrement(45);
/** Invisible arc */
invisible_arc = newArcProto("Invisible", 0, 0.0, ArcProto.Function.NONELEC,
new Technology.ArcLayer(invisible_lay, 0, Poly.Type.FILLED)
);
invisible_arc.setFactoryFixedAngle(true);
invisible_arc.setFactoryAngleIncrement(45);
/** Unrouted arc */
unrouted_arc = newArcProto("Unrouted", 0, 0.0, ArcProto.Function.UNROUTED,
new Technology.ArcLayer(unrouted_lay, 0, Poly.Type.FILLED)
);
unrouted_arc.setFactoryFixedAngle(false);
unrouted_arc.setFactoryAngleIncrement(0);
//**************************************** NODES ****************************************
/** Universal pin */
universalPinNode = PrimitiveNode.newInstance("Universal-Pin", this, 1.0, 1.0, null,
new Technology.NodeLayer []
{
new Technology.NodeLayer(universalLay, 0, Poly.Type.DISC, Technology.NodeLayer.POINTS, new Technology.TechPoint [] {
new Technology.TechPoint(EdgeH.makeCenter(), EdgeV.makeCenter()),
new Technology.TechPoint(EdgeH.makeRightEdge(), EdgeV.makeCenter())})
});
univPinPort = PrimitivePort.newInstance(this, universalPinNode, new ArcProto[] {universal_arc}, "univ", 0,180, 0, PortCharacteristic.UNKNOWN,
EdgeH.makeLeftEdge(), EdgeV.makeBottomEdge(), EdgeH.makeRightEdge(), EdgeV.makeTopEdge());
universalPinNode.addPrimitivePortsFixed(new PrimitivePort [] {univPinPort});
universalPinNode.setFunction(PrimitiveNode.Function.PIN);
universalPinNode.setWipeOn1or2();
// universalPinNode.setHoldsOutline();
universalPinNode.setCanBeZeroSize();
/** Invisible pin */
invisiblePinNode = PrimitiveNode.newInstance0("Invisible-Pin", this, 1.0, 1.0,
new Technology.NodeLayer []
{
new Technology.NodeLayer(invisible_lay, 0, Poly.Type.CLOSED, Technology.NodeLayer.BOX, Technology.TechPoint.makeFullBox())
});
invisPinPort = PrimitivePort.newInstance(this, invisiblePinNode, new ArcProto[] {invisible_arc,universal_arc}, "center", 0,180, 0, PortCharacteristic.UNKNOWN,
EdgeH.makeCenter(), EdgeV.makeCenter(), EdgeH.makeCenter(), EdgeV.makeCenter());
invisiblePinNode.addPrimitivePortsFixed(new PrimitivePort [] {invisPinPort});
invisiblePinNode.setFunction(PrimitiveNode.Function.PIN);
invisiblePinNode.setWipeOn1or2();
invisiblePinNode.setCanBeZeroSize();
/** Unrouted pin */
unroutedPinNode = PrimitiveNode.newInstance("Unrouted-Pin", this, 1.0, 1.0, null,
new Technology.NodeLayer []
{
new Technology.NodeLayer(unrouted_lay, 0, Poly.Type.DISC, Technology.NodeLayer.POINTS, new Technology.TechPoint [] {
new Technology.TechPoint(EdgeH.makeCenter(), EdgeV.makeCenter()),
new Technology.TechPoint(EdgeH.makeRightEdge(), EdgeV.makeCenter())})
});
unroutedPinNode.addPrimitivePortsFixed(new PrimitivePort []
{
PrimitivePort.newInstance(this, unroutedPinNode, new ArcProto[] {unrouted_arc,invisible_arc,universal_arc}, "unrouted", 0,180, 0, PortCharacteristic.UNKNOWN,
EdgeH.makeCenter(), EdgeV.makeCenter(), EdgeH.makeCenter(), EdgeV.makeCenter())
});
unroutedPinNode.setFunction(PrimitiveNode.Function.PIN);
unroutedPinNode.setWipeOn1or2();
unroutedPinNode.setCanBeZeroSize();
/** Cell Center */
cellCenterNode = PrimitiveNode.newInstance("Facet-Center", this, 0.0, 0.0, null,
new Technology.NodeLayer []
{
new Technology.NodeLayer(glyphLay, 0, Poly.Type.CLOSED, Technology.NodeLayer.BOX, Technology.TechPoint.makeFullBox()),
new Technology.NodeLayer(glyphLay, 0, Poly.Type.BIGCROSS, Technology.NodeLayer.POINTS, Technology.TechPoint.makeCenterBox())
});
cellCenterNode.addPrimitivePortsFixed(new PrimitivePort []
{
PrimitivePort.newInstance(this, cellCenterNode, new ArcProto[] {invisible_arc,universal_arc}, "center", 0,180, 0, PortCharacteristic.UNKNOWN,
EdgeH.makeLeftEdge(), EdgeV.makeBottomEdge(), EdgeH.makeRightEdge(), EdgeV.makeTopEdge())
});
cellCenterNode.setFunction(PrimitiveNode.Function.ART);
cellCenterNode.setCanBeZeroSize();
/** Port */
portNode = PrimitiveNode.newInstance("Port", this, 6.0, 6.0, new SizeOffset(2, 2, 2, 2),
new Technology.NodeLayer []
{
new Technology.NodeLayer(glyphLay, 0, Poly.Type.CLOSED, Technology.NodeLayer.BOX, Technology.TechPoint.makeIndented(2))
});
portNode.addPrimitivePortsFixed(new PrimitivePort []
{
PrimitivePort.newInstance(this, portNode, new ArcProto[] {invisible_arc,universal_arc}, "center", 0,180, 0, PortCharacteristic.UNKNOWN,
EdgeH.makeCenter(), EdgeV.makeCenter(), EdgeH.makeCenter(), EdgeV.makeCenter())
});
portNode.setFunction(PrimitiveNode.Function.ART);
portNode.setCanBeZeroSize();
// /** DRC Node */
// drcNode = PrimitiveNode.newInstance("DRC-Node", this, 2.0, 2.0, null,
// new Technology.NodeLayer []
// {
// new Technology.NodeLayer(drcLay, 0, Poly.Type.FILLED, Technology.NodeLayer.BOX, Technology.TechPoint.makeFullBox())
// });
// drcNode.addPrimitivePorts(new PrimitivePort []
// {
// PrimitivePort.newInstance(this, drcNode, new ArcProto[] {invisible_arc,universal_arc}, "center", 0,180, 0, PortCharacteristic.UNKNOWN,
// EdgeH.makeCenter(), EdgeV.makeCenter(), EdgeH.makeCenter(), EdgeV.makeCenter())
// });
// drcNode.setFunction(PrimitiveNode.Function.NODE);
// drcNode.setHoldsOutline();
// drcNode.setSpecialType(PrimitiveNode.POLYGONAL);
//
// /** AFG Node */
// afgNode = PrimitiveNode.newInstance("AFG-Node", this, 2.0, 2.0, null,
// new Technology.NodeLayer []
// {
// new Technology.NodeLayer(afgLay, 0, Poly.Type.FILLED, Technology.NodeLayer.BOX, Technology.TechPoint.makeFullBox())
// });
// afgNode.addPrimitivePorts(new PrimitivePort []
// {
// PrimitivePort.newInstance(this, afgNode, new ArcProto[] {invisible_arc,universal_arc}, "center", 0,180, 0, PortCharacteristic.UNKNOWN,
// EdgeH.makeCenter(), EdgeV.makeCenter(), EdgeH.makeCenter(), EdgeV.makeCenter())
// });
// afgNode.setFunction(PrimitiveNode.Function.NODE);
// afgNode.setHoldsOutline();
// afgNode.setSpecialType(PrimitiveNode.POLYGONAL);
//
/** Essential Bounds Node */
essentialBoundsNode = PrimitiveNode.newInstance("Essential-Bounds", this, 0.0, 0.0, null,
new Technology.NodeLayer []
{
new Technology.NodeLayer(glyphLay, 0, Poly.Type.OPENED, Technology.NodeLayer.POINTS, new Technology.TechPoint [] {
new Technology.TechPoint(EdgeH.fromCenter(-1), EdgeV.makeCenter()),
new Technology.TechPoint(EdgeH.makeCenter(), EdgeV.makeCenter()),
new Technology.TechPoint(EdgeH.makeCenter(), EdgeV.fromCenter(-1))})
});
essentialBoundsNode.addPrimitivePortsFixed(new PrimitivePort []
{
PrimitivePort.newInstance(this, essentialBoundsNode, new ArcProto[] {invisible_arc,universal_arc}, "center", 0,180, 0, PortCharacteristic.UNKNOWN,
EdgeH.makeLeftEdge(), EdgeV.makeBottomEdge(), EdgeH.makeRightEdge(), EdgeV.makeTopEdge())
});
essentialBoundsNode.setFunction(PrimitiveNode.Function.ART);
essentialBoundsNode.setCanBeZeroSize();
/** Simulation Probe Node */
simProbeNode = PrimitiveNode.newInstance("Simulation-Probe", this, 10.0, 10.0, null,
new Technology.NodeLayer []
{
new Technology.NodeLayer(simprobe_lay, 0, Poly.Type.FILLED, Technology.NodeLayer.BOX, Technology.TechPoint.makeFullBox())
});
simProbePort = PrimitivePort.newInstance(this, simProbeNode, new ArcProto[] {invisible_arc,universal_arc}, "center", 0,180, 0, PortCharacteristic.UNKNOWN,
EdgeH.makeLeftEdge(), EdgeV.makeBottomEdge(), EdgeH.makeRightEdge(), EdgeV.makeTopEdge());
simProbeNode.addPrimitivePortsFixed(new PrimitivePort [] {simProbePort});
simProbeNode.setFunction(PrimitiveNode.Function.ART);
simProbeNode.setCanBeZeroSize();
// The pure layer nodes
drcNode = drcLay.makePureLayerNode("DRC-Node", 2.0, Poly.Type.FILLED, "center", invisible_arc, universal_arc);
afgNode = afgLay.makePureLayerNode("AFG-Node", 2.0, Poly.Type.FILLED, "center", invisible_arc, universal_arc);
// drcLay.setPureLayerNode(drcNode);
// afgLay.setPureLayerNode(afgNode);
//Foundry
newFoundry(Foundry.Type.NONE, null);
oldNodeNames.put("Cell-Center", cellCenterNode);
}
public void setBackgroudColor(Color c)
{
universalLay.setGraphics(universalLay.getGraphics().withColor(c));
glyphLay.setGraphics(universalLay.getGraphics().withColor(c));
}
/**
* Puts into shape builder s the polygons that describe node "n", given a set of
* NodeLayer objects to use.
* This method is overridden by specific Technologys.
* @param b shape builder where to put polygons
* @param n the ImmutableNodeInst that is being described.
* @param pn proto of the ImmutableNodeInst in this Technology
* @param primLayers an array of NodeLayer objects to convert to Poly objects.
* The prototype of this NodeInst must be a PrimitiveNode and not a Cell.
*/
@Override
protected void genShapeOfNode(AbstractShapeBuilder b, ImmutableNodeInst n, PrimitiveNode pn, Technology.NodeLayer[] primLayers) {
if (pn == invisiblePinNode)
{
boolean hasDisplayVars = false;
for (Iterator<Variable> it = n.getVariables(); it.hasNext(); ) {
Variable var = it.next();
if (var.isDisplay())
hasDisplayVars = true;
}
if (hasDisplayVars || n.isUsernamed() || b.getMemoization().hasExports(n))
return;
// if (ni.isInvisiblePinWithText())
// primLayers = NULLNODELAYER;
}
b.genShapeOfNode(n, pn, primLayers, null);
}
// /**
// * Method to update the connecitivity list for universal and invisible pins so that
// * they can connect to ALL arcs. This is called at initialization and again
// * whenever the number of technologies changes.
// */
// public void makeUnivList()
// {
// // count the number of arcs in all technologies
// int tot = 0;
// for(Iterator<Technology> it = Technology.getTechnologies(); it.hasNext(); )
// {
// Technology tech = it.next();
// tot += tech.getNumArcs();
// }
//
// // make an array for each arc
// ArcProto [] upconn = new ArcProto[tot];
//
// // fill the array
// tot = 0;
// for(Iterator<Technology> it = Technology.getTechnologies(); it.hasNext(); )
// {
// Technology tech = it.next();
// for(Iterator<ArcProto> ait = tech.getArcs(); ait.hasNext(); )
// {
// ArcProto ap = ait.next();
// upconn[tot++] = ap;
// }
// }
//
// // store the array in this technology
// univPinPort.setConnections(upconn);
// invisPinPort.setConnections(upconn);
// simProbePort.setConnections(upconn);
// }
/**
* Tells if all ArcProtos can connect to the PrimitivePort
* @param pp PrimitivePort to test
* @return true if all ArcProtos can connect to the PrimitivePort
*/
@Override
public boolean isUniversalConnectivityPort(PrimitivePort pp) {
return pp == univPinPort || pp == invisPinPort || pp == simProbePort;
}
// /**
// * Method to convert old primitive names to their proper NodeProtos.
// * @param name the name of the old primitive.
// * @return the proper PrimitiveNode to use (or null if none can be determined).
// */
// public PrimitiveNode convertOldNodeName(String name)
// {
// if (name.equals("Cell-Center")) return(cellCenterNode);
// return null;
// }
/**
* Method to detect if this Generic proto is not relevant for some tool calculation and therefore
* could be skip. E.g. cellCenter, drcNodes, essential bounds.
* Similar for layer generation and automatic fill.
* @param ni the NodeInst in question.
* @return true if it is a special node (cell center, etc.)
*/
public static boolean isSpecialGenericNode(NodeInst ni)
{
if (ni.isCellInstance()) return false;
PrimitiveNode np = (PrimitiveNode)ni.getProto();
if (!(np.getTechnology() instanceof Generic)) return false;
Generic tech = (Generic)np.getTechnology();
return (np == tech.cellCenterNode || np == tech.drcNode ||
np == tech.essentialBoundsNode || np == tech.afgNode);
}
}