📄 romgenerator.java
字号:
/* -*- 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 + -