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

📄 mimicstitch.java

📁 The ElectricTM VLSI Design System is an open-source Electronic Design Automation (EDA) system that c
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/* -*- tab-width: 4 -*- * * Electric(tm) VLSI Design System * * File: MimicStitch.java * Routing tool: Mimic Stitcher (duplicates user's routes elsewhere in the cell). * Written by Steven M. Rubin, Sun Microsystems. * * Copyright (c) 2003 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.routing;import com.sun.electric.database.ImmutableArcInst;import com.sun.electric.database.geometry.DBMath;import com.sun.electric.database.geometry.Poly;import com.sun.electric.database.hierarchy.Cell;import com.sun.electric.database.hierarchy.EDatabase;import com.sun.electric.database.hierarchy.Export;import com.sun.electric.database.id.ArcProtoId;import com.sun.electric.database.network.Netlist;import com.sun.electric.database.prototype.NodeProto;import com.sun.electric.database.prototype.PortProto;import com.sun.electric.database.topology.ArcInst;import com.sun.electric.database.topology.Connection;import com.sun.electric.database.topology.NodeInst;import com.sun.electric.database.topology.PortInst;import com.sun.electric.database.variable.EditWindow_;import com.sun.electric.database.variable.UserInterface;import com.sun.electric.technology.ArcProto;import com.sun.electric.technology.PrimitiveNode;import com.sun.electric.technology.SizeOffset;import com.sun.electric.tool.Job;import com.sun.electric.tool.JobException;import com.sun.electric.tool.user.Highlight2;import com.sun.electric.tool.user.dialogs.EDialog;import com.sun.electric.tool.user.ui.TopLevel;import java.awt.Frame;import java.awt.GridBagConstraints;import java.awt.GridBagLayout;import java.awt.Insets;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.geom.Point2D;import java.awt.geom.Rectangle2D;import java.util.ArrayList;import java.util.Collections;import java.util.Comparator;import java.util.HashMap;import java.util.HashSet;import java.util.Iterator;import java.util.List;import java.util.Map;import javax.swing.JButton;import javax.swing.JLabel;import javax.swing.SwingUtilities;import javax.swing.WindowConstants;/** * This is the Mimic Stitching tool. */public class MimicStitch{	/** router to use */            private static InteractiveRouter router = new SimpleWirer();	private static final int NUMSITUATIONS          =  7;	private static final int LIKELYDIFFPORT         =  1;	private static final int LIKELYDIFFPORTWIDTH    =  2;	private static final int LIKELYDIFFARCCOUNT     =  4;	private static final int LIKELYDIFFNODETYPE     =  8;	private static final int LIKELYDIFFNODESIZE     = 16;	private static final int LIKELYARCSSAMEDIR      = 32;	private static final int LIKELYALREADYCONNECTED = 64;	private static int situations[] = null;	private static void buildLikelySituations()	{		if (situations != null) return;		int numSituations = 1 << NUMSITUATIONS;		List<Integer> allSituations = new ArrayList<Integer>();		for(int i=0; i<numSituations; i++) allSituations.add(new Integer(i));		Collections.sort(allSituations, new SituationSorter());		situations = new int[numSituations];		for(int i=0; i<numSituations; i++)			situations[i] = allSituations.get(i).intValue();	}	private static class SituationSorter implements Comparator<Integer>	{    	public int compare(Integer r1, Integer r2)        {    		int i1 = r1.intValue();    		int i2 = r2.intValue();    		int b1 = 0, b2 = 0;    		for(int i=0; i<NUMSITUATIONS; i++)    		{    			int mask = 1 << i;    			if ((i1 & mask) != 0) b1++;    			if ((i2 & mask) != 0) b2++;    		}    		return b1 - b2;        }	}	private static class PossibleArc	{		private int       situation;		private ArcInst   ai;		private NodeInst  ni1, ni2;		private PortProto pp1, pp2;//		private Point2D   pt1, pt2;	};	/**	 * Entry point for mimic router.	 * @param forced true if this mimic operation was explicitly requested.	 */	public static void mimicStitch(boolean forced)	{		buildLikelySituations();		UserInterface ui = Job.getUserInterface();		EditWindow_ wnd = ui.needCurrentEditWindow_();		if (wnd == null) return;		Routing.Activity lastActivity = Routing.getRoutingTool().getLastActivity();		if (lastActivity == null)		{			System.out.println("No wiring activity to mimic");			return;		}		// if a single arc was deleted, mimiced it		if (lastActivity.numDeletedArcs == 1 && lastActivity.numCreatedArcs == 0)		{			mimicdelete(lastActivity);			lastActivity.numDeletedArcs = 0;			return;		}		// if a single arc was just created, mimic that		if (lastActivity.numCreatedArcs == 1)		{            ArcInst ai = EDatabase.clientDatabase().getCell(lastActivity.createdArcsParents[0]).getArcById(lastActivity.createdArcs[0].arcId);//			ArcInst ai = lastActivity.createdArcs[0];			new MimicStitchJob(ai, 0, ai, 1, ai.getLambdaBaseWidth(), ai.getProto(), 0, 0, forced);//			new MimicStitchJob(ai, 0, ai, 1, ai.getLambdaFullWidth(), ai.getProto(), 0, 0, forced);			lastActivity.numCreatedArcs = 0;			return;		}		// if multiple arcs were just created, find the true end and mimic that		if (lastActivity.numCreatedArcs > 1 && lastActivity.numCreatedNodes > 0)		{			// find the ends of arcs that do not attach to the intermediate pins			HashSet<NodeInst> gotOne = new HashSet<NodeInst>();			HashSet<NodeInst> gotMany = new HashSet<NodeInst>();			for(int i=0; i<lastActivity.numCreatedArcs; i++)			{                ArcInst ai = EDatabase.clientDatabase().getCell(lastActivity.createdArcsParents[i]).getArcById(lastActivity.createdArcs[i].arcId);//				ArcInst ai = lastActivity.createdArcs[i];				for(int e=0; e<2; e++)				{					NodeInst ni = ai.getPortInst(e).getNodeInst();					if (!gotMany.contains(ni))					{						if (!gotOne.contains(ni)) gotOne.add(ni); else						{							gotOne.remove(ni);							gotMany.add(ni);						}					}				}			}			int foundEnds = 0;			Connection [] ends = new Connection[2];			double width = 0;			for(int i=0; i<lastActivity.numCreatedArcs; i++)			{                ArcInst ai = EDatabase.clientDatabase().getCell(lastActivity.createdArcsParents[i]).getArcById(lastActivity.createdArcs[i].arcId);//				ArcInst ai = lastActivity.createdArcs[i];				for(int e=0; e<2; e++)				{					NodeInst ni = ai.getPortInst(e).getNodeInst();					if (!gotOne.contains(ni)) continue;					if (foundEnds < 2)					{						ends[foundEnds] = ai.getConnection(e);						if (ai.getLambdaBaseWidth() > width)							width = ai.getLambdaBaseWidth();//						if (ai.getLambdaFullWidth() > width)//							width = ai.getLambdaFullWidth();					}					foundEnds++;				}			}			// if exactly two ends are found, mimic that connection			if (foundEnds == 2)			{				double prefX = 0, prefY = 0;				if (lastActivity.numCreatedNodes == 1)				{					Poly portPoly0 = ends[0].getPortInst().getPoly();					double x0 = portPoly0.getCenterX();					double y0 = portPoly0.getCenterY();					Poly portPoly1 = ends[1].getPortInst().getPoly();					double x1 = portPoly1.getCenterX();					double y1 = portPoly1.getCenterY();					prefX = lastActivity.createdNodes[0].anchor.getLambdaX() - (x0+x1) / 2;					prefY = lastActivity.createdNodes[0].anchor.getLambdaY() - (y0+y1) / 2;				} else if (lastActivity.numCreatedNodes == 2)				{					Poly portPoly0 = ends[0].getPortInst().getPoly();					double x0 = portPoly0.getCenterX();					double y0 = portPoly0.getCenterY();					Poly portPoly1 = ends[1].getPortInst().getPoly();					double x1 = portPoly1.getCenterX();					double y1 = portPoly1.getCenterY();					prefX = (lastActivity.createdNodes[0].anchor.getLambdaX() +						lastActivity.createdNodes[1].anchor.getLambdaX()) / 2 - (x0+x1) / 2;					prefY = (lastActivity.createdNodes[0].anchor.getLambdaY() +						lastActivity.createdNodes[1].anchor.getLambdaY()) / 2 - (y0+y1) / 2;				}				new MimicStitchJob(ends[0].getArc(), ends[0].getEndIndex(), ends[1].getArc(), ends[1].getEndIndex(),					width, null, prefX, prefY, forced);			}			lastActivity.numCreatedArcs = 0;			return;		}	}	/**	 * Method to mimic the deletion of an arc.	 */	private static void mimicdelete(Routing.Activity activity)	{		UserInterface ui = Job.getUserInterface();		EditWindow_ wnd = ui.needCurrentEditWindow_();		if (wnd == null) return;		// determine information about deleted arc		ImmutableArcInst mimicAi = activity.deletedArc;        Cell cell = Cell.inCurrentThread(activity.deletedArcParent);        if (cell == null) return; // cell killed		NodeInst mimicNiHead = cell.getNodeById(mimicAi.headNodeId);		NodeInst mimicNiTail = cell.getNodeById(mimicAi.tailNodeId);        if (mimicNiHead == null || mimicNiTail == null) return; // arc end killed		ArcProtoId typ = mimicAi.protoId;		Point2D pt0 = mimicAi.headLocation;		Point2D pt1 = mimicAi.tailLocation;		double dist = pt0.distance(pt1);		int angle = 0;		if (dist != 0) angle = DBMath.figureAngle(pt0, pt1);		// look for a similar situation to delete		List<PossibleArc> arcKills = new ArrayList<PossibleArc>();		for(Iterator<ArcInst> it = cell.getArcs(); it.hasNext(); )		{			ArcInst ai = it.next();			// arc must be of the same type			if (ai.getProto().getId() != typ) continue;			// must be the same length and angle			Point2D end0 = ai.getHeadLocation();			Point2D end1 = ai.getTailLocation();			double thisDist = end0.distance(end1);			if (dist != thisDist) continue;			if (dist != 0)			{				int thisAngle = DBMath.figureAngle(end0, end1);				if ((angle%1800) != (thisAngle%1800)) continue;			}						PossibleArc pa = new PossibleArc();			pa.ai = ai;			pa.situation = 0;			// arc must connect to the same type of port			boolean matchPort = false;			if (ai.getHeadPortInst().getPortProto().getId() == activity.deletedPorts[0] &&				ai.getTailPortInst().getPortProto().getId() == activity.deletedPorts[1]) matchPort = true;			if (ai.getHeadPortInst().getPortProto().getId() == activity.deletedPorts[1] &&				ai.getTailPortInst().getPortProto().getId() == activity.deletedPorts[0]) matchPort = true;			if (!matchPort) pa.situation |= LIKELYDIFFPORT;			// arcs must have the same bus width						NodeInst niHead = ai.getHeadPortInst().getNodeInst();			NodeInst niTail = ai.getTailPortInst().getNodeInst();			int con1 = mimicNiHead.getNumConnections() + mimicNiTail.getNumConnections() + 2;			int con2 = niHead.getNumConnections() + niTail.getNumConnections();			if (con1 != con2) pa.situation |= LIKELYDIFFARCCOUNT;			// arc must connect to the same type of node			boolean matchNode = false;			if (niHead.getProto() == mimicNiHead.getProto() && niTail.getProto() == mimicNiTail.getProto())				matchNode = true;			if (niHead.getProto() == mimicNiTail.getProto() && niTail.getProto() == mimicNiHead.getProto())				matchNode = true;			if (!matchNode) pa.situation |= LIKELYDIFFNODETYPE;			// determine size of nodes on mimic arc			double mimicWidHead = mimicNiHead.getLambdaBaseXSize();			double mimicHeiHead = mimicNiHead.getLambdaBaseYSize();//			SizeOffset so = mimicNiHead.getSizeOffset();//			double mimicWidHead = mimicNiHead.getXSize() - so.getLowXOffset() - so.getHighXOffset();//			double mimicHeiHead = mimicNiHead.getYSize() - so.getLowYOffset() - so.getHighYOffset();			double mimicWidTail = mimicNiTail.getLambdaBaseXSize();			double mimicHeiTail = mimicNiTail.getLambdaBaseYSize();//			so = mimicNiTail.getSizeOffset();//			double mimicWidTail = mimicNiTail.getXSize() - so.getLowXOffset() - so.getHighXOffset();//			double mimicHeiTail = mimicNiTail.getYSize() - so.getLowYOffset() - so.getHighYOffset();			// determine size of nodes on possible deleted arc			double widHead = niHead.getLambdaBaseXSize();			double heiHead = niHead.getLambdaBaseYSize();//			so = niHead.getSizeOffset();//			double widHead = niHead.getXSize() - so.getLowXOffset() - so.getHighXOffset();//			double heiHead = niHead.getYSize() - so.getLowYOffset() - so.getHighYOffset();			double widTail = niTail.getLambdaBaseXSize();			double heiTail = niTail.getLambdaBaseYSize();//			so = niTail.getSizeOffset();//			double widTail = niTail.getXSize() - so.getLowXOffset() - so.getHighXOffset();//			double heiTail = niTail.getYSize() - so.getLowYOffset() - so.getHighYOffset();			// flag if the sizes differ			if (widHead != mimicWidHead || heiHead != mimicHeiHead) pa.situation |= LIKELYDIFFNODESIZE;			if (widTail != mimicWidTail || heiTail != mimicHeiTail) pa.situation |= LIKELYDIFFNODESIZE;			// the same! queue it for deletion			arcKills.add(pa);		}		boolean mimicInteractive = Routing.isMimicStitchInteractive();		boolean matchPorts = Routing.isMimicStitchMatchPorts();		boolean matchPortWidth = Routing.isMimicStitchMatchPortWidth();		boolean matchArcCount = Routing.isMimicStitchMatchNumArcs();		boolean matchNodeType = Routing.isMimicStitchMatchNodeType();		boolean matchNodeSize = Routing.isMimicStitchMatchNodeSize();		boolean noOtherArcsThisDir = Routing.isMimicStitchNoOtherArcsSameDir();		boolean notAlreadyConnected = Routing.isMimicStitchOnlyNewTopology();		processPossibilities(cell, arcKills, 0, 0, Job.Type.EXAMINE, true,			mimicInteractive, matchPorts, matchPortWidth, matchArcCount,			matchNodeType, matchNodeSize, notAlreadyConnected, noOtherArcsThisDir);	}	/**	 * Class to examine a circuit and find mimic opportunities in a new thread.	 */	private static class MimicStitchJob extends Job	{		private ArcInst ai1, ai2;		private int end1, end2;		private double oWidth;		private ArcProto oProto;		private double prefX, prefY;		private boolean forced;		private MimicStitchJob(ArcInst ai1, int end1, ArcInst ai2, int end2, double oWidth, ArcProto oProto,								double prefX, double prefY, boolean forced)		{			super("Mimic-Stitch", Routing.getRoutingTool(), Job.Type.EXAMINE, null, null, Job.Priority.USER);			this.ai1 = ai1;			this.end1 = end1;			this.ai2 = ai2;			this.end2 = end2;			this.oWidth = oWidth;			this.oProto = oProto;			this.prefX = prefX;			this.prefY = prefY;			this.forced = forced;			setReportExecutionFlag(true);			startJob();		}		public boolean doIt() throws JobException		{			// get options			boolean mimicInteractive = Routing.isMimicStitchInteractive();			boolean matchPorts = Routing.isMimicStitchMatchPorts();			boolean matchPortWidth = Routing.isMimicStitchMatchPortWidth();			boolean matchArcCount = Routing.isMimicStitchMatchNumArcs();			boolean matchNodeType = Routing.isMimicStitchMatchNodeType();			boolean matchNodeSize = Routing.isMimicStitchMatchNodeSize();			boolean noOtherArcsThisDir = Routing.isMimicStitchNoOtherArcsSameDir();			boolean notAlreadyConnected = Routing.isMimicStitchOnlyNewTopology();			mimicOneArc(ai1, end1, ai2, end2, oWidth, oProto, prefX, prefY, forced, Job.Type.EXAMINE,

⌨️ 快捷键说明

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