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

📄 connectivity.java

📁 The ElectricTM VLSI Design System is an open-source Electronic Design Automation (EDA) system that c
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
    private void addErrorLog(Cell cell, String msg, EPoint... pList)    {        List<EPoint> pointList = new ArrayList<EPoint>();        for(EPoint p : pList)            pointList.add(p);        errorLogger.logError(msg, null, null, null, pointList, null, cell, -1);        System.out.println(msg);    }    /**	 * Top-level method in extracting connectivity from a Cell.	 * A new version of the cell is created that has real nodes (transistors, contacts) and arcs.	 * This cell should have pure-layer nodes which will be converted.	 */	private Cell doExtract(Cell oldCell, boolean recursive, Pattern pat, boolean top, Job job,                           List<List<ERectangle>> addedBatchRectangles, List<List<ERectangle>> addedBatchLines, List<String> addedBatchNames)	{		if (recursive)		{			// first see if subcells need to be converted			for(Iterator<NodeInst> it = oldCell.getNodes(); it.hasNext(); )			{				NodeInst ni = it.next();				if (ni.isCellInstance())				{					Cell subCell = (Cell)ni.getProto();					// do not recurse if this subcell will be expanded					if (pat != null)					{						Matcher mat = pat.matcher(subCell.noLibDescribe());						if (mat.find()) continue;					}					Cell convertedCell = convertedCells.get(subCell);					if (convertedCell == null)					{						doExtract(subCell, recursive, pat, false, job, addedBatchRectangles, addedBatchLines, addedBatchNames);					}				}			}		}		// create the new version of the cell		String newCellName = oldCell.getName() + oldCell.getView().getAbbreviationExtension();		Cell newCell = Cell.makeInstance(oldCell.getLibrary(), newCellName);		if (newCell == null)		{			System.out.println("Cannot create new cell: " + newCellName);			return null;		}		convertedCells.put(oldCell, newCell);		// create a merge for the geometry in the cell		PolyMerge merge = new PolyMerge();		// convert the nodes		if (!startSection("Gathering geometry in " + oldCell + "..."))		// HAS PROGRESS IN IT            return null; // aborted        Set<Cell> expandedCells = new HashSet<Cell>();		exportsToRestore = new ArrayList<Export>();		pinsForLater = new ArrayList<ExportedPin>();		allCutLayers = new HashMap<Layer,List<PolyBase>>();		extractCell(oldCell, newCell, pat, expandedCells, merge, GenMath.MATID);		if (expandedCells.size() > 0)		{			System.out.print("These cells were expanded:");			for(Cell c : expandedCells)				System.out.print(" " + c.describe(false));			System.out.println();		}		// determine if this is a "P-well" or "N-well" process		findMissingWells(merge);		// now remember the original merge		PolyMerge originalMerge = new PolyMerge();		originalMerge.addMerge(merge, new AffineTransform());		// start by extracting vias		initDebugging();		if (!startSection("Extracting vias..."))             return null; // aborted        if (!extractVias(merge, originalMerge, newCell))            return null; // aborted        termDebugging(addedBatchRectangles, addedBatchLines, addedBatchNames, "Vias");		// now extract transistors		initDebugging();		if (!startSection("Extracting transistors..."))             return null; // aborted        extractTransistors(merge, originalMerge, newCell);		termDebugging(addedBatchRectangles, addedBatchLines, addedBatchNames, "Transistors");		// extend geometry that sticks out in space		initDebugging();		if (!startSection("Extracting extensions..."))             return null; // aborted        extendGeometry(merge, originalMerge, newCell, true);		termDebugging(addedBatchRectangles, addedBatchLines, addedBatchNames, "StickOuts");		// look for wires and pins		initDebugging();		if (!startSection("Extracting wires..."))             return null; // aborted        if (makeWires(merge, originalMerge, newCell)) return newCell;		termDebugging(addedBatchRectangles, addedBatchLines, addedBatchNames, "Wires");		// convert any geometry that connects two networks		initDebugging();		if (!startSection("Extracting connections..."))             return null; // aborted        extendGeometry(merge, originalMerge, newCell, false);		termDebugging(addedBatchRectangles, addedBatchLines, addedBatchNames, "Bridges");		// dump any remaining layers back in as extra pure layer nodes		initDebugging();		if (!startSection("Extracting leftover geometry..."))             return null; // aborted        convertAllGeometry(merge, originalMerge, newCell);		termDebugging(addedBatchRectangles, addedBatchLines, addedBatchNames, "Pures");		// reexport any that were there before		if (!startSection("Adding connecting wires..."))             return null; // aborted        restoreExports(oldCell, newCell);		// cleanup by auto-stitching		PolyMerge originalUnscaledMerge = new PolyMerge();		double shrinkage = 1.0 / SCALEFACTOR;		AffineTransform shrink = new AffineTransform(shrinkage, 0, 0, shrinkage, 0, 0);		originalUnscaledMerge.addMerge(originalMerge, shrink);		Set<ArcInst> allArcs = null;		if (DEBUGSTEPS)		{			allArcs = new HashSet<ArcInst>();			for(Iterator<ArcInst> it = newCell.getArcs(); it.hasNext(); )				allArcs.add(it.next());		}        AutoStitch.runAutoStitch(newCell, null, null, job, originalUnscaledMerge, null, false, true, true);		if (DEBUGSTEPS)		{			initDebugging();			for(Iterator<ArcInst> it = newCell.getArcs(); it.hasNext(); )			{				ArcInst ai = it.next();				if (allArcs.contains(ai)) continue;	            Poly arcPoly = ai.makeLambdaPoly(ai.getGridBaseWidth(), Poly.Type.CLOSED);				addedRectangles.add(ERectangle.fromLambda(arcPoly.getBounds2D()));			}			termDebugging(addedBatchRectangles, addedBatchLines, addedBatchNames, "Stitches");		}		System.out.println("Extraction done.");		return newCell;	}    /**     * Method to start a new connection section.     * @param msg message to display in progress window     * @return False if the job is scheduled for abort or was aborted     */    private boolean startSection(String msg)	{		System.out.println(msg);        if (job.checkAbort())            return false;        Job.getUserInterface().setProgressNote(msg);		Job.getUserInterface().setProgressValue(0);        return true;    }	private void initDebugging()	{		if (DEBUGSTEPS)		{			addedRectangles = new ArrayList<ERectangle>();			addedLines = new ArrayList<ERectangle>();		}	}	private void termDebugging(List<List<ERectangle>> addedBatchRectangles,		List<List<ERectangle>> addedBatchLines, List<String> addedBatchNames, String descr)	{		if (DEBUGSTEPS)		{			addedBatchRectangles.add(addedRectangles);			addedBatchLines.add(addedLines);			addedBatchNames.add(descr);		}	}	private static class ExportedPin	{		Point2D location;		NodeInst ni;		AffineTransform trans;		ExportedPin(NodeInst ni, Point2D location, AffineTransform trans)		{			this.ni = ni;			this.location = location;			this.trans = trans;		}	}	/**	 * Method to extract a cell's contents into the merge.	 * @param oldCell the cell being extracted.	 * @param newCell the new cell being created.	 * @param pat a pattern of subcell names that will be expanded.	 * @param expandedCells a set of cells that matched the pattern and were expanded.	 * @param merge the merge to be filled.	 * @param prevTrans the transformation coming into this cell.	 */	private void extractCell(Cell oldCell, Cell newCell, Pattern pat, Set<Cell> expandedCells, PolyMerge merge, AffineTransform prevTrans)	{		Map<NodeInst,NodeInst> newNodes = new HashMap<NodeInst,NodeInst>();		int totalNodes = oldCell.getNumNodes();		int soFar = 0;		for(Iterator<NodeInst> nIt = oldCell.getNodes(); nIt.hasNext(); )		{			NodeInst ni = nIt.next();			soFar++;			if ((soFar % 100) == 0) Job.getUserInterface().setProgressValue(soFar * 100 / totalNodes);			if (ni.getProto() == Generic.tech().cellCenterNode) continue;			// see if the node can be copied or must be extracted			NodeProto copyType = null;			if (ni.isCellInstance())			{				Cell subCell = (Cell)ni.getProto();				// if subcell is expanded, do it now				if (pat != null)				{					Matcher mat = pat.matcher(subCell.noLibDescribe());					if (mat.find())					{						// expanding the subcell						expandedCells.add(subCell);						AffineTransform subTrans = ni.translateOut(ni.rotateOut(prevTrans));						extractCell(subCell, newCell, pat, expandedCells, merge, subTrans);						continue;					}				}				// subcell not expanded, figure out what gets placed in the new cell				copyType = convertedCells.get(subCell);				if (copyType == null) copyType = subCell;			} else			{				PrimitiveNode np = (PrimitiveNode)ni.getProto();				// special case for exported but unconnected pins: save for later				if (np.getFunction() == PrimitiveNode.Function.PIN)				{					if (ni.hasExports() && !ni.hasConnections())					{						ExportedPin ep = new ExportedPin(ni, ni.getTrueCenter(), prevTrans);						pinsForLater.add(ep);						continue;					}				}				if (np.getFunction() != PrimitiveNode.Function.NODE) copyType = ni.getProto(); else				{					if (ignoreNodes.contains(np)) copyType = ni.getProto();				}			}			// copy it now if requested			if (copyType != null)			{				double sX = ni.getXSize();				double sY = ni.getYSize();				if (copyType instanceof Cell)				{					Rectangle2D cellBounds = ((Cell)copyType).getBounds();					sX = cellBounds.getWidth();					sY = cellBounds.getHeight();				}				Point2D instanceAnchor = new Point2D.Double(0, 0);				prevTrans.transform(ni.getAnchorCenter(), instanceAnchor);				NodeInst newNi = NodeInst.makeInstance(copyType, instanceAnchor, sX, sY,					newCell, ni.getOrient(), ni.getName(), ni.getTechSpecific());				if (newNi == null)				{                    addErrorLog(newCell, "Problem creating new instance of " + ni.getProto(), new EPoint(sX, sY));                    return;				}				newNodes.put(ni, newNi);				// copy exports too				for(Iterator<Export> it = ni.getExports(); it.hasNext(); )				{					Export e = it.next();					PortInst pi = newNi.findPortInstFromProto(e.getOriginalPort().getPortProto());					Export.newInstance(newCell, pi, e.getName());				}				continue;			}			// see if the size is at an odd coordinate (and may suffer rounding problems)			boolean growABit = false;			if (((int)(ni.getXSize() * DBMath.GRID) % 2) != 0 ||				((int)(ni.getYSize() * DBMath.GRID) % 2) != 0) growABit = true;			// extract the geometry from the pure-layer node			AffineTransform trans = ni.rotateOut(prevTrans);			Poly [] polys = tech.getShapeOfNode(ni);			for(int j=0; j<polys.length; j++)			{				Poly poly = polys[j];				// get the layer for the geometry				Layer layer = poly.getLayer();				if (layer == null) continue;				// make sure the geometric database is made up of proper layers				layer = geometricLayer(layer);				// finally add the geometry to the merge				poly.transform(trans);				Point2D [] points = poly.getPoints();				if (Extract.isGridAlignExtraction())				{					Point2D hold = new Point2D.Double();					for(int i=0; i<points.length; i++)					{						hold.setLocation(points[i]);						Job.getUserInterface().alignToGrid(hold);						poly.setPoint(i, hold.getX(), hold.getY());					}				} else				{					// grow the polygon to account for rounding problems					if (growABit)					{						double growth = DBMath.getEpsilon()/2;						Point2D polyCtr = poly.getCenter();						for(int i=0; i<points.length; i++)						{							double x = points[i].getX();							double y = points[i].getY();							if (x < polyCtr.getX()) x -= growth; else x += growth;							if (y < polyCtr.getY()) y -= growth; else y += growth;							poly.setPoint(i, x, y);						}					}				}				for(int i=0; i<points.length; i++)					poly.setPoint(i, scaleUp(points[i].getX()), scaleUp(points[i].getY()));				if (layer.getFunction().isContact())				{					// cut layers are stored in lists because merging them is too expensive and pointless					List<PolyBase> cutsOnLayer = allCutLayers.get(layer);					if (cutsOnLayer == null)

⌨️ 快捷键说明

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