/* -*- tab-width: 4 -*-
*
* Electric(tm) VLSI Design System
*
* File: DrcRing.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.tool.generator.layout.gates;
import com.sun.electric.database.EditingPreferences;
import java.awt.geom.Rectangle2D;
import com.sun.electric.database.hierarchy.Cell;
import com.sun.electric.database.prototype.NodeProto;
import com.sun.electric.database.topology.PortInst;
import com.sun.electric.technology.ArcProto;
import com.sun.electric.technology.Technology;
import com.sun.electric.tool.generator.layout.LayoutLib;
import com.sun.electric.tool.generator.layout.StdCellParams;
import com.sun.electric.tool.generator.layout.TechType;
import com.sun.electric.util.math.DBMath;
/** Create a ring in layers p1 and m1 - m5. This ring is useful for
* testing DRC correctness of my gate libraries. I will draw a ring
* around every gate and then run DRC. */
public class DrcRing {
// private static void error(boolean pred, String msg) {
// LayoutLib.error(pred, msg);
// }
/** Draw a rectangular ring from arc. The space inside the ring has
* width w and height h. Position the ring so that the bottom left
* inside corner is at (0, 0). All edges are on a 0.5 lambda grid
* as long as w and h are multiples of 0.5 lambda. */
private static void drawRing(ArcProto arc, double w, double h, Cell f) {
if (arc == null) {
return;
}
// metal-5 minimum width is 6 lambda
double arcW = 6;
EditingPreferences ep = f.getEditingPreferences();
NodeProto pin = arc.findOverridablePinProto(ep);
double pinLoX = - arcW/2;
double pinHiX = w + arcW/2;
double pinLoY = - arcW/2;
double pinHiY = h + arcW/2;
/*
double pinLoX = -w/2 - arcW/2;
double pinHiX = w/2 + arcW/2;
double pinLoY = -h/2 - arcW/2;
double pinHiY = h/2 + arcW/2;
*/
double defSz = LayoutLib.DEF_SIZE;
PortInst blPort = LayoutLib.newNodeInst(pin, pinLoX, pinLoY, defSz, defSz,
0, f).getOnlyPortInst();
PortInst brPort = LayoutLib.newNodeInst(pin, pinHiX, pinLoY, defSz, defSz,
0, f).getOnlyPortInst();
PortInst tlPort = LayoutLib.newNodeInst(pin, pinLoX, pinHiY, defSz, defSz,
0, f).getOnlyPortInst();
PortInst trPort = LayoutLib.newNodeInst(pin, pinHiX, pinHiY, defSz, defSz,
0, f).getOnlyPortInst();
LayoutLib.newArcInst(arc, arcW, blPort, brPort);
LayoutLib.newArcInst(arc, arcW, tlPort, trPort);
LayoutLib.newArcInst(arc, arcW, blPort, tlPort);
LayoutLib.newArcInst(arc, arcW, brPort, trPort);
}
private static void drawRing(NodeProto np, double w, double h, double thickness, Cell f, char half, double pwellRatio) {
double arcW = thickness;
double pinLoX = -arcW;
double pinHiX = w;
double pinLoY = 0;
double pinHiY = h;
double lrHeight = h;
if (half == 'T') {
pinLoY = DBMath.round(h*pwellRatio);
lrHeight = DBMath.round(h*pwellRatio);
}
if (half == 'B') {
pinHiY = DBMath.round(h*(1-pwellRatio));
lrHeight = DBMath.round(h*(1-pwellRatio));
}
Rectangle2D left = new Rectangle2D.Double(pinLoX, pinLoY, arcW, lrHeight);
Rectangle2D right = new Rectangle2D.Double(pinHiX, pinLoY, arcW, lrHeight);
Rectangle2D top = new Rectangle2D.Double(pinLoX, pinHiY, w + 2*arcW, arcW);
Rectangle2D bottom = new Rectangle2D.Double(pinLoX, pinLoY - arcW, w + 2*arcW, arcW);
LayoutLib.roundBounds(left);
LayoutLib.roundBounds(right);
LayoutLib.roundBounds(top);
LayoutLib.roundBounds(bottom);
LayoutLib.newNodeInst(np, left.getCenterX(), left.getCenterY(), left.getWidth(), left.getHeight(), 0, f);
LayoutLib.newNodeInst(np, right.getCenterX(), right.getCenterY(), right.getWidth(), right.getHeight(), 0, f);
if (half != 'B')
LayoutLib.newNodeInst(np, top.getCenterX(), top.getCenterY(), top.getWidth(), top.getHeight(), 0, f);
if (half != 'T')
LayoutLib.newNodeInst(np, bottom.getCenterX(), bottom.getCenterY(), bottom.getWidth(), bottom.getHeight(), 0, f);
}
/** Draw rings with inside width w and inside height h. The ring
* position places the bottom left inside corner at (0, 0) */
public static Cell makePart(double w, double h, StdCellParams stdCell) {
TechType tech = stdCell.getTechType();
String nm = "drcRing_W"+w+"_H"+h+"{lay}";
Cell ring = stdCell.findPart(nm);
if (ring!=null) return ring;
ring = stdCell.newPart(nm);
boolean is90nm = ring.getTechnology() == Technology.getCMOS90Technology();
if (is90nm) {
// if (Tech.is90nm()) {
// ignore poly, but put in select rings
double pwellRatio = stdCell.getPmosWellHeight()/(stdCell.getNmosWellHeight()+stdCell.getPmosWellHeight());
drawRing(tech.pselNode(), w, h, 4.8, ring, 'B', pwellRatio);
drawRing(tech.nselNode(), w, h, 4.8, ring, 'T', pwellRatio);
} else {
drawRing(tech.p1(), w, h, ring);
}
drawRing(tech.m1(), w, h, ring);
drawRing(tech.m2(), w, h, ring);
drawRing(tech.m3(), w, h, ring);
drawRing(tech.m4(), w, h, ring);
drawRing(tech.m5(), w, h, ring);
return ring;
}
}