📄 edif.java
字号:
value = getToken((char)0); if (value == null) throw new IOException("Illegal number value"); if (!value.equalsIgnoreCase("e")) throw new IOException("Illegal number value"); // now the matissa value = getToken((char)0); if (value == null) throw new IOException("No matissa value"); double matissa = TextUtils.atof(value); // now the exponent value = getToken((char)0); if (value == null) throw new IOException("No exponent value"); double exponent = TextUtils.atof(value); getDelimeter(')'); return matissa * Math.pow(10.0, exponent); } return TextUtils.atof(value); } private NodeInst placePin(NodeProto np, double cX, double cY, double sX, double sY, Orientation orient, Cell parent) { for(Iterator<NodeInst> it = parent.getNodes(); it.hasNext(); ) { NodeInst ni = it.next(); if (ni.getProto() != np) continue; if (!ni.getOrient().equals(orient)) continue; if (ni.getAnchorCenterX() != cX) continue; if (ni.getAnchorCenterY() != cY) continue; return ni; } NodeInst ni = NodeInst.makeInstance(np, new Point2D.Double(cX, cY), sX, sY, parent, orient, null, 0); return ni; } /** * Method to return the text height to use when it says "textheight" units in the EDIF file. */ private double convertTextSize(double textHeight) { double i = textHeight / 4; if (i <= 0) i = 0.5; return i; } private void makeArc(double [] x, double [] y) { GenMath.MutableDouble [] A = new GenMath.MutableDouble[2]; GenMath.MutableDouble [] B = new GenMath.MutableDouble[2]; GenMath.MutableDouble [] C = new GenMath.MutableDouble[2]; for(int i=0; i<2; i++) { A[i] = new GenMath.MutableDouble(0); B[i] = new GenMath.MutableDouble(0); C[i] = new GenMath.MutableDouble(0); } // get line equations of perpendicular bi-sectors of p1 to p2 double px1 = (x[0] + x[1]) / 2.0; double py1 = (y[0] + y[1]) / 2.0; // now rotate end point 90 degrees double px0 = px1 - (y[0] - py1); double py0 = py1 + (x[0] - px1); equationOfALine(px0, py0, px1, py1, A[0], B[0], C[0]); // get line equations of perpendicular bi-sectors of p2 to p3 px1 = (x[2] + x[1]) / 2.0; py1 = (y[2] + y[1]) / 2.0; // now rotate end point 90 degrees double px2 = px1 - (y[2] - py1); double py2 = py1 + (x[2] - px1); equationOfALine(px1, py1, px2, py2, A[1], B[1], C[1]); // determine the point of intersection Point2D ctr = determineIntersection(A, B, C); double ixc = ctr.getX(); double iyc = ctr.getY(); double dx = ixc - x[0]; double dy = iyc - y[0]; double r = Math.hypot(dx, dy); // now calculate the angle to the start and endpoint dx = x[0] - ixc; dy = y[0] - iyc; if (dx == 0.0 && dy == 0.0) { System.out.println("Domain error doing arc computation"); return; } double a0 = Math.atan2(dy, dx) * 1800.0 / Math.PI; if (a0 < 0.0) a0 += 3600.0; dx = x[2] - ixc; dy = y[2] - iyc; if (dx == 0.0 && dy == 0.0) { System.out.println("Domain error doing arc computation"); return; } double a2 = Math.atan2(dy, dx) * 1800.0 / Math.PI; if (a2 < 0.0) a2 += 3600.0; // determine the angle of rotation, object orientation, and direction // calculate x1*y2 + x2*y3 + x3*y1 - y1*x2 - y2*x3 - y3*x1 double area = x[0]*y[1] + x[1]*y[2] + x[2]*y[0] - y[0]*x[1] - y[1]*x[2] - y[2]*x[0]; double ar = 0, so = 0; int rot = 0; boolean trans = false; if (area > 0.0) { // counter clockwise if (a2 < a0) a2 += 3600.0; ar = a2 - a0; rot = (int)a0; so = (a0 - rot) * Math.PI / 1800.0; } else { // clockwise if (a0 > 2700) { rot = 3600 - (int)a0 + 2700; so = ((3600.0 - a0 + 2700.0) - rot) * Math.PI / 1800.0; } else { rot = 2700 - (int)a0; so = ((2700.0 - a0) - rot) * Math.PI / 1800.0; } if (a0 < a2) a0 += 3600; ar = a0 - a2; trans = true; } // get the bounds of the circle double sX = r*2; double sY = r*2; Orientation or = Orientation.fromC(rot, trans); if (curCellPage > 0) iyc += (curCellPage-1) * Cell.FrameDescription.MULTIPAGESEPARATION; NodeInst ni = NodeInst.makeInstance(curFigureGroup != null && curFigureGroup != Artwork.tech().boxNode ? curFigureGroup : Artwork.tech().circleNode, new Point2D.Double(ixc, iyc), sX, sY, curCell, or, null, 0); if (ni == null) { System.out.println("Error, line " + lineReader.getLineNumber() + ": could not create arc"); errorCount++; } else { // store the angle of the arc ni.setArcDegrees(so, ar*Math.PI/1800.0); } } private Export makeExport(Cell cell, PortInst pi, String name, PortCharacteristic pc) { Export ppt = Export.newInstance(cell, pi, convertParens(name), pc); return ppt; } private String convertParens(String name) { return name.replace('(', '[').replace(')', ']'); } /** * Method to determine the intersection of two lines * Inputs: Ax + By + C = 0 form * Outputs: x, y - the point of intersection * returns 1 if found, 0 if non-intersecting */ private Point2D determineIntersection(GenMath.MutableDouble [] A, GenMath.MutableDouble [] B, GenMath.MutableDouble [] C) { // check for parallel lines double A1B2 = A[0].doubleValue() * B[1].doubleValue(); double A2B1 = A[1].doubleValue() * B[0].doubleValue(); if (A1B2 == A2B1) { // check for coincident lines if (C[0].doubleValue() == C[1].doubleValue()) return null; return null; } double A1C2 = A[0].doubleValue() * C[1].doubleValue(); double A2C1 = A[1].doubleValue() * C[0].doubleValue(); if (A[0].doubleValue() != 0) { double Y = (A2C1 - A1C2) / (A1B2 - A2B1); double X = -(B[0].doubleValue() * Y + C[0].doubleValue()) / A[0].doubleValue(); return new Point2D.Double(X, Y); } double Y = (A1C2 - A2C1) / (A2B1 - A1B2); double X = -(B[1].doubleValue() * Y + C[1].doubleValue()) / A[1].doubleValue(); return new Point2D.Double(X, Y); } /** * Method to calculate the equation of a line (Ax + By + C = 0) * Inputs: sx, sy - Start point * ex, ey - End point * px, py - Point line should pass through * Outputs: A, B, C - constants for the line */ private void equationOfALine(double sx, double sy, double ex, double ey, GenMath.MutableDouble A, GenMath.MutableDouble B, GenMath.MutableDouble C) { if (sx == ex) { A.setValue(1.0); B.setValue(0.0); C.setValue(-ex); } else if (sy == ey) { A.setValue(0.0); B.setValue(1.0); C.setValue(-ey); } else { // let B = 1 then B.setValue(1.0); if (sx != 0.0) { // Ax1 + y1 + C = 0 => A = -(C + y1) / x1 // C = -Ax2 - y2 => C = (Cx2 + y1x2) / x1 - y2 => Cx1 - Cx2 = y1x2 - y2x1 // C = (y2x1 - y1x2) / (x2 - x1) C.setValue((ey * sx - sy * ex) / (ex - sx)); A.setValue(-(C.doubleValue() + sy) / sx); } else { C.setValue((sy * ex - ey * sx) / (sx - ex)); A.setValue(-(C.doubleValue() + ey) / ex); } } } private void nameEDIFArc(ArcInst ai, boolean forceBus) { if (isArray) { // name the bus if (netReference.length() > 0) { ai.newVar("EDIF_name", netReference); } StringBuffer aName = new StringBuffer(); if (netName.indexOf('[') >= 0) { // the name is already indexed: break it apart and reindex it int xMost = arrayXVal, yMost = arrayYVal; if (yMost > xMost) { xMost = arrayYVal; yMost = arrayXVal; } for (int iX = 0; iX < xMost; iX++) { for (int iY = 0; iY < yMost; iY++) { if (aName.length() > 0) aName.append(','); aName.append(getMemberName(netName, iX, iY)); } } } else { if (forceBus) { // a typical foreign array bus will have some range value appended // to the name. This will cause some odd names with duplicate values for (int iX = 0; iX < arrayXVal; iX++) { for (int iY = 0; iY < arrayYVal; iY++) { if (aName.length() > 0) aName.append(','); if (arrayXVal > 1) { if (arrayYVal > 1) aName.append(netName + "[" + iX + "," + iY + "]"); else aName.append(netName + "[" + iX + "]"); } else aName.append(netName + "[" + iY + "]"); } } } else { aName.append(netName); } } putNameOnArcOnce(ai, convertParens(aName.toString())); } else { if (netReference.length() > 0) { ai.newVar("EDIF_name", netName); } if (netName.length() > 0) { // set name of arc but don't display name putNameOnArcOnce(ai, convertParens(netName)); } } } private void putNameOnArcOnce(ArcInst ai, String name) { if (namedArcs != null) { Map<String,List<ArcInst>> cellArcNames = namedArcs.get(curCell); if (cellArcNames == null) { cellArcNames = new HashMap<String,List<ArcInst>>(); namedArcs.put(curCell, cellArcNames); } List<ArcInst> arcsWithName = cellArcNames.get(name); if (arcsWithName == null) { arcsWithName = new ArrayList<ArcInst>(); cellArcNames.put(name, arcsWithName); } arcsWithName.add(ai); } } /** * Method to locate the nodeinstance and portproto corresponding to * to a direct intersection with the given point. * inputs: * cell - cell to search * x, y - the point to exam * ap - the arc used to connect port (must match pp) */ private List<PortInst> findEDIFPort(Cell cell, double x, double y, ArcProto ap) { List<PortInst> ports = new ArrayList<PortInst>(); PortInst bestPi = null; Point2D pt = new Point2D.Double(x, y); double bestDist = Double.MAX_VALUE; ArcInst ai = null; for(Iterator<RTBounds> sea = cell.searchIterator(new Rectangle2D.Double(x, y, 0, 0)); sea.hasNext(); ) { RTBounds geom = sea.next(); if (geom instanceof NodeInst) { // now locate a portproto NodeInst ni = (NodeInst)geom; if (offpageNodes != null && offpageNodes.contains(ni)) continue; for(Iterator<PortInst> it = ni.getPortInsts(); it.hasNext(); ) { PortInst pi = it.next(); Poly poly = pi.getPoly(); if (poly.isInside(pt)) { // check if port connects to arc ...*/ if (pi.getPortProto().getBasePort().connectsTo(ap)) ports.add(pi); } else { double dist = pt.distance(new Point2D.Double(poly.getCenterX(), poly.getCenterY())); if (bestPi == null || dist < bestDist) { bestDist = dist; bestPi = pi; } } } } else { // only accept valid wires ArcInst oAi = (ArcInst)geom; if (oAi.getProto().getTechnology() == Schematics.tech()) { // make sure the point is really on the arc if (GenMath.distToLine(oAi.getHeadLocation(), oAi.getTailLocation(), pt) == 0) ai = oAi; } } } if (ports.size() == 0 && ai != null) { // direct hit on an arc, verify connection ArcProto nAp = ai.getProto(); PrimitiveNode np = nAp.findPinProto(); if (np == null) return ports; PortProto pp = np.getPort(0); if (!pp.getBasePort().connectsTo(ap)) return ports; // try to split arc (from us_getnodeonarcinst)*/ // break is at (prefx, prefy): save information about the arcinst PortInst fPi = ai.getHeadPortInst(); Point2D fPt = ai.getHeadLocation(); PortInst tPi = ai.getTailPortInst(); Point2D tPt = ai.getTailLocation(); // create the splitting pin NodeInst ni = placePin(np, x, y, np.getDefWidth(), np.getDefHeight(), Orientation.IDENT, cell); if (ni == null) { System.out.println("Cannot create splitting pin"); return ports; } // set the node, and port PortInst pi = ni.findPortInstFromProto(pp); ports.add(pi); // create the two new arcinsts ArcInst ar1 = ArcInst.makeInstance(nAp, fPi, pi, fPt, pt, null); ArcInst ar2 = ArcInst.makeInstance(nAp, pi, tPi, pt, tPt, null); if (ar1 == null || ar2 == null) { System.out.println("Error creating the split arc parts"); return ports; } ar1.copyPropertiesFrom(ai); if (ai.isHeadNegated()) ar1.setHeadNegated(true); if (ai.isTailNegated()) ar2.setTailNegated(true); // delete the old arcinst ai.kill(); } return ports; } private void checkBusNames(ArcInst ai, String base, HashSet<ArcInst> seenArcs) { if (ai.getProto() != Schematics.tech().bus_arc) { // verify the name String aName = ai.getName(); { if (aName.startsWith(base)) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -