/* -*- 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, Oracle and/or its affiliates. All rights reserved.
*
* 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.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.IconParameters;
import com.sun.electric.tool.user.dialogs.OpenFile;
import com.sun.electric.tool.user.ui.WindowFrame;
import com.sun.electric.util.math.Orientation;
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;
private static IconParameters iconParameters = IconParameters.makeInstance(true);
/**
* 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 wf = WindowFrame.getCurrentWindowFrame();
if (User.isShowCellsInNewWindow()) wf = null;
if (wf == null) wf = WindowFrame.createEditWindow(topLevel);
wf.setCellWindow(topLevel, null);
}
}
}
/**
* 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;
apport1 = decnout[i];
appos1 = getCStylePortPosition(ap1, apport1);
ap2 = rompln;
apport2 = rompin[i];
appos2 = getCStylePortPosition(ap2, apport2);
makeCStyleArcInst(m2arc, 4*lambda, ap1, apport1, appos1[0],
appos1[1], ap2, apport2, appos2[0], appos2[1]);
}
/////// connect rompgnd to invgnd
if (folds > 1)
{
for (int i=0; i<romarray.length/folds; i++)
{
ap1 = invpln;
apport1 = invgnd[i];
appos1 = getCStylePortPosition(ap1, apport1);
ap2 = rompln;
apport2 = rompgnd[i*folds/2];
appos2 = getCStylePortPosition(ap2, apport2);
makeCStyleArcInst(m1arc, 4*lambda, ap1, apport1, appos1[0],
appos1[1], ap2,apport2,appos2[0], appos2[1]);
}
} else
{
for (int i=0; i<romarray.length/(2*folds); i++)
{
ap1 = invpln;
apport1 = invgnd[i];
appos1 = getCStylePortPosition(ap1, apport1);
ap2 = rompln;
apport2 = rompgnd[i];
appos2 = getCStylePortPosition(ap2, apport2);
makeCStyleArcInst(m1arc, 4*lambda, ap1, apport1, appos1[0],
appos1[1], ap2,apport2,appos2[0], appos2[1]);
}
}
/////// connect top ininv1 to ininv2
for (int i=0; i<bits; i++)
{
ap1 = ininvtop1;
apport1 = ivttop[i];
appos1 = getCStylePortPosition(ap1, apport1);
ap2 = ininvtop2;
apport2 = ivttop[i];
appos2 = getCStylePortPosition(ap2, apport2);
makeCStyleArcInst(m2arc, 4*lambda, ap1, apport1, appos1[0],
appos1[1], ap2, apport2, appos2[0], appos2[1]);
}
/////// connect top ininv1 to ndecoder
for (int i=0; i<bits; i++)
{
ap1 = ininvtop1;
apport1 = ivtbot[i];
appos1 = getCStylePortPosition(ap1, apport1);
ap2 = pplane;
apport2 = decpbit[i*2];
appos2 = getCStylePortPosition(ap2, apport2);
makeCStyleArcInst(m1arc, 4*lambda, ap1, apport1, appos1[0],
appos1[1], ap2, apport2, appos2[0], appos2[1]);
ap1 = ininvtop1;
apport1 = ivtbar[i];
appos1 = getCStylePortPosition(ap1, apport1);
ap2 = pplane;
apport2 = decpbit[(i*2)+1];
appos2 = getCStylePortPosition(ap2, apport2);
makeCStyleArcInst(m1arc, 4*lambda, ap1, apport1, appos1[0],
appos1[1], ap2, apport2, appos2[0], appos2[1]);
}
/////// connect top ininv2 to pdecoder
for (int i=0; i<bits; i++)
{
ap1 = ininvtop2;
apport1 = ivtbot[i];
appos1 = getCStylePortPosition(ap1, apport1);
ap2 = nplane;
apport2 = decnbit[i*2];
appos2 = getCStylePortPosition(ap2, apport2);
makeCStyleArcInst(m1arc, 4*lambda, ap1, apport1, appos1[0],
appos1[1], ap2, apport2, appos2[0], appos2[1]);
ap1 = ininvtop2;
apport1 = ivtbar[i];
appos1 = getCStylePortPosition(ap1, apport1);
ap2 = nplane;
apport2 = decnbit[(i*2)+1];
appos2 = getCStylePortPosition(ap2, apport2);
makeCStyleArcInst(m1arc, 4*lambda, ap1, apport1, appos1[0],
appos1[1], ap2, apport2, appos2[0], appos2[1]);
}
//////// connect two top decoder inverterplanes and decoder together (vdd)
ap1 = ininvtop1;
apport1 = ivtvdd;
appos1 = getCStylePortPosition(ap1, apport1);
ap2 = ininvtop2;
apport2 = ivtvdd;
appos2 = getCStylePortPosition(ap2, apport2);
ap3 = pplane;
apport3 = decpvdd;
appos3 = getCStylePortPosition(ap3, apport3);
makeCStyleArcInst(m2arc, 4*lambda, ap1, apport1, appos1[0],
appos1[1], ap2, apport2, appos2[0], appos2[1]);
makeCStyleArcInst(m2arc, 4*lambda, ap1, apport1, appos1[0],
appos1[1], ap3, apport3, appos3[0], appos3[1]);
//////// connect two top decoder inverterplanes and romplane together (gnd)
ap1 = ininvtop1;
apport1 = ivtgnd;
appos1 = getCStylePortPosition(ap1, apport1);
ap2 = ininvtop2;
apport2 = ivtgnd;
appos2 = getCStylePortPosition(ap2, apport2);
ap3 = rompln;
apport3 = rompgndc;
appos3 = getCStylePortPosition(ap3, apport3);
makeCStyleArcInst(m2arc, 4*lambda, ap1, apport1, appos1[0],
appos1[1], ap2, apport2, appos2[0], appos2[1]);
makeCStyleArcInst(m1arc, 4*lambda, ap2, apport2, appos2[0],
appos2[1], ap3, apport3, appos3[0], appos3[1]);
makeCStyleExport(rom, ap2, apport2, "gnd", PortCharacteristic.GND);
//////// connect decoder inverter vdd to rom vdd
ap1 = ininvtop2;
apport1 = ivtvdd;
appos1 = getCStylePortPosition(ap1, apport1);
ap2 = rompln;
apport2 = rompvdd;
appos2 = getCStylePortPosition(ap2, apport2);
makeCStyleArcInst(m2arc, 4*lambda, ap1, apport1, appos1[0],
appos1[1], ap2, apport2, appos2[0], appos2[1]);
// begin (folds > 1)
if (folds > 1)
{
decoderpmos(destLib, lambda, foldbits, dpm, bot);
decodernmos(destLib, lambda, foldbits, dnm, bot);
ininverterplane(destLib, lambda, foldbits, invb, bot, bits);
muxplane(destLib, lambda, folds, romarray.length, mp);
////////////// decodernmosmux
Cell decpmux = destLib.findNodeProto(dpm+"{lay}");
Rectangle2D decpmuxBounds = decpmux.getBounds();
PortProto[] decpmuxin = new PortProto[folds];
PortProto[] decpmuxout = new PortProto[folds];
PortProto[] decpmuxbit = new PortProto[2*foldbits];
PortProto decpmuxvdd = decpmux.findPortProto("vdd");
PortProto decpmuxvddb = decpmux.findPortProto("vddb");
for (int i=0; i<folds; i++)
{
decpmuxin[i] = decpmux.findPortProto("wordin"+i);
decpmuxout[i] = decpmux.findPortProto("word"+i);
}
for (int i=0; i<foldbits; i++)
{
decpmuxbit[2*i] = decpmux.findPortProto("bot_in"+i);
decpmuxbit[(2*i)+1] = decpmux.findPortProto("bot_in"+i+"_b");
}
////////////// decoderpmosmux
Cell decnmux = destLib.findNodeProto(dnm+"{lay}");
Rectangle2D decnmuxBounds = decnmux.getBounds();
PortProto[] decnmuxout = new PortProto[folds];
PortProto[] decnmuxin = new PortProto[folds];
PortProto[] decnmuxbit = new PortProto[2*foldbits];
for (int i=0; i<folds; i++)
{
decnmuxin[i] = decnmux.findPortProto("mid"+i);
decnmuxout[i] = decnmux.findPortProto("word"+i);
}
for (int i=0; i<foldbits; i++)
{
decnmuxbit[2*i] = decnmux.findPortProto("bot_in"+i);
decnmuxbit[(2*i)+1] = decnmux.findPortProto("bot_in"+i+"_b");
}
////////////////////// muxplane
Cell muxp = destLib.findNodeProto(mp+"{lay}");
Rectangle2D muxpBounds = muxp.getBounds();
PortProto[] muxin = new PortProto[romarray.length];
PortProto[] muxout = new PortProto[romarray.length/folds];
PortProto[] muxsel = new PortProto[folds];
for (int i=0; i<romarray.length; i++)
{
muxin[i] = muxp.findPortProto("muxin"+i);
}
for (int i=0; i<romarray.length/folds; i++)
{
muxout[i] = muxp.findPortProto("muxout"+i);
}
for (int i=0; i<folds; i++)
{
muxsel[i] = muxp.findPortProto("sel"+i);
}
////////////////////// ininverterplane bottom
Cell ininvbp = destLib.findNodeProto(invb+"{lay}");
Rectangle2D ininvbpBounds = ininvbp.getBounds();
PortProto[] ivbtop = new PortProto[foldbits];
PortProto[] ivbbot = new PortProto[foldbits];
PortProto[] ivbbar = new PortProto[foldbits];
PortProto ivbvdd = ininvbp.findPortProto("vdd");
PortProto ivbgnd = ininvbp.findPortProto("gnd");
for (int i=0; i<foldbits; i++)
{
ivbtop[i] = ininvbp.findPortProto("in_top"+i);
ivbbot[i] = ininvbp.findPortProto("in_bot"+i);
ivbbar[i] = ininvbp.findPortProto("in_b"+i);
}
NodeInst muxpln =
makeCStyleNodeInst(muxp, muxpBounds.getMinX()+rompoffset, muxpBounds.getMaxX()+rompoffset,
muxpBounds.getMinY()+muxpoffsety, muxpBounds.getMaxY()+muxpoffsety,
0, 2700, rom);
NodeInst pplnmx =
makeCStyleNodeInst(decpmux, decpmuxBounds.getMinX()+foldoffsetx,
decpmuxBounds.getMaxX()+foldoffsetx,
decpmuxBounds.getMinY()+muxpoffsety+foldoffsety,
decpmuxBounds.getMaxY()+muxpoffsety+foldoffsety, 0, 0, rom);
NodeInst nplnmx =
makeCStyleNodeInst(decnmux, decnmuxBounds.getMinX()+foldoffsetx+offset,
decnmuxBounds.getMaxX()+foldoffsetx+offset,
decnmuxBounds.getMinY()+muxpoffsety+foldoffsety,
decnmuxBounds.getMaxY()+muxpoffsety+foldoffsety, 0, 0, rom);
NodeInst ininvbot1 =
makeCStyleNodeInst(ininvbp,ininvbpBounds.getMinX()+foldoffsetx,
ininvbpBounds.getMaxX()+foldoffsetx, ininvbpBounds.getMinY()+invpoffsety,
ininvbpBounds.getMaxY()+invpoffsety, 0, 0, rom);
NodeInst ininvbot2 =
makeCStyleNodeInst(ininvbp, ininvbpBounds.getMinX()+foldoffsetx+offset,
ininvbpBounds.getMaxX()+foldoffsetx+offset,
ininvbpBounds.getMinY()+invpoffsety,
ininvbpBounds.getMaxY()+invpoffsety, 0, 0, rom);
for (int i=0; i<foldbits; i++)
{
ap1 = ininvbot1;
apport1 = ivbbot[i];
makeCStyleExport(rom, ap1, apport1, "colsel"+i, PortCharacteristic.IN);
}
ap1 = nplane;
apport1 = decn.findPortProto("gnd");
appos1 = getCStylePortPosition(ap1, apport1);
ap3 = pplnmx;
apport3 = decpmuxvdd;
appos3 = getCStylePortPosition(ap3, apport3);
ap4 = pplane;
apport4 = decpvddb;
appos4 = getCStylePortPosition(ap4, apport4);
makeCStyleArcInst(m1arc, 4*lambda, ap4, apport4, appos4[0],
appos4[1], ap3, apport3, appos3[0], appos3[1]);
ap3 = nplnmx;
apport3 = decnmux.findPortProto("gnd");
appos3 = getCStylePortPosition(ap3, apport3);
makeCStyleArcInst(m1arc, 4*lambda, ap1, apport1, appos1[0],
appos1[1], ap3, apport3, appos3[0], appos3[1]);
// decnmuxout, decpmuxin
for (int i=0; i<folds; i++)
{
ap1 = pplnmx;
apport1 = decpmuxout[i];
appos1 = getCStylePortPosition(ap1, apport1);
ap2 = nplnmx;
apport2 = decnmuxin[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<folds; i++)
{
ap1 = nplnmx;
apport1 = decnmuxout[i];
appos1 = getCStylePortPosition(ap1, apport1);
ap2 = muxpln;
apport2 = muxsel[i];
appos2 = getCStylePortPosition(ap2, apport2);
makeCStyleArcInst(m2arc, 4*lambda, ap1, apport1,appos1[0],
appos1[1],ap2,apport2,appos2[0], appos2[1]);
}
///////connect rompout to muxin
for (int i=0; i<romarray.length; i++)
{
ap1 = rompln;
apport1 = rompout[i];
appos1 = getCStylePortPosition(ap1, apport1);
ap2 = muxpln;
apport2 = muxin[i];
appos2 = getCStylePortPosition(ap2, apport2);
makeCStyleArcInst(m1arc, 4*lambda, ap1, apport1,appos1[0],
appos1[1],ap2,apport2,appos2[0], appos2[1]);
}
/////// connect muxout to invin
for (int i=0; i<romarray.length/folds; i++)
{
ap1 = invpln;
apport1 = invin[i];
appos1 = getCStylePortPosition(ap1, apport1);
ap2 = muxpln;
apport2 = muxout[i];
appos2 = getCStylePortPosition(ap2, apport2);
makeCStyleArcInst(m1arc, 4*lambda, ap1, apport1,appos1[0],
appos1[1],ap2,apport2,appos2[0], appos2[1]);
}
/////// connect bot ininv1 to ininv2
for (int i=0; i<foldbits; i++)
{
ap1 = ininvbot1;
apport1 = ivbbot[i];
appos1 = getCStylePortPosition(ap1, apport1);
ap2 = ininvbot2;
apport2 = ivbbot[i];
appos2 = getCStylePortPosition(ap2, apport2);
makeCStyleArcInst(m2arc, 4*lambda, ap1, apport1,appos1[0],
appos1[1],ap2,apport2,appos2[0], appos2[1]);
}
/////// connect bot ininv1 to nmuxdecoder
for (int i=0; i<foldbits; i++)
{
ap1 = ininvbot1;
apport1 = ivbtop[i];
appos1 = getCStylePortPosition(ap1, apport1);
ap2 = pplnmx;
apport2 = decpmuxbit[i*2];
appos2 = getCStylePortPosition(ap2, apport2);
makeCStyleArcInst(m1arc, 4*lambda, ap1, apport1, appos1[0],
appos1[1], ap2, apport2, appos2[0], appos2[1]);
ap1 = ininvbot1;
apport1 = ivbbar[i];
appos1 = getCStylePortPosition(ap1, apport1);
ap2 = pplnmx;
apport2 = decpmuxbit[(i*2)+1];
appos2 = getCStylePortPosition(ap2, apport2);
makeCStyleArcInst(m1arc, 4*lambda, ap1, apport1, appos1[0],
appos1[1], ap2, apport2, appos2[0], appos2[1]);
}
/////// connect bot ininv2 to pmuxdecoder
for (int i=0; i<foldbits; i++)
{
ap1 = ininvbot2;
apport1 = ivbtop[i];
appos1 = getCStylePortPosition(ap1, apport1);
ap2 = nplnmx;
apport2 = decnmuxbit[i*2];
appos2 = getCStylePortPosition(ap2, apport2);
makeCStyleArcInst(m1arc, 4*lambda, ap1, apport1, appos1[0],
appos1[1], ap2, apport2, appos2[0], appos2[1]);
ap1 = ininvbot2;
apport1 = ivbbar[i];
appos1 = getCStylePortPosition(ap1, apport1);
ap2 = nplnmx;
apport2 = decnmuxbit[(i*2)+1];
appos2 = getCStylePortPosition(ap2, apport2);
makeCStyleArcInst(m1arc, 4*lambda, ap1, apport1, appos1[0],
appos1[1], ap2, apport2, appos2[0], appos2[1]);
}
//////// connect two mux decoder inverterplanes and mux decoder together (vdd)
ap1 = ininvbot1;
apport1 = ivbvdd;
appos1 = getCStylePortPosition(ap1, apport1);
ap2 = ininvbot2;
apport2 = ivbvdd;
appos2 = getCStylePortPosition(ap2, apport2);
ap3 = pplnmx;
apport3 = decpmuxvddb;
appos3 = getCStylePortPosition(ap3, apport3);
makeCStyleArcInst(m2arc, 4*lambda, ap1, apport1, appos1[0],
appos1[1], ap2, apport2, appos2[0], appos2[1]);
makeCStyleArcInst(m1arc, 4*lambda, ap1, apport1, appos1[0],
appos1[1], ap3, apport3, appos3[0], appos3[1]);
//////// connect two mux decoder inverterplanes and inverterplane together (gnd)
ap1 = ininvbot1;
apport1 = ivbgnd;
appos1 = getCStylePortPosition(ap1, apport1);
ap2 = ininvbot2;
apport2 = ivbgnd;
appos2 = getCStylePortPosition(ap2, apport2);
ap3 = invpln;
apport3 = invgndc;
appos3 = getCStylePortPosition(ap3, apport3);
makeCStyleArcInst(m2arc, 4*lambda, ap1, apport1, appos1[0],
appos1[1], ap2, apport2, appos2[0], appos2[1]);
makeCStyleArcInst(m2arc, 4*lambda, ap3, apport3, appos3[0],
appos3[1], ap2, apport2, appos2[0], appos2[1]);
//////// connect mux decoder to inverter vdd
ap1 = invpln;
apport1 = invvddc;
appos1 = getCStylePortPosition(ap1, apport1);
ap2 = ininvbot2;
apport2 = ivbvdd;
appos2 = getCStylePortPosition(ap2, apport2);
makeCStyleArcInst(m2arc, 4*lambda, ap1, apport1, appos1[0],
appos1[1], ap2, apport2, appos2[0], appos2[1]);
}
// end (folds > 1)
// begin (folds == 1)
if (folds == 1)
{
for (int i=0; i<romarray.length; i++)
{
ap1 = invpln;
apport1 = invin[i];
appos1 = getCStylePortPosition(ap1, apport1);
ap2 = rompln;
apport2 = rompout[i];
appos2 = getCStylePortPosition(ap2, apport2);
makeCStyleArcInst(m1arc, 4*lambda, ap1, apport1, appos1[0],
appos1[1], ap2, apport2, appos2[0], appos2[1]);
}
// connect vdd of decoderpmos to vdd of inverterplane
NodeProto m1m2c = tech.findNodeProto("Metal-1-Metal-2-Con");
PortProto m1m2cport = m1m2c.getPort(0);
double[] m1m2cbox = {-5*lambda/2, 5*lambda/2, -5*lambda/2, 5*lambda/2};
double vddoffsetx = offset - 4*lambda;
double vddoffsety = invpoffsety - 26*lambda;
NodeInst vddbot =
makeCStyleNodeInst(m1m2c, m1m2cbox[0]+vddoffsetx, m1m2cbox[1]+vddoffsetx,
m1m2cbox[2]+vddoffsety, m1m2cbox[3]+vddoffsety, 0, 0, rom);
ap1 = invpln;
apport1 = invvddc;
appos1 = getCStylePortPosition(ap1, apport1);
ap2 = vddbot;
apport2 = m1m2cport;
appos2 = getCStylePortPosition(ap2, apport2);
ap3 = pplane;
apport3 = decpvddb;
appos3 = getCStylePortPosition(ap3, apport3);
makeCStyleArcInst(m2arc, 4*lambda, ap1, apport1, appos1[0],
appos1[1], ap2, apport2, appos2[0], appos2[1]);
makeCStyleArcInst(m1arc, 4*lambda, ap2, apport2, appos2[0],
appos2[1], ap3, apport3, appos3[0], appos3[1]);
}
// return the top-level
return rom;
}
/**
*/
private static void romplane(Library destLib, double lambda, int romarray[][], String rp)
{
int i, m;
double x, y;
NodeInst ap1, ap2, ap3, ap4, gnd1, gnd2, intgnd;
PortProto apport1, apport2, apport3, apport4, gndport1, gndport2,
intgndport;
double[] appos1, appos2, appos3, appos4, gndpos1, gndpos2, intgndpos;
int inputs = romarray[0].length;
int wordlines = romarray.length;
NodeInst[][] andtrans = new NodeInst[wordlines+2][inputs+2];
NodeInst[] pulluptrans = new NodeInst[wordlines+2];
NodeInst[] nwellc = new NodeInst[(wordlines+2)/2];
NodeInst[][] minpins = new NodeInst[wordlines+2][inputs+2];
NodeInst[][] diffpins = new NodeInst[wordlines+2][inputs+2];
NodeInst[][] gndpins = new NodeInst[wordlines/2][inputs+2];
NodeInst[] gnd_2pins = new NodeInst[wordlines/2];
NodeInst[] m1polypins = new NodeInst[inputs+2];
NodeInst[] m1m2pins = new NodeInst[inputs+2];
NodeInst[] m1m2_2pins = new NodeInst[wordlines+2];
NodeInst[] m1m2_3pins = new NodeInst[wordlines+2];
NodeInst[] m1m2_4pins = new NodeInst[wordlines+2];
NodeInst[] mpac_1pins = new NodeInst[wordlines+2];
NodeInst[] mpac_2pins = new NodeInst[wordlines+2];
NodeInst gndpex[] = new NodeInst[1];
NodeInst gndm1ex[] = new NodeInst[1];
NodeInst gnd1pin = null;
NodeInst vdd2pin = null;
PortProto[] nwellcports = new PortProto[(wordlines+2)/2];
PortProto[][] minports = new PortProto[wordlines+2][inputs+2];
PortProto[][] gndports = new PortProto[wordlines/2][inputs+2];
PortProto[] gnd_2ports = new PortProto[wordlines/2];
PortProto[] m1m2_2ports = new PortProto[wordlines+2];
PortProto[] m1m2_3ports = new PortProto[wordlines+2];
PortProto[] m1m2_4ports = new PortProto[wordlines+2];
PortProto[] mpac_1ports = new PortProto[wordlines+2];
PortProto[] mpac_2ports = new PortProto[wordlines+2];
PortProto gndpexport[] = new PortProto[1];
PortProto gndm1export[] = new PortProto[1];
PortProto gnd1port = null;
PortProto vdd2port = null;
// get pointers to primitives
NodeProto nmos = tech.findNodeProto("N-Transistor");
PortProto nmosg1port = nmos.findPortProto("poly-right");
PortProto nmosg2port = nmos.findPortProto("poly-left");
PortProto nmosd1port = nmos.findPortProto("diff-top");
PortProto nmosd2port = nmos.findPortProto("diff-bottom");
double[] nmosbox = {-nmos.getDefWidth()/2-lambda/2,
nmos.getDefWidth()/2+lambda/2,
-nmos.getDefHeight()/2,
nmos.getDefHeight()/2};
NodeProto pmos = tech.findNodeProto("P-Transistor");
PortProto pmosg1port = pmos.findPortProto("poly-right");
PortProto pmosg2port = pmos.findPortProto("poly-left");
PortProto pmosd1port = pmos.findPortProto("diff-top");
PortProto pmosd2port = pmos.findPortProto("diff-bottom");
double bbb = 15;
double ccc = 23;
double[] pmosbox = {-bbb*lambda/2, bbb*lambda/2, -ccc*lambda/2, ccc*lambda/2};
NodeProto ppin = tech.findNodeProto("Polysilicon-1-Pin");
PortProto ppinport = ppin.getPort(0);
double[] ppinbox = {-ppin.getDefWidth()/2,
ppin.getDefWidth()/2,
-ppin.getDefHeight()/2,
ppin.getDefHeight()/2};
NodeProto m1pin = tech.findNodeProto("Metal-1-Pin");
PortProto m1pinport = m1pin.getPort(0);
double[] m1pinbox = {-m1pin.getDefWidth()/2-lambda/2,
m1pin.getDefWidth()/2+lambda/2,
-m1pin.getDefHeight()/2-lambda/2,
m1pin.getDefHeight()/2+lambda/2};
NodeProto m2pin = tech.findNodeProto("Metal-2-Pin");
PortProto m2pinport = m2pin.getPort(0);
double[] m2pinbox = {-m2pin.getDefWidth()/2-lambda/2,
m2pin.getDefWidth()/2+lambda/2,
-m2pin.getDefHeight()/2-lambda/2,
m2pin.getDefHeight()/2+lambda/2};
NodeProto diffpin = tech.findNodeProto("Active-Pin");
PortProto diffpinport = diffpin.getPort(0);
double[] diffpinbox =
{-diffpin.getDefWidth()/2-lambda/2,
diffpin.getDefWidth()/2+lambda/2,
-diffpin.getDefHeight()/2-lambda/2,
diffpin.getDefHeight()/2+lambda/2};
NodeProto nwnode = tech.findNodeProto("N-Well-Node");
NodeProto pwnode = tech.findNodeProto("P-Well-Node");
NodeProto psnode = tech.findNodeProto("P-Select-Node");
NodeProto mnac = tech.findNodeProto("Metal-1-N-Active-Con");
PortProto mnacport = mnac.getPort(0);
double aaa = 17;
double[] mnacbox = {-aaa*lambda/2, aaa*lambda/2, -aaa*lambda/2, aaa*lambda/2};
NodeProto mpac = tech.findNodeProto("Metal-1-P-Active-Con");
PortProto mpacport = mpac.getPort(0);
double[] mpacbox = {-aaa*lambda/2, aaa*lambda/2, -aaa*lambda/2, aaa*lambda/2};
NodeProto mpwc = tech.findNodeProto("Metal-1-P-Well-Con");
PortProto mpwcport = mpwc.getPort(0);
double[] mpwcbox = {-17*lambda/2, 17*lambda/2, -17*lambda/2, 17*lambda/2};
NodeProto mnwc = tech.findNodeProto("Metal-1-N-Well-Con");
PortProto mnwcport = mnwc.getPort(0);
double nwellx = 29;
double nwelly = 17;
double[] mnwcbox ={-nwellx*lambda/2,nwellx*lambda/2,-nwelly*lambda/2,nwelly*lambda/2};
NodeProto mpc = tech.findNodeProto("Metal-1-Polysilicon-1-Con");
PortProto mpcport = mpc.getPort(0);
double mx = 5;
double[] mpcbox = {-mx*lambda/2, mx*lambda/2, -mx*lambda/2, mx*lambda/2};
NodeProto m1m2c = tech.findNodeProto("Metal-1-Metal-2-Con");
PortProto m1m2cport = m1m2c.getPort(0);
double[] m1m2cbox = {-mx*lambda/2, mx*lambda/2, -mx*lambda/2, mx*lambda/2};
NodeProto nsnode = tech.findNodeProto("N-Select-Node");
ArcProto parc = tech.findArcProto("Polysilicon-1");
ArcProto m1arc = tech.findArcProto("Metal-1");
ArcProto m2arc = tech.findArcProto("Metal-2");
ArcProto ndiffarc = tech.findArcProto("N-Active");
ArcProto pdiffarc = tech.findArcProto("P-Active");
// create a cell called "romplane{lay}" in the destination library
Cell romplane = Cell.newInstance(destLib, rp+"{lay}");
makeCStyleNodeInst(pwnode,-4*lambda,(8*lambda*(inputs+2)),
-4*lambda,3*8*lambda*(wordlines)/2,0,0,romplane);
double ptranssize = 20;
makeCStyleNodeInst(psnode,-28*lambda,(ptranssize-28)*lambda,4*lambda,
(4+3*8*wordlines/2)*lambda,0,0,romplane);
makeCStyleNodeInst(nsnode,0*lambda,(8*lambda*inputs),4*lambda,
(4+3*8*wordlines/2)*lambda,0,0,romplane);
makeCStyleNodeInst(nwnode,-38*lambda,(ptranssize-38)*lambda,20*lambda,
(4+3*8*wordlines/2)*lambda,0,0,romplane);
// Create instances of objects on rom plane
x = 0;
for (i=0; i<inputs+1; i++)
{
x += 8*lambda;
y = 0;
if (i < inputs)
{
andtrans[0][i] =
makeCStyleNodeInst(ppin, ppinbox[0]+x, ppinbox[1]+x, ppinbox[2],
ppinbox[3], 0, 0, romplane);
m1polypins[i] =
makeCStyleNodeInst(mpc, mpcbox[0]+x, mpcbox[1]+x, mpcbox[2],
mpcbox[3], 0, 0, romplane);
m1m2pins[i] =
makeCStyleNodeInst(m1m2c, m1m2cbox[0]+x, m1m2cbox[1]+x,
m1m2cbox[2], m1m2cbox[3], 0, 0, romplane);
ap1 = m1m2pins[i];
apport1 = m1m2cport;
makeCStyleExport(romplane, ap1, apport1, "wordline_"+(inputs-i-1), PortCharacteristic.IN);
}
for (m=0; m<wordlines; m++)
{
y += 8*lambda;
if (m%2 == 1)
{
if (i%2 == 1)
{
gndpins[m/2][i] =
makeCStyleNodeInst(mnac, mnacbox[0]+x-4*lambda,
mnacbox[1]+x-4*lambda, mnacbox[2]+y,
mnacbox[3]+y, 0, 0, romplane);
gndports[m/2][i] = mnacport;
} else
{
if (i == inputs)
{
gndpins[m/2][i] =
makeCStyleNodeInst(mpwc, mpwcbox[0]+x-4*lambda,
mpwcbox[1]+x-4*lambda, mpwcbox[2]+y,
mpwcbox[3]+y, 0, 0, romplane);
gndports[m/2][i] = mpwcport;
} else
{
gndpins[m/2][i] =
makeCStyleNodeInst(m1pin, m1pinbox[0]+x-4*lambda,
m1pinbox[1]+x-4*lambda, m1pinbox[2]+y, m1pinbox[3]+y,
0, 0, romplane);
gndports[m/2][i] = m1pinport;
}
}
if (i == 0)
{
gnd_2pins[m/2] =
makeCStyleNodeInst(m1pin, m1pinbox[0]+x-12*lambda,
m1pinbox[1]+x-12*lambda, m1pinbox[2]+y, m1pinbox[3]+y,
0, 0, romplane);
gnd_2ports[m/2] = m1pinport;
if (m == 1)
{
gndm1ex[m/2] =
makeCStyleNodeInst(m1pin, m1pinbox[0]+x-12*lambda,
m1pinbox[1]+x-12*lambda,
m1pinbox[2]+y-16*lambda,
m1pinbox[3]+y-16*lambda, 0, 0, romplane);
gndm1export[m/2] = m1pinport;
gnd1pin =
makeCStyleNodeInst(m1pin, m1pinbox[0]+x-8*lambda,
m1pinbox[1]+x-8*lambda,
m1pinbox[2]+y-16*lambda,
m1pinbox[3]+y-16*lambda, 0, 0, romplane);
gnd1port = m1pinport;
vdd2pin =
makeCStyleNodeInst(m2pin, m2pinbox[0]+x-32*lambda,
m2pinbox[1]+x-32*lambda,
m2pinbox[2]+y-16*lambda,
m2pinbox[3]+y-16*lambda, 0, 0, romplane);
vdd2port = m2pinport;
}
}
y+= 8*lambda;
}
if (i < inputs)
{
if (romarray[m][i] == 1)
{
// create a transistor
andtrans[m+1][i] =
makeCStyleNodeInst(nmos, nmosbox[0]+x, nmosbox[1]+x,
nmosbox[2]+y, nmosbox[3]+y,1,0,romplane);
} else
{
andtrans[m+1][i] =
makeCStyleNodeInst(ppin, ppinbox[0]+x, ppinbox[1]+x,
ppinbox[2]+y,ppinbox[3]+y,0,0,romplane);
}
}
boolean transcont = false;
if (i < inputs) transcont = (romarray[m][i] == 1);
if (i > 1) transcont |= (romarray[m][i-1] == 1);
if (i%2 == 0 && transcont)
{
minpins[m][i] =
makeCStyleNodeInst(mnac, mnacbox[0]+x-4*lambda,
mnacbox[1]+x-4*lambda, mnacbox[2]+y,
mnacbox[3]+y, 0, 0, romplane);
diffpins[m][i] =
makeCStyleNodeInst(m1pin, m1pinbox[0]+x-4*lambda,
m1pinbox[1]+x-4*lambda, m1pinbox[2]+y,
m1pinbox[3]+y, 0, 0, romplane);
minports[m][i] = mnacport;
} else
{
minpins[m][i] =
makeCStyleNodeInst(m1pin, m1pinbox[0]+x-4*lambda,
m1pinbox[1]+x-4*lambda, m1pinbox[2]+y,
m1pinbox[3]+y, 0, 0, romplane);
if ((transcont) || ((i==1) && (romarray[m][0] == 1))) {
diffpins[m][i] =
makeCStyleNodeInst(diffpin, diffpinbox[0]+x-4*lambda,
diffpinbox[1]+x-4*lambda, diffpinbox[2]+y,
diffpinbox[3]+y, 0, 0, romplane);
} else
{
diffpins[m][i] =
makeCStyleNodeInst(m1pin, m1pinbox[0]+x-4*lambda,
m1pinbox[1]+x-4*lambda,m1pinbox[2]+y,m1pinbox[3]+y,
0, 0, romplane);
}
minports[m][i] = m1pinport;
}
if (i == inputs)
{
ap1 = minpins[m][i];
apport1 = minports[m][i];
makeCStyleExport(romplane, ap1, apport1, "out_"+m, PortCharacteristic.OUT);
}
if (i == 0)
{
if (m%2 == 1)
{
nwellc[m/2] =
makeCStyleNodeInst(mnwc, m1m2cbox[0]+x-46*lambda,
mnwcbox[1]+x-46*lambda, mnwcbox[2]+y,
mnwcbox[3]+y, 0, 0, romplane);
nwellcports[m/2] = mnwcport;
}
m1m2_2pins[m] =
makeCStyleNodeInst(m1m2c, m1m2cbox[0]+x-4*lambda,
m1m2cbox[1]+x-4*lambda, m1m2cbox[2]+y,
m1m2cbox[3]+y, 0, 0, romplane);
m1m2_2ports[m] = m1m2cport;
m1m2_3pins[m] =
makeCStyleNodeInst(m1m2c, m1m2cbox[0]+x-20*lambda,
m1m2cbox[1]+x-20*lambda, m1m2cbox[2]+y,
m1m2cbox[3]+y, 0, 0, romplane);
m1m2_3ports[m] = m1m2cport;
mpac_1pins[m] =
makeCStyleNodeInst(mpac, mpacbox[0]+x-20*lambda,
mpacbox[1]+x-20*lambda, mpacbox[2]+y,
mpacbox[3]+y, 0, 0, romplane);
mpac_1ports[m] = mpacport;
pulluptrans[m] =
makeCStyleNodeInst(pmos, pmosbox[0]+x-26*lambda,
pmosbox[1]+x-26*lambda, pmosbox[2]+y,
pmosbox[3]+y, 1, 0, romplane);
mpac_2pins[m] =
makeCStyleNodeInst(mpac, mpacbox[0]+x-32*lambda,
mpacbox[1]+x-32*lambda, mpacbox[2]+y,
mpacbox[3]+y, 0, 0, romplane);
mpac_2ports[m] = mpacport;
m1m2_4pins[m] =
makeCStyleNodeInst(m1m2c, m1m2cbox[0]+x-32*lambda,
m1m2cbox[1]+x-32*lambda, m1m2cbox[2]+y,
m1m2cbox[3]+y, 0, 0, romplane);
m1m2_4ports[m] = m1m2cport;
if (m == 0) {
gndpex[m] =
makeCStyleNodeInst(mpc, mpcbox[0]+x-26*lambda,
mpcbox[1]+x-26*lambda,
mpcbox[2]+y-8*lambda,
mpcbox[3]+y-8*lambda, 0, 0, romplane);
gndpexport[m] = mpcport;
}
}
}
}
// finished placing objects, start wiring arcs
for (i=0; i<inputs; i++)
{
ap1 = andtrans[0][i];
apport1 = ppinport;
appos1 = getCStylePortPosition(ap1, apport1);
ap2 = m1polypins[i];
apport2 = mpcport;
appos2 = getCStylePortPosition(ap2, apport2);
ap3 = m1m2pins[i];
apport3 = m1m2cport;
appos3 = getCStylePortPosition(ap3, apport3);
makeCStyleArcInst(parc, 2*lambda, ap1, apport1, appos1[0],
appos1[1], ap2, apport2, appos2[0], appos2[1]);
makeCStyleArcInst(m1arc, 4*lambda, ap2, apport2, appos2[0],
appos2[1], ap3, apport3, appos3[0], appos3[1]);
}
for (i=0; i<inputs; i++)
{
ap1 = andtrans[0][i];
apport1 = ppinport;
appos1 = getCStylePortPosition(ap1, apport1);
for (m=1; m<wordlines+1; m++)
{
ap2 = andtrans[m][i];
if (romarray[m-1][i] == 1)
{
apport2 = nmosg1port;
apport3 = nmosg2port;
} else
{
apport2 = ppinport;
apport3 = ppinport;
}
appos2 = getCStylePortPosition(ap2, apport2);
appos3 = getCStylePortPosition(ap2, apport3);
makeCStyleArcInst(parc, 2*lambda, ap1, apport1, appos1[0],
appos1[1], ap2, apport2,
appos2[0], appos2[1]);
ap1 = ap2;
apport1 = apport3;
appos1 = appos3;
}
}
// connect m1 wordline lines
for (m=0; m<wordlines; m++)
{
ap1 = minpins[m][0];
apport1 = minports[m][0];
appos1 = getCStylePortPosition(ap1, apport1);
for (i=1; i<inputs+1; i++)
{
ap2 = minpins[m][i];
apport2 = minports[m][i];
appos2 = getCStylePortPosition(ap2, apport2);
makeCStyleArcInst(m1arc, 4*lambda, ap1, apport1, appos1[0],
appos1[1], ap2, apport2,
appos2[0], appos2[1]);
ap1 = ap2;
apport1 = apport2;
appos1 = appos2;
}
}
// connect transistors to wordline lines
for (m=0; m<wordlines; m++)
{
for (i=0; i<inputs; i++)
{
if (romarray[m][i] == 1)
{
// connect transistor
ap1 = andtrans[m+1][i];
gnd1 = ap1;
if (i%2 == 0)
{
apport1 = nmosd1port;
gndport1 = nmosd2port;
ap2 = minpins[m][i];
gnd2 = gndpins[m/2][i+1];
intgnd = diffpins[m][i+1];
} else
{
apport1 = nmosd2port;
gndport1 = nmosd1port;
ap2 = minpins[m][i+1];
gnd2 = gndpins[m/2][i];
intgnd = diffpins[m][i];
}
appos1 = getCStylePortPosition(ap1, apport1);
gndpos1 = getCStylePortPosition(gnd1, gndport1);
apport2 = mnacport;
appos2 = getCStylePortPosition(ap2, apport2);
gndport2 = mnacport;
gndpos2 = getCStylePortPosition(gnd2, gndport2);
intgndport = diffpinport;
intgndpos = getCStylePortPosition(intgnd, intgndport);
makeCStyleArcInst(ndiffarc, 4/*16*/*lambda, ap1, apport1,
appos1[0], appos1[1],
ap2, apport2, appos2[0],
appos2[1]);
makeCStyleArcInst(ndiffarc, 4/*16*/*lambda, gnd1, gndport1,
gndpos1[0], gndpos1[1],
intgnd, intgndport, intgndpos[0],
intgndpos[1]);
makeCStyleArcInst(ndiffarc, 4/*16*/*lambda, intgnd, intgndport,
intgndpos[0], intgndpos[1],
gnd2, gndport2, gndpos2[0],
gndpos2[1]);
}
}
}
// connect ground lines
for (m=0; m<wordlines/2; m++)
{
ap1 = gndpins[m][0];
apport1 = gndports[m][0];
appos1 = getCStylePortPosition(ap1, apport1);
for (i=1; i<inputs+1; i++)
{
ap2 = gndpins[m][i];
apport2 = gndports[m][i];
appos2 = getCStylePortPosition(ap2, apport2);
makeCStyleArcInst(m1arc, 4*lambda, ap1, apport1, appos1[0],
appos1[1], ap2, apport2,
appos2[0], appos2[1]);
if (i == inputs)
{
makeCStyleExport(romplane, ap1, apport1, "romgnd"+m, PortCharacteristic.GND);
}
ap1 = ap2;
apport1 = apport2;
appos1 = appos2;
}
}
// extend the gnd plane
for (m=0; m<wordlines/2; m++)
{
ap1 = gndpins[m][0];
apport1 = gndports[m][0];
appos1 = getCStylePortPosition(ap1, apport1);
ap2 = gnd_2pins[m];
apport2 = gnd_2ports[m];
appos2 = getCStylePortPosition(ap2, apport2);
makeCStyleArcInst(m1arc, 4*lambda, ap1, apport1, appos1[0],
appos1[1], ap2, apport2, appos2[0],
appos2[1]);
}
// tie up all the gndlines
ap1 = gnd_2pins[0];
apport1 = gnd_2ports[0];
appos1 = getCStylePortPosition(ap1, apport1);
for (m=0; m<wordlines/2; m++)
{
ap2 = gnd_2pins[m];
apport2 = gnd_2ports[m];
appos2 = getCStylePortPosition(ap2, apport2);
makeCStyleArcInst(m1arc, 4*lambda, ap1, apport1, appos1[0],
appos1[1], ap2, apport2, appos2[0], appos2[1]);
if (m == (wordlines/2 - 1))
{
makeCStyleExport(romplane, ap2, apport2, "gnd", PortCharacteristic.GND);
}
}
ap2 = gndm1ex[0];
apport2 = gndm1export[0];
appos2 = getCStylePortPosition(ap2, apport2);
makeCStyleArcInst(m1arc, 4*lambda, ap1, apport1, appos1[0],
appos1[1], ap2, apport2, appos2[0], appos2[1]);
ap1 = gnd1pin;
apport1 = gnd1port;
appos1 = getCStylePortPosition(ap1, apport1);
makeCStyleArcInst(m1arc, 4*lambda, ap1, apport1, appos1[0],
appos1[1], ap2, apport2, appos2[0], appos2[1]);
makeCStyleExport(romplane, ap1, apport1, "gndc", PortCharacteristic.GND);
ap1 = gndpex[0];
apport1 = gndpexport[0];
appos1 = getCStylePortPosition(ap1, apport1);
makeCStyleArcInst(m1arc, 4*lambda, ap1, apport1, appos1[0],
appos1[1], ap2, apport2, appos2[0], appos2[1]);
ap2 = pulluptrans[0];
apport2 = pmosg1port;
appos2 = getCStylePortPosition(ap2, apport2);
makeCStyleArcInst(parc, 3*lambda, ap1, apport1, appos1[0],
appos1[1], ap2, apport2, appos2[0], appos2[1]);
// connect m1m2contact from romplane to m1m2contact before pull-up trans
for (m=0; m<wordlines; m++)
{
ap1 = minpins[m][0];
apport1 = minports[m][0];
appos1 = getCStylePortPosition(ap1, apport1);
ap2 = m1m2_2pins[m];
apport2 = m1m2_2ports[m];
appos2 = getCStylePortPosition(ap2, apport2);
ap3 = m1m2_3pins[m];
apport3 = m1m2_3ports[m];
appos3 = getCStylePortPosition(ap3, apport3);
makeCStyleArcInst(m1arc, 4*lambda, ap1, apport1, appos1[0],
appos1[1], ap2, apport2, appos2[0], appos2[1]);
makeCStyleArcInst(m2arc, 4*lambda, ap2, apport2, appos2[0],
appos2[1], ap3, apport3, appos3[0], appos3[1]);
}
// connect m1m2contact from romplane to mpac of pull-up trans
for (m=0; m<wordlines; m++)
{
ap1 = m1m2_3pins[m];
apport1 = m1m2_3ports[m];
appos1 = getCStylePortPosition(ap1, apport1);
ap2 = mpac_1pins[m];
apport2 = mpac_1ports[m];
appos2 = getCStylePortPosition(ap2, apport2);
makeCStyleArcInst(m1arc, 4*lambda, ap1, apport1, appos1[0],
appos1[1], ap2, apport2, appos2[0], appos2[1]);
}
// connect pull-up transistors to the mpac
for (m=0; m<wordlines; m++)
{
ap1 = pulluptrans[m];
ap4 = ap1;
apport4 = pmosd1port;
apport1 = pmosd2port;
ap2= mpac_1pins[m];
ap3= mpac_2pins[m];
apport2 = mpacport;
apport3 = mpacport;
appos1 = getCStylePortPosition(ap1, apport1);
appos4 = getCStylePortPosition(ap4, apport4);
appos2 = getCStylePortPosition(ap2, apport2);
appos3 = getCStylePortPosition(ap3, apport3);
makeCStyleArcInst(pdiffarc, 3/*15*/*lambda, ap1, apport1, appos1[0],
appos1[1], ap2, apport2, appos2[0], appos2[1]);
makeCStyleArcInst(pdiffarc, 3/*15*/*lambda, ap4, apport4, appos4[0],
appos4[1], ap3, apport3, appos3[0], appos3[1]);
}
// connect mpac of pull-up trans to m1m2c
for (m=0; m<wordlines; m++)
{
ap1 = m1m2_4pins[m];
apport1 = m1m2_4ports[m];
appos1 = getCStylePortPosition(ap1, apport1);
ap2 = mpac_2pins[m];
apport2 = mpac_2ports[m];
appos2 = getCStylePortPosition(ap2, apport2);
makeCStyleArcInst(m1arc, 4*lambda, ap1, apport1, appos1[0],
appos1[1], ap2, apport2, appos2[0], appos2[1]);
}
// connect mpac of pull-up trans to m1m2c
for (m=0; m<wordlines; m++)
{
if (m%2 ==1)
{
ap1 = nwellc[m/2];
apport1 = nwellcports[m/2];
appos1 = getCStylePortPosition(ap1, apport1);
ap2 = mpac_2pins[m];
apport2 = mpac_2ports[m];
appos2 = getCStylePortPosition(ap2, apport2);
makeCStyleArcInst(m1arc, 4*lambda, ap1, apport1, appos1[0],
appos1[1], ap2, apport2, appos2[0], appos2[1]);
}
}
// tie up all the vddlines
ap1 = m1m2_4pins[0];
apport1 = m1m2_4ports[0];
appos1 = getCStylePortPosition(ap1, apport1);
for (m=0; m<wordlines; m++)
{
ap2 = m1m2_4pins[m];
apport2 = m1m2_4ports[m];
appos2 = getCStylePortPosition(ap2, apport2);
makeCStyleArcInst(m2arc, 4*lambda, ap1, apport1, appos1[0],
appos1[1], ap2, apport2, appos2[0], appos2[1]);
}
ap2 = vdd2pin;
apport2 = vdd2port;
appos2 = getCStylePortPosition(ap2, apport2);
makeCStyleArcInst(m2arc, 4*lambda, ap1, apport1, appos1[0],
appos1[1], ap2, apport2, appos2[0], appos2[1]);
makeCStyleExport(romplane, ap2, apport2, "vdd", PortCharacteristic.PWR);
// connect poly for the pull-up transistor
for (m=0; m<wordlines-1; m++)
{
ap1 = pulluptrans[m];
apport1 = pmosg2port;
appos1 = getCStylePortPosition(ap1, apport1);
ap2 = pulluptrans[m+1];
apport2 = pmosg1port;
appos2 = getCStylePortPosition(ap2, apport2);
makeCStyleArcInst(parc, 3*lambda, ap1, apport1, appos1[0],
appos1[1], ap2, apport2, appos2[0], appos2[1]);
}
}
/**
*/
private static void decodernmos(Library destLib, double lambda, int bits, String cellname, boolean top)
{
int[][] romplane = generateplane(bits);
int i, m;
double x, y;
NodeInst ap1, ap2, ap3, vdd1, vdd2;
PortProto apport1, apport2, apport3, vddport1, vddport2;
double[] appos1, appos2, appos3, vddpos1, vddpos2;
int inputs = romplane[0].length;
int wordlines = romplane.length;
NodeInst[][] ortrans = new NodeInst[wordlines+3][inputs+2];
NodeInst[][] minpins = new NodeInst[wordlines+2][inputs+2];
NodeInst[][] vddpins = new NodeInst[wordlines][inputs/2];
NodeInst[] pwrpins = new NodeInst[inputs/2];
NodeInst[][] m1m2pins = new NodeInst[wordlines+2][inputs+2];
PortProto[][] minports = new PortProto[wordlines+2][inputs+2];
PortProto[][] vddports = new PortProto[wordlines][inputs/2];
PortProto[] pwrports = new PortProto[inputs/2];
PortProto[][] m1m2ports = new PortProto[wordlines+2][inputs+2];
// get pointers to primitives
NodeProto nmos = tech.findNodeProto("N-Transistor");
PortProto nmosg1port = nmos.findPortProto("poly-right");
PortProto nmosg2port = nmos.findPortProto("poly-left");
PortProto nmosd1port = nmos.findPortProto("diff-top");
PortProto nmosd2port = nmos.findPortProto("diff-bottom");
double[] nmosbox = {-nmos.getDefWidth()/2-lambda/2,
nmos.getDefWidth()/2+lambda/2,
-nmos.getDefHeight()/2,
nmos.getDefHeight()/2};
NodeProto ppin = tech.findNodeProto("Polysilicon-1-Pin");
PortProto ppinport = ppin.getPort(0);
double[] ppinbox = {-ppin.getDefWidth()/2,
ppin.getDefWidth()/2,
-ppin.getDefHeight()/2,
ppin.getDefHeight()/2};
NodeProto m1pin = tech.findNodeProto("Metal-1-Pin");
PortProto m1pinport = m1pin.getPort(0);
double[] m1pinbox = {-m1pin.getDefWidth()/2-lambda/2,
m1pin.getDefWidth()/2+lambda/2,
-m1pin.getDefHeight()/2-lambda/2,
m1pin.getDefHeight()/2+lambda/2};
NodeProto m2pin = tech.findNodeProto("Metal-2-Pin");
PortProto m2pinport = m2pin.getPort(0);
double[] m2pinbox = {-m1pin.getDefWidth()/2-lambda/2,
m1pin.getDefWidth()/2+lambda/2,
-m1pin.getDefHeight()/2-lambda/2,
m1pin.getDefHeight()/2+lambda/2};
NodeProto pwnode = tech.findNodeProto("P-Well-Node");
double mx = 5;
NodeProto mpc = tech.findNodeProto("Metal-1-Polysilicon-1-Con");
PortProto mpcport = mpc.getPort(0);
double[] mpcbox = {-mx*lambda/2, mx*lambda/2, -mx*lambda/2, mx*lambda/2};
NodeProto m1m2c = tech.findNodeProto("Metal-1-Metal-2-Con");
PortProto m1m2cport = m1m2c.getPort(0);
double[] m1m2cbox = {-5*lambda/2, 5*lambda/2, -5*lambda/2, 5*lambda/2};
NodeProto mnac = tech.findNodeProto("Metal-1-N-Active-Con");
PortProto mnacport = mnac.getPort(0);
double aaa = 17;
double[] mnacbox = {-aaa*lambda/2, aaa*lambda/2, -aaa*lambda/2, aaa*lambda/2};
// centers around 6 goes up by multiples of 2
ArcProto parc = tech.findArcProto("Polysilicon-1");
ArcProto m1arc = tech.findArcProto("Metal-1");
ArcProto m2arc = tech.findArcProto("Metal-2");
ArcProto ndiffarc = tech.findArcProto("N-Active");
// create a cell called cellname+"{lay}" in the destination library
Cell decn = Cell.newInstance(destLib, cellname+"{lay}");
NodeProto nsnode = tech.findNodeProto("N-Select-Node");
makeCStyleNodeInst(pwnode,0,(8*lambda*(2*bits+1)), 0,8*lambda*(wordlines+1),0,0,decn);
makeCStyleNodeInst(nsnode,0,(8*lambda*(2*bits+1)), 0,8*lambda*(wordlines+1),0,0,decn);
// Create instances of objects on decoder nmos plane
x = 0;
for (i=0; i<inputs+1; i++)
{
x += 8*lambda;
y = 0;
if (i%2 ==1)
{
x += 0*lambda;
}
if (i < inputs)
{
if (top == true)
{
ortrans[0][i] =
makeCStyleNodeInst(ppin, ppinbox[0]+x, ppinbox[1]+x,
ppinbox[2], ppinbox[3], 0, 0, decn);
} else
{
ortrans[0][i] =
makeCStyleNodeInst(mpc, mpcbox[0]+x, mpcbox[1]+x,
mpcbox[2], mpcbox[3], 0, 0, decn);
}
}
for (m=0; m<wordlines; m++)
{
y += 8*lambda;
if (i%2 == 1)
{
vddpins[m][i/2] =
makeCStyleNodeInst(mnac, mnacbox[0]+x-4*lambda,
mnacbox[1]+x-4*lambda,
mnacbox[2]+y, mnacbox[3]+y, 0, 0, decn);
vddports[m][i/2] = mnacport;
if (m == (wordlines-1))
{
pwrpins[i/2] =
makeCStyleNodeInst(m1pin, m1pinbox[0]+x-4*lambda,
m1pinbox[1]+x-4*lambda,
m1pinbox[2]+y+(8*lambda),
m1pinbox[3]+y+(8*lambda), 0, 0, decn);
pwrports[i/2] = m1pinport;
}
}
if (i < inputs)
{
if (romplane[m][i] == 1)
{
// create a transistor
ortrans[m+1][i] =
makeCStyleNodeInst(nmos, nmosbox[0]+x, nmosbox[1]+x,
nmosbox[2]+y, nmosbox[3]+y, 1, 0, decn);
} else
{
ortrans[m+1][i] =
makeCStyleNodeInst(ppin, ppinbox[0]+x, ppinbox[1]+x,
ppinbox[2]+y, ppinbox[3]+y, 0, 0, decn);
}
if (m == wordlines-1)
{
if (top == true)
{
ortrans[m+2][i] =
makeCStyleNodeInst(mpc, mpcbox[0]+x, mpcbox[1]+x,
mpcbox[2]+y+16*lambda,
mpcbox[3]+y+16*lambda,
0, 0, decn);
} else
{
ortrans[m+2][i] =
makeCStyleNodeInst(ppin, ppinbox[0]+x, ppinbox[1]+x,
ppinbox[2]+y+4*lambda, ppinbox[3]+y+4*lambda,
0, 0, decn);
}
}
}
boolean transcont = false;
if (i < inputs) transcont = (romplane[m][i] == 1);
if (i > 1) transcont |= (romplane[m][i-1] == 1);
if (i%2 == 0 && transcont)
{
minpins[m][i] =
makeCStyleNodeInst(mnac, mnacbox[0]+x-4*lambda,
mnacbox[1]+x-4*lambda, mnacbox[2]+y,
mnacbox[3]+y, 0, 0, decn);
minports[m][i] = mnacport;
m1m2pins[m][i] =
makeCStyleNodeInst(m1m2c, m1m2cbox[0]+x-4*lambda,
m1m2cbox[1]+x-4*lambda, m1m2cbox[2]+y,
m1m2cbox[3]+y, 0, 0, decn);
m1m2ports[m][i] = m1m2cport;
} else
{
minpins[m][i] =
makeCStyleNodeInst(m2pin, m2pinbox[0]+x-4*lambda,
m2pinbox[1]+x-4*lambda, m2pinbox[2]+y,
m2pinbox[3]+y, 0, 0, decn);
minports[m][i] = m2pinport;
if (i==0)
{
m1m2pins[m][i] =
makeCStyleNodeInst(m1m2c, m1m2cbox[0]+x-4*lambda,
m1m2cbox[1]+x-4*lambda, m1m2cbox[2]+y,
m1m2cbox[3]+y, 0, 0, decn);
m1m2ports[m][i] = m1m2cport;
} else
{
m1m2pins[m][i] =
makeCStyleNodeInst(m2pin, m2pinbox[0]+x-4*lambda,
m2pinbox[1]+x-4*lambda, m2pinbox[2]+y,
m2pinbox[3]+y, 0, 0, decn);
m1m2ports[m][i] = m2pinport;
}
}
if (i==0)
{
ap1 = m1m2pins[m][i];
apport1 = m1m2ports[m][i];
makeCStyleExport(decn, ap1, apport1, "mid"+m, PortCharacteristic.IN);
}
}
}
// finished making instances, start making arcs
ap1 = pwrpins[0];
apport1 = pwrports[0];
appos1 = getCStylePortPosition(ap1, apport1);
for (i=1; i<inputs/2; i++)
{
ap2 = pwrpins[i];
apport2 = pwrports[i];
appos2 = getCStylePortPosition(ap2, apport2);
makeCStyleArcInst(m1arc, 4*lambda,
ap1, apport1, appos1[0], appos1[1],
ap2, apport2, appos2[0], appos2[1]);
ap1 = ap2;
apport1 = apport2;
appos1 = appos2;
}
makeCStyleExport(decn, ap1, apport1, "gnd", PortCharacteristic.GND);
m = wordlines - 1;
for (i=0; i<inputs/2; i++)
{
ap1 = vddpins[m][i];
apport1 = vddports[m][i];
appos1 = getCStylePortPosition(ap1, apport1);
ap2 = pwrpins[i];
apport2 = pwrports[i];
appos2 = getCStylePortPosition(ap2, apport2);
makeCStyleArcInst(m1arc, 4*lambda,
ap1, apport1, appos1[0], appos1[1],
ap2, apport2, appos2[0], appos2[1]);
}
// connect polysilicon gates
for (i=0; i<inputs; i++)
{
ap1 = ortrans[wordlines+1][i];
if (top == true)
{
apport1 = mpcport;
} else
{
apport1 = ppinport;
}
appos1 = getCStylePortPosition(ap1, apport1);
if (i%2 == 0)
{
makeCStyleExport(decn, ap1, apport1, "top_in"+(i/2), PortCharacteristic.IN);
} else
{
makeCStyleExport(decn, ap1, apport1, "top_in"+((i-1)/2)+"_b", PortCharacteristic.IN);
}
ap1 = ortrans[0][i];
if (top == true)
{
apport1 = ppinport;
} else
{
apport1 = mpcport;
}
appos1 = getCStylePortPosition(ap1, apport1);
if (i%2 == 0)
{
makeCStyleExport(decn, ap1, apport1, "bot_in"+(i/2), PortCharacteristic.IN);
} else
{
makeCStyleExport(decn, ap1, apport1, "bot_in"+((i-1)/2)+"_b", PortCharacteristic.IN);
}
for (m=1; m<wordlines+1; m++)
{
ap2 = ortrans[m][i];
if (romplane[m-1][i] == 1)
{
apport2 = nmosg1port;
apport3 = nmosg2port;
} else
{
apport2 = ppinport;
apport3 = ppinport;
}
appos2 = getCStylePortPosition(ap2, apport2);
appos3 = getCStylePortPosition(ap2, apport3);
makeCStyleArcInst(parc, 2*lambda,
ap1,apport1,appos1[0],appos1[1],
ap2,apport2,appos2[0],appos2[1]);
ap1 = ap2;
apport1 = apport3;
appos1 = appos3;
}
ap2 = ortrans[wordlines+1][i];
if (top == true)
{
apport2 = mpcport;
apport3 = mpcport;
} else
{
apport2 = ppinport;
apport3 = ppinport;
}
appos2 = getCStylePortPosition(ap2, apport2);
appos3 = getCStylePortPosition(ap2, apport3);
makeCStyleArcInst(parc, 2*lambda,
ap1, apport1, appos1[0], appos1[1],
ap2, apport2, appos2[0], appos2[1]);
}
// connect m2 wordline lines
for (m=0; m<wordlines; m++)
{
ap1 = m1m2pins[m][0];
apport1 = m1m2ports[m][0];
appos1 = getCStylePortPosition(ap1, apport1);
for (i=1; i<inputs+1; i++)
{
ap2 = m1m2pins[m][i];
apport2 = m1m2ports[m][i];
appos2 = getCStylePortPosition(ap2, apport2);
makeCStyleArcInst(m2arc, 4*lambda, ap1, apport1,
appos1[0], appos1[1], ap2, apport2, appos2[0], appos2[1]);
ap1 = ap2;
apport1 = apport2;
appos1 = appos2;
}
makeCStyleExport(decn, ap1, apport1, "word"+m, PortCharacteristic.OUT);
}
// connect transistors to wordline lines
for (m=0; m<wordlines; m++)
{
for (i=0; i<inputs; i++)
{
if (romplane[m][i] == 1)
{
// connect transistor
ap1 = ortrans[m+1][i];
vdd1 = ap1;
if (i%2 == 0)
{
apport1 = nmosd1port;
vddport1 = nmosd2port;
ap2 = minpins[m][i];
ap3 = m1m2pins[m][i];
vdd2 = vddpins[m][i/2];
} else
{
apport1 = nmosd2port;
vddport1 = nmosd1port;
ap2 = minpins[m][i+1];
ap3 = m1m2pins[m][i+1];
vdd2 = vddpins[m][i/2];
}
apport2 = mnacport;
apport3 = m1m2cport;
vddport2 = mnacport;
appos1 = getCStylePortPosition(ap1, apport1);
vddpos1 = getCStylePortPosition(vdd1, vddport1);
appos2 = getCStylePortPosition(ap2, apport2);
appos3 = getCStylePortPosition(ap3, apport3);
vddpos2 = getCStylePortPosition(vdd2, vddport2);
// ndiffarc size centers around 12 and goes up by multiples of 2
makeCStyleArcInst(ndiffarc, 4/*16*/*lambda, ap1, apport1,
appos1[0], appos1[1], ap2,
apport2, appos2[0], appos2[1]);
makeCStyleArcInst(ndiffarc, 4/*16*/*lambda, vdd1, vddport1,
vddpos1[0], vddpos1[1], vdd2,
vddport2, vddpos2[0], vddpos2[1]);
makeCStyleArcInst(m1arc, 4*lambda, ap2, apport2,
appos2[0], appos2[1], ap3,
apport3, appos3[0], appos3[1]);
}
}
}
// connect vdd lines
for (i=0; i<inputs/2; i++)
{
ap1 = vddpins[0][i];
apport1 = vddports[0][i];
appos1 = getCStylePortPosition(ap1, apport1);
for (m=1; m<wordlines; m++)
{
ap2 = vddpins[m][i];
apport2 = vddports[m][i];
appos2 = getCStylePortPosition(ap2, apport2);
makeCStyleArcInst(m1arc, 4*lambda, ap1, apport1,
appos1[0], appos1[1],
ap2, apport2, appos2[0], appos2[1]);
ap1 = ap2;
apport1 = apport2;
appos1 = appos2;
}
}
}
/**
*/
private static void decoderpmos(Library destLib, double lambda, int bits, String cellname, boolean top)
{
int[][] romplane = generateplane(bits);
int i, m;
double x, y;
NodeInst ap1, ap2, ap3, apx, apy;
PortProto apport1, apport2, apport3, apportx, apporty;
double[] appos1, appos2, appos3, apposx, apposy;
int inputs = romplane[0].length;
int wordlines = romplane.length;
NodeInst[][] andtrans = new NodeInst[wordlines+2][inputs+2];
NodeInst[][] minpins = new NodeInst[wordlines+3][inputs+2];
NodeInst[] m1m2pins = new NodeInst[wordlines+2];
NodeInst[] m2pins = new NodeInst[wordlines+2];
NodeInst vddpin = null;
NodeInst vddbpin = null;
NodeInst vddcpin = null;
PortProto[][] minports = new PortProto[wordlines+2][inputs+2];
PortProto[] m1m2ports = new PortProto[wordlines+2];
PortProto[] m2ports = new PortProto[wordlines+2];
PortProto vddport = null;
PortProto vddbport = null;
PortProto vddcport = null;
// get pointers to primitives
NodeProto pmos = tech.findNodeProto("P-Transistor");
PortProto pmosg1port = pmos.findPortProto("poly-right");
PortProto pmosg2port = pmos.findPortProto("poly-left");
PortProto pmosd1port = pmos.findPortProto("diff-top");
PortProto pmosd2port = pmos.findPortProto("diff-bottom");
double[] pmosbox = {-pmos.getDefWidth()/2-lambda/2,
pmos.getDefWidth()/2+lambda/2,
-pmos.getDefHeight()/2,
pmos.getDefHeight()/2};
NodeProto ppin = tech.findNodeProto("Polysilicon-1-Pin");
PortProto ppinport = ppin.getPort(0);
double[] ppinbox = {-ppin.getDefWidth()/2,
ppin.getDefWidth()/2,
-ppin.getDefHeight()/2,
ppin.getDefHeight()/2};
NodeProto m1pin = tech.findNodeProto("Metal-1-Pin");
PortProto m1pinport = m1pin.getPort(0);
double[] m1pinbox = {-m1pin.getDefWidth()/2-lambda/2,
m1pin.getDefWidth()/2+lambda/2,
-m1pin.getDefHeight()/2-lambda/2,
m1pin.getDefHeight()/2+lambda/2};
NodeProto m2pin = tech.findNodeProto("Metal-2-Pin");
PortProto m2pinport = m2pin.getPort(0);
double[] m2pinbox = {-m1pin.getDefWidth()/2-lambda/2,
m1pin.getDefWidth()/2+lambda/2,
-m1pin.getDefHeight()/2-lambda/2,
m1pin.getDefHeight()/2+lambda/2};
double mx = 5;
NodeProto mpc = tech.findNodeProto("Metal-1-Polysilicon-1-Con");
PortProto mpcport = mpc.getPort(0);
double[] mpcbox = {-mx*lambda/2, mx*lambda/2, -mx*lambda/2, mx*lambda/2};
NodeProto m1m2c = tech.findNodeProto("Metal-1-Metal-2-Con");
PortProto m1m2cport = m1m2c.getPort(0);
double[] m1m2cbox = {-5*lambda/2, 5*lambda/2, -5*lambda/2, 5*lambda/2};
NodeProto mpac = tech.findNodeProto("Metal-1-P-Active-Con");
PortProto mpacport = mpac.getPort(0);
double[] mpacbox = {-17*lambda/2, 17*lambda/2, -17*lambda/2, 17*lambda/2};
// centers around 6 goes up my multiple of 2
NodeProto mnwc = tech.findNodeProto("Metal-1-N-Well-Con");
PortProto mnwcport = mnwc.getPort(0);
double[] mnwcbox = {-17*lambda/2, 17*lambda/2, -17*lambda/2, 17*lambda/2};
ArcProto parc = tech.findArcProto("Polysilicon-1");
ArcProto m1arc = tech.findArcProto("Metal-1");
ArcProto m2arc = tech.findArcProto("Metal-2");
ArcProto pdiffarc = tech.findArcProto("P-Active");
NodeProto nwnode = tech.findNodeProto("N-Well-Node");
// create a cell called cellname+"{lay}" in the destination library
Cell decp = Cell.newInstance(destLib, cellname+"{lay}");
NodeProto psnode = tech.findNodeProto("P-Select-Node");
makeCStyleNodeInst(nwnode,0,(8*lambda*(2*bits)),
0,8*lambda*(wordlines+1),0,0,decp);
makeCStyleNodeInst(psnode,0,(8*lambda*(2*bits)),
0,8*lambda*(wordlines+1),0,0,decp);
// Create instances of objects on decoder pmos plane
x = 0;
for (i=0; i<inputs+1; i++)
{
x += 8*lambda;
y = 0;
if (i < inputs)
{
if (top == true)
{
andtrans[0][i] =
makeCStyleNodeInst(ppin, ppinbox[0]+x, ppinbox[1]+x,
ppinbox[2], ppinbox[3], 0, 0, decp);
} else
{
andtrans[0][i] =
makeCStyleNodeInst(mpc, mpcbox[0]+x, mpcbox[1]+x,
mpcbox[2], mpcbox[3], 0, 0, decp);
}
}
for (m=0; m<wordlines; m++)
{
y += 8*lambda;
if (i < inputs)
{
if (romplane[m][i] == 1)
{
// create a transistor
andtrans[m+1][i] =
makeCStyleNodeInst(pmos, pmosbox[0]+x, pmosbox[1]+x,
pmosbox[2]+y, pmosbox[3]+y, 1, 0, decp);
} else
{
andtrans[m+1][i] =
makeCStyleNodeInst(ppin, ppinbox[0]+x, ppinbox[1]+x,
ppinbox[2]+y, ppinbox[3]+y, 0, 0, decp);
}
if (m == wordlines-1)
{
if (top == true)
{
andtrans[m+2][i] =
makeCStyleNodeInst(mpc, mpcbox[0]+x, mpcbox[1]+x,
mpcbox[2]+y+16*lambda,
mpcbox[3]+y+16*lambda,0,0,decp);
} else
{
andtrans[m+2][i] =
makeCStyleNodeInst(ppin, ppinbox[0]+x, ppinbox[1]+x,
ppinbox[2]+y+4*lambda, ppinbox[3]+y+4*lambda,
0, 0, decp);
}
}
}
boolean transcont = false;
if (i < inputs) transcont = (romplane[m][i] == 1);
if (i == 0)
{
m1m2pins[m] =
makeCStyleNodeInst(m1m2c, m1m2cbox[0]+x-4*lambda,
m1m2cbox[1]+x-4*lambda, m1m2cbox[2]+y,
m1m2cbox[3]+y, 0, 0, decp);
m1m2ports[m] = m1m2cport;
}
if (i == (inputs))
{
m2pins[m] =
makeCStyleNodeInst(m2pin, m2pinbox[0]+x-4*lambda,
m2pinbox[1]+x-4*lambda, m2pinbox[2]+y,
m2pinbox[3]+y, 0, 0, decp);
m2ports[m] = m2pinport;
}
if (i >= 1) transcont |= (romplane[m][i-1] == 1);
if (transcont)
{
minpins[m][i] =
makeCStyleNodeInst(mpac, mpacbox[0]+x-4*lambda,
mpacbox[1]+x-4*lambda, mpacbox[2]+y,
mpacbox[3]+y, 0, 0, decp);
minports[m][i] = mpacport;
} else
{
if (i == inputs)
{
minpins[m][i] =
makeCStyleNodeInst(mnwc, mnwcbox[0]+x-4*lambda,
mnwcbox[1]+x-4*lambda, mnwcbox[2]+y,
mnwcbox[3]+y, 0, 0, decp);
minports[m][i] = mnwcport;
} else
{
minpins[m][i] =
makeCStyleNodeInst(m1pin, m1pinbox[0]+x-4*lambda,
m1pinbox[1]+x-4*lambda, m1pinbox[2]+y,
m1pinbox[3]+y, 0, 0, decp);
minports[m][i] = m1pinport;
}
}
if (i == inputs)
{
vddpin =
makeCStyleNodeInst(m1pin, m1pinbox[0]+x-4*lambda,
m1pinbox[1]+x-4*lambda,
m1pinbox[2]+y+8*lambda,
m1pinbox[3]+y+8*lambda, 0, 0, decp);
vddport = m1pinport;
if (m == 0)
{
vddbpin =
makeCStyleNodeInst(m1pin, m1pinbox[0]+x+4*lambda,
m1pinbox[1]+x+4*lambda,
m1pinbox[2]+y+0*lambda,
m1pinbox[3]+y+0*lambda, 0, 0, decp);
vddbport = m1pinport;
}
if (m == wordlines-1)
{
vddcpin =
makeCStyleNodeInst(m1m2c, m1m2cbox[0]+x+4*lambda,
m1m2cbox[1]+x+4*lambda,
m1m2cbox[2]+y+8*lambda,
m1m2cbox[3]+y+8*lambda, 0, 0, decp);
vddcport = m1m2cport;
}
}
}
}
// connect polysilicon gates
for (i=0; i<inputs; i++)
{
ap1 = andtrans[wordlines+1][i];
if (top == true)
{
apport1 = mpcport;
} else
{
apport1 = ppinport;
}
appos1 = getCStylePortPosition(ap1, apport1);
if (i%2 == 0)
{
makeCStyleExport(decp, ap1, apport1, "top_in"+(i/2), PortCharacteristic.IN);
} else
{
makeCStyleExport(decp, ap1, apport1, "top_in"+((i-1)/2)+"_b", PortCharacteristic.IN);
}
ap1 = andtrans[0][i];
if (top == true)
{
apport1 = ppinport;
} else
{
apport1 = mpcport;
}
appos1 = getCStylePortPosition(ap1, apport1);
if (i%2 == 0)
{
makeCStyleExport(decp, ap1, apport1, "bot_in"+(i/2), PortCharacteristic.IN);
} else
{
makeCStyleExport(decp, ap1, apport1, "bot_in"+((i-1)/2)+"_b", PortCharacteristic.IN);
}
for (m=1; m<wordlines+1; m++)
{
ap2 = andtrans[m][i];
if (romplane[m-1][i] == 1)
{
apport2 = pmosg1port;
apport3 = pmosg2port;
} else
{
apport2 = ppinport;
apport3 = ppinport;
}
appos2 = getCStylePortPosition(ap2, apport2);
appos3 = getCStylePortPosition(ap2, apport3);
makeCStyleArcInst(parc,2*lambda,ap1,apport1,appos1[0],
appos1[1],ap2,apport2,appos2[0], appos2[1]);
ap1 = ap2;
apport1 = apport3;
appos1 = appos3;
}
ap2 = andtrans[wordlines+1][i];
if (top == true)
{
apport2 = mpcport;
apport3 = mpcport;
} else
{
apport2 = ppinport;
apport3 = ppinport;
}
appos2 = getCStylePortPosition(ap2, apport2);
appos3 = getCStylePortPosition(ap2, apport3);
makeCStyleArcInst(parc,2*lambda,ap1,apport1,appos1[0],
appos1[1],ap2,apport2,appos2[0], appos2[1]);
}
// connect m1 wordline lines
for (m=0; m<wordlines; m++)
{
ap1 = minpins[m][0];
apport1 = minports[m][0];
appos1 = getCStylePortPosition(ap1, apport1);
for (i=1; i<inputs+1; i++)
{
ap2 = minpins[m][i];
apport2 = minports[m][i];
appos2 = getCStylePortPosition(ap2, apport2);
if (romplane[m][i-1] != 1)
{
makeCStyleArcInst(m1arc,4*lambda,ap1,apport1,appos1[0],
appos1[1],ap2,apport2, appos2[0], appos2[1]);
}
ap1 = ap2;
apport1 = apport2;
appos1 = appos2;
}
}
// connect transistors to wordline lines
for (m=0; m<wordlines; m++)
{
for (i=0; i<inputs; i++)
{
if (romplane[m][i] == 1)
{
ap1 = andtrans[m+1][i];
apport1 = pmosd1port;
apport2 = pmosd2port;
appos1 = getCStylePortPosition(ap1, apport1);
appos2 = getCStylePortPosition(ap1, apport2);
apx = minpins[m][i];
apy = minpins[m][i+1];
apportx = mpacport;
apporty = mpacport;
apposx = getCStylePortPosition(apx, apportx);
apposy = getCStylePortPosition(apy, apporty);
// pdiffarc size centers around 12 and goes up by multiples of 2
makeCStyleArcInst(pdiffarc,4/*16*/*lambda,ap1,apport1,
appos1[0], appos1[1],apx,
apportx,apposx[0],apposx[1]);
makeCStyleArcInst(pdiffarc,4/*16*/*lambda,ap1,apport2,
appos2[0], appos2[1],apy,
apporty,apposy[0],apposy[1]);
}
}
}
// connect ground lines
i = inputs;
ap1 = minpins[0][i];
apport1 = minports[0][i];
appos1 = getCStylePortPosition(ap1, apport1);
for (m=1; m<wordlines; m++)
{
ap2 = minpins[m][i];
apport2 = minports[m][i];
appos2 = getCStylePortPosition(ap2, apport2);
makeCStyleArcInst(m1arc,4*lambda,ap1,apport1,appos1[0],
appos1[1],ap2,apport2,appos2[0], appos2[1]);
ap1 = ap2;
apport1 = apport2;
appos1 = appos2;
}
ap1 = vddpin;
apport1 = vddport;
appos1 = getCStylePortPosition(ap1, apport1);
ap2 = minpins[wordlines-1][inputs];
apport2 = minports[wordlines-1][inputs];
appos2 = getCStylePortPosition(ap2, apport2);
makeCStyleArcInst(m1arc,4*lambda,ap1,apport1,appos1[0],
appos1[1],ap2,apport2,appos2[0], appos2[1]);
ap1 = vddcpin;
apport1 = vddcport;
appos1 = getCStylePortPosition(ap1, apport1);
ap2 = vddpin;
apport2 = vddport;
appos2 = getCStylePortPosition(ap2, apport2);
makeCStyleArcInst(m1arc,4*lambda,ap1,apport1,appos1[0],
appos1[1],ap2,apport2,appos2[0], appos2[1]);
makeCStyleExport(decp, ap1, apport1, "vdd", PortCharacteristic.PWR);
ap1 = vddbpin;
apport1 = vddbport;
appos1 = getCStylePortPosition(ap1, apport1);
ap2 = minpins[0][inputs];
apport2 = minports[0][inputs];
appos2 = getCStylePortPosition(ap2, apport2);
makeCStyleArcInst(m1arc,4*lambda,ap1,apport1,appos1[0],
appos1[1],ap2,apport2,appos2[0], appos2[1]);
makeCStyleExport(decp, ap1, apport1, "vddb", PortCharacteristic.PWR);
// connect metal 2 lines
for (m=0; m<wordlines; m++)
{
ap1 = m1m2pins[m];
apport1 = m1m2ports[m];
appos1 = getCStylePortPosition(ap1,apport1);
ap2 = m2pins[m];
apport2 = m2ports[m];
appos2 = getCStylePortPosition(ap2, apport2);
ap3 = minpins[m][0];
apport3 = minports[m][0];
appos3 = getCStylePortPosition(ap3, apport3);
makeCStyleArcInst(m2arc,4*lambda,ap1,apport1,appos1[0],
appos1[1],ap2,apport2,appos2[0], appos2[1]);
makeCStyleArcInst(m1arc,4*lambda,ap1,apport1,appos1[0],
appos1[1],ap3,apport3,appos3[0], appos3[1]);
makeCStyleExport(decp, ap2, apport2, "word"+m, PortCharacteristic.OUT);
makeCStyleExport(decp, ap1, apport1, "wordin"+m, PortCharacteristic.IN);
}
}
/**
*/
private static int[][] generatemuxarray(int folds, int romoutputs)
{
int muxes = romoutputs/folds;
int[][] muxarray = new int[romoutputs][folds];
for (int i=0; i<muxes; i++)
{
for (int j=0; j<folds; j++)
{
for (int k=0; k<folds; k++)
{
if (j == k)
{
muxarray[i*folds+j][k] = 1;
} else
{
muxarray[i*folds+j][k] = 0;
}
}
}
}
StringBuffer sb = new StringBuffer();
for (int i=0; i<romoutputs; i++)
{
sb = new StringBuffer();
for (int j=0; j<folds; j++)
{
sb.append(Integer.toString(muxarray[i][j]));
}
}
return muxarray;
}
/**
*/
private static void muxplane(Library destLib, double lambda, int folds, int romoutputs, String mp)
{
int[][] muxarray = generatemuxarray(folds,romoutputs);
int muxnumber = folds;
int selects = folds;
int outputbits = romoutputs;
int i, m;
double x, y;
NodeInst ap1, ap2, ap3, apx, apy;
PortProto apport1, apport2, apport3, apportx, apporty;
double[] appos1, appos2, appos3, apposx, apposy;
NodeInst[][] ntrans = new NodeInst[outputbits+2][selects+2];
NodeInst[][] minpins = new NodeInst[outputbits+2][selects+2];
NodeInst[] m1m2pins2 = new NodeInst[outputbits+2];
NodeInst[] m1m2pins = new NodeInst[selects+2];
NodeInst[] m1polypins = new NodeInst[outputbits+2];
PortProto[][] minports = new PortProto[outputbits+2][selects+2];
PortProto[] m1m2ports2 = new PortProto[outputbits+2];
// get pointers to primitives
NodeProto nmos = tech.findNodeProto("N-Transistor");
PortProto nmosg1port = nmos.findPortProto("poly-right");
PortProto nmosg2port = nmos.findPortProto("poly-left");
PortProto nmosd1port = nmos.findPortProto("diff-top");
PortProto nmosd2port = nmos.findPortProto("diff-bottom");
double[] nmosbox = {-nmos.getDefWidth()/2-lambda/2,
nmos.getDefWidth()/2+lambda/2,
-nmos.getDefHeight()/2,
nmos.getDefHeight()/2};
NodeProto ppin = tech.findNodeProto("Polysilicon-1-Pin");
PortProto ppinport = ppin.getPort(0);
double[] ppinbox = {-ppin.getDefWidth()/2,
ppin.getDefWidth()/2,
-ppin.getDefHeight()/2,
ppin.getDefHeight()/2};
NodeProto m1pin = tech.findNodeProto("Metal-1-Pin");
PortProto m1pinport = m1pin.getPort(0);
double[] m1pinbox = {-m1pin.getDefWidth()/2-lambda/2,
m1pin.getDefWidth()/2+lambda/2,
-m1pin.getDefHeight()/2-lambda/2,
m1pin.getDefHeight()/2+lambda/2};
NodeProto m1m2c = tech.findNodeProto("Metal-1-Metal-2-Con");
PortProto m1m2cport = m1m2c.getPort(0);
double[] m1m2cbox = {-5*lambda/2, 5*lambda/2, -5*lambda/2, 5*lambda/2};
NodeProto mnac = tech.findNodeProto("Metal-1-N-Active-Con");
PortProto mnacport = mnac.getPort(0);
double mult = 17;
double[] mnacbox = {-1*mult*lambda/2, mult*lambda/2, -1*mult*lambda/2, mult*lambda/2};
NodeProto mpc = tech.findNodeProto("Metal-1-Polysilicon-1-Con");
PortProto mpcport = mpc.getPort(0);
double mx = 5;
double[] mpcbox = {-mx*lambda/2, mx*lambda/2, -mx*lambda/2, mx*lambda/2};
ArcProto parc = tech.findArcProto("Polysilicon-1");
ArcProto m1arc = tech.findArcProto("Metal-1");
ArcProto m2arc = tech.findArcProto("Metal-2");
ArcProto ndiffarc = tech.findArcProto("N-Active");
NodeProto pwnode = tech.findNodeProto("P-Well-Node");
// create a cell called "muxplane{lay}" in the destination library
Cell muxplane = Cell.newInstance(destLib, mp+"{lay}");
makeCStyleNodeInst(pwnode,-8*lambda,lambda*8*(folds+1),
-8*lambda,8*lambda*3*romoutputs/2,0,0,muxplane);
// Create instances of objects in mux plane
x = 0;
for (i=0; i<selects+1; i++)
{
x += 8*lambda;
y = 0;
if (i < selects)
{
ntrans[0][i] =
makeCStyleNodeInst(ppin, ppinbox[0]+x, ppinbox[1]+x, ppinbox[2],
ppinbox[3], 0, 0, muxplane);
m1polypins[i] =
makeCStyleNodeInst(mpc, mpcbox[0]+x, mpcbox[1]+x, mpcbox[2],
mpcbox[3], 0, 0, muxplane);
m1m2pins[i] =
makeCStyleNodeInst(m1m2c, m1m2cbox[0]+x, m1m2cbox[1]+x, m1m2cbox[2],
m1m2cbox[3], 0, 0, muxplane);
ap1 = m1m2pins[i];
apport1 = m1m2cport;
makeCStyleExport(muxplane, ap1, apport1, "sel"+(selects-i-1), PortCharacteristic.IN);
}
for (m=0; m<outputbits; m++)
{
y += 8*lambda;
if (m%2 == 1)
{
y += 8*lambda;
}
if (i < selects)
{
if (muxarray[m][i] == 1)
{
// create a transistor
ntrans[m+1][i] =
makeCStyleNodeInst(nmos, nmosbox[0]+x, nmosbox[1]+x,
nmosbox[2]+y, nmosbox[3]+y,1,0,muxplane);
} else
{
ntrans[m+1][i] =
makeCStyleNodeInst(ppin, ppinbox[0]+x, ppinbox[1]+x,
ppinbox[2]+y,ppinbox[3]+y,0,0,muxplane);
}
}
boolean transcont = false;
if (i < selects) transcont = (muxarray[m][i] == 1);
if (i == (selects))
{
m1m2pins2[m] =
makeCStyleNodeInst(m1m2c, m1m2cbox[0]+x-4*lambda,
m1m2cbox[1]+x-4*lambda, m1m2cbox[2]+y,
m1m2cbox[3]+y, 0, 0, muxplane);
m1m2ports2[m] = m1m2cport;
}
if (i >= 1) transcont |= (muxarray[m][i-1] == 1);
if (transcont)
{
minpins[m][i] =
makeCStyleNodeInst(mnac, mnacbox[0]+x-4*lambda,
mnacbox[1]+x-4*lambda, mnacbox[2]+y,
mnacbox[3]+y, 0, 0, muxplane);
minports[m][i] = mnacport;
} else
{
minpins[m][i] =
makeCStyleNodeInst(m1pin, m1pinbox[0]+x-4*lambda,
m1pinbox[1]+x-4*lambda, m1pinbox[2]+y,
m1pinbox[3]+y, 0, 0, muxplane);
minports[m][i] = m1pinport;
}
}
}
// finished placing objects, now wire arcs
// connect polysilicon gates
for (i=0; i<selects; i++)
{
ap1 = ntrans[0][i];
apport1 = ppinport;
appos1 = getCStylePortPosition(ap1, apport1);
ap2 = m1polypins[i];
apport2 = mpcport;
appos2 = getCStylePortPosition(ap2, apport2);
ap3 = m1m2pins[i];
apport3 = m1m2cport;
appos3 = getCStylePortPosition(ap3, apport3);
makeCStyleArcInst(parc, 2*lambda, ap1, apport1, appos1[0],
appos1[1],ap2, apport2, appos2[0], appos2[1]);
makeCStyleArcInst(m1arc, 4*lambda, ap2, apport2, appos2[0],
appos2[1],ap3, apport3, appos3[0], appos3[1]);
}
// connect polysilicon gates
for (i=0; i<selects; i++)
{
ap1 = ntrans[0][i];
apport1 = ppinport;
appos1 = getCStylePortPosition(ap1, apport1);
for (m=1; m<outputbits+1; m++)
{
ap2 = ntrans[m][i];
if (muxarray[m-1][i] == 1)
{
apport2 = nmosg1port;
apport3 = nmosg2port;
} else
{
apport2 = ppinport;
apport3 = ppinport;
}
appos2 = getCStylePortPosition(ap2, apport2);
appos3 = getCStylePortPosition(ap2, apport3);
makeCStyleArcInst(parc, 2*lambda, ap1, apport1, appos1[0],
appos1[1], ap2, apport2, appos2[0], appos2[1]);
ap1 = ap2;
apport1 = apport3;
appos1 = appos3;
}
}
// connect m1 wordline lines
for (m=0; m<outputbits; m++)
{
ap1 = minpins[m][0];
apport1 = minports[m][0];
appos1 = getCStylePortPosition(ap1, apport1);
for (i=1; i<selects+1; i++)
{
ap2 = minpins[m][i];
apport2 = minports[m][i];
appos2 = getCStylePortPosition(ap2, apport2);
if (muxarray[m][i-1] != 1)
{
makeCStyleArcInst(m1arc, 4*lambda, ap1, apport1,
appos1[0], appos1[1],
ap2, apport2, appos2[0], appos2[1]);
}
if (i == 1)
{
makeCStyleExport(muxplane, ap1, apport1, "muxin"+m, PortCharacteristic.IN);
}
ap1 = ap2;
apport1 = apport2;
appos1 = appos2;
}
}
// connect transistors to wordline lines
for (m=0; m<outputbits; m++)
{
for (i=0; i<selects; i++)
{
if (muxarray[m][i] == 1)
{
// connect transistor
ap1 = ntrans[m+1][i];
apport1 = nmosd1port;
apport2 = nmosd2port;
appos1 = getCStylePortPosition(ap1, apport1);
appos2 = getCStylePortPosition(ap1, apport2);
apx = minpins[m][i];
apy = minpins[m][i+1];
apportx = mnacport;
apporty = mnacport;
apposx = getCStylePortPosition(apx, apportx);
apposy = getCStylePortPosition(apy, apporty);
makeCStyleArcInst(ndiffarc, 4/*16*/*lambda, ap1, apport1,
appos1[0], appos1[1],
apx, apportx, apposx[0], apposx[1]);
makeCStyleArcInst(ndiffarc, 4/*16*/*lambda, ap1, apport2,
appos2[0], appos2[1],
apy, apporty, apposy[0], apposy[1]);
}
}
}
for(int j = 0 ; j < outputbits; j++)
{
i = selects;
ap1 = minpins[j][i];
apport1 = minports[j][i];
appos1 = getCStylePortPosition(ap1, apport1);
ap2 = m1m2pins2[j];
apport2 = m1m2ports2[j];
appos2 = getCStylePortPosition(ap2, apport2);
makeCStyleArcInst(m1arc, 4*lambda, ap1, apport1, appos1[0],
appos1[1], ap2, apport2, appos2[0], appos2[1]);
}
// connect mux together
for(int j = 0 ; j < outputbits/muxnumber; j++)
{
ap1 = m1m2pins2[j*muxnumber];
apport1 = m1m2ports2[j*muxnumber];
appos1 = getCStylePortPosition(ap1, apport1);
for (m=1+j*muxnumber; m<muxnumber+j*muxnumber; m++) {
ap2 = m1m2pins2[m];
apport2 = m1m2ports2[m];
appos2 = getCStylePortPosition(ap2, apport2);
makeCStyleArcInst(m2arc, 4*lambda, ap1, apport1, appos1[0],
appos1[1],ap2, apport2, appos2[0], appos2[1]);
}
makeCStyleExport(muxplane, ap1, apport1, "muxout"+j, PortCharacteristic.OUT);
}
}
/**
*/
private static void inverterplane(Library destLib, double lambda, int outs, int folds, String ip)
{
int i;
double x, y;
NodeInst ap1, ap2, ap3;
PortProto apport1, apport2, apport3, gndport1, vddport1;
double[] appos1, appos2, appos3, gndpos1, vddpos1;
NodeInst[] ntrans = new NodeInst[outs/folds];
NodeInst[] ptrans = new NodeInst[outs/folds];
NodeInst[] inpins = new NodeInst[outs/folds];
NodeInst[] polypins = new NodeInst[outs/folds];
NodeInst[] intppins = new NodeInst[outs/folds];
NodeInst[] nmospins = new NodeInst[outs/folds];
NodeInst[] pmospins = new NodeInst[outs/folds];
NodeInst[] gndpins = new NodeInst[outs/2];
NodeInst[] vddpins = new NodeInst[outs/2];
NodeInst[] midvddpins = new NodeInst[outs/2];
NodeInst[] gndpins2 = new NodeInst[outs/folds];
NodeInst[] pwellpins2 = new NodeInst[outs/folds];
NodeInst[] vddpins2 = new NodeInst[outs/folds];
NodeInst[] midvddpins2 = new NodeInst[outs/folds];
NodeInst gndc = null;
NodeInst nwellc = null;
NodeInst nwellm = null;
PortProto[] inports = new PortProto[outs/folds];
PortProto[] polyports = new PortProto[outs/folds];
PortProto[] intpports = new PortProto[outs/folds];
PortProto[] nmosports = new PortProto[outs/folds];
PortProto[] pmosports = new PortProto[outs/folds];
PortProto[] gndports = new PortProto[outs/2];
PortProto[] vddports = new PortProto[outs/2];
PortProto[] midvddports = new PortProto[outs/2];
PortProto[] pwellports2 = new PortProto[outs/folds];
PortProto[] gndports2 = new PortProto[outs/folds];
PortProto[] vddports2 = new PortProto[outs/folds];
PortProto[] midvddports2 = new PortProto[outs/folds];
PortProto gndcport = null;
PortProto nwellcport = null;
PortProto nwellmport = null;
// get pointers to primitives
NodeProto nmos = tech.findNodeProto("N-Transistor");
PortProto nmosg1port = nmos.findPortProto("poly-right");
PortProto nmosg2port = nmos.findPortProto("poly-left");
PortProto nmosd1port = nmos.findPortProto("diff-top");
PortProto nmosd2port = nmos.findPortProto("diff-bottom");
double[] nmosbox = {-nmos.getDefWidth()/2-lambda/2,
nmos.getDefWidth()/2+lambda/2,
-nmos.getDefHeight()/2,
nmos.getDefHeight()/2};
NodeProto pmos = tech.findNodeProto("P-Transistor");
PortProto pmosg2port = pmos.findPortProto("poly-left");
PortProto pmosd1port = pmos.findPortProto("diff-top");
PortProto pmosd2port = pmos.findPortProto("diff-bottom");
double[] pmosbox = {-pmos.getDefWidth()/2-lambda/2,
pmos.getDefWidth()/2+lambda/2,
-pmos.getDefHeight()/2,
pmos.getDefHeight()/2};
NodeProto ppin = tech.findNodeProto("Polysilicon-1-Pin");
PortProto ppinport = ppin.getPort(0);
double[] ppinbox = {-ppin.getDefWidth()/2,
ppin.getDefWidth()/2,
-ppin.getDefHeight()/2,
ppin.getDefHeight()/2};
NodeProto nwnode = tech.findNodeProto("N-Well-Node");
NodeProto pwnode = tech.findNodeProto("P-Well-Node");
NodeProto m1m2c = tech.findNodeProto("Metal-1-Metal-2-Con");
PortProto m1m2cport = m1m2c.getPort(0);
double[] m1m2cbox = {-5*lambda/2, 5*lambda/2, -5*lambda/2, 5*lambda/2};
NodeProto mnac = tech.findNodeProto("Metal-1-N-Active-Con");
PortProto mnacport = mnac.getPort(0);
double aaa = 17;
double[] mnacbox = {-aaa*lambda/2, aaa*lambda/2, -aaa*lambda/2, aaa*lambda/2};
NodeProto mpac = tech.findNodeProto("Metal-1-P-Active-Con");
PortProto mpacport = mpac.getPort(0);
double[] mpacbox = {-aaa*lambda/2, aaa*lambda/2, -aaa*lambda/2, aaa*lambda/2}; //
NodeProto mpc = tech.findNodeProto("Metal-1-Polysilicon-1-Con");
PortProto mpcport = mpc.getPort(0);
double mx = -7;
double my = 5;
double[] mpcbox = {-mx*lambda/2, mx*lambda/2, -my*lambda/2, my*lambda/2};
NodeProto mpwc = tech.findNodeProto("Metal-1-P-Well-Con");
PortProto mpwcport = mpwc.getPort(0);
double[] mpwcbox = {-17*lambda/2, 17*lambda/2, -17*lambda/2, 17*lambda/2};
NodeProto mnwc = tech.findNodeProto("Metal-1-N-Well-Con");
PortProto mnwcport = mnwc.getPort(0);
double[] mnwcbox = {-17*lambda/2, 17*lambda/2, -17*lambda/2, 17*lambda/2};
ArcProto parc = tech.findArcProto("Polysilicon-1");
ArcProto m1arc = tech.findArcProto("Metal-1");
ArcProto m2arc = tech.findArcProto("Metal-2");
ArcProto ndiffarc = tech.findArcProto("N-Active");
ArcProto pdiffarc = tech.findArcProto("P-Active");
// create a cell called "inverterplane{lay}" in the destination library
Cell invp = Cell.newInstance(destLib, ip+"{lay}");
makeCStyleNodeInst(pwnode,-32*lambda,(3*lambda*8*outs/2)+8*lambda,
-18*lambda,16*lambda,0,0,invp);
makeCStyleNodeInst(nwnode,-32*lambda,(3*lambda*8*outs/2)+8*lambda,
-34*lambda,-18*lambda,0,0,invp);
// Create instances of objects on inverter plane
x = 0*lambda;
for (i=0; i<outs; i++)
{
x += 8*lambda;
y = 0;
if (folds > 1)
{
if (i % folds == 1)
{
pwellpins2[i/folds] =
makeCStyleNodeInst(mpwc, mpwcbox[0]+x, mpwcbox[1]+x,
mpwcbox[2]+y, mpwcbox[3]+y, 0, 0, invp);
pwellports2[i/folds] = mpwcport;
gndpins2[i/folds] =
makeCStyleNodeInst(mnac, mnacbox[0]+x, mnacbox[1]+x,
mnacbox[2]+y-10*lambda,
mnacbox[3]+y-10*lambda, 0, 0, invp);
gndports2[i/folds] = mnacport;
midvddpins2[i/folds] =
makeCStyleNodeInst(mpac, mpacbox[0]+x, mpacbox[1]+x,
mpacbox[2]+y-26*lambda,
mpacbox[3]+y-26*lambda, 0, 0, invp);
midvddports2[i/folds] = mpacport;
vddpins2[i/folds] =
makeCStyleNodeInst(m1m2c, m1m2cbox[0]+x, m1m2cbox[1]+x,
m1m2cbox[2]+y-26*lambda,
m1m2cbox[3]+y-26*lambda, 0, 0, invp);
vddports2[i/folds] = m1m2cport;
if (i == 1)
{
gndc =
makeCStyleNodeInst(m1m2c, m1m2cbox[0]+x, m1m2cbox[1]+x,
m1m2cbox[2]+y-10*lambda,
m1m2cbox[3]+y-10*lambda, 0, 0, invp);
gndcport = m1m2cport;
makeCStyleExport(invp, gndc, gndcport, "gnd", PortCharacteristic.GND);
}
}
} else
{
if (i%2 == 1)
{
// place gnd, intvdd, vddpins
// pwellpins[i/2] =
// makeCStyleNodeInst(mpwc, mpwcbox[0]+x, mpwcbox[1]+x,
// mpwcbox[2]+y-10*lambda,
// mpwcbox[3]+y-10*lambda, 0, 0, invp);
// pwellports[i/2] = mpwcport;
gndpins[i/2] =
makeCStyleNodeInst(mnac, mnacbox[0]+x, mnacbox[1]+x,
mnacbox[2]+y-10*lambda,
mnacbox[3]+y-10*lambda, 0, 0, invp);
gndports[i/2] = mnacport;
midvddpins[i/2] =
makeCStyleNodeInst(mpac, mpacbox[0]+x, mpacbox[1]+x,
mpacbox[2]+y-26*lambda,
mpacbox[3]+y-26*lambda, 0, 0, invp);
midvddports[i/2] = mpacport;
vddpins[i/2] =
makeCStyleNodeInst(m1m2c, m1m2cbox[0]+x, m1m2cbox[1]+x,
m1m2cbox[2]+y-26*lambda,
m1m2cbox[3]+y-26*lambda, 0, 0, invp);
vddports[i/2] = m1m2cport;
if (i == 1)
{
nwellc =
makeCStyleNodeInst(mnwc, mnwcbox[0]+x-24*lambda,
mnwcbox[1]+x-24*lambda,
mnwcbox[2]+y-26*lambda,
mnwcbox[3]+y-26*lambda, 0, 0, invp);
nwellcport = mnwcport;
nwellm =
makeCStyleNodeInst(m1m2c, m1m2cbox[0]+x-24*lambda,
m1m2cbox[1]+x-24*lambda,
m1m2cbox[2]+y-26*lambda,
m1m2cbox[3]+y-26*lambda, 0, 0, invp);
nwellmport = m1m2cport;
gndc =
makeCStyleNodeInst(m1m2c, m1m2cbox[0]+x, m1m2cbox[1]+x,
m1m2cbox[2]+y-10*lambda,
m1m2cbox[3]+y-10*lambda, 0, 0, invp);
gndcport = m1m2cport;
makeCStyleExport(invp, gndc, gndcport, "gnd", PortCharacteristic.GND);
}
}
}
if (i%2 == 1)
{
x += 8*lambda;
}
if (folds > 1)
{
if (i%folds == 0)
{
inpins[i/folds] =
makeCStyleNodeInst(mpc, mpcbox[0]+x-6*lambda,
mpacbox[1]+x-6*lambda, mpcbox[2]+y,
mpcbox[3]+y, 0, 0, invp);
inports[i/folds] = mpcport;
polypins[i/folds] =
makeCStyleNodeInst(ppin, ppinbox[0]+x, ppinbox[1]+x,
ppinbox[2]+y-6*lambda, ppinbox[3]+y-6*lambda,
0, 0, invp);
polyports[i/folds] = ppinport;
nmospins[i/folds] =
makeCStyleNodeInst(mnac, mnacbox[0]+x, mnacbox[1]+x,
mnacbox[2]+y-10*lambda, mnacbox[3]+y-10*lambda,
0, 0, invp);
nmosports[i/folds] = mnacport;
pmospins[i/folds] =
makeCStyleNodeInst(mpac, mpacbox[0]+x, mpacbox[1]+x,
mpacbox[2]+y-26*lambda, mpacbox[3]+y-26*lambda,
0, 0, invp);
pmosports[i/folds] = mpacport;
}
} else
{
// place inpins, polypins, nmospins, pmospins
inpins[i] =
makeCStyleNodeInst(mpc, mpcbox[0]+x-6*lambda, mpacbox[1]+x-6*lambda,
mpcbox[2]+y, mpcbox[3]+y, 0, 0, invp);
inports[i] = mpcport;
polypins[i] =
makeCStyleNodeInst(ppin, ppinbox[0]+x, ppinbox[1]+x,
ppinbox[2]+y-6*lambda, ppinbox[3]+y-6*lambda,
0, 0, invp);
polyports[i] = ppinport;
nmospins[i] =
makeCStyleNodeInst(mnac, mnacbox[0]+x, mnacbox[1]+x,
mnacbox[2]+y-10*lambda, mnacbox[3]+y-10*lambda,
0, 0, invp);
nmosports[i] = mnacport;
pmospins[i] =
makeCStyleNodeInst(mpac, mpacbox[0]+x, mpacbox[1]+x,
mpacbox[2]+y-26*lambda, mpacbox[3]+y-26*lambda,
0, 0, invp);
pmosports[i] = mpacport;
}
if (folds > 1)
{
if (i%folds == 0)
{
double off = 4*lambda;
ptrans[i/folds] =
makeCStyleNodeInst(pmos, pmosbox[0]+x+off, pmosbox[1]+x+off,
pmosbox[2]+y-26*lambda,
pmosbox[3]+y-26*lambda, 1, 0, invp);
ntrans[i/folds] =
makeCStyleNodeInst(nmos, nmosbox[0]+x+off, nmosbox[1]+x+off,
nmosbox[2]+y-10*lambda,
nmosbox[3]+y-10*lambda, 1, 0, invp);
intppins[i/folds] =
makeCStyleNodeInst(ppin, ppinbox[0]+x+off, ppinbox[1]+x+off,
ppinbox[2]+y-6*lambda, ppinbox[3]+y-6*lambda,
0, 0, invp);
intpports[i/folds] = ppinport;
}
} else
{
double off = 0;
if (i%2 == 0)
{
off = 4*lambda;
} else
{
off = -4*lambda;
}
ptrans[i] =
makeCStyleNodeInst(pmos, pmosbox[0]+x+off, pmosbox[1]+x+off,
pmosbox[2]+y-26*lambda, pmosbox[3]+y-26*lambda,
1, 0, invp);
ntrans[i] =
makeCStyleNodeInst(nmos, nmosbox[0]+x+off, nmosbox[1]+x+off,
nmosbox[2]+y-10*lambda, nmosbox[3]+y-10*lambda,
1, 0, invp);
intppins[i] =
makeCStyleNodeInst(ppin, ppinbox[0]+x+off, ppinbox[1]+x+off,
ppinbox[2]+y-6*lambda, ppinbox[3]+y-6*lambda,
0, 0, invp);
intpports[i] = ppinport;
}
}
// connect transistors to diffusion lines
if (folds > 1)
{
for (i=0; i<outs/folds; i++)
{
ap2 = nmospins[i];
ap3 = gndpins2[i];
ap1 = ntrans[i];
apport1 = nmosd1port;
gndport1 = nmosd2port;
appos1 = getCStylePortPosition(ap1, apport1);
gndpos1 = getCStylePortPosition(ap1, gndport1);
apport2 = mnacport;
appos2 = getCStylePortPosition(ap2, apport2);
apport3 = mnacport;
appos3 = getCStylePortPosition(ap3, apport3);
// ndiffarc size centers around 12 and goes up by multiples of 2
makeCStyleArcInst(ndiffarc, 4/*16*/*lambda, ap1, apport1,
appos1[0], appos1[1],
ap2, apport2, appos2[0], appos2[1]);
makeCStyleArcInst(ndiffarc, 4/*16*/*lambda, ap1, gndport1,
gndpos1[0], gndpos1[1],
ap3, apport3, appos3[0], appos3[1]);
}
} else
{
for (i=0; i<outs; i++)
{
if (i%2 == 0)
{
ap2 = nmospins[i];
ap3 = gndpins[i/2];
} else
{
ap2 = gndpins[i/2];
ap3 = nmospins[i];
}
ap1 = ntrans[i];
apport1 = nmosd1port;
gndport1 = nmosd2port;
appos1 = getCStylePortPosition(ap1, apport1);
gndpos1 = getCStylePortPosition(ap1, gndport1);
apport2 = mnacport;
appos2 = getCStylePortPosition(ap2, apport2);
apport3 = mnacport;
appos3 = getCStylePortPosition(ap3, apport3);
makeCStyleArcInst(ndiffarc, 4/*16*/*lambda, ap1, apport1,
appos1[0], appos1[1],
ap2, apport2, appos2[0], appos2[1]);
makeCStyleArcInst(ndiffarc, 4/*16*/*lambda, ap1, gndport1,
gndpos1[0], gndpos1[1],
ap3, apport3, appos3[0], appos3[1]);
}
}
if (folds >1)
{
for (i=0; i<outs/folds; i++)
{
ap2 = pmospins[i];
ap3 = midvddpins2[i];
ap1 = ptrans[i];
ap1 = ptrans[i];
apport1 = pmosd1port;
vddport1 = pmosd2port;
appos1 = getCStylePortPosition(ap1, apport1);
vddpos1 = getCStylePortPosition(ap1, vddport1);
apport2 = mpacport;
appos2 = getCStylePortPosition(ap2, apport2);
apport3 = mpacport;
appos3 = getCStylePortPosition(ap3, apport3);
makeCStyleArcInst(pdiffarc, 4/*16*/*lambda, ap1, apport1,
appos1[0], appos1[1],
ap2, apport2, appos2[0], appos2[1]);
makeCStyleArcInst(pdiffarc, 4/*16*/*lambda, ap1, vddport1,
vddpos1[0], vddpos1[1],
ap3, apport3, appos3[0], appos3[1]);
}
} else
{
// connect transistors to diffusion lines
for (i=0; i<outs; i++)
{
if (i%2 == 0)
{
ap2 = pmospins[i];
ap3 = midvddpins[i/2];
} else
{
ap2 = midvddpins[i/2];
ap3 = pmospins[i];
}
ap1 = ptrans[i];
apport1 = pmosd1port;
vddport1 = pmosd2port;
appos1 = getCStylePortPosition(ap1, apport1);
vddpos1 = getCStylePortPosition(ap1, vddport1);
apport2 = mpacport;
appos2 = getCStylePortPosition(ap2, apport2);
apport3 = mpacport;
appos3 = getCStylePortPosition(ap3, apport3);
makeCStyleArcInst(pdiffarc, 4/*16*/*lambda, ap1, apport1,
appos1[0], appos1[1],
ap2, apport2, appos2[0], appos2[1]);
makeCStyleArcInst(pdiffarc, 4/*16*/*lambda, ap1, vddport1,
vddpos1[0], vddpos1[1],
ap3, apport3, appos3[0], appos3[1]);
}
}
// metal-1 mpac to mnac
for (i=0; i<outs/folds; i++)
{
ap1 = nmospins[i];
apport1 = nmosports[i];
appos1 = getCStylePortPosition(ap1, apport1);
ap2 = pmospins[i];
apport2 = pmosports[i];
appos2 = getCStylePortPosition(ap2, apport2);
makeCStyleArcInst(m1arc, 4*lambda, ap1, apport1, appos1[0],
appos1[1], ap2, apport2, appos2[0], appos2[1]);
}
// poly inpins to polypins
for (i=0; i<outs/folds; i++)
{
ap1 = inpins[i];
apport1 = inports[i];
appos1 = getCStylePortPosition(ap1, apport1);
ap2 = polypins[i];
apport2 = polyports[i];
appos2 = getCStylePortPosition(ap2, apport2);
makeCStyleArcInst(parc, 2*lambda, ap1, apport1, appos1[0],
appos1[1], ap2, apport2, appos2[0], appos2[1]);
}
// poly polypins to intppins
for (i=0; i<outs/folds; i++)
{
ap1 = polypins[i];
apport1 = polyports[i];
appos1 = getCStylePortPosition(ap1, apport1);
ap2 = intppins[i];
apport2 = intpports[i];
appos2 = getCStylePortPosition(ap2, apport2);
makeCStyleArcInst(parc, 2*lambda, ap1, apport1, appos1[0],
appos1[1], ap2, apport2, appos2[0], appos2[1]);
}
// poly intppins to ntrans
for (i=0; i<outs/folds; i++)
{
ap1 = intppins[i];
apport1 = intpports[i];
appos1 = getCStylePortPosition(ap1, apport1);
ap2 = ntrans[i];
apport2 = nmosg2port;
appos2 = getCStylePortPosition(ap2, apport2);
makeCStyleArcInst(parc, 2*lambda, ap1, apport1, appos1[0],
appos1[1], ap2, apport2, appos2[0], appos2[1]);
}
// poly ntrans to ptrans
for (i=0; i<outs/folds; i++)
{
ap1 = ntrans[i];
apport1 = nmosg1port;
appos1 = getCStylePortPosition(ap1, apport1);
ap2 = ptrans[i];
apport2 = pmosg2port;
appos2 = getCStylePortPosition(ap2, apport2);
makeCStyleArcInst(parc, 2*lambda, ap1, apport1, appos1[0],
appos1[1], ap2, apport2, appos2[0], appos2[1]);
}
if (folds > 1)
{
for (i=0; i < outs/folds; i++)
{
ap1 = pwellpins2[i];
apport1 = pwellports2[i];
appos1 = getCStylePortPosition(ap1, apport1);
ap2 = gndpins2[i];
apport2 = gndports2[i];
appos2 = getCStylePortPosition(ap2, apport2);
makeCStyleArcInst(m1arc, 4*lambda, ap1, apport1, appos1[0],
appos1[1], ap2, apport2, appos2[0], appos2[1]);
}
for (i=0; i < outs/folds; i++)
{
ap1 = midvddpins2[i];
apport1 = midvddports2[i];
appos1 = getCStylePortPosition(ap1, apport1);
ap2 = vddpins2[i];
apport2 = vddports2[i];
appos2 = getCStylePortPosition(ap2, apport2);
makeCStyleArcInst(m1arc, 4*lambda, ap1, apport1, appos1[0],
appos1[1], ap2, apport2, appos2[0], appos2[1]);
}
// metal 2 vddpins
ap1 = vddpins2[0];
apport1 = vddports2[0];
appos1 = getCStylePortPosition(ap1, apport1);
for (i=1; i<outs/folds; i++)
{
ap2 = vddpins2[i];
apport2 = vddports2[i];
appos2 = getCStylePortPosition(ap2, apport2);
makeCStyleArcInst(m2arc, 4*lambda, ap1, apport1, appos1[0],
appos1[1], ap2, apport2, appos2[0], appos2[1]);
}
makeCStyleExport(invp, ap1, apport1, "vdd", PortCharacteristic.PWR);
for (i=0; i<outs/folds; i++)
{
ap1 = gndpins2[i];
apport1 = gndports2[i];
makeCStyleExport(invp, ap1, apport1, "invgnd" + i, PortCharacteristic.GND);
}
ap1 = gndpins2[0];
apport1 = gndports2[0];
appos1 = getCStylePortPosition(ap1, apport1);
} else
{
// metal 1 midvddpins to vddpins
for (i=0; i<outs/2; i++)
{
ap1 = midvddpins[i];
apport1 = midvddports[i];
appos1 = getCStylePortPosition(ap1, apport1);
ap2 = vddpins[i];
apport2 = vddports[i];
appos2 = getCStylePortPosition(ap2, apport2);
makeCStyleArcInst(m1arc, 4*lambda, ap1, apport1, appos1[0],
appos1[1], ap2, apport2, appos2[0], appos2[1]);
}
ap1 = vddpins[0];
apport1 = vddports[0];
appos1 = getCStylePortPosition(ap1, apport1);
ap2 = nwellm;
apport2 = nwellmport;
appos2 = getCStylePortPosition(ap2, apport2);
ap3 = nwellc;
apport3 = nwellcport;
appos3 = getCStylePortPosition(ap3, apport3);
makeCStyleArcInst(m2arc, 4*lambda, ap1, apport1, appos1[0],
appos1[1], ap2, apport2, appos2[0], appos2[1]);
makeCStyleArcInst(m1arc, 4*lambda, ap3, apport3, appos3[0],
appos3[1], ap2, apport2, appos2[0], appos2[1]);
// metal 2 vddpins
ap1 = vddpins[0];
apport1 = vddports[0];
appos1 = getCStylePortPosition(ap1, apport1);
for (i=1; i<outs/2; i++)
{
ap2 = vddpins[i];
apport2 = vddports[i];
appos2 = getCStylePortPosition(ap2, apport2);
makeCStyleArcInst(m2arc, 4*lambda, ap1, apport1, appos1[0],
appos1[1], ap2, apport2, appos2[0], appos2[1]);
}
makeCStyleExport(invp, ap1, apport1, "vdd", PortCharacteristic.PWR);
for (i=0; i<outs/2; i++)
{
ap1 = gndpins[i];
apport1 = gndports[i];
makeCStyleExport(invp, ap1, apport1, "invgnd" + i, PortCharacteristic.GND);
}
ap1 = gndpins[0];
apport1 = gndports[0];
appos1 = getCStylePortPosition(ap1, apport1);
}
ap2 = gndc;
apport2 = gndcport;
appos2 = getCStylePortPosition(ap2, apport2);
makeCStyleArcInst(m1arc,4*lambda,ap1,apport1,appos1[0],
appos1[1], ap2, apport2, appos2[0], appos2[1]);
for (i=0; i<outs/folds; i++)
{
ap1 = inpins[i];
apport1 = inports[i];
makeCStyleExport(invp, ap1, apport1, "invin" + i, PortCharacteristic.IN);
}
for (i=0; i<outs/folds; i++)
{
ap1 = pmospins[i];
apport1 = pmosports[i];
makeCStyleExport(invp, ap1, apport1, "invout"+((outs/folds - 1) - i), PortCharacteristic.OUT);
}
}
/**
*/
private static void ininverterplane(Library destLib, double lambda, int outs, String layoutname, boolean top,
int lengthbits)
{
int i;
double x, y;
NodeInst ap1, ap2, ap3;
PortProto apport1, apport2, apport3, gndport1, vddport1;
double[] appos1, appos2, appos3, gndpos1, vddpos1;
NodeInst[] ntrans = new NodeInst[outs];
NodeInst[] ptrans = new NodeInst[outs];
NodeInst[] inpins = new NodeInst[outs];
NodeInst[] inpins2 = new NodeInst[outs];
NodeInst[] outpins = new NodeInst[outs];
NodeInst[] outpins2 = new NodeInst[outs];
NodeInst[] polypins = new NodeInst[outs];
NodeInst[] intppins = new NodeInst[outs];
NodeInst[] polypins2 = new NodeInst[outs];
NodeInst[] intppins2 = new NodeInst[outs];
NodeInst[] gndpins = new NodeInst[outs];
NodeInst[] midvddpins = new NodeInst[outs];
NodeInst[] nmospins = new NodeInst[outs];
NodeInst[] gndpins2 = new NodeInst[outs];
NodeInst[] vddpins = new NodeInst[outs];
NodeInst[] pmospins = new NodeInst[outs];
NodeInst vddc = null;
NodeInst nwellc = null;
NodeInst gndc = null;
NodeInst pwellc = null;
PortProto[] inports = new PortProto[outs];
PortProto[] outports = new PortProto[outs];
PortProto[] inports2 = new PortProto[outs];
PortProto[] outports2 = new PortProto[outs];
PortProto[] polyports = new PortProto[outs];
PortProto[] intpports = new PortProto[outs];
PortProto[] polyports2 = new PortProto[outs];
PortProto[] intpports2 = new PortProto[outs];
PortProto[] nmosports = new PortProto[outs];
PortProto[] pmosports = new PortProto[outs];
PortProto[] gndports = new PortProto[outs];
PortProto[] gndports2 = new PortProto[outs];
PortProto[] vddports = new PortProto[outs];
PortProto[] midvddports = new PortProto[outs];
PortProto vddcport = null;
PortProto nwellport = null;
PortProto gndcport = null;
PortProto pwellport = null;
// get pointers to primitives
NodeProto nmos = tech.findNodeProto("N-Transistor");
PortProto nmosg1port = nmos.findPortProto("poly-right");
PortProto nmosg2port = nmos.findPortProto("poly-left");
PortProto nmosd1port = nmos.findPortProto("diff-top");
PortProto nmosd2port = nmos.findPortProto("diff-bottom");
double[] nmosbox = {-nmos.getDefWidth()/2-lambda/2,
nmos.getDefWidth()/2+lambda/2,
-nmos.getDefHeight()/2,
nmos.getDefHeight()/2};
NodeProto pmos = tech.findNodeProto("P-Transistor");
PortProto pmosg1port = pmos.findPortProto("poly-right");
PortProto pmosg2port = pmos.findPortProto("poly-left");
PortProto pmosd1port = pmos.findPortProto("diff-top");
PortProto pmosd2port = pmos.findPortProto("diff-bottom");
double[] pmosbox = {-pmos.getDefWidth()/2-lambda/2,
pmos.getDefWidth()/2+lambda/2,
-pmos.getDefHeight()/2,
pmos.getDefHeight()/2};
NodeProto ppin = tech.findNodeProto("Polysilicon-1-Pin");
PortProto ppinport = ppin.getPort(0);
double[] ppinbox = {-ppin.getDefWidth()/2,
ppin.getDefWidth()/2,
-ppin.getDefHeight()/2,
ppin.getDefHeight()/2};
NodeProto m1pin = tech.findNodeProto("Metal-1-Pin");
NodeProto m2pin = tech.findNodeProto("Metal-2-Pin");
PortProto m2pinport = m2pin.getPort(0);
double[] m2pinbox = {-m1pin.getDefWidth()/2-lambda/2,
m1pin.getDefWidth()/2+lambda/2,
-m1pin.getDefHeight()/2-lambda/2,
m1pin.getDefHeight()/2+lambda/2};
NodeProto nwnode = tech.findNodeProto("N-Well-Node");
NodeProto pwnode = tech.findNodeProto("P-Well-Node");
NodeProto m1m2c = tech.findNodeProto("Metal-1-Metal-2-Con");
PortProto m1m2cport = m1m2c.getPort(0);
double[] m1m2cbox = {-5*lambda/2, 5*lambda/2, -5*lambda/2, 5*lambda/2};
NodeProto mnac = tech.findNodeProto("Metal-1-N-Active-Con");
PortProto mnacport = mnac.getPort(0);
double aaa = 17;
double[] mnacbox = {-aaa*lambda/2, aaa*lambda/2, -aaa*lambda/2, aaa*lambda/2};
// centers around 6 goes up by multiples of 2
NodeProto mpac = tech.findNodeProto("Metal-1-P-Active-Con");
PortProto mpacport = mpac.getPort(0);
double[] mpacbox = {-aaa*lambda/2, aaa*lambda/2, -aaa*lambda/2, aaa*lambda/2};
// centers around 6 goes up by multiples of 2
double mx = -7;
double my = 5;
NodeProto mpc = tech.findNodeProto("Metal-1-Polysilicon-1-Con");
PortProto mpcport = mpc.getPort(0);
double[] mpcbox = {-mx*lambda/2, mx*lambda/2, -my*lambda/2, my*lambda/2};
NodeProto mpwc = tech.findNodeProto("Metal-1-P-Well-Con");
PortProto mpwcport = mpwc.getPort(0);
double[] mpwcbox = {-17*lambda/2, 17*lambda/2, -17*lambda/2, 17*lambda/2};
NodeProto mnwc = tech.findNodeProto("Metal-1-N-Well-Con");
PortProto mnwcport = mnwc.getPort(0);
double[] mnwcbox = {-17*lambda/2, 17*lambda/2, -17*lambda/2, 17*lambda/2};
ArcProto parc = tech.findArcProto("Polysilicon-1");
ArcProto m1arc = tech.findArcProto("Metal-1");
ArcProto m2arc = tech.findArcProto("Metal-2");
ArcProto ndiffarc = tech.findArcProto("N-Active");
ArcProto pdiffarc = tech.findArcProto("P-Active");
// create a cell called layoutname+lay}" in the destination library
Cell ininvp = Cell.newInstance(destLib, layoutname+"{lay}");
double lowX = -8*lambda;
lowX += 7*lambda;
double highX = (4*lambda*8*lengthbits)+24*lambda;
highX -= 64*lambda;
makeCStyleNodeInst(pwnode, lowX,highX, -18*lambda,10*lambda, 0,0,ininvp);
makeCStyleNodeInst(nwnode, lowX,highX, -36*lambda,-18*lambda, 0,0,ininvp);
// Create instances of objects on input inverter plane
x = 0;
for (i=0; i<outs; i++)
{
x += 8*lambda;
y = 0;
// place inpins, polypins, gndpins, midvddpins
gndpins[i] =
makeCStyleNodeInst(mnac,mnacbox[0]+x,mnacbox[1]+x,mnacbox[2]+y-10*lambda,
mnacbox[3]+y-10*lambda,0,0,ininvp);
gndports[i] = mnacport;
midvddpins[i] =
makeCStyleNodeInst(mpac,mpacbox[0]+x,mpacbox[1]+x,mpacbox[2]+y-26*lambda,
mpacbox[3]+y-26*lambda,0,0,ininvp);
midvddports[i] = mpacport;
double off = 4*lambda;
ptrans[i] =
makeCStyleNodeInst(pmos,pmosbox[0]+x+off,pmosbox[1]+x+off,
pmosbox[2]+y-26*lambda,pmosbox[3]+y-26*lambda,
1,0,ininvp);
ntrans[i] =
makeCStyleNodeInst(nmos,nmosbox[0]+x+off,nmosbox[1]+x+off,
nmosbox[2]+y-10*lambda,nmosbox[3]+y-10*lambda,
1,0,ininvp);
// place gnd, intvdd, vddpins
x += 8*lambda;
polypins[i] =
makeCStyleNodeInst(ppin,ppinbox[0]+x-8*lambda,ppinbox[1]+x-8*lambda,
ppinbox[2]+y-6*lambda,ppinbox[3]+y-6*lambda,
0,0,ininvp);
polyports[i] = ppinport;
inpins[i] =
makeCStyleNodeInst(mpc,mpcbox[0]+x-14*lambda,mpacbox[1]+x-14*lambda,
mpcbox[2]+y,mpcbox[3]+y,0,0,ininvp);
inports[i] = mpcport;
if (top == true)
{
inpins2[i] =
makeCStyleNodeInst(m1m2c,m1m2cbox[0]+x-8*lambda,
m1m2cbox[1]+x-8*lambda,
m1m2cbox[2]+y+(8*lambda*(i+1)),
m1m2cbox[3]+y+(8*lambda*(i+1)),0,0,ininvp);
inports2[i] = m1m2cport;
}
intppins[i] =
makeCStyleNodeInst(ppin,ppinbox[0]+x-off,ppinbox[1]+x-off,
ppinbox[2]+y-6*lambda,ppinbox[3]+y-6*lambda,
0,0,ininvp);
intpports[i] = ppinport;
pmospins[i] =
makeCStyleNodeInst(mpac,mpacbox[0]+x,mpacbox[1]+x,mpacbox[2]+y-26*lambda,
mpacbox[3]+y-26*lambda,0,0,ininvp);
pmosports[i] = mpacport;
vddpins[i] = makeCStyleNodeInst(m1m2c,m1m2cbox[0]+x-8*lambda,
m1m2cbox[1]+x-8*lambda,
m1m2cbox[2]+y-26*lambda,
m1m2cbox[3]+y-26*lambda,0,0,ininvp);
vddports[i] = m1m2cport;
nmospins[i] =
makeCStyleNodeInst(mnac,mnacbox[0]+x,mnacbox[1]+x,mnacbox[2]+y-10*lambda,
mnacbox[3]+y-10*lambda,0,0,ininvp);
nmosports[i] = mnacport;
gndpins2[i] =
makeCStyleNodeInst(m1m2c,m1m2cbox[0]+x-8*lambda,m1m2cbox[1]+x-8*lambda,
m1m2cbox[2]+y-10*lambda,m1m2cbox[3]+y-10*lambda,
0,0,ininvp);
gndports2[i] = m1m2cport;
outpins[i] =
makeCStyleNodeInst(mpc,mpcbox[0]+x-14*lambda,mpacbox[1]+x-14*lambda,
mpcbox[2]+y-36*lambda,mpcbox[3]+y-36*lambda,
0,0,ininvp);
outports[i] = mpcport;
if (top == false)
{
outpins2[i] =
makeCStyleNodeInst(m1m2c,m1m2cbox[0]+x-8*lambda,
m1m2cbox[1]+x-8*lambda,
m1m2cbox[2]+y-(8*lambda*(i+1))-36*lambda,
m1m2cbox[3]+y-(8*lambda*(i+1))-36*lambda,
0,0,ininvp);
outports2[i] = m1m2cport;
}
polypins2[i] =
makeCStyleNodeInst(ppin,ppinbox[0]+x-8*lambda,ppinbox[1]+x-8*lambda,
ppinbox[2]+y-30*lambda,ppinbox[3]+y-30*lambda,
0,0,ininvp);
polyports2[i] = ppinport;
intppins2[i] =
makeCStyleNodeInst(ppin,ppinbox[0]+x-off,ppinbox[1]+x-off,
ppinbox[2]+y-30*lambda,ppinbox[3]+y-30*lambda,
0,0,ininvp);
intpports2[i] = ppinport;
if (i == (outs-1))
{
if (top == true)
{
vddc =
makeCStyleNodeInst(m2pin,m2pinbox[0]+x+12*lambda,
m2pinbox[1]+x+12*lambda,
m2pinbox[2]+y-26*lambda,
m2pinbox[3]+y-26*lambda,0,0,ininvp);
vddcport = m2pinport;
gndc =
makeCStyleNodeInst(m1m2c,m1m2cbox[0]+x+12*lambda,
m1m2cbox[1]+x+12*lambda,
m1m2cbox[2]+y-10*lambda,
m1m2cbox[3]+y-10*lambda,0,0,ininvp);
gndcport = m1m2cport;
pwellc =
makeCStyleNodeInst(mpwc,mpwcbox[0]+x+12*lambda,
mpwcbox[1]+x+12*lambda,mpwcbox[2]+y-10*lambda,
mpwcbox[3]+y-10*lambda,0,0,ininvp);
pwellport = mpwcport;
} else
{
vddc =
makeCStyleNodeInst(m1m2c,m1m2cbox[0]+x+12*lambda,
m1m2cbox[1]+x+12*lambda,
m1m2cbox[2]+y-26*lambda,
m1m2cbox[3]+y-26*lambda,0,0,ininvp);
vddcport = m1m2cport;
nwellc =
makeCStyleNodeInst(mnwc,mnwcbox[0]+x+12*lambda,
mnwcbox[1]+x+12*lambda,mnwcbox[2]+y-26*lambda,
mnwcbox[3]+y-26*lambda,0,0,ininvp);
nwellport = mnwcport;
gndc =
makeCStyleNodeInst(m2pin,m2pinbox[0]+x+12*lambda,
m2pinbox[1]+x+12*lambda,
m2pinbox[2]+y-10*lambda,
m2pinbox[3]+y-10*lambda,0,0,ininvp);
gndcport = m2pinport;
}
}
}
// connect transistors to diffusion lines
for (i=0; i<outs; i++)
{
ap2 = gndpins[i];
ap3 = nmospins[i];
ap1 = ntrans[i];
apport1 = nmosd1port;
gndport1 = nmosd2port;
appos1 = getCStylePortPosition(ap1, apport1);
gndpos1 = getCStylePortPosition(ap1, gndport1);
apport2 = mnacport;
appos2 = getCStylePortPosition(ap2, apport2);
apport3 = mnacport;
appos3 = getCStylePortPosition(ap3, apport3);
// ndiffarc size centers around 12 and goes up by multiples of 2
makeCStyleArcInst(ndiffarc,4/*16*/*lambda,ap1,apport1,appos1[0],
appos1[1],ap2,apport2,appos2[0], appos2[1]);
makeCStyleArcInst(ndiffarc,4/*16*/*lambda,ap1,gndport1,gndpos1[0],
gndpos1[1],ap3,apport3,appos3[0], appos3[1]);
}
// connect transistors to diffusion lines
for (i=0; i<outs; i++)
{
ap2 = midvddpins[i];
ap3 = pmospins[i];
ap1 = ptrans[i];
apport1 = pmosd1port;
vddport1 = pmosd2port;
appos1 = getCStylePortPosition(ap1, apport1);
vddpos1 = getCStylePortPosition(ap1, vddport1);
apport2 = mpacport;
appos2 = getCStylePortPosition(ap2, apport2);
apport3 = mpacport;
appos3 = getCStylePortPosition(ap3, apport3);
// pdiffarc size centers around 12 and goes up by multiples of 2
makeCStyleArcInst(pdiffarc,4/*16*/*lambda,ap1,apport1,appos1[0],
appos1[1],ap2,apport2,appos2[0], appos2[1]);
makeCStyleArcInst(pdiffarc,4/*16*/*lambda,ap1,vddport1,vddpos1[0],
vddpos1[1],ap3,apport3,appos3[0], appos3[1]);
}
// metal-1 mpac to mnac
for (i=0; i<outs; i++)
{
ap1 = nmospins[i];
apport1 = nmosports[i];
appos1 = getCStylePortPosition(ap1, apport1);
ap2 = pmospins[i];
apport2 = pmosports[i];
appos2 = getCStylePortPosition(ap2, apport2);
makeCStyleArcInst(m1arc,4*lambda,ap1,apport1,appos1[0],
appos1[1],ap2,apport2,appos2[0], appos2[1]);
}
if (top == true)
{
ap1 = gndc;
apport1 = gndcport;
appos1 = getCStylePortPosition(ap1, apport1);
ap2 = pwellc;
apport2 = pwellport;
appos2 = getCStylePortPosition(ap2, apport2);
makeCStyleArcInst(m1arc,4*lambda,ap1,apport1,appos1[0],
appos1[1],ap2,apport2,appos2[0], appos2[1]);
} else
{
ap1 = vddc;
apport1 = vddcport;
appos1 = getCStylePortPosition(ap1, apport1);
ap2 = nwellc;
apport2 = nwellport;
appos2 = getCStylePortPosition(ap2, apport2);
makeCStyleArcInst(m1arc,4*lambda,ap1,apport1,appos1[0],
appos1[1],ap2,apport2,appos2[0], appos2[1]);
}
if (top == true)
{
for (i=0; i<outs; i++)
{
ap1 = inpins[i];
apport1 = inports[i];
appos1 = getCStylePortPosition(ap1, apport1);
ap2 = inpins2[i];
apport2 = inports2[i];
appos2 = getCStylePortPosition(ap2, apport2);
makeCStyleArcInst(m1arc,4*lambda,ap1,apport1,appos1[0],
appos1[1],ap2,apport2,appos2[0], appos2[1]);
}
} else
{
for (i=0; i<outs; i++)
{
ap1 = outpins[i];
apport1 = outports[i];
appos1 = getCStylePortPosition(ap1, apport1);
ap2 = outpins2[i];
apport2 = outports2[i];
appos2 = getCStylePortPosition(ap2, apport2);
makeCStyleArcInst(m1arc,4*lambda,ap1,apport1,appos1[0],
appos1[1],ap2,apport2,appos2[0], appos2[1]);
}
}
// poly inpins to polypins
for (i=0; i<outs; i++)
{
ap1 = inpins[i];
apport1 = inports[i];
appos1 = getCStylePortPosition(ap1, apport1);
ap2 = polypins[i];
apport2 = polyports[i];
appos2 = getCStylePortPosition(ap2, apport2);
makeCStyleArcInst(parc,2*lambda,ap1,apport1,appos1[0],
appos1[1],ap2,apport2,appos2[0], appos2[1]);
}
// poly polypins to intppins
for (i=0; i<outs; i++)
{
ap1 = polypins[i];
apport1 = polyports[i];
appos1 = getCStylePortPosition(ap1, apport1);
ap2 = intppins[i];
apport2 = intpports[i];
appos2 = getCStylePortPosition(ap2, apport2);
makeCStyleArcInst(parc,2*lambda,ap1,apport1,appos1[0],
appos1[1],ap2,apport2,appos2[0], appos2[1]);
}
// poly intppins to ntrans
for (i=0; i<outs; i++)
{
ap1 = intppins[i];
apport1 = intpports[i];
appos1 = getCStylePortPosition(ap1, apport1);
ap2 = ntrans[i];
apport2 = nmosg2port;
appos2 = getCStylePortPosition(ap2, apport2);
makeCStyleArcInst(parc,2*lambda,ap1,apport1,appos1[0],
appos1[1],ap2,apport2,appos2[0], appos2[1]);
}
// poly ntrans to ptrans
for (i=0; i<outs; i++)
{
ap1 = ntrans[i];
apport1 = nmosg1port;
appos1 = getCStylePortPosition(ap1, apport1);
ap2 = ptrans[i];
apport2 = pmosg2port;
appos2 = getCStylePortPosition(ap2, apport2);
makeCStyleArcInst(parc,2*lambda,ap1,apport1,appos1[0],
appos1[1],ap2,apport2,appos2[0], appos2[1]);
}
// poly outpins to polypins
for (i=0; i<outs; i++)
{
ap1 = outpins[i];
apport1 = outports[i];
appos1 = getCStylePortPosition(ap1, apport1);
ap2 = polypins2[i];
apport2 = polyports2[i];
appos2 = getCStylePortPosition(ap2, apport2);
makeCStyleArcInst(parc,2*lambda,ap1,apport1,appos1[0],
appos1[1],ap2,apport2,appos2[0], appos2[1]);
}
// poly polypins to intppins
for (i=0; i<outs; i++)
{
ap1 = polypins2[i];
apport1 = polyports2[i];
appos1 = getCStylePortPosition(ap1, apport1);
ap2 = intppins2[i];
apport2 = intpports2[i];
appos2 = getCStylePortPosition(ap2, apport2);
makeCStyleArcInst(parc,2*lambda,ap1,apport1,appos1[0],
appos1[1],ap2,apport2,appos2[0], appos2[1]);
}
// poly outtppins to ptrans
for (i=0; i<outs; i++)
{
ap1 = intppins2[i];
apport1 = intpports2[i];
appos1 = getCStylePortPosition(ap1, apport1);
ap2 = ptrans[i];
apport2 = pmosg1port;
appos2 = getCStylePortPosition(ap2, apport2);
makeCStyleArcInst(parc,2*lambda,ap1,apport1,appos1[0],
appos1[1],ap2,apport2,appos2[0], appos2[1]);
}
// metal 1 pmospins to vddpins
for (i=0; i<outs; i++)
{
ap1 = midvddpins[i];
apport1 = midvddports[i];
appos1 = getCStylePortPosition(ap1, apport1);
ap2 = vddpins[i];
apport2 = vddports[i];
appos2 = getCStylePortPosition(ap2, apport2);
makeCStyleArcInst(m1arc,4*lambda,ap1,apport1,appos1[0],
appos1[1],ap2,apport2,appos2[0], appos2[1]);
}
// metal 1 nmospins to nmospins2
for (i=0; i<outs; i++)
{
ap1 = gndpins[i];
apport1 = gndports[i];
appos1 = getCStylePortPosition(ap1, apport1);
ap2 = gndpins2[i];
apport2 = gndports2[i];
appos2 = getCStylePortPosition(ap2, apport2);
makeCStyleArcInst(m1arc,4*lambda,ap1,apport1,appos1[0],
appos1[1],ap2,apport2,appos2[0], appos2[1]);
}
// metal 2 nmospins
ap1 = gndpins2[0];
apport1 = gndports2[0];
appos1 = getCStylePortPosition(ap1, apport1);
for (i=1; i<outs; i++)
{
ap2 = gndpins2[i];
apport2 = gndports2[i];
appos2 = getCStylePortPosition(ap2, apport2);
makeCStyleArcInst(m2arc,4*lambda,ap1,apport1,appos1[0],
appos1[1],ap2,apport2,appos2[0], appos2[1]);
}
// metal 2 vddpins
ap1 = vddpins[0];
apport1 = vddports[0];
appos1 = getCStylePortPosition(ap1, apport1);
for (i=1; i<outs; i++)
{
ap2 = vddpins[i];
apport2 = vddports[i];
appos2 = getCStylePortPosition(ap2, apport2);
makeCStyleArcInst(m2arc,4*lambda,ap1,apport1,appos1[0],
appos1[1],ap2,apport2,appos2[0], appos2[1]);
}
ap1 = vddpins[0];
apport1 = vddports[0];
appos1 = getCStylePortPosition(ap1, apport1);
ap2 = vddc;
apport2 = vddcport;
appos2 = getCStylePortPosition(ap2, apport2);
makeCStyleArcInst(m2arc,4*lambda,ap1,apport1,appos1[0],
appos1[1],ap2,apport2,appos2[0], appos2[1]);
makeCStyleExport(ininvp, ap2, apport2, "vdd", PortCharacteristic.PWR);
ap1 = gndpins2[0];
apport1 = gndports2[0];
appos1 = getCStylePortPosition(ap1, apport1);
ap2 = gndc;
apport2 = gndcport;
appos2 = getCStylePortPosition(ap2, apport2);
makeCStyleArcInst(m2arc,4*lambda,ap1,apport1,appos1[0],
appos1[1],ap2,apport2,appos2[0], appos2[1]);
makeCStyleExport(ininvp, ap2, apport2, "gnd", PortCharacteristic.GND);
if (top == true)
{
for (i=0; i<outs; i++)
{
ap1 = inpins2[i];
apport1 = inports2[i];
makeCStyleExport(ininvp, ap1, apport1, "in_top" + i, PortCharacteristic.IN);
}
} else
{
for (i=0; i<outs; i++)
{
ap1 = inpins[i];
apport1 = inports[i];
makeCStyleExport(ininvp, ap1, apport1, "in_top" + i, PortCharacteristic.IN);
}
}
if (top == true)
{
for (i=0; i<outs; i++)
{
ap1 = outpins[i];
apport1 = outports[i];
makeCStyleExport(ininvp, ap1, apport1, "in_bot" + i, PortCharacteristic.IN);
}
} else
{
for (i=0; i<outs; i++)
{
ap1 = outpins2[i];
apport1 = outports2[i];
makeCStyleExport(ininvp, ap1, apport1, "in_bot" + i, PortCharacteristic.IN);
}
}
for (i=0; i<outs; i++)
{
ap1 = pmospins[i];
apport1 = pmosports[i];
makeCStyleExport(ininvp, ap1, apport1, "in_b" + i, PortCharacteristic.IN);
}
}
/**
*/
private static int[][] romarraygen(String romfile)
{
boolean end = false;
int[][] returnarray = new int[1][1];
try
{
BufferedReader in = new BufferedReader(new FileReader(romfile));
try
{
int w = -1;
int bits = 0;
StringBuffer sb;
StringBuffer allfile = new StringBuffer();
while (!end)
{
w++;
String temp = in.readLine();
if (temp == null)
{
end = true;
} else
{
sb = new StringBuffer(temp);
if (w==1)
{
bits = sb.length();
}
if (w==0)
{
folds = Integer.parseInt(temp,10);
} else
{
allfile.append(sb);
}
}
}
w--;
// set globalbits
globalbits = w/folds;
returnarray = new int[bits][w];
for (int r=0; r<w; r++)
{
for (int s=0; s<bits; s++)
{
if (allfile.charAt(r*bits + s) == '1')
{
returnarray[s][w-r-1] = 1;
} else
{
returnarray[s][w-r-1] = 0;
}
}
}
} catch (IOException e)
{
}
} catch(FileNotFoundException e)
{
System.out.println(e.toString());
}
return returnarray;
}
/**
*/
private static int[][] generateplane(int bits)
{
int lines = (int) (Math.pow(2.0, bits));
char[][] wordlines = new char[lines][bits];
for (int i = 0; i<lines; i++)
{
int len = Integer.toBinaryString(i).length();
int leadingz = bits - len;
int h;
for (h=0; h<leadingz; h++)
{
wordlines[i][h] = '0';
}
for (int j=h; j<bits; j++)
{
wordlines[i][j] = Integer.toBinaryString(i).charAt(j-h);
}
}
int[][] x = new int[lines][bits];
for (int j = 0; j<lines; j++)
{
for (int k = 0; k<bits; k++)
{
x[j][k] = Character.getNumericValue(wordlines[j][k]);
}
}
int[][] wcomp = new int[lines][2*bits];
for (int j = 0; j<lines; j++)
{
for (int k = 0; k<bits; k++)
{
wcomp[j][(2*k)] = x[j][k];
int complement;
if (x[j][k] == 1)
{
complement = 0;
} else
{
complement = 1;
}
wcomp[j][(2*k)+1] = complement;
}
}
int[][] wcompb = new int[lines][2*bits];
for (int j = 0; j<lines; j++)
{
for (int k = 0; k<(2*bits); k++)
{
wcompb[j][k] = wcomp[j][(2*bits)-1-k];
}
}
return wcompb;
}
/**
* Method to fold the ROM data.
*/
private static int[][] romfold(int[][] romarray)
{
int roma = romarray.length*folds;
int romb = romarray[1].length/folds;
int[][] foldedrom = new int[roma][romb];
for (int i=0; i<romarray.length; i++)
{
for (int j=0; j<folds; j++)
{
for (int k=0; k<romb; k++)
{
foldedrom[folds*i+j][k] = romarray[i][j*romb+k];
}
}
}
return foldedrom;
}
/**
* Method to convert C-style node creation parameters into the real thing.
*/
private static NodeInst makeCStyleNodeInst(NodeProto np, double lX, double hX, double lY, double hY, int trn, int rot, Cell parent)
{
double cX = (lX+hX)/2;
double cY = (lY+hY)/2;
if (np instanceof Cell)
{
// adjust center according to anchor of the cell
Rectangle2D bounds = ((Cell)np).getBounds();
cX -= bounds.getCenterX();
cY -= bounds.getCenterY();
}
double width = hX - lX;
double height = hY - lY;
Orientation orient = Orientation.fromC(rot, trn != 0);
NodeInst ni = NodeInst.makeInstance(np, new Point2D.Double(cX, cY), width, height, parent, orient, null);
// if (trn != 0)
// {
// height = -height;
// rot = (rot + 900) % 3600;
// }
// NodeInst ni = NodeInst.makeInstance(np, new Point2D.Double(cX, cY), width, height, parent, rot, null, 0);
return ni;
}
/**
* Method to convert C-style Arc creation parameters into the real thing.
*/
private static void makeCStyleArcInst(ArcProto ap, double wid, NodeInst hNI, PortProto hPP, double hX, double hY,
NodeInst tNI, PortProto tPP, double tX, double tY)
{
PortInst head = hNI.findPortInstFromProto(hPP);
PortInst tail = tNI.findPortInstFromProto(tPP);
ArcInst.makeInstanceBase(ap, wid, head, tail, new Point2D.Double(hX, hY), new Point2D.Double(tX, tY), null);
// ArcInst.makeInstanceFull(ap, wid, head, tail, new Point2D.Double(hX, hY), new Point2D.Double(tX, tY), null);
}
/**
* Method to create an export on a cell.
* @param parent the Cell in which to create the Export.
* @param ni the NodeInst in the Cell from which to export a port.
* @param pp the PortProto on that NodeInst to export.
* @param name the name of the new Export.
* @param exporttype the Characteristic (in, out, etc.) of the new Export.
*/
private static void makeCStyleExport(Cell parent, NodeInst ni, PortProto pp, String name, PortCharacteristic exporttype)
{
PortInst pi = ni.findPortInstFromProto(pp);
Export.newInstance(parent, pi, name, exporttype);
}
/**
* Method to return an array of two doubles that describes the center of a port.
* @param ni the NodeInst with the port.
* @param pp the PortProto on that NodeInst.
* @return an array of two doubles that describes the X/Y of the center of a port.
*/
private static double [] getCStylePortPosition(NodeInst ni, PortProto pp)
{
PortInst pi = ni.findPortInstFromProto(pp);
Poly poly = pi.getPoly();
double [] ret = new double[2];
ret[0] = poly.getCenterX();
ret[1] = poly.getCenterY();
return ret;
}
}