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

📄 flagdesign.java

📁 The ElectricTM VLSI Design System is an open-source Electronic Design Automation (EDA) system that c
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
package com.sun.electric.tool.generator.flag;

import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import com.sun.electric.database.geometry.Orientation;
import com.sun.electric.database.hierarchy.Cell;
import com.sun.electric.database.hierarchy.Export;
import com.sun.electric.database.hierarchy.HierarchyEnumerator;
import com.sun.electric.database.hierarchy.Library;
import com.sun.electric.database.prototype.PortCharacteristic;
import com.sun.electric.database.topology.Geometric;
import com.sun.electric.database.topology.NodeInst;
import com.sun.electric.database.topology.PortInst;
import com.sun.electric.database.variable.VarContext;
import com.sun.electric.technology.ArcProto;
import com.sun.electric.tool.generator.flag.router.Router;
import com.sun.electric.tool.generator.flag.router.SogRouterAdapter;
import com.sun.electric.tool.generator.flag.router.ToConnect;
import com.sun.electric.tool.generator.flag.scan.Scan;
import com.sun.electric.tool.generator.layout.AbutRouter;
import com.sun.electric.tool.generator.layout.LayoutLib;
import com.sun.electric.tool.generator.layout.TechType;
import com.sun.electric.tool.generator.layout.LayoutLib.Corner;
import com.sun.electric.tool.ncc.basic.NccCellAnnotations;
import com.sun.electric.tool.user.ExportChanges;


/** Super class for the physical design objects of all Cells */
public class FlagDesign {
    public static final double DEF_SIZE = LayoutLib.DEF_SIZE;
	private final FlagConfig config;
	private final Scan scan;
	private final Router router;
	private final SogRouterAdapter sogRouterAdapter;

	public TechType tech() {return config.techTypeEnum.getTechType();}
    
	
//	public static Rectangle2D findColBounds(Collection<NodeInst> stages) {
//		double minX, minY, maxX, maxY;
//		minX = minY = Double.MAX_VALUE;
//		maxX = maxY = Double.MIN_VALUE;
//		for (NodeInst ni : stages) {
//			Rectangle2D bounds = ni.findEssentialBounds();
//			error(bounds==null, 
//					        "Layout Cell is missing essential bounds: "+
//					        ni.getProto().describe(false));
//			minX = Math.min(minX, bounds.getMinX());
//			maxX = Math.max(maxX, bounds.getMaxX());
//			minY = Math.min(minY, bounds.getMinY());
//			maxY = Math.max(maxY, bounds.getMaxY());
//		}
//		return new Rectangle2D.Double(minX, minY, maxX-minX, maxY-minY);
//	}
//	private void sortPortInstsBotToTop(List<PortInst> pis) {
//		Collections.sort(pis, new Comparator<PortInst>() {
//			public int compare(PortInst p1, PortInst p2) {
//				double diff = p1.getCenter().getY() -
//				              p2.getCenter().getY();
//				return (int) Math.signum(diff);
//			}
//		});
//	}
//	private Rectangle2D getPortInstBounds(ToConnect toConn) {
//		double minX, minY, maxX, maxY;
//		minX = minY = Double.MAX_VALUE;
//		maxX = maxY = Double.MIN_VALUE;
//		for (PortInst pi : toConn.getPortInsts()) {
//			double x = pi.getCenter().getX();
//			double y = pi.getCenter().getY();
//			if (x<minX) minX=x;
//			if (x>maxX) maxX=x;
//			if (y<minY) minY=y;
//			if (y>maxY) maxY=y;
//		}
//		return new Rectangle2D.Double(minX, minY, maxX-minX, maxY-minY);
//	}
	
//	private void connect2PinM3(ToConnect toConn) {
//		prln("M3 "+toConn.toString());
//		PortInst pi1 = toConn.getPortInsts().get(0);
//		PortInst pi2 = toConn.getPortInsts().get(1);
//		error(!connectsToM3(pi1) || ! connectsToM3(pi2),
//				        "only 1 of 2 pins connects to m3");
//		double x1 = pi1.getCenter().getX();
//		double x2 = pi2.getCenter().getX();
//		error(x1!=x2, "m3 net not vertical");
//		
//		LayoutLib.newArcInst(tech().m3(), SIGNAL_WID, pi1, pi2);
//		
//	}
	
//	private void dumpChannels(LayerChannels m2chan, LayerChannels m3chan) {
//        prln("m2 channels");
//        prln(m2chan.toString());
//        
//        prln("m3 channels");
//        prln(m3chan.toString());
//	}
//	private List<ToConnect> reduceToTwoPinX(List<List<PortInst>> portLists) {
//		List<ToConnect> twoPins = new ArrayList<ToConnect>();
//		while (portLists.size()>1) {
//			ClosestClusters cc = findClosest(portLists);
//			ToConnect tc = new ToConnect(null);
//			tc.addPortInst(cc.pair.p1);
//			tc.addPortInst(cc.pair.p2);
//			twoPins.add(tc);
//			List<PortInst> pl1 = portLists.get(cc.ndx1);
//			List<PortInst> pl2 = portLists.get(cc.ndx2);
//			pl1.addAll(pl2);
//			portLists.remove(cc.ndx2);
//		}
//		return twoPins;
//	}
	

	/** Convert each ToConnect with more than two pins to multiple two 
	 * pin TwoConnects */ 
//	private List<ToConnect> reduceToTwoPin(List<ToConnect> toConns) {
//		List<ToConnect> twoPins = new ArrayList<ToConnect>();
//		for (ToConnect tc : toConns) {
//			// Skip Exported net that touches no stage PortInsts 
//			if (tc.size()==0) continue;
//			
//			// Some PortInsts on a ToConnect may already be connected in 
//			// schematic by abut router
//			List<List<PortInst>> connPorts = groupConnectedPorts(tc);
//
//			// Generate a list of two pin ToConnects that connects  
//			// disconnected pin lists.
//			twoPins.addAll(reduceToTwoPinX(connPorts));
//		}
//		return twoPins;
//	}
	
	
	private void fattenVerticalM3(Map<Double, PortInst> bot,
			                      Map<Double, PortInst> top) {
		for (Double x : bot.keySet()) {
			PortInst piBot = bot.get(x);
			PortInst piTop = top.get(x);
			if (piTop==null) continue;
			LayoutLib.newArcInst(tech().m3(), config.m3PwrGndWid, 
		                         piBot, piTop);
		}
	}
	
	// Hack until I get a chance to fatten based upon need.
//	private void fattenPwrGnd(List<NodeInst> stages) {
//		Rectangle2D colBounds = findBounds(stages.get(0).getParent());
//		NodeInst topInst = stages.get(stages.size()-1);
//		Map<Double, PortInst> topPwr = new TreeMap<Double, PortInst>();
//		Map<Double, PortInst> topGnd = new TreeMap<Double, PortInst>();
//		getM3PwrGndExports(topPwr, topGnd, topInst, colBounds.getMaxY());
//		
//		NodeInst botInst = stages.get(0);
//		Map<Double, PortInst> botPwr = new TreeMap<Double, PortInst>();
//		Map<Double, PortInst> botGnd = new TreeMap<Double, PortInst>();
//		getM3PwrGndExports(botPwr, botGnd, botInst, colBounds.getMinY());
//
//		fattenVerticalM3(botGnd, topGnd);
//		fattenVerticalM3(botPwr, topPwr);
//	}
	
	
	private static class CloseToBound implements Comparator<PortInst> {
		private Rectangle2D bound;
		private double distToBound(PortInst pi) {
			double x = pi.getCenter().getX();
			double l = Math.abs(x - bound.getMinX());
			double r = Math.abs(x - bound.getMaxX());
			double y = pi.getCenter().getY();
			double b = Math.abs(y - bound.getMinY());
			double t = Math.abs(y - bound.getMaxY());
			return Math.min(Math.min(l, r), 
					        Math.min(t, b)); 
		}
		public CloseToBound(Rectangle2D bound) {this.bound=bound;}
		public int compare(PortInst pi1, PortInst pi2) {
			double d = distToBound(pi1) - distToBound(pi2);
			return (int) Math.signum(d);
		}
	}
	
	
	
	private void reExportIfPortNameMatches(List<String> expNms,
			                               List<PortInst> ports) {
		if (ports.isEmpty()) return;
		Cell parent = ports.get(0).getNodeInst().getParent();
		for (Iterator<String> sIt=expNms.iterator(); sIt.hasNext();) {
			String nm = sIt.next();
			if (parent.findExport(nm)!=null) {
				sIt.remove();
			} else {
				
			}
		}
		
	}
	/** If PortInst name matches Export name then export PortInst and
	 * remove PortInst and export name from respective lists. */
	private void exportPortInstsWithMatchingNames(List<String> expNames,
			                                      List<PortInst> ports) {
		for (Iterator<String> sIt=expNames.iterator(); sIt.hasNext();) {
			String expNm = sIt.next();
			for (Iterator<PortInst> pIt=ports.iterator(); pIt.hasNext();) {
				PortInst pi = pIt.next();
				String portNm = pi.getPortProto().getName();
				if (expNm.equals(portNm)) {
					Export.newInstance(pi.getNodeInst().getParent(), 
					                   pi, expNm);
					sIt.remove();
					pIt.remove();
					break;
				}
			}
		}
	}
	
	private void exportTheRest(List<String> expNames, List<PortInst> ports) {
		for (int i=0; i<expNames.size(); i++) {
			String expNm = expNames.get(i);
			if (i>=ports.size()) {
				prln("Error: Schematic export: "+expNm+
					  " couldn't be added to layout");
				continue;
			}
			PortInst pi = ports.get(i);
			Export.newInstance(pi.getNodeInst().getParent(), 
	                           pi, expNm);
		}
	}
	
	/** Re-export all ports that the schematic exports. Don't do power
	 * and ground because they are handled by another method. 
	 * There are three criteria for selecting which PortInst to export. First, 
	 * prefer a PortInst with the same as the export. Second, prefer a PortInst
	 * without connections. Third, prefer a PortInst that is close to the cell
	 * boundary. */
	private void reExport(Cell layCell, List<ToConnect> toConns) {
		Rectangle2D colBounds = Utils.findBounds(layCell);
		CloseToBound closeToBound = new CloseToBound(colBounds);
		for (ToConnect tc : toConns) {
			if (tc.numPortInsts()>0 && tc.isExported() && !tc.isPowerOrGround()) {
				// separate out connected and not connected PortInsts
				// Because PortInst.hasConnections() is so slow, make sure
				// we do this test once. Keeping two different lists accomplishes
				// this.
				List<PortInst> unconnPorts = new ArrayList<PortInst>();
				List<PortInst> connPorts = new ArrayList<PortInst>();
				for (PortInst pi : tc.getPortInsts()) {
					if (pi.hasConnections()) connPorts.add(pi);
					else  unconnPorts.add(pi);
				}
				Collections.sort(connPorts, closeToBound);
				Collections.sort(unconnPorts, closeToBound);

				// allPorts sorted by following criterea in order of importance:
				// 1) no arcs connected
				// 2) distance to boundary
				List<PortInst> allPorts = new ArrayList<PortInst>();
				allPorts.addAll(unconnPorts);
				allPorts.addAll(connPorts);
				
				List<String> expNames = new ArrayList<String>();
				expNames.addAll(tc.getExportName());
				exportPortInstsWithMatchingNames(expNames, allPorts);
				
				exportTheRest(expNames, allPorts);
			}
		}
	}
	
	
	private static class CompareLayInstSchPos implements Comparator<NodeInst> {
		Map<NodeInst, SchematicPosition> layInstToSchPos;
		public int compare(NodeInst ni1, NodeInst ni2) {
			SchematicPosition sp1, sp2;
			sp1 = layInstToSchPos.get(ni1);
			sp2 = layInstToSchPos.get(ni2);
			return sp1.compareTo(sp2);
		}
		public CompareLayInstSchPos(Map<NodeInst, SchematicPosition> layInstToSchPos) {
			this.layInstToSchPos = layInstToSchPos;
		}
	}
	// sort layout instances according to X-coordinate in schematic
	private List<NodeInst> getSortedLayInsts(SchematicVisitor visitor) {
        List<NodeInst> layInsts = 
        	new ArrayList<NodeInst>(visitor.getLayInsts());
        Map<NodeInst, SchematicPosition> layInstSchPos = 
        	visitor.getLayInstSchematicPositions();
        
        CompareLayInstSchPos compareLayInstSchPos = 
        	new CompareLayInstSchPos(layInstSchPos);
        
        Collections.sort(layInsts, compareLayInstSchPos);
        return layInsts;
	}

	private Map<Cell,Integer> getCellCounts(List<NodeInst> layInsts) {
		Map<Cell,Integer> cellToCount = new HashMap<Cell,Integer>();
		for (NodeInst ni : layInsts) {
			Cell c = (Cell) ni.getProto();
			Integer cnt = cellToCount.get(c);
			if (cnt==null) cnt = 0;
			cellToCount.put(c, cnt+1);
		}
		return cellToCount; 
	}
	
	// Print report in the same order as sortedLayInsts
	private void printInstanceReport(List<NodeInst> sortedLayInsts) {
		prln("Here are the Cell's I've instantiated: ");
		Map<Cell,Integer> cellToCount = getCellCounts(sortedLayInsts);
		for (NodeInst ni : sortedLayInsts) {
			Cell c = (Cell) ni.getProto();
			Integer cnt = cellToCount.get(c);
			if (cnt!=null) {
				prln("    "+cnt+"   "+c.describe(false));
				// Only print report the first time we encounter the Cell
				cellToCount.remove(c);
			}
		}
		
	}
	
	//	private boolean isPlain(NodeInst ni) {
//		return ni.getProto().getName().contains("aPlainStage");
//	}
//	
//	// infinityA and infinityB need to be stretched to the height of infinityC
//	private void stretchInfinityAB(List<NodeInst> layInsts) {
//		Cell parent = layInsts.get(0).getParent();
//		Cell dummyStage = STAGE_LIB.findNodeProto("aDummyStage{lay}");
//		if (!layInsts.get(0).getParent().getName().contains("infinityA") &&

⌨️ 快捷键说明

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