📄 elib.java
字号:
/* -*- tab-width: 4 -*- * * Electric(tm) VLSI Design System * * File: ELIB.java * Input/output tool: ELIB Library output * 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.io.output;import com.sun.electric.database.CellBackup;import com.sun.electric.database.CellRevision;import com.sun.electric.database.ImmutableArcInst;import com.sun.electric.database.ImmutableCell;import com.sun.electric.database.ImmutableElectricObject;import com.sun.electric.database.ImmutableExport;import com.sun.electric.database.ImmutableIconInst;import com.sun.electric.database.ImmutableLibrary;import com.sun.electric.database.ImmutableNodeInst;import com.sun.electric.database.ImmutablePortInst;import com.sun.electric.database.LibraryBackup;import com.sun.electric.database.Snapshot;import com.sun.electric.database.geometry.DBMath;import com.sun.electric.database.geometry.EPoint;import com.sun.electric.database.geometry.ERectangle;import com.sun.electric.database.geometry.Orientation;import com.sun.electric.database.hierarchy.Library;import com.sun.electric.database.hierarchy.View;import com.sun.electric.database.id.ArcProtoId;import com.sun.electric.database.id.CellId;import com.sun.electric.database.id.ExportId;import com.sun.electric.database.id.IdManager;import com.sun.electric.database.id.LibId;import com.sun.electric.database.id.NodeProtoId;import com.sun.electric.database.id.PortProtoId;import com.sun.electric.database.id.PrimitiveNodeId;import com.sun.electric.database.id.TechId;import com.sun.electric.database.prototype.PortProto;import com.sun.electric.database.text.CellName;import com.sun.electric.database.text.Setting;import com.sun.electric.database.text.TextUtils;import com.sun.electric.database.text.Version;import com.sun.electric.database.topology.ArcInst;import com.sun.electric.database.topology.NodeInst;import com.sun.electric.database.variable.CodeExpression;import com.sun.electric.database.variable.TextDescriptor;import com.sun.electric.database.variable.Variable;import com.sun.electric.technology.ArcProto;import com.sun.electric.technology.PrimitiveNode;import com.sun.electric.technology.PrimitivePort;import com.sun.electric.technology.TechPool;import com.sun.electric.technology.Technology;import com.sun.electric.technology.technologies.Generic;import com.sun.electric.tool.Job;import com.sun.electric.tool.Tool;import com.sun.electric.tool.io.ELIBConstants;import java.awt.geom.Rectangle2D;import java.io.IOException;import java.net.URL;import java.util.ArrayList;import java.util.Collection;import java.util.HashMap;import java.util.Iterator;import java.util.LinkedHashMap;import java.util.List;import java.util.Map;import java.util.TreeMap;import java.util.TreeSet;/** * This class writes files in binary (.elib) format. */public class ELIB extends Output{ /** Snapshot being saved. */ Snapshot snapshot; /** IdManager of Snapshot being saved. */ IdManager idManager; /** TechPool of Snapshot being saved. */ TechPool techPool; /** Library being saved. */ LibId theLibId; /** Map of referenced objects for library files */ HashMap<Object,Integer> objInfo; /** List of referenced Technologies */ final ArrayList<Technology> technologies = new ArrayList<Technology>(); /** Maps memory face index to disk face index */ private int[] faceMap = new int[TextDescriptor.ActiveFont.getMaxIndex() + 1]; /** Name space of variable names */ private TreeMap<String,Short> nameSpace; /** Scale for irrelevant technologies. */ private double irrelevantScale; /** map with "next in cell group" pointers */ private HashMap<CellId,CellId> cellInSameGroup = new HashMap<CellId,CellId>(); /** true to write a 6.XX compatible library (MAGIC11) */ private boolean compatibleWith6; /** map to assign indices to cell names (for 6.XX) */ private TreeMap<String,Integer> cellIndexMap = new TreeMap<String,Integer>(TextUtils.STRING_NUMBER_ORDER); /** Project settings. */ private HashMap<Setting,Object> projectSettings = new HashMap<Setting,Object>(); /** size correctors for technologies */ private HashMap<TechId,Technology.SizeCorrector> sizeCorrectors = new HashMap<TechId,Technology.SizeCorrector>(); /** Topological sort of cells in library to be written */ private LinkedHashMap<CellId,Integer> cellOrdering = new LinkedHashMap<CellId,Integer>(); /** Map from nodeId to nodeIndex for current Cell. */ int[] nodeIndexByNodeId; ArrayList<CellRevision> localCells = new ArrayList<CellRevision>(); ArrayList<CellRevision> externalCells = new ArrayList<CellRevision>(); int nodeIndex = 0; int portProtoIndex = 0; int nodeProtoIndex = 0; int arcIndex = 0; int primNodeProtoIndex = 0; int primPortProtoIndex = 0; int arcProtoIndex = 0; int toolCount = 0; int[] primNodeCounts; int[] primArcCounts; int[] groupRenumber; ELIB() { } public void write6Compatible() { compatibleWith6 = true; } // ----------------------- public methods ------------------------------- /** * Method to write a Library in binary (.elib) format. * @param snapshot Snapshot to be written * @param theLibId the Library to be written. */ protected boolean writeLib(Snapshot snapshot, LibId theLibId) { this.snapshot = snapshot; idManager = snapshot.idManager; techPool = snapshot.techPool; this.theLibId = theLibId; // Gather objects referenced from Cells objInfo = new HashMap<Object,Integer>(); nameSpace = new TreeMap<String,Short>(TextUtils.STRING_NUMBER_ORDER); for (CellBackup cellBackup: snapshot.cellBackups) { if (cellBackup == null) continue; CellRevision cellRevision = cellBackup.cellRevision; CellId cellId = cellRevision.d.cellId; if (cellId.libId != theLibId) continue; gatherCell(cellRevision.d.cellId); for (ImmutableNodeInst n: cellRevision.nodes) { NodeProtoId np = n.protoId; if (np instanceof CellId) { gatherCell((CellId)np); } else { gatherObj(np); gatherTech(((PrimitiveNodeId)np).techId); } if (n.hasPortInstVariables()) { for (Iterator<PortProtoId> it = n.getPortsWithVariables(); it.hasNext(); ) { PortProtoId portId = it.next(); gatherVariables(portId.getName(snapshot), n.getPortInst(portId)); } } gatherVariables(null, n); gatherFont(n.nameDescriptor); gatherFont(n.protoDescriptor); } for (ImmutableArcInst a: cellRevision.arcs) { ArcProtoId apId = a.protoId; gatherObj(apId); gatherTech(apId.techId); //gatherObj(ai.getHead().getPortInst().getPortProto()); //gatherObj(ai.getTail().getPortInst().getPortProto()); gatherVariables(null, a); gatherFont(a.nameDescriptor); } for (ImmutableExport e: cellRevision.exports) { //gatherObj(e.getOriginalPort().getPortProto()); gatherVariables(null, e); gatherFont(e.nameDescriptor); } gatherVariables(null, cellRevision.d); } gatherVariables(null, snapshot.getLib(theLibId).d); // Gather objects refetenced from preferences for (Iterator<Tool> it = Tool.getTools(); it.hasNext(); ) gatherSettings(it.next()); for (Iterator<Technology> it = Technology.getTechnologies(); it.hasNext(); ) { Technology tech = it.next(); TechId techId = tech.getId(); if (!objInfo.containsKey(techId)) continue; technologies.add(tech); gatherSettings(tech); } putNameSpace(Library.FONT_ASSOCIATIONS.getName()); putNameSpace(NodeInst.NODE_NAME.getName()); putNameSpace(ArcInst.ARC_NAME.getName()); short varIndex = 0; for (Map.Entry<String,Short> e : nameSpace.entrySet()) { e.setValue(new Short(varIndex++)); } // make sure all technologies with irrelevant scale information have the same scale value for(Technology tech: technologies) { if (tech.isScaleRelevant()) continue; if (tech == Generic.tech()) continue; irrelevantScale = Math.max(irrelevantScale, tech.getScale()); } // Sort CellIds TreeMap<String,LibId> sortedLibIds = new TreeMap<String,LibId>(TextUtils.STRING_NUMBER_ORDER); HashMap<LibId,TreeMap<CellName,CellId>> sortedCellIds = new HashMap<LibId,TreeMap<CellName,CellId>>(); for (CellBackup cellBackup: snapshot.cellBackups) { if (cellBackup == null) continue; CellId cellId = cellBackup.cellRevision.d.cellId; if (!objInfo.containsKey(cellId)) continue; LibId libId = cellId.libId; sortedLibIds.put(libId.libName, libId); TreeMap<CellName,CellId> sortedCellIdsInLibrary = sortedCellIds.get(libId); if (sortedCellIdsInLibrary == null) { sortedCellIdsInLibrary = new TreeMap<CellName,CellId>(); sortedCellIds.put(libId, sortedCellIdsInLibrary); } sortedCellIdsInLibrary.put(cellId.cellName, cellId); } for (CellId cellId: sortedCellIds.get(theLibId).values()) localCells.add(snapshot.getCellRevision(cellId)); // count and number the cells, nodes, arcs, and ports in this library int maxGroup = -1; ArrayList<TreeMap<CellName,CellId>> cellGroups_ = new ArrayList<TreeMap<CellName,CellId>>(); for (CellRevision cellRevision: localCells) maxGroup = Math.max(maxGroup, snapshot.cellGroups[cellRevision.d.cellId.cellIndex]); groupRenumber = new int[maxGroup + 1]; for(CellRevision cellRevision: localCells) { CellId cellId = cellRevision.d.cellId; cellOrdering.put(cellId, new Integer(nodeProtoIndex)); putObjIndex(cellId, nodeProtoIndex++); for (ImmutableExport e: cellRevision.exports) putObjIndex(e.exportId, portProtoIndex++); nodeIndex += cellRevision.nodes.size(); arcIndex += cellRevision.arcs.size(); int snapshotGroup = snapshot.cellGroups[cellId.cellIndex]; int elibGroup = groupRenumber[snapshotGroup]; if (elibGroup == 0) { cellGroups_.add(new TreeMap<CellName,CellId>()); elibGroup = cellGroups_.size(); groupRenumber[snapshotGroup] = elibGroup; } cellGroups_.get(elibGroup - 1).put(cellId.cellName, cellId); // gather proto name if creating version-6-compatible output if (compatibleWith6) { String protoName = cellId.cellName.getName(); if (!cellIndexMap.containsKey(protoName)) cellIndexMap.put(protoName, null); } } for (int i = 0; i < cellGroups_.size(); i++) { TreeMap<CellName,CellId> cellGroup_ = cellGroups_.get(i); Iterator<CellId> git = cellGroup_.values().iterator(); CellId firstCellInGroup = git.next(); CellId lastCellInGroup = firstCellInGroup; while (git.hasNext()) { CellId cellInGroup = git.next();// assert cellInSameGroup.get(lastCellInGroup) == cellInGroup; cellInSameGroup.put(lastCellInGroup, cellInGroup); lastCellInGroup = cellInGroup; }// assert cellInSameGroup.get(lastCellInGroup) == firstCellInGroup; cellInSameGroup.put(lastCellInGroup, firstCellInGroup); } // count and number the cells in other libraries for (LibId libId: sortedLibIds.values()) { if (libId == theLibId) continue; for (CellId cellId: sortedCellIds.get(libId).values()) { assert objInfo.containsKey(cellId); CellRevision cellRevision = snapshot.getCellRevision(cellId); externalCells.add(cellRevision); putObjIndex(cellId, nodeProtoIndex++); for (ImmutableExport e: cellRevision.exports) putObjIndex(e.exportId, portProtoIndex++); // gather proto name if creating version-6-compatible output if (compatibleWith6) { String protoName = cellId.cellName.getName(); if (!cellIndexMap.containsKey(protoName)) cellIndexMap.put(protoName, null); } } } // count the number of primitives primNodeCounts = new int[technologies.size()]; primArcCounts = new int[technologies.size()]; for (int techCount = 0; techCount < technologies.size(); techCount++) { Technology tech = technologies.get(techCount); TechId techId = tech.getId(); putObjIndex(techId, techCount); int primNodeStart = primNodeProtoIndex; for (Iterator<PrimitiveNode> nit = tech.getNodes(); nit.hasNext(); ) { PrimitiveNode np = nit.next(); if (!objInfo.containsKey(np.getId())) continue; putObjIndex(np.getId(), -2 - primNodeProtoIndex++); for (Iterator<PortProto> pit = np.getPorts(); pit.hasNext(); ) { PrimitivePort pp = (PrimitivePort)pit.next(); putObjIndex(pp.getId(), -2 - primPortProtoIndex++); } } primNodeCounts[techCount] = primNodeProtoIndex - primNodeStart; int primArcStart = arcProtoIndex; for(Iterator<ArcProto> ait = tech.getArcs(); ait.hasNext(); ) { ArcProtoId apId = ait.next().getId(); if (!objInfo.containsKey(apId)) continue; putObjIndex(apId, -2 - arcProtoIndex++); } primArcCounts[techCount] = arcProtoIndex - primArcStart; } // count the number of tools for (Iterator<Tool> it = Tool.getTools(); it.hasNext(); ) { Tool tool = it.next(); if (!objInfo.containsKey(tool)) continue; toolCount++; } try { return writeTheLibrary(); } catch (IOException e) { System.out.println("End of file reached while writing " + filePath); return true; } } /** * Method to write the .elib file. * Returns true on error. */ boolean writeTheLibrary() throws IOException { // write the header int magic = ELIBConstants.MAGIC13; if (compatibleWith6) magic = ELIBConstants.MAGIC11; writeBigInteger(magic); writeByte((byte)2); // size of Short writeByte((byte)4); // size of Int writeByte((byte)1); // size of Char // write number of objects writeBigInteger(toolCount); writeBigInteger(technologies.size()); writeBigInteger(primNodeProtoIndex); writeBigInteger(primPortProtoIndex); writeBigInteger(arcProtoIndex); writeBigInteger(nodeProtoIndex); writeBigInteger(nodeIndex); writeBigInteger(portProtoIndex); writeBigInteger(arcIndex); writeBigInteger(0); // write count of cells if creating version-6-compatible output int cellCount = 0; if (compatibleWith6) { for(Map.Entry<String,Integer> e : cellIndexMap.entrySet()) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -