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

📄 decode.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: Decode.java * MOSIS CMOS PLA Generator. * Originally written by Wallace Kroeker at the University of Calgary * Translated to Java by Steven Rubin, Sun Microsystems. * * 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.tool.generator.cmosPLA;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.prototype.PortProto;import com.sun.electric.database.topology.NodeInst;import com.sun.electric.database.variable.Variable;import java.awt.geom.Rectangle2D;/** * Class to generate the decoder part of MOSIS CMOS PLAs. */public class Decode{	private PLA pla;	Decode(PLA pla)	{		this.pla = pla;	}	Cell decodeGen(Library library, Cell pmosCell, Cell nmosCell, String cellName, boolean inputsOnTop)	{		Cell cell = Cell.makeInstance(library, cellName);		NodeInst pNode = pla.makeInstance(cell, pmosCell, 0, 0, false);		if (pNode == null) return null;		pNode.rotate(Orientation.RRR);  // rotate by 90 degrees		Rectangle2D nodeRect = pNode.getBounds();		double x = nodeRect.getWidth();		if (x < 0) x = -x;		x += 12; // SEPARATION		NodeInst nNode = pla.makeInstance(cell, nmosCell, x, 0, false);		if (nNode == null) return null;		nNode.rotate(Orientation.RRR);  // rotate by 90 degrees		NodeInst [] both = decodeBufs(pmosCell, pNode, nmosCell, nNode, cell, x, inputsOnTop);		if (both == null) return null;		if (decodeRoute(pmosCell, pNode, nmosCell, nNode, cell, both[0], both[1], inputsOnTop)) return null;		decExp(nmosCell, nNode, cell);		return cell;	}	private NodeInst [] decodeBufs(Cell pmosCell, NodeInst pNode, Cell nmosCell,		NodeInst nNode, Cell decodeCell, double X, boolean inputsOnTop)	{		NodeInst lastNode = null;		NodeInst newNode = null;		NodeInst firstPNode = null, lastPNode = null, lastNNode = null;		int rows = 2;		Variable var = pmosCell.getVar("PLA_access_rows");		if (var != null) rows = ((Integer)var.getObject()).intValue(); else			System.out.println("ACCESS_rows defaulting to 2");		Export pwrWPort = null, pwrEPort = null, gndWPort = null, gndEPort = null;		char side = 'w';		if (inputsOnTop) side = 'e';		Rectangle2D nodeBounds = pNode.getBounds();		double lowX = nodeBounds.getMinX();		double lowY = nodeBounds.getMinY();		double highY = nodeBounds.getMaxY();		Rectangle2D bufBounds = pla.decoderInv.getBounds();		double diff = bufBounds.getHeight();		if (diff < 0) diff = -diff;		int limit = rows / 4;		if (limit == 0 || (rows % 4) != 0) limit++;		int cnt = 0;		double y = highY;		if (inputsOnTop) y = lowY - diff;		y -= 13;		double xOffset = lowX - 38;		if ((rows %4) == 0) xOffset = lowX - 18;		pwrWPort = pla.decoderInv.findExport("PWR.m-2.w");		pwrEPort = pla.decoderInv.findExport("PWR.m-2.e");		gndWPort = pla.decoderInv.findExport("GND.m-2.w");		gndEPort = pla.decoderInv.findExport("GND.m-2.e");		for (int i = limit; i > 0; i--)		{			newNode = pla.makeInstance(decodeCell, pla.decoderInv, i*50 + xOffset, y, !inputsOnTop);			if (newNode == null) return(null);			NodeInst newNode2 = pla.makeInstance(decodeCell, pla.decoderInv, X + i*50 + xOffset, y, !inputsOnTop);			if (newNode2 == null) return(null);			if (lastPNode == null && lastNNode == null)			{				Export.newInstance(decodeCell, newNode2.findPortInstFromProto(pwrEPort), "PWR.m-2.e");				Export.newInstance(decodeCell, newNode2.findPortInstFromProto(gndEPort), "GND.m-2.e");				firstPNode = lastPNode = newNode;				lastNNode = lastNode = newNode2;			} else			{				// get wired				if (pwrWPort != null && pwrEPort != null)				{					pla.makeWire(pla.m2Arc, 14, lastPNode, pwrWPort, newNode, pwrEPort, decodeCell);					pla.makeWire(pla.m2Arc, 14, lastNNode, pwrWPort, newNode2, pwrEPort, decodeCell);				}				if (gndWPort != null && gndEPort != null)				{					pla.makeWire(pla.m2Arc, 14, lastNNode, gndWPort, newNode, gndEPort, decodeCell);					pla.makeWire(pla.m2Arc, 14, lastNNode, gndWPort, newNode2, gndEPort, decodeCell);				}				lastPNode = newNode;				lastNNode = newNode2;			}			for (int x = cnt; x < cnt+4; x++)			{				String aName = "ACCESS" + x + ".m-1." + side;				Export pPort = pmosCell.findExport(aName);				Export nPort = pla.decoderInv.findExport("LINE" + (x % 4) + ".p.n");				if (pPort != null && nPort != null)					pla.makeWire(pla.pArc, 2, pNode, pPort, newNode, nPort, decodeCell);				pPort = nmosCell.findExport(aName);				if (nPort != null && pPort != null)					pla.makeWire(pla.pArc, 2, nNode, pPort, newNode2, nPort, decodeCell);			}			cnt += 4;		}		if (pwrWPort != null && pwrEPort != null)		{			pla.makeWire(pla.m2Arc, 14, lastNNode, pwrWPort, firstPNode, pwrEPort, decodeCell);			Export.newInstance(decodeCell, lastPNode.findPortInstFromProto(pwrWPort), "PWR.m-2.w");		}		if (gndWPort != null && gndEPort != null)		{			pla.makeWire(pla.m2Arc, 14, lastNNode, gndWPort, firstPNode, gndEPort, decodeCell);			Export.newInstance(decodeCell, lastPNode.findPortInstFromProto(gndWPort), "GND.m-2.w");		}		NodeInst [] both = new NodeInst[2];		both[0] = lastPNode;		both[1] = lastNode;		return both;	}	private void decExp(Cell nmosCell, NodeInst nNode, Cell decodeCell)	{		int x = 0;		char side = 'n';		String name = "DATA" + x + ".m-1." + side;		Export pp = nmosCell.findExport(name);		while (pp != null)		{			Export.newInstance(decodeCell, nNode.findPortInstFromProto(pp), name);			x++;			name = "DATA" + x + ".m-1." + side;			pp = nmosCell.findExport(name);		}	}	private boolean decodeRoute(Cell pmosCell, NodeInst pNode, Cell nmosCell,		NodeInst nNode, Cell decodeCell, NodeInst firstNode, NodeInst lastNode, boolean inputsOnTop)	{		// Make connection between N and P planes		Export pPort = pmosCell.findExport("DATA0.m-1.n");		Export nPort = nmosCell.findExport("DATA0.m-1.s");		int cnt = 0;		while (pPort != null && nPort != null)		{			// Connect them up here			pla.makeWire(pla.m1Arc, 4, pNode, pPort, nNode, nPort, decodeCell);			// now find the next ports			cnt += 1;			pPort = pmosCell.findExport("DATA" + cnt + ".m-1.n");			nPort = nmosCell.findExport("DATA" + cnt + ".m-1.s");		}		// Make connection between PWR and P-plane		pPort = pmosCell.findExport("DATA0.m-1.s");		nPort = pmosCell.findExport("PWR0.m-1.s");		if (pPort != null && nPort != null)			pla.makeWire(pla.m1Arc, 4, pNode, pPort, pNode, nPort, decodeCell);		Poly poly = pNode.findPortInstFromProto(nPort).getPoly();		double pX = poly.getCenterX();		double pY = poly.getCenterY();		NodeInst pmNode1 = pla.makePin(decodeCell, pX-13, pY, 6, pla.m12Con);		if (pmNode1 == null) return true;		pla.makeWire(pla.m1Arc, 4, pNode, nPort, pmNode1, pmNode1.getProto().getPort(0), decodeCell);		if (!inputsOnTop) // Buffers are at the top of the cell		{			PortProto pwrPort = firstNode.getProto().findPortProto("PWR.m-2.w");			NodeInst pmNode2 = pla.makePin(decodeCell, pX-13, pY+24, 14, pla.m2Pin);			if (pmNode2 == null) return true;			pla.makeWire(pla.m2Arc, 14, pmNode1, pmNode1.getProto().getPort(0), pmNode2, pmNode2.getProto().getPort(0), decodeCell);			pla.makeWire(pla.m2Arc, 14, firstNode, pwrPort, pmNode2, pmNode2.getProto().getPort(0), decodeCell);		}		nPort = pPort;		pPort = pmosCell.findExport("DATA1.m-1.s");		cnt = 1;		int pwrCnt = 0;		while (pPort != null && nPort != null)		{			// Connect them up here			pla.makeWire(pla.m1Arc, 4, pNode, pPort, pNode, nPort, decodeCell);			// now find the next ports			cnt += 1;			nPort = pPort;			if ((cnt % 4) == 0)			{				pwrCnt += 1;				String name = "PWR" + pwrCnt + ".m-1.s";				pPort = pmosCell.findExport(name);				if (pPort != null)					pla.makeWire(pla.m1Arc, 4, pNode, pPort, pNode, nPort, decodeCell);				poly = pNode.findPortInstFromProto(pPort).getPoly();				pX = poly.getCenterX();				pY = poly.getCenterY();				NodeInst pmNode2 = pla.makePin(decodeCell, pX-13, pY, 6, pla.m12Con);				if (pmNode2 == null) return true;				pla.makeWire(pla.m1Arc, 4, pNode, pPort, pmNode2, pmNode2.getProto().getPort(0), decodeCell);				pla.makeWire(pla.m2Arc, 14, pmNode1, pmNode1.getProto().getPort(0), pmNode2, pmNode2.getProto().getPort(0), decodeCell);				pmNode1 = pmNode2;				nPort = pPort;			}			pPort = pmosCell.findExport("DATA" + cnt + ".m-1.s");		}		if (inputsOnTop) // Buffers are at the top of the cell		{			PortProto pwrPort = firstNode.getProto().findPortProto("PWR.m-2.w");			NodeInst pmNode2 = pla.makePin(decodeCell, pX-13, pY-24, 14, pla.m2Pin);			if (pmNode2 == null) return true;			pla.makeWire(pla.m2Arc, 14, pmNode1, pmNode1.getProto().getPort(0), pmNode2, pmNode2.getProto().getPort(0), decodeCell);			pla.makeWire(pla.m2Arc, 14, firstNode, pwrPort, pmNode2, pmNode2.getProto().getPort(0), decodeCell);		}		// Make connection between GND and N-plane		nPort = nmosCell.findExport("GND0.m-1.n");		poly = nNode.findPortInstFromProto(nPort).getPoly();		pX = poly.getCenterX();		pY = poly.getCenterY();		pmNode1 = pla.makePin(decodeCell, pX+13, pY, 6, pla.m12Con);		if (pmNode1 == null) return true;		pla.makeWire(pla.m1Arc, 4, nNode, nPort, pmNode1, pmNode1.getProto().getPort(0), decodeCell);		if (!inputsOnTop) // Buffers are at the top of the cell		{			PortProto pwrPort = lastNode.getProto().findPortProto("GND.m-2.e");			NodeInst pmNode2 = pla.makePin(decodeCell, pX+13, pY+90, 14, pla.m2Pin);			if (pmNode2 == null) return true;			pla.makeWire(pla.m2Arc, 14, pmNode1, pmNode1.getProto().getPort(0), pmNode2, pmNode2.getProto().getPort(0), decodeCell);			pla.makeWire(pla.m2Arc, 14, lastNode, pwrPort, pmNode2, pmNode2.getProto().getPort(0), decodeCell);		}		cnt = 1;		nPort = nmosCell.findExport("GND" + cnt + ".m-1.n");		while (nPort != null)		{			// Connect them up here			poly = nNode.findPortInstFromProto(nPort).getPoly();			pX = poly.getCenterX();			pY = poly.getCenterY();			NodeInst pmNode2 = pla.makePin(decodeCell, pX+13, pY, 6, pla.m12Con);			if (pmNode2 == null) return true;			pla.makeWire(pla.m1Arc, 4, nNode, nPort, pmNode2, pmNode2.getProto().getPort(0), decodeCell);			pla.makeWire(pla.m2Arc, 14, pmNode1, pmNode1.getProto().getPort(0), pmNode2, pmNode2.getProto().getPort(0), decodeCell);			pmNode1 = pmNode2;			cnt++;			nPort = nmosCell.findExport("GND" + cnt + ".m-1.n");		}		if (inputsOnTop) // Buffers are at the bottom of the cell		{			PortProto pwrPort = lastNode.getProto().findPortProto("GND.m-2.e");			NodeInst pmNode2 = pla.makePin(decodeCell, pX+13, pY-90, 14, pla.m2Pin);			if (pmNode2 == null) return true;			pla.makeWire(pla.m2Arc, 14, pmNode1, pmNode1.getProto().getPort(0), pmNode2, pmNode2.getProto().getPort(0), decodeCell);			pla.makeWire(pla.m2Arc, 14, lastNode, pwrPort, pmNode2, pmNode2.getProto().getPort(0), decodeCell);		}		char side = 's';		char acSide = 'e';		if (inputsOnTop)		{			side = 'n';			acSide = 'w';		}		int columns = 2;		Variable var = pmosCell.getVar("PLA_access_rows");		if (var != null) columns = ((Integer)var.getObject()).intValue() / 2; else			System.out.println("DATA_cols defaulting to 2");		int initOffset = 8;		int sep = 7;		cnt = 0;		String name = "ACCESS" + cnt + ".m-1." + acSide;		pPort = pmosCell.findExport(name);		nPort = nmosCell.findExport(name);		while (pPort != null && nPort != null)		{			// wire it			int inCnt = cnt/2;			poly = pNode.findPortInstFromProto(pPort).getPoly();			pX = poly.getCenterX();			poly = nNode.findPortInstFromProto(nPort).getPoly();			double nX = poly.getCenterX();			double nY = poly.getCenterY();			double y, oY;			if (inputsOnTop)			{				y = nY + initOffset + inCnt*sep;				oY = y + (columns - inCnt - 1)*sep;			} else			{				y = nY - initOffset - inCnt*sep;				oY = y - (columns - inCnt - 1)*sep;			}			pmNode1 = pla.makePin(decodeCell, pX, y, 6, pla.mpCon);			if (pmNode1 == null) return true;			NodeInst pmNode2 = pla.makePin(decodeCell, nX, y, 6, pla.mpCon);			if (pmNode2 == null) return true;			pla.makeWire(pla.m1Arc, 4, pmNode1, pmNode1.getProto().getPort(0), pmNode2, pmNode2.getProto().getPort(0), decodeCell);			pla.makeWire(pla.pArc, 2, pNode, pPort, pmNode1, pmNode1.getProto().getPort(0), decodeCell);			pla.makeWire(pla.pArc, 2, nNode, nPort, pmNode2, pmNode2.getProto().getPort(0), decodeCell);			pmNode1 = pla.makePin(decodeCell, nX, oY, 4, pla.m1Pin);			if (pmNode1 == null) return true;			pla.makeWire(pla.m1Arc, 4, pmNode1,				pmNode1.getProto().getPort(0), pmNode2, pmNode2.getProto().getPort(0), decodeCell);			Export.newInstance(decodeCell, pmNode1.findPortInstFromProto(pmNode1.getProto().getPort(0)), "INPUT" + inCnt + ".m-1." + side);			cnt += 2;  // Only route every second one			name = "ACCESS" + cnt + ".m-1." + acSide;			pPort = pmosCell.findExport(name);			nPort = nmosCell.findExport(name);		}		return false;	}}

⌨️ 快捷键说明

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