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

📄 fpga.java

📁 The ElectricTM VLSI Design System is an open-source Electronic Design Automation (EDA) system that c
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
/* -*- tab-width: 4 -*- * * Electric(tm) VLSI Design System * * File: FPGA.java * FPGA, a customizable technology. * Written by Steven M. Rubin * * Copyright (c) 2005 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.technology.technologies;import com.sun.electric.database.ImmutableArcInst;import com.sun.electric.database.geometry.EGraphics;import com.sun.electric.database.geometry.EPoint;import com.sun.electric.database.geometry.ERectangle;import com.sun.electric.database.geometry.GenMath;import com.sun.electric.database.geometry.Orientation;import com.sun.electric.database.geometry.Poly;import com.sun.electric.database.hierarchy.Cell;import com.sun.electric.database.hierarchy.Export;import com.sun.electric.database.hierarchy.Library;import com.sun.electric.database.hierarchy.Nodable;import com.sun.electric.database.network.Netlist;import com.sun.electric.database.network.Network;import com.sun.electric.database.prototype.NodeProto;import com.sun.electric.database.prototype.PortCharacteristic;import com.sun.electric.database.prototype.PortProto;import com.sun.electric.database.text.TextUtils;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.topology.RTBounds;import com.sun.electric.database.variable.EditWindow0;import com.sun.electric.database.variable.EditWindow_;import com.sun.electric.database.variable.ElectricObject;import com.sun.electric.database.variable.TextDescriptor;import com.sun.electric.database.variable.UserInterface;import com.sun.electric.database.variable.VarContext;import com.sun.electric.database.variable.Variable;import com.sun.electric.technology.AbstractShapeBuilder;import com.sun.electric.technology.ArcProto;import com.sun.electric.technology.EdgeH;import com.sun.electric.technology.EdgeV;import com.sun.electric.technology.Foundry;import com.sun.electric.technology.Layer;import com.sun.electric.technology.PrimitiveNode;import com.sun.electric.technology.PrimitivePort;import com.sun.electric.technology.Technology;import com.sun.electric.tool.Job;import com.sun.electric.tool.JobException;import com.sun.electric.tool.io.FileType;import com.sun.electric.tool.user.User;import com.sun.electric.tool.user.dialogs.OpenFile;import com.sun.electric.tool.user.dialogs.PromptAt;import java.awt.geom.Point2D;import java.awt.geom.Rectangle2D;import java.io.IOException;import java.io.InputStreamReader;import java.io.LineNumberReader;import java.net.URL;import java.net.URLConnection;import java.util.ArrayList;import java.util.Iterator;import java.util.List;/** * This is the FPGA Technology. */public class FPGA extends Technology{	/** the FPGA Technology object. */	public static FPGA tech() { return sysFPGA; }	private final Layer wireLayer, componentLayer, pipLayer, repeaterLayer;	private final ArcProto wireArc;	private final PrimitiveNode wirePinNode, pipNode, repeaterNode;	public FPGA(Generic generic)	{		super(generic, "fpga", Foundry.Type.NONE, 1);		setTechShortName("FPGA");		setTechDesc("FPGA Building-Blocks");		setFactoryScale(2000, true);   // in nanometers: really 2 microns		setStaticTechnology();		setNonStandard();		setNoPrimitiveNodes();		//**************************************** LAYERS ****************************************		/** Wire layer */		wireLayer = Layer.newInstance(this, "Wire",			new EGraphics(false, false, null, 0, 255,0,0,1,true,			new int[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}));		/** Component layer */		componentLayer = Layer.newInstance(this, "Component",			new EGraphics(false, false, null, 0, 0,0,0,1,true,			new int[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}));		/** Pip layer */		pipLayer = Layer.newInstance(this, "Pip",			new EGraphics(false, false, null, 0, 0,255,0,1,true,			new int[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}));		/** Repeater layer */		repeaterLayer = Layer.newInstance(this, "Repeater",			new EGraphics(false, false, null, 0, 0,0,255,1,true,			new int[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}));		// The layer functions		wireLayer.setFunction(Layer.Function.METAL1);		// wire		componentLayer.setFunction(Layer.Function.ART);		// component		pipLayer.setFunction(Layer.Function.ART);			// pip		repeaterLayer.setFunction(Layer.Function.ART);		// repeater		//**************************************** ARC ****************************************		/** wire arc */		wireArc = newArcProto("wire", 0, 0.0, ArcProto.Function.METAL1,			new Technology.ArcLayer(wireLayer, 0, Poly.Type.FILLED)		);		wireArc.setFactoryFixedAngle(true);		wireArc.setFactorySlidable(false);		wireArc.setFactoryAngleIncrement(45);		//**************************************** NODES ****************************************		/** wire pin */		wirePinNode = PrimitiveNode.newInstance("Wire_Pin", this, 1, 1, null,			new Technology.NodeLayer []			{				new Technology.NodeLayer(wireLayer, 0, Poly.Type.DISC, Technology.NodeLayer.POINTS, new Technology.TechPoint [] {					new Technology.TechPoint(EdgeH.makeCenter(), EdgeV.makeCenter()),					new Technology.TechPoint(EdgeH.makeRightEdge(), EdgeV.makeCenter())})			});		wirePinNode.addPrimitivePorts(new PrimitivePort []			{				PrimitivePort.newInstance(this, wirePinNode, new ArcProto[] {wireArc}, "wire", 0,180, 0, PortCharacteristic.UNKNOWN,					EdgeH.makeCenter(), EdgeV.makeCenter(), EdgeH.makeCenter(), EdgeV.makeCenter())			});		wirePinNode.setFunction(PrimitiveNode.Function.PIN);		wirePinNode.setSquare();		wirePinNode.setWipeOn1or2();		/** pip */		pipNode = PrimitiveNode.newInstance("Pip", this, 2, 2, null,			new Technology.NodeLayer []			{				new Technology.NodeLayer(pipLayer, 0, Poly.Type.FILLED, Technology.NodeLayer.BOX, new Technology.TechPoint [] {					new Technology.TechPoint(EdgeH.makeLeftEdge(), EdgeV.makeBottomEdge()),					new Technology.TechPoint(EdgeH.makeRightEdge(), EdgeV.makeTopEdge())})			});		pipNode.addPrimitivePorts(new PrimitivePort []			{				PrimitivePort.newInstance(this, pipNode, new ArcProto[] {wireArc}, "pip", 0,180, 0, PortCharacteristic.UNKNOWN,					EdgeH.makeCenter(), EdgeV.makeCenter(), EdgeH.makeCenter(), EdgeV.makeCenter())			});		pipNode.setFunction(PrimitiveNode.Function.CONNECT);		pipNode.setSquare();		/** repeater */		repeaterNode = PrimitiveNode.newInstance("Repeater", this, 10, 3, null,			new Technology.NodeLayer []			{				new Technology.NodeLayer(repeaterLayer, 0, Poly.Type.FILLED, Technology.NodeLayer.BOX, new Technology.TechPoint [] {					new Technology.TechPoint(EdgeH.makeLeftEdge(), EdgeV.makeBottomEdge()),					new Technology.TechPoint(EdgeH.makeRightEdge(), EdgeV.makeTopEdge())})			});		repeaterNode.addPrimitivePorts(new PrimitivePort []			{				PrimitivePort.newInstance(this, repeaterNode, new ArcProto[] {wireArc}, "a", 180,45, 0, PortCharacteristic.UNKNOWN,					EdgeH.makeLeftEdge(), EdgeV.makeCenter(), EdgeH.makeLeftEdge(), EdgeV.makeCenter()),				PrimitivePort.newInstance(this, repeaterNode, new ArcProto[] {wireArc}, "b", 0,45, 1, PortCharacteristic.UNKNOWN,					EdgeH.makeRightEdge(), EdgeV.makeCenter(), EdgeH.makeRightEdge(), EdgeV.makeCenter())			});		repeaterNode.setFunction(PrimitiveNode.Function.CONNECT);		// Building information for palette		nodeGroups = new Object[7][1];		int count = 0;		nodeGroups[count++][0] = wireArc;		nodeGroups[count++][0] = Technology.SPECIALMENUCELL;		nodeGroups[count++][0] = Technology.SPECIALMENUMISC;		nodeGroups[count++][0] = Technology.SPECIALMENUPURE;		nodeGroups[count++][0] = wirePinNode;		nodeGroups[count++][0] = pipNode;		nodeGroups[count++][0] = repeaterNode;		// Foundry		newFoundry(Foundry.Type.NONE, null);	}	/******************** TREE STRUCTURE FOR ARCHITECTURE FILE ********************/	/** max depth of FPGA nesting */	private static final int MAXDEPTH = 50;	private static class LispTree	{		private String keyword;		private int lineNumber;		private List<Object> values;		LispTree()		{			values = new ArrayList<Object>();		}		void add(Object obj) { values.add(obj); }		int size() { return values.size(); }		boolean isLeaf(int i) { return !(values.get(i) instanceof LispTree); }		boolean isBranch(int i) { return values.get(i) instanceof LispTree; }		String getLeaf(int i) { return (String)values.get(i); }		LispTree getBranch(int i) { return (LispTree)values.get(i); }	};	private static LispTree [] treeStack = new LispTree[MAXDEPTH];	private static int         treeDepth;	private static LispTree    treePosition;	/******************** ADDITIONAL INFORMATION ABOUT PRIMITIVES ********************/	/** level of display */						private static final int DISPLAYLEVEL       =  07;	/**   display no internals */				private static final int NOPRIMDISPLAY      =   0;	/**   display all internals */				private static final int FULLPRIMDISPLAY    =  01;	/**   display only active internals */		private static final int ACTIVEPRIMDISPLAY  =  02;	/** set to display text */					private static final int TEXTDISPLAY        = 010;	/** set if segment or pip is active */		private static final int ACTIVEPART = 1;	/** saved area for segment/pip activity */	private static final int ACTIVESAVE = 2;	private static class FPGAPort	{		String             name;		double             posX, posY;		int                con;		PortCharacteristic characteristic;		PrimitivePort      pp;	};	private static class FPGANet	{		String     name;		int        segActive;		Point2D [] segFrom;		Point2D [] segTo;	};	private static class FPGAPip	{		String  name;		int     pipActive;		int     con1, con2;		double  posX, posY;	};	private static class FPGANode extends PrimitiveNode	{		FPGAPort [] portList;		FPGANet  [] netList;		FPGAPip  [] pipList;		protected FPGANode(String protoName, Technology tech, double defWidth, double defHeight,			Technology.NodeLayer [] layers)		{			super(protoName, tech, EPoint.ORIGIN, EPoint.ORIGIN, null, defWidth, defHeight,				ERectangle.ORIGIN, ERectangle.ORIGIN, layers);		}		int numPorts()		{			if (portList == null) return 0;			return portList.length;		}		int numNets()		{			if (netList == null) return 0;			return netList.length;		}		int numPips()		{			if (pipList == null) return 0;			return pipList.length;		}	};	/** key of Variable holding active pips. */				private static final Variable.Key ACTIVEPIPS_KEY = Variable.newKey("FPGA_activepips");	/** key of Variable holding active repeaters. */		private static final Variable.Key ACTIVEREPEATERS_KEY = Variable.newKey("FPGA_activerepeaters");//	/** key of Variable holding cache of pips on node. */	private static final Variable.Key NODEPIPCACHE_KEY = Variable.newKey("FPGA_nodepipcache");//	/** key of Variable holding cache of active arcs. */	private static final Variable.Key ARCACTIVECACHE_KEY = Variable.newKey("FPGA_arcactivecache");	/** name of current repeater for activity examining */	private String         repeaterName;	/** nonzero if current repeater is found to be active */private boolean        repeaterActive;	/** what is being displayed */							private int            internalDisplay = FULLPRIMDISPLAY | TEXTDISPLAY;	/** whether the technology has been read */				private boolean        defined = false;	private static final Technology.NodeLayer[] NULLNODELAYER = new Technology.NodeLayer[0];	/**	 * Method to return a list of Polys that describe a given NodeInst.	 * This method overrides the general one in the Technology object	 * because of the unusual primitives in this Technology.	 * @param ni the NodeInst to describe.	 * @param electrical true to get the "electrical" layers.	 * This makes no sense for Schematics primitives.	 * @param reasonable true to get only a minimal set of contact cuts in large contacts.	 * This makes no sense for Schematics primitives.	 * @param primLayers an array of NodeLayer objects to convert to Poly objects.	 * @param layerOverride the layer to use for all generated polygons (if not null).	 * @return an array of Poly objects.	 */	@Override	protected Poly [] getShapeOfNode(NodeInst ni, boolean electrical, boolean reasonable, Technology.NodeLayer [] primLayers, Layer layerOverride) {		return getShapeOfNode(ni, null, null, electrical, reasonable, primLayers, layerOverride);	}	/**	 * Method to return a list of Polys that describe a given NodeInst.	 * This method overrides the general one in the Technology object	 * because of the unusual primitives in this Technology.	 * @param ni the NodeInst to describe.	 * @param wnd the window in which this node will be drawn.	 * @param context the VarContext to this node in the hierarchy.	 * @param electrical true to get the "electrical" layers.	 * This makes no sense for Schematics primitives.	 * @param reasonable true to get only a minimal set of contact cuts in large contacts.	 * This makes no sense for Schematics primitives.	 * @param primLayers an array of NodeLayer objects to convert to Poly objects.	 * @param layerOverride the layer to use for all generated polygons (if not null).	 * @return an array of Poly objects.	 */	private Poly [] getShapeOfNode(NodeInst ni, EditWindow0 wnd, VarContext context, boolean electrical, boolean reasonable, Technology.NodeLayer [] primLayers, Layer layerOverride)	{		if (ni.isCellInstance()) return null;		PrimitiveNode np = (PrimitiveNode)ni.getProto();		if (np == wirePinNode)		{			if (ni.pinUseCount()) primLayers = NULLNODELAYER;		} else if (np == repeaterNode)		{			if ((internalDisplay&DISPLAYLEVEL) == ACTIVEPRIMDISPLAY)			{				if (!repeaterActive(ni)) primLayers = NULLNODELAYER;			}		} else if (np instanceof FPGANode)		{			// dynamic primitive			FPGANode fn = (FPGANode)np;			// hard reset of all segment and pip activity			int numPips = 0, numSegs = 0;			for(int i=0; i<fn.numNets(); i++) fn.netList[i].segActive = 0;			for(int i=0; i<fn.numPips(); i++) fn.pipList[i].pipActive = 0;			switch (internalDisplay & DISPLAYLEVEL)			{				case NOPRIMDISPLAY:					break;				case ACTIVEPRIMDISPLAY:					// count number of active nets and pips					// determine the active segments and pips					reEvaluatePips(ni, fn, context);					// save the activity bits					for(int i=0; i<fn.numNets(); i++)						if ((fn.netList[i].segActive&ACTIVEPART) != 0)							fn.netList[i].segActive |= ACTIVESAVE;					for(int i=0; i<fn.numPips(); i++)						if ((fn.pipList[i].pipActive&ACTIVEPART) != 0)							fn.pipList[i].pipActive |= ACTIVESAVE;					// propagate inactive segments to others that may be active					if (context != null && context.getNodable() != null)					{						VarContext higher = context.pop();						for(int i=0; i<fn.numNets(); i++)						{							if ((fn.netList[i].segActive&ACTIVESAVE) != 0) continue;							boolean found = false;							for(int j=0; j<fn.numPorts(); j++)							{								if (fn.portList[j].con != i) continue;								for(Iterator<Connection> it = ni.getConnections(); it.hasNext(); )								{									Connection con = it.next();									if (con.getPortInst().getPortProto() != fn.portList[j].pp) continue;									ArcInst ai = con.getArc();									int otherEnd = 1 - con.getEndIndex();									if (arcEndActive(ai, otherEnd, higher)) { found = true;   break; }								}								if (found) break;							}							if (found) fn.netList[i].segActive |= ACTIVESAVE;						}					}					// add up the active segments					for(int i=0; i<fn.numPips(); i++)						if ((fn.pipList[i].pipActive&ACTIVESAVE) != 0) numPips++;					for(int i=0; i<fn.numNets(); i++)						if ((fn.netList[i].segActive&ACTIVESAVE) != 0)							numSegs += fn.netList[i].segFrom.length;					break;				case FULLPRIMDISPLAY:					for(int i=0; i<fn.numNets(); i++)					{						fn.netList[i].segActive |= ACTIVESAVE;

⌨️ 快捷键说明

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