📄 stdcellparams.java
字号:
/* -*- tab-width: 4 -*- * * Electric(tm) VLSI Design System * * File: StdCellParams.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 java.util.ArrayList;import java.util.HashMap;import java.util.Iterator;import com.sun.electric.database.geometry.DBMath;import com.sun.electric.database.geometry.Poly;import com.sun.electric.database.hierarchy.Cell;import com.sun.electric.database.hierarchy.Export;import com.sun.electric.database.hierarchy.Library;import com.sun.electric.database.prototype.NodeProto;import com.sun.electric.database.prototype.PortCharacteristic;import com.sun.electric.database.prototype.PortProto;import com.sun.electric.database.topology.NodeInst;import com.sun.electric.database.topology.PortInst;import com.sun.electric.database.variable.VarContext;import com.sun.electric.database.variable.Variable;import com.sun.electric.technology.ArcProto;import com.sun.electric.technology.Layer;import com.sun.electric.technology.SizeOffset;import com.sun.electric.technology.Technology;import com.sun.electric.tool.ncc.Ncc;import com.sun.electric.tool.ncc.NccOptions;import com.sun.electric.tool.ncc.result.NccResults;/** The bottom of the PMOS well and the top of the NMOS well are at * y=0. PMOS tracks are numbered from 1 to nbPmosTracks(). These * numbers correspond to the lowest and highest, respectively, * unblocked tracks in the PMOS region. NMOS tracks are numbered from * -1 to -nbNmosTracks(). These numbers correspond to the highest and * lowest, respectively, unblocked tracks in the NMOS region. */public class StdCellParams { // ---------------------- private classes -------------------------------- private static class TrackBlockages { private static class Blockage { double bot, top; Blockage(double center, double width) { bot = center - width / 2; top = center + width / 2; } } private ArrayList<Blockage> blockages = new ArrayList<Blockage>(); private double space; TrackBlockages(double s) { this.space = s; } void addBlockage(double center, double width) { blockages.add(new Blockage(center, width)); } boolean isBlocked(double center, double width) { double top = center + width / 2 + space; double bot = center + width / 2 - space; for (int i = 0; i < blockages.size(); i++) { Blockage b = blockages.get(i); if (b.bot < top && b.top > bot) return true; } return false; } } private static void error(boolean pred, String msg) { LayoutLib.error(pred, msg); } // -------------------------- private data --------------------------------- private static final double DEF_SIZE = LayoutLib.DEF_SIZE; private static final Variable.Key ATTR_X = Variable.newKey("ATTR_X"); private static final Variable.Key ATTR_S = Variable.newKey("ATTR_S"); private static final Variable.Key ATTR_SN = Variable.newKey("ATTR_SN"); private static final Variable.Key ATTR_SP = Variable.newKey("ATTR_SP"); // =============================================================== /* These variable's initial values are Technology dependent */ private double nmosWellHeight; private double pmosWellHeight; private double gndY; private double vddY; private double gndWidth; private double vddWidth; private double trackPitch; private double trackWidth; private double m1TrackWidth; private double m2TrackWidth; private double metalSpace; private double pmosTrackOffset; private double nmosTrackOffset; // An "enable" style Nand gate has a weak pullup. This is how much // weaker than normal the PMOS is. private double enableGateStrengthRatio; // Separate well ties from power and ground to allow threshold // control via substrate bias. private boolean separateWellTies; // maximum distance from well tie to any point in well private double maxWellTieRadius;// private String pmosWellTieName = "vnw";// private String nmosWellTieName = "vsb"; private double nmosWellTieY, pmosWellTieY; private double minGateWid; private double maxMosWidth; private double gridResolution; private double drcRingSpace; // for well contacts private double wellConSelectHeight; // height of select layer around well tap private double wellConSelectOffset; // offset of select from anchor point // ====================================================== // Critera for reducing the number of distict sizes. // Default to 10% error. private double sizeErr = 0.1; private static final double selectOverhangsDiffCont = 4.5; private static final double m1OverhangsDiffCont = 2; private static final double m1Space = 3; private ArrayList<Double> nmosTracks = new ArrayList<Double>(); private ArrayList<Double> pmosTracks = new ArrayList<Double>();// private int botNmosTrack, topNmosTrack, botPmosTrack, topPmosTrack; private Library schemLib = null; private Library layoutLib = null; private boolean doubleStrapGate = false; private boolean exhaustivePlace = true; private int nbPlacerPerms = 40000; private boolean simpleName = false; private String vddExportName = "vdd"; private String gndExportName = "gnd"; private PortCharacteristic vddExportRole = PortCharacteristic.PWR; private PortCharacteristic gndExportRole = PortCharacteristic.GND; private TechType tech; // ------------------------ private methods ----------------------------- private void initMoCMOS() { nmosWellHeight = 70; pmosWellHeight = 70; gndY = -21.0; vddY = 21.0; gndWidth = 10; vddWidth = 10; trackPitch = 7; trackWidth = 4; m1TrackWidth = 4; m2TrackWidth = 4; metalSpace = 3; pmosTrackOffset = trackPitch / 2; nmosTrackOffset = -trackPitch / 2; // An "enable" style Nand gate has a weak pullup. This is how much // weaker than normal the PMOS is. enableGateStrengthRatio = .1; // Separate well ties from power and ground to allow threshold // control via substrate bias. separateWellTies = false; // maximum distance from well tie to any point in well maxWellTieRadius = 300;// pmosWellTieName = "vnw";// nmosWellTieName = "vsb"; nmosWellTieY = 0; pmosWellTieY = 0; minGateWid = 3; maxMosWidth = 45; gridResolution = 0.5; drcRingSpace = 3; wellConSelectHeight = 9; wellConSelectOffset = 0; } private void initCMOS90() { nmosWellHeight = 84; pmosWellHeight = 84; gndY = -24.5; vddY = 24.5; gndWidth = 9; vddWidth = 9; trackPitch = 7; trackWidth = 3.4; m1TrackWidth = 3.4; m2TrackWidth = 2.8; metalSpace = 2.4; pmosTrackOffset = 7; nmosTrackOffset = -77; // An "enable" style Nand gate has a weak pullup. This is how much // weaker than normal the PMOS is. enableGateStrengthRatio = .1; // Separate well ties from power and ground to allow threshold // control via substrate bias. separateWellTies = false; // maximum distance from well tie to any point in well maxWellTieRadius = 300;// pmosWellTieName = "vnw";// nmosWellTieName = "vsb"; nmosWellTieY = 0; pmosWellTieY = 0; minGateWid = 5.2; maxMosWidth = 45; gridResolution = 0.1; drcRingSpace = 0; wellConSelectHeight = 8.4; wellConSelectOffset = 0; } /** Initialize Tracks after setting up parameters */ private void init() { TrackBlockages blockages = new TrackBlockages(metalSpace); // The symmetric nand2 and nand3 reserve 2 metal-2 tracks for // internal use only to connect the output. blockages.addBlockage(11, 4); blockages.addBlockage(-11, 4); // Power and ground also block metal-2 tracks blockages.addBlockage(vddY, vddWidth); blockages.addBlockage(gndY, gndWidth); generateTracks(blockages); nmosWellTieY = gndY; pmosWellTieY = vddY; if (separateWellTies) { // Place well ties close to top and bottom of cells nmosWellTieY = getTrackY(- (nbNmosTracks() - 1)); blockages.addBlockage(nmosWellTieY, trackWidth); pmosWellTieY = getTrackY(nbPmosTracks() - 1); blockages.addBlockage(pmosWellTieY, trackWidth); // recompute available tracks with new blockages generateTracks(blockages); } } private boolean is90nm() { return tech.getEnum()==TechType.TechTypeEnum.CMOS90; } // create a list of tracks that don't overlap vdd or gnd private void generateTracks(TrackBlockages blockages) { // this may be called multiple times if setSeparateWellTies is called // 0 is an illegal index nmosTracks.clear(); pmosTracks.clear(); // tracks in PMOS region for (double y = pmosTrackOffset; y < pmosWellHeight; y += trackPitch) { if (!blockages.isBlocked(y, trackWidth)) pmosTracks.add(new Double(y)); } // tracks in NMOS region for (double y = nmosTrackOffset; y > -nmosWellHeight; y -= trackPitch) { if (!blockages.isBlocked(y, trackWidth)) nmosTracks.add(new Double(y)); } } private double quantizeMantissa(double mantissa) { double szRatio = (1 + sizeErr) / (1 - sizeErr); // find n such that (szRatio^n) is closest to mantissa double logBaseSzRatio = Math.log(mantissa) / Math.log(szRatio); double floorN = Math.floor(logBaseSzRatio); double ceilN = Math.ceil(logBaseSzRatio); double hiApprox = Math.pow(szRatio, ceilN); double loApprox = Math.pow(szRatio, floorN); return (hiApprox - mantissa < mantissa - loApprox) ? (hiApprox) : (loApprox); } private int calcNbGroups(double maxAvailWid, double totWid, int groupSz) { int nbGroups = (int) Math.ceil(totWid / maxAvailWid / groupSz); // If groupSz is even then we always create an even number of // fingers and we don't have to add more fingers to reduce // diffusion capacitance. if (groupSz % 2 == 0) return nbGroups; // If nbGroups is even then we always create an even number of // fingers and we don't have to add more fingers to reduce // diffusion capacitance if (nbGroups % 2 == 0) return nbGroups; // if totWid is less than maxAvailWid and groupSz is 1, just // use 1 gate (no fingers) if ((totWid < maxAvailWid) && (groupSz == 1)) return 1; // try adding one more group to get an even number of fingers int roundupGroups = nbGroups + 1; double wid = totWid / groupSz / roundupGroups; // Don't fold if gate width is less than width of diffusion // contact. if (wid >= tech.getDiffContWidth()) nbGroups = roundupGroups; return nbGroups; } private void fillDiffAndSelectNotch(PortInst prevPort, PortInst thisPort, FoldedMos mosLeft, FoldedMos mosRight, boolean fillDiffNotch) { double diffWid = mosLeft.getPhysWidth(); Cell f = mosLeft.getSrcDrn(0).getNodeInst().getParent();// PrimitiveNode diffCont =// mosLeft instanceof FoldedPmos ? tech.pdm1 : tech.ndm1; ArcProto diffArc = mosLeft instanceof FoldedPmos ? tech.pdiff() : tech.ndiff();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -