📄 fillgeneratortool.java
字号:
/* -*- tab-width: 4 -*- * * Electric(tm) VLSI Design System * * File: FillGeneratorTool.java * * Copyright (c) 2006 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.fill;import java.lang.reflect.Constructor;import java.util.ArrayList;import java.util.HashMap;import java.util.Iterator;import java.util.LinkedList;import java.util.List;import com.sun.electric.database.geometry.EPoint;import com.sun.electric.database.hierarchy.Cell;import com.sun.electric.database.hierarchy.Library;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.technology.ArcProto;import com.sun.electric.technology.PrimitiveNode;import com.sun.electric.tool.Job;import com.sun.electric.tool.Tool;import com.sun.electric.tool.generator.layout.Gallery;import com.sun.electric.tool.generator.layout.LayoutLib;import com.sun.electric.tool.generator.layout.Tech;import com.sun.electric.tool.generator.layout.TechType;abstract class MetalFloorplanBase extends Floorplan{ /** width Vdd wires */ public double vddWidth; /** width Gnd wires */ public double gndWidth; MetalFloorplanBase(double cellWidth, double cellHeight, boolean horiz) { super(cellWidth, cellHeight, horiz); vddWidth = gndWidth = 0; }}// ------------------------------ MetalFloorplanFlex ------------------------------// Similar to Metalfloor but number of power/gnd lines is determined by cell sizeclass MetalFloorplanFlex extends MetalFloorplanBase { public final double minWidth, space, vddReserve, gndReserve; MetalFloorplanFlex(double cellWidth, double cellHeight, double vddReserve, double gndReserve, double space, double vddW, double gndW, boolean horiz) { super(cellWidth, cellHeight, horiz); this.vddWidth = vddW; //27; this.gndWidth = gndW; //20; this.space = space; this.vddReserve = vddReserve; this.gndReserve = gndReserve; minWidth = vddReserve + gndReserve + 2*space + 2*gndWidth + 2*vddWidth; }}// ------------------------------ MetalFloorplan ------------------------------// Floor plan://// half of Gnd reserved// gggggggggggggggggggg// wide space// vvvvvvvvvvvvvvvvvvvv// Vdd reserved// vvvvvvvvvvvvvvvvvvvv// wide space// gggggggggggggggggggg// half of Gnd reservedclass MetalFloorplan extends MetalFloorplanBase { /** no gap between Vdd wires */ public final boolean mergedVdd; /** if horizontal then y coordinate of top Vdd wire * if vertical then x coordinate of right Vdd wire */ public final double vddCenter; /** if horizontal then y coordinate of top Gnd wire * if vertical then x coordinate of right Gnd wire */ public final double gndCenter; public final double coverage; private double roundDownOneLambda(double x) { return Math.floor(x); } // Round metal widths down to multiples of 1 lambda resolution. // Then metal center can be on 1/2 lambda grid without problems. MetalFloorplan(double cellWidth, double cellHeight, double vddReserve, double gndReserve, double space, boolean horiz) { super(cellWidth, cellHeight, horiz); mergedVdd = vddReserve==0; double cellSpace = horiz ? cellHeight : cellWidth; double metalSpace = cellSpace - 2*space - vddReserve - gndReserve; // gnd is always in two pieces gndWidth = roundDownOneLambda(metalSpace / 4); gndCenter = cellSpace/2 - gndReserve/2 - gndWidth/2; // vdd may be one or two pieces if (mergedVdd) { vddWidth = gndWidth*2; vddCenter = 0; } else { vddWidth = gndWidth; vddCenter = vddReserve/2 + vddWidth/2; } // compute coverage statistics double cellArea = cellWidth * cellHeight; double strapLength = horiz ? cellWidth : cellHeight; double vddArea = (mergedVdd ? 1 : 2) * vddWidth * strapLength; double gndArea = 2 * gndWidth * strapLength; coverage = (vddArea + gndArea)/cellArea; }// Save this code in case I need to replicate LoCo FillCell exactly// MetalFloorplan(double cellWidth, double cellHeight,// double vddReserve, double gndReserve,// double space, boolean horiz) {// super(cellWidth, cellHeight, horiz);// mergedVdd = vddReserve==0;// double cellSpace = horiz ? cellHeight : cellWidth;// if (mergedVdd) {// double w = cellSpace/2 - space - vddReserve;// vddWidth = roundDownOneLambda(w);// vddCenter = 0;// } else {// double w = (cellSpace/2 - space - vddReserve) / 2;// vddWidth = roundDownOneLambda(w);// vddCenter = vddReserve/2 + vddWidth/2;// }// double vddEdge = vddCenter + vddWidth/2;// double w = cellSpace/2 - vddEdge - space - gndReserve/2;// gndWidth = roundDownOneLambda(w);// gndCenter = vddEdge + space + gndWidth/2;//// // compute coverage statistics// double cellArea = cellWidth * cellHeight;// double strapLength = horiz ? cellWidth : cellHeight;// double vddArea = (mergedVdd ? 1 : 2) * vddWidth * strapLength;// double gndArea = 2 * gndWidth * strapLength;// coverage = (vddArea + gndArea)/cellArea;// }}// ------------------------------- ExportBars ---------------------------------class ExportBar{ PortInst[] ports = null; Double center = null; ExportBar(PortInst p1, PortInst p2, double c) { ports = new PortInst[2]; ports[0] = p1; ports[1] = p2; center = (c); // autoboxing }}class MetalLayer implements VddGndStraps { protected final MetalFloorplanBase plan; protected final int layerNum; protected final PrimitiveNode pin; protected final ArcProto metal; protected ArrayList<ExportBar> vddBars = new ArrayList<ExportBar>(); protected ArrayList<ExportBar> gndBars = new ArrayList<ExportBar>(); public boolean addExtraArc() { return true; } private void buildGnd(Cell cell) { double pinX, pinY; MetalFloorplan plan = (MetalFloorplan)this.plan; if (plan.horizontal) { pinX = plan.cellWidth/2; // - plan.gndWidth/2; pinY = plan.gndCenter; } else { pinX = plan.gndCenter; pinY = plan.cellHeight/2; // - plan.gndWidth/2; } PortInst tl = LayoutLib.newNodeInst(pin, -pinX, pinY, G.DEF_SIZE, G.DEF_SIZE, 0, cell ).getOnlyPortInst(); PortInst tr = LayoutLib.newNodeInst(pin, pinX, pinY, G.DEF_SIZE, G.DEF_SIZE, 0, cell ).getOnlyPortInst(); PortInst bl = LayoutLib.newNodeInst(pin, -pinX, -pinY, G.DEF_SIZE, G.DEF_SIZE, 0, cell ).getOnlyPortInst(); PortInst br = LayoutLib.newNodeInst(pin, pinX, -pinY, G.DEF_SIZE, G.DEF_SIZE, 0, cell ).getOnlyPortInst(); if (plan.horizontal) { G.noExtendArc(metal, plan.gndWidth, tl, tr); G.noExtendArc(metal, plan.gndWidth, bl, br); gndBars.add(new ExportBar(bl, br, -plan.gndCenter)); gndBars.add(new ExportBar(tl, tr, plan.gndCenter)); } else { G.noExtendArc(metal, plan.gndWidth, bl, tl); G.noExtendArc(metal, plan.gndWidth, br, tr); gndBars.add(new ExportBar(bl, tl, -plan.gndCenter)); gndBars.add(new ExportBar(br, tr, plan.gndCenter)); } } private void buildVdd(Cell cell) { double pinX, pinY; MetalFloorplan plan = (MetalFloorplan)this.plan; if (plan.horizontal) { pinX = plan.cellWidth/2; // - plan.vddWidth/2; pinY = plan.vddCenter; } else { pinX = plan.vddCenter; pinY = plan.cellHeight/2; // - plan.vddWidth/2; } if (plan.mergedVdd) { PortInst tr = LayoutLib.newNodeInst(pin, pinX, pinY, G.DEF_SIZE, G.DEF_SIZE, 0, cell ).getOnlyPortInst(); PortInst bl = LayoutLib.newNodeInst(pin, -pinX, -pinY, G.DEF_SIZE, G.DEF_SIZE, 0, cell ).getOnlyPortInst(); G.noExtendArc(metal, plan.vddWidth, bl, tr); vddBars.add(new ExportBar(bl, tr, plan.vddCenter)); } else { PortInst tl = LayoutLib.newNodeInst(pin, -pinX, pinY, G.DEF_SIZE, G.DEF_SIZE, 0, cell ).getOnlyPortInst(); PortInst tr = LayoutLib.newNodeInst(pin, pinX, pinY, G.DEF_SIZE, G.DEF_SIZE, 0, cell ).getOnlyPortInst(); PortInst bl = LayoutLib.newNodeInst(pin, -pinX, -pinY, G.DEF_SIZE, G.DEF_SIZE, 0, cell ).getOnlyPortInst(); PortInst br = LayoutLib.newNodeInst(pin, pinX, -pinY, G.DEF_SIZE, G.DEF_SIZE, 0, cell ).getOnlyPortInst(); if (plan.horizontal) { G.noExtendArc(metal, plan.vddWidth, tl, tr); G.noExtendArc(metal, plan.vddWidth, bl, br); vddBars.add(new ExportBar(bl, br, -plan.vddCenter)); vddBars.add(new ExportBar(tl, tr, plan.vddCenter)); } else { G.noExtendArc(metal, plan.vddWidth, bl, tl); G.noExtendArc(metal, plan.vddWidth, br, tr); vddBars.add(new ExportBar(bl, tl, -plan.vddCenter)); vddBars.add(new ExportBar(br, tr, plan.vddCenter)); } } } /** It has to be protected to be overwritten by sub classes */ protected void buildGndAndVdd(Cell cell) { buildGnd(cell); buildVdd(cell); } public MetalLayer(int layerNum, Floorplan plan, Cell cell) { this.plan = (MetalFloorplanBase)plan; this.layerNum = layerNum; metal = METALS[layerNum];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -