/* -*- tab-width: 4 -*- * * Electric(tm) VLSI Design System * * File: Diode.java * * 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.simulation.interval; import com.sun.electric.util.math.MutableInterval; /** * This class contains a set of expressions which defines model equations * of diode. */ public class Diode { final static double CHARGE = 1.6021918e-19; final static double CONSTboltz = 1.3806226e-23; final static double REFTEMP = 300.15; ExprEval ev = new ExprEval(); ExprEval.DoubleConstExpr is = ev.newConst(1e-14); ExprEval.DoubleConstExpr gmin = ev.newConst(0.0); //ExprEval.DoubleConstExpr gmin = ev.newConst(1e-12); ExprEval.DoubleConstExpr vt = ev.newConst(CONSTboltz * REFTEMP / CHARGE); ExprEval.DoubleConstExpr vd = ev.newConst(); ExprEval.DoubleExpr cd; ExprEval.DoubleExpr gd; //ExprEval.DoubleConstExpr rs; //ExprEval.DoubleConstExpr n; //ExprEval.DoubleConstExpr tt; //ExprEval.DoubleConstExpr cjo; //ExprEval.DoubleConstExpr wj; //ExprEval.DoubleConstExpr m; //ExprEval.DoubleConstExpr fc; //ExprEval.DoubleConstExpr temp; Diode() { is.setName("is"); gmin.setName("gmin"); vt.setName("vt"); vd.setName("vd"); // evd = exp(vd/vt) ExprEval.DoubleExpr evd = vd.divide(vt).exp(); evd.setName("evd"); // cdp = is*(evd-1) ExprEval.DoubleExpr cdp = is.multiply(evd.subtract(ev.newConst(1.0))); cdp.setName("cdp"); // gdp = (is/vt)*evd ExprEval.DoubleExpr gdp = is.divide(vt).multiply(evd); gdp.setName("gdp"); // arg = vt*(3/e)/vd ExprEval.DoubleExpr arg = vt.multiply(ev.newConst(3.0/Math.E)).divide(vd); arg.setName("arg"); // arg3 = arg*arg*arg ExprEval.DoubleExpr arg3 = arg.multiply(arg).multiply(arg); arg3.setName("arg3"); // cdm = -is*(1 + arg3) ExprEval.DoubleExpr cdm = is.negate().multiply(ev.newConst(1.0).add(arg3)); cdm.setName("cdm"); // gdm = is*3*arg3/vd ExprEval.DoubleExpr gdm = is.multiply(ev.newConst(3)).multiply(arg3).divide(vd); gdm.setName("gdm"); // direct = (vd >= -3*vt) ExprEval.BooleanExpr direct = vd.ge(ev.newConst(-3).multiply(vt)); direct.setName("direct"); // cd0 = (direct ? cdp : cdm) ExprEval.DoubleExpr cd0 = direct.ite(cdp,cdm); cd0.setName("cd0"); // gd0 = (direct ? gdp : gdm) ExprEval.DoubleExpr gd0 = direct.ite(gdp,gdm); gd0.setName("gd0"); // cd = cd0 + gmin*vd cd = cd0.add(gmin.multiply(vd)); cd.setName("cd"); // gd = gd0 +gmin gd = gd0.add(gmin); gd.setName("gd"); } /** * Test program plots in raw file diode current versus voltage: * at interval [v-delta,v+delta], * and at 3 point of this interval - ceneter and borders */ public static void plotDiode(String filePath) { System.out.println("Plotting Diode graph to file " + filePath); Diode d = new Diode(); //d.ev.printAll(false); double delta = 0.001; int numPoints = 10000; int numVars = 11; RawFile raw = new RawFile(numPoints + 1, numVars); raw.setVar(0, "vd", "voltage"); raw.setVar(1, "j", "current"); raw.setVar(2, "g", "conductance"); raw.setVar(3, "jm", "current"); raw.setVar(4, "gm", "conductance"); raw.setVar(5, "jp", "current"); raw.setVar(6, "gp", "conductance"); raw.setVar(7, "jl", "current"); raw.setVar(8, "gl", "conductance"); raw.setVar(9, "jh", "current"); raw.setVar(10,"gh", "conductance"); for (int k = 0; k <= numPoints; k++) { double vd = -0.2 + 0.3 / numPoints * k; raw.set(k, 0, vd); d.vd.setV(vd); d.ev.calcAll(); raw.set(k, 1, d.cd.v()); raw.set(k, 2, d.gd.v()); d.vd.setV(vd-delta); d.ev.calcAll(); raw.set(k, 3, d.cd.v()); raw.set(k, 4, d.gd.v()); d.vd.setV(vd+delta); d.ev.calcAll(); raw.set(k, 5, d.cd.v()); raw.set(k, 6, d.gd.v()); d.vd.setInterval(vd-delta,vd+delta); d.ev.calcIntervalAll(); raw.set(k, 7, d.cd.inf()); raw.set(k, 8, d.gd.inf()); raw.set(k, 9, d.cd.sup()); raw.set(k, 10, d.gd.sup()); } raw.write(filePath); //raw.writeBinary(filePath, null); } public static void main (String argv[]) { plotDiode("diode.raw"); } }