![JAR search and dependency download from the Maven repository](/logo.png)
com.sun.electric.technology.PrimitiveNode Maven / Gradle / Ivy
/* -*- tab-width: 4 -*-
*
* Electric(tm) VLSI Design System
*
* File: PrimitiveNode.java
*
* Copyright (c) 2003, 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.technology;
import com.sun.electric.database.CellBackup;
import com.sun.electric.database.EObjectInputStream;
import com.sun.electric.database.EObjectOutputStream;
import com.sun.electric.database.EditingPreferences;
import com.sun.electric.database.ImmutableNodeInst;
import com.sun.electric.database.geometry.EPoint;
import com.sun.electric.database.geometry.ERectangle;
import com.sun.electric.database.geometry.Poly;
import com.sun.electric.database.id.PortProtoId;
import com.sun.electric.database.id.PrimitiveNodeId;
import com.sun.electric.database.id.PrimitivePortId;
import com.sun.electric.database.prototype.NodeProto;
import com.sun.electric.database.prototype.PortProto;
import com.sun.electric.database.text.Name;
import com.sun.electric.technology.technologies.Generic;
import com.sun.electric.util.TextUtils;
import com.sun.electric.util.collections.ArrayIterator;
import com.sun.electric.util.math.DBMath;
import com.sun.electric.util.math.EDimension;
import com.sun.electric.util.math.FixpCoord;
import com.sun.electric.util.math.Orientation;
import java.io.IOException;
import java.io.InvalidObjectException;
import java.io.PrintWriter;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
/**
* A PrimitiveNode represents information about a NodeProto that lives in a
* Technology. It has a name, and several functions that describe how
* to draw it
*/
public class PrimitiveNode implements NodeProto, Comparable, Serializable {
/**
* Function is a typesafe enum class that describes the function of a NodeProto.
* Functions are technology-independent and include different types of transistors,
* contacts, and other circuit elements.
*/
public static enum Function {
/** Describes a node with unknown behavior. */
UNKNOWN("unknown", "node", false, false),
/** Describes a single-layer pin.
* Pins connects wires of a single layer, have no geometry, and connect in the center of the node. */
PIN("pin", "pin", false, false),
/** Describes a two-layer contact.
* Contacts connects wires of two different layers in the center of the node. */
CONTACT("contact", "contact", false, false),
/** Describes a pure-layer node.
* Pure-layer nodes have a solid piece of geometry on a single layer. */
NODE("pure-layer-node", "plnode", false, false),
/** Describes a node that connects all ports. */
CONNECT("connection", "conn", false, false),
/** Describes an nMOS transistor.
* It has gate on the first and third ports, the source on the second port, and the drain on the fourth port. */
TRANMOS("nMOS-transistor", "nmos", true, false),
/** Describes a pMOS transistor.
* It has gate on the first and third ports, the source on the second port, and the drain on the fourth port. */
TRAPMOS("pMOS-transistor", "pmos", true, false),
/** Describes an nMOS depletion transistor (should be named TRANMOSD but isn't for historical purposes).
* It has gate on the first and third ports, the source on the second port, and the drain on the fourth port. */
TRADMOS("depletion-nMOS-transistor", "nmos-d", true, false),
/** Describes a pMOS depletion transistor.
* It has gate on the first and third ports, the source on the second port, and the drain on the fourth port. */
TRAPMOSD("depletion-pMOS-transistor", "pmos-d", true, false),
/** Describes an nMOS native transistor.
* It has gate on the first and third ports, the source on the second port, and the drain on the fourth port. */
TRANMOSNT("native-nMOS-transistor", "nmos-nt", true, false),
/** Describes a pMOS native transistor.
* It has gate on the first and third ports, the source on the second port, and the drain on the fourth port. */
TRAPMOSNT("native-pMOS-transistor", "pmos-nt", true, false),
/** Describes an nMOS floating gate transistor.
* It has gate on the first and third ports, the source on the second port, and the drain on the fourth port. */
TRANMOSFG("floating-gate-nMOS-transistor", "nmos-fg", true, false),
/** Describes a pMOS floating gate transistor.
* It has gate on the first and third ports, the source on the second port, and the drain on the fourth port. */
TRAPMOSFG("floating-gate-pMOS-transistor", "pmos-fg", true, false),
/** Describes an nMOS carbon nanotube transistor.
* It has gate on the first and third ports, the source on the second port, and the drain on the fourth port. */
TRANMOSCN("carbon-nanotube-nMOS-transistor", "nmos-cn", true, false),
/** Describes a pMOS carbon nanotube transistor.
* It has gate on the first and third ports, the source on the second port, and the drain on the fourth port. */
TRAPMOSCN("carbon-nanotube-pMOS-transistor", "pmos-cn", true, false),
/** Describes an nMOS low-threshold transistor.
* It has gate on the first and third ports, the source on the second port, and the drain on the fourth port. */
TRANMOSVTL("low-threshold-nMOS-transistor", "nmos-vtl", true, false),
/** Describes a pMOS low-threshold transistor.
* It has gate on the first and third ports, the source on the second port, and the drain on the fourth port. */
TRAPMOSVTL("low-threshold-pMOS-transistor", "pmos-vtl", true, false),
/** Describes an nMOS high-threshold transistor.
* It has gate on the first and third ports, the source on the second port, and the drain on the fourth port. */
TRANMOSVTH("high-threshold-nMOS-transistor", "nmos-vth", true, false),
/** Describes a pMOS high-threshold transistor.
* It has gate on the first and third ports, the source on the second port, and the drain on the fourth port. */
TRAPMOSVTH("high-threshold-pMOS-transistor", "pmos-vth", true, false),
/** Describes an nMOS high-voltage (1) transistor.
* It has gate on the first and third ports, the source on the second port, and the drain on the fourth port. */
TRANMOSHV1("high-voltage-1-nMOS-transistor", "nmos-hv1", true, false),
/** Describes a pMOS high-voltage (1) transistor.
* It has gate on the first and third ports, the source on the second port, and the drain on the fourth port. */
TRAPMOSHV1("high-voltage-1-pMOS-transistor", "pmos-hv1", true, false),
/** Describes an nMOS higher-voltage (2) transistor.
* It has gate on the first and third ports, the source on the second port, and the drain on the fourth port. */
TRANMOSHV2("high-voltage-2-nMOS-transistor", "nmos-hv2", true, false),
/** Describes a pMOS higher-voltage (2) transistor.
* It has gate on the first and third ports, the source on the second port, and the drain on the fourth port. */
TRAPMOSHV2("high-voltage-2-pMOS-transistor", "pmos-hv2", true, false),
/** Describes an nMOS highest-voltage (3) transistor.
* It has gate on the first and third ports, the source on the second port, and the drain on the fourth port. */
TRANMOSHV3("high-voltage-3-nMOS-transistor", "nmos-hv3", true, false),
/** Describes a pMOS highest-voltage (3) transistor.
* It has gate on the first and third ports, the source on the second port, and the drain on the fourth port. */
TRAPMOSHV3("high-voltage-3-pMOS-transistor", "pmos-hv3", true, false),
/** Describes an nMOS native high-voltage (1) transistor.
* It has gate on the first and third ports, the source on the second port, and the drain on the fourth port. */
TRANMOSNTHV1("native-high-voltage-1-nMOS-transistor", "nmos-nt-hv1", true, false),
/** Describes a pMOS native high-voltage (1) transistor.
* It has gate on the first and third ports, the source on the second port, and the drain on the fourth port. */
TRAPMOSNTHV1("native-high-voltage-1-pMOS-transistor", "pmos-nt-hv1", true, false),
/** Describes an nMOS native higher-voltage (2) transistor.
* It has gate on the first and third ports, the source on the second port, and the drain on the fourth port. */
TRANMOSNTHV2("native-high-voltage-2-nMOS-transistor", "nmos-nt-hv2", true, false),
/** Describes a pMOS native higher-voltage (2) transistor.
* It has gate on the first and third ports, the source on the second port, and the drain on the fourth port. */
TRAPMOSNTHV2("native-high-voltage-2-pMOS-transistor", "pmos-nt-hv2", true, false),
/** Describes an nMOS native highest-voltage (3) transistor.
* It has gate on the first and third ports, the source on the second port, and the drain on the fourth port. */
TRANMOSNTHV3("native-high-voltage-3-nMOS-transistor", "nmos-nt-hv3", true, false),
/** Describes a pMOS native highest-voltage (3) transistor.
* It has gate on the first and third ports, the source on the second port, and the drain on the fourth port. */
TRAPMOSNTHV3("native-high-voltage-3-pMOS-transistor", "pmos-nt-hv3", true, false),
/** Describes a NPN junction transistor.
* It has base on the first port, emitter on the second port, and collector on the third port. */
TRANPN("NPN-transistor", "npn", true, false),
/** Describes a PNP junction transistor.
* It has base on the first port, emitter on the second port, and collector on the third port. */
TRAPNP("PNP-transistor", "pnp", true, false),
/** Describes a N-channel junction transistor.
* It has gate on the first port, source on the second port, and drain on the third port. */
TRANJFET("n-type-JFET-transistor", "njfet", true, false),
/** Describes a P-channel junction transistor.
* It has gate on the first port, source on the second port, and drain on the third port. */
TRAPJFET("p-type-JFET-transistor", "pjfet", true, false),
/** Describes a MESFET depletion transistor.
* It has gate on the first port, source on the second port, and drain on the third port. */
TRADMES("depletion-mesfet", "dmes", true, false),
/** Describes a MESFET enhancement transistor.
* It has gate on the first port, source on the second port, and drain on the third port. */
TRAEMES("enhancement-mesfet", "emes", true, false),
/** Describes a general-purpose transistor.
* It is defined self-referentially by the prototype name of the primitive. */
TRANSREF("prototype-defined-transistor", "tref", true, false),
/** Describes an undetermined transistor.
* It has gate on the first port, source on the second port, and drain on the third port.
* The specific transistor type can be determined by examining the value from the NodeInst's "getTechSpecific" method. */
TRANS("transistor", "trans", true, false),
/** Describes a 4-port nMOS transistor.
* It has gate on the first port, source on the second port, drain on the third port, and substrate on the fourth port. */
TRA4NMOS("nMOS-4-port-transistor", "nmos-4", true, false),
/** Describes a 4-port pMOS transistor.
* It has gate on the first port, source on the second port, drain on the third port, and substrate on the fourth port. */
TRA4PMOS("pMOS-4-port-transistor", "pmos-4", true, false),
/** Describes a 4-port nMOS depletion transistor (should be named TRA4NMOSD but isn't for historical purposes).
* It has gate on the first port, source on the second port, drain on the third port, and substrate on the fourth port. */
TRA4DMOS("depletion-nMOS-4-port-transistor", "nmos-d-4", true, false),
/** Describes a 4-port pMOS depletion transistor.
* It has gate on the first port, source on the second port, drain on the third port, and substrate on the fourth port. */
TRA4PMOSD("depletion-pMOS-4-port-transistor", "pmos-d-4", true, false),
/** Describes a 4-port nMOS native transistor.
* It has gate on the first port, source on the second port, drain on the third port, and substrate on the fourth port. */
TRA4NMOSNT("native-nMOS-4-port-transistor", "nmos-nt-4", true, false),
/** Describes a 4-port pMOS native transistor.
* It has gate on the first port, source on the second port, drain on the third port, and substrate on the fourth port. */
TRA4PMOSNT("native-pMOS-4-port-transistor", "pmos-nt-4", true, false),
/** Describes a 4-port nMOS floating gate transistor.
* It has gate on the first and third ports, the source on the second port, and the drain on the fourth port. */
TRA4NMOSFG("floating-gate-nMOS-4-port-transistor", "nmos-fg-4", true, false),
/** Describes a 4-port pMOS floating gate transistor.
* It has gate on the first and third ports, the source on the second port, and the drain on the fourth port. */
TRA4PMOSFG("floating-gate-pMOS-4-port-transistor", "pmos-fg-4", true, false),
/** Describes a 4-port nMOS carbon nanotube transistor.
* It has gate on the first and third ports, the source on the second port, and the drain on the fourth port. */
TRA4NMOSCN("carbon-nanotube-nMOS-4-port-transistor", "nmos-cn-4", true, false),
/** Describes a 4-port pMOS carbon nanotube transistor.
* It has gate on the first and third ports, the source on the second port, and the drain on the fourth port. */
TRA4PMOSCN("carbon-nanotube-pMOS-4-port-transistor", "pmos-cn-4", true, false),
/** Describes a 4-port nMOS low-threshold transistor.
* It has gate on the first port, source on the second port, drain on the third port, and substrate on the fourth port. */
TRA4NMOSVTL("low-threshold-nMOS-4-port-transistor", "nmos-vtl-4", true, false),
/** Describes a 4-port pMOS low-threshold transistor.
* It has gate on the first port, source on the second port, drain on the third port, and substrate on the fourth port. */
TRA4PMOSVTL("low-threshold-pMOS-4-port-transistor", "pmos-vtl-4", true, false),
/** Describes a 4-port nMOS high-threshold transistor.
* It has gate on the first port, source on the second port, drain on the third port, and substrate on the fourth port. */
TRA4NMOSVTH("high-threshold-nMOS-4-port-transistor", "nmos-vth-4", true, false),
/** Describes a 4-port pMOS high-threshold transistor.
* It has gate on the first port, source on the second port, drain on the third port, and substrate on the fourth port. */
TRA4PMOSVTH("high-threshold-pMOS-4-port-transistor", "pmos-vth-4", true, false),
/** Describes a 4-port nMOS high-voltage (1) transistor.
* It has gate on the first port, source on the second port, drain on the third port, and substrate on the fourth port. */
TRA4NMOSHV1("high-voltage-1-nMOS-4-port-transistor", "nmos-hv1-4", true, false),
/** Describes a 4-port pMOS high-threshold (1) transistor.
* It has gate on the first port, source on the second port, drain on the third port, and substrate on the fourth port. */
TRA4PMOSHV1("high-voltage-1-pMOS-4-port-transistor", "pmos-hv1-4", true, false),
/** Describes a 4-port nMOS higher-voltage (2) transistor.
* It has gate on the first port, source on the second port, drain on the third port, and substrate on the fourth port. */
TRA4NMOSHV2("high-voltage-2-nMOS-4-port-transistor", "nmos-hv2-4", true, false),
/** Describes a 4-port pMOS higher-threshold (2) transistor.
* It has gate on the first port, source on the second port, drain on the third port, and substrate on the fourth port. */
TRA4PMOSHV2("high-voltage-2-pMOS-4-port-transistor", "pmos-hv2-4", true, false),
/** Describes a 4-port nMOS highest-voltage (3) transistor.
* It has gate on the first port, source on the second port, drain on the third port, and substrate on the fourth port. */
TRA4NMOSHV3("high-voltage-3-nMOS-4-port-transistor", "nmos-hv3-4", true, false),
/** Describes a 4-port pMOS highest-threshold (3) transistor.
* It has gate on the first port, source on the second port, drain on the third port, and substrate on the fourth port. */
TRA4PMOSHV3("high-voltage-3-pMOS-4-port-transistor", "pmos-hv3-4", true, false),
/** Describes a 4-port nMOS native high-voltage (1) transistor.
* It has gate on the first port, source on the second port, drain on the third port, and substrate on the fourth port. */
TRA4NMOSNTHV1("native-high-voltage-1-nMOS-4-port-transistor", "nmos-nt-hv1-4", true, false),
/** Describes a 4-port pMOS native high-threshold (1) transistor.
* It has gate on the first port, source on the second port, drain on the third port, and substrate on the fourth port. */
TRA4PMOSNTHV1("native-high-voltage-1-pMOS-4-port-transistor", "pmos-nt-hv1-4", true, false),
/** Describes a 4-port nMOS native higher-voltage (2) transistor.
* It has gate on the first port, source on the second port, drain on the third port, and substrate on the fourth port. */
TRA4NMOSNTHV2("native-high-voltage-2-nMOS-4-port-transistor", "nmos-nt-hv2-4", true, false),
/** Describes a 4-port pMOS native higher-threshold (2) transistor.
* It has gate on the first port, source on the second port, drain on the third port, and substrate on the fourth port. */
TRA4PMOSNTHV2("native-high-voltage-2-pMOS-4-port-transistor", "pmos-nt-hv2-4", true, false),
/** Describes a 4-port nMOS native highest-voltage (3) transistor.
* It has gate on the first port, source on the second port, drain on the third port, and substrate on the fourth port. */
TRA4NMOSNTHV3("native-high-voltage-3-nMOS-4-port-transistor", "nmos-nt-hv3-4", true, false),
/** Describes a 4-port pMOS native highest-threshold (3) transistor.
* It has gate on the first port, source on the second port, drain on the third port, and substrate on the fourth port. */
TRA4PMOSNTHV3("native-high-voltage-3-pMOS-4-port-transistor", "pmos-nt-hv3-4", true, false),
/** Describes a 4-port NPN junction transistor.
* It has base on the first port, emitter on the second port, collector on the third port, and substrate on the fourth port. */
TRA4NPN("NPN-4-port-transistor", "npn-4", true, false),
/** Describes a 4-port PNP junction transistor.
* It has base on the first port, emitter on the second port, collector on the third port, and substrate on the fourth port. */
TRA4PNP("PNP-4-port-transistor", "pnp-4", true, false),
/** Describes a 4-port N-channel junction transistor.
* It has gate on the first port, source on the second port, drain on the third port, and substrate on the fourth port. */
TRA4NJFET("n-type-JFET-4-port-transistor", "njfet-4", true, false),
/** Describes a 4-port P-channel junction transistor.
* It has gate on the first port, source on the second port, drain on the third port, and substrate on the fourth port. */
TRA4PJFET("p-type-JFET-4-port-transistor", "pjfet-4", true, false),
/** Describes a 4-port MESFET depletion transistor.
* It has gate on the first port, source on the second port, drain on the third port, and substrate on the fourth port. */
TRA4DMES("4-port-depletion-mesfet", "dmes-4", true, false),
/** Describes a 4-port MESFET enhancement transistor.
* It has gate on the first port, source on the second port, drain on the third port, and substrate on the fourth port. */
TRA4EMES("4-port-enhancement-mesfet", "emes-4", true, false),
/** Describes a general-purpose transistor.
* It has gate on the first port, source on the second port, drain on the third port, and substrate on the fourth port.
* The specific transistor type can be determined by examining the value from the NodeInst's "getTechSpecific" method. */
TRANS4("4-port-transistor", "trans-4", true, false),
/** Describes a resistor. */
RESIST("resistor", "res", false, false),
/** Describes a poly resistor. */
//@Deprecated
PRESIST("poly-resistor", "pres", false, false),
/** Describes a hi ressistant poly resistor. */
RESHIRESPOLY2("hi-res-poly2-resistor", "p2res", false, false),
/** Describes an n-poly resistor */
RESNPOLY("n-type-poly-resistor", "resnpoly", false, false),
/** Describes a p-poly resistor */
RESPPOLY("p-type-poly-resistor", "resppoly", false, false),
/** Describes an n-poly non silicide resistor */
RESNNSPOLY("n-type-no-silicide-poly-resistor", "resnnspoly", false, false),
/** Describes a p-poly non silicide resistor */
RESPNSPOLY("p-type-no-silicide-poly-resistor", "respnspoly", false, false),
/** Describes a well resistor. */
//@Deprecated
WRESIST("well-resistor", "wres", false, false),
/** Describes an n-well resistor */
RESNWELL("n-type-well-resistor", "resnwell", false, false),
/** Describes a p-well resistor */
RESPWELL("p-type-well-resistor", "respwell", false, false),
/** Describes an n-active resistor */
RESNACTIVE("n-type-active-resistor", "resnactive", false, false),
/** Describes a p-active resistor */
RESPACTIVE("p-type-active-resistor", "respactive", false, false),
/** Describes an esd device */
ESDDEVICE("esd-device", "esdd", false, false),
/** Describes a capacitor. */
CAPAC("capacitor", "cap", false, false),
/** Describes an electrolytic capacitor. */
ECAPAC("electrolytic-capacitor", "ecap", false, false),
/** Describes a poly2 capacitor. */
POLY2CAPAC("poly2-capacitor", "poly2cap", false, false),
/** Describes a diode. */
DIODE("diode", "diode", false, false),
/** Describes a zener diode. */
DIODEZ("zener-diode", "zdiode", false, false),
/** Describes an inductor. */
INDUCT("inductor", "ind", false, false),
/** Describes a meter. */
METER("meter", "meter", false, false),
/** Describes a transistor base. */
BASE("base", "base", false, false),
/** Describes a transistor emitter. */
EMIT("emitter", "emit", false, false),
/** Describes a transistor collector. */
COLLECT("collector", "coll", false, false),
/** Describes a buffer.
* It has input on the first port, clocking on the second port, and output on the third port. */
BUFFER("buffer", "buf", false, false),
/** Describes an AND gate.
* It has inputs on the first port and output on the second port. */
GATEAND("AND-gate", "and", false, false),
/** Describes an OR gate.
* It has inputs on the first port and output on the second port. */
GATEOR("OR-gate", "or", false, false),
/** Describes an XOR gate.
* It has inputs on the first port and output on the second port. */
GATEXOR("XOR-gate", "xor", false, false),
/** Describes a RS flip-flop with master-slave triggering. */
FLIPFLOPRSMS("flip-flop-RS-MS", "ffRSms", false, true),
/** Describes a RS flip-flop with positive triggering. */
FLIPFLOPRSP("flip-flop-RS-P", "ffRSp", false, true),
/** Describes a RS flip-flop with negative triggering. */
FLIPFLOPRSN("flip-flop-RS-N", "ffRSn", false, true),
/** Describes a JK flip-flop with master-slave triggering. */
FLIPFLOPJKMS("flip-flop-JK-MS", "ffJKms", false, true),
/** Describes a JK flip-flop with positive triggering. */
FLIPFLOPJKP("flip-flop-JK-P", "ffJKp", false, true),
/** Describes a JK flip-flop with negative triggering. */
FLIPFLOPJKN("flip-flop-JK-N", "ffJKn", false, true),
/** Describes a D flip-flop with master-slave triggering. */
FLIPFLOPDMS("flip-flop-D-MS", "ffDms", false, true),
/** Describes a D flip-flop with positive triggering. */
FLIPFLOPDP("flip-flop-D-P", "ffDp", false, true),
/** Describes a D flip-flop with negative triggering. */
FLIPFLOPDN("flip-flop-D-N", "ffDn", false, true),
/** Describes a T flip-flop with master-slave triggering. */
FLIPFLOPTMS("flip-flop-T-MS", "ffTms", false, true),
/** Describes a T flip-flop with positive triggering. */
FLIPFLOPTP("flip-flop-T-P", "ffTp", false, true),
/** Describes a T flip-flop with negative triggering. */
FLIPFLOPTN("flip-flop-T-N", "ffTn", false, true),
/** Describes a multiplexor. */
MUX("multiplexor", "mux", false, false),
/** Describes a power connection. */
CONPOWER("power", "pwr", false, false),
/** Describes a ground connection. */
CONGROUND("ground", "gnd", false, false),
/** Describes voltage or current source. */
SOURCE("source", "source", false, false),
/** Describes a substrate contact. */
SUBSTRATE("substrate", "substr", false, false),
/** Describes a well contact. */
WELL("well", "well", false, false),
/** Describes a pure artwork. */
ART("artwork", "art", false, false),
/** Describes an array. */
ARRAY("array", "array", false, false),
/** Describes an alignment object. */
ALIGN("align", "align", false, false),
/** Describes a current-controlled voltage source. */
CCVS("ccvs", "ccvs", false, false),
/** Describes a current-controlled current source. */
CCCS("cccs", "cccs", false, false),
/** Describes a voltage-controlled voltage source. */
VCVS("vcvs", "vcvs", false, false),
/** Describes a voltage-controlled current source. */
VCCS("vccs", "vccs", false, false),
/** Describes a transmission line. */
TLINE("transmission-line", "transm", false, false);
private final String name;
private final String shortName;
private final Name basename;
private final boolean isTransistor;
private final boolean isFlipFlop;
private Function(String name, String shortName, boolean isTransistor, boolean isFlipFlop) {
this.name = name;
this.shortName = shortName;
this.basename = Name.findName(TextUtils.canonicString(shortName) + "@0").getBasename();
this.isTransistor = isTransistor;
this.isFlipFlop = isFlipFlop;
}
/**
* Method to return a List of all Functions that exist.
* @return a List of all Functions that exist.
*/
public static List getFunctions() {
return Arrays.asList(Function.class.getEnumConstants());
}
/**
* Method to find a Function by its type name.
* @param typeName the name of the type to find.
* @return a Function (null if not found).
*/
public static Function findType(String typeName) {
List allFuncs = getFunctions();
for (Function fun : allFuncs) {
if (fun.enumName().equalsIgnoreCase(typeName)) {
return fun;
}
}
return null;
}
/**
* Method to find a Function from its name.
* @param name the name to find.
* @return a Function (null if not found).
*/
public static Function findName(String name) {
List allFuncs = getFunctions();
for (Function fun : allFuncs) {
if (fun.name.equalsIgnoreCase(name)) {
return fun;
}
}
return null;
}
/**
* Returns a name of this Function.
* @return a name of this Function.
*/
public String getName() {
return name;
}
/**
* Returns the constant name for this Function.
* Constant names are used when writing Java code, so they must be the same as the actual symbol name.
* @return the constant name for this Function.
*/
public String getConstantName() {
return name();
}
/**
* Returns a short name of this Function.
* @return a short name of this Function.
*/
public String getShortName() {
return shortName;
}
/**
* Returns a base name of this Function for autonaming.
* @return a base name of this Function for autonaming.
*/
public Name getBasename() {
return basename;
}
/**
* Method to tell whether this function describes a contact.
* @return true if this function is a contact.
*/
public boolean isContact() {
return this == CONTACT;
}
/**
* Method to tell whether this function describes a pin.
* @return true if this function is a pin.
*/
public boolean isPin() {
return this == PIN;
}
/**
* Method to tell whether this function describes a capacitor (normal or electrolytic).
* @return true if this function describes a capacitor (normal or electrolytic).
*/
public boolean isCapacitor() {
return this == CAPAC || this == ECAPAC || this == POLY2CAPAC;
}
/**
* Method to tell whether this function describes a resistor (normal, poly or nwell resistor).
* @return true if this function describes a resistor (normal, poly or nwell resistor).
*/
public boolean isResistor() {
return this == RESIST || isComplexResistor();
}
/**
* Method to tell whether this function describes a non simple resistor
* @return true if this function describes a non simple resistor.
*/
public boolean isComplexResistor() {
return this == PRESIST || this == WRESIST || this == RESHIRESPOLY2
|| this == RESNPOLY || this == RESPPOLY
|| this == RESNNSPOLY || this == RESPNSPOLY
|| this == RESNWELL || this == RESPWELL
|| this == RESNACTIVE || this == RESPACTIVE;
}
/**
* Method to tell whether this function describes an ESD device.
* @return true if this function describes an ESD device.
*/
public boolean isESDDevice() {
return this == ESDDEVICE;
}
/**
* Method to tell whether this function describes a transistor.
* @return true if this function describes a transistor.
*/
public boolean isTransistor() {
return isTransistor;
}
/**
* Method to tell whether this function describes a carbon-nanotube transistor.
* @return true if this function describes a carbon-nanotube transistor.
*/
public boolean isCNTransistor() {
return this == TRANMOSCN || this == TRA4NMOSCN || this == TRAPMOSCN || this == TRA4PMOSCN;
}
/**
* Method to tell whether this function describes a field-effect transtor.
* This includes the nMOS, PMOS, and DMOS transistors, as well as the DMES and EMES transistors.
* @return true if this function describes a field-effect transtor.
*/
public boolean isFET() {
if (this == TRANMOS || this == TRA4NMOS || this == TRAPMOS || this == TRA4PMOS
|| this == TRADMOS || this == TRA4DMOS || this == TRAPMOSD || this == TRA4PMOSD
|| this == TRANMOSNT || this == TRA4NMOSNT || this == TRAPMOSNT || this == TRA4PMOSNT
|| this == TRANMOSFG || this == TRA4NMOSFG || this == TRAPMOSFG || this == TRA4PMOSFG
|| this == TRANMOSCN || this == TRA4NMOSCN || this == TRAPMOSCN || this == TRA4PMOSCN
|| this == TRANMOSVTL || this == TRA4NMOSVTL || this == TRAPMOSVTL || this == TRA4PMOSVTL
|| this == TRANMOSVTH || this == TRA4NMOSVTH || this == TRAPMOSVTH || this == TRA4PMOSVTH
|| this == TRANMOSHV1 || this == TRA4NMOSHV1 || this == TRAPMOSHV1 || this == TRA4PMOSHV1
|| this == TRANMOSHV2 || this == TRA4NMOSHV2 || this == TRAPMOSHV2 || this == TRA4PMOSHV2
|| this == TRANMOSHV3 || this == TRA4NMOSHV3 || this == TRAPMOSHV3 || this == TRA4PMOSHV3
|| this == TRANMOSNTHV1 || this == TRA4NMOSNTHV1 || this == TRAPMOSNTHV1 || this == TRA4PMOSNTHV1
|| this == TRANMOSNTHV2 || this == TRA4NMOSNTHV2 || this == TRAPMOSNTHV2 || this == TRA4PMOSNTHV2
|| this == TRANMOSNTHV3 || this == TRA4NMOSNTHV3 || this == TRAPMOSNTHV3 || this == TRA4PMOSNTHV3
|| this == TRANJFET || this == TRA4NJFET || this == TRAPJFET || this == TRA4PJFET
|| this == TRADMES || this == TRA4DMES || this == TRAEMES || this == TRA4EMES) {
return true;
}
return false;
}
/**
* Method to tell whether this function describes a 4-port transtor and to return the equivalent 3-port function.
* @return the equivalent 3-port transistor function for this 4-port function.
* Returns null if this is not a 4-port transistor function.
*/
public Function make3PortTransistor() {
if (!isTransistor) {
return null;
}
if (this == TRA4NMOS) {
return TRANMOS;
}
if (this == TRA4PMOS) {
return TRAPMOS;
}
if (this == TRA4DMOS) {
return TRADMOS;
}
if (this == TRA4PMOSD) {
return TRAPMOSD;
}
if (this == TRA4NMOSNT) {
return TRANMOSNT;
}
if (this == TRA4PMOSNT) {
return TRAPMOSNT;
}
if (this == TRA4NMOSFG) {
return TRANMOSFG;
}
if (this == TRA4PMOSFG) {
return TRAPMOSFG;
}
if (this == TRA4NMOSCN) {
return TRANMOSCN;
}
if (this == TRA4PMOSCN) {
return TRAPMOSCN;
}
if (this == TRA4NMOSVTL) {
return TRANMOSVTL;
}
if (this == TRA4PMOSVTL) {
return TRAPMOSVTL;
}
if (this == TRA4NMOSVTH) {
return TRANMOSVTH;
}
if (this == TRA4PMOSVTH) {
return TRAPMOSVTH;
}
if (this == TRA4NMOSHV1) {
return TRANMOSHV1;
}
if (this == TRA4PMOSHV1) {
return TRAPMOSHV1;
}
if (this == TRA4NMOSHV2) {
return TRANMOSHV2;
}
if (this == TRA4PMOSHV2) {
return TRAPMOSHV2;
}
if (this == TRA4NMOSHV3) {
return TRANMOSHV3;
}
if (this == TRA4PMOSHV3) {
return TRAPMOSHV3;
}
if (this == TRA4NMOSNTHV1) {
return TRANMOSNTHV1;
}
if (this == TRA4PMOSNTHV1) {
return TRAPMOSNTHV1;
}
if (this == TRA4NMOSNTHV2) {
return TRANMOSNTHV2;
}
if (this == TRA4PMOSNTHV2) {
return TRAPMOSNTHV2;
}
if (this == TRA4NMOSNTHV3) {
return TRANMOSNTHV3;
}
if (this == TRA4PMOSNTHV3) {
return TRAPMOSNTHV3;
}
if (this == TRA4NPN) {
return TRANPN;
}
if (this == TRA4PNP) {
return TRAPNP;
}
if (this == TRA4NJFET) {
return TRANJFET;
}
if (this == TRA4PJFET) {
return TRAPJFET;
}
if (this == TRA4DMES) {
return TRADMES;
}
if (this == TRA4EMES) {
return TRAEMES;
}
if (this == TRANS4) {
return TRANS;
}
return null;
}
/**
* Method to tell whether this function describes an n-Type transtor.
* This includes the MOS transistors, as well as the DMES and EMES transistors.
* @return true if this function describes an n-Type transtor.
*/
public boolean isNTypeTransistor() {
if (this == TRANMOS || this == TRA4NMOS
|| this == TRADMOS || this == TRA4DMOS
|| this == TRANMOSNT || this == TRA4NMOSNT
|| this == TRANMOSFG || this == TRA4NMOSFG
|| this == TRANMOSCN || this == TRA4NMOSCN
|| this == TRANMOSVTL || this == TRA4NMOSVTL
|| this == TRANMOSVTH || this == TRA4NMOSVTH
|| this == TRANMOSHV1 || this == TRA4NMOSHV1
|| this == TRANMOSHV2 || this == TRA4NMOSHV2
|| this == TRANMOSHV3 || this == TRA4NMOSHV3
|| this == TRANMOSNTHV1 || this == TRA4NMOSNTHV1
|| this == TRANMOSNTHV2 || this == TRA4NMOSNTHV2
|| this == TRANMOSNTHV3 || this == TRA4NMOSNTHV3
|| this == TRADMES || this == TRA4DMES
|| this == TRAEMES || this == TRA4EMES) {
return true;
}
return false;
}
/**
* Method to tell whether this function describes a p-Type transtor.
* @return true if this function describes a p-Type transtor.
*/
public boolean isPTypeTransistor() {
if (this == TRAPMOS || this == TRA4PMOS
|| this == TRAPMOSD || this == TRA4PMOSD
|| this == TRAPMOSNT || this == TRA4PMOSNT
|| this == TRAPMOSFG || this == TRA4PMOSFG
|| this == TRAPMOSCN || this == TRA4PMOSCN
|| this == TRAPMOSVTL || this == TRA4PMOSVTL
|| this == TRAPMOSVTH || this == TRA4PMOSVTH
|| this == TRAPMOSHV1 || this == TRA4PMOSHV1
|| this == TRAPMOSHV2 || this == TRA4PMOSHV2
|| this == TRAPMOSHV3 || this == TRA4PMOSHV3
|| this == TRAPMOSNTHV1 || this == TRA4PMOSNTHV1
|| this == TRAPMOSNTHV2 || this == TRA4PMOSNTHV2
|| this == TRAPMOSNTHV3 || this == TRA4PMOSNTHV3) {
return true;
}
return false;
}
/**
* Method to tell whether this function describes a bipolar transistor.
* This includes NPN and PNP transistors.
* @return true if this function describes a bipolar transtor.
*/
public boolean isBipolar() {
return this == TRANPN || this == TRA4NPN || this == TRAPNP || this == TRA4PNP;
}
/**
* Method to tell whether this function describes a flip-flop.
* @return true if this function describes a flip-flop.
*/
public boolean isFlipFlop() {
return isFlipFlop;
}
/**
* Returns a printable version of this Function.
* @return a printable version of this Function.
*/
@Override
public String toString() {
return name;
}
/** Returns name of the enumeration constant. For example "TRANMOS".
* By convention, the enumeration names encode information that isn't
* otherwise available. The transistor "TRANMOS" is the same as "TRA4NMOS"
* except that the latter has a substrate connection. RKao
* @return name of the enumeration constant
*/
public String enumName() {
return super.toString();
}
}
// constants used in the "specialType" field
/** Defines a normal node. */
public static final int NORMAL = 0;
/** Defines a serpentine transistor. */
public static final int SERPTRANS = 1;
/** Defines a polygonal transistor. */
public static final int POLYGONAL = 2;
/** set if node is a low vt transistor */
public static final int LOWVTBIT = 010;
/** set if node is a high vt transistor */
public static final int HIGHVTBIT = 020;
/** set if node is a native transistor */
public static final int NATIVEBIT = 040;
/** set if node is a od18 transistor */
public static final int OD18BIT = 0100;
/** set if node is a od25 transistor */
public static final int OD25BIT = 0200;
/** set if node is a od33 transistor */
public static final int OD33BIT = 0400;
/** set if node is a cross contact */
public static final int CROSSCONTACT = 010000000;
/** set if node is an aligned contact */
public static final int ALIGNCONTACT = 020000000;
/** set if nonmanhattan instances shrink */
private static final int NODESHRINK = 01;
/** set if instances can be wiped */
private static final int ARCSWIPE = 01000;
/** set if node is to be kept square in size */
private static final int NSQUARE = 02000;
/** primitive can hold trace information */
private static final int HOLDSTRACE = 04000;
/** set if this primitive can be zero-sized */
private static final int CANBEZEROSIZE = 010000;
/** set to erase if connected to 1 or 2 arcs */
private static final int WIPEON1OR2 = 020000;
/** set if primitive is lockable (cannot move) */
private static final int LOCKEDPRIM = 040000;
/** set if primitive is selectable by edge, not area */
private static final int NEDGESELECT = 0100000;
/** set if nonmanhattan arcs on this shrink */
private static final int ARCSHRINK = 0200000;
// /** set if nonmanhattan arcs on this shrink */ private static final int NINVISIBLE = 0400000;
/** set if node will be considered in palette */
private static final int SKIPSIZEINPALETTE = 01000000;
/** set if not used (don't put in menu) */
private static final int NNOTUSED = 02000000;
// --------------------- private data -----------------------------------
/** The Id of this PrimitiveNode. */
private final PrimitiveNodeId protoId;
/** This PrimitiveNode's Technology. */
private final Technology tech;
/** The group containing this PrimitiveNode */
PrimitiveNodeGroup group;
/** The function of this PrimitiveNode. */
private Function function;
/** layers describing this primitive */
private Technology.NodeLayer[] layers;
/** electrical layers describing this */
private Technology.NodeLayer[] electricalLayers;
/** PrimitivePorts on the PrimitiveNode. */
private PrimitivePort[] primPorts = {};
/** array of ports by portId.chronIndex */
private PrimitivePort[] portsByChronIndex = {};
/** flag bits */
private int userBits;
/** Index of this PrimitiveNode per tech */
private int techPrimNodeIndex = -1;
/** special factors for unusual primitives */
private double[] specialValues;
/** true if contains MULTICUTBOX layers */
private int numMultiCuts;
/** minimum width and height rule */
private NodeSizeRule minNodeSize;
/** size corrector */
private final EPoint[] sizeCorrectors = {EPoint.ORIGIN, EPoint.ORIGIN};
/** offset from database to user */
private SizeOffset offset;
/** base (highlight) rectangle of standard node */
private ERectangle baseRectangle;
/** full (true) rectangle of standard node */
private ERectangle fullRectangle;
/** amount to automatically grow to fit arcs */
private EDimension autoGrowth;
/** template for Spice decks (null if none) */
private String spiceTemplate;
/** factory default instance */
private ImmutableNodeInst factoryDefaultInst;
/** factory default base (highlight) dimension of standard node */
private EDimension factoryDefaultBaseDimension;
// ------------------ private and protected methods ----------------------
/**
* The constructor is never called externally. Use the factory "newInstance" instead.
*/
protected PrimitiveNode(String protoName, Technology tech, EPoint fullSizeCorrector,
double defWidth, double defHeight, ERectangle baseRectangle, Technology.NodeLayer[] layers) {
this(protoName, tech, fullSizeCorrector, EPoint.fromGrid(baseRectangle.getGridWidth() >> 1, baseRectangle.getGridHeight() >> 1),
null, defWidth, defHeight,
ERectangle.fromGrid(-fullSizeCorrector.getGridX(), -fullSizeCorrector.getGridY(), 2 * fullSizeCorrector.getGridX(), 2 * fullSizeCorrector.getGridY()),
baseRectangle, layers);
}
protected PrimitiveNode(String protoName, Technology tech, EPoint sizeCorrector1, EPoint sizeCorrector2, String minSizeRule,
double defWidth, double defHeight, ERectangle fullRectangle, ERectangle baseRectangle, Technology.NodeLayer[] layers) {
// things in the base class
if (!Technology.jelibSafeName(protoName)) {
System.out.println("PrimitiveNode name " + protoName + " is not safe to write in the JELIB");
}
this.protoId = tech.getId().newPrimitiveNodeId(protoName);
this.function = Function.UNKNOWN;
// things in this class
this.tech = tech;
this.layers = layers;
this.electricalLayers = null;
this.userBits = 0;
sizeCorrectors[0] = sizeCorrector1;
sizeCorrectors[1] = sizeCorrector2;
this.fullRectangle = fullRectangle;
this.baseRectangle = baseRectangle;
if (minSizeRule != null) {
minNodeSize = new NodeSizeRule(minSizeRule);
}
assert defWidth >= 0.0 && defHeight >= 0.0;
double factoryExtendX = DBMath.round(0.5 * (defWidth - fullRectangle.getLambdaWidth()));
double factoryExtendY = DBMath.round(0.5 * (defHeight - fullRectangle.getLambdaHeight()));
EPoint factorySize = EPoint.fromLambda(factoryExtendX * 2, factoryExtendY * 2);
factoryDefaultInst = ImmutableNodeInst.newInstance(0, protoId, function.getBasename(), null, Orientation.IDENT,
EPoint.ORIGIN, factorySize, 0, 0, null);
factoryDefaultBaseDimension = new EDimension(baseRectangle.getCoordWidth().add(factorySize.getCoordX()),
baseRectangle.getCoordHeight().add(factorySize.getCoordY()));
double lx = baseRectangle.getLambdaMinX() - fullRectangle.getLambdaMinX();
double hx = fullRectangle.getLambdaMaxX() - baseRectangle.getLambdaMaxX();
double ly = baseRectangle.getLambdaMinY() - fullRectangle.getLambdaMinY();
double hy = fullRectangle.getLambdaMaxY() - baseRectangle.getLambdaMaxY();
offset = new SizeOffset(lx, hx, ly, hy);
this.autoGrowth = null;
int numMultiCuts = 0;
for (Technology.NodeLayer nodeLayer : layers) {
if (nodeLayer.getRepresentation() == Technology.NodeLayer.MULTICUTBOX) {
numMultiCuts++;
}
}
this.numMultiCuts = numMultiCuts;
// add to the nodes in this technology
tech.addNodeProto(this);
check();
}
protected Object writeReplace() {
return new PrimitiveNodeKey(this);
}
private static class PrimitiveNodeKey extends EObjectInputStream.Key {
public PrimitiveNodeKey() {
}
private PrimitiveNodeKey(PrimitiveNode pn) {
super(pn);
}
@Override
public void writeExternal(EObjectOutputStream out, PrimitiveNode pn) throws IOException {
out.writeObject(pn.getTechnology());
out.writeInt(pn.getId().chronIndex);
}
@Override
public PrimitiveNode readExternal(EObjectInputStream in) throws IOException, ClassNotFoundException {
Technology tech = (Technology) in.readObject();
int chronIndex = in.readInt();
PrimitiveNode pn = tech.getPrimitiveNodeByChronIndex(chronIndex);
if (pn == null) {
throw new InvalidObjectException("primitive node not found");
}
return pn;
}
}
static class Polygonal extends PrimitiveNode {
private final Technology.NodeLayer primLayer;
Polygonal(String protoName, Technology tech, EPoint fullSizeCorrector,
double defWidth, double defHeight, ERectangle baseRectangle, Technology.NodeLayer[] layers) {
super(protoName, tech, fullSizeCorrector, defWidth, defHeight, baseRectangle, layers);
setHoldsOutline();
primLayer = layers[0];
check();
}
Polygonal(String protoName, Technology tech, EPoint sizeCorrector1, EPoint sizeCorrector2,
String minSizeRule, double width, double height,
ERectangle fullRectangle, ERectangle baseRectangle, Technology.NodeLayer[] layers) {
super(protoName, tech, sizeCorrector1, sizeCorrector2, minSizeRule, width, height,
fullRectangle, baseRectangle, layers);
setHoldsOutline();
primLayer = layers[0];
check();
}
@Override
void check() {
assert !isArcsWipe() && !isWipeOn1or2();
assert getNodeLayers().length == 1;
assert getElectricalLayers() == null;
Technology.NodeLayer nl = getNodeLayers()[0];
assert !nl.isPseudoLayer();
assert nl.getRepresentation() == Technology.NodeLayer.BOX;
assert !nl.getLayer().isCarbonNanotubeLayer();
assert !nl.getStyle().isText();
super.check();
}
@Override
public int getSpecialType() {
return POLYGONAL;
}
@Override
public void genShape(AbstractShapeBuilder b, ImmutableNodeInst n) {
assert n.protoId == getId();
// if node is erased, remove layers
Layer layer = primLayer.getLayer();
if (b.skipLayer(layer)) {
return;
}
Poly.Type style = primLayer.getStyle();
PrimitivePort pp = primLayer.getPort(this);
b.setCurNode(n);
EPoint[] outline = n.getTrace();
if (outline != null) {
boolean removeCoincidentPoints;
boolean removeSameStartEnd;
switch (style) {
case FILLED:
case CLOSED:
removeCoincidentPoints = true;
removeSameStartEnd = true;
break;
case OPENED:
case OPENEDT1:
case OPENEDT2:
case OPENEDT3:
removeCoincidentPoints = true;
removeSameStartEnd = false;
default:
removeCoincidentPoints = false;
removeSameStartEnd = false;
}
int startPoint = 0;
for (int i = 1; i < outline.length; i++) {
boolean breakPoint = (i == outline.length - 1) || (outline[i] == null);
if (breakPoint) {
if (i == outline.length - 1) {
i++;
}
b.pushOutlineSegment(outline, startPoint, i - startPoint,
removeCoincidentPoints, removeSameStartEnd);
b.pushPoly(style, layer, null, pp);
startPoint = i + 1;
}
}
} else {
EdgeH leftEdge = primLayer.getLeftEdge();
EdgeH rightEdge = primLayer.getRightEdge();
EdgeV topEdge = primLayer.getTopEdge();
EdgeV bottomEdge = primLayer.getBottomEdge();
long portLowX = leftEdge.getFixpValue(n.size);
long portHighX = rightEdge.getFixpValue(n.size);
long portLowY = bottomEdge.getFixpValue(n.size);
long portHighY = topEdge.getFixpValue(n.size);
b.pushPoint(portLowX, portLowY);
b.pushPoint(portHighX, portLowY);
b.pushPoint(portHighX, portHighY);
b.pushPoint(portLowX, portHighY);
b.pushPoly(style, layer, null, pp);
}
}
@Override
public void genBounds(ImmutableNodeInst n, long[] gridCoords) {
EPoint[] trace = n.getTrace();
if (trace != null) {
long lx = trace[0].getGridX();
long ly = trace[0].getGridY();
long hx = lx;
long hy = ly;
for (int i = 1; i < trace.length; i++) {
EPoint p = trace[i];
if (p == null) {
continue;
}
long x = p.getGridX();
long y = p.getGridY();
lx = Math.min(lx, x);
ly = Math.min(ly, y);
hx = Math.max(hx, x);
hy = Math.max(hy, y);
}
long anchorX = n.anchor.getGridX();
long anchorY = n.anchor.getGridY();
gridCoords[0] = anchorX + lx;
gridCoords[1] = anchorY + ly;
gridCoords[2] = anchorX + hx;
gridCoords[3] = anchorY + hy;
return;
}
// if (n.orient == Orientation.IDENT) {
// assert n.orient == Orientation.IDENT;
// long anchorX = n.anchor.getGridX();
// long anchorY = n.anchor.getGridY();
// long halfSizeX = n.size.getGridX() >> 1;
// long halfSizeY = n.size.getGridY() >> 1;
// gridCoords[0] = anchorX - halfSizeX;
// gridCoords[1] = anchorY - halfSizeY;
// gridCoords[2] = anchorX + halfSizeX;
// gridCoords[3] = anchorY + halfSizeY;
// return true;
// }
// assert n.getTrace() == null;
super.genBounds(n, gridCoords);
}
}
static class Serpentine extends PrimitiveNode {
Serpentine(String protoName, Technology tech, EPoint sizeCorrector1, EPoint sizeCorrector2,
String minSizeRule, double width, double height,
ERectangle fullRectangle, ERectangle baseRectangle, Technology.NodeLayer[] layers, double[] specialValues) {
super(protoName, tech, sizeCorrector1, sizeCorrector2, minSizeRule, width, height,
fullRectangle, baseRectangle, layers);
setHoldsOutline();
setCanShrink();
setSpecialValues(specialValues);
}
@Override
public int getSpecialType() {
return SERPTRANS;
}
@Override
public void genShape(AbstractShapeBuilder b, ImmutableNodeInst n) {
assert n.protoId == getId();
assert !isArcsWipe() && !isWipeOn1or2();
Technology.NodeLayer[] primLayers = getNodeLayers();
if (b.isElectrical()) {
Technology.NodeLayer[] eLayers = getElectricalLayers();
if (eLayers != null) {
primLayers = eLayers;
}
}
AbstractShapeBuilder.SerpentineTrans std = b.newSerpentineTrans(n, this, primLayers);
if (std.layersTotal > 0) {
b.setCurNode(n);
std.initTransPolyFilling();
for (int i = 0; i < std.layersTotal; i++) {
std.fillTransPoly();
}
return;
}
b.genShapeOfNode(n, this, primLayers, null);
}
}
// ------------------------- public methods -------------------------------
/**
* Method to create a new PrimitiveNode from the parameters.
* FullRectangle of the new node equals to the BaseRectngle
* @param protoName the name of the PrimitiveNode.
* Primitive names may not contain unprintable characters, spaces, tabs, a colon (:), semicolon (;) or curly braces ({}).
* @param tech the Technology of the PrimitiveNode.
* @param width the width of the PrimitiveNode.
* @param height the height of the PrimitiveNode.
* @param layers the Layers that comprise the PrimitiveNode.
* @return the newly created PrimitiveNode.
*/
public static PrimitiveNode newInstance(String protoName, Technology tech, double width, double height,
Technology.NodeLayer[] layers) {
EPoint sizeCorrector = EPoint.fromLambda(0.5 * width, 0.5 * height);
ERectangle baseRectangle = ERectangle.fromGrid(-sizeCorrector.getGridX(), -sizeCorrector.getGridY(),
2 * sizeCorrector.getGridX(), 2 * sizeCorrector.getGridY());
return new PrimitiveNode(protoName, tech, sizeCorrector,
width, height, baseRectangle, layers);
}
/**
* Method to create a new PrimitiveNode from the parameters.
* @param protoName the name of the PrimitiveNode.
* Primitive names may not contain unprintable characters, spaces, tabs, a colon (:), semicolon (;) or curly braces ({}).
* @param tech the Technology of the PrimitiveNode.
* @param width the width of the PrimitiveNode.
* @param height the height of the PrimitiveNode.
* @param baseRectangle base rectangle of the reported/selected part of the PrimitiveNode.
* @param layers the Layers that comprise the PrimitiveNode.
* @return the newly created PrimitiveNode.
*/
public static PrimitiveNode newInstance(String protoName, Technology tech, double width, double height,
ERectangle baseRectangle, Technology.NodeLayer[] layers) {
EPoint sizeCorrector = EPoint.fromLambda(0.5 * width, 0.5 * height);
return new PrimitiveNode(protoName, tech, sizeCorrector,
width, height, baseRectangle, layers);
}
/** Method to return NodeProtoId of this NodeProto.
* NodeProtoId identifies NodeProto independently of threads.
* PrimitiveNodes are shared among threads, so this method returns this PrimitiveNode.
* @return NodeProtoId of this NodeProto.
*/
@Override
public PrimitiveNodeId getId() {
return protoId;
}
/**
* Method to return the name of this PrimitiveNode in the Technology.
* @return the name of this PrimitiveNode.
*/
@Override
public String getName() {
return protoId.name;
}
/**
* Method to return the full name of this PrimitiveNode.
* Full name has format "techName:primName"
* @return the full name of this PrimitiveNode.
*/
public String getFullName() {
return protoId.fullName;
}
/**
* Method to set the function of this PrimitiveNode.
* The Function is a technology-independent description of the behavior of this PrimitiveNode.
* @param function the new function of this PrimitiveNode.
*/
public void setFunction(Function function) {
checkChanging();
this.function = function;
}
/**
* Method to return the function of this PrimitiveNode.
* The Function is a technology-independent description of the behavior of this PrimitiveNode.
* @return the function of this PrimitiveNode.
*/
@Override
public Function getFunction() {
return function;
}
/**
* Method to return the function of this PrimitiveNode, grouped according to its
* general function.
* For example, all transistors return the same value.
* @return the group function of this PrimitiveNode.
*/
public Function getGroupFunction() {
if (function.isTransistor) {
return Function.TRANS;
}
if (function.isResistor() || function.isCapacitor()
|| function == Function.DIODE || function == Function.DIODEZ || function == Function.INDUCT) {
return Function.INDUCT;
}
if (function == Function.CCVS || function == Function.CCCS
|| function == Function.VCVS || function == Function.VCCS
|| function == Function.TLINE) {
return Function.TLINE;
}
if (function == Function.BASE || function == Function.EMIT
|| function == Function.COLLECT) {
return Function.COLLECT;
}
if (function == Function.BUFFER || function == Function.GATEAND
|| function == Function.GATEOR || function == Function.MUX
|| function == Function.GATEXOR) {
return Function.GATEXOR;
}
if (function == Function.CONPOWER || function == Function.CONGROUND) {
return Function.CONGROUND;
}
if (function == Function.METER || function == Function.SOURCE) {
return Function.SOURCE;
}
if (function == Function.SUBSTRATE || function == Function.WELL) {
return Function.CONTACT;
}
return function;
}
/**
* Method to return the pure "NodeProto Function" a PrimitiveNode in this Technology.
* This method is overridden by technologies (such as Schematics) that know the node's function.
* @param techBits tech bits
* @return the PrimitiveNode.Function that describes the PrinitiveNode with specific tech bits.
*/
public PrimitiveNode.Function getPrimitiveFunction(int techBits) {
return function;
}
/**
* Method to return the technology-specific function bits for a given PrimitiveNode.Function.
* @param function the universal function description
* @return the technology-specific bits to use for that function in this technology.
*/
public int getPrimitiveFunctionBits(PrimitiveNode.Function function) {
return 0;
}
/**
* Method to tell whether this primitive node prototype has technology-specific information on it.
* At the current time, only certain Schematics primitives have this information.
* @return true this primitive node prototype has technology-specific information on it.
*/
public boolean isTechSpecific() {
return false;
}
/**
* Method to return the list of NodeLayers that comprise this PrimitiveNode.
* @return the list of Layers that comprise this PrimitiveNode.
*/
public Technology.NodeLayer[] getNodeLayers() {
return layers;
}
/**
* Method to reset the list of Layers that comprise this PrimitiveNode.
* @param layers
*/
// public void setLayers(Technology.NodeLayer [] layers)
// {
// this.layers = layers;
// }
/**
* Method to return an iterator over the layers in this PrimitiveNode.
* @return an iterator over the layers in this PrimitiveNode.
*/
public Iterator getLayerIterator() {
return new NodeLayerIterator(layers);
}
/**
* Iterator for Layers on this NodeProto
*/
private static class NodeLayerIterator implements Iterator {
Technology.NodeLayer[] array;
int pos;
public NodeLayerIterator(Technology.NodeLayer[] a) {
array = a;
pos = 0;
}
@Override
public boolean hasNext() {
return pos < array.length;
}
@Override
public Layer next() throws NoSuchElementException {
if (pos >= array.length) {
throw new NoSuchElementException();
}
return array[pos++].getLayer();
}
@Override
public void remove() throws UnsupportedOperationException, IllegalStateException {
throw new UnsupportedOperationException();
}
}
/**
* Method to return the list of electrical Layers that comprise this PrimitiveNode.
* Like the list returned by "getLayers", the results describe this PrimitiveNode,
* but each layer is tied to a specific port on the node.
* If any piece of geometry covers more than one port,
* it must be split for the purposes of an "electrical" description.
* For example, the MOS transistor has 2 layers: Active and Poly.
* But it has 3 electrical layers: Active, Active, and Poly.
* The active must be split since each half corresponds to a different PrimitivePort on the PrimitiveNode.
* @return the list of electrical Layers that comprise this PrimitiveNode.
*/
public Technology.NodeLayer[] getElectricalLayers() {
return electricalLayers;
}
/**
* Method to set the list of electrical Layers that comprise this PrimitiveNode.
* Like the list returned by "getLayers", the results describe this PrimitiveNode,
* but each layer is tied to a specific port on the node.
* If any piece of geometry covers more than one port,
* it must be split for the purposes of an "electrical" description.
* For example, the MOS transistor has 2 layers: Active and Poly.
* But it has 3 electrical layers: Active, Active, and Poly.
* The active must be split since each half corresponds to a different PrimitivePort on the PrimitiveNode.
* @param electricalLayers the list of electrical Layers that comprise this PrimitiveNode.
*/
public void setElectricalLayers(Technology.NodeLayer[] electricalLayers) {
this.electricalLayers = electricalLayers;
if (false) {
layers = electricalLayers;
}
}
/**
* Method to find the NodeLayer on this PrimitiveNode with a given Layer.
* If there are more than 1 with the given Layer, the first is returned.
* @param layer the Layer to find.
* @return the NodeLayer that has this Layer.
*/
public Technology.NodeLayer findNodeLayer(Layer layer, boolean electrical) {
// Give higher priority to electrical layers
Technology.NodeLayer[] nodes = (electrical) ? electricalLayers : layers;
if (nodes != null) {
for (int j = 0; j < nodes.length; j++) {
Technology.NodeLayer oneLayer = nodes[j];
if (oneLayer.getLayer() == layer) {
return oneLayer;
}
}
}
return null;
}
/**
* Tells whether this PrimitiveNode has NodeLayer with MULTICUTBOX representation.
* For now, multicut primitives and resistor primitives have such NodeLayers.
* @return true if this PrimitiveNode has NodeLayer with MULTICUTBOX representation.
*/
public boolean hasMultiCuts() {
return numMultiCuts > 0;
}
/**
* Find a NodeLayer of this PrimitiveNode has NodeLayer with MULTICUTBOX representation.
* If no such NodeLayer exists, returns null, if many - returns any of them..
* @return a NodeLayer of this PrimitiveNode has NodeLayer with MULTICUTBOX representation.
*/
public Technology.NodeLayer findMulticut() {
for (Technology.NodeLayer nl : layers) {
if (nl.getRepresentation() == Technology.NodeLayer.MULTICUTBOX) {
return nl;
}
}
return null;
}
/**
* Tells whether this PrimitiveNode is multicut, i.e. it has exactly one NodeLayer with MULTICUTBOX representation,
* @return true if this PrimitiveNode is multicut.
*/
public boolean isMulticut() {
return numMultiCuts == 1;
}
/**
* Method to return the default full width of this PrimitiveNode.
* The default size is fetched from thread-local EditingPreferences
* @return the default width of this PrimitiveNode.
* @deprecated Use method with explicit EditingPreferences parameter.
*/
public double getDefWidth() {
return getDefWidth(EditingPreferences.getThreadEditingPreferences());
}
/**
* Method to return the default full width of this PrimitiveNode.
* The default size is fetched from thread-local EditingPreferences
* @param ep EditingPreferences with default sizes and text descriptors.
* @return the default width of this PrimitiveNode.
*/
@Override
public double getDefWidth(EditingPreferences ep) {
return DBMath.gridToLambda(fullRectangle.getGridWidth() + getDefSize(ep).getGridX());
}
/**
* Method to return the default full height of this PrimitiveNode.
* The default size is fetched from thread-local EditingPreferences
* @return the default height of this PrimitiveNode.
* @deprecated Use method with explicit EditingPreferences parameter.
*/
public double getDefHeight() {
return getDefHeight(EditingPreferences.getThreadEditingPreferences());
}
/**
* Method to return the default full height of this PrimitiveNode.
* The default size is fetched from thread-local EditingPreferences
* @param ep EditingPreferences with default sizes and text descriptors.
* @return the default height of this PrimitiveNode.
*/
@Override
public double getDefHeight(EditingPreferences ep) {
return DBMath.gridToLambda(fullRectangle.getGridHeight() + getDefSize(ep).getGridY());
}
/**
* Method to return the default size of this PrimitiveNode
* in specified EditingPreferences.
* @param ep specified EditingPreferences with default sizes
* @return the default size this PrimitiveNode
*/
@Override
public EPoint getDefSize(EditingPreferences ep) {
return getDefaultInst(ep).size;
}
/**
* Method to return the default base width of this PrimitiveNode in lambda units
* in specified EditingPreferences.
* @param ep specified EditingPreferences
* @return the default base width of this PrimitiveNode in lambda units.
*/
public double getDefaultLambdaBaseWidth(EditingPreferences ep) {
return DBMath.gridToLambda(getDefaultGridBaseWidth(ep));
}
/**
* Method to return the default base hwight of this PrimitiveNode in lambda units
* in specified EditingPreferences.
* @param ep specified EditingPreferences
* @return the default base height of this PrimitiveNode in lambda units.
*/
public double getDefaultLambdaBaseHeight(EditingPreferences ep) {
return DBMath.gridToLambda(getDefaultGridBaseHeight(ep));
}
/**
* Method to return the default base width of this PrimitiveNode in grid units
* in specified EditingPreferences.
* @param ep specified EditingPreferences
* @return the default base width of this PrimitiveNode in grid units.
*/
public long getDefaultGridBaseWidth(EditingPreferences ep) {
return baseRectangle.getGridWidth() + getDefaultInst(ep).size.getGridX();
}
/**
* Method to return the default base height of this PrimitiveNode in grid units
* in specified EditingPreferences.
* @param ep specified EditingPreferences
* @return the default base height of this PrimitiveNode in grid units.
*/
public long getDefaultGridBaseHeight(EditingPreferences ep) {
return baseRectangle.getGridHeight() + getDefaultInst(ep).size.getGridY();
}
/**
* Method to return the factory default base diminsion of this PrimitiveNode.
* @return the factory default base dimension of this PrimitiveNode.
*/
public EDimension getFactoryDefaultBaseDimension() {
return factoryDefaultBaseDimension;
}
/**
* Method to return the factory defaut extend of this PrimitiveNode over minimal width and height.
* @return the defaut extend of this PrimitiveNode over minimal width as EPoint.
*/
public EPoint getFactoryDefaultSize() {
return factoryDefaultInst.size;
}
/**
* Method to return the default immutable instance of this PrimitiveNode
* in specified EditingPreferences.
* @param ep specified EditingPreferences
* @return the default immutable instance of this PrimitiveNode
*/
public ImmutableNodeInst getDefaultInst(EditingPreferences ep) {
ImmutableNodeInst defaultInst = ep.getDefaultNode(protoId);
return defaultInst != null ? defaultInst : factoryDefaultInst;
}
/**
* Method to return the factory default immutable instance of this PrimitiveNode
* @return the factory default immutable instance of this PrimitiveNode
*/
public ImmutableNodeInst getFactoryDefaultInst() {
return factoryDefaultInst;
}
/**
* Method to get the size offset of this PrimitiveNode.
* To get the SizeOffset for a specific NodeInst, use Technology.getSizeOffset(ni).
* Use this method only to get the SizeOffset of a PrimitiveNode.
* @return the size offset of this PrimitiveNode.
*/
@Override
public SizeOffset getProtoSizeOffset() {
return offset;
}
/**
* Method to get the base (highlight) ERectangle of this PrimitiveNode.
* Base ERectangle is a highlight rectangle of standard-size NodeInst of
* this PrimtiveNode
* To get the base ERectangle for a specific NodeInst, use Technology.getBaseRectangle(ni).
* Use this method only to get the base ERectangle of a PrimitiveNode.
* @return the base ERectangle of this PrimitiveNode.
*/
public ERectangle getBaseRectangle() {
return baseRectangle;
}
/**
* Method to get the full (true) ERectangle of this PrimitiveNode.
* Base ERectangle is a highlight rectangle of standard-size NodeInst of
* this PrimtiveNode
* To get the full (true) ERectangle for a specific NodeInst, use Technology.getBaseRectangle(ni).
* Use this method only to get the base ERectangle of a PrimitiveNode.
* @return the base ERectangle of this PrimitiveNode.
*/
public ERectangle getFullRectangle() {
return fullRectangle;
}
EPoint getSizeCorrector(int version) {
return sizeCorrectors[version];
}
EPoint getMinimumSize() {
double minX = -baseRectangle.getWidth();
double minY = -baseRectangle.getHeight();
for (PrimitivePort pp : primPorts) {
double lm = pp.getLeft().getMultiplier();
double rm = pp.getRight().getMultiplier();
assert lm <= rm;
if (lm < rm) {
double x = -pp.getRight().getAdder().subtract(pp.getLeft().getAdder()).getLambda() / (rm - lm);
if (x > minX) {
minX = x;
}
}
double bm = pp.getBottom().getMultiplier();
double tm = pp.getTop().getMultiplier();
assert bm <= tm;
if (bm < tm) {
double y = -pp.getTop().getAdder().subtract(pp.getBottom().getAdder()).getLambda() / (tm - bm);
if (y > minY) {
minY = y;
}
}
}
return EPoint.fromLambda(minX, minY);
}
/**
* Method to return the minimum size rule for this PrimitiveNode.
* @return the minimum size rule for this PrimitiveNode.
*/
public NodeSizeRule getMinSizeRule() {
return minNodeSize;
}
/**
* Method to set the minimum height of this PrimitiveNode.
* If no name is provided, it uses the PrimitiveNode name to compose the rule name.
* @param minHeight the minimum height of this PrimitiveNode.
*/
public void setMinSize(double minWidth, double minHeight, String minSizeRule) {
setSizeCorrector(minWidth, minHeight);
// If no name is provided, it uses the PrimitiveNode name to compose the rule name.
// That is done in the class NodeSizeRule
if (DBMath.areEquals(minWidth, minHeight)) {
minNodeSize = new NodeSizeRule(minSizeRule);
} else // Different functions to check node sizes.
{
minNodeSize = new AsymmetricNodeSizeRule(minSizeRule);
}
check();
}
private void setSizeCorrector(double refWidth, double refHeight) {
long extendX = DBMath.lambdaToGrid(0.5 * refWidth);
long extendY = DBMath.lambdaToGrid(0.5 * refHeight);
sizeCorrectors[0] = EPoint.fromGrid(extendX, extendY);
fullRectangle = ERectangle.fromGrid(-extendX, -extendY, 2 * extendX, 2 * extendY);
long lx = fullRectangle.getGridMinX() + offset.getLowXGridOffset();
long hx = fullRectangle.getGridMaxX() - offset.getHighXGridOffset();
long ly = fullRectangle.getGridMinY() + offset.getLowYGridOffset();
long hy = fullRectangle.getGridMaxY() - offset.getHighYGridOffset();
baseRectangle = ERectangle.fromGrid(lx, ly, hx - lx, hy - ly);
sizeCorrectors[1] = EPoint.fromGrid(baseRectangle.getGridWidth() >> 1, baseRectangle.getGridHeight() >> 1);
check();
}
/**
* Method to set the size offset of this PrimitiveNode.
* @param offset the size offset of this PrimitiveNode.
*/
public void setSizeOffset(SizeOffset offset) {
this.offset = offset;
long lx = fullRectangle.getGridMinX() + offset.getLowXGridOffset();
long hx = fullRectangle.getGridMaxX() - offset.getHighXGridOffset();
long ly = fullRectangle.getGridMinY() + offset.getLowYGridOffset();
long hy = fullRectangle.getGridMaxY() - offset.getHighYGridOffset();
baseRectangle = ERectangle.fromGrid(lx, ly, hx - lx, hy - ly);
sizeCorrectors[1] = EPoint.fromGrid(baseRectangle.getGridWidth() >> 1, baseRectangle.getGridHeight() >> 1);
check();
}
/**
* Method to set the auto-growth factor on this PrimitiveNode.
* The auto-growth factor is the amount to exand the node when new arcs
* want to connect to an expandable port and there is no room for the arcs.
* The only nodes that have auto-growth factors are the AND, OR, XOR, SWITCH, and MUX
* nodes of the Schematics technology.
* These nodes have ports that can accomodate any number of arcs.
* @param dX the X amount to grow this PrimitiveNode when arcs don't fit.
* @param dY the Y amount to grow this PrimitiveNode when arcs don't fit.
*/
public void setAutoGrowth(double dX, double dY) {
autoGrowth = new EDimension(dX, dY);
}
/**
* Method to get the auto-growth factor for this PrimitiveNode.
* The auto-growth factor is the amount to exand the node when new arcs
* want to connect to an expandable port and there is no room for the arcs.
* The only nodes that have auto-growth factors are the AND, OR, XOR, SWITCH, and MUX
* nodes of the Schematics technology.
* These nodes have ports that can accomodate any number of arcs.
* @return the amount to grow this PrimitiveNode when arcs don't fit.
*/
public EDimension getAutoGrowth() {
return autoGrowth;
}
/**
* 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 Technologies.
* @param b shape builder where to put polygons
* @param n the ImmutableNodeInst that is being described.
*/
public void genShape(AbstractShapeBuilder b, ImmutableNodeInst n) {
assert n.protoId == getId();
// if node is erased, remove layers
if (b.isWipePins() && b.getMemoization() != null) {
if (isArcsWipe() && b.getMemoization().isWiped(n)) {
return;
}
if (isWipeOn1or2() && b.getMemoization().pinUseCount(n)) {
return;
}
}
Technology.NodeLayer[] primLayers = getNodeLayers();
if (b.isElectrical()) {
Technology.NodeLayer[] eLayers = getElectricalLayers();
if (eLayers != null) {
primLayers = eLayers;
}
}
b.genShapeOfNode(n, this, primLayers, null);
}
public void genBounds(ImmutableNodeInst n, long[] gridCoords) {
ERectangle full = getFullRectangle(); // Can full rectangle be assymetric ?!
if (full.getGridMinX() != -full.getGridMaxX() || full.getGridMinY() != -full.getGridMaxY()) {
long halfSizeX = n.size.getGridX() >> 1;
long halfSizeY = n.size.getGridY() >> 1;
gridCoords[0] = full.getGridMinX() - halfSizeX;
gridCoords[1] = full.getGridMinY() - halfSizeY;
gridCoords[2] = full.getGridMaxX() + halfSizeX;
gridCoords[3] = full.getGridMaxY() + halfSizeY;
n.orient.rectangleBounds(gridCoords);
long anchorX = n.anchor.getGridX();
long anchorY = n.anchor.getGridY();
gridCoords[0] += anchorX;
gridCoords[1] += anchorY;
gridCoords[2] += anchorX;
gridCoords[3] += anchorY;
return;
}
long gridWidth = n.size.getGridX() + full.getGridWidth();
long gridHeight = n.size.getGridY() + full.getGridHeight();
if (gridWidth == 0 && gridHeight == 0) {
gridCoords[0] = gridCoords[2] = n.anchor.getGridX();
gridCoords[1] = gridCoords[3] = n.anchor.getGridY();
return;
}
long gridW2, gridH2;
if (n.orient.isManhattan()) {
gridCoords[0] = gridWidth >> 1;
gridCoords[1] = gridHeight >> 1;
n.orient.transformPoints(1, gridCoords);
gridW2 = Math.abs(gridCoords[0]);
gridH2 = Math.abs(gridCoords[1]);
} else {
long fixpW2 = gridWidth << (FixpCoord.FRACTION_BITS - 1);
long fixpH2 = gridHeight << (FixpCoord.FRACTION_BITS - 1);
long[] fixpCoords = gridCoords; // Reuse gridCoords temporarily
fixpCoords[0] = -fixpW2;
fixpCoords[1] = -fixpH2;
fixpCoords[2] = fixpW2;
fixpCoords[3] = fixpH2;
n.orient.rectangleBounds(fixpCoords);
gridW2 = -(fixpCoords[0] >> FixpCoord.FRACTION_BITS);
gridH2 = -(fixpCoords[0] >> FixpCoord.FRACTION_BITS);
}
long gridAnchorX = n.anchor.getGridX();
long gridAnchorY = n.anchor.getGridY();
gridCoords[0] = gridAnchorX - gridW2;
gridCoords[1] = gridAnchorY - gridH2;
gridCoords[2] = gridAnchorX + gridW2;
gridCoords[3] = gridAnchorY + gridH2;
}
public void genElibBounds(CellBackup.Memoization m, ImmutableNodeInst n, long[] gridCoords) {
ERectangle full = getFullRectangle(); // Can full rectangle be assymetric ?!
if (full.getGridMinX() == -full.getGridMaxX() && full.getGridMinY() == -full.getGridMaxY()) {
long gridWidth = n.size.getGridX() + full.getGridWidth();
long gridHeight = n.size.getGridY() + full.getGridHeight();
if (gridWidth == 0 && gridHeight == 0) {
gridCoords[0] = gridCoords[2] = n.anchor.getGridX();
gridCoords[1] = gridCoords[3] = n.anchor.getGridY();
return;
}
// special case for pins that become steiner points
if (isWipeOn1or2() && m != null && !m.hasExports(n) && m.pinUseCount(n)) {
gridCoords[0] = gridCoords[2] = n.anchor.getGridX();
gridCoords[1] = gridCoords[3] = n.anchor.getGridY();
return;
}
}
genBounds(n, gridCoords);
}
/**
* Method to set the Spice template on this PrimitiveNode.
* The Spice template is a string that has parameters which are
* filled-in to produce the line in the Spice deck corresponding to this PrimitiveNode.
* @param st the Spice template on this PrimitiveNode.
*/
public void setSpiceTemplate(String st) {
spiceTemplate = st;
}
/**
* Method to get the Spice template on this PrimitiveNode.
* The Spice template is a string that has parameters which are
* filled-in to produce the line in the Spice deck corresponding to this PrimitiveNode.
* @return the Spice template on this PrimitiveNode.
*/
public String getSpiceTemplate() {
return spiceTemplate;
}
/**
* Method to return the Technology of this PrimitiveNode.
* @return the Technology of this PrimitiveNode.
*/
@Override
public Technology getTechnology() {
return tech;
}
/**
* Method to return the PrimitiveNodeGroup that contains this PrimitiveNode.
* Return null if this PrimitiveNode is not contained in any group.
* @return the Technology of this PrimitiveNode.
*/
public PrimitiveNodeGroup getPrimitiveNodeGroup() {
return group;
}
/**
* Method to add an array of PrimitivePorts to this PrimitiveNode.
* The method is only used during initialization.
* @param ports the array of PrimitivePorts to add.
*/
public void addPrimitivePorts(PrimitivePort... ports) {
assert ports.length == primPorts.length;
for (int i = 0; i < primPorts.length; i++) {
assert primPorts[i] == ports[i];
assert primPorts[i].getPortIndex() == i;
assert primPorts[i].getId().externalId.isEmpty() == (ports.length == 1);
}
check();
}
void addPrimitivePort(PrimitivePort pp) {
assert pp.getParent() == this;
assert pp.getPortIndex() == primPorts.length;
PrimitivePort[] newPrimPorts = new PrimitivePort[primPorts.length + 1];
System.arraycopy(primPorts, 0, newPrimPorts, 0, primPorts.length);
newPrimPorts[pp.getPortIndex()] = pp;
primPorts = newPrimPorts;
PrimitivePortId primitivePortId = pp.getId();
if (primitivePortId.chronIndex >= portsByChronIndex.length) {
PrimitivePort[] newPortsByChronIndex = new PrimitivePort[primitivePortId.chronIndex + 1];
System.arraycopy(portsByChronIndex, 0, newPortsByChronIndex, 0, portsByChronIndex.length);
portsByChronIndex = newPortsByChronIndex;
}
portsByChronIndex[primitivePortId.chronIndex] = pp;
}
/**
* Method to find the PortProto that has a particular name.
* @return the PortProto, or null if there is no PortProto with that name.
*/
@Override
public PortProto findPortProto(String name) {
if (name == null) {
return null;
}
return findPortProto(Name.findName(name));
}
/**
* Method to find the PortProto that has a particular Name.
* @return the PortProto, or null if there is no PortProto with that name.
*/
@Override
public PortProto findPortProto(Name name) {
if (name == null) {
return null;
}
for (int i = 0; i < primPorts.length; i++) {
PrimitivePort pp = primPorts[i];
if (pp.getNameKey() == name) {
return pp;
}
}
return null;
}
/**
* Returns the PrimitivePort in this technology with a particular chron index
* @param chron index the Id of the PrimitivePort.
* @return the PrimitivePort in this technology with that Id.
*/
PrimitivePort getPrimitivePortByChronIndex(int chronIndex) {
return chronIndex < portsByChronIndex.length ? portsByChronIndex[chronIndex] : null;
}
/**
* Method to return an iterator over all PortProtos of this NodeProto.
* @return an iterator over all PortProtos of this NodeProto.
*/
@Override
public Iterator getPorts() {
return ArrayIterator.iterator((PortProto[]) primPorts);
}
/**
* Method to return an iterator over all PrimitivePorts of this PrimitiveNode.
* @return an iterator over all PrimitvePorts of this NodeProto.
*/
public Iterator getPrimitivePorts() {
return ArrayIterator.iterator(primPorts);
}
/**
* Method to return the number of PortProtos on this NodeProto.
* @return the number of PortProtos on this NodeProto.
*/
@Override
public int getNumPorts() {
return primPorts.length;
}
/**
* Method to return the PortProto at specified position.
* @param portIndex specified position of PortProto.
* @return the PortProto at specified position..
*/
@Override
public final PrimitivePort getPort(int portIndex) {
return primPorts[portIndex];
}
/**
* Method to return the PortProto by thread-independent PortProtoId.
* @param portProtoId thread-independent PortProtoId.
* @return the PortProto.
* @throws IllegalArgumentException if portProtoId is not from this NodeProto.
*/
@Override
public PrimitivePort getPort(PortProtoId portProtoId) {
if (portProtoId.getParentId() != protoId) {
throw new IllegalArgumentException();
}
int chronIndex = portProtoId.chronIndex;
return chronIndex < portsByChronIndex.length ? portsByChronIndex[chronIndex] : null;
}
/**
* Method to return the PrimitivePort on this PrimitiveNode that can connect to an arc of the specified type.
* The method finds a PrimitivePort that can make the connection.
* @param arc the type of arc to connect to an instance of this PrimitiveNode.
* @return a PrimitivePort that can connect to this type of ArcProto.
* Returns null if this ArcProto cannot connect to anything on this PrimitiveNode.
*/
public PrimitivePort connectsTo(ArcProto arc) {
for (int i = 0; i < primPorts.length; i++) {
PrimitivePort pp = primPorts[i];
if (pp.connectsTo(arc)) {
return pp;
}
}
return null;
}
/**
* Method to return the special type of this PrimitiveNode.
* It can be one of NORMAL, SERPTRANS, POLYGONAL.
* @return the special type of this PrimitiveNode.
*/
public int getSpecialType() {
return NORMAL;
}
/**
* Method to return the name of a special PrimitiveNode type.
* @param t the integer special type.
* @return the name of that type.
*/
public static String getSpecialTypeName(int t) {
if (t == NORMAL) {
return "normal";
}
if (t == SERPTRANS) {
return "serp-trans";
}
if (t == POLYGONAL) {
return "outline";
}
return "?";
}
/**
* Method to return the special values stored on this PrimitiveNode.
* The special values are an array of integers that describe unusual features of the PrimitiveNode.
* They are only relevant for certain specialType cases:
*
* - for MULTICUT:
*
* - cut size is [0] x [1]
*
- cut indented [2] x [3] from highlighting
*
- cuts spaced [4] apart for 1-dimensional contact
*
- cuts spaced [5] apart for 2-dimensional contact
*
* - for SERPTRANS:
*
* - layer count is [0] (never used)
*
- active port inset [1] from end of serpentine path
*
- active port is [2] from poly edge
*
- poly width is [3]
*
- poly port inset [4] from poly edge
*
- poly port is [5] from active edge
*
* @return the special values stored on this PrimitiveNode.
*/
public double[] getSpecialValues() {
return specialValues;
}
public EPoint getMulticut2Size() {
Technology.NodeLayer cutLayer = findMulticut();
assert cutLayer.getLeftEdge().getMultiplier() == -0.5;
assert cutLayer.getBottomEdge().getMultiplier() == -0.5;
assert cutLayer.getRightEdge().getMultiplier() == 0.5;
assert cutLayer.getTopEdge().getMultiplier() == 0.5;
double x = cutLayer.getMulticutSizeX().add(cutLayer.getMulticutSep2D()).add(cutLayer.getLeftEdge().getAdder()).subtract(cutLayer.getRightEdge().getAdder()).getLambda();
double y = cutLayer.getMulticutSizeY().add(cutLayer.getMulticutSep2D()).add(cutLayer.getBottomEdge().getAdder()).subtract(cutLayer.getTopEdge().getAdder()).getLambda();
x += fullRectangle.getLambdaWidth();
y += fullRectangle.getLambdaHeight();
return EPoint.fromLambda(x, y);
}
/**
* Method to set the special values stored on this PrimitiveNode.
* The special values are an array of values that describe unusual features of the PrimitiveNode.
* The meaning depends on the specialType (see the documentation for "getSpecialValues").
* @param specialValues the special values for this PrimitiveNode.
*/
public void setSpecialValues(double[] specialValues) {
if (specialValues.length != 6) {
throw new IndexOutOfBoundsException("Invalid number of values in setSpecialValues");
}
this.specialValues = specialValues;
}
/**
* Method to tell whether this PrimitiveNode is a Pin.
* Pin nodes have one port, no valid geometry, and are used to connect arcs.
* @return true if this PrimitiveNode is a Pin.
*/
public boolean isPin() {
return (getFunction().isPin());
}
/**
* Method to describe this PrimitiveNode as a string.
* If the primitive is not from the current technology, prepend the technology name.
* @param withQuotes to wrap description between quotes
* @return a description of this PrimitiveNode.
*/
@Override
public String describe(boolean withQuotes) {
String name = "";
if (tech != Technology.getCurrent()) {
name += tech.getTechName() + ":";
}
name += getName();
return (withQuotes) ? "'" + name + "'" : name;
}
/**
* Method to describe this PrimitiveNode as a string.
* Always prepend the technology name.
* @return a description of this PrimitiveNode.
*/
@Override
public String libDescribe() {
return getFullName();
}
/**
* Method to describe this PrimitiveNode as a string.
* Always prepend the technology name.
* @return a description of this PrimitiveNode.
*/
@Override
public String noLibDescribe() {
return getName();
}
/**
* Method to determine if node has a given bit on. This is usefull for different
* @param bit bit containing information to query. It could be LOWVTTRANS,
* HIGHVTTRANS, NATIVETRANS, OD18TRANS, OD25TRANS or OD33TRANS in case of transistors.
* @return true if the given bit is on in the node.
*/
public boolean isNodeBitOn(int bit) {
assert (bit == LOWVTBIT
|| bit == HIGHVTBIT
|| bit == NATIVEBIT
|| bit == OD18BIT
|| bit == OD25BIT
|| bit == OD33BIT);
return (userBits & bit) != 0;
}
/**
* Method to set certain bit during construction
* @param bit
*/
public void setNodeBit(int bit) {
checkChanging();
userBits |= bit;
}
/**
* Method to allow instances of this PrimitiveNode not to be considered in
* tech palette for the calculation of the largest icon.
* Valid for menu display
*/
public void setSkipSizeInPalette() {
checkChanging();
userBits |= SKIPSIZEINPALETTE;
}
/**
* Method to tell if instaces of this PrimitiveNode are special (don't appear in menu).
* Valid for menu display
*/
public boolean isSkipSizeInPalette() {
return (userBits & SKIPSIZEINPALETTE) != 0;
}
/**
* Method to allow instances of this PrimitiveNode to shrink.
* Shrinkage occurs on MOS transistors when they are connected to wires at angles that are not manhattan
* (the angle between the transistor and the wire is not a multiple of 90 degrees).
* The actual transistor must be shrunk back appropriately to prevent little tabs from emerging at the connection site.
* This state is only set on primitive node prototypes.
* If the actual NodeInst is to shrink, it must be marked with "setShortened".
* Note that shrinkage does not apply if there is no arc connected.
*/
public void setCanShrink() {
checkChanging();
userBits |= NODESHRINK;
}
/**
* Method to prevent instances of this PrimitiveNode from shrinking.
* Shrinkage occurs on MOS transistors when they are connected to wires at angles that are not manhattan
* (the angle between the transistor and the wire is not a multiple of 90 degrees).
* The actual transistor must be shrunk back appropriately to prevent little tabs from emerging at the connection site.
* This state is only set on primitive node prototypes.
* If the actual NodeInst is to shrink, it must be marked with "setShortened".
* Note that shrinkage does not apply if there is no arc connected.
*/
public void clearCanShrink() {
checkChanging();
userBits &= ~NODESHRINK;
}
/**
* Method to tell if instances of this PrimitiveNode can shrink.
* Shrinkage occurs on MOS transistors when they are connected to wires at angles that are not manhattan
* (the angle between the transistor and the wire is not a multiple of 90 degrees).
* The actual transistor must be shrunk back appropriately to prevent little tabs from emerging at the connection site.
* This state is only set on primitive node prototypes.
* If the actual NodeInst is to shrink, it must be marked with "setShortened".
* Note that shrinkage does not apply if there is no arc connected.
* @return true if instances of this PrimitiveNode can shrink.
*/
public boolean canShrink() {
return (userBits & NODESHRINK) != 0;
}
/**
* Method to set this PrimitiveNode so that instances of it are "arc-wipable".
* For display efficiency reasons, pins that have arcs connected to them should not bother being drawn.
* Therefore, pin prototypes have this state set, and when instances of the
* appropriate arc prototypes connect to instances of these pins, they stop being drawn.
* It is necessary for the arc prototype to enable wiping (with setWipable).
* A NodeInst that becomes wiped out has "setWiped" called.
*/
public void setArcsWipe() {
checkChanging();
userBits |= ARCSWIPE;
}
/**
* Method to set this PrimitiveNode so that instances of it are not "arc-wipable".
* For display efficiency reasons, pins that have arcs connected to them should not bother being drawn.
* Therefore, pin prototypes have this state set, and when instances of the
* appropriate arc prototypes connect to instances of these pins, they stop being drawn.
* It is necessary for the arc prototype to enable wiping (with setWipable).
* A NodeInst that becomes wiped out has "setWiped" called.
*/
public void clearArcsWipe() {
checkChanging();
userBits &= ~ARCSWIPE;
}
/**
* Method to tell if instances of this PrimitiveNode are "arc-wipable" by when created.
* For display efficiency reasons, pins that have arcs connected to them should not bother being drawn.
* Therefore, pin prototypes have this state set, and when instances of the
* appropriate arc prototypes connect to instances of these pins, they stop being drawn.
* It is necessary for the arc prototype to enable wiping (with setWipable).
* A NodeInst that becomes wiped out has "setWiped" called.
* @return true if instances of this PrimitiveNode are "arc-wipable" by when created.
*/
public boolean isArcsWipe() {
return (userBits & ARCSWIPE) != 0;
}
/**
* Method to set this PrimitiveNode so that instances of it are "square".
* Square nodes must have the same X and Y size.
* This is useful for round components that really have only one dimension.
*/
public void setSquare() {
checkChanging();
userBits |= NSQUARE;
}
/**
* Method to set this PrimitiveNode so that instances of it are not "square".
* Square nodes must have the same X and Y size.
* This is useful for round components that really have only one dimension.
*/
public void clearSquare() {
checkChanging();
userBits &= ~NSQUARE;
}
/**
* Method to tell if instances of this PrimitiveNode are square.
* Square nodes must have the same X and Y size.
* This is useful for round components that really have only one dimension.
* @return true if instances of this PrimitiveNode are square.
*/
public boolean isSquare() {
return (userBits & NSQUARE) != 0;
}
/**
* Method to set this PrimitiveNode so that instances of it may hold outline information.
* Outline information is an array of coordinates that define the node.
* It can be as simple as an opened-polygon that connects the points,
* or a serpentine transistor that lays down polysilicon to follow the points.
*/
public void setHoldsOutline() {
checkChanging();
userBits |= HOLDSTRACE;
}
/**
* Method to set this PrimitiveNode so that instances of it may not hold outline information.
* Outline information is an array of coordinates that define the node.
* It can be as simple as an opened-polygon that connects the points,
* or a serpentine transistor that lays down polysilicon to follow the points.
*/
public void clearHoldsOutline() {
checkChanging();
userBits &= ~HOLDSTRACE;
}
/**
* Method to tell if instances of this PrimitiveNode can hold an outline.
* Outline information is an array of coordinates that define the node.
* It can be as simple as an opened-polygon that connects the points,
* or a serpentine transistor that lays down polysilicon to follow the points.
* @return true if instances of this PrimitiveNode can hold an outline.
*/
public boolean isHoldsOutline() {
return (userBits & HOLDSTRACE) != 0;
}
/**
* Method to set this PrimitiveNode so that it can be zero in size.
* The display system uses this to eliminate zero-size nodes that cannot be that way.
*/
public void setCanBeZeroSize() {
checkChanging();
userBits |= CANBEZEROSIZE;
}
/**
* Method to set this PrimitiveNode so that it cannot be zero in size.
* The display system uses this to eliminate zero-size nodes that cannot be that way.
*/
public void clearCanBeZeroSize() {
checkChanging();
userBits &= ~CANBEZEROSIZE;
}
/**
* Method to tell if instances of this PrimitiveNode can be zero in size.
* The display system uses this to eliminate zero-size nodes that cannot be that way.
* @return true if instances of this PrimitiveNode can be zero in size.
*/
public boolean isCanBeZeroSize() {
return (userBits & CANBEZEROSIZE) != 0;
}
/**
* Method to set this PrimitiveNode so that instances of it are wiped when 1 or 2 arcs connect.
* This is used in Schematics pins, which are not shown if 1 or 2 arcs connect, but are shown
* when standing alone, or when 3 or more arcs make a "T" or other connection to it.
*/
public void setWipeOn1or2() {
checkChanging();
userBits |= WIPEON1OR2;
}
/**
* Method to set this PrimitiveNode so that instances of it are not wiped when 1 or 2 arcs connect.
* Only Schematics pins enable this state.
*/
public void clearWipeOn1or2() {
checkChanging();
userBits &= ~WIPEON1OR2;
}
/**
* Method to tell if instances of this PrimitiveNode are wiped when 1 or 2 arcs connect.
* This is used in Schematics pins, which are not shown if 1 or 2 arcs connect, but are shown
* when standing alone, or when 3 or more arcs make a "T" or other connection to it.
* @return true if instances of this PrimitiveNode are wiped when 1 or 2 arcs connect.
*/
public boolean isWipeOn1or2() {
return (userBits & WIPEON1OR2) != 0;
}
/**
* Method to set this PrimitiveNode so that instances of it are locked.
* Locked Primitives cannot be created, deleted, or modified.
* Typically, array technologies (such as FPGA) have lockable primitives which are used for the fixed part of a design,
* and then locked to prevent the customization work from damaging the circuit.
*/
public void setLockedPrim() {
checkChanging();
userBits |= LOCKEDPRIM;
}
/**
* Method to set this PrimitiveNode so that instances of it are not locked.
* Locked Primitives cannot be created, deleted, or modified.
* Typically, array technologies (such as FPGA) have lockable primitives which are used for the fixed part of a design,
* and then locked to prevent the customization work from damaging the circuit.
*/
public void clearLockedPrim() {
checkChanging();
userBits &= ~LOCKEDPRIM;
}
/**
* Method to tell if instances of this PrimitiveNode are loced.
* Locked Primitives cannot be created, deleted, or modified.
* Typically, array technologies (such as FPGA) have lockable primitives which are used for the fixed part of a design,
* and then locked to prevent the customization work from damaging the circuit.
* @return true if instances of this PrimitiveNode are loced.
*/
public boolean isLockedPrim() {
return (userBits & LOCKEDPRIM) != 0;
}
/**
* Method to set this PrimitiveNode so that instances of it are selectable only by their edges.
* Artwork primitives that are not filled-in or are outlines want edge-selection, instead
* of allowing a click anywhere in the bounding box to work.
*/
public void setEdgeSelect() {
checkChanging();
userBits |= NEDGESELECT;
}
/**
* Method to set this PrimitiveNode so that instances of it are not selectable only by their edges.
* Artwork primitives that are not filled-in or are outlines want edge-selection, instead
* of allowing a click anywhere in the bounding box to work.
*/
public void clearEdgeSelect() {
checkChanging();
userBits &= ~NEDGESELECT;
}
/**
* Method to tell if instances of this PrimitiveNode are selectable on their edges.
* Artwork primitives that are not filled-in or are outlines want edge-selection, instead
* of allowing a click anywhere in the bounding box to work.
* @return true if instances of this PrimitiveNode are selectable on their edges.
*/
public boolean isEdgeSelect() {
return (userBits & NEDGESELECT) != 0;
}
/**
* Method to set this PrimitiveNode so that arcs connected to instances will shrink in nonmanhattan situations.
* This happens to pins where any combination of multiple arcs in angles that are not increments of 90 degrees
* will cause tabs to emerge at the connection site.
*/
public void setArcsShrink() {
checkChanging();
userBits |= ARCSHRINK;
}
/**
* Method to set this PrimitiveNode so that arcs connected to instances will not shrink in nonmanhattan situations.
* This happens to pins where any combination of multiple arcs in angles that are not increments of 90 degrees
* will cause tabs to emerge at the connection site.
*/
public void clearArcsShrink() {
checkChanging();
userBits &= ~ARCSHRINK;
}
/**
* Method to tell if instances of this PrimitiveNode cause arcs to shrink in nonmanhattan situations.
* This happens to pins where any combination of multiple arcs in angles that are not increments of 90 degrees
* will cause tabs to emerge at the connection site.
* @return true if instances of this PrimitiveNode cause arcs to shrink in nonmanhattan situations.
*/
public boolean isArcsShrink() {
return (userBits & ARCSHRINK) != 0;
}
/**
* Method to set this PrimitiveNode so that it is not used.
* Unused nodes do not appear in the component menus and cannot be created by the user.
* The state is useful for hiding primitives that the user should not use.
* @param set
*/
public void setNotUsed(boolean set) {
checkChanging();
if (set) {
userBits |= NNOTUSED;
} else {
userBits &= ~NNOTUSED; // clear
}
}
/**
* Method to tell if this PrimitiveNode is used.
* Unused nodes do not appear in the component menus and cannot be created by the user.
* The state is useful for hiding primitives that the user should not use.
* @return true if this PrimitiveNode is used.
*/
public boolean isNotUsed() {
return (userBits & NNOTUSED) != 0;
}
/**
* Method to determine if PrimitiveNode represents a well node
* @return true if this PrimitiveNode is a well node
*/
public boolean isPureWellNode() {
// Not even looking at
if (function != PrimitiveNode.Function.NODE) {
return false;
}
// only one layer
if (layers.length != 1) {
return false;
}
Layer layer = layers[0].getLayer();
return (layer.getFunction().isWell());
}
/**
* Method to determine if PrimitiveNode represents substrate node
* @return true if this PrimitiveNode is a substrate node
*/
public boolean isPureSubstrateNode() {
// Not even looking at
if (function != PrimitiveNode.Function.NODE) {
return false;
}
// only one layer
if (layers.length != 1) {
return false;
}
Layer layer = layers[0].getLayer();
return (layer.getFunction().isSubstrate());
}
/**
* Method to retrieve index of the node in the given technology.
* It must add the total number of layers to guarantee indexes don't collide with
* layer indices. This function MUST be in sync with
* The sequence of indices is: rules for single layers, rules for nodes, rules that
* involve more than 1 layers.
* @return the index of this node in its Technology.
*/
public final int getPrimNodeInddexInTech() {
return techPrimNodeIndex;
}
/**
* Method to set the index of this node in its Technology.
* @param index the index to use for this node in its Technology.
*/
public void setPrimNodeIndexInTech(int index) {
techPrimNodeIndex = index;
assert techPrimNodeIndex == protoId.chronIndex;
}
/**
* Compares PrimtiveNodes by their Technologies and definition order.
* @param that the other PrimitiveNode.
* @return a comparison between the PrimitiveNodes.
*/
@Override
public int compareTo(PrimitiveNode that) {
if (this.tech != that.tech) {
int cmp = this.tech.compareTo(that.tech);
if (cmp != 0) {
return cmp;
}
}
return this.techPrimNodeIndex - that.techPrimNodeIndex;
}
/**
* Returns a printable version of this PrimitiveNode.
* @return a printable version of this PrimitiveNode.
*/
@Override
public String toString() {
return "node " + describe(true);
}
private static final String[] nodeBits = {
"NODESHRINK", null, null,
"LOWVTBIT", "HIGHVTBIT", "NATIVEBIT",
"OD18BIT", "OD25BIT", "OD33BIT",
"ARCSWIPE", "NSQUARE", "HOLDSTRACE",
"CANBEZEROSIZE", "WIPEON1OR2", "LOCKEDPRIM",
"NEDGESELECT", "ARCSHRINK", "NINVISIBLE",
"SKIPSIZEINPALETTE", "NNOTUSED", null
};
protected void dump(PrintWriter out) {
out.print("PrimitiveNode " + getName() + " " + getFunction());
if (isNotUsed()) {
out.println(" NOTUSED");
return;
}
Technology.printlnBits(out, nodeBits, userBits);
out.print("\tspecialType=" + getSpecialType() + " numMultiCuts=" + numMultiCuts);
if (specialValues != null) {
for (double v : specialValues) {
out.print(" " + v);
}
}
out.println();
if (offset != null) {
out.println("\t" + offset);
}
out.println("\tfullRectangle=" + fullRectangle);
out.println("\tbaseRectangle=" + baseRectangle);
if (minNodeSize != null) {
out.println("\tminNodeSize w=" + minNodeSize.getWidth() + " h=" + minNodeSize.getHeight() + " rule=" + minNodeSize.getRuleName());
}
if (autoGrowth != null) {
out.println("\tautoGrowth " + autoGrowth);
}
Technology.printlnPref(out, 1, "DefaultExtendXFor" + getName() + "IN" + tech.getTechName(), factoryDefaultInst.size.getLambdaX() * 0.5);
Technology.printlnPref(out, 1, "DefaultExtendYFor" + getName() + "IN" + tech.getTechName(), factoryDefaultInst.size.getLambdaY() * 0.5);
for (int techVersion = 0; techVersion < 2; techVersion++) {
EPoint sizeCorrector = getSizeCorrector(techVersion);
String diskOffset = "diskOffset" + (techVersion + 1);
double x = sizeCorrector.getLambdaX();
double y = sizeCorrector.getLambdaY();
out.println("\t" + diskOffset + "=" + x + "," + y);
}
out.println("\tlayers:");
boolean isSerp = getSpecialType() == SERPTRANS;
dumpNodeLayers(out, layers, isSerp);
if (electricalLayers != null) {
out.println("\telectricalLayers:");
dumpNodeLayers(out, electricalLayers, isSerp);
}
for (PrimitivePort pp : primPorts) {
pp.dump(out);
}
}
protected void dumpNodeLayers(PrintWriter out, Technology.NodeLayer[] layers, boolean isSerp) {
EPoint correction = EPoint.fromGrid(fullRectangle.getGridWidth(), fullRectangle.getGridHeight());
for (Technology.NodeLayer nl : layers) {
nl.dump(out, correction, isSerp);
}
}
protected Xml.PrimitiveNodeGroup makeXml(Map
© 2015 - 2025 Weber Informatics LLC | Privacy Policy