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

📄 layout.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: Layout.java * * 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.database.constraint;import com.sun.electric.database.CellBackup;import com.sun.electric.database.IdMapper;import com.sun.electric.database.ImmutableArcInst;import com.sun.electric.database.ImmutableCell;import com.sun.electric.database.ImmutableExport;import com.sun.electric.database.ImmutableLibrary;import com.sun.electric.database.ImmutableNodeInst;import com.sun.electric.database.Snapshot;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.hierarchy.Library;import com.sun.electric.database.id.CellId;import com.sun.electric.database.prototype.PortProto;import com.sun.electric.database.topology.ArcInst;import com.sun.electric.database.topology.NodeInst;import com.sun.electric.database.topology.PortInst;import com.sun.electric.database.variable.ElectricObject;import com.sun.electric.database.variable.TextDescriptor;import com.sun.electric.database.variable.Variable;import com.sun.electric.technology.PrimitiveNode;import com.sun.electric.technology.PrimitivePort;import com.sun.electric.technology.Technology;import java.awt.geom.AffineTransform;import java.util.ArrayList;import java.util.HashMap;import java.util.Iterator;import java.util.Map;import java.util.Set;/** * Class to implement the layout-constraint system. * Handles the fixed-angle and rigid constraints. * Also propagates these constraints up the hierarchy. */public class Layout extends Constraints{//	private static final Layout layoutConstraint = new Layout();	static final boolean DEBUG = false;    private static boolean doChangesQuietly;    private static Snapshot oldSnapshot;    private static long revisionDate;    private static String userName;    private static Set<Cell> goodSpacingDRCCells, goodAreaDRCCells;    private static Variable goodSpacingDRCDate, goodSpacingDRCBit, goodAreaDRCDate;    /** Shadow Cell info */    private static final ArrayList<LayoutCell> cellInfos = new ArrayList<LayoutCell>();    /** Map which contains temporary rigidity of ArcInsts. */    private static final HashMap<ArcInst,Boolean> tempRigid = new HashMap<ArcInst,Boolean>();    /** key of Variable for last valid DRC date on a Cell. Only spacing rules */    public static final Variable.Key DRC_LAST_GOOD_DATE_SPACING = Variable.newKey("DRC_last_good_drc_date");    /** key of Variable for last valid DRC bit on a Cell. Only spacing rules */    public static final Variable.Key DRC_LAST_GOOD_BIT_SPACING = Variable.newKey("DRC_last_good_drc_bit");    /** Default valud when no bit is found **/    public static final int DRC_LAST_GOOD_BIT_DEFAULT = -1;    /** No need of bit for area since it is only 1 mode */    public static final Variable.Key DRC_LAST_GOOD_DATE_AREA = Variable.newKey("DRC_last_good_drc_area_date");    Layout() {}//	/**//	 * Method to return the current constraint solver.//	 * @return the current constraint solver.//	 *///	public static Layout getConstraint() { return layoutConstraint; }	/**	 * Method to set the subsequent changes to be "quiet".	 * Quiet changes are not passed to constraint satisfaction, not recorded for Undo and are not broadcast.     * This method is used to suppress endBatch.	 */	public static void changesQuiet(boolean quiet) {        doChangesQuietly = true;    }	/**	 * Method to start a batch of changes.     * @param initialSnapshot snapshot before job changes.	 */    @Override	public void startBatch(Snapshot initialSnapshot)	{		// force every cell to remember its current bounds        doChangesQuietly = false;        oldSnapshot = initialSnapshot;        tempRigid.clear();        goodSpacingDRCCells = null;        goodAreaDRCCells = null;        makeLayoutCells();	}	/**	 * Method to do hierarchical update on any cells that changed	 */    @Override	public void endBatch(String userName)	{        if (DEBUG) {            System.out.println("Temporary rigid:");            for (Map.Entry<ArcInst,Boolean> e : tempRigid.entrySet()) {                System.out.println("\t" + e.getKey() + " --> " + e.getValue());            }        }        Layout.userName = userName;        revisionDate = System.currentTimeMillis();        if (goodSpacingDRCCells != null)        {            TextDescriptor td = TextDescriptor.getCellTextDescriptor().withDisplay(false);            goodSpacingDRCDate = Variable.newInstance(DRC_LAST_GOOD_DATE_SPACING, new Long(revisionDate + 1), td); // If cell is changed during this 1 millisecond ???        }        if (goodAreaDRCCells != null)        {            TextDescriptor td = TextDescriptor.getCellTextDescriptor().withDisplay(false);            goodAreaDRCDate = Variable.newInstance(DRC_LAST_GOOD_DATE_AREA, new Long(revisionDate + 1), td); // If cell is changed during this 1 millisecond ???        }        if (!doChangesQuietly) {            // Propagate changes and mark changed cells.            for(Iterator<Library> it = Library.getLibraries(); it.hasNext(); ) {                Library lib = it.next();                for(Iterator<Cell> cIt = lib.getCells(); cIt.hasNext(); ) {                    Cell cell = cIt.next();                    assert cell.isLinked();                    LayoutCell cellInfo = getCellInfo(cell);                    cellInfo.compute();                }            }        }        cellInfos.clear();        tempRigid.clear();        // Set revision dates to modified Cells, update DRC date, update bounds        for(Iterator<Library> it = Library.getLibraries(); it.hasNext(); ) {            Library lib = it.next();            for(Iterator<Cell> cIt = lib.getCells(); cIt.hasNext(); ) {                Cell cell = cIt.next();                cell.lowLevelMadeRevision(revisionDate, userName, oldSnapshot.getCellRevision(cell.getId()));                if (goodSpacingDRCCells != null && goodSpacingDRCCells.contains(cell)) {                    cell.addVar(goodSpacingDRCDate);                    cell.addVar(goodSpacingDRCBit);                }                if (goodAreaDRCCells != null && goodAreaDRCCells.contains(cell)) {                    cell.addVar(goodAreaDRCDate);                }            }        }        EDatabase.serverDatabase().backup();        goodSpacingDRCCells = null;        goodAreaDRCCells = null;        oldSnapshot = null;	}	/**	 * Method to handle a change to a NodeInst.	 * @param ni the NodeInst that was changed.	 * @param oD the old contents of the NodeInst.	 */    @Override	public void modifyNodeInst(NodeInst ni, ImmutableNodeInst oD) {        if (doChangesQuietly) return;        getCellInfo(ni.getParent()).modifyNodeInst(ni, oD);    }	/**	 * Method to handle a change to an ArcInst.	 * @param ai the ArcInst that changed.     * @param oD the old contents of the ArcInst.	 */    @Override	public void modifyArcInst(ArcInst ai, ImmutableArcInst oD) {        if (doChangesQuietly) return;        getCellInfo(ai.getParent()).modifyArcInst(ai, oD);    }	/**	 * Method to handle a change to an Export.	 * @param pp the Export that moved.	 * @param oldD the old contents of the Export.	 */    @Override	public void modifyExport(Export pp, ImmutableExport oldD) {        if (doChangesQuietly) return;        PortInst oldPi = pp.getParent().getPortInst(oldD.originalNodeId, oldD.originalPortId);        if (oldPi == pp.getOriginalPort()) return;        getCellInfo(pp.getParent()).modifyExport(pp, oldPi);    }	/**	 * Method to handle a change to a Cell.	 * @param cell the Cell that was changed.	 * @param oD the old contents of the Cell.	 */    @Override	public void modifyCell(Cell cell, ImmutableCell oD) {}	/**	 * Method to handle a change to a Library.	 * @param lib the Library that was changed.	 * @param oldD the old contents of the Library.	 */    @Override	public void modifyLibrary(Library lib, ImmutableLibrary oldD) {}	/**	 * Method to handle the creation of a new ElectricObject.	 * @param obj the ElectricObject that was just created.	 */    @Override	public void newObject(ElectricObject obj) {        if (doChangesQuietly) return;        Cell cell = obj.whichCell();        if (obj == cell)            newCellInfo(cell, null);        else if (cell != null)            getCellInfo(cell).newObject(obj);	}    /**     * Method to announce than Ids were renamed.     * @param idMapper mapper from old Ids to new Ids.     */    @Override    public void renameIds(IdMapper idMapper) {        EDatabase database = EDatabase.serverDatabase();        for (CellId cellId: idMapper.getNewCellIds())            newObject(cellId.inDatabase(database));//        for (ExportId exportId: idMapper.getNewExportIds())//            newObject(exportId.inDatabase(database));    }	/**	 * Method to set temporary rigidity on an ArcInst.	 * @param ai the ArcInst to make temporarily rigid/not-rigid.	 * @param tempRigid true to make the ArcInst temporarily rigid;	 * false to make it temporarily not-rigid.	 */	public static void setTempRigid(ArcInst ai, boolean tempRigid)	{        if (DEBUG) System.out.println("setTempRigid " + ai + " " + tempRigid);        ai.checkChanging();        Layout.tempRigid.put(ai, Boolean.valueOf(tempRigid));//		if (tempRigid)//		{//			if (ai.getChangeClock() == changeClock + 2) return;//			ai.setChangeClock(changeClock + 2);//		} else//		{//			if (ai.getChangeClock() == changeClock + 3) return;//			ai.setChangeClock(changeClock + 3);//		}	}	/**	 * Method to remove temporary rigidity on an ArcInst.	 * @param ai the ArcInst to remove temporarily rigidity.	 */	public static void removeTempRigid(ArcInst ai)	{        ai.checkChanging();        tempRigid.remove(ai);//		if (ai.getChangeClock() != changeClock + 3 && ai.getChangeClock() != changeClock + 2) return;//		ai.setChangeClock(changeClock - 3);	}    /*     * Method to request to set     */    public static void setGoodDRCCells(Set<Cell> goodDRCCells, Variable.Key key, int activeBits, boolean inMemory)    {        assert(!inMemory); // call only if you are storing in disk        if (key == DRC_LAST_GOOD_DATE_SPACING)        {            Layout.goodSpacingDRCCells = goodDRCCells;            TextDescriptor td = TextDescriptor.getCellTextDescriptor().withDisplay(false);            goodSpacingDRCBit = Variable.newInstance(DRC_LAST_GOOD_BIT_SPACING, new Integer(activeBits), td);        }        else // min area        {            Layout.goodAreaDRCCells = goodDRCCells;        }    }    /**     ** Returns rigidity of an ArcInst considering temporary rigidity.     * @param ai ArcInst to test rigidity.     * @return true if the ArcInst is considered rigid in this batch.     */    static boolean isRigid(ArcInst ai) {        Boolean override = tempRigid.get(ai);        return override != null ? override.booleanValue() : ai.isRigid();    }    private static void makeLayoutCells() {        cellInfos.clear();		for(Iterator<Library> it = Library.getLibraries(); it.hasNext(); )		{			Library lib = it.next();			for(Iterator<Cell> cIt = lib.getCells(); cIt.hasNext(); )			{				Cell cell = cIt.next();                newCellInfo(cell, oldSnapshot.getCell(cell.getId()));			}		}    }	/******************** NODE MODIFICATION CODE *************************/	/**	 * Method to compute the position of portinst "pi" and	 * place the center of the area in the parameters "x" and "y".  The position	 * is the "old" position, as determined by any changes that may have occured	 * to the nodeinst (and any sub-nodes).	 */	static Poly oldPortPosition(PortInst pi)	{        NodeInst ni = pi.getNodeInst();        PortProto pp = pi.getPortProto();		// descend to the primitive node		AffineTransform subrot = makeOldRot(ni);        if (subrot == null) return null;		NodeInst bottomNi = ni;		PortProto bottomPP = pp;		while (bottomNi.isCellInstance())		{			AffineTransform localtran = makeOldTrans(bottomNi);			subrot.concatenate(localtran);            PortInst bottomPi = getOldOriginalPort((Export)bottomPP);			bottomNi = bottomPi.getNodeInst();			bottomPP = bottomPi.getPortProto();			localtran = makeOldRot(bottomNi);			subrot.concatenate(localtran);		}		// if the node hasn't changed, use its current values        ImmutableNodeInst d = Layout.getOldD(bottomNi);        assert d != null;        if (d != bottomNi.getD()) {			// create a fake node with these values            bottomNi = NodeInst.makeDummyInstance(bottomNi.getProto());            bottomNi.lowLevelModify(d);		}		PrimitiveNode np = (PrimitiveNode)bottomNi.getProto();		Technology tech = np.getTechnology();		Poly poly = tech.getShapeOfPort(bottomNi, (PrimitivePort)bottomPP);		poly.transform(subrot);		return (poly);	}	private static AffineTransform makeOldRot(NodeInst ni)	{		// if the node has not been modified, just use the current transformation        ImmutableNodeInst d = getOldD(ni);        if (d == null) return null;		// get the old values        double cX = d.anchor.getX();        double cY = d.anchor.getY();        return d.orient.rotateAbout(cX, cY);	}	private static AffineTransform makeOldTrans(NodeInst ni)	{        ImmutableNodeInst d = getOldD(ni);        if (d == null) return null;		// create the former translation matrix		AffineTransform transform = new AffineTransform();        double cX = d.anchor.getX();        double cY = d.anchor.getY();		transform.translate(cX, cY);		return transform;	}    static PortInst getOldOriginalPort(Export e) {        return getCellInfo(e.getParent()).getOldOriginalPort(e);    }    static ImmutableNodeInst getOldD(NodeInst ni) {        return getCellInfo(ni.getParent()).getOldD(ni);    }    private static void newCellInfo(Cell cell, CellBackup oldBackup) {        int cellIndex = cell.getCellIndex();        while (cellInfos.size() <= cellIndex) cellInfos.add(null);//        assert cellInfos.get(cellIndex) == null;        cellInfos.set(cellIndex, new LayoutCell(cell, oldBackup));    }    static LayoutCell getCellInfo(Cell cell) {        return cellInfos.get(cell.getCellIndex());    }}

⌨️ 快捷键说明

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