package TFT; use IniFile; @ISA = qw(IniFile); #公開したいサブルーチン @EXPORT = qw(); use strict; #use warnings; use Math::Matrix; use Math::MatrixReal; use PDL::Opt::Simplex; use Sci::Material; use Deps; use Utils; use JFile; use CSV; use Sci qw($kB $e $e0); #=============================================== # 大域変数 #=============================================== #============================================================ # 変数等取得関数 #============================================================ #============================================================ # コンストラクタ、デストラクタ #============================================================ sub new { my ($module, $app) = @_; my $self = IniFile->new('', 0, 0); my $this = bless $self, ref($module) || $module; $this->SetApplication($app) if($app); return $this; } sub DESTROY { my $this = shift; } #============================================================ # 一般関数 #============================================================ sub SetParameters { my ($this, %args) = @_; Utils::MergeHash($this, \%args); } sub PrepareForCalculation { my ($this) = @_; my $T = $this->{T}; my $W = $this->{W}; my $L = $this->{L}; my $Nes = $this->{Nes} * 1.0e6; my $Epss = $this->{Epss} * $e0; my $uFE = $this->{uFE} * 1.0e-4; my $material = new Material; $this->{Cox} = $material->CalCapacitance($this->{Epsg}, 0.01*0.01, $this->{dg}*1.0e-9) if(!defined $this->{Cox}); # F/cm2 my $Cox = $this->{Cox} * 1.0e4; # my $S = $this->{S}; # my $VB = $this->{VB}; # my $VFB = $this->{VFB}; # my $Vth = $this->{Vth}; $this->{K} = $W / $L * $uFE * $Cox; $this->{Kth} = 2.0 / 3.0 * sqrt(abs(2 * $Epss * $e * $Nes)) / $Cox; $this->{Ks} = $Epss * $e * $Nes / $Cox / $Cox; $this->{Ks2} = 2.0 * $Cox * $Cox / $Epss / $e / $Nes; } sub SetPolarity { my ($this, $iPolarity) = @_; return $this->{Polarity} = $iPolarity; } sub PinchoffVds { my ($this, $Vgs) = @_; my $VFB = $this->{VFB}; my $VB = $this->{VB}; my $c = 1.0 + $this->{Ks2} * abs($Vgs - $VFB); my $Vpinch = $Vgs - $VFB - 2.0*$VB * $this->{Ks} * (1.0 - sqrt($c)); return $Vpinch; } sub PinchoffVdsAtSmallVds { my ($this, $Vgs) = @_; my $Vth = $this->{Vth}; my $Vpinch = $Vgs - $Vth; return $Vpinch; } sub TFTIds { my ($this, $Vgs, $Vds) = @_; if($this->{Polarity} > 0) { return $this->nTFTIds($Vgs, $Vds); } return $this->pTFTIds($Vgs, $Vds); } sub nTFTIds { my ($this, $Vgs, $Vds) = @_; return $this->IdsByModel($Vgs, $Vds); } sub pTFTIds { my ($this, $Vgs, $Vds) = @_; return $this->IdsByModel(-$Vgs, $Vds); } sub Ids { my ($this, $Vgs, $Vds) = @_; my $VFB = $this->{VFB}; my $VB = $this->{VB}; my $K = $this->{K}; my $Veff = $Vgs - $VFB - 2.0*$VB - 0.5*$Vds; return 0.0 if($Veff < 0.0); my $a = $Veff * $Vds; my $b = abs($Vds + 2.0 * $VB)**1.5 - abs(2.0 * $VB)**1.5; my $Ids = $K * ($a - $this->{Kth} * $b); return $Ids; } sub IdsAtSmallVds { my ($this, $Vgs, $Vds) = @_; my $Vth = $this->{Vth}; my $K = $this->{K}; my $Veff = $Vgs - $Vth; return 0.0 if($Veff < 0.0); my $Ids = $K * ($Veff * $Vds - $Vds * $Vds * 0.5); return $Ids; } sub IdsByModel { my ($this, $Vgs, $Vds) = @_; my $Model = $this->{Model}; my $Vpinch; if($Model eq 'Exact') { $Vpinch = $this->PinchoffVds($Vgs); } else { $Vpinch = $this->PinchoffVdsAtSmallVds($Vgs); } my $Ipinch= $this->Ids($Vgs, $Vpinch); #print "Vgs=$Vgs Vp=$Vpinch, Ip=$Ipinch Vth=$this->{Vth}\n"; my $Ids; if($Model eq 'Exact') { if($Vds > $Vpinch) { $Ids = $this->Ids($Vgs, $Vpinch); } else { $Ids = $this->Ids($Vgs, $Vds); } } else { if($Vds > $Vpinch) { $Ids = $this->IdsAtSmallVds($Vgs, $Vpinch); } else { $Ids = $this->IdsAtSmallVds($Vgs, $Vds); } } return $Ids; } sub FermiDiracFunction { my ($E, $T, $EF, $C0, $Wa) = @_; # eV #print "E=$E EF=$EF kB=$kB T=$T e=$e Wa=$Wa\n"; return $C0 / (1.0 + exp(($E-$EF)/($kB*$T/$e+$Wa))); } 1;