2004-06-06 14:13:59 +00:00
|
|
|
/***************************************************************************
|
2005-10-24 06:10:35 +00:00
|
|
|
mosfet.cpp
|
|
|
|
------------
|
2004-06-06 14:13:59 +00:00
|
|
|
begin : Fri Jun 4 2004
|
|
|
|
copyright : (C) 2003 by Michael Margraf
|
2004-06-16 17:41:33 +00:00
|
|
|
email : michael.margraf@alumni.tu-berlin.de
|
2004-06-06 14:13:59 +00:00
|
|
|
***************************************************************************/
|
|
|
|
|
|
|
|
/***************************************************************************
|
|
|
|
* *
|
|
|
|
* This program 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 2 of the License, or *
|
|
|
|
* (at your option) any later version. *
|
|
|
|
* *
|
|
|
|
***************************************************************************/
|
|
|
|
|
|
|
|
#include "mosfet.h"
|
2007-02-19 07:07:50 +00:00
|
|
|
#include "node.h"
|
2015-01-09 18:33:12 +03:00
|
|
|
#include "misc.h"
|
2015-02-20 18:42:16 +03:00
|
|
|
#include "extsimkernels/spicecompat.h"
|
2004-06-06 14:13:59 +00:00
|
|
|
|
|
|
|
|
|
|
|
MOSFET::MOSFET()
|
|
|
|
{
|
2007-02-27 07:04:18 +00:00
|
|
|
// properties obtained from "Basic_MOSFET" in mosfet_sub.cpp
|
2004-06-06 14:13:59 +00:00
|
|
|
Description = QObject::tr("MOS field-effect transistor");
|
2006-04-28 06:04:44 +00:00
|
|
|
createSymbol();
|
|
|
|
tx = x2+4;
|
|
|
|
ty = y1+4;
|
|
|
|
Model = "_MOSFET";
|
2004-06-06 14:13:59 +00:00
|
|
|
}
|
|
|
|
|
2006-04-28 06:04:44 +00:00
|
|
|
// -------------------------------------------------------
|
2004-06-06 14:13:59 +00:00
|
|
|
Component* MOSFET::newOne()
|
|
|
|
{
|
|
|
|
MOSFET* p = new MOSFET();
|
2004-08-08 17:52:32 +00:00
|
|
|
p->Props.first()->Value = Props.first()->Value;
|
|
|
|
p->Props.next()->Value = Props.next()->Value;
|
2005-10-24 06:10:35 +00:00
|
|
|
p->recreate(0);
|
2004-06-06 14:13:59 +00:00
|
|
|
return p;
|
|
|
|
}
|
|
|
|
|
2006-04-28 06:04:44 +00:00
|
|
|
// -------------------------------------------------------
|
2005-06-23 06:06:40 +00:00
|
|
|
Element* MOSFET::info(QString& Name, char* &BitmapFile, bool getNewOne)
|
2004-06-06 14:13:59 +00:00
|
|
|
{
|
|
|
|
Name = QObject::tr("n-MOSFET");
|
2007-09-17 21:57:02 +00:00
|
|
|
BitmapFile = (char *) "nmosfet";
|
2004-06-06 14:13:59 +00:00
|
|
|
|
|
|
|
if(getNewOne) return new MOSFET();
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2006-04-28 06:04:44 +00:00
|
|
|
// -------------------------------------------------------
|
2005-06-23 06:06:40 +00:00
|
|
|
Element* MOSFET::info_p(QString& Name, char* &BitmapFile, bool getNewOne)
|
2004-06-06 14:13:59 +00:00
|
|
|
{
|
|
|
|
Name = QObject::tr("p-MOSFET");
|
2007-09-17 21:57:02 +00:00
|
|
|
BitmapFile = (char *) "pmosfet";
|
2004-06-06 14:13:59 +00:00
|
|
|
|
|
|
|
if(getNewOne) {
|
|
|
|
MOSFET* p = new MOSFET();
|
2004-10-13 19:51:59 +00:00
|
|
|
p->Props.first()->Value = "pfet";
|
|
|
|
p->Props.next()->Value = "-1.0 V";
|
2005-10-24 06:10:35 +00:00
|
|
|
p->recreate(0);
|
2004-06-06 14:13:59 +00:00
|
|
|
return p;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2006-04-28 06:04:44 +00:00
|
|
|
// -------------------------------------------------------
|
2005-06-23 06:06:40 +00:00
|
|
|
Element* MOSFET::info_depl(QString& Name, char* &BitmapFile, bool getNewOne)
|
2004-08-08 17:52:32 +00:00
|
|
|
{
|
|
|
|
Name = QObject::tr("depletion MOSFET");
|
2007-09-17 21:57:02 +00:00
|
|
|
BitmapFile = (char *) "dmosfet";
|
2004-08-08 17:52:32 +00:00
|
|
|
|
|
|
|
if(getNewOne) {
|
|
|
|
MOSFET* p = new MOSFET();
|
|
|
|
p->Props.first();
|
|
|
|
p->Props.next()->Value = "-1.0 V";
|
2005-10-24 06:10:35 +00:00
|
|
|
p->recreate(0);
|
2004-08-08 17:52:32 +00:00
|
|
|
return p;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2006-04-28 06:04:44 +00:00
|
|
|
// -------------------------------------------------------
|
|
|
|
void MOSFET::createSymbol()
|
2004-06-06 14:13:59 +00:00
|
|
|
{
|
2022-02-20 15:43:44 +01:00
|
|
|
Lines.append(new qucs::Line(-14,-13,-14, 13,QPen(Qt::darkBlue,3)));
|
|
|
|
Lines.append(new qucs::Line(-30, 0,-14, 0,QPen(Qt::darkBlue,2)));
|
2006-04-28 06:04:44 +00:00
|
|
|
|
2022-02-20 15:43:44 +01:00
|
|
|
Lines.append(new qucs::Line(-10,-11, 0,-11,QPen(Qt::darkBlue,2)));
|
|
|
|
Lines.append(new qucs::Line( 0,-11, 0,-30,QPen(Qt::darkBlue,2)));
|
|
|
|
Lines.append(new qucs::Line(-10, 11, 0, 11,QPen(Qt::darkBlue,2)));
|
|
|
|
Lines.append(new qucs::Line( 0, 0, 0, 30,QPen(Qt::darkBlue,2)));
|
|
|
|
Lines.append(new qucs::Line(-10, 0, 0, 0,QPen(Qt::darkBlue,2)));
|
2006-04-28 06:04:44 +00:00
|
|
|
|
2022-02-20 15:43:44 +01:00
|
|
|
Lines.append(new qucs::Line(-10,-16,-10, -7,QPen(Qt::darkBlue,3)));
|
|
|
|
Lines.append(new qucs::Line(-10, 7,-10, 16,QPen(Qt::darkBlue,3)));
|
2004-06-06 14:13:59 +00:00
|
|
|
|
2004-08-08 17:52:32 +00:00
|
|
|
if(Props.first()->Value == "nfet") {
|
2022-02-20 15:43:44 +01:00
|
|
|
Lines.append(new qucs::Line( -9, 0, -4, -5,QPen(Qt::darkBlue,2)));
|
|
|
|
Lines.append(new qucs::Line( -9, 0, -4, 5,QPen(Qt::darkBlue,2)));
|
2004-06-06 14:13:59 +00:00
|
|
|
}
|
|
|
|
else {
|
2022-02-20 15:43:44 +01:00
|
|
|
Lines.append(new qucs::Line( -1, 0, -6, -5,QPen(Qt::darkBlue,2)));
|
|
|
|
Lines.append(new qucs::Line( -1, 0, -6, 5,QPen(Qt::darkBlue,2)));
|
2004-06-06 14:13:59 +00:00
|
|
|
}
|
|
|
|
|
2014-11-23 12:24:05 +01:00
|
|
|
if((Props.next()->Value.trimmed().at(0) == '-') ==
|
2006-04-28 06:04:44 +00:00
|
|
|
(Props.first()->Value == "nfet"))
|
2022-02-20 15:43:44 +01:00
|
|
|
Lines.append(new qucs::Line(-10, -8,-10, 8,QPen(Qt::darkBlue,3)));
|
2006-04-28 06:04:44 +00:00
|
|
|
else
|
2022-02-20 15:43:44 +01:00
|
|
|
Lines.append(new qucs::Line(-10, -4,-10, 4,QPen(Qt::darkBlue,3)));
|
2006-04-28 06:04:44 +00:00
|
|
|
|
|
|
|
Ports.append(new Port(-30, 0));
|
|
|
|
Ports.append(new Port( 0,-30));
|
|
|
|
Ports.append(new Port( 0, 30));
|
2004-08-08 17:52:32 +00:00
|
|
|
|
2006-04-28 06:04:44 +00:00
|
|
|
x1 = -30; y1 = -30;
|
|
|
|
x2 = 4; y2 = 30;
|
2004-06-06 14:13:59 +00:00
|
|
|
}
|
2007-02-19 07:07:50 +00:00
|
|
|
|
|
|
|
// -------------------------------------------------------
|
|
|
|
QString MOSFET::netlist()
|
|
|
|
{
|
|
|
|
QString s = "MOSFET:"+Name;
|
|
|
|
|
|
|
|
// output all node names
|
2014-09-03 20:39:51 +02:00
|
|
|
foreach(Port *p1, Ports)
|
2007-02-19 07:07:50 +00:00
|
|
|
s += " "+p1->Connection->Name; // node names
|
|
|
|
s += " "+Ports.at(2)->Connection->Name; // connect substrate to source
|
|
|
|
|
|
|
|
// output all properties
|
|
|
|
for(Property *p2 = Props.first(); p2 != 0; p2 = Props.next())
|
|
|
|
s += " "+p2->Name+"=\""+p2->Value+"\"";
|
|
|
|
|
|
|
|
return s + '\n';
|
|
|
|
}
|
2014-12-24 18:34:34 +03:00
|
|
|
|
2015-01-18 15:24:55 +03:00
|
|
|
QString MOSFET::spice_netlist(bool isXyce)
|
2014-12-24 18:34:34 +03:00
|
|
|
{
|
2015-02-20 18:42:16 +03:00
|
|
|
QString s = spicecompat::check_refdes(Name,SpiceModel);
|
2014-12-24 18:34:34 +03:00
|
|
|
QList<int> pin_seq;
|
|
|
|
pin_seq<<1<<0<<2<<2; // Pin sequence: DGS; coonect substrate to source
|
|
|
|
// output all node names
|
|
|
|
foreach(int pin, pin_seq) {
|
|
|
|
QString nam = Ports.at(pin)->Connection->Name;
|
|
|
|
if (nam=="gnd") nam = "0";
|
|
|
|
s += " "+ nam; // node names
|
|
|
|
}
|
|
|
|
|
|
|
|
QStringList spice_incompat,spice_tr;
|
|
|
|
spice_incompat<<"Type"<<"Temp"<<"L"<<"W"<<"Ad"<<"As"<<"Pd"<<"Ps"
|
|
|
|
<<"Rg"<<"N"<<"Tt"<<"Nrd"<<"Nrs"<<"Ffe";
|
|
|
|
// spice-incompatible parameters
|
2015-01-18 15:24:55 +03:00
|
|
|
if (isXyce) {
|
2022-07-05 07:08:28 -04:00
|
|
|
spice_tr<<"Vt0"<<"VtO"; // parameters that need conversion of names
|
2015-01-18 15:24:55 +03:00
|
|
|
} else {
|
|
|
|
spice_tr.clear();
|
|
|
|
}
|
|
|
|
|
2014-12-24 18:34:34 +03:00
|
|
|
|
2014-12-25 14:14:44 +03:00
|
|
|
QStringList check_defaults_list;
|
|
|
|
QString unit;
|
|
|
|
check_defaults_list<<"Nsub"<<"Nss";
|
|
|
|
foreach (QString parnam,check_defaults_list) { // Check some parameters for default value (zero)
|
|
|
|
double val,fac; // And reduce parameter list
|
2015-03-05 19:12:30 +03:00
|
|
|
misc::str2num(getProperty(parnam)->Value,val,unit,fac);
|
2014-12-25 14:14:44 +03:00
|
|
|
if ((val *= fac)==0.0) {
|
|
|
|
spice_incompat.append(parnam);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-12-24 18:34:34 +03:00
|
|
|
QString par_str = form_spice_param_list(spice_incompat,spice_tr);
|
|
|
|
|
|
|
|
QString mosfet_type = getProperty("Type")->Value.at(0).toUpper();
|
|
|
|
|
|
|
|
double l,w,as,ad,ps,pd,fac;
|
2015-03-05 19:12:30 +03:00
|
|
|
misc::str2num(getProperty("L")->Value,l,unit,fac);
|
2014-12-24 18:34:34 +03:00
|
|
|
l *= fac;
|
2015-03-05 19:12:30 +03:00
|
|
|
misc::str2num(getProperty("W")->Value,w,unit,fac);
|
2014-12-24 18:34:34 +03:00
|
|
|
w *= fac;
|
2015-03-05 19:12:30 +03:00
|
|
|
misc::str2num(getProperty("Ad")->Value,ad,unit,fac);
|
2014-12-24 18:34:34 +03:00
|
|
|
ad *= fac;
|
2015-03-05 19:12:30 +03:00
|
|
|
misc::str2num(getProperty("As")->Value,as,unit,fac);
|
2014-12-24 18:34:34 +03:00
|
|
|
as *= fac;
|
2015-03-05 19:12:30 +03:00
|
|
|
misc::str2num(getProperty("Pd")->Value,pd,unit,fac);
|
2014-12-24 18:34:34 +03:00
|
|
|
pd *= fac;
|
2015-03-05 19:12:30 +03:00
|
|
|
misc::str2num(getProperty("Ps")->Value,ps,unit,fac);
|
2014-12-24 18:34:34 +03:00
|
|
|
ps *= fac;
|
|
|
|
|
|
|
|
s += QString(" MMOD_%1 L=%2 W=%3 Ad=%4 As=%5 Pd=%6 Ps=%7 Temp=%8\n")
|
|
|
|
.arg(Name).arg(l).arg(w).arg(ad).arg(as).arg(pd).arg(ps).arg(getProperty("Temp")->Value);
|
|
|
|
s += QString(".MODEL MMOD_%1 %2MOS (%3)\n").arg(Name).arg(mosfet_type).arg(par_str);
|
|
|
|
|
|
|
|
return s;
|
|
|
|
}
|