/* -*- tab-width: 4 -*- * * Electric(tm) VLSI Design System * * File: GateRegression.java * * Copyright (c) 2003 Sun Microsystems and Static Free Software * * Electric(tm) is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * Electric(tm) is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Electric(tm); see the file COPYING. If not, write to * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, Mass 02111-1307, USA. */ package com.sun.electric.tool.generator.layout; import java.lang.reflect.Method; import com.sun.electric.database.hierarchy.Cell; import com.sun.electric.database.hierarchy.Library; import com.sun.electric.database.topology.NodeInst; import com.sun.electric.technology.Technology; import com.sun.electric.tool.Job; import com.sun.electric.tool.JobException; import com.sun.electric.tool.generator.layout.gates.MoCMOSGenerator; import com.sun.electric.tool.io.IOTool; import com.sun.electric.tool.user.User; /* * Regression test for gate generators */ public class GateRegression extends Job { private TechType.TechTypeEnum technology; private int backupScheme; // specify which gates shouldn't be surrounded by DRC rings private static final DrcRings.Filter FILTER = new DrcRings.Filter() { public boolean skip(NodeInst ni) { // well tie cells don't pass DRC with DrcRings return ni.getProto().getName().indexOf("mosWellTie_") != -1; } }; private static void allSizes(StdCellParams stdCell, TechType.TechTypeEnum technology) { double minSz = 0.1; double maxSz = 200;//500; for (double d=minSz; d<maxSz; d*=10) { for (double x=d; x<Math.min(d*10, maxSz); x*=1.01) { aPass(x, stdCell, technology); } } } public static void aPass(double x, StdCellParams stdCell, TechType.TechTypeEnum technology) { if (technology == TechType.TechTypeEnum.MOCMOS || technology == TechType.TechTypeEnum.TSMC180) { MoCMOSGenerator.generateAllGates(x, stdCell); } Technology cmos90 = Technology.getCMOS90Technology(); if (cmos90 != null && technology == TechType.TechTypeEnum.CMOS90) { // invoke the CMOS90 generator by reflection because it may not exist try { Class<?> cmos90GeneratorClass = Class.forName("com.sun.electric.plugins.tsmc.gates90nm.CMOS90Generator"); Class [] parameterTypes = new Class[] {Double.class, StdCellParams.class}; Method generateMethod = cmos90GeneratorClass.getDeclaredMethod("generateAllGates", parameterTypes); generateMethod.invoke(null, new Object[] {new Double(x), stdCell}); } catch (Exception e) { System.out.println("ERROR invoking the CMOS90 gate generator"); } // CMOS90Generator.generateAllGates(x, stdCell); } } public boolean doIt() throws JobException { Library scratchLib = LayoutLib.openLibForWrite("scratch"+technology); runRegression(technology, scratchLib, backupScheme); return true; } /** Programatic interface to gate regressions. * @return the number of errors detected */ public static int runRegression(TechType.TechTypeEnum technology, Library scratchLib, int backupScheme) throws JobException { System.out.println("begin Gate Regression"); // Tech.setTechnology(technology); This call can't be done inside the doIt() because it calls the preferences StdCellParams stdCell; Technology cmos90 = Technology.getCMOS90Technology(); if (cmos90 != null && technology == TechType.TechTypeEnum.CMOS90) { stdCell = new StdCellParams(TechType.TechTypeEnum.CMOS90); stdCell.setOutputLibrary(scratchLib); stdCell.enableNCC("purpleFour"); stdCell.setSizeQuantizationError(0.05); stdCell.setMaxMosWidth(1000); } else { // Test the parameters used by divider stdCell = GateLayoutGenerator.dividerParams(technology); stdCell.setOutputLibrary(scratchLib); stdCell.setSizeQuantizationError(0.05); stdCell.setSimpleName(false); // stdCell = new StdCellParams(scratchLib, Tech.MOCMOS); // stdCell.enableNCC("purpleFour"); // stdCell.setSizeQuantizationError(0.05); // stdCell.setMaxMosWidth(1000); // stdCell.setVddY(21); // stdCell.setGndY(-21); // stdCell.setNmosWellHeight(84); // stdCell.setPmosWellHeight(84); } // a normal run //Inv2iKn.makePart(10, stdCell); //Inv2iKn_wideOutput.makePart(10, stdCell); allSizes(stdCell, technology); // test the ability to move ground bus stdCell.setGndY(stdCell.getGndY() - 7); stdCell.setNmosWellHeight(stdCell.getNmosWellHeight()+7); //allSizes(stdCell, technology); aPass(10, stdCell, technology); aPass(200, stdCell, technology); stdCell.setGndY(stdCell.getGndY() + 7); stdCell.setNmosWellHeight(stdCell.getNmosWellHeight()-7); // test different PMOS to NMOS heights stdCell.setNmosWellHeight(50); stdCell.setPmosWellHeight(100); //allSizes(stdCell, technology); aPass(10, stdCell, technology); aPass(200, stdCell, technology); stdCell.setNmosWellHeight(100); stdCell.setPmosWellHeight(50); //allSizes(stdCell, technology); aPass(10, stdCell, technology); aPass(200, stdCell, technology); stdCell.setNmosWellHeight(70); stdCell.setPmosWellHeight(70); Cell gallery = Gallery.makeGallery(scratchLib); DrcRings.addDrcRings(gallery, FILTER, stdCell); //IOTool.setCIFOutMergesBoxes(true); //int numCifErrs = CIF.writeCIFFile(gallery, VarContext.globalContext, "scratch.cif"); LayoutLib.writeLibrary(scratchLib, backupScheme); System.out.println("done."); // The gate layout generators used to generate layout with no CIF // errors. Then one day the CIF generator changed and began reporting // lots of errors. I'm not sure if the errors are real or not. Until // we understand this I don't think it's important for us to check the // CIF error count in the regression. As long as DRC and NCC pass, // we're happy with the layout. We no longer use CIF. RKao return 0 /*numCifErrs*/; } public GateRegression(TechType.TechTypeEnum techNm) { super("Run Gate regression", User.getUserTool(), Job.Type.CHANGE, null, null, Job.Priority.ANALYSIS); this.technology = techNm; this.backupScheme = IOTool.getBackupRedundancy(); startJob(); } }