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

📄 romgenerator.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: ROMGenerator.java * Written by: David Harris (David_Harris@hmc.edu) * Based on code developed by Frank Lee <chlee@hmc.edu> and Jason Imada <jimada@hmc.edu>  * * 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.generator;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.NodeProto;import com.sun.electric.database.prototype.PortCharacteristic;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.technology.ArcProto;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.ui.WindowFrame;import java.awt.geom.Point2D;import java.awt.geom.Rectangle2D;import java.io.BufferedReader;import java.io.FileNotFoundException;import java.io.FileReader;import java.io.IOException;/** * Class to build ROMs from personality tables. */public class ROMGenerator{	private static int globalbits;	private static int folds;	private static double lambda = 1;	private static Technology tech;		/**	 * Main entry point for ROM generation.	 * The method creates layout for a pseudo-nMOS ROM array.	 *	 * The personality file has this format:	 * The first line lists the degree of folding.  For example,	 * a 256-word x 10-bit ROM with a folding degree of 4 will	 * be implemented as a 64 x 40 array with 4:1 column multiplexers	 * to return 10 bits of data while occupying more of a square form	 * factor. The number of words and degree of folding should be	 * powers of 2.  The remaining lines of the file list the contents	 * of each word.  The parser is pretty picky.  There should	 * be a carriage return after the list word, but no other blank	 * lines in the file.	 * 	 * Here is a sample personality file:	 *     1	 *     010101	 *     011001	 *     100101	 *     101010	 *     4	 *     00000000	 *     10000000	 *     01000000	 *     11000000	 *	 * The tool may be slow, especially for large ROMs.  When done, there may be some	 * extraneous and bad pins left over; using "Edit / Cleanup Cell / Cleanup	 * Pins Everywhere" will fix these (though this isn't strictly necessary).	 *	 * The ROMs produced should pass DRC and ERC and simulate with IRSIM.  One	 * was successfully fabricated Spring of 2002 by Genevieve Breed and Matthew	 * Erler in the MOSIS 0.6 micron AMI process.	 */	public static void generateROM()	{		// get the personality file		String romFile = OpenFile.chooseInputFile(FileType.TEXT, null);		if (romFile == null) return;		// build the ROM (in a separate Job thread)		new DoROM(Library.getCurrent(), romFile);	}	/**	 * Method to generate a ROM from a given ROM file.     * @param destLib destination library.	 * @param romFile the file to use.	 */	public static void generateROM(Library destLib, String romFile)	{		// build the ROM (in a separate Job thread)//		new DoROM(destLib, romFile);        makeAROM(destLib, romFile, "ROMCELL");	}	/**	 * Class to generate a ROM in a separate Job thread.	 */	private static class DoROM extends Job	{        private Library destLib;		private String romfile;		private Cell topLevel;		private DoROM(Library destLib, String romfile)		{			super("ROM Generator", User.getUserTool(), Job.Type.CHANGE, null, null, Job.Priority.USER);            this.destLib = destLib;			this.romfile = romfile;			startJob();		}		public boolean doIt() throws JobException		{			// Set the root name of the cells			String romcell = "ROMCELL";			// build the ROM			topLevel = makeAROM(destLib, romfile, romcell);			fieldVariableChanged("topLevel");			return true;		}        public void terminateOK()        {            if (topLevel != null)                WindowFrame.createEditWindow(topLevel);        }	}	/**	 * Main method to build a ROM.     * @param destLib destination library.	 * @param romfile the disk file with the ROM personality.	 * @param romcell the root name of all ROM cells.	 * @return the top-level cell.	 */	public static Cell makeAROM(Library destLib, String romfile, String romcell)	{		NodeInst ap1, ap2, ap3, ap4;		PortProto apport1, apport2, apport3, apport4;		double[] appos1, appos2, appos3, appos4;		// presume MOSIS CMOS		tech = Technology.getMocmosTechnology();			int[][] romarray = romarraygen(romfile);			String dpr  = new String(romcell+"_decoderpmos");		String dnr  = new String(romcell+"_decodernmos");		String dpm  = new String(romcell+"_decoderpmosmux");		String dnm  = new String(romcell+"_decodernmosmux");		String invt = new String(romcell+"_invertertop");		String invb = new String(romcell+"_inverterbot");		String romname =  new String(romcell+"_rom");		String rp =   new String(romcell+"_romplane");		String ip =   new String(romcell+"_inverterplane");		String mp =   new String(romcell+"_muxplane");		if (folds > 1)		{			romarray = romfold(romarray);		}		romplane(destLib, lambda, romarray, rp);		int bits =			(new Double(Math.ceil(Math.log(globalbits)/Math.log(2.0)))).intValue();		int words = (int) (Math.pow(2.0, bits));		int foldbits =			(new Double(Math.ceil(Math.log(folds)/Math.log(2.0)))).intValue();		boolean top = true;		boolean bot = false;		// make subcells		decoderpmos(destLib, lambda, bits, dpr, top);		decodernmos(destLib, lambda, bits, dnr, top);		inverterplane(destLib, lambda, romarray.length, folds, ip);		ininverterplane(destLib, lambda, bits, invt, top, bits);		ArcProto m1arc = tech.findArcProto("Metal-1");		ArcProto m2arc = tech.findArcProto("Metal-2");		////////////// decoderpmos			Cell decp = destLib.findNodeProto(dpr+"{lay}");		Rectangle2D decpBounds = decp.getBounds();		PortProto[] decpin = new PortProto[words];		PortProto[] decpout = new PortProto[words];		PortProto[] decpbit = new PortProto[2*bits];		PortProto decpvdd = decp.findPortProto("vdd");		PortProto decpvddb = decp.findPortProto("vddb");		for (int i=0; i<words; i++)		{			decpin[i] = decp.findPortProto("wordin"+i);			decpout[i] = decp.findPortProto("word"+i);		}		for (int i=0; i<bits; i++)		{			decpbit[2*i] = decp.findPortProto("top_in"+i);			decpbit[(2*i)+1] = decp.findPortProto("top_in"+i+"_b");		}		////////////// decodernmos			Cell decn = destLib.findNodeProto(dnr+"{lay}");		Rectangle2D decnBounds = decn.getBounds();	 	PortProto[] decnout = new PortProto[words];	 	PortProto[] decnin = new PortProto[words];	 	PortProto[] decnbit = new PortProto[2*bits];				for (int i=0; i<words; i++)		{			decnin[i] = decn.findPortProto("mid"+i);			decnout[i] = decn.findPortProto("word"+i);		}		for (int i=0; i<bits; i++)		{			decnbit[2*i] = decn.findPortProto("top_in"+i);			decnbit[(2*i)+1] = decn.findPortProto("top_in"+i+"_b");		}			////////////////////// romplane		Cell romp = destLib.findNodeProto(rp+"{lay}");		Rectangle2D rompBounds = romp.getBounds();		PortProto[] rompin = new PortProto[globalbits];		PortProto[] rompout = new PortProto[romarray.length];		PortProto[] rompgnd = new PortProto[romarray.length/2];		PortProto rompvdd = romp.findPortProto("vdd");		PortProto rompgndc = romp.findPortProto("gndc");		for (int i=0; i<globalbits; i++)		{			rompin[i] = romp.findPortProto("wordline_"+i);		}		for (int i=0; i<romarray.length; i++)		{			rompout[i] = romp.findPortProto("out_"+i);		}		for (int i=0; i<romarray.length/2; i++)		{			rompgnd[i] = romp.findPortProto("romgnd"+i);		}			////////////////////// inverterplane		Cell invp = destLib.findNodeProto(ip+"{lay}");		Rectangle2D invpBounds = invp.getBounds();		PortProto[] invin = new PortProto[romarray.length];		PortProto[] invout = new PortProto[romarray.length];		PortProto[] invgnd = new PortProto[romarray.length/2];		PortProto invvddc = invp.findPortProto("vdd");		PortProto invgndc = invp.findPortProto("gnd");		for (int i=0; i<romarray.length/folds; i++)		{			invin[i] = invp.findPortProto("invin"+i);			invout[i] = invp.findPortProto("invout"+i);		}				int invplanegnd = romarray.length/folds;		if (folds == 1)		{			invplanegnd = invplanegnd / 2;		}			for (int i=0; i<invplanegnd; i++)		{			invgnd[i] = invp.findPortProto("invgnd"+i);		}			////////////////////// ininverterplane top		Cell ininvtp = destLib.findNodeProto(invt+"{lay}");		Rectangle2D ininvtpBounds = ininvtp.getBounds();		PortProto[] ivttop  = new PortProto[bits];		PortProto[] ivtbot = new PortProto[bits];		PortProto[] ivtbar = new PortProto[bits];		PortProto ivtvdd = ininvtp.findPortProto("vdd");		PortProto ivtgnd = ininvtp.findPortProto("gnd");		for (int i=0; i<bits; i++)		{			ivttop[i] = ininvtp.findPortProto("in_top"+i);			ivtbot[i] = ininvtp.findPortProto("in_bot"+i);			ivtbar[i] = ininvtp.findPortProto("in_b"+i);		}			// create new layout named "rom{lay}" in destination library		Cell rom = Cell.newInstance(destLib, romname+"{lay}");			////////// calculate pplane offset		double offset = (2*bits*(8*lambda)) + (16*lambda);		double rompoffset = (8*lambda)*2*bits + (12*lambda) + offset;		double rompoffsety = 8*lambda*(globalbits+1);		double foldoffsetx = (2*(bits-foldbits)*(8*lambda));		double muxpoffsety = -6*lambda;		double foldoffsety = -8*lambda*(folds+1);		double ininvtoffset = (globalbits+2)*8*lambda+48*lambda;		// smr added this line to make things line-up properly		ininvtoffset += 44*lambda;			double invpoffsety = -8*lambda*(folds+1)-16*lambda;		if (folds == 1)		{			invpoffsety = invpoffsety + 24*lambda;		}			NodeInst nplane =			makeCStyleNodeInst(decn, decnBounds.getMinX()+offset, decnBounds.getMaxX()+offset, decnBounds.getMinY(),								 decnBounds.getMaxY(), 0, 0, rom);		NodeInst pplane =			makeCStyleNodeInst(decp, decpBounds.getMinX(), decpBounds.getMaxX(), decpBounds.getMinY(), decpBounds.getMaxY(),								 0, 0, rom);		NodeInst rompln =			makeCStyleNodeInst(romp, rompBounds.getMinX()+rompoffset, rompBounds.getMaxX()+rompoffset,								 rompBounds.getMinY()+rompoffsety, rompBounds.getMaxY()+rompoffsety,								 0, 2700, rom);		NodeInst invpln =			makeCStyleNodeInst(invp, invpBounds.getMinX()+rompoffset, invpBounds.getMaxX()+rompoffset,								 invpBounds.getMinY()+invpoffsety, invpBounds.getMaxY()+invpoffsety, 0, 0, rom);		NodeInst ininvtop1 =			makeCStyleNodeInst(ininvtp,ininvtpBounds.getMinX(),ininvtpBounds.getMaxX(),								 ininvtpBounds.getMinY()+ininvtoffset, ininvtpBounds.getMaxY()+ininvtoffset,								 0, 0, rom);		NodeInst ininvtop2 =			makeCStyleNodeInst(ininvtp,ininvtpBounds.getMinX()+offset, ininvtpBounds.getMaxX()+offset,								 ininvtpBounds.getMinY()+ininvtoffset,								 ininvtpBounds.getMaxY()+ininvtoffset, 0, 0, rom);		////////////// exports on top level		for (int i=0; i<bits; i++)		{			ap1 = ininvtop1;			apport1 = ivttop[i];			makeCStyleExport(rom, ap1, apport1, ("sel"+i), PortCharacteristic.IN);		}		for (int i=0; i<romarray.length/folds; i++)		{			ap1 = invpln;			apport1 = invout[i];			makeCStyleExport(rom, ap1, apport1, ("out"+i), PortCharacteristic.OUT);		}		ap2 = rompln;		apport2 = rompvdd;		makeCStyleExport(rom, ap2, apport2, ("vdd"), PortCharacteristic.PWR);		// TODO: this arc comes out diagonal!!!		ap1 = nplane;		apport1 = decn.findPortProto("gnd");		appos1 = getCStylePortPosition(ap1, apport1);		ap2 = rompln;		apport2 = rompgndc;		appos2 = getCStylePortPosition(ap2, apport2);		makeCStyleArcInst(m1arc, 4*lambda, ap1, apport1, appos1[0],							appos1[1], ap2, apport2, appos2[0], appos2[1]);		apport2 = romp.findPortProto("gnd");		// decnout, decpin		for (int i=0; i<words; i++)		{			ap1 = pplane;			apport1 = decpout[i];			appos1 = getCStylePortPosition(ap1, apport1); 			ap2 = nplane;			apport2 = decnin[i];			appos2 = getCStylePortPosition(ap2, apport2); 			makeCStyleArcInst(m2arc, 4*lambda, ap1, apport1, appos1[0],								appos1[1], ap2, apport2, appos2[0], appos2[1]);		}		for (int i=0; i<words; i++)		{			if (i >= globalbits) continue;			ap1 = nplane;

⌨️ 快捷键说明

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