⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 abstractshapebuilder.java

📁 The ElectricTM VLSI Design System is an open-source Electronic Design Automation (EDA) system that c
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
        long pureGridRadius = Math.abs(gridRadius);        double gridLength = a.getGridLength();                // see if the lambdaRadius can work with these arc ends        if (pureGridRadius*2 < gridLength) return false;                // determine the center of the circle        Point2D [] centers = DBMath.findCenters(pureGridRadius, a.headLocation.gridMutable(), a.tailLocation.gridMutable());        if (centers == null) return false;                Point2D centerPt = centers[1];        if (gridRadius < 0) {            centerPt = centers[0];        }        double centerX = centerPt.getX();        double centerY = centerPt.getY();                // determine the base and range of angles        int angleBase = DBMath.figureAngle(a.headLocation.getGridX() - centerX, a.headLocation.getGridY() - centerY);        int angleRange = DBMath.figureAngle(a.tailLocation.getGridX() - centerX, a.tailLocation.getGridY() - centerY);        angleRange -= angleBase;        if (angleRange < 0) angleRange += 3600;                // force the curvature to be the smaller part of a circle (used to determine this by the reverse-ends bit)        if (angleRange > 1800) {            angleBase += angleRange;            if (angleBase < 0) angleBase += 3600;            angleRange = 3600 - angleRange;        }                // determine the number of intervals to use for the arc        int pieces = angleRange;        while (pieces > MAXARCPIECES) pieces /= 2;        if (pieces == 0) return false;                // get the inner and outer radii of the arc        double outerRadius = pureGridRadius + gridWidth / 2;        double innerRadius = outerRadius - gridWidth;                // fill the polygon        for(int i=0; i<=pieces; i++) {            int angle = (angleBase + i * angleRange / pieces) % 3600;            pushPoint(DBMath.cos(angle) * innerRadius + centerX, DBMath.sin(angle) * innerRadius + centerY);        }        for(int i=pieces; i>=0; i--) {            int angle = (angleBase + i * angleRange / pieces) % 3600;            pushPoint(DBMath.cos(angle) * outerRadius + centerX, DBMath.sin(angle) * outerRadius + centerY);        }        return true;    }        /**     * Generate shape of this ImmutableArcInst in easy case.     * @param a the arc information.     * @return true if shape was generated.     */    public boolean genShapeEasy(ImmutableArcInst a) {        if (m.isHardArc(a.arcId)) return false;        ArcProto protoType = techPool.getArcProto(a.protoId);        int gridExtendOverMin = (int)a.getGridExtendOverMin();        int minLayerExtend = gridExtendOverMin + protoType.getMinLayerGridExtend();         if (minLayerExtend == 0) {            assert protoType.getNumArcLayers() == 1;            Technology.ArcLayer primLayer = protoType.getArcLayer(0);            Layer layer = primLayer.getLayer();            if (onlyTheseLayers != null && !onlyTheseLayers.contains(layer.getFunction(), layer.getFunctionExtras())) return true;            Poly.Type style = primLayer.getStyle();            if (style == Poly.Type.FILLED) style = Poly.Type.OPENED;            intCoords[0] = (int)a.tailLocation.getGridX();            intCoords[1] = (int)a.tailLocation.getGridY();            intCoords[2] = (int)a.headLocation.getGridX();            intCoords[3] = (int)a.headLocation.getGridY();            addIntLine(intCoords, style, primLayer.getLayer());            return true;        }        boolean tailExtended = false;        if (a.isTailExtended()) {            short shrinkT = shrinkage.get(a.tailNodeId);            if (shrinkT == Shrinkage.EXTEND_90)                tailExtended = true;            else if (shrinkT != Shrinkage.EXTEND_0)                return false;        }        boolean headExtended = false;        if (a.isHeadExtended()) {            short shrinkH = shrinkage.get(a.headNodeId);            if (shrinkH == Shrinkage.EXTEND_90)                headExtended = true;            else if (shrinkH != Shrinkage.EXTEND_0)                return false;        }        for (int i = 0, n = protoType.getNumArcLayers(); i < n; i++) {            Technology.ArcLayer primLayer = protoType.getArcLayer(i);            Layer layer = primLayer.getLayer();            assert primLayer.getStyle() == Poly.Type.FILLED;            if (onlyTheseLayers != null && !onlyTheseLayers.contains(layer.getFunction(), layer.getFunctionExtras())) continue;            a.makeGridBoxInt(intCoords, tailExtended, headExtended, gridExtendOverMin + protoType.getLayerGridExtend(i));            addIntBox(intCoords, layer);        }        return true;    }        public void pushPoint(EPoint p, double gridX, double gridY) {        pushPointLow(p.getGridX() + DBMath.roundShapeCoord(gridX), p.getGridY() + DBMath.roundShapeCoord(gridY));    }        public void pushPoint(double gridX, double gridY) {        pushPointLow(DBMath.roundShapeCoord(gridX), DBMath.roundShapeCoord(gridY));    }        public void pushPoint(EPoint p) {        pushPointLow(p.getGridX(), p.getGridY());    }        private void pushPointLow(double gridX, double gridY) {        if (pointCount*2 >= doubleCoords.length)            resize();        doubleCoords[pointCount*2] = gridX;        doubleCoords[pointCount*2 + 1] = gridY;        pointCount++;    }        private void resize() {        double[] newDoubleCoords = new double[doubleCoords.length*2];        System.arraycopy(doubleCoords, 0, newDoubleCoords, 0, doubleCoords.length);        doubleCoords = newDoubleCoords;    }        public void pushPoly(Poly.Type style, Layer layer) {        addDoublePoly(pointCount, style, layer);        pointCount = 0;    }        public void pushBox(int minX, int minY, int maxX, int maxY, Layer layer) {        intCoords[0] = minX;        intCoords[1] = minY;        intCoords[2] = maxX;        intCoords[3] = maxY;        addIntBox(intCoords, layer);    }        public abstract void addDoublePoly(int numPoints, Poly.Type style, Layer layer);        public abstract void addIntLine(int[] coords, Poly.Type style, Layer layer);    public abstract void addIntBox(int[] coords, Layer layer);        public static class Shrinkage {        public static final short EXTEND_90 = 0;        public static final short EXTEND_0 = 1;        private static final short EXTEND_ANY = 2;            private static final int ANGLE_SHIFT = 12;        private static final int ANGLE_MASK = (1 << ANGLE_SHIFT) - 1;        private static final int ANGLE_DIAGONAL_MASK = 1 << (ANGLE_SHIFT*2);        private static final int ANGLE_COUNT_SHIFT = ANGLE_SHIFT*2 + 1;                private final short[] shrink;                public Shrinkage() {            shrink = new short[0];        }                public Shrinkage(CellBackup cellBackup) {            CellRevision cellRevision = cellBackup.cellRevision;            TechPool techPool = cellBackup.techPool;            int maxNodeId = -1;            for (int nodeIndex = 0; nodeIndex < cellRevision.nodes.size(); nodeIndex++)                maxNodeId = Math.max(maxNodeId, cellRevision.nodes.get(nodeIndex).nodeId);            int[] angles = new int[maxNodeId+1];            for (ImmutableArcInst a: cellRevision.arcs) {                ArcProto ap = techPool.getArcProto(a.protoId);                if (a.getGridExtendOverMin() + ap.getMaxLayerGridExtend() == 0) continue;                if (a.tailNodeId == a.headNodeId && a.tailPortId == a.headPortId) {                    // Fake register for full shrinkage                    registerArcEnd(angles, a.tailNodeId, 0, false, false);                    continue;                }                boolean is90 = a.isManhattan();                registerArcEnd(angles, a.tailNodeId, a.getOppositeAngle(), is90, a.isTailExtended());                registerArcEnd(angles, a.headNodeId, a.getAngle(), is90, a.isHeadExtended());            }            short[] shrink = new short[maxNodeId + 1];            for (int nodeIndex = 0; nodeIndex < cellRevision.nodes.size(); nodeIndex++) {                ImmutableNodeInst n = cellRevision.nodes.get(nodeIndex);                NodeProtoId np = n.protoId;                if (np instanceof PrimitiveNodeId && techPool.getPrimitiveNode((PrimitiveNodeId)np).isArcsShrink())                    shrink[n.nodeId] = computeShrink(angles[n.nodeId]);            }            this.shrink = shrink;        }                /**         * Method to tell the "end shrink" factors on all arcs on a specified ImmutableNodeInst.         * EXTEND_90 indicates no shortening (extend the arc by half its width).         * EXTEND_0 indicates no extend.         * EXTEND_ANY + [0..3600) is a sum of arc angles modulo 3600         * if this ImmutableNodeInst is a pin which can "isArcsShrink" and this pin connects         * exactly two arcs whit extended ends and angle between arcs is accute.         * @param nodeId nodeId of specified ImmutableNodeInst         * @return shrink factor of specified ImmutableNodeInst is wiped.         */        public short get(int nodeId) {            return nodeId < shrink.length ? shrink[nodeId] : 0;        }            private void registerArcEnd(int[] angles, int nodeId, int angle, boolean is90, boolean extended) {        assert angle >= 0 && angle < 3600;        int ang = angles[nodeId];        if (extended) {            int count = ang >>> ANGLE_COUNT_SHIFT;            switch (count) {                case 0:                    ang |= angle;                    ang += (1 << ANGLE_COUNT_SHIFT);                    break;                case 1:                    ang |= (angle << ANGLE_SHIFT);                    ang += (1 << ANGLE_COUNT_SHIFT);                    break;                case 2:                    ang += (1 << ANGLE_COUNT_SHIFT);                    break;            }            if (!is90)                ang |= ANGLE_DIAGONAL_MASK;        } else {            ang |= (3 << ANGLE_COUNT_SHIFT);        }        angles[nodeId] = ang;    }        static short computeShrink(int angs) {        boolean hasAny = (angs&ANGLE_DIAGONAL_MASK) != 0;        int count = angs >>> ANGLE_COUNT_SHIFT;                if (hasAny && count == 2) {            int ang0 = angs & ANGLE_MASK;            int ang1 = (angs >> ANGLE_SHIFT) & ANGLE_MASK;            int da = ang0 > ang1 ? ang0 - ang1 : ang1 - ang0;            if (da == 900 || da == 2700) return EXTEND_90;            if (da == 1800) return EXTEND_0;            if (900 < da && da < 2700) {                int a = ang0 + ang1;                if (a >= 3600)                    a -= 3600;                return (short)(EXTEND_ANY + a);            }        }        return EXTEND_90;    }            }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -