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

📄 ercantenna.java

📁 The ElectricTM VLSI Design System is an open-source Electronic Design Automation (EDA) system that c
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
								trans.concatenate(tTrans);								AffineTransform rTrans = ao.hierstack[i].rotateOut();								trans.concatenate(rTrans);							}								Technology tech = ai.getProto().getTechnology();							if (tech != curTech) continue;							Poly [] polyList = tech.getShapeOfArc(ai);							for(int i=0; i<polyList.length; i++)							{								Poly poly = polyList[i];								if (poly.getLayer() != lay) continue;								if (vmerge == null)									vmerge = new PolyMerge();								poly.transform(trans);								vmerge.addPolygon(poly.getLayer(), poly);							}						}					}					if (vmerge != null)					{						// get the area of the antenna						double totalRegionPerimeterArea = 0.0;                        for (Layer oLay : vmerge.getKeySet())						{							double thickness = oLay.getThickness();							if (thickness == 0)							{								if (oLay.getFunction().isMetal()) thickness = DEFMETALTHICKNESS; else									if (oLay.getFunction().isPoly()) thickness = DEFPOLYTHICKNESS;							}							List<PolyBase> merges = vmerge.getMergedPoints(oLay, true);							for(PolyBase merged : merges)							{								totalRegionPerimeterArea += merged.getPerimeter() * thickness;							}						}						// see if it is an antenna violation						double ratio = totalRegionPerimeterArea / totalGateArea;						double neededratio = getAntennaRatio(lay);						if (ratio > worstRatio) worstRatio = ratio;						if (ratio >= neededratio)						{							// error							String errMsg = "layer " + lay.getName() + " has perimeter-area " + totalRegionPerimeterArea +								"; gates have area " + totalGateArea + ", ratio is " + ratio + " but limit is " + neededratio;							List<PolyBase> polyList = new ArrayList<PolyBase>();                            for (Layer oLay : vmerge.getKeySet())							{								List<PolyBase> merges = vmerge.getMergedPoints(oLay, true);								for(PolyBase merged : merges)								{									polyList.add(merged);								}							}							errorLogger.logError(errMsg, null, null, null, null, polyList, cell, 0);						}					}				}			}		}			// now look at subcells		fsCell.add(cell);		for(Iterator<NodeInst> it = cell.getNodes(); it.hasNext(); )		{			NodeInst ni = it.next();			if (!ni.isCellInstance()) continue;			Cell subCell = (Cell)ni.getProto();			if (fsCell.contains(subCell)) continue;				if (checkThisCell(subCell, lay, job)) return true;		}		return false;	}		/**	 * Method to follow a node around the cell.	 * @param ni the NodeInst to follow.	 * @param pp the PortProto on the NodeInst.	 * @param lay the layer to consider.	 * @param trans a transformation to the top-level.	 * @return ERCANTPATHNULL if it found no gate or active on the path.	 * Returns ERCANTPATHGATE if it found gates on the path.	 * Returns ERCANTPATHACTIVE if it found active on the path.	 */	private int followNode(NodeInst ni, PortProto pp, Layer lay, AffineTransform trans, Job job)	{		// presume that nothing was found		int ret = ERCANTPATHNULL;		firstSpreadAntennaObj = new ArrayList<AntennaObject>();		NodeInst [] antstack = new NodeInst[200];		int depth = 0;			// keep walking along the nodes and arcs		for(;;)		{			if (job.checkAbort()) return ERCABORTED;			// if this is a subcell, recurse on it			fsGeom.add(ni);			NodeInst thisni = ni;			while (thisni.isCellInstance())			{				antstack[depth] = thisni;				depth++;				thisni = ((Export)pp).getOriginalPort().getNodeInst();				pp = ((Export)pp).getOriginalPort().getPortProto();			}				// see if we hit a transistor			boolean seen = false;			if (thisni.getFunction().isFET())			{				// stop tracing				if (thisni.getTransistorDrainPort().getPortProto() == pp ||					thisni.getTransistorSourcePort().getPortProto() == pp)				{					// touching the diffusion side of the transistor					return ERCANTPATHACTIVE;				}				// touching the gate side of the transistor				TransistorSize dim = thisni.getTransistorSize(VarContext.globalContext);				totalGateArea += dim.getDoubleLength() * dim.getDoubleWidth();				ret = ERCANTPATHGATE;			} else			{				// normal primitive: propagate				if (hasDiffusion(thisni)) return ERCANTPATHACTIVE;				AntennaObject ao = new AntennaObject(ni);					if (haveAntennaObject(ao))				{					// already in the list: free this object					seen = true;				} else				{					// not in the list: add it					ao.loadAntennaObject(antstack, depth);					addAntennaObject(ao);				}			}				// look at all arcs on the node			if (!seen)			{				int found = findArcs(thisni, pp, lay, depth, antstack);				if (found == ERCANTPATHACTIVE) return found;				if (depth > 0)				{					found = findExports(thisni, pp, lay, depth, antstack);					if (found == ERCANTPATHACTIVE) return found;				}			}				// look for an unspread antenna object and keep walking			if (firstSpreadAntennaObj.size() == 0) break;			AntennaObject ao = firstSpreadAntennaObj.get(0);			firstSpreadAntennaObj.remove(0);				ArcInst ai = (ArcInst)ao.geom;			ni = ai.getPortInst(ao.otherend).getNodeInst();			pp = ai.getPortInst(ao.otherend).getPortProto();			depth = ao.hierstack.length;			for(int i=0; i<depth; i++)				antstack[i] = ao.hierstack[i];		}		return ret;	}		/**	 * Method to tell whether a NodeInst has diffusion on it.	 * @param ni the NodeInst in question.	 * @return true if the NodeInst has diffusion on it.	 */	private boolean hasDiffusion(NodeInst ni)	{		// stop if this is a pin		if (ni.getFunction() == PrimitiveNode.Function.PIN) return false;			// analyze to see if there is diffusion here		Technology tech = ni.getProto().getTechnology();		Poly [] polyList = tech.getShapeOfNode(ni);		for(int i=0; i<polyList.length; i++)		{			Poly poly = polyList[i];			Layer.Function fun = poly.getLayer().getFunction();			if (fun.isDiff()) return true;		}		return false;	}	private int findArcs(NodeInst ni, PortProto pp, Layer lay, int depth, NodeInst [] antstack)	{        PortInst pi = ni.findPortInstFromProto(pp);		for(Iterator<Connection> it = pi.getConnections(); it.hasNext(); )		{			Connection con = it.next();//		for(Iterator it = ni.getConnections(); it.hasNext(); )//		{//			Connection con = it.next();//			PortInst pi = con.getPortInst();//			if (pi.getPortProto() != pp) continue;			ArcInst ai = con.getArc();			// see if it is the desired layer			if (ai.getProto().getFunction().isDiffusion()) return ERCANTPATHACTIVE;			Layer aLayer = arcProtoToLayer.get(ai.getProto());			if (aLayer == null) continue;			if (ai.getProto().getFunction().isMetal() != aLayer.getFunction().isMetal()) continue;			if (ai.getProto().getFunction().isPoly() != aLayer.getFunction().isPoly()) continue;			if (ai.getProto().getFunction().getLevel() > aLayer.getFunction().getLevel()) continue;			// make an antenna object for this arc			fsGeom.add(ai);			AntennaObject ao = new AntennaObject(ai);			if (haveAntennaObject(ao)) continue;			ao.loadAntennaObject(antstack, depth);			int other = 0;			if (ai.getPortInst(0) == pi) other = 1;			ao.otherend = other;			addAntennaObject(ao);			// add to the list of "unspread" antenna objects			firstSpreadAntennaObj.add(ao);		}		return ERCANTPATHNULL;	}	private int findExports(NodeInst ni, PortProto pp, Layer lay, int depth, NodeInst [] antstack)	{		depth--;		for(Iterator<Export> it = ni.getExports(); it.hasNext(); )		{			Export e = it.next();			if (e != pp) continue;			ni = antstack[depth];			pp = e;			int found = findArcs(ni, pp, lay, depth, antstack);			if (found == ERCANTPATHACTIVE) return found;			if (depth > 0)			{				found = findExports(ni, pp, lay, depth, antstack);				if (found == ERCANTPATHACTIVE) return found;			}		}		return ERCANTPATHNULL;	}		/**	 * Method to tell whether an AntennaObject is in the active list.	 * @param ao the AntennaObject.	 * @return true if the AntennaObject is already in the list.	 */	private boolean haveAntennaObject(AntennaObject ao)	{		for(AntennaObject oAo : pathList)		{				if (oAo.geom == ao.geom && oAo.depth == ao.depth)			{				boolean found = true;				int len = 0;				if (ao.hierstack != null) len = ao.hierstack.length;				int oLen = 0;				if (oAo.hierstack != null) oLen = oAo.hierstack.length;				if (len != oLen) continue;				for(int i=0; i<len; i++)				{					if (oAo.hierstack[i] != ao.hierstack[i]) { found = false;   break; }				}				if (found) return true;			}		}		return false;	}		/**	 * Method to add an AntennaObject to the list of antenna objects on this path.	 * @param ao the AntennaObject to add.	 */	private void addAntennaObject(AntennaObject ao)	{		pathList.add(ao);	}	/**	 * Method to return the maximum antenna ratio on a given Layer.	 * @param layer the layer in question.	 * @return the maximum antenna ratio for the Layer.	 */	private double getAntennaRatio(Layer layer)	{		// find the ArcProto that corresponds to this layer		ArcProto ap = layerToArcProto.get(layer);		if (ap == null) return 0;		// return its ratio		return ERC.tool.getAntennaRatio(ap);        //return ap.getAntennaRatio();	}}

⌨️ 快捷键说明

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