📄 fillgeneratortool.java
字号:
pin = PINS[layerNum]; buildGndAndVdd(cell); } public boolean isHorizontal() {return plan.horizontal;} public int numVdd() {return vddBars.size();} public double getVddCenter(int n) { return (vddBars.get(n).center); // autoboxing } public PortInst getVdd(int n, int pos) {return vddBars.get(n).ports[pos];} public double getVddWidth(int n) {return plan.vddWidth;} public int numGnd() {return gndBars.size();} public double getGndCenter(int n) { return (gndBars.get(n).center); // autoboxing } public PortInst getGnd(int n, int pos) {return gndBars.get(n).ports[pos];} public double getGndWidth(int n) {return (plan).gndWidth;} public PrimitiveNode getPinType() {return pin;} public ArcProto getMetalType() {return metal;} public double getCellWidth() {return plan.cellWidth;} public double getCellHeight() {return plan.cellHeight;} public int getLayerNumber() {return layerNum;}}// ------------------------------- MetalLayerFlex -----------------------------class MetalLayerFlex extends MetalLayer { public MetalLayerFlex(int layerNum, Floorplan plan, Cell cell) { super(layerNum, plan, cell); } public boolean addExtraArc() { return false; } // For automatic fill generator no extra arcs are wanted. protected void buildGndAndVdd(Cell cell) { double pinX, pinY; double limit = 0; MetalFloorplanFlex plan = (MetalFloorplanFlex)this.plan; if (plan.horizontal) { limit = plan.cellHeight/2; } else { limit = plan.cellWidth/2; } double position = 0; int i = 0; while (position < limit) { boolean even = (i%2==0); double maxDelta = 0, pos = 0; if (even) { maxDelta = plan.vddReserve/2 + plan.vddWidth; pos = plan.vddReserve/2 + plan.vddWidth/2 + position; } else { maxDelta = plan.gndReserve/2 + plan.gndWidth; pos = plan.gndReserve/2 + plan.gndWidth/2 + position; } if (position + maxDelta > limit) return; // border was reached if (plan.horizontal) { pinY = pos; pinX = plan.cellWidth/2; } else { pinX = pos; pinY = plan.cellHeight/2; } // Vdd if even, gnd if odd if (!even) addBars(cell, pinX, pinY, plan.gndWidth, gndBars); else addBars(cell, pinX, pinY, plan.vddWidth, vddBars); if (even) { maxDelta = plan.vddReserve/2 + plan.vddWidth + plan.space + plan.gndWidth; pos = plan.vddReserve/2 + plan.vddWidth + plan.space + plan.gndWidth/2 + position; } else { maxDelta = plan.gndReserve/2 + plan.gndWidth + plan.space + plan.vddWidth; pos = plan.gndReserve/2 + plan.gndWidth + plan.space + plan.vddWidth/2 + position; } if (position + maxDelta > limit) return; // border was reached if (plan.horizontal) pinY = pos; else pinX = pos; // Gnd if even, vdd if odd if (!even) { addBars(cell, pinX, pinY, plan.vddWidth, vddBars); position = ((plan.horizontal)?pinY:pinX) + plan.vddWidth/2 + plan.vddReserve/2; } else { addBars(cell, pinX, pinY, plan.gndWidth, gndBars); position = ((plan.horizontal)?pinY:pinX) + plan.gndWidth/2 + plan.gndReserve/2; } i++; } } private void addBars(Cell cell, double pinX, double pinY, double width, ArrayList<ExportBar> bars) { 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(); double center = 0; if (plan.horizontal) { G.noExtendArc(metal, width, tl, tr); G.noExtendArc(metal, width, bl, br); center = pinY; bars.add(new ExportBar(bl, br, -center)); bars.add(new ExportBar(tl, tr, center)); } else { G.noExtendArc(metal, width, bl, tl); G.noExtendArc(metal, width, br, tr); center = pinX; bars.add(new ExportBar(bl, tl, -center)); bars.add(new ExportBar(br, tr, center)); } }}//---------------------------------- CapLayer ---------------------------------class CapLayer implements VddGndStraps { private CapCell capCell; private NodeInst capCellInst; private CapFloorplan plan; public boolean addExtraArc() { return true; } public CapLayer(CapFloorplan plan, CapCell capCell, Cell cell) { this.plan = plan; this.capCell = capCell; double angle = plan.horizontal ? 0 : 90; if (capCell != null) capCellInst = LayoutLib.newNodeInst(capCell.getCell(), 0, 0, G.DEF_SIZE, G.DEF_SIZE, angle, cell); } public boolean isHorizontal() {return plan.horizontal;} public int numVdd() {return (capCell != null) ? capCell.numVdd() : 0;} public PortInst getVdd(int n, int pos) { return capCellInst.findPortInst(FillCell.VDD_NAME+"_"+n); } public double getVddCenter(int n) { EPoint center = getVdd(n, 0).getCenter(); return plan.horizontal ? center.getY() : center.getX(); } public double getVddWidth(int n) {return capCell.getVddWidth();} public int numGnd() {return capCell.numGnd();} public PortInst getGnd(int n, int pos) { return capCellInst.findPortInst(FillCell.GND_NAME+"_"+n); } public double getGndCenter(int n) { EPoint center = getGnd(n, 0).getCenter(); return plan.horizontal ? center.getY() : center.getX(); } public double getGndWidth(int n) {return capCell.getGndWidth();} public PrimitiveNode getPinType() {return Tech.m1pin();} public ArcProto getMetalType() {return Tech.m1();} public double getCellWidth() {return plan.cellWidth;} public double getCellHeight() {return plan.cellHeight;} public int getLayerNumber() {return 1;}}class FillRouter { private HashMap<String,List<PortInst>> portMap = new HashMap<String,List<PortInst>>(); private String makeKey(PortInst pi) { EPoint center = pi.getCenter(); String x = ""+center.getX(); // LayoutLib.roundCenterX(pi); String y = ""+center.getY(); // LayoutLib.roundCenterY(pi); return x+"x"+y; }// private boolean bothConnect(ArcProto a, PortProto pp1, PortProto pp2) {// return pp1.connectsTo(a) && pp2.connectsTo(a);// } private ArcProto findCommonArc(PortInst p1, PortInst p2) { ArcProto[] metals = {Tech.m6(), Tech.m5(), Tech.m4(), Tech.m3(), Tech.m2(), Tech.m1()}; PortProto pp1 = p1.getPortProto(); PortProto pp2 = p2.getPortProto(); for (int i=0; i<metals.length; i++) { if (pp1.connectsTo(metals[i]) && pp2.connectsTo(metals[i])) { return metals[i]; } } return null; } private void connectPorts(List<PortInst> ports) { for (Iterator<PortInst> it=ports.iterator(); it.hasNext(); ) { PortInst first = it.next(); double width = LayoutLib.widestWireWidth(first); it.remove(); for (PortInst pi : ports) { ArcProto a = findCommonArc(first, pi); if (a!=null) LayoutLib.newArcInst(a, width, first, pi); } } } private FillRouter(ArrayList<PortInst> ports) { for (PortInst pi : ports) { String key = makeKey(pi); List<PortInst> l = portMap.get(key); if (l==null) { l = new LinkedList<PortInst>(); portMap.put(key, l); } l.add(pi); } for (String str : portMap.keySet()) { connectPorts(portMap.get(str)); } } public static void connectCoincident(ArrayList<PortInst> ports) { new FillRouter(ports); }}/** * Object for building fill libraries */public class FillGeneratorTool extends Tool { public FillGenConfig config; protected Library lib; private boolean libInitialized; public List<Cell> masters; protected CapCell capCell; protected Floorplan[] plans; /** the fill generator tool. */ private static FillGeneratorTool tool = getTool(); // Depending on generator plugin available public static FillGeneratorTool getTool() { if (tool != null) return tool; FillGeneratorTool tool; try { Class<?> extraClass = Class.forName("com.sun.electric.plugins.generator.FillCellTool"); Constructor instance = extraClass.getDeclaredConstructor(); // varags Object obj = instance.newInstance(); // varargs; tool = (FillGeneratorTool)obj; } catch (Exception e) { if (Job.getDebug()) System.out.println("GNU Release can't find Fill Cell Generator plugin"); tool = new FillGeneratorTool(); } return tool; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -