The Designer's Guide Community Forum
https://designers-guide.org/forum/YaBB.pl
Modeling >> Semiconductor Devices >> Model of VCSEL. I'm begging you to help an amateur. Thanks a million
https://designers-guide.org/forum/YaBB.pl?num=1502064467

Message started by lummiuster on Aug 6th, 2017, 5:07pm

Title: Model of VCSEL. I'm begging you to help an amateur. Thanks a million
Post by lummiuster on Aug 6th, 2017, 5:07pm

Hi, I am modeling a VCSEL. First I made it work on Matlab but I can't make it work on VerilogA. I suspect I am not using the right variable to perform my iterations (electrical vs real parameters). I have written in red the part where I suspect I did something wrong.

Here is my matlab code:
For i=1:20
XXs = S*k;
XXn = N/zn;
qzni = q*zn/Etai;

ddXn = (Ira-Ioff)-XXn*qzni/Taon - (q/(Etai*k))*Go*(zn*XXn-No)*Xs/(1+(epsilon*XXs/k));
ddXs = -XXs + k*Taop*Beta*zn*XXn/Taon + Taop*Go*(zn*XXn-No)*XXs/(1+(epsilon*XXs/k));
           
XXn = (Xn+ddXn)*0.5*(1+tanh((Xn+ddXn)*10e20));  
XXs = (Xs+ddXs)*0.5*(1+tanh((Xs+ddXs)*10e20));  

S = XXs/k;
N = XXn*zn;



Here is the VerilogA part that represent the matlab code:

electrical S,N;
Output S,N;
real XXs,XXn,qzni,ddXn,ddXs,nXn,nXs;

analog begin

XXs = V(S,refnode)*k;
XXn = V(N,refnode)/zn;
qzni = q*zn/Etai;

ddXn = (Ira-Ioff)-XXn*qzni/Taon - (q/(Etai*k))*Go*(zn*XXn-No)*XXs/(1+(epsilon*XXs/k));
ddXs = -XXs + k*Taop*Beta*zn*XXn/Taon + Taop*Go*(zn*XXn-No)*XXs/(1+(epsilon*XXs/k));

nXn = (XXn+ddXn)*0.5*(1+tanh((XXn+ddXn)*10e30));
nXs = (XXs+ddXs)*0.5*(1+tanh((XXs+ddXs)*10e30));

I(S,refnode) <+ -ddt(V(S,refnode))+nXs/k;
I(N,refnode) <+ -ddt(V(N,refnode))+nXn*zn;
end


Can anyone please assist me on this? It is my first time ever working with verilogA so a specific answer would be highly appreciated.
Best regards,
Bill

Title: Re: Model of VCSEL. I'm begging you to help an amateur. Thanks a million
Post by Ken Kundert on Aug 6th, 2017, 10:17pm

You should give a complete model. You should also tell us what problem you are trying to solve.

You should also describe your variables and your formulas. Otherwise the only people that can help you are that know both Verilog-A and VCSELs.

-Ken

Title: Re: Model of VCSEL. I'm begging you to help an amateur. Thanks a million
Post by lummiuster on Aug 6th, 2017, 10:31pm

Below is my full VCSEL code. What i'm interested in is to get S or N. My problem is that when I run the DC simulation (sweep anode input current from 0 mA to 40 mA), the simulated graph stops at 2 mA rather than 40 mA. Also, the output (N, or S) remains the same. I have good reasons to think that it is because of how I declared the values S and N. Thanks in advance.

// VerilogA for reza_lib, VCSEL_NC, veriloga

`include "constants.vams"
`include "disciplines.vams"

module VCSEL_NC12(cathode,anode,Popt,refnode,Ts,tqw,mesure,Po);
input cathode,anode,Ts,refnode;
output Popt,mesure,Po;

electrical cathode,anode,Popt,refnode,Ts,tqw,Po,Xs,Xn,N,S;
electrical cathodeint,anodeint,mesure;

     branch (anodeint,cathodeint) bra;
     branch (anodeint,cathodeint) bca;
     branch (anode,anodeint) brm;
     branch (cathodeint,cathode) brdc;
     branch (anode,cathode) bcp;

parameter real q       = 1.602e-19;          // [C] electron charge  
parameter real To = 20;
parameter real zn = 1e7;  //% convergence test

parameter real Eta = 0.399619;  // % n  
parameter real Etai = 1; // % ni   NA
parameter real Rth = 2.6e3;      //  % multiply by 1000 for watt
parameter real Itho = 0.396942e-3; // % Ith?
parameter real Ioff0 = 1.246e-3;
parameter real Ioff1 = -2.545e-5;
parameter real Ioff2 = 2.908e-7;
parameter real Ioff3 = -2.531e-10;
parameter real Ioff4 = 1.022e-12;
parameter real Beta = 1.00003e-6;// % SS
parameter real Taon = 5e-9;// % tn
parameter real Taop = 2.28e-12;// % tp
parameter real k = 2.6e-8;
parameter real Go = 1.6e4;
parameter real No = 1.94e7;
parameter real nr = 3.5;
parameter real pr = 2.4e-9;
parameter real lambdao = 863e-9;

parameter real  tth = 1e-6;
parameter real epsilon = 3.4e-23;
     parameter real Ttherm            = 1e-6 from [0:inf);            //sec, thermal time constant

     parameter real NNo            = 1e18 from (0:inf);
     parameter real MMo            = 1e16 from (0:inf);
     parameter real PPo            = 1e15 from (0:inf);
     parameter real delta            = 5e-8 from (0:inf);

real Vv,T,Ioff,TempQW,Tfit,heatgen,Ta,T_Rth,DTr,qzni,ddXn,ddXs,XXs,XXn,nXn,nXs,positive,lambda,poS,Xss,Xnn,Ss,Nn,IN1,IN2,IN3,IS1,IS2,IS3;

analog begin
     @(initial_step) begin
     Ioff=Ioff0;
     T=V(Ts);
     T_Rth=T/Rth;
     end

           TempQW      = V(tqw,refnode);
           Tfit = TempQW-To;
Vv = 1.721+275*I(anode)-2.439*pow(10,4)*pow(I(anode),2)+1.338*pow(10,6)*pow(I(anode),3)-4.154*pow(10,7)*pow(I(anode),4)+6.683*pow(10,8)*pow(I(anode),5)-4.296*pow(10,9)*pow(I(anode),6);
Ioff = Ioff0 + Ioff1*(T) + Ioff2*pow(T,2) + Ioff3*pow(T,3) + Ioff4*pow(T,4);
V(Popt) <+ Eta*(I(anode)-Ioff-Itho)*0.5*(1+tanh((I(anode)-Ioff-Itho)*10e8));
heatgen = Vv*I(anode) - V(Popt);
Ta=T_Rth;
T_Rth = To/Rth +(heatgen);
T=T_Rth*Rth;
DTr=T_Rth-Ta;

lambda = lambdao*(1-(pr/nr)*(No-I(Xn,refnode)*zn*zn));


XXs = V(S,refnode)*k;
XXn = V(N,refnode)/zn;
qzni = q*zn/Etai;

ddXn = (I(anode)-Ioff)-XXn*qzni/Taon - (q/(Etai*k))*Go*(zn*XXn-No)*XXs/(1+(epsilon*XXs/k));
ddXs = -XXs + k*Taop*Beta*zn*XXn/Taon + Taop*Go*(zn*XXn-No)*XXs/(1+(epsilon*XXs/k));
nXn = (XXn+ddXn)*0.5*(1+tanh((XXn+ddXn)*10e30));
nXs = (XXs+ddXs)*0.5*(1+tanh((XXs+ddXs)*10e30));

I(S,refnode) <+ -ddt(V(S,refnode))+nXs/k;
I(N,refnode) <+ -ddt(V(N,refnode))+nXn*zn;
V(S,refnode) <+ -ddt(V(S,refnode))+I(S,refnode)*1;
V(N,refnode) <+  -ddt(V(N,refnode))+I(S,refnode)*1;

I(Xs,refnode)            <+ -ddt(V(Xs,refnode))+nXs;
I(Xn,refnode)            <+ -ddt(V(Xn,refnode))+nXn;
     //I(S,refnode)            <+ I(Xs,refnode)/k;
//I(S,refnode)            <+ poS/k;
//I(S,refnode)            <+ (I(Xs,refnode)*0.5*(1+tanh(I(Xs,refnode)*pow(10,18))))/k;
     //I(N,refnode)            <+ I(Xn,refnode)*zn;

//V(Po,refnode)      <+ I(S,refnode)*k;
V(Po,refnode)      <+ V(S,refnode)/(25*pow(k,2));
V(mesure,refnode)      <+ V(N,refnode);
//V(mesure,refnode)      <+ I(S,refnode)*k;
V(tqw,refnode)      <+ T - ddt(Ttherm*V(tqw,refnode));  //good

end
endmodule




For comparaison here is my Matlab code:

q  = 1.602e-19;          % [C] electron charge  
To = 20;
T = To+0.001;
zn = 1e7;                      % convergence test

Eta = 0.399619;                % n  
Etai = 1;                      % ni  
Rth = 2.6*1000;                     % multiply by 1000 for watt
Itho = 0.396942e-3;            % Ith
Ioff0 = 1.246e-3;
Ioff1 = -2.545e-5;
Ioff2 = 2.908e-7;
Ioff3 = -2.531e-10;
Ioff4 = 1.022e-12;
Beta = 1.00003e-6;             % SS
Taon = 5e-9;                   % tn
Taop = 2.28e-12;               % tp
k = 2.6e-8;
Go = 1.6e4;
No = 1.94e7;
tth = 1e-6;
epsilon = 3.4e-23;
V=1.721+275*Ira-2.439*10^4*Ira^2+1.338*10^6*Ira^3-4.154*10^7*Ira^4+6.683*10^8*Ira^5-4.296*10^9*Ira^6;
pr = 2.4e-9;
nr = 3.5;
lambdao =863e-9;

N = No;
S = 5.2874e+10;
Ioff=Ioff0;
DT=0;
DTr=0;
T_Rth = T/Rth;

%Temperature-------------------------------------------------
for i=1:300
Popt = Eta*(Ira-Itho-Ioff);
if Popt<0
   Popt=0;
end
Ta=T_Rth;
T_Rth = To/Rth + (V*Ira-Popt)-tth*DTr/Rth;
T=T_Rth*Rth;
DTr=T_Rth-Ta;
Ioff = Ioff0 + Ioff1*(T) + Ioff2*(T)^2 + Ioff3*(T)^3 + Ioff4*(T)^4;
end
%Rate Equations-----------------------------------------------------------------------------------------------
for i=1:100000
    lambda = lambdao*(1-(pr/nr)*(N-No));
Xs = S*k;
Xn = N/zn;

qzni = q*zn/Etai;
ddXn = (Ira-Ioff)-Xn*qzni/Taon - (q/(Etai*k))*Go*(zn*Xn-No)*Xs/(1+(epsilon*Xs/k));
ddXs = -Xs + k*Taop*Beta*zn*Xn/Taon + Taop*Go*(zn*Xn-No)*Xs/(1+(epsilon*Xs/k));

Xn = Xn + ddXn;              
Xs = Xs + ddXs;              
Xn = Xn*0.5*(1+tanh(Xn*10e20)); % Xn [0 to infinity
Xs = Xs*0.5*(1+tanh(Xs*10e20)); % Xs [0 to infinity
S = Xs/k;
N = Xn*zn;
Po = k*S;
if Po<0
   Po=0;
end
S=Po/k;
out = N;
end
end

Title: Re: Model of VCSEL. I'm begging you to help an amateur. Thanks a million
Post by Geoffrey_Coram on Aug 7th, 2017, 12:54pm

I'm very suspicious of a number like 10e30:
nXn = (XXn+ddXn)*0.5*(1+tanh((XXn+ddXn)*10e30));

especially since tanh(20) is already indistinguishable from 1 in double-precision arithmetic.

Title: Re: Model of VCSEL. I'm begging you to help an amateur. Thanks a million
Post by Geoffrey_Coram on Aug 7th, 2017, 12:57pm

Oh, and this probably isn't doing what you think it is:

I(S,refnode) <+ -ddt(V(S,refnode))+nXs/k;
I(N,refnode) <+ -ddt(V(N,refnode))+nXn*zn;
V(S,refnode) <+ -ddt(V(S,refnode))+I(S,refnode)*1;
V(N,refnode) <+  -ddt(V(N,refnode))+I(S,refnode)*1;

According to the value retention rules of Verilog-AMS, if you contribute to the voltage V(S,refnode), then the simulator throws out all previous contributions to the current I(S,refnode).

Title: Re: Model of VCSEL. I'm begging you to help an amateur. Thanks a million
Post by lummiuster on Aug 8th, 2017, 5:07pm

Thanks for your answer.
So when I wrote:

I(S,refnode) <+ -ddt(V(S,refnode))+nXs/k;
I(N,refnode) <+ -ddt(V(N,refnode))+nXn*zn;
V(S,refnode) <+ -ddt(V(S,refnode))+I(S,refnode)*1;
V(N,refnode) <+  -ddt(V(N,refnode))+I(S,refnode)*1;

What I wanted is to have
S=S+dt.

Can you please show me how to write the following code. (I will describe it with Matlab lines):

Xs = S*k;
Xn = N/zn;

dXn = Xs*10-Xn*5;
dXs = Xn*2-Xs*4;
           
Xn = Xn+ddXn;
Xs = Xs+ddXs;

S = Xs/k;
N = Xn*zn;

Since S and N change at every iteration, I suspect they should be declared as an electrical parameter. Am I right? If you could simply write the code above but in VerilogA I would be forever grateful.

Title: Re: Model of VCSEL. I'm begging you to help an amateur. Thanks a million
Post by Ken Kundert on Aug 11th, 2017, 11:39am

In Verilog-A you have nodes, branches, signals, and variables. You are mixing them up.  In the line:

Code:
I(S,refnode) <+ -ddt(V(S,refnode))+nXs/k;

S and refnode are nodes. They do not have values per see. This is a big difference with your Matlab representation. There S is a variable and so has a value.

(S,refnode) is a branch. It does not have a value either, but you can get or set branch voltages and currents. In this line you are probing the voltage on the branch using V(S,refnode) and you are setting its current with I(S,refnode). Thus, this line creates a branch between the nodes S and refnode. A current flows through that branch that equals the derivative of the branch voltage plus an offset (xXs/k).

So fundamentally, your question does not make a lot of sense because you have not defined your terms. What is S? Is it a voltage or current?


Quote:
Since S and N change at every iteration, I suspect they should be declared as an electrical parameter. Am I right?


No. You use electrical to declare nodes. You usually do not declare nodes within a model, they are generally only found at the ports. Instead, a model constructs a collection of branches that connect to the port nodes. The branches are used to define current paths through the model and allow you to measure the desired voltages and currents.

To write a model in Verilog-A, you should ...
1. Read Introduction to Verilog-A
2. Identify the nodes and branches you need. Generally the nodes will be the ports (pins) of the device and the branches are needed to define what you mean when you measure or specify any voltage or current. In other words, for every voltage or current you need to either measure or specify, there must be a corresponding branch.
3. Now you can write your model with the following three parts:
  a. part one consists of code that copies all the measured voltages and currents into variables
  b. part two is your matlab code
  c. part three consists of contribution statements that act to convert the output variable values into the specified voltages and currents.

This is basically the heart of the difference between Matlab and Verilog-A. With Matlab you are responsible for writing all of the equation and Matlab simply evaluates them in the order you gave them in. But Verilog-A understands voltages and current and you must write the models in those terms. In Matlab you give equations for the whole system but in Verilog-A you give equations for a single model. The simulator then takes your Verilog-A model, combines it with the rest of the circuit, and then solves for the voltages and current. In other words, it finds a set of voltages for which Kirchhoff's laws are satisfied.

For example, consider a varactor whose constitutive equation taken from Modeling Varactors:

   q(v) = C0 v + C1 ln( cosh( (v - v0)v1)))

Now assume that this capacitor has two ports: a and c. We need to measure the voltage from a to c, so we need a branch between the two. We also want to specify the current from a to c, so we need a branch, but we can use the same branch for both. To write this in Verilog-A you would do the following:

Code:
module varactor (a, c);                // defines the name of the component and the name of the pins
electrical a, c;                      // declares the type of the pins
parameter real C0 = 1p                      // declares a parameter
parameter real C1 = 0.5p;                // declares a parameter
parameter real v0 = 0;                      // declares a parameter
parameter real v1 = 1                      // declares a parameter
real v, q;                            // declares desired variables
analog begin
   v = V(a,c);                      // part 1
   q = C0*v + C1*ln(cosh((v-v0)/v1)));     // part 2
   I(a,c) = ddt(q);                      // part 3
end
endmodule

Easy peasy.

-Ken

The Designer's Guide Community Forum » Powered by YaBB 2.2.2!
YaBB © 2000-2008. All Rights Reserved.