📄 foldedmos.java
字号:
/* -*- tab-width: 4 -*- * * Electric(tm) VLSI Design System * * File: FoldedMos.java * * Copyright (c) 2003 Sun Microsystems and Static Free Software * * Electric(tm) is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * Electric(tm) is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Electric(tm); see the file COPYING. If not, write to * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, Mass 02111-1307, USA. */package com.sun.electric.tool.generator.layout;import java.awt.geom.Rectangle2D;import com.sun.electric.database.geometry.Poly;import com.sun.electric.database.hierarchy.Cell;import com.sun.electric.database.prototype.NodeProto;import com.sun.electric.database.topology.NodeInst;import com.sun.electric.database.topology.PortInst;import com.sun.electric.technology.ArcProto;import com.sun.electric.technology.PrimitiveNode;import com.sun.electric.tool.generator.layout.TechType.MosInst;/** * first cut at a folded transistor generator. Transistors are rotated 90 * degrees counter clockwise so that gates are vertical. * * FoldedMos is abstract. Instantiate FoldedNmos or FoldedPmos instead. */public abstract class FoldedMos { // -------------------------- public types ------------------------------- /** * Users use GateSpace objects to tell the FoldedMos constructors to leave * additional space between diffusion contacts and gates and between * adjacent gates. There are a total of nbFolds * (nbSeries-1) such spaces. * * <p> * The FoldedMos constructor builds FoldedMos transistors from left to * right. Just before it adds a new poly gate or a new diffusion contact * (except for the first diffusion contact) it calls GateSpace.getExtraSpace * to find out the amount of "extra space" it should leave between this new * object and the preceeding object. */ public interface GateSpace { /** * The getExtraSpace() method returns the desired amount of "extra * space" to leave between the specified objects. * * <p> * First, we define "extra space". The "normal" distance from the center * of a minimum sized diffusion contact and the center of a minimum * width transistor gate is 4 lambda. For this normal spacing we define * the "extra space" to be 0 lambda. However if the width of the * transistor is less than 5 lambda, then the distance between the * centers of the diffusion contact and the gate must be 4.5 lambda. In * that case we define the extra space to be .5 lambda. * * <p> * Similarly if the distance between the centers of two adjacent series * gates is 5 lambda then the "extraSpace" is 0 lambda. However if the * distance between the centers of two adjacent series gates is 6 lambda * then the "extra space" is 1 lambda. * * @param requiredExtraSpace * the extra space required by the design rules. Normally * this is 0 lambda. However, if the gate width is less than * 5 lambda, the requiredExtraSpace between the diffusion * contact and the gate is .5 lambda. * @param foldNdx * the index of this fold. This will range between 0 and * nbFolds-1 * @param nbFolds * the number of folds in this FoldedMos * @param spaceNdx * the index of this space within this fold. This will range * between 0 and nbGates. If spaceNdx==0 or spaceNdx==nbGates * then getSpace must return the distance between a diffusion * contact and a gate. Otherwise getSpace must return the * distance between gates spaceNdx-1 and spaceNdx. * @param nbGates * the total number of gates in this FoldedMos. * @return the desired extra space. Note that the returned extra space * must be greater than or equal to requiredExtraSpace to avoid * DRC errors. */ double getExtraSpace(double requiredExtraSpace, int foldNdx, int nbFolds, int spaceNdx, int nbGates); } // ---------------------------- private data -------------------------------- private static final GateSpace useMinSp= new GateSpace() { public double getExtraSpace(double requiredExtraSpace, int foldNdx, int nbFolds, int spaceNdx, int nbGates) { return requiredExtraSpace; } }; private PortInst[] diffVias; private MosInst[] moss; private PortInst[] internalDiffs; private double difContWid; private double gateWidth; private double physWidth; private double mosY; private TechType tech; // -------------------- protected and private methods --------------------- // after rotating 90 degrees counter clock wise private static void error(boolean pred, String msg) { LayoutLib.error(pred, msg); } private boolean isPmos() { return this instanceof FoldedPmos; } // This method is necessary to ensure that the edges of all // diffusion arcs are on the .5 lambda grid to avoid CIF resolution // errors. The method assumes that diff widths are integral and // attempts to position the ArcInst endpoints on a .5 lambda grid. // // The centers of ports may not be on .5 lambda grid for two // reasons. First, the x coordinates of the centers of diffusion // ports of a MOS transistor are ALWAYS off grid when the transistor // is on grid. Second, the y coordinate of the centers of diffusion // ports of a MOS transistor are off grid when the transistor width // is .5 plus an integer. // // The first problem requires the rounding of the x coordinate onto // the .5 lambda grid. The second problem is handled by using the y // coordinate of the contact. private void newDiffArc(ArcProto diff, double y, PortInst p1, PortInst p2) { double x1= tech.roundToGrid(LayoutLib.roundCenterX(p1)); double x2= tech.roundToGrid(LayoutLib.roundCenterX(p2)); NodeInst ni1= p1.getNodeInst(); NodeInst ni2= p2.getNodeInst(); Poly poly1= ni1.getShapeOfPort(p1.getPortProto()); Poly poly2= ni2.getShapeOfPort(p2.getPortProto()); // For CMOS90, Diff node's ports are always zero in size, so when // diff node and diffCon node are at different y positions, you // cannot always create a single arc. In CMOS90, as long as the arc is a // multiple // of 0.2 wide and the end points are at a grid multiple of 0.1, there // are no grid problems, so we can just use a track router if (!poly1.contains(x1, y) || !poly2.contains(x2, y)) { LayoutLib.newArcInst(diff, LayoutLib.DEF_SIZE, p1, p2); } else { LayoutLib .newArcInst(diff, LayoutLib.DEF_SIZE, p1, x1, y, p2, x2, y); } } // If necessary, add metal-1 to guarantee that metal-1 meets minimum area // requirements. private void addM1ForMinArea(PortInst diffContPort, double difContHei, char justify) { double diffOverM1 = (tech.getDiffContWidth()-tech.getDiffCont_m1Width())/2; double metalH = difContHei - diffOverM1*2; double metalW = tech.getDiffCont_m1Width(); double area = (metalH * metalW); if (area>=tech.getM1MinArea()) return; // Insufficient metal-1. Add some! Cell cell = diffContPort.getNodeInst().getParent(); // How high should m1 be? Round up to nearest .2 lambda. double reqH = tech.getM1MinArea() / metalW; reqH = Math.ceil(reqH / .2) * .2; double x = diffContPort.getCenter().getX(); double y = diffContPort.getCenter().getY(); if (justify=='T') { // align tops of metal-1 and diffusion contact double yHi = y + metalH/2 - metalW/2; PortInst piHi = LayoutLib.newNodeInst(tech.m1pin(), x, yHi, LayoutLib.DEF_SIZE, LayoutLib.DEF_SIZE, 0, cell).getOnlyPortInst(); LayoutLib.newArcInst(tech.m1(), metalW, diffContPort, piHi); double yLo = yHi - reqH + metalW; PortInst piLo = LayoutLib.newNodeInst(tech.m1pin(), x, yLo, LayoutLib.DEF_SIZE, LayoutLib.DEF_SIZE, 0, cell).getOnlyPortInst(); LayoutLib.newArcInst(tech.m1(), metalW, diffContPort, piLo); } else { // align bottoms of metal-1 and diffusion contact double yLo = y - metalH/2 + metalW/2; PortInst piLo = LayoutLib.newNodeInst(tech.m1pin(), x, yLo, LayoutLib.DEF_SIZE, LayoutLib.DEF_SIZE, 0, cell).getOnlyPortInst(); LayoutLib.newArcInst(tech.m1(), metalW, diffContPort, piLo); double yHi = y + reqH - metalW; PortInst piHi = LayoutLib.newNodeInst(tech.m1pin(), x, yHi, LayoutLib.DEF_SIZE, LayoutLib.DEF_SIZE, 0, cell).getOnlyPortInst(); LayoutLib.newArcInst(tech.m1(), metalW, diffContPort, piHi); } } /** * Construct a MOS transistor that has been folded to fit within a certain * height. The gates always vertical: no rotation is supported. * * <p> * Edge alignment to grid is a subtle issue. Limitations in the CIF format * require all edges to lie on the 0.5 lambda grid. The user of FoldedMos is * responsible for positioning the outer boundaries of the FoldedMos on * grid. To do this she must ensure that x is on grid, that gateWid is a * multiple of 0.5 lambda. Furthermore, if gateWid is less than the width of * a minimum-sized diffusion contact (5 lambda) then y must be on grid. If * gateWid is greater than the width of a minimum-sized diffusion contact * then (y - gateWid)/2) must be on grid. * * <p>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -