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

📄 techconversionresult.java

📁 The ElectricTM VLSI Design System is an open-source Electronic Design Automation (EDA) system that c
💻 JAVA
字号:
/* -*- tab-width: 4 -*- * * Electric(tm) VLSI Design System * * File: TechConversionResult.java * Technology Editor, conversion of technology libraries to technologies * Written by Steven M. Rubin, Sun Microsystems. * * Copyright (c) 2007 Sun Microsystems and Static Free Software * * Electric(tm) is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * Electric(tm) is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Electric(tm); see the file COPYING.  If not, write to * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, Mass 02111-1307, USA. */package com.sun.electric.tool.user.tecEdit;import com.sun.electric.database.hierarchy.Cell;import com.sun.electric.database.text.TextUtils;import com.sun.electric.database.topology.NodeInst;import com.sun.electric.database.variable.EditWindow_;import com.sun.electric.tool.Job;import java.awt.geom.Point2D;import java.awt.geom.Rectangle2D;import java.io.Serializable;import java.util.HashMap;import java.util.List;import java.util.Map;import java.util.Set;/** * Class to define error messages that arise during technology creation. * This class is necessary because errors occur during Jobs, but the display * of the errors must be done on the client side.  Therefore, objects of * this class are passed from the server to the client for display. */public class TechConversionResult implements Serializable{	private boolean good;	private String errorMessage;	private NodeInst ni;	private Cell cell;	private List<Example> neList;	private Sample ns;	private double sampleCoord;	private boolean xDir;	public TechConversionResult() { good = true; }	/**	 * Method to return the success status.	 * @return true if the conversion failed.	 */	public boolean failed() { return !good; }	/**	 * Method to mark a general error.	 * @param ni the NodeInst that caused the error (may be null).	 * @param cell the Cell where the error occurred (may be null).	 * @param errorMessage the message to display.	 */	public void markError(NodeInst ni, Cell cell, String errorMessage)	{		good = false;		this.cell = cell;		this.ni = ni;		this.errorMessage = errorMessage;	}	/**	 * Method to mark an error in determining stretching rules.	 * @param neList the Examples that invoked the error.	 * @param ns the Sample on the main Example that failed.	 * @param cell the Cell with the error.	 * @param sampleCoord the coordinate (in X or Y) where the failure occurred.	 * @param xDir true for an X-axis error, false for Y-axis.	 */	public void markStretchProblem(List<Example> neList, Sample ns, Cell cell, double sampleCoord, boolean xDir)	{		good = false;		this.neList = neList;		this.ns = ns;		this.cell = cell;		this.sampleCoord = sampleCoord;		this.xDir = xDir;	}	/**	 * Method to return the error message associated with this conversion.	 * @return the error message associated with this conversion.	 */	public String getErrorMessage()	{		String fullErrorMsg = errorMessage;		if (cell != null)		{    		String prefixErrorMsg = "Cell " + cell.describe(false);    		if (ni != null) prefixErrorMsg += ", node " + ni.describe(false);    		fullErrorMsg = prefixErrorMsg + ": " + fullErrorMsg;		}		return fullErrorMsg;	}	/**	 * Method to highlight the error.	 */	public void showError()	{		// more complex errors have their own way to display		if (errorMessage == null)		{			explainStretchProblem();			return;		}		if (cell != null)		{			Job.getUserInterface().displayCell(cell);    		EditWindow_ wnd = Job.getUserInterface().getCurrentEditWindow_();    		if (wnd != null && ni != null)    		{    			wnd.clearHighlighting();    			wnd.addElectricObject(ni, cell);    			wnd.finishedHighlighting();    		}		}		String msg = getErrorMessage();		Job.getUserInterface().showErrorMessage(msg, "Analysis Failure");		System.out.println(msg);	}	/**	 * Method to explain a stretching rule problem.	 * @param neList the list of Examples	 * @param ns the sample in the main Example	 * @param np the Cell.	 * @param sampleCoord the coordinate of the stretching failure.	 * @param xDir true if this is in the X direction, false for Y.	 */	private void explainStretchProblem()	{		Job.getUserInterface().displayCell(cell);		EditWindow_ wnd = Job.getUserInterface().getCurrentEditWindow_();		if (wnd == null) return;		wnd.clearHighlighting();		Map<Sample,double[]> factorList = new HashMap<Sample,double[]>();		double[] factors = showSampleInExample(wnd, ns, neList.get(0), sampleCoord, xDir, true);		factorList.put(ns, factors);		for(int n=1; n<neList.size(); n++)		{			Example e = neList.get(n);			for(Sample s : e.samples)			{				if (s.assoc == ns)				{					factors = showSampleInExample(wnd, s, e, sampleCoord, xDir, false);					factorList.put(s, factors);				}			}		}		// see if the offending sample can be guessed		Set<Sample> allSamples = factorList.keySet();		Map<Sample,Integer> offendingSample = new HashMap<Sample,Integer>();		for(int i=0; i<4; i++)		{			double v1 = 0, v2 = 0;			int v1Count = 0, v2Count = 0;			Sample s1 = null, s2 = null;			for(Sample s : allSamples)			{				factors = factorList.get(s);				if (v1Count == 0)				{					v1Count++;					v1 = factors[i];					s1 = s;					continue;				}				if (v1 == factors[i])				{					v1Count++;					continue;				}				if (v2Count == 0)				{					v2Count++;					v2 = factors[i];					s2 = s;					continue;				}				if (v2 == factors[i])				{					v2Count++;					continue;				}			}			if (v1Count+v2Count != allSamples.size()) continue;			Sample offendingSamp = null;			if (v1Count == 1) offendingSamp = s1;			if (v2Count == 1) offendingSamp = s2;			if (offendingSamp != null)			{				Integer prev = offendingSample.get(offendingSamp);				if (prev == null) prev = new Integer(1); else prev = new Integer(prev.intValue()+1);				offendingSample.put(offendingSamp, prev);			}		}		Sample offendingSamp = null;		int num = 0;		for(Sample s : offendingSample.keySet())		{			int numTimes = offendingSample.get(s).intValue();			if (numTimes > num)			{				num = numTimes;				offendingSamp = s;			}		}		// show the offending sample if found, all if not		String err = "Cannot determine " + (xDir?"X":"Y") + " stretching rule for layer " + Info.getSampleName(ns.layer) +			" in " + cell;		String additional = "\nOne of these stretching rules must be the same for every example:" +			"\nOut (the distance from the center to the point)" +			"\nIn (the distance from the edge to the point)" +			"\nPer (the percentage of the point from the center to the edge)" +			"\nOpp (the distance from the opposite edge to the point)";		if (offendingSamp == null)		{			offendingSamp = ns;			for(Sample s : allSamples)				wnd.addElectricObject(s.node, cell);		} else		{			wnd.addElectricObject(offendingSamp.node, cell);			additional += "\n\nThe error is probably with node " + offendingSamp.node.describe(false);		}		wnd.finishedHighlighting();		Job.getUserInterface().showErrorMessage(err+additional, "Analysis Failure");		System.out.println(err);	}	private double[] showSampleInExample(EditWindow_ wnd, Sample ns, Example e, double sampleCoord,		boolean xDir, boolean mainExample)	{		Cell cell = ns.node.getParent();		Rectangle2D exampleBounds = wnd.getCell().getBounds();		double singleStep = Math.max(exampleBounds.getHeight(), exampleBounds.getWidth()) / 45;		double doubleStep = singleStep * 2;		double halfStep = singleStep / 2;		double exampleHalfSize = (xDir ? (e.hx - e.lx) : (e.hy - e.ly)) / 2;		double exampleCtr = (xDir ? (e.lx + e.hx) : (e.ly + e.hy)) / 2;		// first draw bold bars above/below example at the edges and center		Point2D pt1 = makeDisplayPoint(e, 0, exampleCtr-exampleHalfSize, xDir);		Point2D pt2 = makeDisplayPoint(e, singleStep, exampleCtr-exampleHalfSize, xDir);		wnd.addHighlightLine(pt1, pt2, cell, true);		pt1 = makeDisplayPoint(e, 0, exampleCtr+exampleHalfSize, xDir);		pt2 = makeDisplayPoint(e, singleStep, exampleCtr+exampleHalfSize, xDir);		wnd.addHighlightLine(pt1, pt2, cell, true);		pt1 = makeDisplayPoint(e, 0, exampleCtr, xDir);		pt2 = makeDisplayPoint(e, doubleStep, exampleCtr, xDir);		wnd.addHighlightLine(pt1, pt2, cell, true);		Rectangle2D mainSampleBounds = ns.assoc.node.getBounds();		Rectangle2D sampleBounds = ns.node.getBounds();		boolean adjusted = false;		if (mainExample) adjusted = true; else		{			if (xDir)			{				if (sampleCoord == mainSampleBounds.getMinX())					{ adjusted = true;   sampleCoord = sampleBounds.getMinX(); }				if (sampleCoord == mainSampleBounds.getMaxX())					{ adjusted = true;   sampleCoord = sampleBounds.getMaxX(); }			} else			{				if (sampleCoord == mainSampleBounds.getMinY())					{ adjusted = true;   sampleCoord = sampleBounds.getMinY(); }				if (sampleCoord == mainSampleBounds.getMaxY())					{ adjusted = true;   sampleCoord = sampleBounds.getMaxY(); }			}		}		// determine the 4 stretching factors (out, in, %, opp)		double [] factors = new double[4];		double percentOut = Math.abs(sampleCoord-exampleCtr) / exampleHalfSize;		double distOut = Math.abs(sampleCoord-exampleCtr);		factors[0] = distOut;		factors[1] = exampleHalfSize-distOut;		factors[2] = Math.round(percentOut*100);		factors[3] = distOut+exampleHalfSize;		if (adjusted)		{			double arrowCoord = sampleCoord;			double arrowCoordInv = sampleCoord;			double farEnd, closeEnd;			if (sampleCoord > exampleCtr)			{				arrowCoord -= singleStep;				arrowCoordInv += singleStep;				closeEnd = exampleCtr + exampleHalfSize;				farEnd = exampleCtr - exampleHalfSize;			} else			{				arrowCoord += singleStep;				arrowCoordInv -= singleStep;				closeEnd = exampleCtr - exampleHalfSize;				farEnd = exampleCtr + exampleHalfSize;			}			// now draw bar where problem is			pt1 = makeDisplayPoint(e, halfStep, sampleCoord, xDir);			pt2 = makeDisplayPoint(e, doubleStep+singleStep, sampleCoord, xDir);			wnd.addHighlightLine(pt1, pt2, cell, false);			// draw arrow from opposite edge to problem location			if (sampleCoord != farEnd)			{				pt1 = makeDisplayPoint(e, singleStep, farEnd, xDir);				pt2 = makeDisplayPoint(e, singleStep, sampleCoord, xDir);				wnd.addHighlightLine(pt1, pt2, cell, false);				pt1 = makeDisplayPoint(e, singleStep, sampleCoord, xDir);				pt2 = makeDisplayPoint(e, singleStep-singleStep/3, arrowCoord, xDir);				wnd.addHighlightLine(pt1, pt2, cell, false);				pt1 = makeDisplayPoint(e, singleStep, sampleCoord, xDir);				pt2 = makeDisplayPoint(e, singleStep+singleStep/3, arrowCoord, xDir);				wnd.addHighlightLine(pt1, pt2, cell, false);			}			// draw arrow from center to problem location			if (sampleCoord != exampleCtr)			{				pt1 = makeDisplayPoint(e, doubleStep, exampleCtr, xDir);				pt2 = makeDisplayPoint(e, doubleStep, sampleCoord, xDir);				wnd.addHighlightLine(pt1, pt2, cell, false);				pt1 = makeDisplayPoint(e, doubleStep, sampleCoord, xDir);				pt2 = makeDisplayPoint(e, doubleStep-singleStep/3, arrowCoord, xDir);				wnd.addHighlightLine(pt1, pt2, cell, false);				pt1 = makeDisplayPoint(e, doubleStep, sampleCoord, xDir);				pt2 = makeDisplayPoint(e, doubleStep+singleStep/3, arrowCoord, xDir);				wnd.addHighlightLine(pt1, pt2, cell, false);			}			// draw arrow from close edge to problem location			if (sampleCoord != closeEnd)			{				pt1 = makeDisplayPoint(e, doubleStep, closeEnd, xDir);				pt2 = makeDisplayPoint(e, doubleStep, sampleCoord, xDir);				wnd.addHighlightLine(pt1, pt2, cell, false);				pt1 = makeDisplayPoint(e, doubleStep, sampleCoord, xDir);				pt2 = makeDisplayPoint(e, doubleStep-singleStep/3, arrowCoordInv, xDir);				wnd.addHighlightLine(pt1, pt2, cell, false);				pt1 = makeDisplayPoint(e, doubleStep, sampleCoord, xDir);				pt2 = makeDisplayPoint(e, doubleStep+singleStep/3, arrowCoordInv, xDir);				wnd.addHighlightLine(pt1, pt2, cell, false);			}			// write factors			pt2 = makeDisplayPoint(e, doubleStep+halfStep, xDir ? exampleCtr : (exampleCtr-halfStep), xDir);			wnd.addHighlightMessage(cell, "Out="+TextUtils.formatDouble(factors[0])+				" Per="+((int)factors[2]), pt2);			pt2 = makeDisplayPoint(e, doubleStep-halfStep, xDir ? closeEnd+halfStep : (closeEnd-halfStep), xDir);			wnd.addHighlightMessage(cell, "In="+TextUtils.formatDouble(factors[1]), pt2);			pt2 = makeDisplayPoint(e, singleStep+halfStep, xDir ? farEnd : (farEnd-halfStep), xDir);			wnd.addHighlightMessage(cell, "Opp="+TextUtils.formatDouble(factors[3]), pt2);		}		return factors;	}	private Point2D makeDisplayPoint(Example e, double offsetOrtho, double sampleCoord, boolean xDir)	{		if (xDir) return new Point2D.Double(sampleCoord, e.hy+offsetOrtho);		return new Point2D.Double(e.hx+offsetOrtho, sampleCoord);	}}

⌨️ 快捷键说明

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