51 changed files with 6726 additions and 0 deletions
@ -0,0 +1,64 @@ |
|||
//VerilogA for amp,edfa,veriloga |
|||
//单模,单正向 |
|||
//后续更新 |
|||
|
|||
`include "constants.vams" |
|||
`include "disciplines.vams" |
|||
|
|||
`define NUM_INT 10000 |
|||
|
|||
module edfa(Ipow,Iphase,Ilam,Opow,Ophase,Olam); |
|||
parameter integer alpha_use_dBm = 1 from [0:1]; |
|||
parameter real length = 6 from (0:inf); |
|||
parameter real sig_a = 3.86e-25 from (0:inf); //absorption, 1550nm |
|||
parameter real sig_e = 4.27e-25 from (0:inf); //emission, 1550nm |
|||
parameter real tau = 10.0e-3 from (0:inf); |
|||
parameter real gamma = 0.67 from (0:1); |
|||
parameter real nEr = 2.5e24 from (0:inf); |
|||
parameter real beff = 1.5e-6 from (0:inf); |
|||
parameter real bgloss = 0.03 from [0:inf); |
|||
parameter real bandwidth = 0.0 from [0:inf); |
|||
|
|||
input Ipow, Iphase, Ilam; |
|||
output Opow, Ophase, Olam; |
|||
electrical Ipow, Iphase, Ilam, Opow, Ophase, Olam; |
|||
|
|||
real Pk; |
|||
real Pase = 0; |
|||
real dz; |
|||
real dPk, dPase; |
|||
real lk; |
|||
real f2; |
|||
integer i; |
|||
real freq; |
|||
real df; |
|||
|
|||
analog begin |
|||
freq = `P_C/V(Ilam); |
|||
dz = length/`NUM_INT; |
|||
Pk=V(Ipow); |
|||
|
|||
if (alpha_use_dBm == 0) begin |
|||
lk=bgloss; |
|||
end |
|||
else if (alpha_use_dBm == 1) begin |
|||
lk=bgloss/10.0*ln(10); |
|||
end |
|||
|
|||
for (i=0; i<`NUM_INT; i=i+1) begin |
|||
f2=tau*(Pk+Pase)/(`M_PI*beff*beff*`P_H*freq)*gamma*sig_a/(1+tau*(Pk+Pase)/(`M_PI*beff*beff*`P_H*freq)*gamma*(sig_a+sig_e)); |
|||
// $display("f2=%e",f2); |
|||
dPk = (sig_e*f2-sig_a*(1-f2))*gamma*nEr*Pk-lk*Pk; |
|||
// $display("dPk=%e",dPk); |
|||
dPase = (sig_e*f2-sig_a*(1-f2))*gamma*nEr*Pase+sig_e*gamma*nEr*f2*2.0*`P_H*freq*bandwidth-lk*Pase; |
|||
// $display("dPase=%e",dPase); |
|||
Pk = Pk + dPk*dz; |
|||
Pase = Pase + dPase*dz; |
|||
end |
|||
|
|||
V(Opow) <+ Pk + Pase; |
|||
V(Olam) <+ V(Ilam); |
|||
V(Ophase) <+ V(Iphase); |
|||
end |
|||
|
|||
endmodule |
@ -0,0 +1,69 @@ |
|||
//VerilogA for amp,soa,veriloga |
|||
|
|||
`include "constants.vams" |
|||
`include "disciplines.vams" |
|||
|
|||
module soa(Ipow,Iphase,Ilam,Opow,Ophase,Olam,Vinj,Gnd); |
|||
parameter real length = 500e-6 from (0:1e-3]; |
|||
parameter real width = 3e-6 from (0:50e-6]; |
|||
parameter real height = 80e-9 from (0:5e-6]; |
|||
parameter real gamma = 0.15 from (0:1]; |
|||
parameter real alpha_s = 4000 from (0:5e4]; |
|||
parameter real dg = 2.78e-20 from (0:50e-20]; |
|||
parameter real Ntr = 1.4e24 from (0:5e25]; |
|||
parameter real alpha = 5.0 from [-20:20]; |
|||
parameter real A = 1.43e8 from [0:1e11]; |
|||
parameter real B = 1e-16 from (0:1e-13]; |
|||
parameter real C = 3e-41 from (0:1e-37]; |
|||
|
|||
input Ipow,Iphase,Ilam,Vinj; |
|||
output Opow,Ophase,Olam; |
|||
inout Gnd; |
|||
electrical Ipow,Iphase,Ilam,Vinj,Opow,Ophase,Olam,Gnd; |
|||
electrical Na; |
|||
|
|||
real eir,eii,soar,soai,eor,eoi; |
|||
real E_in,ph_in; |
|||
real g,gtot,Pav,N; |
|||
real Vsoa; |
|||
real freq; |
|||
|
|||
branch(Gnd,Na) Iin; |
|||
branch(Na,Gnd) C1,Ra,Ib,Ic,Iav; |
|||
|
|||
analog initial begin |
|||
N=3e24; |
|||
end |
|||
|
|||
analog begin |
|||
freq=`P_C/V(Ilam); |
|||
Vsoa=length*width*height; |
|||
|
|||
N=V(Na)/(`P_Q*Vsoa); |
|||
g=dg*(N-Ntr); |
|||
gtot=gamma*g-alpha_s; |
|||
Pav=V(Ipow)*(exp(gtot*length)-1)/(gtot*length); |
|||
|
|||
I(Iin) <+ I(Vinj); |
|||
I(C1) <+ ddt(V(C1)); |
|||
I(Ra) <+ A*V(Ra); |
|||
I(Ib) <+ `P_Q*Vsoa*B*pow(N,2); |
|||
I(Ic) <+ `P_Q*Vsoa*C*pow(N,3); |
|||
I(Iav) <+ `P_Q*gamma*g*Pav*length/(`P_H*freq); |
|||
|
|||
E_in=sqrt(V(Ipow)); |
|||
ph_in=V(Iphase)/360*2*`M_PI; |
|||
eir=E_in*cos(ph_in); |
|||
eii=E_in*sin(ph_in); |
|||
soar=exp((gamma*g*length-alpha_s*length)/2)*cos(alpha*gamma*g*length/2); |
|||
soai=exp((gamma*g*length-alpha_s*length)/2)*sin(alpha*gamma*g*length/2); |
|||
eor=soar*eir-soai*eii; |
|||
eoi=soai*eir+soar*eii; |
|||
|
|||
V(Opow) <+ eor**2+eoi**2; |
|||
V(Ophase) <+ atan2(eoi,eor)*360/(2*`M_PI); |
|||
V(Olam) <+ V(Ilam); |
|||
end |
|||
|
|||
|
|||
endmodule |
@ -0,0 +1,124 @@ |
|||
//VerilogA for laser,dfb,veriloga |
|||
|
|||
`include "constants.vams" |
|||
`include "disciplines.vams" |
|||
|
|||
module dfb(Vin,Vlam,Gnd,OpowL,OpowR,OphaseL,OphaseR,OlamL,OlamR); |
|||
parameter real L = 300u from [0:inf); |
|||
parameter real W = 1.5u from [0:inf); |
|||
parameter real D = 0.2u from [0:inf); |
|||
parameter real GAM = 0.3 from [0:1); |
|||
parameter real T = 10n from [0:inf); |
|||
parameter real BEATsp = 5e-5 from [0:inf); |
|||
parameter integer ID = 0 from [0:1]; |
|||
parameter real G0 = 25000 from [0:inf); |
|||
parameter real Ntr = 1e24 from [0:inf); |
|||
parameter real EPS = 6e-23 from [0:inf); |
|||
parameter real B = 1e-16 from [0:inf); |
|||
parameter real A = 7.5E-41 from [0:inf); |
|||
parameter real Rl = 1e-8 from [0:1); |
|||
parameter real Rr = 1E-8 from [0:1); |
|||
parameter real ALFA0 = 5000 from [0:inf); |
|||
parameter real Q1 = 1.9998 from [0:inf); |
|||
parameter real Q2 = 1.4391E-4 from [0:inf); |
|||
parameter real Rat = 1 from [0:inf); |
|||
parameter real Ng = 3.6 from [0:inf); |
|||
parameter real N0 = 6.5e13 from [0:inf); |
|||
parameter real Vbi = 1.13 from [0:inf); |
|||
parameter real EIT = 2 from [0:inf); |
|||
parameter real Rs = 1E-5 from [0:inf); |
|||
parameter real Cp = 0p from [0:inf); |
|||
parameter real Rd = 1E15 from [0:inf); |
|||
parameter real Csc0 = 0p from [0:inf); |
|||
|
|||
|
|||
input Vin,Vlam; |
|||
inout Gnd; |
|||
output OpowL,OpowR,OphaseL,OphaseR,OlamL,OlamR; |
|||
electrical Vin,Vlam,Gnd,OpowL,OpowR,OphaseL,OphaseR,OlamL,OlamR; |
|||
electrical Nin1,Ns,Nph; |
|||
|
|||
real VT=`P_K*$temperature/`P_Q; |
|||
real Vact; |
|||
real Cg; |
|||
real CPL,CPR,Tph,QV,Cph,Rph; |
|||
real Cd,Csc; |
|||
real N,G; |
|||
|
|||
real UL,UW,UD; |
|||
real UN0,UG0,UNtr,UEPS; |
|||
real UA,UB,UALFA0,ULAMBDA,ULSPEED,UQ2; |
|||
|
|||
branch (Nin1,Gnd) R2,C1,C2,C3,B1,B2,B3,B4; |
|||
branch (Gnd,Ns) B5,B6,R3,C4; |
|||
branch (Gnd,Nph) B7,C5; |
|||
|
|||
analog begin |
|||
|
|||
UL=L*1e6; |
|||
UW=W*1e6; |
|||
UD=D*1e6; |
|||
UG0=G0*1e-6; |
|||
UN0=N0*1e-18; |
|||
UNtr=Ntr*1e-18; |
|||
UEPS=EPS*1e18; |
|||
UA=A*1e36; |
|||
UB=B*1e18; |
|||
UALFA0=ALFA0*1e-6; |
|||
ULAMBDA=V(Vlam)*1e6; |
|||
ULSPEED=`P_C*1e6; |
|||
UQ2=Q2*1e6; |
|||
|
|||
Vact=UL*UW*UD; |
|||
Cg=ULSPEED/Ng; |
|||
CPL=`P_H*Cg*Vact*Rat*ULSPEED*(1-Rl)/ULAMBDA/UQ2; |
|||
CPR=`P_H*Cg*Vact*Rat*ULSPEED*(1-Rr)/ULAMBDA/UQ2; |
|||
Tph=Ng/(ULSPEED*(UALFA0+Q1/UQ2)); |
|||
QV=`P_Q*Vact; |
|||
Cph=QV; |
|||
Rph=Tph/QV; |
|||
|
|||
N=UN0*(exp(V(Nin1,Gnd)/EIT/VT)-1.0); |
|||
|
|||
if (N<UNtr) |
|||
G=0; |
|||
else begin |
|||
if (ID<1) |
|||
G=UG0*(N/UNtr-1.0)/(1.0+UEPS*abs(V(Ns,Gnd))); |
|||
else |
|||
G=UG0*ln(N/UNtr)/(1.0+UEPS*abs(V(Ns,Gnd))); |
|||
end |
|||
|
|||
Cd=QV*UN0*exp(V(Nin1,Gnd)/EIT/VT)/(EIT*VT); |
|||
if (V(Nin1,Gnd)<Vbi) |
|||
Csc=Csc0/sqrt(1.0-V(Nin1,Gnd)/Vbi); |
|||
else |
|||
Csc=Csc0/sqrt(0.1); |
|||
|
|||
V(Vin,Nin1) <+ I(Vin,Nin1)*Rs; |
|||
V(R2) <+ I(R2)*Rd; |
|||
I(C1) <+ Cp*ddt(V(C1)); |
|||
I(C2) <+ Cd*ddt(V(C2)); |
|||
I(C3) <+ Csc*ddt(V(C3)); |
|||
I(B1) <+ QV*N/T; |
|||
I(B2) <+ QV*UA*pow(N,3); |
|||
I(B3) <+ QV*UB*pow(N,2); |
|||
I(B4) <+ QV*Cg*GAM*G*abs(V(Gnd,Ns)); |
|||
|
|||
I(B5) <+ BEATsp*QV*UB*pow(N,2); |
|||
I(B6) <+ QV*Cg*GAM*G*abs(V(Gnd,Ns)); |
|||
I(C4) <+ Cph*ddt(V(C4)); |
|||
V(R3) <+ I(R3)*Rph; |
|||
|
|||
//I(B7) <+ te_ph1*ALPHA/2; |
|||
//I(C5) <+ ddt(V(C5)); |
|||
|
|||
V(OpowL) <+ CPL*V(Ns,Gnd); |
|||
V(OpowR) <+ CPR*V(Ns,Gnd); |
|||
V(OphaseL) <+ 0; |
|||
V(OphaseR) <+ 0; |
|||
V(OlamL) <+ V(Vlam); |
|||
V(OlamR) <+ V(Vlam); |
|||
end |
|||
|
|||
endmodule |
@ -0,0 +1,108 @@ |
|||
//VerilogA for laser,dhld,veriloga |
|||
|
|||
`include "constants.vams" |
|||
`include "disciplines.vams" |
|||
|
|||
module dhld(Vin,Vlam,Gnd,OpowL,OphaseL,OlamL,OpowR,OphaseR,OlamR); |
|||
|
|||
input Vin,Vlam; |
|||
output OpowL,OphaseL,OlamL,OpowR,OphaseR,OlamR; |
|||
inout Gnd; |
|||
electrical Vin,Vlam,Gnd,Nlight,Nv,OpowL,OphaseL,OlamL,OpowR,OphaseR,OlamR; |
|||
|
|||
parameter real L = 250u from (0:inf); |
|||
parameter real W = 1u from (0:inf); |
|||
parameter real D = 0.15u from (0:inf); |
|||
parameter real An1 = 1.0E8 from [0:inf); |
|||
parameter real An2 = 1.1E-17 from [0:inf); |
|||
parameter real An3 = 2.0E-41 from [0:inf); |
|||
parameter real An4 = 0 from [0:inf); |
|||
parameter real A = 3.5 from (3:inf); |
|||
parameter real Ar1 = 4.2E8 from [0:inf); |
|||
parameter real Ar2 = 1.5E-16 from [0:inf); |
|||
parameter real GAM = 0.3 from (0:1]; |
|||
parameter real G0 = 1.4E-12 from (0:inf); |
|||
parameter real Ntr = 1.5E24 from (0:inf); |
|||
parameter real EPS = 1E-25 from [0:inf); |
|||
parameter real B = 1 from [0:inf); |
|||
parameter real Bsp = 1E-3 from [0:1]; |
|||
parameter real ALFA = 2000 from [0:inf); |
|||
parameter real Rl = 0.3 from [0:1); |
|||
parameter real Rr = 0.3 from [0:1); |
|||
parameter real Ne = 7.8E7 from (0:inf); |
|||
parameter real EIT = 2 from (0:inf); |
|||
parameter real Nr = 3.5 from (0:inf); |
|||
parameter real Vbi = 1.13 from (0:inf); |
|||
parameter real Csc0 = 10p from [0:inf); |
|||
parameter real Rs = 5 from [0:inf); |
|||
parameter real Cp = 1p from [0:inf); |
|||
parameter real Rd = 1E15 from [0:inf); |
|||
|
|||
real VT=`P_K*$temperature/`P_Q; |
|||
real Vact; |
|||
real Tph; |
|||
real QV; |
|||
real Cph,Rph; |
|||
real CPL,CPR; |
|||
|
|||
real N,N0,LMD; |
|||
real G; |
|||
real Cd; |
|||
real Csc; |
|||
real Rn; |
|||
real Rra; |
|||
real aca,acp; |
|||
|
|||
branch (Nv,Gnd) R2,C1,C2,C3,B1,B2,B3; |
|||
branch (Gnd,Nlight) B4,B5,R3,C4; |
|||
|
|||
analog begin |
|||
LMD=V(Vlam); |
|||
Vact=L*W*D; |
|||
Tph=Nr/(`P_C*(GAM*ALFA-ln(Rl*Rr)/2.0/L)); |
|||
QV=`P_Q*Vact; |
|||
Cph=`P_Q/VT; |
|||
Rph=VT*Tph/`P_Q; |
|||
CPL=`P_H*`P_C*`P_C*(Rl-1.0)*ln(Rl*Rr)/(2.0*Nr*VT*L*LMD*(1-Rl+sqrt(Rl/Rr)*(1-Rr))); |
|||
CPR=`P_H*`P_C*`P_C*(Rr-1.0)*ln(Rl*Rr)/(2.0*Nr*VT*L*LMD*(1-Rr+sqrt(Rr/Rl)*(1-Rl))); |
|||
N=Ne*exp(V(Nv,Gnd)/EIT/VT)-1; |
|||
Cd=QV*Ne*exp(V(Nv,Gnd)/EIT/VT)/(EIT*VT); |
|||
if (V(Nv,Gnd)<Vbi) begin |
|||
Csc=Csc0/sqrt(1-V(Nv,Gnd)/Vbi); |
|||
end |
|||
else begin |
|||
Csc=Csc0/sqrt(0.1); |
|||
end |
|||
Rn=An1*N+An2*pow(N,2)+An3*pow(N,3)+An4*pow(N,A); |
|||
Rra=Ar1*N+Ar2*pow(N,2); |
|||
if (N<Ntr) begin |
|||
G=0; |
|||
end |
|||
else begin |
|||
G=QV*GAM*G0*(N-Ntr)/pow(1+EPS*abs(V(Gnd,Nlight)),B); |
|||
end |
|||
|
|||
V(Vin,Nv) <+ I(Vin,Nv)*Rs; |
|||
|
|||
V(R2) <+ I(R2)*Rd; |
|||
I(C1) <+ Cp*ddt(V(C1)); |
|||
I(C2) <+ Cd*ddt(V(C2)); |
|||
I(C3) <+ Csc*ddt(V(C3)); |
|||
I(B1) <+ QV*Rn; |
|||
I(B2) <+ QV*Rra; |
|||
I(B3) <+ G*abs(V(Gnd,Nlight))/Vact/VT; |
|||
|
|||
V(R3) <+ I(R3)*Rph; |
|||
I(C4) <+ Cph*ddt(V(C4)); |
|||
I(B4) <+ Bsp*QV*Rra; |
|||
I(B5) <+ G*abs(V(Gnd,Nlight))/Vact/VT; |
|||
|
|||
V(OpowL,Gnd) <+ CPL*V(Nlight,Gnd); |
|||
V(OpowR,Gnd) <+ CPR*V(Nlight,Gnd); |
|||
V(OphaseL) <+ 0; |
|||
V(OphaseR) <+ 0; |
|||
V(OlamL) <+ V(Vlam); |
|||
V(OlamR) <+ V(Vlam); |
|||
end |
|||
|
|||
endmodule |
@ -0,0 +1,201 @@ |
|||
//VerilogA for laser,eml,veriloga |
|||
|
|||
`include "constants.vams" |
|||
`include "disciplines.vams" |
|||
|
|||
`define MAX_ARRAY 1000 |
|||
|
|||
module eml(Vin,Vlam,Vsig1,Vsig2,Opow,Ophase,Olam,Gnd); |
|||
parameter real L = 300u from [0:inf); |
|||
parameter real W = 1.5u from [0:inf); |
|||
parameter real D = 0.2u from [0:inf); |
|||
parameter real GAM = 0.3 from [0:1); |
|||
parameter real T = 10n from [0:inf); |
|||
parameter real BEATsp = 5e-5 from [0:inf); |
|||
parameter integer ID = 0 from [0:1]; |
|||
parameter real G0 = 25000 from [0:inf); |
|||
parameter real Ntr = 1e24 from [0:inf); |
|||
parameter real EPS = 6e-23 from [0:inf); |
|||
parameter real B = 1e-16 from [0:inf); |
|||
parameter real A = 7.5E-41 from [0:inf); |
|||
parameter real Rl = 1e-8 from [0:1); |
|||
parameter real ALFA0 = 5000 from [0:inf); |
|||
parameter real Q1 = 1.9998 from [0:inf); |
|||
parameter real Q2 = 1.4391E-4 from [0:inf); |
|||
parameter real Rat = 1 from [0:inf); |
|||
parameter real Ng = 3.6 from [0:inf); |
|||
parameter real N0 = 6.5e13 from [0:inf); |
|||
parameter real Vbi = 1.13 from [0:inf); |
|||
parameter real EIT = 2 from [0:inf); |
|||
parameter real Rs = 1E-5 from [0:inf); |
|||
parameter real Cp = 0p from [0:inf); |
|||
parameter real Rd = 1E15 from [0:inf); |
|||
parameter real Csc0 = 0p from [0:inf); |
|||
parameter real Gam_c = 0 from (-inf:inf); |
|||
parameter integer tau_L = 6 from [1:inf); |
|||
parameter integer num_carriler = 2 from [1:inf); |
|||
parameter integer num_voltage = 6 from [1:inf); |
|||
//TODO: file for multinomial coefficients |
|||
parameter string tau_file = "./tau_mat.in"; |
|||
parameter string alpha_file = "./alpha_mat.in"; |
|||
parameter string gamma_file = "./gamma_mat.in"; |
|||
//Use LF!!! |
|||
|
|||
input Vin,Vlam,Vsig1,Vsig2; |
|||
output Opow,Ophase,Olam; |
|||
inout Gnd; |
|||
electrical Vin,Vlam,Vsig1,Vsig2,Opow,Ophase,Olam,Gnd; |
|||
electrical Ns_eam,Nph_eam; |
|||
electrical Nin1,Ns,Nph; |
|||
|
|||
real Vcalc; |
|||
real Gamma=0,Alpha=0; |
|||
real tau=0; |
|||
real opow,ophase; |
|||
integer file_tau,file_alpha,file_gamma; |
|||
integer i,j; |
|||
real f=1e-18; |
|||
real readfile=0; |
|||
real tau_array[0:`MAX_ARRAY]; |
|||
real alpha_array[0:`MAX_ARRAY]; |
|||
real gamma_array[0:`MAX_ARRAY]; |
|||
|
|||
real VT=`P_K*$temperature/`P_Q; |
|||
real Vact; |
|||
real Cg; |
|||
real CPL,Tph,QV,Cph,Rph; |
|||
real Cd,Csc; |
|||
real N,G; |
|||
real opow_laser,ophase_laser; |
|||
|
|||
real UL,UW,UD; |
|||
real UN0,UG0,UNtr,UEPS; |
|||
real UA,UB,UALFA0,ULAMBDA,ULSPEED,UQ2; |
|||
|
|||
branch (Gnd,Ns_eam) Cs,Is; |
|||
branch (Ns_eam,Gnd) It; |
|||
branch (Gnd,Nph_eam) Cph_eam,Iph; |
|||
|
|||
branch (Nin1,Gnd) R2,C1,C2,C3,B1,B2,B3,B4; |
|||
branch (Gnd,Ns) B5,B6,R3,C4; |
|||
branch (Gnd,Nph) B7,C5; |
|||
|
|||
analog initial begin |
|||
UL=L*1e6; |
|||
UW=W*1e6; |
|||
UD=D*1e6; |
|||
UG0=G0*1e-6; |
|||
UN0=N0*1e-18; |
|||
UNtr=Ntr*1e-18; |
|||
UEPS=EPS*1e18; |
|||
UA=A*1e36; |
|||
UB=B*1e18; |
|||
UALFA0=ALFA0*1e-6; |
|||
ULSPEED=`P_C*1e6; |
|||
UQ2=Q2*1e6; |
|||
|
|||
Vact=UL*UW*UD; |
|||
Cg=ULSPEED/Ng; |
|||
Tph=Ng/(ULSPEED*(UALFA0+Q1/UQ2)); |
|||
QV=`P_Q*Vact; |
|||
Cph=QV; |
|||
Rph=Tph/QV; |
|||
end |
|||
|
|||
analog begin |
|||
ULAMBDA=V(Vlam)*1e6; |
|||
CPL=`P_H*Cg*Vact*Rat*ULSPEED*(1-Rl)/ULAMBDA/UQ2; |
|||
N=UN0*(exp(V(Nin1,Gnd)/EIT/VT)-1.0); |
|||
|
|||
if (N<UNtr) |
|||
G=0; |
|||
else begin |
|||
if (ID<1) |
|||
G=UG0*(N/UNtr-1.0)/(1.0+UEPS*abs(V(Ns,Gnd))); |
|||
else |
|||
G=UG0*ln(N/UNtr)/(1.0+UEPS*abs(V(Ns,Gnd))); |
|||
end |
|||
|
|||
Cd=QV*UN0*exp(V(Nin1,Gnd)/EIT/VT)/(EIT*VT); |
|||
if (V(Nin1,Gnd)<Vbi) |
|||
Csc=Csc0/sqrt(1.0-V(Nin1,Gnd)/Vbi); |
|||
else |
|||
Csc=Csc0/sqrt(0.1); |
|||
|
|||
V(Vin,Nin1) <+ I(Vin,Nin1)*Rs; |
|||
V(R2) <+ I(R2)*Rd; |
|||
I(C1) <+ Cp*ddt(V(C1)); |
|||
I(C2) <+ Cd*ddt(V(C2)); |
|||
I(C3) <+ Csc*ddt(V(C3)); |
|||
I(B1) <+ QV*N/T; |
|||
I(B2) <+ QV*UA*pow(N,3); |
|||
I(B3) <+ QV*UB*pow(N,2); |
|||
I(B4) <+ QV*Cg*GAM*G*abs(V(Gnd,Ns)); |
|||
|
|||
I(B5) <+ BEATsp*QV*UB*pow(N,2); |
|||
I(B6) <+ QV*Cg*GAM*G*abs(V(Gnd,Ns)); |
|||
I(C4) <+ Cph*ddt(V(C4)); |
|||
V(R3) <+ I(R3)*Rph; |
|||
|
|||
//I(B7) <+ te_ph1*ALPHA/2; |
|||
//I(C5) <+ ddt(V(C5)); |
|||
|
|||
opow_laser = CPL*V(Ns,Gnd); |
|||
ophase_laser=0; |
|||
|
|||
if (readfile==0) begin |
|||
file_tau=$fopen(tau_file,"r"); |
|||
file_alpha=$fopen(alpha_file,"r"); |
|||
file_gamma=$fopen(gamma_file,"r"); |
|||
if (file_tau==0 || file_alpha==0 || file_gamma==0) begin |
|||
$display("Error: Could not open file"); |
|||
$finish; |
|||
end |
|||
for (i=0;i<tau_L;i=i+1) begin |
|||
$fscanf(file_tau,"%f",tau_array[i]); |
|||
end |
|||
for (i=0;i<num_voltage;i=i+1) begin |
|||
for (j=0;j<num_carriler;j=j+1) begin |
|||
$fscanf(file_alpha,"%f",alpha_array[i*num_carriler+j]); |
|||
$fscanf(file_gamma,"%f",gamma_array[i*num_carriler+j]); |
|||
end |
|||
end |
|||
$fclose(file_tau); |
|||
$fclose(file_alpha); |
|||
$fclose(file_gamma); |
|||
readfile=1; |
|||
end |
|||
|
|||
Vcalc=V(Vsig1)-V(Vsig2); |
|||
tau=0; |
|||
for (i=0;i<tau_L;i=i+1) begin |
|||
tau=tau+tau_array[i]*pow(Vcalc,i); |
|||
end |
|||
Gamma=0; |
|||
Alpha=0; |
|||
for (i=0;i<num_voltage;i=i+1) begin |
|||
for (j=0;j<num_carriler;j=j+1) begin |
|||
Gamma=Gamma+gamma_array[i*num_carriler+j]*pow(Vcalc,j)*pow(V(Ns_eam),i); //pow(N,i)*pow(f,i) |
|||
Alpha=Alpha+alpha_array[i*num_carriler+j]*pow(Vcalc,j)*pow(V(Ns_eam),i); //Caution the unit |
|||
end |
|||
end |
|||
if (Gamma==0) |
|||
opow=0; |
|||
else begin |
|||
opow=pow(sqrt(opow_laser)*exp(-Gamma/2),2); |
|||
end |
|||
|
|||
I(Is) <+ f*V(Vlam)/(`P_H*`P_C)*exp(-Gam_c)*(1-exp(-Gamma+2*Gam_c))*opow_laser; |
|||
I(It) <+ V(Ns_eam)/tau; |
|||
I(Cs) <+ ddt(V(Cs)); |
|||
|
|||
I(Iph) <+ Alpha/2*ddt(Gamma); |
|||
I(Cph_eam) <+ ddt(V(Cph_eam)); |
|||
ophase=V(Nph_eam)+ophase_laser; |
|||
|
|||
V(Opow) <+ opow; |
|||
V(Ophase) <+ ophase/(2*`M_PI)*360.0; |
|||
V(Olam) <+ V(Vlam); |
|||
end |
|||
|
|||
endmodule |
@ -0,0 +1,98 @@ |
|||
//VerilogA for laser,qwld,veriloga |
|||
|
|||
`include "constants.vams" |
|||
`include "disciplines.vams" |
|||
|
|||
module qwld(Vin,Vlam,Gnd,OpowL,OphaseL,OlamL,OpowR,OphaseR,OlamR); |
|||
input Vin,Vlam; |
|||
inout Gnd; |
|||
output OpowL,OphaseL,OlamL,OpowR,OphaseR,OlamR; |
|||
electrical Vin,Vlam,Gnd,OpowL,OphaseL,OlamL,OpowR,OphaseR,OlamR,Nin1,Nlight; |
|||
|
|||
parameter real Vw = 6e-18 from (0:inf); |
|||
parameter real Vs = 6e-17 from (0:inf); |
|||
//parameter real Gws = 0.1; |
|||
//parameter real Alpha_w = 9.6e-37; |
|||
//parameter real Alpha_s = 9.12e-36; |
|||
parameter real tau_s = 6p from (0:inf); |
|||
parameter real tau_e = 200p from (0:inf); |
|||
parameter real tau_n = 0.125n from (0:inf); |
|||
parameter real tau_p = 1p from (0:inf); |
|||
parameter real Gamma = 0.4 from (0:1]; |
|||
parameter real xi = 1.5e-23 from (0:inf); |
|||
parameter real beta = 1e-4 from [0:1]; |
|||
parameter real g0 = 7.2e-12 from (0:inf); |
|||
parameter real Nom = 1e24 from (0:inf); |
|||
parameter real eta = 2 from (0:inf); |
|||
parameter real Cn = 1 from (0:inf); |
|||
parameter real Rl = 0.3 from [0:1]; |
|||
parameter real Rr = 0.3 from [0:1]; |
|||
parameter real Nr = 3.5 from (0:inf); |
|||
parameter real L = 500u from (0:inf); |
|||
|
|||
real Gws=Vw/Vs; |
|||
real VT=`P_K*$temperature/`P_Q; |
|||
//real Gws=Alpha_w/Alpha_s; |
|||
real Alpha_w=`P_Q*Vw; |
|||
real Alpha_s=`P_Q*Vs; |
|||
real Rsch; |
|||
real Csch; |
|||
real Cch; |
|||
real Rch; |
|||
real Nw,G; |
|||
real CPL,CPR; |
|||
real TEMPR=$temperature; |
|||
|
|||
branch (Vin,Gnd) RRsch,CCsch; |
|||
branch (Gnd,Vin) G1; |
|||
branch (Nin1,Gnd) Gn,Ga,RRgnd; |
|||
branch (Gnd,Nin1) Gs; |
|||
branch (Nin1,Nlight) Gst; |
|||
branch (Gnd,Nlight) Gb; |
|||
branch (Nlight,Gnd) RRch,CCch; |
|||
|
|||
real UAlpha_w,UNom,Ug0,Uxi; |
|||
|
|||
analog begin |
|||
UAlpha_w=Alpha_w*1e18; |
|||
UNom=Nom*1e-18; |
|||
Ug0=g0*1e18; |
|||
Uxi=xi*1e18; |
|||
|
|||
Rsch=`P_Q*Gws*tau_s/UAlpha_w/Cn; |
|||
Csch=UAlpha_w*Cn/`P_Q/Gws; |
|||
Cch=UAlpha_w; |
|||
Rch=tau_p/UAlpha_w; |
|||
|
|||
Nw=UNom*exp(`P_Q*V(Nin1,Gnd)/(eta*`P_K*TEMPR)); |
|||
G=Ug0*(Nw-UNom)/(sqrt(Nw/pow(10,24-18))+sqrt(UNom/pow(10,24-18))); |
|||
|
|||
CPL=`P_H*`P_C*`P_C*(Rl-1.0)*ln(Rl*Rr)/(2.0*Nr*L*V(Vlam)*(1-Rl+sqrt(Rl/Rr)*(1-Rr)))*(Vs+Vw)*1e18; |
|||
CPR=`P_H*`P_C*`P_C*(Rr-1.0)*ln(Rl*Rr)/(2.0*Nr*L*V(Vlam)*(1-Rr+sqrt(Rr/Rl)*(1-Rl)))*(Vs+Vw)*1e18; |
|||
|
|||
|
|||
V(RRsch) <+ Rsch*I(RRsch); |
|||
I(CCsch) <+ Csch*ddt(V(CCsch)); |
|||
I(G1) <+ tau_n/tau_e*UAlpha_w*Nw/tau_n; |
|||
|
|||
I(Gs) <+ V(Vin,Gnd)/Rsch-tau_n/tau_e*UAlpha_w*Nw/tau_n; |
|||
I(Gn) <+ UAlpha_w*Nw/tau_n; |
|||
I(Ga) <+ tau_n*ddt(UAlpha_w*Nw/tau_n); |
|||
V(RRgnd) <+ 1T*I(RRgnd); |
|||
|
|||
I(Gst) <+ Gamma*UAlpha_w*G*abs(V(Nlight,Gnd))/(1+Uxi*abs(V(Nlight,Gnd))); |
|||
|
|||
I(Gb) <+ beta*UAlpha_w*Nw/tau_n; |
|||
V(RRch) <+ I(RRch)*Rch; |
|||
I(CCch) <+ Cch*ddt(V(CCch)); |
|||
|
|||
V(OpowL,Gnd) <+ CPL*V(Nlight,Gnd); |
|||
V(OpowR,Gnd) <+ CPR*V(Nlight,Gnd); |
|||
V(OphaseL) <+ 0; |
|||
V(OphaseR) <+ 0; |
|||
V(OlamL) <+ V(Vlam); |
|||
V(OlamR) <+ V(Vlam); |
|||
end |
|||
|
|||
|
|||
endmodule |
@ -0,0 +1,380 @@ |
|||
//VerilogA for laser,vcsel,veriloga |
|||
// DOI: 10.1109/JLT.2021.3064465 |
|||
|
|||
`include "constants.vams" |
|||
`include "./disciplines.vams" |
|||
|
|||
module vcsel(Vin,Vlam,Gnd,Opow,Ophase,Olam,Tout); |
|||
parameter real Egart = 1.53 from (0:inf); |
|||
parameter real dEga = -1.63e-3 from (-inf:inf); |
|||
parameter real meA = 0.0622 from (0:inf); |
|||
parameter real mhhA = 0.346 from (0:inf); |
|||
parameter real tcap = 7.0e-12 from (0:inf); |
|||
parameter real etaA = 1.6 from [0:inf); |
|||
parameter real etaesc = 2.0 from [0:inf); |
|||
parameter real A0A = 7.4e5 from (0:inf); |
|||
parameter real Art = 0.45e9 from (-inf:inf); |
|||
parameter real dA = 0 from (-inf:inf); |
|||
parameter real d2A = 0 from (-inf:inf); |
|||
parameter real Brt = 3.0e-16 from (-inf:inf); |
|||
parameter real dB = -1.19e-18 from (-inf:inf); |
|||
parameter real d2B = 5.74e-21 from (-inf:inf); |
|||
parameter real Crt = -7.9e-42 from (-inf:inf); |
|||
parameter real dC = 8.2e-44 from (-inf:inf); |
|||
parameter real d2C = -5.4e-46 from (-inf:inf); |
|||
|
|||
parameter real Egbrt = 1.89 from (0:inf); |
|||
parameter real dEgb = -4.5e-4 from (-inf:inf); |
|||
parameter real meB = 0.0977 from (0:inf); |
|||
parameter real mhhB = 0.596 from (0:inf); |
|||
parameter real etainj = 0.8 from [0:1]; |
|||
parameter real tspb = 5.0e-9 from (0:inf); |
|||
parameter real etaB = 1.0 from [0:inf); |
|||
parameter real etaleak = 2.0 from [0:inf]; |
|||
parameter real A0B = 7.4e5 from (0:inf); |
|||
parameter real Egcrt = 2.31 from (0:inf); |
|||
parameter real dEgc = 4.94e-4 from (-inf:inf); |
|||
|
|||
parameter real a0rt = 7.54e5 from (0:inf); |
|||
parameter real da0 = 8.22e2 from (-inf:inf); |
|||
parameter real d2a0 = 2.66 from (-inf:inf); |
|||
parameter real a1d = -1.4e13 from (-inf:inf); |
|||
parameter real a1u = -1.34e13 from (-inf:inf); |
|||
parameter real a2d = 1.57e20 from (-inf:inf); |
|||
parameter real a2u = 2.03e21 from (-inf:inf); |
|||
parameter real N0rt = 2.76e24 from (0:inf); |
|||
parameter real dN0 = 9.22e21 from (-inf:inf); |
|||
parameter real Ns = -1.5e21 from (-inf:inf); |
|||
parameter real eps = 5.0e-24 from (0:1]; |
|||
parameter real lamgrt = 857.0e-9 from (0:inf); |
|||
parameter real dlamg = 0.314e-9 from (-inf:inf); |
|||
parameter real dlamgdna = -3.26e-33 from (-inf:inf); |
|||
parameter real d2lamgdna = -5.44e-60 from (-inf:inf); |
|||
|
|||
// parameter real lamrt = 847.3e-9; |
|||
parameter real dlam = 0.064e-9 from (-inf:inf); |
|||
parameter real vg = 1e8 from (0:inf); |
|||
parameter real gam = 3.28e-2 from (0:1]; |
|||
parameter real beta = 4.68e-2 from (0:1]; |
|||
parameter real alabsrt = 6.19e10 from (0:inf); |
|||
parameter real dalabs = 0 from (-inf:inf); |
|||
parameter real d2alabs = 7e6 from (-inf:inf); |
|||
parameter real albmrt = 1.35e10 from (0:inf); |
|||
parameter real dalbm = -1.5e8 from (-inf:inf); |
|||
parameter real altmrt = 1.91e11 from (0:inf); |
|||
parameter real daltm = -7e8 from (-inf:inf); |
|||
|
|||
parameter real tth = 1e-7 from (0:inf); |
|||
parameter real rthrt = 2.8e3 from (0:inf); |
|||
parameter real drth = 2.5 from (-inf:inf); |
|||
|
|||
parameter real nqw = 5 from (0:inf); |
|||
parameter real dqw = 4e-9 from (0:inf); |
|||
parameter real dsch = 74e-9 from (0:inf); |
|||
parameter real Aape = 38.5e-12 from (0:inf); |
|||
|
|||
parameter real Lb = 0 from [0:inf); |
|||
parameter real Rb = 0 from [0:inf); |
|||
parameter real Lp1 = 76.0e-12 from [0:inf); |
|||
parameter real Rp1 = 0 from [0:inf); |
|||
parameter real Lp2 = 0 from [0:inf); |
|||
parameter real Rp2 = 0 from [0:inf); |
|||
parameter real Cp = 50.0e-15 from [0:inf); |
|||
parameter real Rp3 = 150.0e-3 from [0:inf); |
|||
parameter real rmrt = 170 from [0:inf); |
|||
parameter real drm = -0.96 from (-inf:inf); |
|||
parameter real d2rm = 1.38e-2 from (-inf:inf); |
|||
parameter real d3rm = -1.11e-4 from (-inf:inf); |
|||
parameter real etaRm1 = 0.285 from [0:1]; |
|||
parameter real etaRm2 = 0.125 from [0:1]; |
|||
parameter real etaRm3 = 0.590 from [0:1]; |
|||
parameter real Cm1 = 2.02e-15 from [0:inf); |
|||
parameter real Cm2 = 19.5e-15 from [0:inf); |
|||
parameter real Cm3 = 88.6e-15 from [0:inf); |
|||
parameter real Cdep = 50.0e-15 from [0:inf); |
|||
|
|||
input Vin,Vlam; |
|||
output Opow,Ophase,Olam,Tout; |
|||
inout Gnd; |
|||
thermal Tout; |
|||
electrical Vin,Vlam,Gnd,Opow,Ophase,Olam; |
|||
electrical Nscha,Nschb,Nph,NTem,NTru; |
|||
electrical NLb,NLbp,NLp1,NLp,NLp2,NLp3,NLpm,NLm12,NLm23,NLsch; |
|||
|
|||
//cir1 |
|||
branch(Vin,NLb) LLb; |
|||
branch(NLb,NLbp) RRb; |
|||
branch(NLbp,NLp1) LLp1; |
|||
branch(NLp1,NLp) RRp1; |
|||
branch(NLp,NLp3) CCp; |
|||
branch(NLp3,Gnd) RRp3; |
|||
branch(NLp,NLp2) LLp2; |
|||
branch(NLp2,NLpm) RRp2; |
|||
branch(NLpm,NLm12) CCm1,RRm1; |
|||
branch(NLm12,NLm23) CCm2,RRm2; |
|||
branch(NLm23,NLsch) CCm3,RRm3; |
|||
branch(NLsch,Gnd) CCdep,BUsch; |
|||
|
|||
//cir2 |
|||
branch(Gnd,Nschb) BIinj,BIescb; |
|||
branch(Nschb,Gnd) BIspb,BIcapb,BIleak,CCb; |
|||
|
|||
//cir3 |
|||
branch(Gnd,Nscha) BIcapa; |
|||
branch(Nscha,Gnd) BIspa1,BIspa2,BIspa3,BIesca,BIsta,CCa; |
|||
|
|||
//cir4 |
|||
branch(Gnd,Nph) BIsts,BIsp; |
|||
branch(Nph,Gnd) BIabs,BIbm,BItm,CCs; |
|||
|
|||
//cir5 |
|||
branch(Gnd,NTem) BIgen,CCt; |
|||
branch(NTem,NTru) RRth; |
|||
branch(NTru,Gnd) BUamb; |
|||
|
|||
real fa = 1; |
|||
real fb = 1; |
|||
real fs = 1; |
|||
real ft = 1; |
|||
|
|||
real cop = 1; |
|||
real midn; |
|||
|
|||
real k = `P_K; |
|||
real kev = 8.6173357e-5; |
|||
real q = `P_Q; |
|||
real h = `P_H; |
|||
real hev = 4.135667e-15; |
|||
real pi = `M_PI; |
|||
real m0 = 9.109e-31; |
|||
|
|||
real Tamb = $temperature; |
|||
real Trt = 273.15+25; |
|||
real na,nb,S,Tem; |
|||
real rm,Ega,Egb,Egc,A,B,C,a0,N0,lam,lamg,alabs,albm,altm,rth,a1,a2; |
|||
real Va,Vb; |
|||
real Nc,Nv,Efa,Efb; |
|||
real Usch,g,ggen,Rm1,Rm2,Rm3; |
|||
real Isch,Iinj,Iesc,Ileak,Ist,Isp; |
|||
real Cb,Ca,Cs,Ct,RthR; |
|||
real Popt; |
|||
real Rspb,Rcap,Rabs,Rbm,Rtm,Rspa1,Ispa2,Ispa3; |
|||
|
|||
real Zdqw = dqw * cop;//1 |
|||
real Zdsch = dsch * cop;//1 |
|||
real ZA0B = A0B * pow(cop,-2);//-2 |
|||
real ZA0A = A0A * pow(cop,-2);//-2 |
|||
real ZBrt = Brt * pow(cop,3);//3 |
|||
real ZdB = dB * pow(cop,3);//3 |
|||
real Zd2B = d2B * pow(cop,3);//3 |
|||
real ZCrt = Crt * pow(cop,6);//6 |
|||
real ZdC = dC * pow(cop,6);//6 |
|||
real Zd2C = d2C * pow(cop,6);//6 |
|||
real Za0rt = a0rt * pow(cop,-1);//-1 |
|||
real Zda0 = da0 * pow(cop,-1);//-1 |
|||
real Zd2a0 = d2a0 * pow(cop,-1);//-1 |
|||
real Za1,Za2;//-2,-3 |
|||
real ZN0rt = N0rt * pow(cop,-3);//-3 |
|||
real ZdN0 = dN0 * pow(cop,-3);//-3 |
|||
real ZNs = Ns * pow(cop,-3);//-3 |
|||
real Zeps = eps * pow(cop,3);//3 |
|||
real Zlamgrt = lamgrt * cop;//1 |
|||
real Zdlamg = dlamg * cop;//1 |
|||
real Zdlamgdna = dlamgdna * pow(cop,4);//4 |
|||
real Zd2lamgdna = d2lamgdna * pow(cop,7);//7 |
|||
real Zlamrt;// = lamrt * cop;//1 |
|||
real Zdlam = dlam * cop;//1 |
|||
real Zvg = vg * cop;//1 |
|||
real Zm0 = m0 * pow(cop,-2);//-2 |
|||
real ZVa,ZVb;//3 |
|||
real ZPc = `P_C * cop;//1 |
|||
|
|||
real Mefa11,Mefa12,Mefa13,Mefa21,Mefa22,Mefa23; |
|||
real Mefb11,Mefb12,Mefb13,Mefb14,Mefb15,Mefb16,Mefb17,Mefb18,Mefb1,Mefb21,Mefb22,Mefb23,Mefb24,Mefb25,Mefb26,Mefb27,Mefb28,Mefb2; |
|||
real Mg1,Mg2,Mg3,Mg4,Mg5,Mg6; |
|||
real Mesc1,Mesc2,Mesc3; |
|||
real Mleak1,Mleak2,Mleak3; |
|||
|
|||
analog initial begin |
|||
Va = dqw * nqw * Aape; //(6) |
|||
Vb = dsch * Aape; //(7) |
|||
|
|||
ZVa = Va * pow(cop,3);//3 |
|||
ZVb = Vb * pow(cop,3);//3 |
|||
|
|||
Rspb = fb / q * tspb; //(11) |
|||
Rcap = fb / q * tcap; //(12) |
|||
Ca = q / fa; //(25) |
|||
Cb = q / fb; //(26) |
|||
|
|||
midn = 2 * pi * Zm0 * k / pow(h,2); |
|||
Tem=Tamb; |
|||
end |
|||
|
|||
analog begin |
|||
Zlamrt = V(Vlam) * cop;//1 |
|||
|
|||
na = abs(V(Nscha)) / fa; |
|||
nb = abs(V(Nschb)) / fb; |
|||
S = abs(V(Nph)) / fs; |
|||
Tem = abs(V(NTem)) / ft; |
|||
|
|||
rm = rmrt + drm * (Tem - Trt) + 0.5 * d2rm * pow((Tem - Trt),2) + 1.0 / 6.0 * d3rm * pow((Tem - Trt),3); //(47) |
|||
Ega = (Egart + dEga * (Tem - Trt)); //(48) |
|||
Egb = (Egbrt + dEgb * (Tem - Trt)); //(49) |
|||
Egc = (Egcrt + dEgc * (Tem - Trt)); //(50) |
|||
A = Art + dA * (Tem - Trt); //(51) |
|||
B = ZBrt + ZdB * (Tem - Trt) + 0.5 * Zd2B * pow((Tem - Trt),2); //(52) |
|||
C = ZCrt + ZdC * (Tem - Trt) + 0.5 * Zd2C * pow((Tem - Trt),2); //(53) |
|||
a0 = Za0rt + Zda0 * (Tem - Trt) + 0.5 * Zd2a0 * pow((Tem - Trt),2); //(54) |
|||
N0 = ZN0rt + ZdN0 * (Tem - Trt); //(55) |
|||
lam = Zlamrt + Zdlam * (Tem - Trt); //(56) |
|||
lamg = Zlamgrt + Zdlamg * (Tem - Trt) + Zdlamgdna * (na / ZVa) + 0.5 * Zd2lamgdna * pow((na / ZVa),2); //(57) |
|||
alabs = alabsrt + dalabs * (Tem - Trt) + 0.5 * d2alabs * pow((Tem - Trt),2); //(58) |
|||
albm = albmrt + dalbm * (Tem - Trt); //(59) |
|||
altm = altmrt + daltm * (Tem - Trt); //(60) |
|||
rth = rthrt + drth * (Tem - Trt); //(61) |
|||
if (lam > lamg) begin |
|||
a1 = a1u; |
|||
a2 = a2u; |
|||
end |
|||
else begin |
|||
a1 = a1d; |
|||
a2 = a2d; |
|||
end |
|||
|
|||
Za1 = a1 * pow(cop,-2);//-2 |
|||
Za2 = a2 * pow(cop,-3);//-3 |
|||
|
|||
Nc = 2.0 * abs(midn * meB * Tem)**(3.0/2.0); //(4) |
|||
Nv = 2.0 * abs(midn * mhhB * Tem )**(3.0/2.0); //(5) |
|||
|
|||
Mefa11 = Zdqw * na / ZVa; |
|||
Mefa12 = 2.0 * midn * Tem * meA; |
|||
Mefa13 = kev * Tem * ln(limexp(Mefa11 / Mefa12) - 1.0); |
|||
Mefa21 = Zdqw * na / ZVa; |
|||
Mefa22 = 2.0 * midn * Tem * mhhA; |
|||
Mefa23 = kev * Tem * ln(limexp(Mefa21 / Mefa22) - 1.0); |
|||
Efa = Ega + etaA * (Mefa13 + Mefa23); //(2) |
|||
|
|||
Mefb11 = nb / ZVb / Nc; |
|||
Mefb12 = 1.0 - pow(Mefb11,2); |
|||
Mefb13 = ln(Mefb11) / Mefb12; |
|||
Mefb14 = 3.0 * sqrt(pi) * nb / ZVb / 4.0 / Nc; |
|||
Mefb15 = Mefb14**(2.0/3.0); |
|||
Mefb16 = 0.24 + 1.08 * Mefb15; |
|||
Mefb17 = 1.0 + pow(Mefb16,-2); |
|||
Mefb18 = Mefb15 / Mefb17; |
|||
Mefb1 = Mefb13 + Mefb18; |
|||
Mefb21 = nb / ZVb / Nv; |
|||
Mefb22 = 1.0 - pow(Mefb21,2); |
|||
Mefb23 = ln(Mefb21) / Mefb22; |
|||
Mefb24 = 3.0 * sqrt(pi) * nb / ZVb / 4.0 / Nv; |
|||
Mefb25 = Mefb24**(2.0/3.0); |
|||
Mefb26 = 0.24 + 1.08 * Mefb25; |
|||
Mefb27 = 1.0 + pow(Mefb26,-2); |
|||
Mefb28 = Mefb25 / Mefb27; |
|||
Mefb2 = Mefb23 + Mefb28; |
|||
Efb = Egb + etaB * kev * Tem * (Mefb1 + Mefb2); //(3) |
|||
|
|||
Mg1 = (na / ZVa + ZNs)/(N0 + ZNs); |
|||
Mg2 = a0 * ln(Mg1); |
|||
Mg3 = Za1 * (lam - lamg); |
|||
Mg4 = Za2 * pow((lam - lamg),2); |
|||
Mg5 = 1.0 + Zeps * S * gam / ZVa; |
|||
Mg6 = Mg2 - Mg3 - Mg4; |
|||
g = Mg6 / Mg5; //(17) |
|||
if (g < 0) begin |
|||
g = 0; |
|||
end |
|||
// etas = hev * ZPc / lam; //(39) |
|||
Popt = hev * ZPc / lam * I(BItm); //(32) |
|||
ggen = V(Vin,Gnd) * I(LLb) - Popt; //(41) |
|||
Rm1 = rm * etaRm1; |
|||
Rm2 = rm * etaRm2; |
|||
Rm3 = rm * etaRm3; |
|||
RthR = rth * ft; //(45) |
|||
Cs = q / fs; //(38) |
|||
Ct = tth / rth / ft; //(44) |
|||
Iinj = etainj * Isch; //(10) |
|||
|
|||
Mesc1 = ZA0A * ZVa * pow(Tem,2) / (Zdqw * nqw); |
|||
Mesc2 = limexp(-Egb / (etaesc * kev * Tem)); |
|||
Mesc3 = limexp(Efa / (etaesc * kev * Tem)); |
|||
Iesc = Mesc1 * Mesc2 * (Mesc3 - 1); //(13) |
|||
Mleak1 = ZA0B * ZVb * pow(Tem,2) / Zdsch; |
|||
Mleak2 = limexp(-Egc / (etaleak * kev * Tem)); |
|||
Mleak3 = limexp(Efb / (etaleak * kev * Tem)); |
|||
Ileak = Mleak1 * Mleak2 * (Mleak3 - 1); //(14) |
|||
Rspa1 = fa / (q * A); //(15) |
|||
Ispa2 = B * pow(na,2) / ZVa * q; //(15) |
|||
Ispa3 = C * pow(na,3) / pow(ZVa,2) * q; //(15) |
|||
Ist = gam * Zvg * g * S * q; //(16) |
|||
|
|||
Isp = q * beta * B * pow(na,2) / ZVa; //(28) |
|||
Rabs = fs / (q * alabs); //(29) |
|||
Rbm = fs / (q * albm); //(30) |
|||
Rtm = fs / (q * altm); //(31) |
|||
|
|||
Isch = I(BUsch); |
|||
Usch = (na * Efa + nb * Efb)/((na + nb)); //(1) |
|||
|
|||
//cir1 |
|||
V(LLb) <+ Lb * ddt(I(LLb)); |
|||
V(RRb) <+ Rb * I(RRb); |
|||
V(LLp1) <+ Lp1 * ddt(I(LLp1)); |
|||
V(RRp1) <+ Rp1 * I(RRp1); |
|||
I(CCp) <+ Cp * ddt(V(CCp)); |
|||
V(RRp3) <+ Rp3 * I(RRp3); |
|||
V(LLp2) <+ Lp2 * ddt(I(LLp2)); |
|||
V(RRp2) <+ Rp2 * I(RRp2); |
|||
I(CCm1) <+ Cm1 * ddt(V(CCm1)); |
|||
V(RRm1) <+ Rm1 * I(RRm1); |
|||
I(CCm2) <+ Cm2 * ddt(V(CCm2)); |
|||
V(RRm2) <+ Rm2 * I(RRm2); |
|||
I(CCm3) <+ Cm3 * ddt(V(CCm3)); |
|||
V(RRm3) <+ Rm3 * I(RRm3); |
|||
I(CCdep) <+ Cdep * ddt(V(CCdep)); |
|||
V(BUsch) <+ Usch; |
|||
|
|||
//cir2 |
|||
I(BIinj) <+ Iinj; //(18) |
|||
I(BIescb) <+ Iesc; //(21) |
|||
V(BIspb) <+ Rspb * I(BIspb); //(19) |
|||
V(BIcapb) <+ Rcap * I(BIcapb); //(20) |
|||
I(BIleak) <+ Ileak; //(22) |
|||
I(CCb) <+ Cb * ddt(V(CCb)); |
|||
|
|||
//cir3 |
|||
I(BIcapa) <+ I(BIcapb); //(20) |
|||
I(CCa) <+ Ca * ddt(V(CCa)); |
|||
V(BIspa1) <+ Rspa1 * I(BIspa1); //(23) |
|||
I(BIspa2) <+ Ispa2; //(23) |
|||
I(BIspa3) <+ Ispa3; //(23) |
|||
I(BIesca) <+ Iesc; //(21) |
|||
I(BIsta) <+ Ist; //(24) |
|||
|
|||
//cir4 |
|||
I(BIsts) <+ Ist; //(33) |
|||
I(BIsp) <+ Isp; //(34) |
|||
I(CCs) <+ Cs * ddt(V(CCs)); |
|||
V(BIabs) <+ Rabs * I(BIabs); //(35) |
|||
V(BIbm) <+ Rbm * I(BIbm);//(36) |
|||
V(BItm) <+ Rtm * I(BItm); //(37) |
|||
|
|||
//cir5 |
|||
I(BIgen) <+ ggen; //(43) |
|||
I(CCt) <+ Ct * ddt(V(CCt)); |
|||
V(RRth) <+ RthR * I(RRth); |
|||
V(BUamb) <+ Tamb * ft; //(46) |
|||
|
|||
//Light output |
|||
V(Opow) <+ Popt; |
|||
V(Ophase) <+ 0; |
|||
V(Olam) <+ lam / cop; |
|||
|
|||
//Temperature output |
|||
Temp(Tout) <+ Tem - 273.15; |
|||
end |
|||
|
|||
endmodule |
@ -0,0 +1,18 @@ |
|||
//VerilogA for lightsource,cw_maginput,veriloga |
|||
`include "constants.vams" |
|||
`include "disciplines.vams" |
|||
|
|||
module cw_maginput(Vmag,Vphase,Vlam,Opow,Ophase,Olam); |
|||
parameter real GainCoeff = 1 from [0:inf); |
|||
parameter real PhaseCoeff = 0 from (-360:360); |
|||
|
|||
input Vmag,Vphase,Vlam; |
|||
output Opow,Ophase,Olam; |
|||
electrical Vmag,Vphase,Vlam,Pout,Opow,Ophase,Olam; |
|||
|
|||
analog begin |
|||
V(Opow) <+ pow(V(Vmag)*GainCoeff,2); |
|||
V(Ophase) <+ PhaseCoeff+V(Vphase); |
|||
V(Olam) <+ V(Vlam); |
|||
end |
|||
endmodule |
@ -0,0 +1,19 @@ |
|||
//VerilogA for lightsource,cw_powinput,veriloga |
|||
`include "constants.vams" |
|||
`include "disciplines.vams" |
|||
|
|||
module cw_powinput(Vpow,Vphase,Vlam,Opow,Ophase,Olam); |
|||
parameter real GainCoeff = 1 from [0:inf); |
|||
parameter real PhaseCoeff = 0 from (-360:360); |
|||
|
|||
input Vpow,Vphase,Vlam; |
|||
output Opow,Ophase,Olam; |
|||
electrical Vpow,Vphase,Vlam,Pout,Opow,Ophase,Olam; |
|||
|
|||
analog begin |
|||
V(Opow) <+ GainCoeff*V(Vpow); |
|||
V(Ophase) <+ PhaseCoeff+V(Vphase); |
|||
V(Olam) <+ V(Vlam); |
|||
end |
|||
|
|||
endmodule |
@ -0,0 +1,23 @@ |
|||
//VerilogA for lightsource,cw_realimageinput,veriloga |
|||
`include "constants.vams" |
|||
`include "disciplines.vams" |
|||
|
|||
module cw_realimageinput(Vreal,Vimag,Vlam,Opow,Ophase,Olam); |
|||
parameter real GainCoeff = 1 from [0:inf); |
|||
parameter real PhaseCoeff = 0 from (-360:360); |
|||
|
|||
input Vreal,Vimag,Vlam; |
|||
output Opow,Ophase,Olam; |
|||
electrical Vreal,Vimag,Vlam,Pout,Opow,Ophase,Olam; |
|||
real mag,phase; |
|||
|
|||
analog begin |
|||
mag=sqrt(pow(V(Vreal),2)+pow(V(Vimag),2)); |
|||
phase=acos(V(Vreal)/mag); |
|||
V(Opow) <+ pow(mag*GainCoeff,2); |
|||
V(Ophase) <+ (PhaseCoeff+phase)/(2*`M_PI)*360.0; |
|||
V(Olam) <+ V(Vlam); |
|||
end |
|||
|
|||
|
|||
endmodule |
@ -0,0 +1,17 @@ |
|||
//VerilogA for lightsource,led,veriloga |
|||
`include "constants.vams" |
|||
`include "disciplines.vams" |
|||
|
|||
module led(Vcurr,Vlam,Opow,Ophase,Olam); |
|||
input Vcurr,Vlam; |
|||
output Opow,Ophase,Olam; |
|||
electrical Vcurr,Vlam,Opow,Ophase,Olam; |
|||
|
|||
parameter real eta = 1 from (-inf:inf); |
|||
|
|||
analog begin |
|||
V(Opow) <+ eta*`P_H*`P_C/V(Vlam)*I(Vcurr)/`P_Q; |
|||
V(Ophase) <+ 0; |
|||
V(Olam) <+ V(Vlam); |
|||
end |
|||
endmodule |
@ -0,0 +1,95 @@ |
|||
//VerilogA for modulator,basicea,veriloga |
|||
`include "constants.vams" |
|||
`include "disciplines.vams" |
|||
|
|||
`define MAX_ARRAY 1000 |
|||
|
|||
module basicea(V1,V2,Gnd,Ipow,Iphase,Ilam,Opow,Ophase,Olam); |
|||
parameter real Gam_c = 0 from (-inf:inf); |
|||
parameter integer tau_L = 6 from [1:inf); |
|||
parameter integer num_carriler = 2 from [1:inf); |
|||
parameter integer num_voltage = 6 from [1:inf); |
|||
//TODO: file for multinomial coefficients |
|||
parameter string tau_file = "./tau_mat.in"; |
|||
parameter string alpha_file = "./alpha_mat.in"; |
|||
parameter string gamma_file = "./gamma_mat.in"; |
|||
//Use LF!!! |
|||
|
|||
input Ipow,Iphase,Ilam; |
|||
output Opow,Ophase,Olam; |
|||
inout V1,V2,Gnd; |
|||
electrical V1,V2,Ipow,Iphase,Ilam,Opow,Ophase,Olam,Gnd,Nph,Ns; |
|||
|
|||
real Vcalc; |
|||
real Gamma=0,Alpha=0; |
|||
real tau=0; |
|||
real opow,ophase; |
|||
integer file_tau,file_alpha,file_gamma; |
|||
integer i,j; |
|||
real f=1e-18; |
|||
real readfile=0; |
|||
real tau_array[0:`MAX_ARRAY]; |
|||
real alpha_array[0:`MAX_ARRAY]; |
|||
real gamma_array[0:`MAX_ARRAY]; |
|||
|
|||
branch (Gnd,Ns) Cs,Is; |
|||
branch (Ns,Gnd) It; |
|||
branch (Gnd,Nph) Cph,Iph; |
|||
|
|||
analog begin |
|||
if (readfile==0) begin |
|||
file_tau=$fopen(tau_file,"r"); |
|||
file_alpha=$fopen(alpha_file,"r"); |
|||
file_gamma=$fopen(gamma_file,"r"); |
|||
if (file_tau==0 || file_alpha==0 || file_gamma==0) begin |
|||
$display("Error: Could not open file"); |
|||
$finish; |
|||
end |
|||
for (i=0;i<tau_L;i=i+1) begin |
|||
$fscanf(file_tau,"%f",tau_array[i]); |
|||
end |
|||
for (i=0;i<num_voltage;i=i+1) begin |
|||
for (j=0;j<num_carriler;j=j+1) begin |
|||
$fscanf(file_alpha,"%f",alpha_array[i*num_carriler+j]); |
|||
$fscanf(file_gamma,"%f",gamma_array[i*num_carriler+j]); |
|||
end |
|||
end |
|||
$fclose(file_tau); |
|||
$fclose(file_alpha); |
|||
$fclose(file_gamma); |
|||
readfile=1; |
|||
end |
|||
|
|||
Vcalc=V(V1)-V(V2); |
|||
tau=0; |
|||
for (i=0;i<tau_L;i=i+1) begin |
|||
tau=tau+tau_array[i]*pow(Vcalc,i); |
|||
end |
|||
Gamma=0; |
|||
Alpha=0; |
|||
for (i=0;i<num_voltage;i=i+1) begin |
|||
for (j=0;j<num_carriler;j=j+1) begin |
|||
Gamma=Gamma+gamma_array[i*num_carriler+j]*pow(Vcalc,j)*pow(V(Ns),i); //pow(N,i)*pow(f,i) |
|||
Alpha=Alpha+alpha_array[i*num_carriler+j]*pow(Vcalc,j)*pow(V(Ns),i); //Caution the unit |
|||
end |
|||
end |
|||
if (Gamma==0) |
|||
opow=0; |
|||
else begin |
|||
opow=pow(sqrt(V(Ipow))*exp(-Gamma/2),2); |
|||
end |
|||
|
|||
I(Is) <+ f*V(Ilam)/(`P_H*`P_C)*exp(-Gam_c)*(1-exp(-Gamma+2*Gam_c))*V(Ipow); |
|||
I(It) <+ V(Ns)/tau; |
|||
I(Cs) <+ ddt(V(Cs)); |
|||
|
|||
I(Iph) <+ Alpha/2*ddt(Gamma); |
|||
I(Cph) <+ ddt(V(Cph)); |
|||
ophase=V(Nph)+V(Iphase)*(2*`M_PI)/360.0; |
|||
|
|||
V(Opow) <+ opow; |
|||
V(Ophase) <+ ophase/(2*`M_PI)*360.0; |
|||
V(Olam) <+ V(Ilam); |
|||
end |
|||
|
|||
endmodule |
@ -0,0 +1,82 @@ |
|||
//VerilogA for modulator,basicmz,veriloga |
|||
//With no S21 - S21 is ideal |
|||
|
|||
`include "constants.vams" |
|||
`include "disciplines.vams" |
|||
|
|||
module basicmz(Ipow,Iphase,Ilam,Opow,Ophase,Olam,Vrfu,Vrfl,Vdcu,Vdcl,Gnd); |
|||
parameter real VpiDC = 5 from (0:inf); |
|||
parameter real VpiRF = 5 from (0:inf); |
|||
parameter real insloss = 6 from [0:inf); |
|||
parameter real extratio = 35 from [0:inf); |
|||
parameter integer lowarmphase = -1 from [-1:1] exclude 0; |
|||
parameter real dVdcdT = 0 from (-inf:inf); |
|||
parameter real dVrfdT = 0 from (-inf:inf); |
|||
parameter real reftem = 25 from (-273.15:inf); |
|||
// parameter real eleclenupper = 40.0e-3 from (0:inf); |
|||
// parameter real indexmisupper = 0.05; |
|||
// parameter real mwavelossupper = 0.005 from [0:inf); |
|||
// parameter real eleclenlower = 40.0e-3 from (0:inf); |
|||
// parameter real indexmislower = 0.05; |
|||
// parameter real mwavelosslower = 0.005 from [0:inf); |
|||
// parameter real digfilterorder = 1024 from [8:4096]; |
|||
parameter integer directmod = 0 from [0:1]; |
|||
|
|||
input Ipow,Iphase,Ilam,Vrfu,Vrfl,Vdcu,Vdcl; |
|||
output Opow,Ophase,Olam; |
|||
inout Gnd; |
|||
electrical Ipow,Iphase,Ilam,Opow,Ophase,Olam,Vrfu,Vrfl,Vdcu,Vdcl,Gnd; |
|||
|
|||
branch (Vrfu,Gnd) Rrfu; |
|||
branch (Vrfl,Gnd) Rrfl; |
|||
branch (Vdcu,Gnd) Rdcu; |
|||
branch (Vdcl,Gnd) Rdcl; |
|||
|
|||
real top=$temperature; |
|||
real tref=273.15+reftem; |
|||
real phiu,phil,yspu,yspl,eps; |
|||
real Mpu1,Mpu2,Mpl1,Mpl2; |
|||
real reu,imu,rel,iml,reh,imh,eh,phih,h; |
|||
|
|||
real Rint = 50; |
|||
|
|||
analog begin |
|||
if (directmod == 1) begin |
|||
yspu=(1+1/sqrt(pow(10,extratio/10)))/2*sqrt(2); |
|||
yspl=(1-yspu)*sqrt(2); |
|||
end |
|||
else begin |
|||
if (extratio<6.1) begin |
|||
$display("Error: extratio must be greater than 6.1"); |
|||
$finish; |
|||
end |
|||
eps = 1.0/sqrt(pow(10,extratio/10.0)); |
|||
yspu = sqrt(0.5+eps); |
|||
yspl = sqrt(0.5-eps); |
|||
end |
|||
Mpu1 = `M_PI*V(Vrfu)/(VpiRF+(top-tref)*dVrfdT); |
|||
Mpu2 = `M_PI*V(Vdcu)/(VpiDC+(top-tref)*dVdcdT); |
|||
Mpl1 = `M_PI*V(Vrfl)/(VpiRF+(top-tref)*dVrfdT); |
|||
Mpl2 = `M_PI*V(Vdcl)/(VpiDC+(top-tref)*dVdcdT); |
|||
phiu = (Mpu1+Mpu2); |
|||
phil = lowarmphase*(Mpl1+Mpl2); |
|||
reu = yspu*cos(phiu); |
|||
imu = yspu*sin(phiu); |
|||
rel = yspl*cos(phil); |
|||
iml = yspl*sin(phil); |
|||
reh = reu+rel; |
|||
imh = imu+iml; |
|||
eh = sqrt(reh*reh+imh*imh); |
|||
phih = acos(reh/eh); |
|||
h = 1.0/sqrt(2)*eh/pow(10,insloss/10.0); |
|||
|
|||
I(Rrfu) <+ V(Vrfu)/Rint; |
|||
I(Rrfl) <+ V(Vrfl)/Rint; |
|||
I(Rdcu) <+ V(Vdcu)/Rint; |
|||
I(Rdcl) <+ V(Vdcl)/Rint; |
|||
|
|||
V(Opow) <+ V(Ipow)*h*h; |
|||
V(Ophase) <+ V(Iphase)+phih*360.0/(2*`M_PI); |
|||
V(Olam) <+ V(Ilam); |
|||
end |
|||
endmodule |
@ -0,0 +1,19 @@ |
|||
//VerilogA for modulator,idealam,veriloga |
|||
|
|||
`include "constants.vams" |
|||
`include "disciplines.vams" |
|||
|
|||
module idealam(Ipow,Iphase,Ilam,Opow,Ophase,Olam,Vdata); |
|||
parameter real m = 1 from [0:1]; |
|||
|
|||
input Ipow, Iphase, Ilam, Vdata; |
|||
output Opow, Ophase, Olam; |
|||
electrical Ipow, Iphase, Ilam, Vdata, Opow, Ophase, Olam; |
|||
|
|||
analog begin |
|||
V(Opow) <+ V(Ipow)*(1-m+m*V(Vdata)); |
|||
V(Ophase) <+ V(Iphase); |
|||
V(Olam) <+ V(Ilam); |
|||
end |
|||
|
|||
endmodule |
@ -0,0 +1,23 @@ |
|||
//VerilogA for modulator,idealea,veriloga |
|||
|
|||
`include "constants.vams" |
|||
`include "disciplines.vams" |
|||
|
|||
module idealea(Ipow,Iphase,Ilam,Opow,Ophase,Olam,Vdata); |
|||
parameter real modu = 0.9 from [0:1); |
|||
parameter real chir = 0 from (-inf:inf); |
|||
|
|||
input Ipow,Iphase,Ilam,Vdata; |
|||
output Opow,Ophase,Olam; |
|||
electrical Ipow,Iphase,Ilam,Opow,Ophase,Olam,Vdata; |
|||
|
|||
real dt; |
|||
analog begin |
|||
dt = (1-modu)+modu*V(Vdata); |
|||
V(Opow) <+ V(Ipow)*dt; |
|||
V(Ophase) <+ V(Iphase)+chir/2.0*ln(dt)*360.0/(2*`M_PI); |
|||
V(Olam) <+ V(Ilam); |
|||
end |
|||
|
|||
|
|||
endmodule |
@ -0,0 +1,22 @@ |
|||
//VerilogA for modulator,idealfm,veriloga |
|||
|
|||
`include "constants.vams" |
|||
`include "disciplines.vams" |
|||
|
|||
module idealfm(Ipow,Iphase,Ilam,Opow,Ophase,Olam,Vdata); |
|||
parameter real df = 10e9 from (-inf:inf); |
|||
input Ipow,Iphase,Ilam,Vdata; |
|||
output Opow,Ophase,Olam; |
|||
electrical Ipow,Iphase,Ilam,Opow,Ophase,Olam,Vdata; |
|||
|
|||
real f,dlam; |
|||
|
|||
analog begin |
|||
f = (V(Vdata)-0.5)*df; |
|||
dlam = `P_C/f; |
|||
V(Opow) <+ V(Ipow); |
|||
V(Ophase) <+ V(Iphase); |
|||
V(Olam) <+ V(Ilam) + dlam; |
|||
end |
|||
|
|||
endmodule |
@ -0,0 +1,23 @@ |
|||
//VerilogA for modulator,idealmz,veriloga |
|||
|
|||
`include "constants.vams" |
|||
`include "disciplines.vams" |
|||
|
|||
module idealmz(Ipow,Iphase,Ilam,Opow,Ophase,Olam,Vdata); |
|||
parameter real ext = 30 from [0:inf); |
|||
parameter real sym = -1 from [-1:1); |
|||
parameter integer Chirp = 1 from [-1:1] exclude 0; |
|||
input Ipow,Iphase,Ilam,Vdata; |
|||
output Opow,Ophase,Olam; |
|||
electrical Ipow,Iphase,Ilam,Opow,Ophase,Olam,Vdata; |
|||
|
|||
real fext,dph; |
|||
analog begin |
|||
fext = 1.0 - 4.0 / `M_PI * atan(1.0 / sqrt(pow(10, ext / 10.0))); |
|||
dph = `M_PI / 2.0 * (0.5 - fext * (V(Vdata) - 0.5)); |
|||
V(Olam) <+ V(Ilam); |
|||
V(Ophase) <+ V(Iphase) + Chirp * dph * (1 + sym)/(1 - sym) * 360.0 / (2 * `M_PI); |
|||
V(Opow) <+ V(Ipow) * pow(cos(dph),2); |
|||
end |
|||
|
|||
endmodule |
@ -0,0 +1,18 @@ |
|||
//VerilogA for modulator,idealpm,veriloga |
|||
|
|||
`include "constants.vams" |
|||
`include "disciplines.vams" |
|||
|
|||
module idealpm(Ipow,Iphase,Ilam,Opow,Ophase,Olam,Vdata); |
|||
parameter real dph = 180 from (-inf:inf); |
|||
input Ipow,Iphase,Ilam,Vdata; |
|||
output Opow,Ophase,Olam; |
|||
electrical Ipow,Iphase,Ilam,Opow,Ophase,Olam,Vdata; |
|||
|
|||
analog begin |
|||
V(Opow) <+ V(Ipow); |
|||
V(Ophase) <+ V(Iphase) + dph * V(Vdata) * 360 / (2 * `M_PI); |
|||
V(Olam) <+ V(Ilam); |
|||
end |
|||
|
|||
endmodule |
@ -0,0 +1,584 @@ |
|||
//VerilogA for modulator,neffmz,veriloga |
|||
//Xuanqi Chen, Zhifei Wang, Yi-Shing Chang, Jiang Xu, Jun Feng, Peng Yang, Zhehui Wang, Luan H. K. Duong, ”Modeling and Analysis of Optical Modulators Based on Free-Carrier Plasma Dispersion Effect,” IEEE Transactions on Computer-Aided Design of Integrated Circuits and Systems (TCAD), vol. 39, no. 5, pp. 977-990, May 2020. |
|||
|
|||
`include "constants.vams" |
|||
`include "disciplines.vams" |
|||
|
|||
`define MAX_MODES 200 |
|||
`define MAX_ITER 10000 |
|||
`define IDX_NUM 10000 |
|||
`define TOLERANCE 0.0000000001 |
|||
`define MAX_TABLE_SIZE 300000 |
|||
|
|||
module neffmz(Ipow,Iphase,Ilam,Opow,Ophase,Olam,Vbias,Gnd); |
|||
parameter real design_lam = 1.55e-6 from (0:inf); |
|||
parameter real n_ps = 3.45 from (0:inf); |
|||
parameter real n_sub = 1.45 from (0:inf); |
|||
parameter real width_MMI = 3e-6 from (0:inf); |
|||
parameter real width_port = 0.45e-6 from (0:inf); |
|||
parameter real port_offset = 0.75e-6 from (0:inf); |
|||
parameter real thickness = 0.22e-6 from (0:inf); |
|||
parameter real alpha_mmi = 80 from (0:inf); |
|||
parameter real l_ps = 0.1e-6 from (0:inf); |
|||
parameter real l_arm = 40e-6 from (0:inf); |
|||
parameter real alpha_phaseshift_ref = 80 from [0:inf); |
|||
parameter real alpha_waveguide = 80 from [0:inf); |
|||
parameter real alpha_absorp = 1 from (0:inf); |
|||
parameter real alpha_wd = 1 from (0:inf); |
|||
parameter real rib_width = 0.4e-6 from (0:inf); |
|||
parameter real pn_offset = 0 from [0:inf); |
|||
parameter real ni = 1e16 from (0:inf); |
|||
parameter real N_A = 5e23 from (0:inf); |
|||
parameter real N_D = 1e24 from (0:inf); |
|||
parameter real Lp = 2e-6 from (0:inf); |
|||
parameter real Ln = 1e-6 from (0:inf); |
|||
parameter real epsr_Si = 11.7 from (0:inf); |
|||
parameter real Is = 1e-14 from (0:inf); |
|||
parameter real IBV = 1000u from (0:inf); |
|||
parameter real BV = 40 from (0:inf); |
|||
parameter real V0 = 1 from (0:inf); |
|||
parameter real Cj0 = 1.5p from (0:inf); |
|||
parameter real tau = 0.5n from (0:inf); |
|||
parameter real Rs = 55 from (0:inf); |
|||
parameter real emi = 1 from (0:inf); |
|||
parameter real Vt = 0.0259 from (0:inf); |
|||
parameter string neff_ps_filename = "../../../data/EIM/outputPN1.54-1.56-500.txt"; |
|||
|
|||
input Ipow,Iphase,Ilam,Vbias; |
|||
output Opow,Ophase,Olam; |
|||
inout Gnd; |
|||
electrical Ipow,Iphase,Ilam,Vbias,Opow,Ophase,Olam,Nint,Gnd; |
|||
|
|||
branch (Gnd,Nint) Iint; |
|||
branch (Nint,Gnd) CCj,CCd,Idd,RRs; |
|||
|
|||
real ulam, ulam0, uwidth_in, uwidth_MMI, uoffset, uthickness, alpha0; |
|||
real k1_ref, kc_ref; |
|||
integer mode_num, mode_num_ref; |
|||
real beta_x_MMI, beta_in, beta_x_in; |
|||
real neff_MMI[0:`MAX_MODES]; |
|||
real beta_MMI[0:`MAX_MODES]; |
|||
real length_MMI; |
|||
real ky_in, gamma_in; |
|||
real ky_MMI[0:`MAX_MODES]; |
|||
real gamma_MMI[0:`MAX_MODES]; |
|||
real c0; |
|||
real c0_dis[0:`MAX_MODES]; |
|||
real icoff[0:`MAX_MODES]; |
|||
real delta_beta; |
|||
real ocoff_r[0:`MAX_MODES]; |
|||
real ocoff_i[0:`MAX_MODES]; |
|||
real c1r, c1i, c2r, c2i; |
|||
real inr, ini, out1r, out1i, out2r, out2i; |
|||
real sum_outfield1, sum_outfield2, sum_outfield3, sum_outfield4; |
|||
real sum_singlemode1,sum_singlemode2,sum_singlemode3,sum_singlemode4; |
|||
real border; |
|||
integer i, j; |
|||
real p0=1; |
|||
real h; |
|||
|
|||
real beta_ps; |
|||
real k_ps_r,k_ps_i; |
|||
real p_ps_r,p_ps_i,p_wg_r,p_wg_i; |
|||
real E_in1_r,E_in1_i,E_in2_r,E_in2_i; |
|||
real E_out1_r,E_out1_i,E_out2_r,E_out2_i; |
|||
real alpha_phaseshift; |
|||
real W,Wdp,Wdn; |
|||
real eps,phi_bi,phi; |
|||
real N_avr; |
|||
real gd,Id,Cj,Cd; |
|||
real pn00,np00; |
|||
real lam; |
|||
real neff_phaseshift_ref,neff_phaseshift; |
|||
|
|||
real cp_tr11_r,cp_tr11_i,cp_tr12_r,cp_tr12_i,cp_tr21_r,cp_tr21_i,cp_tr22_r,cp_tr22_i; |
|||
real ar_tr11_r,ar_tr11_i,ar_tr12_r,ar_tr12_i,ar_tr21_r,ar_tr21_i,ar_tr22_r,ar_tr22_i; |
|||
real t1_11_r,t1_11_i,t1_12_r,t1_12_i,t1_21_r,t1_21_i,t1_22_r,t1_22_i; |
|||
real t2_11_r,t2_11_i,t2_12_r,t2_12_i,t2_21_r,t2_21_i,t2_22_r,t2_22_i; |
|||
|
|||
//1550nm |
|||
real sigma_ne=-8.8E-22; |
|||
real sigma_nh=-8.5E-18; |
|||
real sigma_ae=8.5E-18; |
|||
real sigma_ah=6.0E-18; |
|||
|
|||
real xlength=0.6u; |
|||
integer xnum=10001; |
|||
real x[0:10000]; |
|||
real np[0:10000]; |
|||
real pp[0:10000]; |
|||
real pn[0:10000]; |
|||
real nn[0:10000]; |
|||
real xx[0:20001]; |
|||
real n[0:20001]; |
|||
real p[0:20001]; |
|||
real wi,wf; |
|||
real dalpha_e[0:20001]; |
|||
real dalpha_h[0:20001]; |
|||
real dalpha[0:20001]; |
|||
real sum_dalpha; |
|||
real dalpha_avr; |
|||
|
|||
integer ps_file; |
|||
real width_start, width_end, width_step; |
|||
real lam_start, lam_end, lam_step; |
|||
integer width_num, lam_num; |
|||
real tmp; |
|||
real lam_old=0; |
|||
real width_old=0; |
|||
real neff_table_ps[0:`MAX_TABLE_SIZE] = {0}; |
|||
real neff_lamtable_ps[0:`MAX_TABLE_SIZE] = {0}; |
|||
real neff_widthtable_ps[0:`MAX_TABLE_SIZE] = {0}; |
|||
integer read_table_ps=1; |
|||
|
|||
analog function real findzeropoint_rect_x; |
|||
input x_lower_input, x_upper_input, Vx; |
|||
real x_lower_input, x_upper_input, Vx; |
|||
real iter_count; |
|||
real x_lower, x_upper; |
|||
real y_mid; |
|||
|
|||
real y_lower, x_mid; |
|||
|
|||
begin |
|||
findzeropoint_rect_x = -1; |
|||
x_lower = x_lower_input; |
|||
x_upper = x_upper_input; |
|||
iter_count = 0; |
|||
y_mid = 1; |
|||
while (iter_count<`MAX_ITER && abs(y_mid) > `TOLERANCE) begin |
|||
x_mid = (x_lower + x_upper) / 2; |
|||
y_lower = tan(x_lower / 2) - sqrt(pow(Vx,2) - pow(x_lower,2)) / x_lower; |
|||
y_mid = tan(x_mid / 2) - sqrt(pow(Vx,2) - pow(x_mid,2)) / x_mid; |
|||
|
|||
if (abs(y_mid) < `TOLERANCE) begin |
|||
findzeropoint_rect_x = x_mid; |
|||
end |
|||
|
|||
if (y_mid * y_lower < 0) |
|||
x_upper = x_mid; |
|||
else |
|||
x_lower = x_mid; |
|||
|
|||
iter_count = iter_count + 1; |
|||
end |
|||
if (findzeropoint_rect_x == -1) |
|||
$display("No zero point found in the given range. Please try again with different range."); |
|||
end |
|||
endfunction |
|||
|
|||
analog function real findzeropoint_rect_y; |
|||
input x_lower_input, x_upper_input, Vy, m; |
|||
real x_lower_input, x_upper_input, Vy, m; |
|||
real iter_count; |
|||
real x_lower, x_upper; |
|||
real y_mid; |
|||
|
|||
real y_lower, x_mid; |
|||
|
|||
begin |
|||
x_lower = x_lower_input; |
|||
x_upper = x_upper_input; |
|||
iter_count = 0; |
|||
y_mid = 1; |
|||
findzeropoint_rect_y = -1; |
|||
while (iter_count<`MAX_ITER && abs(y_mid) > `TOLERANCE) begin |
|||
x_mid = (x_lower + x_upper) / 2; |
|||
y_lower = tan(x_lower / 2 - m * `M_PI / 2) - sqrt((pow(Vy,2) - pow(x_lower,2))) / x_lower; |
|||
y_mid = tan(x_mid / 2 - m * `M_PI / 2) - sqrt((pow(Vy,2) - pow(x_mid,2))) / x_mid; |
|||
|
|||
if (abs(y_mid) < `TOLERANCE) |
|||
findzeropoint_rect_y = x_mid; |
|||
|
|||
if (y_mid * y_lower < 0) |
|||
x_upper = x_mid; |
|||
else |
|||
x_lower = x_mid; |
|||
iter_count = iter_count + 1; |
|||
end |
|||
if (findzeropoint_rect_y == -1) |
|||
$display("No zero point found in the given range. Please try again with different range."); |
|||
end |
|||
endfunction |
|||
|
|||
analog function real eim_rect; |
|||
input lam, width, thickness, n_ps, n_sub, numflag, mode_index; |
|||
real lam, width, thickness, n_ps, n_sub; |
|||
integer numflag, mode_index; |
|||
real k1, Vx, yx, hx, beta_x, neff_x_MMI, Vy, yy, hxy; |
|||
real beta_xy[0:`MAX_MODES]; |
|||
real neff_xy[0:`MAX_MODES]; |
|||
real beta_xy_out[0:`MAX_MODES]; |
|||
real neff_xy_out[0:`MAX_MODES]; |
|||
integer i, m, mode_num; |
|||
|
|||
begin |
|||
k1=2*`M_PI*n_ps/lam; |
|||
Vx=2*`M_PI/lam*thickness*sqrt((pow(n_ps,2)-pow(n_sub,2))); |
|||
yx=findzeropoint_rect_x(1e-6,min(`M_PI,Vx),Vx); |
|||
hx=yx/thickness; |
|||
beta_x=sqrt(pow(k1,2)-pow(hx,2)); |
|||
neff_x_MMI=lam*beta_x/(2*`M_PI); |
|||
Vy=2*`M_PI/lam*width*sqrt((pow(neff_x_MMI,2)-pow(n_sub,2))); |
|||
i=0; |
|||
m=0; |
|||
while (m*`M_PI<Vy) begin |
|||
yy=findzeropoint_rect_y(m*`M_PI+1e-6,min((m+1)*`M_PI-1e-6,Vy),Vy,m); |
|||
m=m+1; |
|||
// if m*`M_PI>=Vy |
|||
// break |
|||
hxy=yy/width; |
|||
beta_xy[i]=sqrt(pow(beta_x,2)-pow(hxy,2)); |
|||
neff_xy[i]=lam*beta_xy[i]/(2*`M_PI); |
|||
i=i+1; |
|||
end |
|||
mode_num=m-1; |
|||
if (numflag==1 || numflag==2) begin |
|||
for (i=0;i<mode_num;i=i+1) begin |
|||
beta_xy_out[i]=beta_xy[i]; |
|||
neff_xy_out[i]=neff_xy[i]; |
|||
end |
|||
if (numflag==1) |
|||
eim_rect=neff_xy_out[mode_index]; |
|||
else |
|||
eim_rect=beta_xy_out[mode_index]; |
|||
end |
|||
else if (numflag==3) begin |
|||
eim_rect=beta_x; |
|||
end |
|||
else if (numflag==4) begin |
|||
eim_rect=mode_num; |
|||
end |
|||
end |
|||
endfunction |
|||
|
|||
analog function real fieldfunc; |
|||
input y,width,offset,ky,gamma,m,c0; |
|||
real y,width,offset,ky,gamma,m,c0; |
|||
real fai; |
|||
|
|||
begin |
|||
fai = m * `M_PI / 2; |
|||
if (((y - offset) <= (width / 2)) && ((-width / 2) <= (y - offset))) |
|||
fieldfunc=c0 * cos(ky * (y - offset) - fai); |
|||
else if ((y - offset) > width / 2) |
|||
fieldfunc=c0 * cos(ky * width / 2 - fai) * exp(-gamma * ((y - offset) - width / 2)); |
|||
else |
|||
fieldfunc=c0 * cos(ky * width / 2 + fai) * exp(gamma * ((y - offset) + width / 2)); |
|||
end |
|||
endfunction |
|||
|
|||
analog function real normpower_fieldfunc_quad; |
|||
input width,offset,ky,gamma,m,c0,width_MMI,border; |
|||
real width,offset,ky,gamma,m,c0,width_MMI,border; |
|||
real n,h; |
|||
// real border=width_MMI/2; |
|||
integer i; |
|||
real sum; |
|||
begin |
|||
n=`IDX_NUM; |
|||
h=border*2/n; |
|||
sum=0.5*(pow(abs(fieldfunc(-1*border,width,offset,ky,gamma,m,c0)),2)+pow(abs(fieldfunc(border,width,offset,ky,gamma,m,c0)),2)); |
|||
for (i=1;i<n;i=i+1) begin |
|||
sum=sum+pow(abs(fieldfunc(-1*border+i*h,width,offset,ky,gamma,m,c0)),2); |
|||
end |
|||
normpower_fieldfunc_quad=1/sqrt(h*sum); |
|||
end |
|||
endfunction |
|||
|
|||
analog function real infidx_modecoeffcient_quad; |
|||
input width1,offset1,ky1,gamma1,m1,c01,width2,offset2,ky2,gamma2,m2,c02,border; |
|||
real width1,offset1,ky1,gamma1,m1,c01,width2,offset2,ky2,gamma2,m2,c02,border; |
|||
real n,h; |
|||
// real border=20; |
|||
integer i; |
|||
real sum; |
|||
begin |
|||
n=`IDX_NUM; |
|||
h=border*2/n; |
|||
sum=0.5*(fieldfunc(-1*border,width1,offset1,ky1,gamma1,m1,c01)* fieldfunc(-1*border,width2,offset2,ky2,gamma2,m2,c02)+fieldfunc(border,width1,offset1,ky1,gamma1,m1,c01)* fieldfunc(border,width2,offset2,ky2,gamma2,m2,c02)); |
|||
for (i=1;i<n;i=i+1) begin |
|||
sum=sum+fieldfunc(-1*border+i*h,width1,offset1,ky1,gamma1,m1,c01)* fieldfunc(-1*border+i*h,width2,offset2,ky2,gamma2,m2,c02); |
|||
end |
|||
infidx_modecoeffcient_quad=h*sum; |
|||
end |
|||
endfunction |
|||
|
|||
analog initial begin |
|||
ulam0=design_lam*1e6; |
|||
uwidth_in=width_port*1e6; |
|||
uwidth_MMI=width_MMI*1e6; |
|||
uoffset=port_offset*1e6; |
|||
uthickness=thickness*1e6; |
|||
alpha0=alpha_mmi*1e-6; |
|||
k1_ref = 2 * `M_PI * n_ps / ulam0; |
|||
kc_ref = 2 * `M_PI * n_sub / ulam0; |
|||
|
|||
mode_num_ref = eim_rect(ulam0, uwidth_MMI, uthickness, n_ps, n_sub, 4, 0); |
|||
for (i=0;i<mode_num_ref;i=i+1) begin |
|||
beta_MMI[i] = eim_rect(ulam0, uwidth_MMI, uthickness, n_ps, n_sub, 2, i); |
|||
end |
|||
length_MMI = p0*1.5*`M_PI/(beta_MMI[0]-beta_MMI[1]); //0.375Lpi? |
|||
// $display("length_MMI=%f",length_MMI); |
|||
border=20; |
|||
|
|||
pn00=pow(ni,2)/N_D; |
|||
np00=pow(ni,2)/N_A; |
|||
|
|||
eps=epsr_Si*`P_EPS0; |
|||
phi_bi=`P_K*$temperature/`P_Q*log(N_A*N_D/pow(ni,2)); |
|||
|
|||
N_avr=N_A*N_D/(N_A+N_D); |
|||
end |
|||
|
|||
analog begin |
|||
ulam = V(Ilam) * 1e6; |
|||
beta_in=eim_rect(ulam, uwidth_in, uthickness, n_ps, n_sub, 2, 0); |
|||
// $display("beta_in=%f",beta_in); |
|||
beta_x_in=eim_rect(ulam, uwidth_in, uthickness, n_ps, n_sub, 3, 0); |
|||
// $display("beta_x_in=%f",beta_x_in); |
|||
beta_x_MMI=eim_rect(ulam, uwidth_MMI, uthickness, n_ps, n_sub, 3, 0); |
|||
// $display("beta_x_MMI=%f",beta_x_MMI); |
|||
mode_num = eim_rect(ulam, uwidth_MMI, uthickness, n_ps, n_sub, 4, 0); |
|||
// $display("mode_num=%d",mode_num); |
|||
ky_in = sqrt(pow(beta_x_in,2) - pow(beta_in,2)); |
|||
// $display("ky_in=%f",ky_in); |
|||
gamma_in = sqrt(pow(beta_in,2) - pow(kc_ref,2)); |
|||
// $display("gamma_in=%f",gamma_in); |
|||
for (i=0;i<mode_num;i=i+1) begin |
|||
neff_MMI[i] = eim_rect(ulam, uwidth_MMI, uthickness, n_ps, n_sub, 1, i); |
|||
beta_MMI[i] = eim_rect(ulam, uwidth_MMI, uthickness, n_ps, n_sub, 2, i); |
|||
ky_MMI[i] = sqrt(pow(beta_x_MMI,2) - pow(beta_MMI[i],2)); |
|||
gamma_MMI[i] = sqrt(pow(beta_MMI[i],2) - pow(kc_ref,2)); |
|||
// $display("neff_MMI[%d]=%f, beta_MMI[%d]=%f, ky_MMI[%d]=%f, gamma_MMI[%d]=%f",i,neff_MMI[i],i,beta_MMI[i],i,ky_MMI[i],i,gamma_MMI[i]); |
|||
end |
|||
|
|||
c0=normpower_fieldfunc_quad(uwidth_in,0,ky_in,gamma_in,0,1,uwidth_MMI,border); |
|||
// $display("c0=%f",c0); |
|||
for (i=0;i<mode_num;i=i+1) begin |
|||
c0_dis[i]=normpower_fieldfunc_quad(uwidth_MMI,0,ky_MMI[i],gamma_MMI[i],i,1,uwidth_MMI,border); |
|||
// $display("c0_dis[%d]=%f",i,c0_dis[i]); |
|||
icoff[i]=infidx_modecoeffcient_quad(uwidth_in,uoffset,ky_in,gamma_in,0,c0,uwidth_MMI,0,ky_MMI[i],gamma_MMI[i],i,c0_dis[i],border); |
|||
// $display("icoff[%d]=%f",i,icoff[i]); |
|||
end |
|||
|
|||
delta_beta = beta_MMI[0] - beta_MMI[1]; |
|||
// $display("delta_beta=%f",delta_beta); |
|||
for (i=2;i<mode_num;i=i+1) begin |
|||
beta_MMI[i]=beta_MMI[0] - i* (i + 2) * delta_beta / 3; |
|||
// $display("beta_MMI[%d]=%f",i,beta_MMI[i]); |
|||
end |
|||
for (i=0;i<mode_num;i=i+1) begin |
|||
ocoff_r[i]=icoff[i]*cos(-beta_MMI[i]*length_MMI); |
|||
ocoff_i[i]=icoff[i]*sin(-beta_MMI[i]*length_MMI)*-1.0; |
|||
// $display("ocoff_r[%d]=%f, ocoff_i[%d]=%f",i,ocoff_r[i],i,ocoff_i[i]); |
|||
end |
|||
|
|||
h=border*2.0/`IDX_NUM; |
|||
sum_outfield1=0; |
|||
sum_outfield2=0; |
|||
sum_outfield3=0; |
|||
sum_outfield4=0; |
|||
for (j=0;j<mode_num;j=j+1) begin |
|||
sum_singlemode1=0.5*(ocoff_r[j]*fieldfunc(-1*border,uwidth_MMI,0,ky_MMI[j],gamma_MMI[j],j,c0_dis[j])*fieldfunc(-1*border,uwidth_in,uoffset,ky_in,gamma_in,0,c0)+ocoff_r[j]*fieldfunc(border,uwidth_MMI,0,ky_MMI[j],gamma_MMI[j],j,c0_dis[j])*fieldfunc(border,uwidth_in,uoffset,ky_in,gamma_in,0,c0)); |
|||
sum_singlemode2=0.5*(ocoff_i[j]*fieldfunc(-1*border,uwidth_MMI,0,ky_MMI[j],gamma_MMI[j],j,c0_dis[j])*fieldfunc(-1*border,uwidth_in,uoffset,ky_in,gamma_in,0,c0)+ocoff_i[j]*fieldfunc(border,uwidth_MMI,0,ky_MMI[j],gamma_MMI[j],j,c0_dis[j])*fieldfunc(border,uwidth_in,uoffset,ky_in,gamma_in,0,c0)); |
|||
sum_singlemode3=0.5*(ocoff_r[j]*fieldfunc(-1*border,uwidth_MMI,0,ky_MMI[j],gamma_MMI[j],j,c0_dis[j])*fieldfunc(-1*border,uwidth_in,-uoffset,ky_in,gamma_in,0,c0)+ocoff_r[j]*fieldfunc(border,uwidth_MMI,0,ky_MMI[j],gamma_MMI[j],j,c0_dis[j])*fieldfunc(border,uwidth_in,-uoffset,ky_in,gamma_in,0,c0)); |
|||
sum_singlemode4=0.5*(ocoff_i[j]*fieldfunc(-1*border,uwidth_MMI,0,ky_MMI[j],gamma_MMI[j],j,c0_dis[j])*fieldfunc(-1*border,uwidth_in,-uoffset,ky_in,gamma_in,0,c0)+ocoff_i[j]*fieldfunc(border,uwidth_MMI,0,ky_MMI[j],gamma_MMI[j],j,c0_dis[j])*fieldfunc(border,uwidth_in,-uoffset,ky_in,gamma_in,0,c0)); |
|||
for (i=1;i<`IDX_NUM;i=i+1) begin |
|||
sum_singlemode1=sum_singlemode1+ocoff_r[j]*fieldfunc(-1*border+i*h,uwidth_MMI,0,ky_MMI[j],gamma_MMI[j],j,c0_dis[j])*fieldfunc(-1*border+i*h,uwidth_in,uoffset,ky_in,gamma_in,0,c0); |
|||
sum_singlemode2=sum_singlemode2+ocoff_i[j]*fieldfunc(-1*border+i*h,uwidth_MMI,0,ky_MMI[j],gamma_MMI[j],j,c0_dis[j])*fieldfunc(-1*border+i*h,uwidth_in,uoffset,ky_in,gamma_in,0,c0); |
|||
sum_singlemode3=sum_singlemode3+ocoff_r[j]*fieldfunc(-1*border+i*h,uwidth_MMI,0,ky_MMI[j],gamma_MMI[j],j,c0_dis[j])*fieldfunc(-1*border+i*h,uwidth_in,-uoffset,ky_in,gamma_in,0,c0); |
|||
sum_singlemode4=sum_singlemode4+ocoff_i[j]*fieldfunc(-1*border+i*h,uwidth_MMI,0,ky_MMI[j],gamma_MMI[j],j,c0_dis[j])*fieldfunc(-1*border+i*h,uwidth_in,-uoffset,ky_in,gamma_in,0,c0); |
|||
end |
|||
sum_outfield1=sum_outfield1+h*sum_singlemode1; |
|||
sum_outfield2=sum_outfield2+h*sum_singlemode2; |
|||
sum_outfield3=sum_outfield3+h*sum_singlemode3; |
|||
sum_outfield4=sum_outfield4+h*sum_singlemode4; |
|||
end |
|||
c1r=sum_outfield1*exp(-alpha0*length_MMI); |
|||
c1i=sum_outfield2*exp(-alpha0*length_MMI); |
|||
c2r=sum_outfield3*exp(-alpha0*length_MMI); |
|||
c2i=sum_outfield4*exp(-alpha0*length_MMI); |
|||
|
|||
// $display("c1r=%f, c1i=%f, c2r=%f, c2i=%f",c1r,c1i,c2r,c2i); |
|||
|
|||
lam=V(Ilam); |
|||
gd=(-Is*(exp(5)-1)+IBV)/(-5*emi*Vt + BV); |
|||
Id=Is*(exp(V(Nint)/(emi*Vt))-1)+V(Nint)*gd; |
|||
if (V(Nint) >= V0) |
|||
Cj=0; |
|||
else |
|||
Cj=Cj0/sqrt(1-V(Nint)/V0); |
|||
//Cd=Id*tau/(emi*Vt); |
|||
Cd=Is*(exp(V(Nint)/(emi*Vt))-1)*tau/(emi*Vt); |
|||
|
|||
I(Iint) <+ V(Vbias)/Rs; |
|||
I(CCj) <+ Cj*ddt(V(CCj)); |
|||
I(CCd) <+ Cd*ddt(V(CCd)); |
|||
I(Idd) <+ Id; |
|||
V(RRs) <+ I(RRs)*Rs; |
|||
|
|||
phi=phi_bi-V(Nint); |
|||
// $display("V(Nint)=%e",V(Nint)); |
|||
if (phi<0) |
|||
phi=0; |
|||
|
|||
// $display("phi=%e",phi); |
|||
W=alpha_wd * sqrt(2.0*eps*phi/(`P_Q*N_avr)); |
|||
Wdp=N_D * W/(N_A+N_D); |
|||
Wdn=N_A * W/(N_A+N_D); |
|||
|
|||
for (i=0; i<xnum; i=i+1) begin |
|||
x[i]=i*xlength/(xnum-1); |
|||
np[i]=np00*(exp(`P_Q*V(Nint)/(`P_K*$temperature))-1)*exp(-(x[i]-Wdp)/Ln)+np00; |
|||
if (x[i]>Wdp) begin |
|||
pp[i]=N_A; |
|||
end |
|||
else begin |
|||
pp[i]=0; |
|||
end |
|||
pn[i]=pn00*(exp(`P_Q*V(Nint)/(`P_K*$temperature))-1)*exp(-(x[i]-Wdn)/Lp)+pn00; |
|||
if (x[i]>Wdn) begin |
|||
nn[i]=N_D; |
|||
end |
|||
else begin |
|||
nn[i]=0; |
|||
end |
|||
if (np[i]<0) np[i]=0; |
|||
if (pn[i]<0) pn[i]=0; |
|||
end |
|||
|
|||
for (i=0; i<2*xnum; i=i+1) begin |
|||
if (i<xnum) begin |
|||
xx[i]=-x[xnum-1-i]; |
|||
n[i]=np[xnum-1-i]; |
|||
p[i]=pp[xnum-1-i]; |
|||
end |
|||
else begin |
|||
xx[i]=x[i-xnum]; |
|||
n[i]=nn[i-xnum]; |
|||
p[i]=pn[i-xnum]; |
|||
end |
|||
if (abs(xx[i]+rib_width/2) < 0.001u) begin |
|||
wi=i; |
|||
end |
|||
if (abs(xx[i]-rib_width/2) < 0.001u) begin |
|||
wf=i; |
|||
end |
|||
dalpha_e[i]=n[i]*sigma_ae*1e-4; |
|||
dalpha_h[i]=p[i]*sigma_ah*1e-4; |
|||
dalpha[i]=dalpha_e[i] + dalpha_h[i]; |
|||
end |
|||
|
|||
sum_dalpha=0; |
|||
for (i=wi; i<=wf; i=i+1) begin |
|||
sum_dalpha=sum_dalpha+dalpha[i]; |
|||
end |
|||
dalpha_avr=sum_dalpha/(wf-wi+1.0); |
|||
alpha_phaseshift = alpha_phaseshift_ref + dalpha_avr; |
|||
|
|||
if (read_table_ps==0 || lam_old==0 || width_old==0) begin |
|||
read_table_ps=1; |
|||
end |
|||
|
|||
if (read_table_ps == 1) begin |
|||
ps_file=$fopen(neff_ps_filename,"r"); |
|||
if (ps_file==0) begin |
|||
$display("Error: cannot open ps_file %s",neff_ps_filename); |
|||
$finish; |
|||
end |
|||
$fscanf(ps_file,"%f",width_start); |
|||
$fscanf(ps_file,"%f",width_end); |
|||
$fscanf(ps_file,"%d",width_num); |
|||
width_step = (width_end-width_start)/(width_num-1); |
|||
// $display("width_start=%f, width_end=%f, width_num=%f, width_step=%f",width_start,width_end,width_num,width_step); |
|||
$fscanf(ps_file,"%f",lam_start); |
|||
$fscanf(ps_file,"%f",lam_end); |
|||
$fscanf(ps_file,"%d",lam_num); |
|||
lam_step = (lam_end-lam_start)/(lam_num-1); |
|||
// for (i=0; i<width_num; i=i+1) begin |
|||
// $fscanf(ps_file,"%f",tmp); |
|||
// end |
|||
for (i=0; i<width_num; i=i+1) begin |
|||
for (j=0; j<lam_num; j=j+1) begin |
|||
$fscanf(ps_file,"%f",tmp); |
|||
// $display("%f",tmp); |
|||
neff_widthtable_ps[i*lam_num+j] = width_start+i*width_step; |
|||
neff_lamtable_ps[i*lam_num+j] = lam_start+j*lam_step; |
|||
neff_table_ps[i*lam_num+j] = tmp; |
|||
//$display("neff_widthtable_ps[%d]=%f, neff_lamtable_ps[%d]=%f, neff_table_ps[%d]=%f",i*lam_num+j,neff_widthtable_ps[i*lam_num+j],i*lam_num+j,neff_lamtable_ps[i*lam_num+j],i*lam_num+j,neff_table_ps[i*lam_num+j]); |
|||
end |
|||
end |
|||
$fclose(ps_file); |
|||
neff_widthtable_ps[width_num*lam_num+1] = 0; |
|||
neff_lamtable_ps[width_num*lam_num+1] = 0; |
|||
neff_table_ps[width_num*lam_num+1] = 0; |
|||
neff_widthtable_ps[width_num*lam_num+2] = 0; |
|||
neff_lamtable_ps[width_num*lam_num+2] = -1; |
|||
neff_table_ps[width_num*lam_num+2] = 0; |
|||
read_table_ps=2; |
|||
end |
|||
|
|||
if (read_table_ps == 2) begin |
|||
if (lam*1e6<lam_start || lam*1e6>lam_end) begin |
|||
$display("Warning: lam=%f is out of range [%f,%f]",lam*1e6,lam_start,lam_end); |
|||
end |
|||
if (Wdp*1e6<width_start || Wdp*1e6>width_end) begin |
|||
$display("Warning: Wdp=%f is out of range [%f,%f]",Wdp*1e6,width_start,width_end); |
|||
end |
|||
neff_phaseshift = $table_model(Wdp*1e6, lam*1e6, neff_widthtable_ps, neff_lamtable_ps, neff_table_ps); |
|||
// $display("neff=%f",neff_phaseshift); |
|||
end |
|||
|
|||
beta_ps = 2.0*`M_PI*neff_phaseshift/lam; |
|||
|
|||
k_ps_r=-alpha_phaseshift*alpha_absorp; |
|||
k_ps_i=beta_ps; |
|||
|
|||
p_ps_r=exp(k_ps_r*l_ps)*cos(k_ps_i*l_ps); |
|||
p_ps_i=exp(k_ps_r*l_ps)*sin(k_ps_i*l_ps); |
|||
|
|||
p_wg_r=exp((k_ps_r+alpha_waveguide-alpha_phaseshift_ref)*(l_ps+l_arm))*cos((k_ps_i)*(l_ps+l_arm)); |
|||
p_wg_i=exp((k_ps_r+alpha_waveguide-alpha_phaseshift_ref)*(l_ps+l_arm))*sin((k_ps_i)*(l_ps+l_arm)); |
|||
// $display("p_ps_r=%g, p_ps_i=%g, p_wg_r=%g, p_wg_i=%g",p_ps_r,p_ps_i,p_wg_r,p_wg_i); |
|||
ar_tr11_r=p_ps_r; |
|||
ar_tr11_i=p_ps_i; |
|||
ar_tr12_r=0; |
|||
ar_tr12_i=0; |
|||
ar_tr21_r=0; |
|||
ar_tr21_i=0; |
|||
ar_tr22_r=p_wg_r; |
|||
ar_tr22_i=p_wg_i; |
|||
// $display("p_ps_r=%f, p_ps_i=%f, p_wg_r=%f, p_wg_i=%f",p_ps_r,p_ps_i,p_wg_r,p_wg_i); |
|||
|
|||
t1_11_r=c1r*ar_tr11_r-c1i*ar_tr11_i+c2r*ar_tr21_r-c2i*ar_tr21_i; |
|||
t1_11_i=c1r*ar_tr11_i+c1i*ar_tr11_r+c2r*ar_tr21_i+c2i*ar_tr21_r; |
|||
t1_12_r=c1r*ar_tr12_r-c1i*ar_tr12_i+c2r*ar_tr22_r-c2i*ar_tr22_i; |
|||
t1_12_i=c1r*ar_tr12_i+c1i*ar_tr12_r+c2r*ar_tr22_i+c2i*ar_tr22_r; |
|||
t1_21_r=c2r*ar_tr11_r-c2i*ar_tr11_i-c1r*ar_tr21_r+c1i*ar_tr21_i; |
|||
t1_21_i=c2r*ar_tr11_i+c2i*ar_tr11_r-c1r*ar_tr21_i-c1i*ar_tr21_r; |
|||
t1_22_r=c2r*ar_tr12_r-c2i*ar_tr12_i-c1r*ar_tr22_r+c1i*ar_tr22_i; |
|||
t1_22_i=c2r*ar_tr12_i+c2i*ar_tr12_r-c1r*ar_tr22_i-c1i*ar_tr22_r; |
|||
|
|||
t2_11_r=t1_11_r*c1r-t1_11_i*c1i+t1_12_r*c2r-t1_12_i*c2i; |
|||
t2_11_i=t1_11_r*c1i+t1_11_i*c1r+t1_12_r*c2i+t1_12_i*c2r; |
|||
t2_12_r=t1_11_r*c2r-t1_11_i*c2i+t1_12_r*c1r-t1_12_i*c1i; |
|||
t2_12_i=t1_11_r*c2i+t1_11_i*c2r+t1_12_r*c1i+t1_12_i*c1r; |
|||
t2_21_r=t1_21_r*c1r-t1_21_i*c1i+t1_22_r*c2r-t1_22_i*c2i; |
|||
t2_21_i=t1_21_r*c1i+t1_21_i*c1r+t1_22_r*c2i+t1_22_i*c2r; |
|||
t2_22_r=t1_21_r*c2r-t1_21_i*c2i+t1_22_r*c1r-t1_22_i*c1i; |
|||
t2_22_i=t1_21_r*c2i+t1_21_i*c2r+t1_22_r*c1i+t1_22_i*c1r; |
|||
// $display("t2_11_r=%f, t2_11_i=%f, t2_12_r=%f, t2_12_i=%f, t2_21_r=%f, t2_21_i=%f, t2_22_r=%f, t2_22_i=%f",t2_11_r,t2_11_i,t2_12_r,t2_12_i,t2_21_r,t2_21_i,t2_22_r,t2_22_i); |
|||
|
|||
inr=sqrt(V(Ipow))*cos(V(Iphase)/360.0*2*`M_PI); |
|||
ini=sqrt(V(Ipow))*sin(V(Iphase)/360.0*2*`M_PI); |
|||
out1r=t2_11_r*inr-t2_11_i*ini; |
|||
out1i=t2_11_r*ini+t2_11_i*inr; |
|||
out2r=t2_21_r*inr-t2_21_i*ini; |
|||
out2i=t2_21_r*ini+t2_21_i*inr; |
|||
|
|||
V(Olam) <+ lam; |
|||
V(Opow) <+ pow(out1r,2)+pow(out1i,2); |
|||
V(Ophase) <+ atan2(out1i,out1r)*360.0/(2*`M_PI); |
|||
end |
|||
endmodule |
@ -0,0 +1,29 @@ |
|||
//VerilogA for passive,chifilterbasic,veriloga |
|||
|
|||
`include "constants.vams" |
|||
`include "disciplines.vams" |
|||
|
|||
module chifilterbasic(Ipow,Iphase,Ilam,Opow,Ophase,Olam); |
|||
parameter real centerfreq = 1G; |
|||
parameter real bandwidth = 0 from [0:inf); |
|||
parameter real loss = 0 from [0:1]; |
|||
|
|||
input Ipow,Iphase,Ilam; |
|||
output Opow,Ophase,Olam; |
|||
electrical Ipow,Iphase,Ilam,Opow,Ophase,Olam; |
|||
|
|||
real opow,freq; |
|||
|
|||
analog begin |
|||
freq=`P_C/V(Ilam); |
|||
if (freq < centerfreq+bandwidth/2 && freq > centerfreq-bandwidth/2) begin |
|||
opow = V(Ipow); |
|||
end |
|||
else begin |
|||
opow = V(Ipow)*loss; |
|||
end |
|||
V(Opow) <+ opow; |
|||
V(Ophase) <+ V(Iphase); |
|||
V(Olam) <+ V(Ilam); |
|||
end |
|||
endmodule |
@ -0,0 +1,27 @@ |
|||
//VerilogA for passive,chifiltergauss,veriloga |
|||
|
|||
`include "constants.vams" |
|||
`include "disciplines.vams" |
|||
|
|||
module chifiltergauss(Ipow,Iphase,Ilam,Opow,Ophase,Olam); |
|||
parameter real centerfreq = 1G; |
|||
parameter real sigma = 1 from (0:inf); |
|||
parameter integer resize = 0 from [0:1]; |
|||
|
|||
input Ipow,Iphase,Ilam; |
|||
output Opow,Ophase,Olam; |
|||
electrical Ipow,Iphase,Ilam,Opow,Ophase,Olam; |
|||
|
|||
real opow,freq; |
|||
|
|||
analog begin |
|||
freq=`P_C/V(Ilam); |
|||
if (resize == 1) |
|||
opow=V(Ipow)/(sigma*sqrt(2*`M_PI))*exp(-1*pow(freq-centerfreq,2)/(2*pow(sigma,2))); |
|||
else |
|||
opow=V(Ipow)*exp(-1*pow(freq-centerfreq,2)/(2*pow(sigma,2))); |
|||
V(Opow) <+ opow; |
|||
V(Ophase) <+ V(Iphase); |
|||
V(Olam) <+ V(Ilam); |
|||
end |
|||
endmodule |
@ -0,0 +1,21 @@ |
|||
//VerilogA for passive,gainbasic,veriloga |
|||
`include "constants.vams" |
|||
`include "disciplines.vams" |
|||
|
|||
module gainbasic(Ipow,Iphase,Ilam,Opow,Ophase,Olam); |
|||
parameter real G = 1 from [0:inf); |
|||
// parameter real phaseshift=0; |
|||
// parameter real noisefigure=0; |
|||
|
|||
input Ipow,Iphase,Ilam; |
|||
output Opow,Ophase,Olam; |
|||
electrical Ipow,Iphase,Ilam,Opow,Ophase,Olam; |
|||
|
|||
// real S; |
|||
analog begin |
|||
// S=(G*pow(10,noisefigure/10)-1)*`P_C*`P_H/V(Ilam); |
|||
V(Opow) <+ G*V(Ipow); |
|||
V(Ophase) <+ V(Iphase);//+phaseshift; |
|||
V(Olam) <+ V(Ilam); |
|||
end |
|||
endmodule |
@ -0,0 +1,31 @@ |
|||
//VerilogA for passive,jointer2,veriloga |
|||
`include "constants.vams" |
|||
`include "disciplines.vams" |
|||
|
|||
module jointer2(Ipow1,Iphase1,Ilam1,Ipow2,Iphase2,Ilam2,Opow,Ophase,Olam); |
|||
parameter real n1 = 0.5 from [0:1]; |
|||
parameter real n2 = 0.5 from [0:1]; |
|||
|
|||
input Ipow1,Iphase1,Ilam1,Ipow2,Iphase2,Ilam2; |
|||
output Opow,Ophase,Olam; |
|||
electrical Ipow1,Iphase1,Ilam1,Ipow2,Iphase2,Ilam2,Opow,Ophase,Olam; |
|||
|
|||
real r1,i1,r2,i2,ro,io; |
|||
real iph1,iph2,oph; |
|||
|
|||
analog begin |
|||
iph1=V(Iphase1)/360.0*2*`M_PI; |
|||
iph2=V(Iphase2)/360.0*2*`M_PI; |
|||
r1=sqrt(n1*V(Ipow1))*cos(iph1); |
|||
i1=sqrt(n1*V(Ipow1))*sin(iph1); |
|||
r2=sqrt(n2*V(Ipow2))*cos(iph2); |
|||
i2=sqrt(n2*V(Ipow2))*sin(iph2); |
|||
ro=r1+r2; |
|||
io=i1+i2; |
|||
oph=atan2(io,ro)/(2*`M_PI)*360.0; |
|||
V(Opow) <+ pow(ro,2)+pow(io,2); |
|||
V(Ophase) <+ oph; |
|||
//Only same lambda can have correct outcom! |
|||
V(Olam) <+ (V(Ilam1)+V(Ilam2))/2; |
|||
end |
|||
endmodule |
@ -0,0 +1,35 @@ |
|||
//VerilogA for passive,jointer3,veriloga |
|||
`include "constants.vams" |
|||
`include "disciplines.vams" |
|||
|
|||
module jointer3(Ipow1,Iphase1,Ilam1,Ipow2,Iphase2,Ilam2,Ipow3,Iphase3,Ilam3,Opow,Ophase,Olam); |
|||
parameter real n1 = 0.3333 from [0:1]; |
|||
parameter real n2 = 0.3333 from [0:1]; |
|||
parameter real n3 = 0.3333 from [0:1]; |
|||
|
|||
input Ipow1,Iphase1,Ilam1,Ipow2,Iphase2,Ilam2,Ipow3,Iphase3,Ilam3; |
|||
output Opow,Ophase,Olam; |
|||
electrical Ipow1,Iphase1,Ilam1,Ipow2,Iphase2,Ilam2,Ipow3,Iphase3,Ilam3,Opow,Ophase,Olam; |
|||
|
|||
real r1,i1,r2,i2,r3,i3,ro,io; |
|||
real iph1,iph2,iph3,oph; |
|||
|
|||
analog begin |
|||
iph1=V(Iphase1)/360.0*2*`M_PI; |
|||
iph2=V(Iphase2)/360.0*2*`M_PI; |
|||
iph3=V(Iphase3)/360.0*2*`M_PI; |
|||
r1=sqrt(n1*V(Ipow1))*cos(iph1); |
|||
i1=sqrt(n1*V(Ipow1))*sin(iph1); |
|||
r2=sqrt(n2*V(Ipow2))*cos(iph2); |
|||
i2=sqrt(n2*V(Ipow2))*sin(iph2); |
|||
r3=sqrt(n3*V(Ipow3))*cos(iph3); |
|||
i3=sqrt(n3*V(Ipow3))*sin(iph3); |
|||
ro=r1+r2+r3; |
|||
io=i1+i2+i3; |
|||
oph=atan2(io,ro)/(2*`M_PI)*360.0; |
|||
|
|||
V(Ophase) <+ oph; |
|||
V(Opow) <+ pow(ro,2)+pow(io,2); |
|||
V(Olam) <+ (V(Ilam1)+V(Ilam2)+V(Ilam3))/3; |
|||
end |
|||
endmodule |
@ -0,0 +1,134 @@ |
|||
//VerilogA for passive,jointerbasic,veriloga |
|||
|
|||
`include "constants.vams" |
|||
`include "disciplines.vams" |
|||
|
|||
module jointerbasic(Ipow1,Iphase1,Ilam1,Ipow2,Iphase2,Ilam2,Opow,Ophase,Olam); |
|||
parameter integer modespec = 1 from [1:2]; |
|||
parameter integer alpha_use_dBm = 1 from [0:1]; |
|||
parameter real reffreq = 193.1e12 from (0:inf); |
|||
parameter real l_str = 500e-6 from [0:inf); |
|||
parameter real l_up = 500e-6 from [0:inf); |
|||
parameter real l_down = 500e-6 from [0:inf); |
|||
parameter real neff_te = 2.6 from (0:inf); |
|||
parameter real neff_tm = 2.6 from (0:inf); |
|||
parameter real n_gv_te = 4.2 from (0:inf); |
|||
parameter real n_gv_tm = 4.2 from (0:inf); |
|||
parameter real disper_te = 0; |
|||
parameter real disper_tm = 0; |
|||
parameter real attenu_te = 0 from [0:inf);//attenuation in dB/m |
|||
parameter real attenu_tm = 0 from [0:inf);//attenuation in dB/m |
|||
parameter real design_freq = 193.1e12 from (0:inf); |
|||
parameter real s0_te = 0.5 from [0:1]; |
|||
parameter real s0_tm = 0.5 from [0:1]; |
|||
parameter real dfreq_te = 100e12 from [0:inf); |
|||
parameter real dfreq_tm = 100e12 from [0:inf); |
|||
parameter real ds_te = 0; |
|||
parameter real ds_tm = 0; |
|||
parameter real scat_loss_te = 0 from [0:inf); |
|||
parameter real scat_loss_tm = 0 from [0:inf); |
|||
|
|||
input Ipow1,Iphase1,Ilam1,Ipow2,Iphase2,Ilam2; |
|||
output Opow,Ophase,Olam; |
|||
electrical Ipow1,Iphase1,Ilam1,Ipow2,Iphase2,Ilam2,Opow,Ophase,Olam; |
|||
|
|||
real freq,iph1,iph2; |
|||
real eeir1,eeii1,emir1,emii1,eeir2,eeii2,emir2,emii2; |
|||
real alpha_te,alpha_tm; |
|||
real beta_ter,beta_tei,beta_tmr,beta_tmi; |
|||
real s_te,s_tm; |
|||
real t11r,t11i,t12r,t12i,t21r,t21i,t22r,t22i,t13r,t13i,t14r,t14i,t23r,t23i,t24r,t24i; |
|||
real oer,oei,omr,omi; |
|||
|
|||
analog begin |
|||
freq=`P_C/V(Ilam1); |
|||
iph1=V(Iphase1)/360.0*2*`M_PI; |
|||
iph2=V(Iphase2)/360.0*2*`M_PI; |
|||
if (modespec == 1) begin |
|||
eeir1=sqrt(V(Ipow1))*cos(iph1); |
|||
eeii1=sqrt(V(Ipow1))*sin(iph1); |
|||
emir1=0; |
|||
emii1=0; |
|||
eeir2=sqrt(V(Ipow2))*cos(iph2); |
|||
eeii2=sqrt(V(Ipow2))*sin(iph2); |
|||
emir2=0; |
|||
emii2=0; |
|||
end |
|||
else if (modespec == 2) begin |
|||
eeir1=0; |
|||
eeii1=0; |
|||
emir1=sqrt(V(Ipow1))*cos(iph1); |
|||
emii1=sqrt(V(Ipow1))*sin(iph1); |
|||
eeir2=0; |
|||
eeii2=0; |
|||
emir2=sqrt(V(Ipow2))*cos(iph2); |
|||
emii2=sqrt(V(Ipow2))*sin(iph2); |
|||
end |
|||
|
|||
if (alpha_use_dBm == 1) begin |
|||
alpha_te=0.1*ln(10)*attenu_te; |
|||
alpha_tm=0.1*ln(10)*attenu_tm; |
|||
end |
|||
else begin |
|||
alpha_te=attenu_te; |
|||
alpha_tm=attenu_tm; |
|||
end |
|||
|
|||
beta_ter=2*`M_PI*reffreq/`P_C*neff_te+2*`M_PI/`P_C*n_gv_te*(freq-reffreq)-`M_PI*`P_C*disper_te/pow(reffreq,2)*pow(freq-reffreq,2); |
|||
beta_tei=-alpha_te/2; |
|||
beta_tmr=2*`M_PI*reffreq/`P_C*neff_tm+2*`M_PI/`P_C*n_gv_tm*(freq-reffreq)-`M_PI*`P_C*disper_tm/pow(reffreq,2)*pow(freq-reffreq,2); |
|||
beta_tmi=-alpha_tm/2; |
|||
|
|||
if (freq < design_freq-dfreq_te/2) begin |
|||
s_te=s0_te-dfreq_te/2.0*ds_te; |
|||
end |
|||
else if (freq > design_freq+dfreq_te/2) begin |
|||
s_te=s0_te+dfreq_te/2.0*ds_te; |
|||
end |
|||
else begin |
|||
s_te=s0_te+(freq-design_freq)*ds_te; |
|||
end |
|||
if (freq < design_freq-dfreq_tm/2) begin |
|||
s_tm=s0_tm-dfreq_tm/2.0*ds_tm; |
|||
end |
|||
else if (freq > design_freq+dfreq_tm/2) begin |
|||
s_tm=s0_tm+dfreq_tm/2.0*ds_tm; |
|||
end |
|||
else begin |
|||
s_tm=s0_tm+(freq-design_freq)*ds_tm; |
|||
end |
|||
|
|||
t11r=pow(10,-scat_loss_te/10)*sqrt(s_te)*exp(-beta_tei*(l_str+l_up))*cos(-beta_ter*(l_str+l_up)); |
|||
t11i=pow(10,-scat_loss_te/10)*sqrt(s_te)*exp(-beta_tei*(l_str+l_up))*sin(-beta_ter*(l_str+l_up)); |
|||
t12r=0; |
|||
t12i=0; |
|||
t21r=0; |
|||
t21i=0; |
|||
t22r=pow(10,-scat_loss_tm/10)*sqrt(s_tm)*exp(-beta_tmi*(l_str+l_up))*cos(-beta_tmr*(l_str+l_up)); |
|||
t22i=pow(10,-scat_loss_tm/10)*sqrt(s_tm)*exp(-beta_tmi*(l_str+l_up))*sin(-beta_tmr*(l_str+l_up)); |
|||
t13r=pow(10,-scat_loss_te/10)*sqrt(1-s_te)*exp(-beta_tei*(l_str+l_down))*cos(-beta_ter*(l_str+l_down)); |
|||
t13i=pow(10,-scat_loss_te/10)*sqrt(1-s_te)*exp(-beta_tei*(l_str+l_down))*sin(-beta_ter*(l_str+l_down)); |
|||
t14r=0; |
|||
t14i=0; |
|||
t23r=0; |
|||
t23i=0; |
|||
t24r=pow(10,-scat_loss_tm/10)*sqrt(1-s_tm)*exp(-beta_tmi*(l_str+l_down))*cos(-beta_tmr*(l_str+l_down)); |
|||
t24i=pow(10,-scat_loss_tm/10)*sqrt(1-s_tm)*exp(-beta_tmi*(l_str+l_down))*sin(-beta_tmr*(l_str+l_down)); |
|||
|
|||
oer=t11r*eeir1+t12r*emir1+t13r*eeir2+t14r*emir2-t11i*eeii1-t12i*emii1-t13i*eeii2-t14i*emii2; |
|||
oei=t11r*eeii1+t12r*emii1+t13r*eeii2+t14r*emii2+t11i*eeir1+t12i*emir1+t13i*eeir2+t14i*emir2; |
|||
omr=t21r*eeir1+t22r*emir1+t23r*eeir2+t24r*emir2-t21i*eeii1-t22i*emii1-t23i*eeii2-t24i*emii2; |
|||
omi=t21r*eeii1+t22r*emii1+t23r*eeii2+t24r*emii2+t21i*eeir1+t22i*emir1+t23i*eeir2+t24i*emir2; |
|||
|
|||
V(Olam) <+ V(Ilam1); |
|||
if (modespec == 1) begin |
|||
V(Opow) <+ pow(oer,2)+pow(oei,2); |
|||
V(Ophase) <+ atan2(oei,oer)*360.0/(2*`M_PI); |
|||
end |
|||
else if (modespec == 2) begin |
|||
V(Opow) <+ pow(omr,2)+pow(omi,2); |
|||
V(Ophase) <+ atan2(omi,omr)*360.0/(2*`M_PI); |
|||
end |
|||
end |
|||
|
|||
endmodule |
@ -0,0 +1,329 @@ |
|||
//VerilogA for passive,mmi1x2,veriloga |
|||
//Xuanqi Chen, Zhifei Wang, Yi-Shing Chang, Jiang Xu, Jun Feng, Peng Yang, Zhehui Wang, Luan H. K. Duong, ”Modeling and Analysis of Optical Modulators Based on Free-Carrier Plasma Dispersion Effect,” IEEE Transactions on Computer-Aided Design of Integrated Circuits and Systems (TCAD), vol. 39, no. 5, pp. 977-990, May 2020. |
|||
|
|||
`include "constants.vams" |
|||
`include "disciplines.vams" |
|||
|
|||
`define MAX_MODES 200 |
|||
`define MAX_ITER 10000 |
|||
`define IDX_NUM 50000 |
|||
`define TOLERANCE 0.0000000001 |
|||
|
|||
module mmi1x2(Ipow,Iphase,Ilam,Opow1,Ophase1,Olam1,Opow2,Ophase2,Olam2); |
|||
parameter real design_lam = 1.55e-6 from (0:inf); |
|||
parameter real n_ps = 3.45 from (0:inf); |
|||
parameter real n_sub = 1.45 from (0:inf); |
|||
parameter real width_MMI = 3e-6 from (0:inf); |
|||
parameter real width_port = 0.45e-6 from (0:inf); |
|||
parameter real port_offset = 0.75e-6 from (0:inf); |
|||
parameter real thickness = 0.22e-6 from (0:inf); |
|||
parameter real alpha_mmi = 80 from (0:inf); |
|||
|
|||
input Ipow,Iphase,Ilam; |
|||
output Opow1,Ophase1,Olam1,Opow2,Ophase2,Olam2; |
|||
electrical Ipow,Iphase,Ilam,Opow1,Ophase1,Olam1,Opow2,Ophase2,Olam2; |
|||
|
|||
real ulam, ulam0, uwidth_in, uwidth_MMI, uoffset, uthickness, alpha0; |
|||
real k1_ref, kc_ref; |
|||
integer mode_num, mode_num_ref; |
|||
real beta_x_MMI, beta_in, beta_x_in; |
|||
real neff_MMI[0:`MAX_MODES]; |
|||
real beta_MMI[0:`MAX_MODES]; |
|||
real length_MMI; |
|||
real ky_in, gamma_in; |
|||
real ky_MMI[0:`MAX_MODES]; |
|||
real gamma_MMI[0:`MAX_MODES]; |
|||
real c0; |
|||
real c0_dis[0:`MAX_MODES]; |
|||
real icoff[0:`MAX_MODES]; |
|||
real delta_beta; |
|||
real ocoff_r[0:`MAX_MODES]; |
|||
real ocoff_i[0:`MAX_MODES]; |
|||
real c1r, c1i, c2r, c2i; |
|||
real inr, ini, out1r, out1i, out2r, out2i; |
|||
real sum_outfield1, sum_outfield2, sum_outfield3, sum_outfield4; |
|||
real sum_singlemode1,sum_singlemode2,sum_singlemode3,sum_singlemode4; |
|||
|
|||
real border; |
|||
|
|||
integer i, j; |
|||
real p=1; |
|||
real h; |
|||
|
|||
analog function real findzeropoint_rect_x; |
|||
input x_lower_input, x_upper_input, Vx; |
|||
real x_lower_input, x_upper_input, Vx; |
|||
real iter_count; |
|||
real x_lower, x_upper; |
|||
real y_mid; |
|||
|
|||
real y_lower, x_mid; |
|||
|
|||
begin |
|||
findzeropoint_rect_x = -1; |
|||
x_lower = x_lower_input; |
|||
x_upper = x_upper_input; |
|||
iter_count = 0; |
|||
y_mid = 1; |
|||
while (iter_count<`MAX_ITER && abs(y_mid) > `TOLERANCE) begin |
|||
x_mid = (x_lower + x_upper) / 2; |
|||
y_lower = tan(x_lower / 2) - sqrt(pow(Vx,2) - pow(x_lower,2)) / x_lower; |
|||
y_mid = tan(x_mid / 2) - sqrt(pow(Vx,2) - pow(x_mid,2)) / x_mid; |
|||
|
|||
if (abs(y_mid) < `TOLERANCE) begin |
|||
findzeropoint_rect_x = x_mid; |
|||
end |
|||
|
|||
if (y_mid * y_lower < 0) |
|||
x_upper = x_mid; |
|||
else |
|||
x_lower = x_mid; |
|||
|
|||
iter_count = iter_count + 1; |
|||
end |
|||
if (findzeropoint_rect_x == -1) |
|||
$display("No zero point found in the given range. Please try again with different range."); |
|||
end |
|||
endfunction |
|||
|
|||
analog function real findzeropoint_rect_y; |
|||
input x_lower_input, x_upper_input, Vy, m; |
|||
real x_lower_input, x_upper_input, Vy, m; |
|||
real iter_count; |
|||
real x_lower, x_upper; |
|||
real y_mid; |
|||
|
|||
real y_lower, x_mid; |
|||
|
|||
begin |
|||
x_lower = x_lower_input; |
|||
x_upper = x_upper_input; |
|||
iter_count = 0; |
|||
y_mid = 1; |
|||
findzeropoint_rect_y = -1; |
|||
while (iter_count<`MAX_ITER && abs(y_mid) > `TOLERANCE) begin |
|||
x_mid = (x_lower + x_upper) / 2; |
|||
y_lower = tan(x_lower / 2 - m * `M_PI / 2) - sqrt((pow(Vy,2) - pow(x_lower,2))) / x_lower; |
|||
y_mid = tan(x_mid / 2 - m * `M_PI / 2) - sqrt((pow(Vy,2) - pow(x_mid,2))) / x_mid; |
|||
|
|||
if (abs(y_mid) < `TOLERANCE) |
|||
findzeropoint_rect_y = x_mid; |
|||
|
|||
if (y_mid * y_lower < 0) |
|||
x_upper = x_mid; |
|||
else |
|||
x_lower = x_mid; |
|||
iter_count = iter_count + 1; |
|||
end |
|||
if (findzeropoint_rect_y == -1) |
|||
$display("No zero point found in the given range. Please try again with different range."); |
|||
end |
|||
endfunction |
|||
|
|||
analog function real eim_rect; |
|||
input lam, width, thickness, n_ps, n_sub, numflag, mode_index; |
|||
real lam, width, thickness, n_ps, n_sub; |
|||
integer numflag, mode_index; |
|||
real k1, Vx, yx, hx, beta_x, neff_x_MMI, Vy, yy, hxy; |
|||
real beta_xy[0:`MAX_MODES]; |
|||
real neff_xy[0:`MAX_MODES]; |
|||
real beta_xy_out[0:`MAX_MODES]; |
|||
real neff_xy_out[0:`MAX_MODES]; |
|||
integer i, m, mode_num; |
|||
|
|||
begin |
|||
k1=2*`M_PI*n_ps/lam; |
|||
Vx=2*`M_PI/lam*thickness*sqrt((pow(n_ps,2)-pow(n_sub,2))); |
|||
yx=findzeropoint_rect_x(1e-6,min(`M_PI,Vx),Vx); |
|||
hx=yx/thickness; |
|||
beta_x=sqrt(pow(k1,2)-pow(hx,2)); |
|||
neff_x_MMI=lam*beta_x/(2*`M_PI); |
|||
Vy=2*`M_PI/lam*width*sqrt((pow(neff_x_MMI,2)-pow(n_sub,2))); |
|||
i=0; |
|||
m=0; |
|||
while (m*`M_PI<Vy) begin |
|||
yy=findzeropoint_rect_y(m*`M_PI+1e-6,min((m+1)*`M_PI-1e-6,Vy),Vy,m); |
|||
m=m+1; |
|||
// if m*`M_PI>=Vy |
|||
// break |
|||
hxy=yy/width; |
|||
beta_xy[i]=sqrt(pow(beta_x,2)-pow(hxy,2)); |
|||
neff_xy[i]=lam*beta_xy[i]/(2*`M_PI); |
|||
i=i+1; |
|||
end |
|||
mode_num=m-1; |
|||
if (numflag==1 || numflag==2) begin |
|||
for (i=0;i<mode_num;i=i+1) begin |
|||
beta_xy_out[i]=beta_xy[i]; |
|||
neff_xy_out[i]=neff_xy[i]; |
|||
end |
|||
if (numflag==1) |
|||
eim_rect=neff_xy_out[mode_index]; |
|||
else |
|||
eim_rect=beta_xy_out[mode_index]; |
|||
end |
|||
else if (numflag==3) begin |
|||
eim_rect=beta_x; |
|||
end |
|||
else if (numflag==4) begin |
|||
eim_rect=mode_num; |
|||
end |
|||
end |
|||
endfunction |
|||
|
|||
analog function real fieldfunc; |
|||
input y,width,offset,ky,gamma,m,c0; |
|||
real y,width,offset,ky,gamma,m,c0; |
|||
real fai; |
|||
|
|||
begin |
|||
fai = m * `M_PI / 2; |
|||
if (((y - offset) <= (width / 2)) && ((-width / 2) <= (y - offset))) |
|||
fieldfunc=c0 * cos(ky * (y - offset) - fai); |
|||
else if ((y - offset) > width / 2) |
|||
fieldfunc=c0 * cos(ky * width / 2 - fai) * exp(-gamma * ((y - offset) - width / 2)); |
|||
else |
|||
fieldfunc=c0 * cos(ky * width / 2 + fai) * exp(gamma * ((y - offset) + width / 2)); |
|||
end |
|||
endfunction |
|||
|
|||
analog function real normpower_fieldfunc_quad; |
|||
input width,offset,ky,gamma,m,c0,width_MMI,border; |
|||
real width,offset,ky,gamma,m,c0,width_MMI,border; |
|||
real n,h; |
|||
// real border=width_MMI/2; |
|||
integer i; |
|||
real sum; |
|||
begin |
|||
n=`IDX_NUM; |
|||
h=border*2/n; |
|||
sum=0.5*(pow(abs(fieldfunc(-1*border,width,offset,ky,gamma,m,c0)),2)+pow(abs(fieldfunc(border,width,offset,ky,gamma,m,c0)),2)); |
|||
for (i=1;i<n;i=i+1) begin |
|||
sum=sum+pow(abs(fieldfunc(-1*border+i*h,width,offset,ky,gamma,m,c0)),2); |
|||
end |
|||
normpower_fieldfunc_quad=1/sqrt(h*sum); |
|||
end |
|||
endfunction |
|||
|
|||
analog function real infidx_modecoeffcient_quad; |
|||
input width1,offset1,ky1,gamma1,m1,c01,width2,offset2,ky2,gamma2,m2,c02,border; |
|||
real width1,offset1,ky1,gamma1,m1,c01,width2,offset2,ky2,gamma2,m2,c02,border; |
|||
real n,h; |
|||
// real border=20; |
|||
integer i; |
|||
real sum; |
|||
begin |
|||
n=`IDX_NUM; |
|||
h=border*2/n; |
|||
sum=0.5*(fieldfunc(-1*border,width1,offset1,ky1,gamma1,m1,c01)* fieldfunc(-1*border,width2,offset2,ky2,gamma2,m2,c02)+fieldfunc(border,width1,offset1,ky1,gamma1,m1,c01)* fieldfunc(border,width2,offset2,ky2,gamma2,m2,c02)); |
|||
for (i=1;i<n;i=i+1) begin |
|||
sum=sum+fieldfunc(-1*border+i*h,width1,offset1,ky1,gamma1,m1,c01)* fieldfunc(-1*border+i*h,width2,offset2,ky2,gamma2,m2,c02); |
|||
end |
|||
infidx_modecoeffcient_quad=h*sum; |
|||
end |
|||
endfunction |
|||
|
|||
analog initial begin |
|||
ulam0=design_lam*1e6; |
|||
uwidth_in=width_port*1e6; |
|||
uwidth_MMI=width_MMI*1e6; |
|||
uoffset=port_offset*1e6; |
|||
uthickness=thickness*1e6; |
|||
alpha0=alpha_mmi*1e-6; |
|||
k1_ref = 2 * `M_PI * n_ps / ulam0; |
|||
kc_ref = 2 * `M_PI * n_sub / ulam0; |
|||
|
|||
mode_num_ref = eim_rect(ulam0, uwidth_MMI, uthickness, n_ps, n_sub, 4, 0); |
|||
for (i=0;i<mode_num_ref;i=i+1) begin |
|||
beta_MMI[i] = eim_rect(ulam0, uwidth_MMI, uthickness, n_ps, n_sub, 2, i); |
|||
end |
|||
length_MMI = p*0.75*`M_PI/(beta_MMI[0]-beta_MMI[1])/2; //0.375Lpi? |
|||
// $display("length_MMI=%f",length_MMI); |
|||
border=20; |
|||
end |
|||
|
|||
analog begin |
|||
ulam = V(Ilam) * 1e6; |
|||
beta_in=eim_rect(ulam, uwidth_in, uthickness, n_ps, n_sub, 2, 0); |
|||
// $display("beta_in=%f",beta_in); |
|||
beta_x_in=eim_rect(ulam, uwidth_in, uthickness, n_ps, n_sub, 3, 0); |
|||
// $display("beta_x_in=%f",beta_x_in); |
|||
beta_x_MMI=eim_rect(ulam, uwidth_MMI, uthickness, n_ps, n_sub, 3, 0); |
|||
// $display("beta_x_MMI=%f",beta_x_MMI); |
|||
mode_num = eim_rect(ulam, uwidth_MMI, uthickness, n_ps, n_sub, 4, 0); |
|||
// $display("mode_num=%d",mode_num); |
|||
ky_in = sqrt(pow(beta_x_in,2) - pow(beta_in,2)); |
|||
// $display("ky_in=%f",ky_in); |
|||
gamma_in = sqrt(pow(beta_in,2) - pow(kc_ref,2)); |
|||
for (i=0;i<mode_num;i=i+1) begin |
|||
neff_MMI[i] = eim_rect(ulam, uwidth_MMI, uthickness, n_ps, n_sub, 1, i); |
|||
beta_MMI[i] = eim_rect(ulam, uwidth_MMI, uthickness, n_ps, n_sub, 2, i); |
|||
ky_MMI[i] = sqrt(pow(beta_x_MMI,2) - pow(beta_MMI[i],2)); |
|||
gamma_MMI[i] = sqrt(pow(beta_MMI[i],2) - pow(kc_ref,2)); |
|||
// $display("neff_MMI[%d]=%f, beta_MMI[%d]=%f, ky_MMI[%d]=%f, gamma_MMI[%d]=%f",i,neff_MMI[i],i,beta_MMI[i],i,ky_MMI[i],i,gamma_MMI[i]); |
|||
end |
|||
|
|||
c0=normpower_fieldfunc_quad(uwidth_in,0,ky_in,gamma_in,0,1,uwidth_MMI,border); |
|||
// $display("c0=%f",c0); |
|||
for (i=0;i<mode_num;i=i+1) begin |
|||
c0_dis[i]=normpower_fieldfunc_quad(uwidth_MMI,0,ky_MMI[i],gamma_MMI[i],i,1,uwidth_MMI,border); |
|||
// $display("c0_dis[%d]=%f",i,c0_dis[i]); |
|||
icoff[i]=infidx_modecoeffcient_quad(uwidth_in,0,ky_in,gamma_in,0,c0,uwidth_MMI,0,ky_MMI[i],gamma_MMI[i],i,c0_dis[i],border); |
|||
// $display("icoff[%d]=%f",i,icoff[i]); |
|||
end |
|||
|
|||
delta_beta = beta_MMI[0] - beta_MMI[1]; |
|||
// $display("delta_beta=%f",delta_beta); |
|||
for (i=2;i<mode_num;i=i+1) begin |
|||
beta_MMI[i]=beta_MMI[0] - i* (i + 2) * delta_beta / 3; |
|||
// $display("beta_MMI[%d]=%f",i,beta_MMI[i]); |
|||
end |
|||
for (i=0;i<mode_num;i=i+1) begin |
|||
ocoff_r[i]=icoff[i]*cos(-beta_MMI[i]*length_MMI); |
|||
ocoff_i[i]=icoff[i]*sin(-beta_MMI[i]*length_MMI)*-1.0; |
|||
// $display("ocoff_r[%d]=%f, ocoff_i[%d]=%f",i,ocoff_r[i],i,ocoff_i[i]); |
|||
end |
|||
h=border*2.0/`IDX_NUM; |
|||
sum_outfield1=0; |
|||
sum_outfield2=0; |
|||
sum_outfield3=0; |
|||
sum_outfield4=0; |
|||
for (j=0;j<mode_num;j=j+1) begin |
|||
sum_singlemode1=0.5*(ocoff_r[j]*fieldfunc(-1*border,uwidth_MMI,0,ky_MMI[j],gamma_MMI[j],j,c0_dis[j])*fieldfunc(-1*border,uwidth_in,uoffset,ky_in,gamma_in,0,c0)+ocoff_r[j]*fieldfunc(border,uwidth_MMI,0,ky_MMI[j],gamma_MMI[j],j,c0_dis[j])*fieldfunc(border,uwidth_in,uoffset,ky_in,gamma_in,0,c0)); |
|||
sum_singlemode2=0.5*(ocoff_i[j]*fieldfunc(-1*border,uwidth_MMI,0,ky_MMI[j],gamma_MMI[j],j,c0_dis[j])*fieldfunc(-1*border,uwidth_in,uoffset,ky_in,gamma_in,0,c0)+ocoff_i[j]*fieldfunc(border,uwidth_MMI,0,ky_MMI[j],gamma_MMI[j],j,c0_dis[j])*fieldfunc(border,uwidth_in,uoffset,ky_in,gamma_in,0,c0)); |
|||
sum_singlemode3=0.5*(ocoff_r[j]*fieldfunc(-1*border,uwidth_MMI,0,ky_MMI[j],gamma_MMI[j],j,c0_dis[j])*fieldfunc(-1*border,uwidth_in,-uoffset,ky_in,gamma_in,0,c0)+ocoff_r[j]*fieldfunc(border,uwidth_MMI,0,ky_MMI[j],gamma_MMI[j],j,c0_dis[j])*fieldfunc(border,uwidth_in,-uoffset,ky_in,gamma_in,0,c0)); |
|||
sum_singlemode4=0.5*(ocoff_i[j]*fieldfunc(-1*border,uwidth_MMI,0,ky_MMI[j],gamma_MMI[j],j,c0_dis[j])*fieldfunc(-1*border,uwidth_in,-uoffset,ky_in,gamma_in,0,c0)+ocoff_i[j]*fieldfunc(border,uwidth_MMI,0,ky_MMI[j],gamma_MMI[j],j,c0_dis[j])*fieldfunc(border,uwidth_in,-uoffset,ky_in,gamma_in,0,c0)); |
|||
for (i=1;i<`IDX_NUM;i=i+1) begin |
|||
sum_singlemode1=sum_singlemode1+ocoff_r[j]*fieldfunc(-1*border+i*h,uwidth_MMI,0,ky_MMI[j],gamma_MMI[j],j,c0_dis[j])*fieldfunc(-1*border+i*h,uwidth_in,uoffset,ky_in,gamma_in,0,c0); |
|||
sum_singlemode2=sum_singlemode2+ocoff_i[j]*fieldfunc(-1*border+i*h,uwidth_MMI,0,ky_MMI[j],gamma_MMI[j],j,c0_dis[j])*fieldfunc(-1*border+i*h,uwidth_in,uoffset,ky_in,gamma_in,0,c0); |
|||
sum_singlemode3=sum_singlemode3+ocoff_r[j]*fieldfunc(-1*border+i*h,uwidth_MMI,0,ky_MMI[j],gamma_MMI[j],j,c0_dis[j])*fieldfunc(-1*border+i*h,uwidth_in,-uoffset,ky_in,gamma_in,0,c0); |
|||
sum_singlemode4=sum_singlemode4+ocoff_i[j]*fieldfunc(-1*border+i*h,uwidth_MMI,0,ky_MMI[j],gamma_MMI[j],j,c0_dis[j])*fieldfunc(-1*border+i*h,uwidth_in,-uoffset,ky_in,gamma_in,0,c0); |
|||
end |
|||
// $display("sum_singlemode1=%f, sum_singlemode2=%f, sum_singlemode3=%f, sum_singlemode4=%f",sum_singlemode1,sum_singlemode2,sum_singlemode3,sum_singlemode4); |
|||
sum_outfield1=sum_outfield1+h*sum_singlemode1; |
|||
sum_outfield2=sum_outfield2+h*sum_singlemode2; |
|||
sum_outfield3=sum_outfield3+h*sum_singlemode3; |
|||
sum_outfield4=sum_outfield4+h*sum_singlemode4; |
|||
end |
|||
c1r=sum_outfield1*exp(-alpha0*length_MMI); |
|||
c1i=sum_outfield2*exp(-alpha0*length_MMI); |
|||
c2r=sum_outfield3*exp(-alpha0*length_MMI); |
|||
c2i=sum_outfield4*exp(-alpha0*length_MMI); |
|||
// $display("c1r=%f, c1i=%f, c2r=%f, c2i=%f",c1r,c1i,c2r,c2i); |
|||
|
|||
inr=sqrt(V(Ipow))*cos(V(Iphase)/360.0*2*`M_PI); |
|||
ini=sqrt(V(Ipow))*sin(V(Iphase)/360.0*2*`M_PI); |
|||
out1r=c1r*inr-c1i*ini; |
|||
out1i=c1r*ini+c1i*inr; |
|||
out2r=c2r*inr-c2i*ini; |
|||
out2i=c2r*ini+c2i*inr; |
|||
|
|||
V(Opow1) <+ pow(out1r,2)+pow(out1i,2); |
|||
V(Ophase1) <+ atan2(out1i,out1r)*360.0/2/`M_PI; |
|||
V(Olam1) <+ ulam/1e6; |
|||
V(Opow2) <+ pow(out2r,2)+pow(out2i,2); |
|||
V(Ophase2) <+ atan2(out2i,out2r)*360.0/2/`M_PI; |
|||
V(Olam2) <+ ulam/1e6; |
|||
end |
|||
|
|||
endmodule |
@ -0,0 +1,331 @@ |
|||
//VerilogA for passive,mmi2x2,veriloga |
|||
//Xuanqi Chen, Zhifei Wang, Yi-Shing Chang, Jiang Xu, Jun Feng, Peng Yang, Zhehui Wang, Luan H. K. Duong, ”Modeling and Analysis of Optical Modulators Based on Free-Carrier Plasma Dispersion Effect,” IEEE Transactions on Computer-Aided Design of Integrated Circuits and Systems (TCAD), vol. 39, no. 5, pp. 977-990, May 2020. |
|||
|
|||
`include "constants.vams" |
|||
`include "disciplines.vams" |
|||
|
|||
`define MAX_MODES 200 |
|||
`define MAX_ITER 10000 |
|||
`define IDX_NUM 50000 |
|||
`define TOLERANCE 0.0000000001 |
|||
|
|||
module mmi2x2(Ipow1,Iphase1,Ilam1,Ipow2,Iphase2,Ilam2,Opow1,Ophase1,Olam1,Opow2,Ophase2,Olam2); |
|||
parameter real design_lam = 1.55e-6 from (0:inf); |
|||
parameter real n_ps = 3.45 from (0:inf); |
|||
parameter real n_sub = 1.45 from (0:inf); |
|||
parameter real width_MMI = 3e-6 from (0:inf); |
|||
parameter real width_port = 0.45e-6 from (0:inf); |
|||
parameter real port_offset = 0.75e-6 from (0:inf); |
|||
parameter real thickness = 0.22e-6 from (0:inf); |
|||
parameter real alpha_mmi = 80 from (0:inf); |
|||
|
|||
input Ipow1,Iphase1,Ilam1,Ipow2,Iphase2,Ilam2; |
|||
output Opow1,Ophase1,Olam1,Opow2,Ophase2,Olam2; |
|||
electrical Ipow1,Iphase1,Ilam1,Ipow2,Iphase2,Ilam2,Opow1,Ophase1,Olam1,Opow2,Ophase2,Olam2; |
|||
|
|||
real ulam, ulam0, uwidth_in, uwidth_MMI, uoffset, uthickness, alpha0; |
|||
real k1_ref, kc_ref; |
|||
integer mode_num, mode_num_ref; |
|||
real beta_x_MMI, beta_in, beta_x_in; |
|||
real neff_MMI[0:`MAX_MODES]; |
|||
real beta_MMI[0:`MAX_MODES]; |
|||
real length_MMI; |
|||
real ky_in, gamma_in; |
|||
real ky_MMI[0:`MAX_MODES]; |
|||
real gamma_MMI[0:`MAX_MODES]; |
|||
real c0; |
|||
real c0_dis[0:`MAX_MODES]; |
|||
real icoff[0:`MAX_MODES]; |
|||
real delta_beta; |
|||
real ocoff_r[0:`MAX_MODES]; |
|||
real ocoff_i[0:`MAX_MODES]; |
|||
real c1r, c1i, c2r, c2i; |
|||
real in1r, in1i, in2r, in2i, out1r, out1i, out2r, out2i; |
|||
real sum_outfield1, sum_outfield2, sum_outfield3, sum_outfield4; |
|||
real sum_singlemode1,sum_singlemode2,sum_singlemode3,sum_singlemode4; |
|||
|
|||
real border; |
|||
|
|||
integer i, j; |
|||
real p=1; |
|||
real h; |
|||
|
|||
analog function real findzeropoint_rect_x; |
|||
input x_lower_input, x_upper_input, Vx; |
|||
real x_lower_input, x_upper_input, Vx; |
|||
real iter_count; |
|||
real x_lower, x_upper; |
|||
real y_mid; |
|||
|
|||
real y_lower, x_mid; |
|||
|
|||
begin |
|||
findzeropoint_rect_x = -1; |
|||
x_lower = x_lower_input; |
|||
x_upper = x_upper_input; |
|||
iter_count = 0; |
|||
y_mid = 1; |
|||
while (iter_count<`MAX_ITER && abs(y_mid) > `TOLERANCE) begin |
|||
x_mid = (x_lower + x_upper) / 2; |
|||
y_lower = tan(x_lower / 2) - sqrt(pow(Vx,2) - pow(x_lower,2)) / x_lower; |
|||
y_mid = tan(x_mid / 2) - sqrt(pow(Vx,2) - pow(x_mid,2)) / x_mid; |
|||
|
|||
if (abs(y_mid) < `TOLERANCE) begin |
|||
findzeropoint_rect_x = x_mid; |
|||
end |
|||
|
|||
if (y_mid * y_lower < 0) |
|||
x_upper = x_mid; |
|||
else |
|||
x_lower = x_mid; |
|||
|
|||
iter_count = iter_count + 1; |
|||
end |
|||
if (findzeropoint_rect_x == -1) |
|||
$display("No zero point found in the given range. Please try again with different range."); |
|||
end |
|||
endfunction |
|||
|
|||
analog function real findzeropoint_rect_y; |
|||
input x_lower_input, x_upper_input, Vy, m; |
|||
real x_lower_input, x_upper_input, Vy, m; |
|||
real iter_count; |
|||
real x_lower, x_upper; |
|||
real y_mid; |
|||
|
|||
real y_lower, x_mid; |
|||
|
|||
begin |
|||
x_lower = x_lower_input; |
|||
x_upper = x_upper_input; |
|||
iter_count = 0; |
|||
y_mid = 1; |
|||
findzeropoint_rect_y = -1; |
|||
while (iter_count<`MAX_ITER && abs(y_mid) > `TOLERANCE) begin |
|||
x_mid = (x_lower + x_upper) / 2; |
|||
y_lower = tan(x_lower / 2 - m * `M_PI / 2) - sqrt((pow(Vy,2) - pow(x_lower,2))) / x_lower; |
|||
y_mid = tan(x_mid / 2 - m * `M_PI / 2) - sqrt((pow(Vy,2) - pow(x_mid,2))) / x_mid; |
|||
|
|||
if (abs(y_mid) < `TOLERANCE) |
|||
findzeropoint_rect_y = x_mid; |
|||
|
|||
if (y_mid * y_lower < 0) |
|||
x_upper = x_mid; |
|||
else |
|||
x_lower = x_mid; |
|||
iter_count = iter_count + 1; |
|||
end |
|||
if (findzeropoint_rect_y == -1) |
|||
$display("No zero point found in the given range. Please try again with different range."); |
|||
end |
|||
endfunction |
|||
|
|||
analog function real eim_rect; |
|||
input lam, width, thickness, n_ps, n_sub, numflag, mode_index; |
|||
real lam, width, thickness, n_ps, n_sub; |
|||
integer numflag, mode_index; |
|||
real k1, Vx, yx, hx, beta_x, neff_x_MMI, Vy, yy, hxy; |
|||
real beta_xy[0:`MAX_MODES]; |
|||
real neff_xy[0:`MAX_MODES]; |
|||
real beta_xy_out[0:`MAX_MODES]; |
|||
real neff_xy_out[0:`MAX_MODES]; |
|||
integer i, m, mode_num; |
|||
|
|||
begin |
|||
k1=2*`M_PI*n_ps/lam; |
|||
Vx=2*`M_PI/lam*thickness*sqrt((pow(n_ps,2)-pow(n_sub,2))); |
|||
yx=findzeropoint_rect_x(1e-6,min(`M_PI,Vx),Vx); |
|||
hx=yx/thickness; |
|||
beta_x=sqrt(pow(k1,2)-pow(hx,2)); |
|||
neff_x_MMI=lam*beta_x/(2*`M_PI); |
|||
Vy=2*`M_PI/lam*width*sqrt((pow(neff_x_MMI,2)-pow(n_sub,2))); |
|||
i=0; |
|||
m=0; |
|||
while (m*`M_PI<Vy) begin |
|||
yy=findzeropoint_rect_y(m*`M_PI+1e-6,min((m+1)*`M_PI-1e-6,Vy),Vy,m); |
|||
m=m+1; |
|||
// if m*`M_PI>=Vy |
|||
// break |
|||
hxy=yy/width; |
|||
beta_xy[i]=sqrt(pow(beta_x,2)-pow(hxy,2)); |
|||
neff_xy[i]=lam*beta_xy[i]/(2*`M_PI); |
|||
i=i+1; |
|||
end |
|||
mode_num=m-1; |
|||
if (numflag==1 || numflag==2) begin |
|||
for (i=0;i<mode_num;i=i+1) begin |
|||
beta_xy_out[i]=beta_xy[i]; |
|||
neff_xy_out[i]=neff_xy[i]; |
|||
end |
|||
if (numflag==1) |
|||
eim_rect=neff_xy_out[mode_index]; |
|||
else |
|||
eim_rect=beta_xy_out[mode_index]; |
|||
end |
|||
else if (numflag==3) begin |
|||
eim_rect=beta_x; |
|||
end |
|||
else if (numflag==4) begin |
|||
eim_rect=mode_num; |
|||
end |
|||
end |
|||
endfunction |
|||
|
|||
analog function real fieldfunc; |
|||
input y,width,offset,ky,gamma,m,c0; |
|||
real y,width,offset,ky,gamma,m,c0; |
|||
real fai; |
|||
|
|||
begin |
|||
fai = m * `M_PI / 2; |
|||
if (((y - offset) <= (width / 2)) && ((-width / 2) <= (y - offset))) |
|||
fieldfunc=c0 * cos(ky * (y - offset) - fai); |
|||
else if ((y - offset) > width / 2) |
|||
fieldfunc=c0 * cos(ky * width / 2 - fai) * exp(-gamma * ((y - offset) - width / 2)); |
|||
else |
|||
fieldfunc=c0 * cos(ky * width / 2 + fai) * exp(gamma * ((y - offset) + width / 2)); |
|||
end |
|||
endfunction |
|||
|
|||
analog function real normpower_fieldfunc_quad; |
|||
input width,offset,ky,gamma,m,c0,width_MMI,border; |
|||
real width,offset,ky,gamma,m,c0,width_MMI,border; |
|||
real n,h; |
|||
// real border=width_MMI/2; |
|||
integer i; |
|||
real sum; |
|||
begin |
|||
n=`IDX_NUM; |
|||
h=border*2/n; |
|||
sum=0.5*(pow(abs(fieldfunc(-1*border,width,offset,ky,gamma,m,c0)),2)+pow(abs(fieldfunc(border,width,offset,ky,gamma,m,c0)),2)); |
|||
for (i=1;i<n;i=i+1) begin |
|||
sum=sum+pow(abs(fieldfunc(-1*border+i*h,width,offset,ky,gamma,m,c0)),2); |
|||
end |
|||
normpower_fieldfunc_quad=1/sqrt(h*sum); |
|||
end |
|||
endfunction |
|||
|
|||
analog function real infidx_modecoeffcient_quad; |
|||
input width1,offset1,ky1,gamma1,m1,c01,width2,offset2,ky2,gamma2,m2,c02,border; |
|||
real width1,offset1,ky1,gamma1,m1,c01,width2,offset2,ky2,gamma2,m2,c02,border; |
|||
real n,h; |
|||
// real border=20; |
|||
integer i; |
|||
real sum; |
|||
begin |
|||
n=`IDX_NUM; |
|||
h=border*2/n; |
|||
sum=0.5*(fieldfunc(-1*border,width1,offset1,ky1,gamma1,m1,c01)* fieldfunc(-1*border,width2,offset2,ky2,gamma2,m2,c02)+fieldfunc(border,width1,offset1,ky1,gamma1,m1,c01)* fieldfunc(border,width2,offset2,ky2,gamma2,m2,c02)); |
|||
for (i=1;i<n;i=i+1) begin |
|||
sum=sum+fieldfunc(-1*border+i*h,width1,offset1,ky1,gamma1,m1,c01)* fieldfunc(-1*border+i*h,width2,offset2,ky2,gamma2,m2,c02); |
|||
end |
|||
infidx_modecoeffcient_quad=h*sum; |
|||
end |
|||
endfunction |
|||
|
|||
analog initial begin |
|||
ulam0=design_lam*1e6; |
|||
uwidth_in=width_port*1e6; |
|||
uwidth_MMI=width_MMI*1e6; |
|||
uoffset=port_offset*1e6; |
|||
uthickness=thickness*1e6; |
|||
alpha0=alpha_mmi*1e-6; |
|||
k1_ref = 2 * `M_PI * n_ps / ulam0; |
|||
kc_ref = 2 * `M_PI * n_sub / ulam0; |
|||
|
|||
mode_num_ref = eim_rect(ulam0, uwidth_MMI, uthickness, n_ps, n_sub, 4, 0); |
|||
for (i=0;i<mode_num_ref;i=i+1) begin |
|||
beta_MMI[i] = eim_rect(ulam0, uwidth_MMI, uthickness, n_ps, n_sub, 2, i); |
|||
end |
|||
length_MMI = p*1.5*`M_PI/(beta_MMI[0]-beta_MMI[1]); //1.5Lpi? |
|||
// $display("length_MMI=%f",length_MMI); |
|||
border=20; |
|||
end |
|||
|
|||
analog begin |
|||
ulam = V(Ilam1) * 1e6; |
|||
beta_in=eim_rect(ulam, uwidth_in, uthickness, n_ps, n_sub, 2, 0); |
|||
// $display("beta_in=%f",beta_in); |
|||
beta_x_in=eim_rect(ulam, uwidth_in, uthickness, n_ps, n_sub, 3, 0); |
|||
// $display("beta_x_in=%f",beta_x_in); |
|||
beta_x_MMI=eim_rect(ulam, uwidth_MMI, uthickness, n_ps, n_sub, 3, 0); |
|||
// $display("beta_x_MMI=%f",beta_x_MMI); |
|||
mode_num = eim_rect(ulam, uwidth_MMI, uthickness, n_ps, n_sub, 4, 0); |
|||
// $display("mode_num=%d",mode_num); |
|||
ky_in = sqrt(pow(beta_x_in,2) - pow(beta_in,2)); |
|||
// $display("ky_in=%f",ky_in); |
|||
gamma_in = sqrt(pow(beta_in,2) - pow(kc_ref,2)); |
|||
for (i=0;i<mode_num;i=i+1) begin |
|||
neff_MMI[i] = eim_rect(ulam, uwidth_MMI, uthickness, n_ps, n_sub, 1, i); |
|||
beta_MMI[i] = eim_rect(ulam, uwidth_MMI, uthickness, n_ps, n_sub, 2, i); |
|||
ky_MMI[i] = sqrt(pow(beta_x_MMI,2) - pow(beta_MMI[i],2)); |
|||
gamma_MMI[i] = sqrt(pow(beta_MMI[i],2) - pow(kc_ref,2)); |
|||
// $display("neff_MMI[%d]=%f, beta_MMI[%d]=%f, ky_MMI[%d]=%f, gamma_MMI[%d]=%f",i,neff_MMI[i],i,beta_MMI[i],i,ky_MMI[i],i,gamma_MMI[i]); |
|||
end |
|||
|
|||
c0=normpower_fieldfunc_quad(uwidth_in,0,ky_in,gamma_in,0,1,uwidth_MMI,border); |
|||
// $display("c0=%f",c0); |
|||
for (i=0;i<mode_num;i=i+1) begin |
|||
c0_dis[i]=normpower_fieldfunc_quad(uwidth_MMI,0,ky_MMI[i],gamma_MMI[i],i,1,uwidth_MMI,border); |
|||
// $display("c0_dis[%d]=%f",i,c0_dis[i]); |
|||
icoff[i]=infidx_modecoeffcient_quad(uwidth_in,uoffset,ky_in,gamma_in,0,c0,uwidth_MMI,0,ky_MMI[i],gamma_MMI[i],i,c0_dis[i],border); |
|||
// $display("icoff[%d]=%f",i,icoff[i]); |
|||
end |
|||
|
|||
delta_beta = beta_MMI[0] - beta_MMI[1]; |
|||
// $display("delta_beta=%f",delta_beta); |
|||
for (i=2;i<mode_num;i=i+1) begin |
|||
beta_MMI[i]=beta_MMI[0] - i* (i + 2) * delta_beta / 3; |
|||
// $display("beta_MMI[%d]=%f",i,beta_MMI[i]); |
|||
end |
|||
for (i=0;i<mode_num;i=i+1) begin |
|||
ocoff_r[i]=icoff[i]*cos(-beta_MMI[i]*length_MMI); |
|||
ocoff_i[i]=icoff[i]*sin(-beta_MMI[i]*length_MMI)*-1.0; |
|||
// $display("ocoff_r[%d]=%f, ocoff_i[%d]=%f",i,ocoff_r[i],i,ocoff_i[i]); |
|||
end |
|||
h=border*2.0/`IDX_NUM; |
|||
sum_outfield1=0; |
|||
sum_outfield2=0; |
|||
sum_outfield3=0; |
|||
sum_outfield4=0; |
|||
for (j=0;j<mode_num;j=j+1) begin |
|||
sum_singlemode1=0.5*(ocoff_r[j]*fieldfunc(-1*border,uwidth_MMI,0,ky_MMI[j],gamma_MMI[j],j,c0_dis[j])*fieldfunc(-1*border,uwidth_in,uoffset,ky_in,gamma_in,0,c0)+ocoff_r[j]*fieldfunc(border,uwidth_MMI,0,ky_MMI[j],gamma_MMI[j],j,c0_dis[j])*fieldfunc(border,uwidth_in,uoffset,ky_in,gamma_in,0,c0)); |
|||
sum_singlemode2=0.5*(ocoff_i[j]*fieldfunc(-1*border,uwidth_MMI,0,ky_MMI[j],gamma_MMI[j],j,c0_dis[j])*fieldfunc(-1*border,uwidth_in,uoffset,ky_in,gamma_in,0,c0)+ocoff_i[j]*fieldfunc(border,uwidth_MMI,0,ky_MMI[j],gamma_MMI[j],j,c0_dis[j])*fieldfunc(border,uwidth_in,uoffset,ky_in,gamma_in,0,c0)); |
|||
sum_singlemode3=0.5*(ocoff_r[j]*fieldfunc(-1*border,uwidth_MMI,0,ky_MMI[j],gamma_MMI[j],j,c0_dis[j])*fieldfunc(-1*border,uwidth_in,-uoffset,ky_in,gamma_in,0,c0)+ocoff_r[j]*fieldfunc(border,uwidth_MMI,0,ky_MMI[j],gamma_MMI[j],j,c0_dis[j])*fieldfunc(border,uwidth_in,-uoffset,ky_in,gamma_in,0,c0)); |
|||
sum_singlemode4=0.5*(ocoff_i[j]*fieldfunc(-1*border,uwidth_MMI,0,ky_MMI[j],gamma_MMI[j],j,c0_dis[j])*fieldfunc(-1*border,uwidth_in,-uoffset,ky_in,gamma_in,0,c0)+ocoff_i[j]*fieldfunc(border,uwidth_MMI,0,ky_MMI[j],gamma_MMI[j],j,c0_dis[j])*fieldfunc(border,uwidth_in,-uoffset,ky_in,gamma_in,0,c0)); |
|||
for (i=1;i<`IDX_NUM;i=i+1) begin |
|||
sum_singlemode1=sum_singlemode1+ocoff_r[j]*fieldfunc(-1*border+i*h,uwidth_MMI,0,ky_MMI[j],gamma_MMI[j],j,c0_dis[j])*fieldfunc(-1*border+i*h,uwidth_in,uoffset,ky_in,gamma_in,0,c0); |
|||
sum_singlemode2=sum_singlemode2+ocoff_i[j]*fieldfunc(-1*border+i*h,uwidth_MMI,0,ky_MMI[j],gamma_MMI[j],j,c0_dis[j])*fieldfunc(-1*border+i*h,uwidth_in,uoffset,ky_in,gamma_in,0,c0); |
|||
sum_singlemode3=sum_singlemode3+ocoff_r[j]*fieldfunc(-1*border+i*h,uwidth_MMI,0,ky_MMI[j],gamma_MMI[j],j,c0_dis[j])*fieldfunc(-1*border+i*h,uwidth_in,-uoffset,ky_in,gamma_in,0,c0); |
|||
sum_singlemode4=sum_singlemode4+ocoff_i[j]*fieldfunc(-1*border+i*h,uwidth_MMI,0,ky_MMI[j],gamma_MMI[j],j,c0_dis[j])*fieldfunc(-1*border+i*h,uwidth_in,-uoffset,ky_in,gamma_in,0,c0); |
|||
end |
|||
// $display("sum_singlemode1=%f, sum_singlemode2=%f, sum_singlemode3=%f, sum_singlemode4=%f",sum_singlemode1,sum_singlemode2,sum_singlemode3,sum_singlemode4); |
|||
sum_outfield1=sum_outfield1+h*sum_singlemode1; |
|||
sum_outfield2=sum_outfield2+h*sum_singlemode2; |
|||
sum_outfield3=sum_outfield3+h*sum_singlemode3; |
|||
sum_outfield4=sum_outfield4+h*sum_singlemode4; |
|||
end |
|||
c1r=sum_outfield1; |
|||
c1i=sum_outfield2; |
|||
c2r=sum_outfield3; |
|||
c2i=sum_outfield4; |
|||
// $display("c1r=%f, c1i=%f, c2r=%f, c2i=%f",c1r,c1i,c2r,c2i); |
|||
|
|||
in1r=sqrt(V(Ipow1))*cos(V(Iphase1)/360.0*2*`M_PI); |
|||
in1i=sqrt(V(Ipow1))*sin(V(Iphase1)/360.0*2*`M_PI); |
|||
in2r=sqrt(V(Ipow2))*cos(V(Iphase2)/360.0*2*`M_PI); |
|||
in2i=sqrt(V(Ipow2))*sin(V(Iphase2)/360.0*2*`M_PI); |
|||
out1r=c1r*in1r-c1i*in1i+c2r*in2r-c2i*in2i; |
|||
out1i=c1r*in1i+c1i*in1r+c2r*in2i+c2i*in2r; |
|||
out2r=c2r*in1r-c2i*in1i-c1r*in2r+c1i*in2i; |
|||
out2i=c2r*in1i+c2i*in1r-c1r*in2i-c1i*in2r; |
|||
|
|||
V(Opow1) <+ pow(out1r,2)+pow(out1i,2); |
|||
V(Ophase1) <+ atan2(out1i,out1r)*360.0/(2*`M_PI); |
|||
V(Olam1) <+ ulam/1e6; |
|||
V(Opow2) <+ pow(out2r,2)+pow(out2i,2); |
|||
V(Ophase2) <+ atan2(out2i,out2r)*360.0/(2*`M_PI); |
|||
V(Olam2) <+ ulam/1e6; |
|||
end |
|||
|
|||
endmodule |
@ -0,0 +1,24 @@ |
|||
//VerilogA for passive,phasedelay,veriloga |
|||
`include "constants.vams" |
|||
`include "disciplines.vams" |
|||
|
|||
module phasedelay(V1,V2,Ipow,Iphase,Ilam,Opow,Ophase,Olam); |
|||
parameter real a = 1; |
|||
parameter real phi = 0 from (-360:360); |
|||
|
|||
input Ipow,Iphase,Ilam; |
|||
output Opow,Ophase,Olam; |
|||
inout V1,V2; |
|||
electrical V1,V2,Ipow,Iphase,Ilam,Opow,Ophase,Olam; |
|||
|
|||
real iph,oph; |
|||
|
|||
analog begin |
|||
iph=I(Iphase)/360.0*2*`M_PI; |
|||
oph=(iph+a*(V(V1)-V(V2))+phi/360.0*2*`M_PI)*360.0/(2*`M_PI); |
|||
V(Opow) <+ V(Ipow); |
|||
V(Ophase) <+ oph; |
|||
V(Olam) <+ V(Ilam); |
|||
end |
|||
|
|||
endmodule |
@ -0,0 +1,21 @@ |
|||
//VerilogA for passive,spliter2,veriloga |
|||
`include "constants.vams" |
|||
`include "disciplines.vams" |
|||
|
|||
module spliter2(Ipow,Iphase,Ilam,Opow1,Ophase1,Olam1,Opow2,Ophase2,Olam2); |
|||
parameter real r1 = 0.5 from [0:1]; |
|||
parameter real r2 = 0.5 from [0:1]; |
|||
|
|||
input Ipow,Iphase,Ilam; |
|||
output Opow1,Ophase1,Olam1,Opow2,Ophase2,Olam2; |
|||
electrical Ipow,Iphase,Ilam,Opow1,Ophase1,Olam1,Opow2,Ophase2,Olam2; |
|||
|
|||
analog begin |
|||
V(Opow1) <+ V(Ipow)*r1; |
|||
V(Opow2) <+ V(Ipow)*r2; |
|||
V(Ophase1) <+ V(Iphase); |
|||
V(Ophase2) <+ V(Iphase); |
|||
V(Olam1) <+ V(Ilam); |
|||
V(Olam2) <+ V(Ilam); |
|||
end |
|||
endmodule |
@ -0,0 +1,26 @@ |
|||
//VerilogA for passive,spliter3,veriloga |
|||
|
|||
`include "constants.vams" |
|||
`include "disciplines.vams" |
|||
|
|||
module spliter3(Ipow,Iphase,Ilam,Opow1,Ophase1,Olam1,Opow2,Ophase2,Olam2,Opow3,Ophase3,Olam3); |
|||
parameter real r1 = 0.3333 from [0:1]; |
|||
parameter real r2 = 0.3333 from [0:1]; |
|||
parameter real r3 = 0.3333 from [0:1]; |
|||
|
|||
input Ipow,Iphase,Ilam; |
|||
output Opow1,Ophase1,Olam1,Opow2,Ophase2,Olam2,Opow3,Ophase3,Olam3; |
|||
electrical Ipow,Iphase,Ilam,Opow1,Ophase1,Olam1,Opow2,Ophase2,Olam2,Opow3,Ophase3,Olam3; |
|||
|
|||
analog begin |
|||
V(Opow1) <+ V(Ipow)*r1; |
|||
V(Opow2) <+ V(Ipow)*r2; |
|||
V(Opow3) <+ V(Ipow)*r3; |
|||
V(Ophase1) <+ V(Iphase); |
|||
V(Ophase2) <+ V(Iphase); |
|||
V(Ophase3) <+ V(Iphase); |
|||
V(Olam1) <+ V(Ilam); |
|||
V(Olam2) <+ V(Ilam); |
|||
V(Olam3) <+ V(Ilam); |
|||
end |
|||
endmodule |
@ -0,0 +1,136 @@ |
|||
//VerilogA for passive,spliterbasic,veriloga |
|||
|
|||
`include "constants.vams" |
|||
`include "disciplines.vams" |
|||
|
|||
module spliterbasic(Ipow,Iphase,Ilam,Opow1,Ophase1,Olam1,Opow2,Ophase2,Olam2); |
|||
parameter integer modespec = 1 from [1:2]; |
|||
parameter integer alpha_use_dBm = 1 from [0:1]; |
|||
parameter real reffreq = 193.1e12 from (0:inf); |
|||
parameter real l_str = 500e-6 from [0:inf); |
|||
parameter real l_up = 500e-6 from [0:inf); |
|||
parameter real l_down = 500e-6 from [0:inf); |
|||
parameter real neff_te = 2.6 from (0:inf); |
|||
parameter real neff_tm = 2.6 from (0:inf); |
|||
parameter real n_gv_te = 4.2 from (0:inf); |
|||
parameter real n_gv_tm = 4.2 from (0:inf); |
|||
parameter real disper_te = 0; |
|||
parameter real disper_tm = 0; |
|||
parameter real attenu_te = 0 from [0:inf);//attenuation in dB/m |
|||
parameter real attenu_tm = 0 from [0:inf);//attenuation in dB/m |
|||
parameter real design_freq = 193.1e12 from (0:inf); |
|||
parameter real s0_te = 0.5 from [0:1]; |
|||
parameter real s0_tm = 0.5 from [0:1]; |
|||
parameter real dfreq_te = 100e12 from [0:inf); |
|||
parameter real dfreq_tm = 100e12 from [0:inf); |
|||
parameter real ds_te = 0; |
|||
parameter real ds_tm = 0; |
|||
parameter real scat_loss_te = 0 from [0:inf); |
|||
parameter real scat_loss_tm = 0 from [0:inf); |
|||
|
|||
|
|||
input Ipow,Iphase,Ilam; |
|||
output Opow1,Ophase1,Olam1,Opow2,Ophase2,Olam2; |
|||
electrical Ipow,Iphase,Ilam,Opow1,Ophase1,Olam1,Opow2,Ophase2,Olam2; |
|||
|
|||
real freq,iph; |
|||
real eeir,eeii,emir,emii; |
|||
real alpha_te,alpha_tm; |
|||
real beta_ter,beta_tei,beta_tmr,beta_tmi; |
|||
real s_te,s_tm; |
|||
real t11r,t11i,t12r,t12i,t21r,t21i,t22r,t22i,t31r,t31i,t32r,t32i,t41r,t41i,t42r,t42i; |
|||
real o1er,o1ei,o1mr,o1mi,o2er,o2ei,o2mr,o2mi; |
|||
|
|||
analog begin |
|||
freq=`P_C/V(Ilam); |
|||
iph=V(Iphase)/360.0*2*`M_PI; |
|||
if (modespec == 1) begin |
|||
eeir=sqrt(V(Ipow))*cos(iph); |
|||
eeii=sqrt(V(Ipow))*sin(iph); |
|||
emir=0; |
|||
emii=0; |
|||
end |
|||
else if (modespec == 2) begin |
|||
eeir=0; |
|||
eeii=0; |
|||
emir=sqrt(V(Ipow))*cos(iph); |
|||
emii=sqrt(V(Ipow))*sin(iph); |
|||
end |
|||
|
|||
if (alpha_use_dBm == 1) begin |
|||
alpha_te=0.1*ln(10)*attenu_te; |
|||
alpha_tm=0.1*ln(10)*attenu_tm; |
|||
end |
|||
else begin |
|||
alpha_te=attenu_te; |
|||
alpha_tm=attenu_tm; |
|||
end |
|||
|
|||
beta_ter=2*`M_PI*reffreq/`P_C*neff_te+2*`M_PI/`P_C*n_gv_te*(freq-reffreq)-`M_PI*`P_C*disper_te/pow(reffreq,2)*pow(freq-reffreq,2); |
|||
beta_tei=-alpha_te/2; |
|||
beta_tmr=2*`M_PI*reffreq/`P_C*neff_tm+2*`M_PI/`P_C*n_gv_tm*(freq-reffreq)-`M_PI*`P_C*disper_tm/pow(reffreq,2)*pow(freq-reffreq,2); |
|||
beta_tmi=-alpha_tm/2; |
|||
|
|||
if (freq < design_freq-dfreq_te/2) begin |
|||
s_te=s0_te-dfreq_te/2.0*ds_te; |
|||
end |
|||
else if (freq > design_freq+dfreq_te/2) begin |
|||
s_te=s0_te+dfreq_te/2.0*ds_te; |
|||
end |
|||
else begin |
|||
s_te=s0_te+(freq-design_freq)*ds_te; |
|||
end |
|||
if (freq < design_freq-dfreq_tm/2) begin |
|||
s_tm=s0_tm-dfreq_tm/2.0*ds_tm; |
|||
end |
|||
else if (freq > design_freq+dfreq_tm/2) begin |
|||
s_tm=s0_tm+dfreq_tm/2.0*ds_tm; |
|||
end |
|||
else begin |
|||
s_tm=s0_tm+(freq-design_freq)*ds_tm; |
|||
end |
|||
|
|||
t11r=pow(10,-scat_loss_te/10)*sqrt(s_te)*exp(-beta_tei*(l_str+l_up))*cos(-beta_ter*(l_str+l_up)); |
|||
t11i=pow(10,-scat_loss_te/10)*sqrt(s_te)*exp(-beta_tei*(l_str+l_up))*sin(-beta_ter*(l_str+l_up)); |
|||
t12r=0; |
|||
t12i=0; |
|||
t21r=0; |
|||
t21i=0; |
|||
t22r=pow(10,-scat_loss_tm/10)*sqrt(s_tm)*exp(-beta_tmi*(l_str+l_up))*cos(-beta_tmr*(l_str+l_up)); |
|||
t22i=pow(10,-scat_loss_tm/10)*sqrt(s_tm)*exp(-beta_tmi*(l_str+l_up))*sin(-beta_tmr*(l_str+l_up)); |
|||
t31r=pow(10,-scat_loss_te/10)*sqrt(1-s_te)*exp(-beta_tei*(l_str+l_down))*cos(-beta_ter*(l_str+l_down)); |
|||
t31i=pow(10,-scat_loss_te/10)*sqrt(1-s_te)*exp(-beta_tei*(l_str+l_down))*sin(-beta_ter*(l_str+l_down)); |
|||
t32r=0; |
|||
t32i=0; |
|||
t41r=0; |
|||
t41i=0; |
|||
t42r=pow(10,-scat_loss_tm/10)*sqrt(1-s_tm)*exp(-beta_tmi*(l_str+l_down))*cos(-beta_tmr*(l_str+l_down)); |
|||
t42i=pow(10,-scat_loss_tm/10)*sqrt(1-s_tm)*exp(-beta_tmi*(l_str+l_down))*sin(-beta_tmr*(l_str+l_down)); |
|||
|
|||
o1er=t11r*eeir-t11i*eeii+t12r*emir-t12i*emii; |
|||
o1ei=t11r*eeii+t11i*eeir+t12r*emii+t12i*emir; |
|||
o1mr=t21r*eeir-t21i*eeii+t22r*emir-t22i*emii; |
|||
o1mi=t21r*eeii+t21i*eeir+t22r*emii+t22i*emir; |
|||
o2er=t31r*eeir-t31i*eeii+t32r*emir-t32i*emii; |
|||
o2ei=t31r*eeii+t31i*eeir+t32r*emii+t32i*emir; |
|||
o2mr=t41r*eeir-t41i*eeii+t42r*emir-t42i*emii; |
|||
o2mi=t41r*eeii+t41i*eeir+t42r*emii+t42i*emir; |
|||
|
|||
|
|||
V(Olam1) <+ V(Ilam); |
|||
V(Olam2) <+ V(Ilam); |
|||
if (modespec == 1) begin |
|||
V(Opow1) <+ pow(o1er,2)+pow(o1ei,2); |
|||
V(Ophase1) <+ atan2(o1ei,o1er)*360.0/(2*`M_PI); |
|||
V(Opow2) <+ pow(o2er,2)+pow(o2ei,2); |
|||
V(Ophase2) <+ atan2(o2ei,o2er)*360.0/(2*`M_PI); |
|||
end |
|||
else if (modespec == 2) begin |
|||
V(Opow1) <+ pow(o1mr,2)+pow(o1mi,2); |
|||
V(Ophase1) <+ atan2(o1mi,o1mr)*360.0/(2*`M_PI); |
|||
V(Opow2) <+ pow(o2mr,2)+pow(o2mi,2); |
|||
V(Ophase2) <+ atan2(o2mi,o2mr)*360.0/(2*`M_PI); |
|||
end |
|||
end |
|||
|
|||
endmodule |
@ -0,0 +1,150 @@ |
|||
//VerilogA for passive,wgarc,veriloga |
|||
|
|||
`include "constants.vams" |
|||
`include "disciplines.vams" |
|||
|
|||
module wgarc(Ipow,Iphase,Ilam,Opow,Ophase,Olam); |
|||
parameter integer modespec = 1 from [1:2]; |
|||
parameter integer alpha_use_dBm = 1 from [0:1]; |
|||
parameter real reffreq = 193.1e12 from (0:inf); |
|||
parameter real neff_te_0 = 2.6 from (0:inf); |
|||
parameter real neff_tm_0 = 2.6 from (0:inf); |
|||
parameter real n_gv_te = 4.2 from (0:inf); |
|||
parameter real n_gv_tm = 4.2 from (0:inf); |
|||
parameter real disper_te = 0; |
|||
parameter real disper_tm = 0; |
|||
parameter real attenu_te = 0 from [0:inf); |
|||
parameter real attenu_tm = 0 from [0:inf); |
|||
parameter real phasedelay_te = 0; |
|||
parameter real phasedelay_tm = 0; |
|||
parameter real coupling_tem = 0; |
|||
parameter real redius = 1e-3 from (0:inf); |
|||
parameter real angle = 90 from (0:inf); |
|||
parameter real kn_te = 0; |
|||
parameter real kn_tm = 0; |
|||
parameter real A_te = 0 from [0:inf); |
|||
parameter real A_tm = 0 from [0:inf); |
|||
parameter real B_te = 0 from [0:inf); |
|||
parameter real B_tm = 0 from [0:inf); |
|||
|
|||
input Ipow,Iphase,Ilam; |
|||
output Opow,Ophase,Olam; |
|||
electrical Ipow,Iphase,Ilam,Opow,Ophase,Olam; |
|||
|
|||
real eeir,eeii,emir,emii; |
|||
real eeor,eeoi,emor,emoi; |
|||
real t11r,t11i,t12r,t12i,t21r,t21i,t22r,t22i; |
|||
real beta_ter,beta_tei,beta_tmr,beta_tmi,beta_avr,beta_avi,beta_dvr,beta_dvi; |
|||
real delta,trandelta,cdd,bddr,bddi; |
|||
real rfront,ifrontch,t11r1,t1r2,t11i1,t1i2,t22r1,t2r2,t22i1,t2i2; |
|||
real alpha_te0,alpha_tm0; |
|||
real dn_te,dn_tm,dalpha_te,dalpha_tm; |
|||
real alpha_te,alpha_tm,neff_te,neff_tm; |
|||
real length=redius*angle/180*`M_PI; |
|||
real phasedelay_te_u=phasedelay_te/360.0*2*`M_PI; |
|||
real phasedelay_tm_u=phasedelay_tm/360.0*2*`M_PI; |
|||
real freq; |
|||
real iph; |
|||
|
|||
analog begin |
|||
freq=`P_C/V(Ilam); |
|||
iph=V(Iphase)/360.0*2*`M_PI; |
|||
if (modespec == 1) begin |
|||
eeir=sqrt(V(Ipow))*cos(iph); |
|||
eeii=sqrt(V(Ipow))*sin(iph); |
|||
emir=0; |
|||
emii=0; |
|||
end |
|||
else if (modespec == 2) begin |
|||
eeir=0; |
|||
eeii=0; |
|||
emir=sqrt(V(Ipow))*cos(iph); |
|||
emii=sqrt(V(Ipow))*sin(iph); |
|||
end |
|||
|
|||
alpha_te0=0.1*ln(10)*attenu_te; |
|||
alpha_tm0=0.1*ln(10)*attenu_tm; |
|||
dn_te=kn_te/pow(redius,2); |
|||
dn_tm=kn_tm/pow(redius,2); |
|||
dalpha_te=A_te/sqrt(redius)*exp(-B_te*redius); |
|||
dalpha_tm=A_tm/sqrt(redius)*exp(-B_tm*redius); |
|||
|
|||
neff_te=neff_te_0+dn_te; |
|||
neff_tm=neff_tm_0+dn_tm; |
|||
alpha_te=alpha_te0+dalpha_te; |
|||
alpha_tm=alpha_tm0+dalpha_tm; |
|||
|
|||
if (alpha_use_dBm == 1) begin |
|||
alpha_te=0.1*ln(10)*alpha_te; |
|||
alpha_tm=0.1*ln(10)*alpha_tm; |
|||
end |
|||
|
|||
beta_ter=2*`M_PI*reffreq/`P_C*neff_te+2*`M_PI/`P_C*n_gv_te*(freq-reffreq)-`M_PI*`P_C*disper_te/pow(reffreq,2)*pow(freq-reffreq,2); |
|||
beta_tei=-alpha_te/2; |
|||
beta_tmr=2*`M_PI*reffreq/`P_C*neff_tm+2*`M_PI/`P_C*n_gv_tm*(freq-reffreq)-`M_PI*`P_C*disper_tm/pow(reffreq,2)*pow(freq-reffreq,2); |
|||
beta_tmi=-alpha_tm/2; |
|||
if (coupling_tem == 0) begin |
|||
rfront=exp(beta_tei*length); |
|||
t11r1=cos(phasedelay_te_u-beta_ter*length); |
|||
t11i1=sin(phasedelay_te_u-beta_ter*length); |
|||
t22r1=cos(phasedelay_tm_u-beta_tmr*length); |
|||
t22i1=sin(phasedelay_tm_u-beta_tmr*length); |
|||
|
|||
t11r=rfront*t11r1; |
|||
t11i=rfront*t11i1; |
|||
t12r=0; |
|||
t12i=0; |
|||
t21r=0; |
|||
t21i=0; |
|||
t22r=rfront*t22r1; |
|||
t22i=rfront*t22i1; |
|||
end |
|||
else begin |
|||
beta_avr=(beta_ter+beta_tmr)/2; |
|||
beta_avi=(beta_tmi+beta_tmi)/2; |
|||
beta_dvr=(beta_ter-beta_tmr)/2; |
|||
beta_dvi=(beta_tmi-beta_tmi)/2; |
|||
delta=sqrt(beta_dvr*beta_dvr+beta_dvi*beta_dvi+coupling_tem*coupling_tem); |
|||
trandelta=delta*length; |
|||
cdd=coupling_tem/delta; |
|||
bddr=beta_dvr/delta; |
|||
bddi=beta_dvi/delta; |
|||
|
|||
rfront=exp(beta_avi*length); |
|||
t11r1=cos(trandelta)+bddi*sin(trandelta); |
|||
t11i1=-bddr*sin(trandelta); |
|||
t1r2=cos(phasedelay_te_u-beta_avr*length); |
|||
t1i2=sin(phasedelay_te_u-beta_avr*length); |
|||
ifrontch=-cdd*sin(trandelta); |
|||
t2r2=cos(phasedelay_tm_u-beta_avr*length); |
|||
t2i2=sin(phasedelay_tm_u-beta_avr*length); |
|||
t22r1=cos(trandelta)-bddi*sin(trandelta); |
|||
t22i1=bddr*sin(trandelta); |
|||
|
|||
t11r=rfront*(t11r1*t1r2-t11i1*t1i2); |
|||
t11i=rfront*(t11r1*t1i2+t11i1*t1r2); |
|||
t12r=rfront*ifrontch*t1i2; |
|||
t12i=rfront*ifrontch*t1r2; |
|||
t21r=rfront*ifrontch*t2i2; |
|||
t21i=rfront*ifrontch*t2r2; |
|||
t22r=rfront*(t22r1*t2r2-t22i1*t2i2); |
|||
t22i=rfront*(t22r1*t2i2+t22i1*t2r2); |
|||
end |
|||
|
|||
eeor=t11r*eeir-t11i*eeii+t12r*emir-t12i*emii; |
|||
eeoi=t11r*eeii+t11i*eeir+t12r*emii+t12i*emir; |
|||
emor=t21r*eeir-t21i*eeii+t22r*emir-t22i*emii; |
|||
emoi=t21r*eeii+t21i*eeir+t22r*emii+t22i*emir; |
|||
|
|||
V(Olam) <+ V(Ilam); |
|||
if (modespec == 1) begin |
|||
V(Opow) <+ eeor*eeor+eeoi*eeoi; |
|||
V(Ophase) <+ atan2(eeoi,eeor)*360.0/(2*`M_PI); |
|||
end |
|||
else if (modespec == 2) begin |
|||
V(Opow) <+ emor*emor+emoi*emoi; |
|||
V(Ophase) <+ atan2(emoi,emor)*360.0/(2*`M_PI); |
|||
end |
|||
end |
|||
|
|||
endmodule |
@ -0,0 +1,136 @@ |
|||
//VerilogA for passive,wgstrmodecp,veriloga |
|||
|
|||
`include "constants.vams" |
|||
`include "disciplines.vams" |
|||
|
|||
module wgstrmodecp(Ipow,Iphase,Ilam,Opow,Ophase,Olam); |
|||
parameter integer modespec = 1 from [1:2]; |
|||
parameter integer alpha_use_dBm = 1 from [0:1]; |
|||
parameter real reffreq = 193.1e12 from (0:inf); |
|||
parameter real length = 1e-3 from [0:inf); |
|||
parameter real neff_te = 2.6 from (0:inf); |
|||
parameter real neff_tm = 2.6 from (0:inf); |
|||
parameter real n_gv_te = 4.2 from (0:inf); |
|||
parameter real n_gv_tm = 4.2 from (0:inf); |
|||
parameter real disper_te = 0; |
|||
parameter real disper_tm = 0; |
|||
parameter real attenu_te = 0 from [0:inf);//attenuation in dB/m |
|||
parameter real attenu_tm = 0 from [0:inf);//attenuation in dB/m |
|||
parameter real phasedelay_te = 0; |
|||
parameter real phasedelay_tm = 0; |
|||
parameter real coupling_tem = 0; |
|||
|
|||
input Ipow,Iphase,Ilam; |
|||
output Opow,Ophase,Olam; |
|||
electrical Ipow,Iphase,Ilam,Opow,Ophase,Olam; |
|||
|
|||
real eeir,eeii,emir,emii; |
|||
real eeor,eeoi,emor,emoi; |
|||
real t11r,t11i,t12r,t12i,t21r,t21i,t22r,t22i; |
|||
real beta_ter,beta_tei,beta_tmr,beta_tmi,beta_avr,beta_avi,beta_dvr,beta_dvi; |
|||
real rfront_te,rfront_tm,t11r1,t11i1,t1i2,t22r1,t22i1; |
|||
real c1r,c1i,a,t,deltar,deltai,thetar,thetai,sr,si,rr,ri,z1r,z1i,z21r,z21i,z2r,z2i,z3r,z3i; |
|||
real c11r,c11i,c12r,c12i,c21r,c21i,c22r,c22i,c31r,c31i; |
|||
real phasedelay_te_u=phasedelay_te/360.0*2*`M_PI; |
|||
real phasedelay_tm_u=phasedelay_tm/360.0*2*`M_PI; |
|||
real alpha_te,alpha_tm; |
|||
real freq; |
|||
real iph; |
|||
|
|||
analog begin |
|||
freq=`P_C/V(Ilam); |
|||
iph=V(Iphase)/360.0*2*`M_PI; |
|||
if (modespec == 1) begin |
|||
eeir=sqrt(V(Ipow))*cos(iph); |
|||
eeii=sqrt(V(Ipow))*sin(iph); |
|||
emir=0; |
|||
emii=0; |
|||
end |
|||
else if (modespec == 2) begin |
|||
eeir=0; |
|||
eeii=0; |
|||
emir=sqrt(V(Ipow))*cos(iph); |
|||
emii=sqrt(V(Ipow))*sin(iph); |
|||
end |
|||
|
|||
if (alpha_use_dBm == 1) begin |
|||
alpha_te=0.1*ln(10)*attenu_te; |
|||
alpha_tm=0.1*ln(10)*attenu_tm; |
|||
end |
|||
else begin |
|||
alpha_te=attenu_te; |
|||
alpha_tm=attenu_tm; |
|||
end |
|||
|
|||
beta_ter=2*`M_PI*reffreq/`P_C*neff_te+2*`M_PI/`P_C*n_gv_te*(freq-reffreq)-`M_PI*`P_C*disper_te/pow(reffreq,2)*pow(freq-reffreq,2); |
|||
beta_tei=-alpha_te/2; |
|||
beta_tmr=2*`M_PI*reffreq/`P_C*neff_tm+2*`M_PI/`P_C*n_gv_tm*(freq-reffreq)-`M_PI*`P_C*disper_tm/pow(reffreq,2)*pow(freq-reffreq,2); |
|||
beta_tmi=-alpha_tm/2; |
|||
|
|||
beta_avr=(beta_ter+beta_tmr)/2; |
|||
beta_avi=(beta_tmi+beta_tmi)/2; |
|||
beta_dvr=(beta_ter-beta_tmr)/2; |
|||
beta_dvi=(beta_tmi-beta_tmi)/2; |
|||
c1r=beta_dvr*beta_dvr+beta_dvi*beta_dvi+coupling_tem*coupling_tem; |
|||
c1i=2*beta_dvr*beta_dvi; |
|||
a=sqrt(pow(c1r,2)+pow(c1i,2)); |
|||
t=atan2(c1i,c1r); |
|||
deltar=sqrt(a)*cos(t/2); |
|||
deltai=sqrt(a)*sin(t/2); |
|||
thetar=deltar*length; |
|||
thetai=deltai*length; |
|||
sr=coupling_tem*deltar/(deltar*deltar+deltai*deltai); |
|||
si=-coupling_tem*deltai/(deltar*deltar+deltai*deltai); |
|||
rr=(beta_dvr*deltar+beta_dvi*deltai)/(deltar*deltar+deltai*deltai); |
|||
ri=(-beta_dvr*deltai+beta_dvi*deltar)/(deltar*deltar+deltai*deltai); |
|||
|
|||
//cos(theta) |
|||
z1r=(exp(-thetai)+exp(thetai))/2.0*cos(thetar); |
|||
z1i=(exp(-thetai)-exp(thetai))/2.0*sin(thetar); |
|||
//sin(theta) |
|||
z21r=(exp(thetai)+exp(-thetai))/2.0*sin(thetar); |
|||
z21i=(exp(thetai)-exp(-thetai))/2.0*cos(thetar); |
|||
//R*sin(theta) |
|||
z2r=rr*z21r-ri*z21i; |
|||
z2i=rr*z21i+ri*z21r; |
|||
//S*sin(theta) |
|||
z3r=sr*z21r-si*z21i; |
|||
z3i=sr*z21i+si*z21r; |
|||
|
|||
c11r=z1r+z2i; |
|||
c11i=z1i-z2r; |
|||
c12r=exp(beta_avi*length)*cos(-phasedelay_te_u-beta_avr*length); |
|||
c12i=exp(beta_avi*length)*sin(-phasedelay_te_u-beta_avr*length); |
|||
c21r=z1r-z2i; |
|||
c21i=z1i+z2r; |
|||
c22r=exp(beta_avi*length)*cos(-phasedelay_tm_u-beta_avr*length); |
|||
c22i=exp(beta_avi*length)*sin(-phasedelay_tm_u-beta_avr*length); |
|||
c31r=z3i; |
|||
c31i=-z3r; |
|||
|
|||
t11r=c11r*c12r-c11i*c12i; |
|||
t11i=c11r*c12i+c11i*c12r; |
|||
t12r=c31r*c12r-c31i*c12i; |
|||
t12i=c31r*c12i+c31i*c12r; |
|||
t21r=c31r*c22r-c31i*c22i; |
|||
t21i=c31r*c22i+c31i*c22r; |
|||
t22r=c21r*c22r-c21i*c22i; |
|||
t22i=c21r*c22i+c21i*c22r; |
|||
|
|||
eeor=t11r*eeir-t11i*eeii+t12r*emir-t12i*emii; |
|||
eeoi=t11r*eeii+t11i*eeir+t12r*emii+t12i*emir; |
|||
emor=t21r*eeir-t21i*eeii+t22r*emir-t22i*emii; |
|||
emoi=t21r*eeii+t21i*eeir+t22r*emii+t22i*emir; |
|||
|
|||
V(Olam) <+ V(Ilam); |
|||
if (modespec == 1) begin |
|||
V(Opow) <+ eeor*eeor+eeoi*eeoi; |
|||
V(Ophase) <+ atan2(eeoi,eeor)*360.0/(2*`M_PI); |
|||
end |
|||
else if (modespec == 2) begin |
|||
V(Opow) <+ emor*emor+emoi*emoi; |
|||
V(Ophase) <+ atan2(emoi,emor)*360.0/(2*`M_PI); |
|||
end |
|||
end |
|||
|
|||
endmodule |
@ -0,0 +1,65 @@ |
|||
//VerilogA for passive,wgstroptilen,veriloga |
|||
|
|||
`include "constants.vams" |
|||
`include "disciplines.vams" |
|||
|
|||
module wgstroptilen(Ipow,Iphase,Ilam,Opow,Ophase,Olam); |
|||
parameter integer modespec = 1 from [1:2]; |
|||
parameter real optlength_te = 1e-3 from [0:inf); |
|||
parameter real optlength_tm = 1e-3 from [0:inf); |
|||
parameter real optloss_te = 0 from [0:inf); |
|||
parameter real optloss_tm = 0 from [0:inf); |
|||
parameter real phasedelay_te = 0; |
|||
parameter real phasedelay_tm = 0; |
|||
|
|||
input Ipow,Iphase,Ilam; |
|||
output Opow,Ophase,Olam; |
|||
electrical Ipow,Iphase,Ilam,Opow,Ophase,Olam; |
|||
|
|||
real eeir,eeii,emir,emii; |
|||
real eeor,eeoi,emor,emoi; |
|||
real t11r,t11i,t12r,t12i,t21r,t21i,t22r,t22i; |
|||
real iph; |
|||
|
|||
analog begin |
|||
iph=V(Iphase)/360.0*2*`M_PI; |
|||
if (modespec == 1) begin |
|||
eeir=sqrt(V(Ipow))*cos(iph); |
|||
eeii=sqrt(V(Ipow))*sin(iph); |
|||
emir=0; |
|||
emii=0; |
|||
end |
|||
else if (modespec == 2) begin |
|||
eeir=0; |
|||
eeii=0; |
|||
emir=sqrt(V(Ipow))*cos(iph); |
|||
emii=sqrt(V(Ipow))*sin(iph); |
|||
end |
|||
|
|||
//calc transfer matrix |
|||
t11r=pow(10,-optloss_te/20)*cos(phasedelay_te/360.0*2*`M_PI-2*`M_PI/V(Ilam)*optlength_te); |
|||
t11i=pow(10,-optloss_te/20)*sin(phasedelay_te/360.0*2*`M_PI-2*`M_PI/V(Ilam)*optlength_te); |
|||
t12r=0; |
|||
t12i=0; |
|||
t21r=0; |
|||
t21i=0; |
|||
t22r=pow(10,-optloss_tm/20)*cos(phasedelay_tm/360.0*2*`M_PI-2*`M_PI/V(Ilam)*optlength_tm); |
|||
t22i=pow(10,-optloss_tm/20)*sin(phasedelay_tm/360.0*2*`M_PI-2*`M_PI/V(Ilam)*optlength_tm); |
|||
|
|||
eeor=t11r*eeir-t11i*eeii+t12r*emir-t12i*emii; |
|||
eeoi=t11r*eeii+t11i*eeir+t12r*emii+t12i*emir; |
|||
emor=t21r*eeir-t21i*eeii+t22r*emir-t22i*emii; |
|||
emoi=t21r*eeii+t21i*eeir+t22r*emii+t22i*emir; |
|||
|
|||
V(Olam) <+ V(Ilam); |
|||
if (modespec == 1) begin |
|||
V(Opow) <+ eeor*eeor+eeoi*eeoi; |
|||
V(Ophase) <+ atan2(eeoi,eeor)*360.0/(2*`M_PI); |
|||
end |
|||
else if (modespec == 2) begin |
|||
V(Opow) <+ emor*emor+emoi*emoi; |
|||
V(Ophase) <+ atan2(emoi,emor)*360.0/(2*`M_PI); |
|||
end |
|||
end |
|||
|
|||
endmodule |
@ -0,0 +1,284 @@ |
|||
//VerilogA for passive,xcouplerbasic,veriloga |
|||
|
|||
`include "constants.vams" |
|||
`include "disciplines.vams" |
|||
|
|||
module xcouplerbasic(Ipow1,Iphase1,Ilam1,Ipow2,Iphase2,Ilam2,Opow1,Ophase1,Olam1,Opow2,Ophase2,Olam2); |
|||
parameter integer modespec = 1 from [1:2]; |
|||
parameter integer alpha_use_dBm = 1 from [0:1]; |
|||
parameter real reffreq = 193.1e12 from (0:inf); |
|||
parameter real l_upper = 1e-3 from [0:inf); |
|||
parameter real l_lower = 1e-3 from [0:inf); |
|||
parameter real l_coupler = 392.7e-6 from [0:inf); |
|||
parameter real neff_upper_te = 2.6 from (0:inf); |
|||
parameter real neff_upper_tm = 2.6 from (0:inf); |
|||
parameter real neff_lower_te = 2.6 from (0:inf); |
|||
parameter real neff_lower_tm = 2.6 from (0:inf); |
|||
parameter real n_gv_upper_te = 4.2 from (0:inf); |
|||
parameter real n_gv_upper_tm = 4.2 from (0:inf); |
|||
parameter real n_gv_lower_te = 4.2 from (0:inf); |
|||
parameter real n_gv_lower_tm = 4.2 from (0:inf); |
|||
parameter real disper_upper_te = 0 from (-inf:inf); |
|||
parameter real disper_upper_tm = 0 from (-inf:inf); |
|||
parameter real disper_lower_te = 0 from (-inf:inf); |
|||
parameter real disper_lower_tm = 0 from (-inf:inf); |
|||
parameter real attenu_upper_te = 0 from [0:inf); |
|||
parameter real attenu_upper_tm = 0 from [0:inf); |
|||
parameter real attenu_lower_te = 0 from [0:inf); |
|||
parameter real attenu_lower_tm = 0 from [0:inf); |
|||
parameter real coupling_te = 2000 from (-inf:inf); |
|||
parameter real coupling_tm = 2000 from (-inf:inf); |
|||
|
|||
input Ipow1,Iphase1,Ilam1,Ipow2,Iphase2,Ilam2; |
|||
output Opow1,Ophase1,Olam1,Opow2,Ophase2,Olam2; |
|||
electrical Ipow1,Iphase1,Ilam1,Ipow2,Iphase2,Ilam2,Opow1,Ophase1,Olam1,Opow2,Ophase2,Olam2; |
|||
|
|||
real eeir1,eeii1,emir1,emii1; |
|||
real eeir2,eeii2,emir2,emii2; |
|||
real eeor1,eeoi1,emor1,emoi1; |
|||
real eeor2,eeoi2,emor2,emoi2; |
|||
|
|||
real r_sqrt_te,i_sqrt_te,a_sqrt_te,t_sqrt_te; |
|||
real r_sqrt_tm,i_sqrt_tm,a_sqrt_tm,t_sqrt_tm; |
|||
real r_clow; |
|||
real z1r_te,z1i_te,z21r_te,z21i_te,z2r_te,z2i_te,z3r_te,z3i_te; |
|||
real z1r_tm,z1i_tm,z21r_tm,z21i_tm,z2r_tm,z2i_tm,z3r_tm,z3i_tm; |
|||
real c11r_te,c11i_te,c12r_te,c12i_te,c21r_te,c21i_te,c22r_te,c22i_te,c31r_te,c31i_te,c32r_te,c32i_te; |
|||
real c11r_tm,c11i_tm,c12r_tm,c12i_tm,c21r_tm,c21i_tm,c22r_tm,c22i_tm,c31r_tm,c31i_tm,c32r_tm,c32i_tm; |
|||
real c1r_te,c1i_te,c2r_te,c2i_te,c3r_te,c3i_te; |
|||
real c1r_tm,c1i_tm,c2r_tm,c2i_tm,c3r_tm,c3i_tm; |
|||
real t11r,t11i,t12r,t12i,t13r,t13i,t14r,t14i,t21r,t21i,t22r,t22i,t23r,t23i,t24r,t24i; |
|||
real t31r,t31i,t32r,t32i,t33r,t33i,t34r,t34i,t41r,t41i,t42r,t42i,t43r,t43i,t44r,t44i; |
|||
|
|||
real alpha_upper_te,alpha_upper_tm,alpha_lower_te,alpha_lower_tm; |
|||
real beta_upper_ter,beta_upper_tei,beta_upper_tmr,beta_upper_tmi,beta_lower_ter,beta_lower_tei,beta_lower_tmr,beta_lower_tmi; |
|||
real beta_avg_ter,beta_avg_tei,beta_avg_tmr,beta_avg_tmi; |
|||
real beta_diff_ter,beta_diff_tei,beta_diff_tmr,beta_diff_tmi; |
|||
real delta_ter,delta_tei,delta_tmr,delta_tmi; |
|||
real theta_ter,theta_tei,theta_tmr,theta_tmi; |
|||
real r_ter,r_tei,r_tmr,r_tmi; |
|||
real s_ter,s_tei,s_tmr,s_tmi; |
|||
real freq_upper,freq_lower; |
|||
real iph_upper,iph_lower; |
|||
|
|||
analog begin |
|||
iph_upper=V(Iphase1)/360.0*2*`M_PI; |
|||
iph_lower=V(Iphase2)/360.0*2*`M_PI; |
|||
if (V(Ilam1)==0) |
|||
freq_upper=`P_C/V(Ilam2); |
|||
else |
|||
freq_upper=`P_C/V(Ilam1); |
|||
if (V(Ilam2)==0) |
|||
freq_lower=`P_C/V(Ilam1); |
|||
else |
|||
freq_lower=`P_C/V(Ilam2); |
|||
if (modespec ==1) begin |
|||
eeir1=sqrt(V(Ipow1))*cos(iph_upper); |
|||
eeii1=sqrt(V(Ipow1))*sin(iph_upper); |
|||
emir1=0; |
|||
emii1=0; |
|||
eeir2=sqrt(V(Ipow2))*cos(iph_lower); |
|||
eeii2=sqrt(V(Ipow2))*sin(iph_lower); |
|||
emir2=0; |
|||
emii2=0; |
|||
end |
|||
else if (modespec ==2) begin |
|||
eeir1=0; |
|||
eeii1=0; |
|||
emir1=sqrt(V(Ipow1))*cos(iph_upper); |
|||
emii1=sqrt(V(Ipow1))*sin(iph_upper); |
|||
eeir2=0; |
|||
eeii2=0; |
|||
emir2=sqrt(V(Ipow2))*cos(iph_lower); |
|||
emii2=sqrt(V(Ipow2))*sin(iph_lower); |
|||
end |
|||
|
|||
if (alpha_use_dBm == 1) begin |
|||
alpha_upper_te=0.1*ln(10)*attenu_upper_te; |
|||
alpha_upper_tm=0.1*ln(10)*attenu_upper_tm; |
|||
alpha_lower_te=0.1*ln(10)*attenu_lower_te; |
|||
alpha_lower_tm=0.1*ln(10)*attenu_lower_tm; |
|||
end |
|||
else begin |
|||
alpha_upper_te=attenu_upper_te; |
|||
alpha_upper_tm=attenu_upper_tm; |
|||
alpha_lower_te=attenu_lower_te; |
|||
alpha_lower_tm=attenu_lower_tm; |
|||
end |
|||
|
|||
beta_upper_ter=2.0*`M_PI*reffreq/`P_C*neff_upper_te+2*`M_PI/`P_C*n_gv_upper_te*(freq_upper-reffreq)-`M_PI*`P_C*disper_upper_te/pow(reffreq,2)*pow(freq_upper-reffreq,2); |
|||
beta_upper_tei=-0.5*alpha_upper_te; |
|||
beta_upper_tmr=2.0*`M_PI*reffreq/`P_C*neff_upper_tm+2*`M_PI/`P_C*n_gv_upper_tm*(freq_upper-reffreq)-`M_PI*`P_C*disper_upper_tm/pow(reffreq,2)*pow(freq_upper-reffreq,2); |
|||
beta_upper_tmi=-0.5*alpha_upper_tm; |
|||
beta_lower_ter=2.0*`M_PI*reffreq/`P_C*neff_lower_te+2*`M_PI/`P_C*n_gv_lower_te*(freq_lower-reffreq)-`M_PI*`P_C*disper_lower_te/pow(reffreq,2)*pow(freq_lower-reffreq,2); |
|||
beta_lower_tei=-0.5*alpha_lower_te; |
|||
beta_lower_tmr=2.0*`M_PI*reffreq/`P_C*neff_lower_tm+2*`M_PI/`P_C*n_gv_lower_tm*(freq_lower-reffreq)-`M_PI*`P_C*disper_lower_tm/pow(reffreq,2)*pow(freq_lower-reffreq,2); |
|||
beta_lower_tmi=-0.5*alpha_lower_tm; |
|||
|
|||
beta_avg_ter=(beta_upper_ter+beta_lower_ter)/2.0; |
|||
beta_avg_tei=(beta_upper_tei+beta_lower_tei)/2.0; |
|||
beta_avg_tmr=(beta_upper_tmr+beta_lower_tmr)/2.0; |
|||
beta_avg_tmi=(beta_upper_tmi+beta_lower_tmi)/2.0; |
|||
beta_diff_ter=(beta_upper_ter-beta_lower_ter)/2.0; |
|||
beta_diff_tei=(beta_upper_tei-beta_lower_tei)/2.0; |
|||
beta_diff_tmr=(beta_upper_tmr-beta_lower_tmr)/2.0; |
|||
beta_diff_tmi=(beta_upper_tmi-beta_lower_tmi)/2.0; |
|||
|
|||
r_sqrt_te=pow(beta_diff_ter,2)+pow(beta_diff_tei,2)+pow(coupling_te,2); |
|||
i_sqrt_te=2.0*beta_diff_ter*beta_diff_tei; |
|||
a_sqrt_te=sqrt(pow(r_sqrt_te,2)+pow(i_sqrt_te,2)); |
|||
t_sqrt_te=atan2(i_sqrt_te,r_sqrt_te); |
|||
delta_ter=sqrt(a_sqrt_te)*cos(t_sqrt_te/2); |
|||
delta_tei=sqrt(a_sqrt_te)*sin(t_sqrt_te/2); |
|||
r_sqrt_tm=pow(beta_diff_tmr,2)+pow(beta_diff_tmi,2)+pow(coupling_tm,2); |
|||
i_sqrt_tm=2.0*beta_diff_tmr*beta_diff_tmi; |
|||
a_sqrt_tm=sqrt(pow(r_sqrt_tm,2)+pow(i_sqrt_tm,2)); |
|||
t_sqrt_tm=atan2(i_sqrt_tm,r_sqrt_tm); |
|||
delta_tmr=sqrt(a_sqrt_tm)*cos(t_sqrt_tm/2); |
|||
delta_tmi=sqrt(a_sqrt_tm)*sin(t_sqrt_tm/2); |
|||
|
|||
theta_ter=delta_ter*l_coupler; |
|||
theta_tei=delta_tei*l_coupler; |
|||
theta_tmr=delta_tmr*l_coupler; |
|||
theta_tmi=delta_tmi*l_coupler; |
|||
|
|||
r_clow=pow(delta_ter,2)+pow(delta_tei,2); |
|||
r_ter=(beta_diff_ter*delta_ter+beta_diff_tei*delta_tei)/r_clow; |
|||
r_tei=(-beta_diff_ter*delta_tei+beta_diff_tei*delta_ter)/r_clow; |
|||
r_tmr=(beta_diff_tmr*delta_tmr+beta_diff_tmi*delta_tmi)/r_clow; |
|||
r_tmi=(-beta_diff_tmr*delta_tmi+beta_diff_tmi*delta_tmr)/r_clow; |
|||
|
|||
s_ter=coupling_te*delta_ter/(pow(delta_ter,2)+pow(delta_tei,2)); |
|||
s_tei=-coupling_te*delta_tei/(pow(delta_ter,2)+pow(delta_tei,2)); |
|||
s_tmr=coupling_tm*delta_tmr/(pow(delta_tmr,2)+pow(delta_tmi,2)); |
|||
s_tmi=-coupling_tm*delta_tmi/(pow(delta_tmr,2)+pow(delta_tmi,2)); |
|||
|
|||
//cos(theta_te) |
|||
z1r_te=(exp(-theta_tei)+exp(theta_tei))/2.0*cos(theta_ter); |
|||
z1i_te=(exp(-theta_tei)-exp(theta_tei))/2.0*sin(theta_ter); |
|||
//sin(theta_te) |
|||
z21r_te=(exp(theta_tei)+exp(-theta_tei))/2.0*sin(theta_ter); |
|||
z21i_te=(exp(theta_tei)-exp(-theta_tei))/2.0*cos(theta_ter); |
|||
//R*sin(theta_te) |
|||
z2r_te=r_ter*z21r_te-r_tei*z21i_te; |
|||
z2i_te=r_ter*z21i_te+r_tei*z21r_te; |
|||
//S*sin(theta_te) |
|||
z3r_te=s_ter*z21r_te-s_tei*z21i_te; |
|||
z3i_te=s_ter*z21i_te+s_tei*z21r_te; |
|||
//cos(theta_tm) |
|||
z1r_tm=(exp(-theta_tmi)+exp(theta_tmi))/2.0*cos(theta_tmr); |
|||
z1i_tm=(exp(-theta_tmi)-exp(theta_tmi))/2.0*sin(theta_tmr); |
|||
//sin(theta_tm) |
|||
z21r_tm=(exp(theta_tmi)+exp(-theta_tmi))/2.0*sin(theta_tmr); |
|||
z21i_tm=(exp(theta_tmi)-exp(-theta_tmi))/2.0*cos(theta_tmr); |
|||
//R*sin(theta_tm) |
|||
z2r_tm=r_tmr*z21r_tm-r_tmi*z21i_tm; |
|||
z2i_tm=r_tmr*z21i_tm+r_tmi*z21r_tm; |
|||
//S*sin(theta_tm) |
|||
z3r_tm=s_tmr*z21r_tm-s_tmi*z21i_tm; |
|||
z3i_tm=s_tmr*z21i_tm+s_tmi*z21r_tm; |
|||
|
|||
c11r_te=z1r_te+z2i_te; |
|||
c11i_te=z1i_te-z2r_te; |
|||
c12r_te=exp(beta_avg_tei*l_coupler+beta_upper_tei*(l_upper-l_coupler))*cos(-beta_avg_ter*l_coupler-beta_upper_ter*(l_upper-l_coupler)); |
|||
c12i_te=exp(beta_avg_tei*l_coupler+beta_upper_tei*(l_upper-l_coupler))*sin(-beta_avg_ter*l_coupler-beta_upper_ter*(l_upper-l_coupler)); |
|||
c21r_te=z1r_te-z2i_te; |
|||
c21i_te=z1i_te+z2r_te; |
|||
c22r_te=exp(beta_avg_tei*l_coupler+beta_lower_tei*(l_lower-l_coupler))*cos(-beta_avg_ter*l_coupler-beta_lower_ter*(l_lower-l_coupler)); |
|||
c22i_te=exp(beta_avg_tei*l_coupler+beta_lower_tei*(l_lower-l_coupler))*sin(-beta_avg_ter*l_coupler-beta_lower_ter*(l_lower-l_coupler)); |
|||
c31r_te=z3i_te; |
|||
c31i_te=-z3r_te; |
|||
c32r_te=exp(0.5*(beta_upper_tei*l_upper+beta_lower_tei*l_lower))*cos(-0.5*(beta_upper_ter*l_upper+beta_lower_ter*l_lower)); |
|||
c32i_te=exp(0.5*(beta_upper_tei*l_upper+beta_lower_tei*l_lower))*sin(-0.5*(beta_upper_ter*l_upper+beta_lower_ter*l_lower)); |
|||
c11r_tm=z1r_tm+z2i_tm; |
|||
c11i_tm=z1i_tm-z2r_tm; |
|||
c12r_tm=exp(beta_avg_tmi*l_coupler+beta_upper_tmi*(l_upper-l_coupler))*cos(-beta_avg_tmr*l_coupler-beta_upper_tmr*(l_upper-l_coupler)); |
|||
c12i_tm=exp(beta_avg_tmi*l_coupler+beta_upper_tmi*(l_upper-l_coupler))*sin(-beta_avg_tmr*l_coupler-beta_upper_tmr*(l_upper-l_coupler)); |
|||
c21r_tm=z1r_tm-z2i_tm; |
|||
c21i_tm=z1i_tm+z2r_tm; |
|||
c22r_tm=exp(beta_avg_tmi*l_coupler+beta_lower_tmi*(l_lower-l_coupler))*cos(-beta_avg_tmr*l_coupler-beta_lower_tmr*(l_lower-l_coupler)); |
|||
c22i_tm=exp(beta_avg_tmi*l_coupler+beta_lower_tmi*(l_lower-l_coupler))*sin(-beta_avg_tmr*l_coupler-beta_lower_tmr*(l_lower-l_coupler)); |
|||
c31r_tm=z3i_tm; |
|||
c31i_tm=-z3r_tm; |
|||
c32r_tm=exp(0.5*(beta_upper_tmi*l_upper+beta_lower_tmi*l_lower))*cos(-0.5*(beta_upper_tmr*l_upper+beta_lower_tmr*l_lower)); |
|||
c32i_tm=exp(0.5*(beta_upper_tmi*l_upper+beta_lower_tmi*l_lower))*sin(-0.5*(beta_upper_tmr*l_upper+beta_lower_tmr*l_lower)); |
|||
|
|||
c1r_te=c11r_te*c12r_te-c11i_te*c12i_te; |
|||
c1i_te=c11r_te*c12i_te+c11i_te*c12r_te; |
|||
c2r_te=c21r_te*c22r_te-c21i_te*c22i_te; |
|||
c2i_te=c21r_te*c22i_te+c21i_te*c22r_te; |
|||
c3r_te=c31r_te*c32r_te-c31i_te*c32i_te; |
|||
c3i_te=c31r_te*c32i_te+c31i_te*c32r_te; |
|||
c1r_tm=c11r_tm*c12r_tm-c11i_tm*c12i_tm; |
|||
c1i_tm=c11r_tm*c12i_tm+c11i_tm*c12r_tm; |
|||
c2r_tm=c21r_tm*c22r_tm-c21i_tm*c22i_tm; |
|||
c2i_tm=c21r_tm*c22i_tm+c21i_tm*c22r_tm; |
|||
c3r_tm=c31r_tm*c32r_tm-c31i_tm*c32i_tm; |
|||
c3i_tm=c31r_tm*c32i_tm+c31i_tm*c32r_tm; |
|||
|
|||
t11r=c1r_te; |
|||
t11i=c1i_te; |
|||
t12r=0; |
|||
t12i=0; |
|||
t13r=c3r_te; |
|||
t13i=c3i_te; |
|||
t14r=0; |
|||
t14i=0; |
|||
t21r=0; |
|||
t21i=0; |
|||
t22r=c1r_tm; |
|||
t22i=c1i_tm; |
|||
t23r=0; |
|||
t23i=0; |
|||
t24r=c3r_tm; |
|||
t24i=c3i_tm; |
|||
t31r=c3r_te; |
|||
t31i=c3i_te; |
|||
t32r=0; |
|||
t32i=0; |
|||
t33r=c2r_te; |
|||
t33i=c2i_te; |
|||
t34r=0; |
|||
t34i=0; |
|||
t41r=0; |
|||
t41i=0; |
|||
t42r=c3r_tm; |
|||
t42i=c3i_tm; |
|||
t43r=0; |
|||
t43i=0; |
|||
t44r=c2r_tm; |
|||
t44i=c2i_tm; |
|||
|
|||
eeor1=t11r*eeir1-t11i*eeii1+t12r*emir1-t12i*emii1+t13r*eeir2-t13i*eeii2+t14r*emir2-t14i*emii2; |
|||
eeoi1=t11r*eeii1+t11i*eeir1+t12r*emii1+t12i*emir1+t13r*eeii2+t13i*eeir2+t14r*emii2+t14i*emir2; |
|||
emor1=t21r*eeir1-t21i*eeii1+t22r*emir1-t22i*emii1+t23r*eeir2-t23i*eeii2+t24r*emir2-t24i*emii2; |
|||
emoi1=t21r*eeii1+t21i*eeir1+t22r*emii1+t22i*emir1+t23r*eeii2+t23i*eeir2+t24r*emii2+t24i*emir2; |
|||
eeor2=t31r*eeir1-t31i*eeii1+t32r*emir1-t32i*emii1+t33r*eeir2-t33i*eeii2+t34r*emir2-t34i*emii2; |
|||
eeoi2=t31r*eeii1+t31i*eeir1+t32r*emii1+t32i*emir1+t33r*eeii2+t33i*eeir2+t34r*emii2+t34i*emir2; |
|||
emor2=t41r*eeir1-t41i*eeii1+t42r*emir1-t42i*emii1+t43r*eeir2-t43i*eeii2+t44r*emir2-t44i*emii2; |
|||
emoi2=t41r*eeii1+t41i*eeir1+t42r*emii1+t42i*emir1+t43r*eeii2+t43i*eeir2+t44r*emii2+t44i*emir2; |
|||
|
|||
if (V(Ilam1)==0) |
|||
V(Olam1) <+ V(Ilam2); |
|||
else |
|||
V(Olam1) <+ V(Ilam1); |
|||
if (V(Ilam2)==0) |
|||
V(Olam2) <+ V(Ilam1); |
|||
else |
|||
V(Olam2) <+ V(Ilam2); |
|||
if (modespec == 1) begin |
|||
V(Opow1) <+ pow(eeor1,2)+pow(eeoi1,2); |
|||
V(Ophase1) <+ atan2(eeoi1,eeor1)*360.0/(2*`M_PI); |
|||
V(Opow2) <+ pow(eeor2,2)+pow(eeoi2,2); |
|||
V(Ophase2) <+ atan2(eeoi2,eeor2)*360.0/(2*`M_PI); |
|||
end |
|||
else if (modespec == 2) begin |
|||
V(Opow1) <+ pow(emor1,2)+pow(emoi1,2); |
|||
V(Ophase1) <+ atan2(emoi1,emor1)*360.0/(2*`M_PI); |
|||
V(Opow2) <+ pow(emor2,2)+pow(emoi2,2); |
|||
V(Ophase2) <+ atan2(emoi2,emor2)*360.0/(2*`M_PI); |
|||
end |
|||
|
|||
end |
|||
|
|||
endmodule |
@ -0,0 +1,114 @@ |
|||
//VerilogA for passive,xcouplerideal,veriloga |
|||
|
|||
`include "constants.vams" |
|||
`include "disciplines.vams" |
|||
|
|||
module xcouplerideal(Ipow1,Iphase1,Ilam1,Ipow2,Iphase2,Ilam2,Opow1,Ophase1,Olam1,Opow2,Ophase2,Olam2); |
|||
parameter integer modespec = 1 from [1:2]; |
|||
parameter real kappa_te = 0.5 from [0:1]; |
|||
parameter real kappa_tm = 0.5 from [0:1]; |
|||
parameter integer p = 1 from [-1:1] exclude 0; |
|||
|
|||
input Ipow1,Iphase1,Ilam1,Ipow2,Iphase2,Ilam2; |
|||
output Opow1,Ophase1,Olam1,Opow2,Ophase2,Olam2; |
|||
electrical Ipow1,Iphase1,Ilam1,Ipow2,Iphase2,Ilam2,Opow1,Ophase1,Olam1,Opow2,Ophase2,Olam2; |
|||
|
|||
real eeir1,eeii1,emir1,emii1; |
|||
real eeir2,eeii2,emir2,emii2; |
|||
real eeor1,eeoi1,emor1,emoi1; |
|||
real eeor2,eeoi2,emor2,emoi2; |
|||
|
|||
real t11r,t11i,t12r,t12i,t13r,t13i,t14r,t14i,t21r,t21i,t22r,t22i,t23r,t23i,t24r,t24i; |
|||
real t31r,t31i,t32r,t32i,t33r,t33i,t34r,t34i,t41r,t41i,t42r,t42i,t43r,t43i,t44r,t44i; |
|||
real iph_upper,iph_lower; |
|||
|
|||
analog begin |
|||
iph_upper=V(Iphase1)/360.0*2*`M_PI; |
|||
iph_lower=V(Iphase2)/360.0*2*`M_PI; |
|||
if (modespec ==1) begin |
|||
eeir1=sqrt(V(Ipow1))*cos(iph_upper); |
|||
eeii1=sqrt(V(Ipow1))*sin(iph_upper); |
|||
emir1=0; |
|||
emii1=0; |
|||
eeir2=sqrt(V(Ipow2))*cos(iph_lower); |
|||
eeii2=sqrt(V(Ipow2))*sin(iph_lower); |
|||
emir2=0; |
|||
emii2=0; |
|||
end |
|||
else if (modespec ==2) begin |
|||
eeir1=0; |
|||
eeii1=0; |
|||
emir1=sqrt(V(Ipow1))*cos(iph_upper); |
|||
emii1=sqrt(V(Ipow1))*sin(iph_upper); |
|||
eeir2=0; |
|||
eeii2=0; |
|||
emir2=sqrt(V(Ipow2))*cos(iph_lower); |
|||
emii2=sqrt(V(Ipow2))*sin(iph_lower); |
|||
end |
|||
|
|||
t11r=sqrt(1-kappa_te); |
|||
t11i=0; |
|||
t12r=0; |
|||
t12i=0; |
|||
t13r=0; |
|||
t13i=p*sqrt(kappa_te); |
|||
t14r=0; |
|||
t14i=0; |
|||
t21r=0; |
|||
t21i=0; |
|||
t22r=sqrt(1-kappa_tm); |
|||
t22i=0; |
|||
t23r=0; |
|||
t23i=0; |
|||
t24r=0; |
|||
t24i=p*sqrt(kappa_tm); |
|||
t31r=0; |
|||
t31i=p*sqrt(kappa_te); |
|||
t32r=0; |
|||
t32i=0; |
|||
t33r=sqrt(1-kappa_te); |
|||
t33i=0; |
|||
t34r=0; |
|||
t34i=0; |
|||
t41r=0; |
|||
t41i=0; |
|||
t42r=0; |
|||
t42i=p*sqrt(kappa_tm); |
|||
t43r=0; |
|||
t43i=0; |
|||
t44r=sqrt(1-kappa_tm); |
|||
t44i=0; |
|||
|
|||
eeor1=t11r*eeir1-t11i*eeii1+t12r*emir1-t12i*emii1+t13r*eeir2-t13i*eeii2+t14r*emir2-t14i*emii2; |
|||
eeoi1=t11r*eeii1+t11i*eeir1+t12r*emii1+t12i*emir1+t13r*eeii2+t13i*eeir2+t14r*emii2+t14i*emir2; |
|||
emor1=t21r*eeir1-t21i*eeii1+t22r*emir1-t22i*emii1+t23r*eeir2-t23i*eeii2+t24r*emir2-t24i*emii2; |
|||
emoi1=t21r*eeii1+t21i*eeir1+t22r*emii1+t22i*emir1+t23r*eeii2+t23i*eeir2+t24r*emii2+t24i*emir2; |
|||
eeor2=t31r*eeir1-t31i*eeii1+t32r*emir1-t32i*emii1+t33r*eeir2-t33i*eeii2+t34r*emir2-t34i*emii2; |
|||
eeoi2=t31r*eeii1+t31i*eeir1+t32r*emii1+t32i*emir1+t33r*eeii2+t33i*eeir2+t34r*emii2+t34i*emir2; |
|||
emor2=t41r*eeir1-t41i*eeii1+t42r*emir1-t42i*emii1+t43r*eeir2-t43i*eeii2+t44r*emir2-t44i*emii2; |
|||
emoi2=t41r*eeii1+t41i*eeir1+t42r*emii1+t42i*emir1+t43r*eeii2+t43i*eeir2+t44r*emii2+t44i*emir2; |
|||
|
|||
if (V(Ilam1)==0) |
|||
V(Olam1) <+ V(Ilam2); |
|||
else |
|||
V(Olam1) <+ V(Ilam1); |
|||
if (V(Ilam2)==0) |
|||
V(Olam2) <+ V(Ilam1); |
|||
else |
|||
V(Olam2) <+ V(Ilam2); |
|||
if (modespec == 1) begin |
|||
V(Opow1) <+ pow(eeor1,2)+pow(eeoi1,2); |
|||
V(Ophase1) <+ atan2(eeoi1,eeor1)*360.0/(2*`M_PI); |
|||
V(Opow2) <+ pow(eeor2,2)+pow(eeoi2,2); |
|||
V(Ophase2) <+ atan2(eeoi2,eeor2)*360.0/(2*`M_PI); |
|||
end |
|||
else if (modespec == 2) begin |
|||
V(Opow1) <+ pow(emor1,2)+pow(emoi1,2); |
|||
V(Ophase1) <+ atan2(emoi1,emor1)*360.0/(2*`M_PI); |
|||
V(Opow2) <+ pow(emor2,2)+pow(emoi2,2); |
|||
V(Ophase2) <+ atan2(emoi2,emor2)*360.0/(2*`M_PI); |
|||
end |
|||
|
|||
end |
|||
|
|||
endmodule |
@ -0,0 +1,86 @@ |
|||
//VerilogA for pd,msmpd,veriloga |
|||
|
|||
`include "constants.vams" |
|||
`include "disciplines.vams" |
|||
|
|||
module msmpd(Vin,Gnd,Ipow,Iphase,Ilam); |
|||
parameter real Lg = 3u from (0:inf); |
|||
parameter real Se = 3726E-12 from (0:inf); |
|||
parameter real Aa = 2757E-12 from (0:inf); |
|||
parameter real Ac = 3114E-12 from (0:inf); |
|||
parameter real Cf = 0.02 from (0:inf); |
|||
parameter real Cc = 0.5 from [0:inf); |
|||
parameter real Cno = 1.0E-12 from (0:inf); |
|||
parameter real Ci = 0.38 from (0:inf); |
|||
parameter real EPSs = 12.9 from (0:inf); |
|||
parameter real D = 6u from (0:inf); |
|||
parameter real ALFA = 1e10 from [0:inf); |
|||
parameter real Un = 5500E-4 from (0:inf); |
|||
parameter real Up = 400E-4 from (0:inf); |
|||
parameter real Vns = 8.5E4 from (0:inf); |
|||
parameter real Vps = 8.5E4 from (0:inf); |
|||
parameter real Fth = 4.2E10 from (0:inf); |
|||
parameter real Tnr = 0.2n from (0:inf); |
|||
parameter real Tpr = 0.65n from (0:inf); |
|||
parameter real Cm = 10 from (0:inf); |
|||
parameter real Rdark = 9.1E9 from (0:inf); |
|||
parameter real Cp = 0.1p from [0:inf); |
|||
parameter real Rs = 5 from [0:inf); |
|||
parameter real Rgnd = 50 from [0:inf); |
|||
|
|||
input Vin,Ipow,Iphase,Ilam; |
|||
output Gnd; |
|||
electrical Vin,Gnd,Ipow,Iphase,Ilam,Nin1,Nin2,Npn,Npp; |
|||
|
|||
real HV; |
|||
real Go,Rnr,Rpr; |
|||
real Ct,Cga,Cgc; |
|||
real F,Vp,Vn; |
|||
real Fg,Vng,Vpg; |
|||
real Rnt,Rpt; |
|||
|
|||
branch (Nin1,Nin2) CCp,CCt,BIp,BIn,RRdark; |
|||
branch (Gnd,Npn) BIon; |
|||
branch (Npn,Gnd) RRnt,RRnr,CCnon; |
|||
branch (Gnd,Npp) BIop; |
|||
branch (Npp,Gnd) RRpt,RRpr,CCnop; |
|||
|
|||
analog begin |
|||
HV=`P_H*`P_C/V(Ilam); |
|||
Go=`P_Q*Ci*(1-exp(-ALFA*D))/HV; |
|||
Cga=Cc*Aa*sqrt(Cno*V(Npn,Gnd)*`P_EPS0*EPSs/Se/D/V(Nin1,Nin2)); |
|||
Cgc=Cc*Ac*sqrt(Cno*V(Npp,Gnd)*`P_EPS0*EPSs/Se/D/V(Nin1,Nin2)); |
|||
F=Cf*V(Nin1,Nin2)/Lg; |
|||
Fg=V(Nin1,Nin2)/Lg; |
|||
Vp=Up*F/(1.0+Up*F/Vps); |
|||
Vn=(Un*F+Vns*pow(F/Fth,4))/(1+pow(F/Fth,4)); |
|||
Vpg=Up*Fg/(1.0+Up*Fg/Vps); |
|||
Vng=(Un*Fg+Vns*pow(Fg/Fth,4))/(1+pow(Fg/Fth,4)); |
|||
|
|||
Ct=Cga*Cgc/(Cga+Cgc); |
|||
Rnt=Lg/Vng/Cno; |
|||
Rpt=Lg/Vpg/Cno; |
|||
Rnr=Tnr/Cno; |
|||
Rpr=Tpr/Cno; |
|||
|
|||
V(Vin,Nin1) <+ I(Vin,Nin1)*Rs; |
|||
I(CCp) <+ Cp*ddt(V(CCp)); |
|||
I(CCt) <+ Ct*ddt(V(CCt)); |
|||
V(RRdark) <+ I(RRdark)*Rdark; |
|||
I(BIp) <+ Cm*Cno*V(Npp,Gnd)*Vp/Lg; |
|||
I(BIn) <+ Cm*Cno*V(Npn,Gnd)*Vn/Lg; |
|||
|
|||
I(BIon) <+ V(Ipow,Gnd)*Go; |
|||
V(RRnt) <+ I(RRnt)*Rnt; |
|||
V(RRnr) <+ I(RRnr)*Rnr; |
|||
I(CCnon) <+ Cno*ddt(V(CCnon)); |
|||
|
|||
I(BIop) <+ V(Ipow,Gnd)*Go; |
|||
V(RRpt) <+ I(RRpt)*Rpt; |
|||
V(RRpr) <+ I(RRpr)*Rpr; |
|||
I(CCnop) <+ Cno*ddt(V(CCnop)); |
|||
|
|||
V(Gnd,Nin2) <+ Rgnd*I(Gnd,Nin2); |
|||
end |
|||
|
|||
endmodule |
@ -0,0 +1,191 @@ |
|||
//VerilogA for pd,pinapd,veriloga |
|||
`include "constants.vams" |
|||
`include "disciplines.vams" |
|||
|
|||
module pinapd(Vin,Ipow,Iphase,Ilam,Gnd); |
|||
parameter real Idi = 1 from [0:1]; |
|||
parameter real A = 12000E-12 from (0:inf); |
|||
parameter real Wn = 2u from (0:inf); |
|||
parameter real Wi = 4.2u from (0:inf); |
|||
parameter real Wp = 2u from (0:inf); |
|||
parameter real R = 0.35 from (0:1); |
|||
parameter real ALFn = 0.01 from (0:inf); |
|||
parameter real ALFi = 3000 from (0:inf); |
|||
parameter real ALFp = 3000 from (0:inf); |
|||
parameter real Vbi = 0.8 from (0:inf); |
|||
parameter real Nin = 3.3E12 from (0:inf); |
|||
parameter real Nip = 7.3E17 from (0:inf); |
|||
parameter real Nd = 5E24 from (0:inf); |
|||
parameter real Na = 5E24 from (0:inf); |
|||
parameter real Un = 1.05 from (0:inf); |
|||
parameter real Vsn = 1E5 from (0:inf); |
|||
parameter real Fth = 350000 from (0:inf); |
|||
parameter real Up = 0.03 from (0:inf); |
|||
parameter real Vsp = 1E5 from (0:inf); |
|||
parameter real Tp = 1n from (0:inf); |
|||
parameter real Tn = 0.2n from (0:inf); |
|||
parameter real Tnr = 0.2n from (0:inf); |
|||
parameter real Dp = 5.2E-4 from (0:inf); |
|||
parameter real Dn = 260E-4 from (0:inf); |
|||
parameter real An = 5.13E9 from [0:inf); |
|||
parameter real Bn = 1.95E8 from (-inf:inf); |
|||
parameter real Cn = 1 from (-inf:inf); |
|||
parameter real Ap = 7.3E9 from [0:inf); |
|||
parameter real Bp = 2.2E8 from (-inf:inf); |
|||
parameter real Cp = 1 from (-inf:inf); |
|||
parameter real EPSs = 12 from (0:inf); |
|||
parameter real Eg = 0.75 from (0:inf); |
|||
parameter real Mc = 0.041 from (0:inf); |
|||
parameter real GAM = 1.1 from (0:inf); |
|||
parameter real Rd = 1e10 from (0:inf); |
|||
parameter real Cs = 1.0p from (0:inf); |
|||
parameter real Rs = 5 from [0:inf); |
|||
parameter real Cno = 1e-12 from (0:inf); |
|||
parameter real Rgnd = 50 from [0:inf); |
|||
|
|||
input Vin,Ipow,Iphase,Ilam; |
|||
inout Gnd; |
|||
electrical Vin,Ipow,Iphase,Ilam,Gnd; |
|||
electrical Nvin,Ngnd,Npn,Npp,Npi; |
|||
|
|||
real PLANCK2PI = `P_H/`M_TWO_PI; |
|||
real m0 = 9.10938356E-31; |
|||
|
|||
real Np0,Pn0,Ln,Lp,SIT1,SIT2,HV; |
|||
real EAWn,EAWp,EAWi; |
|||
real Vop,Voi,Von; |
|||
real Rp,Rn,Rnr; |
|||
real CHPN,SHPN,CHNP,SHNP; |
|||
real Rnd,Rpd,In0,Ip0,Ln2,ALFp2,Lp2,ALFn2; |
|||
real BEATn0,BEATn,BEATp0,BEATp,Cj; |
|||
real Rnt,Tnt,F,LMD; |
|||
real Vn,Zn,Vp,Zp; |
|||
|
|||
real UA,UWn,UWi,UWp,ULMD; |
|||
real UALFn,UALFi,UALFp; |
|||
real UNin,UNip,UNd,UNa; |
|||
real UUn,UVsn,UFth,UUp,UVsp; |
|||
real UDp,UDn,UAn,UBn,UAp,UBp; |
|||
real ULSPEED,UEPS0; |
|||
|
|||
branch (Nvin,Ngnd) CCs,CCj,RRd,Ii,Id,Ip; |
|||
branch (Gnd,Npn) IVN; |
|||
branch (Npn,Gnd) CCnoN,RRn,Iin; |
|||
branch (Gnd,Npp) IVP; |
|||
branch (Npp,Gnd) CCnoP,RRp,Iip; |
|||
branch (Gnd,Npi) IVI,Iia,Iini; |
|||
branch (Npi,Gnd) CCnoI,RRnr,Iii; |
|||
|
|||
analog begin |
|||
LMD = V(Ilam); |
|||
|
|||
UA = A*1e12; |
|||
UWn = Wn*1e6; |
|||
UWi = Wi*1e6; |
|||
UWp = Wp*1e6; |
|||
ULMD = LMD*1e6; |
|||
UALFn = ALFn*1e-6; |
|||
UALFi = ALFi*1e-6; |
|||
UALFp = ALFp*1e-6; |
|||
UNin = Nin*1e-18; |
|||
UNip = Nip*1e-18; |
|||
UNd = Nd*1e-18; |
|||
UNa = Na*1e-18; |
|||
UUn = Un*1e12; |
|||
UVsn = Vsn*1e6; |
|||
UFth = Fth*1e-6; |
|||
UUp = Up*1e12; |
|||
UVsp = Vsp*1e6; |
|||
UDp = Dp*1e12; |
|||
UDn = Dn*1e12; |
|||
UAn = An*1e-6; |
|||
UBn = Bn*1e-6; |
|||
UAp = Ap*1e-6; |
|||
UBp = Bp*1e-6; |
|||
ULSPEED = `P_C*1e6; |
|||
UEPS0 = `P_EPS0*1e-6; |
|||
|
|||
Np0 = UNip*UNip/UNa; |
|||
Pn0 = UNin*UNin/UNd; |
|||
Ln = sqrt(UDn*Tn); |
|||
Lp = sqrt(UDp*Tp); |
|||
SIT1 = pow(`P_Q,3)*sqrt(2*Mc*m0/(Eg*`P_Q))/(4*`M_PI*pow(PLANCK2PI,2)); |
|||
SIT2 = GAM*sqrt(Mc*m0*(Eg*`P_Q))/(`P_Q*PLANCK2PI)*(Eg*`P_Q); |
|||
// SIT1 = sqrt(Mc/Eg)*3.159E4; |
|||
// SIT2 = GAM*sqrt(Mc*Eg)*Eg*3.623E9; |
|||
HV = `P_H*ULSPEED/ULMD; |
|||
EAWn = exp(-UALFn*UWn); |
|||
EAWp = exp(-UALFp*UWp); |
|||
EAWi = exp(-UALFi*UWi); |
|||
Ln2 = Ln*Ln; |
|||
Lp2 = Lp*Lp; |
|||
ALFn2 = UALFn*UALFn; |
|||
ALFp2 = UALFp*UALFp; |
|||
CHPN = cosh(UWp/Ln); |
|||
SHPN = sinh(UWp/Ln); |
|||
CHNP = cosh(UWn/Lp); |
|||
SHNP = sinh(UWn/Lp); |
|||
BEATn0 = (`P_Q*(1-R)*UALFp*Ln2/HV/(1.0-ALFp2*Ln2))*((CHPN+1.0)/(Ln*SHPN)+(EAWp-1.0)/(UALFp*Ln2*(CHPN-1.0))-UALFp); |
|||
BEATp0 = (`P_Q*(1-R)*UALFn*Lp2/HV/(1.0-ALFn2*Lp2))*((CHNP+1.0)*EAWn/Lp/SHNP+(EAWn-1.0)/(UALFn*Lp2*(CHNP-1.0))+UALFn*EAWn); |
|||
if (Idi > 0) begin |
|||
Vop = `P_Q*(1-R)*(1.0-EAWn)/HV; |
|||
Voi = `P_Q*(1-R)*(1.0-EAWi)*EAWn/HV; |
|||
Von = `P_Q*(1-R)*(1.0-EAWp)*EAWn*EAWi/HV; |
|||
BEATn = BEATn0*EAWn*EAWi; |
|||
BEATp = BEATp0; |
|||
end |
|||
else begin |
|||
Vop = `P_Q*(1-R)*(1.0-EAWn)*EAWp*EAWi/HV; |
|||
Voi = `P_Q*(1-R)*(1.0-EAWi)*EAWp/HV; |
|||
Von = `P_Q*(1-R)*(1.0-EAWp)/HV; |
|||
BEATn = BEATn0; |
|||
BEATp = BEATp0*EAWp*EAWi; |
|||
end |
|||
Rp = Tp/Cno; |
|||
Rn = Tn/Cno; |
|||
Rnr = Tnr/Cno; |
|||
Rnd = Rn*(CHPN-1.0); |
|||
Rpd = Rp*(CHNP-1.0); |
|||
In0 = (`P_Q/Tn)*UA*Np0*Ln*(CHPN+1.0)/SHPN; |
|||
Ip0 = (`P_Q/Tp)*UA*Pn0*Lp*(CHNP+1.0)/SHNP; |
|||
Cj = EPSs*UEPS0*UA/UWi; |
|||
|
|||
F = (V(Nvin,Ngnd)+Vbi)/UWi; |
|||
Vn = (UUn*F+UVsn*(pow((F/UFth),4)))/(1.0+(pow((F/UFth),4))); |
|||
Vp = UUp*F/(1.0+UUp*F/UVsp); |
|||
// Zn = UAn/exp(pow((UBn/F),Cn)); |
|||
Zn = exp(ln(UAn)-pow((UBn/F),Cn)); |
|||
// Zp = UAp/exp(pow((UBp/F),Cp)); |
|||
Zp = exp(ln(UAp)-pow((UBp/F),Cp)); |
|||
Tnt = UWi/Vn; |
|||
Rnt = Tnt/Cno; |
|||
|
|||
V(Vin,Nvin) <+ I(Vin,Nvin)*Rs; |
|||
I(CCs) <+ ddt(V(CCs))*Cs; |
|||
I(CCj) <+ ddt(V(CCj))*Cj; |
|||
V(RRd) <+ I(RRd)*Rd; |
|||
I(Id) <+ SIT1*1E-6*UA*V(Id)*(V(Id)+Vbi)*exp(-SIT2*1E-6*UWi/(V(Id)+Vbi))/UWi; |
|||
I(Ii) <+ V(Npi,Gnd)/Rnt; |
|||
I(Ip) <+ V(Npp,Gnd)/Rpd+BEATp*V(Ipow,Gnd)+Ip0; |
|||
|
|||
I(IVP) <+ V(Ipow,Gnd)*Vop; |
|||
I(CCnoP) <+ ddt(V(CCnoP))*Cno; |
|||
V(RRp) <+ I(RRp)*Rp; |
|||
I(Iip) <+ V(Npp,Gnd)/Rpd+BEATp*V(Ipow,Gnd)+Ip0; |
|||
|
|||
I(IVI) <+ V(Ipow,Gnd)*Voi; |
|||
I(CCnoI) <+ ddt(V(CCnoI))*Cno; |
|||
I(Iia) <+ Cno*V(Npi,Gnd)*(Vn*Zn+Vp*Zp); |
|||
I(Iini) <+ V(Npn,Gnd)/Rnd+BEATn*V(Ipow,Gnd)+In0; |
|||
V(RRnr) <+ I(RRnr)*Rnr; |
|||
I(Iii) <+ V(Npi,Gnd)/Rnt; |
|||
|
|||
I(IVN) <+ V(Ipow,Gnd)*Von; |
|||
I(CCnoN) <+ ddt(V(CCnoN))*Cno; |
|||
V(RRn) <+ I(RRn)*Rn; |
|||
I(Iin) <+ V(Npn,Gnd)/Rnd+BEATn*V(Ipow,Gnd)+In0; |
|||
|
|||
V(Gnd,Ngnd) <+ Rgnd*I(Gnd,Ngnd); |
|||
end |
|||
|
|||
endmodule |
@ -0,0 +1,176 @@ |
|||
//VerilogA for pd,pinpd,veriloga |
|||
`include "constants.vams" |
|||
`include "disciplines.vams" |
|||
|
|||
module pinpd(Vin,Ipow,Iphase,Ilam,Gnd); |
|||
parameter real Idi = 1 from [0:1]; |
|||
parameter real A = 12000E-12 from (0:inf); |
|||
parameter real Wn = 2u from (0:inf); |
|||
parameter real Wi = 4.2u from (0:inf); |
|||
parameter real Wp = 2u from (0:inf); |
|||
parameter real R = 0.35 from (0:1); |
|||
parameter real ALFn = 0.01 from (0:inf); |
|||
parameter real ALFi = 3000 from (0:inf); |
|||
parameter real ALFp = 3000 from (0:inf); |
|||
parameter real Vbi = 0.8 from (0:inf); |
|||
parameter real Nin = 3.3E12 from (0:inf); |
|||
parameter real Nip = 7.3E17 from (0:inf); |
|||
parameter real Nd = 5E24 from (0:inf); |
|||
parameter real Na = 5E24 from (0:inf); |
|||
parameter real Un = 1.05 from (0:inf); |
|||
parameter real Vsn = 1E5 from (0:inf); |
|||
parameter real Fth = 350000 from (0:inf); |
|||
parameter real Up = 0.03 from (0:inf); |
|||
parameter real Vsp = 1E5 from (0:inf); |
|||
parameter real Tp = 1n from (0:inf); |
|||
parameter real Tn = 0.2n from (0:inf); |
|||
parameter real Tnr = 0.2n from (0:inf); |
|||
parameter real Dp = 5.2E-4 from (0:inf); |
|||
parameter real Dn = 260E-4 from (0:inf); |
|||
parameter real EPSs = 12 from (0:inf); |
|||
parameter real Eg = 0.75 from (0:inf); |
|||
parameter real Mc = 0.041 from (0:inf); |
|||
parameter real GAM = 1.1 from (0:inf); |
|||
parameter real Rd = 1e10 from (0:inf); |
|||
parameter real Cs = 1.0p from (0:inf); |
|||
parameter real Rs = 5 from [0:inf); |
|||
parameter real Cno = 1e-12 from (0:inf); |
|||
parameter real Rgnd = 50 from [0:inf); |
|||
|
|||
input Vin,Ipow,Iphase,Ilam; |
|||
inout Gnd; |
|||
electrical Vin,Ipow,Iphase,Ilam,Gnd; |
|||
electrical Nvin,Ngnd,Npn,Npp,Npi; |
|||
|
|||
real PLANCK2PI=`P_H/`M_TWO_PI; |
|||
real m0=9.10938356E-31; |
|||
|
|||
real Np0,Pn0,Ln,Lp,SIT1,SIT2,HV; |
|||
real EAWn,EAWp,EAWi; |
|||
real Vop,Voi,Von; |
|||
real Rp,Rn,Rnr; |
|||
real CHPN,SHPN,CHNP,SHNP; |
|||
real Rnd,Rpd,In0,Ip0,Ln2,ALFp2,Lp2,ALFn2; |
|||
real BEATn0,BEATn,BEATp0,BEATp,Cj; |
|||
real Rnt,Tnt,F,LMD; |
|||
real Vn,Vp; |
|||
|
|||
real UA,UWn,UWi,UWp,ULMD; |
|||
real UALFn,UALFi,UALFp; |
|||
real UNin,UNip,UNd,UNa; |
|||
real UUn,UVsn,UFth,UUp,UVsp; |
|||
real UDp,UDn; |
|||
real ULSPEED,UEPS0; |
|||
|
|||
branch (Nvin,Ngnd) CCs,CCj,RRd,Ii,Id,Ip; |
|||
branch (Gnd,Npn) IVN; |
|||
branch (Npn,Gnd) CCnoN,RRn,Iin; |
|||
branch (Gnd,Npp) IVP; |
|||
branch (Npp,Gnd) CCnoP,RRp,Iip; |
|||
branch (Gnd,Npi) IVI,Iini; |
|||
branch (Npi,Gnd) CCnoI,RRnr,Iii; |
|||
|
|||
analog begin |
|||
LMD=V(Ilam); |
|||
|
|||
UA=A*1e12; |
|||
UWn=Wn*1e6; |
|||
UWi=Wi*1e6; |
|||
UWp=Wp*1e6; |
|||
ULMD=LMD*1e6; |
|||
UALFn=ALFn*1e-6; |
|||
UALFi=ALFi*1e-6; |
|||
UALFp=ALFp*1e-6; |
|||
UNin=Nin*1e-18; |
|||
UNip=Nip*1e-18; |
|||
UNd=Nd*1e-18; |
|||
UNa=Na*1e-18; |
|||
UUn=Un*1e12; |
|||
UVsn=Vsn*1e6; |
|||
UFth=Fth*1e-6; |
|||
UUp=Up*1e12; |
|||
UVsp=Vsp*1e6; |
|||
UDp=Dp*1e12; |
|||
UDn=Dn*1e12; |
|||
ULSPEED=`P_C*1e6; |
|||
UEPS0=`P_EPS0*1e-6; |
|||
|
|||
Np0=UNip*UNip/UNa; |
|||
Pn0=UNin*UNin/UNd; |
|||
Ln=sqrt(UDn*Tn); |
|||
Lp=sqrt(UDp*Tp); |
|||
SIT1=pow(`P_Q,3)*sqrt(2*Mc*m0/(Eg*`P_Q))/(4*`M_PI*pow(PLANCK2PI,2)); |
|||
SIT2=GAM*sqrt(Mc*m0*(Eg*`P_Q))/(`P_Q*PLANCK2PI)*(Eg*`P_Q); |
|||
// SIT1=sqrt(Mc/Eg)*3.159E4; |
|||
// SIT2=GAM*sqrt(Mc*Eg)*Eg*3.623E9; |
|||
HV=`P_H*ULSPEED/ULMD; |
|||
EAWn=exp(-UALFn*UWn); |
|||
EAWp=exp(-UALFp*UWp); |
|||
EAWi=exp(-UALFi*UWi); |
|||
Ln2=Ln*Ln; |
|||
Lp2=Lp*Lp; |
|||
ALFn2=UALFn*UALFn; |
|||
ALFp2=UALFp*UALFp; |
|||
CHPN=cosh(UWp/Ln); |
|||
SHPN=sinh(UWp/Ln); |
|||
CHNP=cosh(UWn/Lp); |
|||
SHNP=sinh(UWn/Lp); |
|||
BEATn0=(`P_Q*(1-R)*UALFp*Ln2/HV/(1.0-ALFp2*Ln2))*((CHPN+1.0)/(Ln*SHPN)+(EAWp-1.0)/(UALFp*Ln2*(CHPN-1.0))-UALFp); |
|||
BEATp0=(`P_Q*(1-R)*UALFn*Lp2/HV/(1.0-ALFn2*Lp2))*((CHNP+1.0)*EAWn/Lp/SHNP+(EAWn-1.0)/(UALFn*Lp2*(CHNP-1.0))+UALFn*EAWn); |
|||
if (Idi > 0) begin |
|||
Vop=`P_Q*(1-R)*(1.0-EAWn)/HV; |
|||
Voi=`P_Q*(1-R)*(1.0-EAWi)*EAWn/HV; |
|||
Von=`P_Q*(1-R)*(1.0-EAWp)*EAWn*EAWi/HV; |
|||
BEATn=BEATn0*EAWn*EAWi; |
|||
BEATp=BEATp0; |
|||
end |
|||
else begin |
|||
Vop=`P_Q*(1-R)*(1.0-EAWn)*EAWp*EAWi/HV; |
|||
Voi=`P_Q*(1-R)*(1.0-EAWi)*EAWp/HV; |
|||
Von=`P_Q*(1-R)*(1.0-EAWp)/HV; |
|||
BEATn=BEATn0; |
|||
BEATp=BEATp0*EAWp*EAWi; |
|||
end |
|||
Rp=Tp/Cno; |
|||
Rn=Tn/Cno; |
|||
Rnr=Tnr/Cno; |
|||
Rnd=Rn*(CHPN-1.0); |
|||
Rpd=Rp*(CHNP-1.0); |
|||
In0=(`P_Q/Tn)*UA*Np0*Ln*(CHPN+1.0)/SHPN; |
|||
Ip0=(`P_Q/Tp)*UA*Pn0*Lp*(CHNP+1.0)/SHNP; |
|||
Cj=EPSs*UEPS0*UA/UWi; |
|||
|
|||
F=(V(Nvin,Ngnd)+Vbi)/UWi; |
|||
Vn=(UUn*F+UVsn*(pow((F/UFth),4)))/(1.0+(pow((F/UFth),4))); |
|||
Vp=UUp*F/(1.0+UUp*F/UVsp); |
|||
Tnt=UWi/Vn; |
|||
Rnt=Tnt/Cno; |
|||
|
|||
V(Vin,Nvin) <+ I(Vin,Nvin)*Rs; |
|||
I(CCs) <+ ddt(V(CCs))*Cs; |
|||
I(CCj) <+ ddt(V(CCj))*Cj; |
|||
V(RRd) <+ I(RRd)*Rd; |
|||
I(Id) <+ SIT1*1E-6*UA*V(Id)*(V(Id)+Vbi)*exp(-SIT2*1E-6*UWi/(V(Id)+Vbi))/UWi; |
|||
I(Ii) <+ V(Npi,Gnd)/Rnt; |
|||
I(Ip) <+ V(Npp,Gnd)/Rpd+BEATp*V(Ipow,Gnd)+Ip0; |
|||
|
|||
I(IVP) <+ V(Ipow,Gnd)*Vop; |
|||
I(CCnoP) <+ ddt(V(CCnoP))*Cno; |
|||
V(RRp) <+ I(RRp)*Rp; |
|||
I(Iip) <+ V(Npp,Gnd)/Rpd+BEATp*V(Ipow,Gnd)+Ip0; |
|||
|
|||
I(IVI) <+ V(Ipow,Gnd)*Voi; |
|||
I(CCnoI) <+ ddt(V(CCnoI))*Cno; |
|||
I(Iini) <+ V(Npn,Gnd)/Rnd+BEATn*V(Ipow,Gnd)+In0; |
|||
V(RRnr) <+ I(RRnr)*Rnr; |
|||
I(Iii) <+ V(Npi,Gnd)/Rnt; |
|||
|
|||
I(IVN) <+ V(Ipow,Gnd)*Von; |
|||
I(CCnoN) <+ ddt(V(CCnoN))*Cno; |
|||
V(RRn) <+ I(RRn)*Rn; |
|||
I(Iin) <+ V(Npn,Gnd)/Rnd+BEATn*V(Ipow,Gnd)+In0; |
|||
|
|||
V(Gnd,Ngnd) <+ Rgnd*I(Gnd,Ngnd); |
|||
end |
|||
|
|||
endmodule |
@ -0,0 +1,243 @@ |
|||
//VerilogA for ring,basicfilter,veriloga |
|||
//port position: |
|||
//12 |
|||
//34 |
|||
`include "constants.vams" |
|||
`include "disciplines.vams" |
|||
|
|||
module basicfilter(Ipow1,Iphase1,Ilam1,Ipow2,Iphase2,Ilam2,Opow1,Ophase1,Olam1,Opow2,Ophase2,Olam2); |
|||
parameter integer modespec = 1 from [1:2]; |
|||
parameter integer alpha_use_dBm = 1 from [0:1]; |
|||
parameter real l_bus = 1e-3 from [0:inf); |
|||
parameter real r_ring = 7.5e-6 from [0:inf); |
|||
parameter real attenu_bus_te = 0 from [0:inf); |
|||
parameter real attenu_bus_tm = 0 from [0:inf); |
|||
parameter real attenu_ring_te = 0 from [0:inf); |
|||
parameter real attenu_ring_tm = 0 from [0:inf); |
|||
parameter real phasedelay_bus_te = 0; |
|||
parameter real phasedelay_bus_tm = 0; |
|||
parameter real phasedelay_ring_te = 0; |
|||
parameter real phasedelay_ring_tm = 0; |
|||
parameter real neff_te = 2.6 from (0:inf); |
|||
parameter real neff_tm = 2.6 from (0:inf); |
|||
parameter real coupling_ring_te_up = 0.145 from [0:1]; |
|||
parameter real coupling_ring_tm_up = 0.145 from [0:1]; |
|||
parameter real coupling_ring_te_down = 0.145 from [0:1]; |
|||
parameter real coupling_ring_tm_down = 0.145 from [0:1]; |
|||
parameter real reffreq = 193.1T from (0:inf); |
|||
parameter real n_gv_te = 4.2 from (0:inf); |
|||
parameter real n_gv_tm = 4.2 from (0:inf); |
|||
parameter real disper_te = 0; |
|||
parameter real disper_tm = 0; |
|||
//parameter real coupling_tem = 0; |
|||
|
|||
input Ipow1,Iphase1,Ilam1,Ipow2,Iphase2,Ilam2; |
|||
output Opow1,Ophase1,Olam1,Opow2,Ophase2,Olam2; |
|||
electrical Ipow1,Iphase1,Ilam1,Ipow2,Iphase2,Ilam2,Opow1,Ophase1,Olam1,Opow2,Ophase2,Olam2; |
|||
|
|||
real eeir2,eeii2,emir2,emii2,eeir3,eeii3,emir3,emii3; |
|||
real eeor1,eeoi1,emor1,emoi1,eeor4,eeoi4,emor4,emoi4; |
|||
real t11r,t11i,t12r,t12i,t13r,t13i,t14r,t14i,t21r,t21i,t22r,t22i,t23r,t23i,t24r,t24i,t31r,t31i,t32r,t32i,t33r,t33i,t34r,t34i,t41r,t41i,t42r,t42i,t43r,t43i,t44r,t44i; |
|||
real beta_te,beta_tm; |
|||
real alpha_bus_te,alpha_bus_tm,alpha_ring_te,alpha_ring_tm; |
|||
real beta_bus_ter,beta_bus_tei,beta_bus_tmr,beta_bus_tmi,beta_ring_ter,beta_ring_tei,beta_ring_tmr,beta_ring_tmi; |
|||
real t_te_up,t_tm_up,t_te_down,t_tm_down; |
|||
real theta_ter,theta_tei,theta_tmr,theta_tmi; |
|||
real kappa_te_up,kappa_tm_up,kappa_te_down,kappa_tm_down; |
|||
real c1er,c1ei,c1em,c1mr,c1mi,c1mm,c2er,c2ei,c2em,c2mr,c2mi,c2mm,c3er,c3ei,c3em,c3mr,c3mi,c3mm; |
|||
real c1e1r,c1e1i,c1e2r,c1e2i,c1m1r,c1m1i,c1m2r,c1m2i; |
|||
real c2e1r,c2e1i,c2e2r,c2e2i,c2m1r,c2m1i,c2m2r,c2m2i; |
|||
real c3e1r,c3e1i,c3e2r,c3e2i,c3m1r,c3m1i,c3m2r,c3m2i; |
|||
real cber,cbei,cbmr,cbmi; |
|||
real l_ring=2*`M_PI*r_ring; |
|||
real phasedelay_bus_te_u=phasedelay_bus_te/360.0*2*`M_PI; |
|||
real phasedelay_bus_tm_u=phasedelay_bus_tm/360.0*2*`M_PI; |
|||
real phasedelay_ring_te_u=phasedelay_ring_te/360.0*2*`M_PI; |
|||
real phasedelay_ring_tm_u=phasedelay_ring_tm/360.0*2*`M_PI; |
|||
real lam,freq; |
|||
real iph2,iph3; |
|||
|
|||
analog begin |
|||
if (V(Ilam1) == 0) begin |
|||
lam=V(Ilam2); |
|||
end |
|||
else if (V(Ilam2) == 0) begin |
|||
lam=V(Ilam1); |
|||
end |
|||
else begin |
|||
lam=V(Ilam1); |
|||
end |
|||
freq=`P_C/lam; |
|||
iph2=V(Iphase2)/360.0*2*`M_PI; |
|||
iph3=V(Iphase1)/360.0*2*`M_PI; |
|||
if (modespec == 1) begin |
|||
eeir2=sqrt(V(Ipow2))*cos(iph2); |
|||
eeii2=sqrt(V(Ipow2))*sin(iph2); |
|||
emir2=0; |
|||
emii2=0; |
|||
eeir3=sqrt(V(Ipow1))*cos(iph3); |
|||
eeii3=sqrt(V(Ipow1))*sin(iph3); |
|||
emir3=0; |
|||
emii3=0; |
|||
end |
|||
else if (modespec == 2) begin |
|||
eeir2=0; |
|||
eeii2=0; |
|||
emir2=sqrt(V(Ipow2))*cos(iph2); |
|||
emii2=sqrt(V(Ipow2))*sin(iph2); |
|||
eeir3=0; |
|||
eeii3=0; |
|||
emir3=sqrt(V(Ipow1))*cos(iph3); |
|||
emii3=sqrt(V(Ipow1))*sin(iph3); |
|||
end |
|||
|
|||
beta_te=2*`M_PI*reffreq/`P_C*neff_te+2*`M_PI/`P_C*n_gv_te*(freq-reffreq)-`M_PI*`P_C*disper_te/pow(reffreq,2)*pow(freq-reffreq,2); |
|||
beta_tm=2*`M_PI*reffreq/`P_C*neff_tm+2*`M_PI/`P_C*n_gv_tm*(freq-reffreq)-`M_PI*`P_C*disper_tm/pow(reffreq,2)*pow(freq-reffreq,2); |
|||
if (alpha_use_dBm == 0) begin |
|||
alpha_bus_te=attenu_bus_te; |
|||
alpha_bus_tm=attenu_bus_tm; |
|||
alpha_ring_te=attenu_ring_te; |
|||
alpha_ring_tm=attenu_ring_tm; |
|||
end |
|||
else if (alpha_use_dBm == 1) begin |
|||
alpha_bus_te=attenu_bus_te/10.0*ln(10); |
|||
alpha_bus_tm=attenu_bus_tm/10.0*ln(10); |
|||
alpha_ring_te=attenu_ring_te/10.0*ln(10); |
|||
alpha_ring_tm=attenu_ring_tm/10.0*ln(10); |
|||
end |
|||
|
|||
|
|||
beta_bus_ter=beta_te; |
|||
beta_bus_tei=-0.5*alpha_bus_te; |
|||
beta_bus_tmr=beta_tm; |
|||
beta_bus_tmi=-0.5*alpha_bus_tm; |
|||
beta_ring_ter=beta_te; |
|||
beta_ring_tei=-0.5*alpha_ring_te; |
|||
beta_ring_tmr=beta_tm; |
|||
beta_ring_tmi=-0.5*alpha_ring_tm; |
|||
|
|||
t_te_up=sqrt(1-coupling_ring_te_up); |
|||
t_tm_up=sqrt(1-coupling_ring_tm_up); |
|||
t_te_down=sqrt(1-coupling_ring_te_down); |
|||
t_tm_down=sqrt(1-coupling_ring_tm_down); |
|||
kappa_te_up=sqrt(coupling_ring_te_up); |
|||
kappa_tm_up=sqrt(coupling_ring_tm_up); |
|||
kappa_te_down=sqrt(coupling_ring_te_down); |
|||
kappa_tm_down=sqrt(coupling_ring_tm_down); |
|||
theta_ter=beta_ring_ter*l_ring-phasedelay_ring_te_u; |
|||
theta_tei=beta_ring_tei*l_ring; |
|||
theta_tmr=beta_ring_tmr*l_ring-phasedelay_ring_tm_u; |
|||
theta_tmi=beta_ring_tmi*l_ring; |
|||
|
|||
c1e1r=kappa_te_up*kappa_te_down*exp(-theta_tei*0.5)*cos(theta_ter*0.5); |
|||
c1e1i=kappa_te_up*kappa_te_down*exp(-theta_tei*0.5)*sin(theta_ter*0.5); |
|||
c1e2r=t_te_up*t_te_down-exp(-theta_tei)*cos(theta_ter); |
|||
c1e2i=exp(-theta_tei)*sin(theta_ter); |
|||
c1em=pow(t_te_up*t_te_down-exp(-theta_tei)*cos(theta_ter),2)+pow(exp(-theta_tei)*sin(theta_ter),2); |
|||
c1er=(c1e1r*c1e2r-c1e1i*c1e2i)/c1em; |
|||
c1ei=(c1e1r*c1e2i+c1e1i*c1e2r)/c1em; |
|||
|
|||
c1m1r=kappa_tm_up*kappa_tm_down*exp(-theta_tmi*0.5)*cos(theta_tmr*0.5); |
|||
c1m1i=kappa_tm_up*kappa_tm_down*exp(-theta_tmi*0.5)*sin(theta_tmr*0.5); |
|||
c1m2r=t_tm_up*t_tm_down-exp(-theta_tmi)*cos(theta_tmr); |
|||
c1m2i=exp(-theta_tmi)*sin(theta_tmr); |
|||
c1mm=pow(t_tm_up*t_tm_down-exp(-theta_tmi)*cos(theta_tmr),2)+pow(exp(-theta_tmi)*sin(theta_tmr),2); |
|||
c1mr=(c1m1r*c1m2r-c1m1i*c1m2i)/c1mm; |
|||
c1mi=(c1m1r*c1m2i+c1m1i*c1m2r)/c1mm; |
|||
|
|||
c2e1r=t_te_up-t_te_down*exp(-theta_tei)*cos(theta_ter); |
|||
c2e1i=-t_te_down*exp(-theta_tei)*sin(theta_ter); |
|||
c2e2r=t_te_up*t_te_down-exp(-theta_tei)*cos(theta_ter); |
|||
c2e2i=exp(-theta_tei)*sin(theta_ter); |
|||
c2em=pow(t_te_up*t_te_down-exp(-theta_tei)*cos(theta_ter),2)+pow(exp(-theta_tei)*sin(theta_ter),2); |
|||
c2er=(c2e1r*c2e2r-c2e1i*c2e2i)/c2em; |
|||
c2ei=(c2e1r*c2e2i+c2e1i*c2e2r)/c2em; |
|||
|
|||
c2m1r=t_tm_up-t_tm_down*exp(-theta_tmi)*cos(theta_tmr); |
|||
c2m1i=-t_tm_down*exp(-theta_tmi)*sin(theta_tmr); |
|||
c2m2r=t_tm_up*t_tm_down-exp(-theta_tmi)*cos(theta_tmr); |
|||
c2m2i=exp(-theta_tmi)*sin(theta_tmr); |
|||
c2mm=pow(t_tm_up*t_tm_down-exp(-theta_tmi)*cos(theta_tmr),2)+pow(exp(-theta_tmi)*sin(theta_tmr),2); |
|||
c2mr=(c2m1r*c2m2r-c2m1i*c2m2i)/c2mm; |
|||
c2mi=(c2m1r*c2m2i+c2m1i*c2m2r)/c2mm; |
|||
|
|||
c3e1r=t_te_down-t_te_up*exp(-theta_tei)*cos(theta_ter); |
|||
c3e1i=-t_te_up*exp(-theta_tei)*sin(theta_ter); |
|||
c3e2r=t_te_up*t_te_down-exp(-theta_tei)*cos(theta_ter); |
|||
c3e2i=exp(-theta_tei)*sin(theta_ter); |
|||
c3em=pow(t_te_up*t_te_down-exp(-theta_tei)*cos(theta_ter),2)+pow(exp(-theta_tei)*sin(theta_ter),2); |
|||
c3er=(c3e1r*c3e2r-c3e1i*c3e2i)/c3em; |
|||
c3ei=(c3e1r*c3e2i+c3e1i*c3e2r)/c3em; |
|||
|
|||
c3m1r=t_tm_down-t_tm_up*exp(-theta_tmi)*cos(theta_tmr); |
|||
c3m1i=-t_tm_up*exp(-theta_tmi)*sin(theta_tmr); |
|||
c3m2r=t_tm_up*t_tm_down-exp(-theta_tmi)*cos(theta_tmr); |
|||
c3m2i=exp(-theta_tmi)*sin(theta_tmr); |
|||
c3mm=pow(t_tm_up*t_tm_down-exp(-theta_tmi)*cos(theta_tmr),2)+pow(exp(-theta_tmi)*sin(theta_tmr),2); |
|||
c3mr=(c3m1r*c3m2r-c3m1i*c3m2i)/c3mm; |
|||
c3mi=(c3m1r*c3m2i+c3m1i*c3m2r)/c3mm; |
|||
|
|||
cber=exp(beta_bus_tei*l_bus)*cos(-beta_bus_ter*l_bus-phasedelay_bus_te_u); |
|||
cbei=exp(beta_bus_tei*l_bus)*sin(-beta_bus_ter*l_bus-phasedelay_bus_te_u); |
|||
cbmr=exp(beta_bus_tmi*l_bus)*cos(-beta_bus_tmr*l_bus-phasedelay_bus_tm_u); |
|||
cbmi=exp(beta_bus_tmi*l_bus)*sin(-beta_bus_tmr*l_bus-phasedelay_bus_tm_u); |
|||
|
|||
t11r=c1er*cber-c1ei*cbei; |
|||
t11i=c1er*cbei+c1ei*cber; |
|||
t12r=0; |
|||
t12i=0; |
|||
t13r=c3er*cber-c3ei*cbei; |
|||
t13i=c3er*cbei+c3ei*cber; |
|||
t14r=0; |
|||
t14i=0; |
|||
t21r=0; |
|||
t21i=0; |
|||
t22r=c1mr*cbmr-c1mi*cbmi; |
|||
t22i=c1mr*cbmi+c1mi*cbmr; |
|||
t23r=0; |
|||
t23i=0; |
|||
t24r=c3mr*cbmr-c3mi*cbmi; |
|||
t24i=c3mr*cbmi+c3mi*cbmr; |
|||
t31r=c2er*cber-c2ei*cbei; |
|||
t31i=c2er*cbei+c2ei*cber; |
|||
t32r=0; |
|||
t32i=0; |
|||
t33r=c1er*cber-c1ei*cbei; |
|||
t33i=c1er*cbei+c1ei*cber; |
|||
t34r=0; |
|||
t34i=0; |
|||
t41r=0; |
|||
t41i=0; |
|||
t42r=c2mr*cbmr-c2mi*cbmi; |
|||
t42i=c2mr*cbmi+c2mi*cbmr; |
|||
t43r=0; |
|||
t43i=0; |
|||
t44r=c1mr*cbmr-c1mi*cbmi; |
|||
t44i=c1mr*cbmi+c1mi*cbmr; |
|||
|
|||
eeor1=t11r*eeir2+t12r*emir2+t13r*eeir3+t14r*emir3-t11i*eeii2-t12i*emii2-t13i*eeii3-t14i*emii3; |
|||
eeoi1=t11r*eeii2+t12r*emii2+t13r*eeii3+t14r*emii3+t11i*eeir2+t12i*emir2+t13i*eeir3+t14i*emir3; |
|||
emor1=t21r*eeir2+t22r*emir2+t23r*eeir3+t24r*emir3-t21i*eeii2-t22i*emii2-t23i*eeii3-t24i*emii3; |
|||
emoi1=t21r*eeii2+t22r*emii2+t23r*eeii3+t24r*emii3+t21i*eeir2+t22i*emir2+t23i*eeir3+t24i*emir3; |
|||
eeor4=t31r*eeir2+t32r*emir2+t33r*eeir3+t34r*emir3-t31i*eeii2-t32i*emii2-t33i*eeii3-t34i*emii3; |
|||
eeoi4=t31r*eeii2+t32r*emii2+t33r*eeii3+t34r*emii3+t31i*eeir2+t32i*emir2+t33i*eeir3+t34i*emir3; |
|||
emor4=t41r*eeir2+t42r*emir2+t43r*eeir3+t44r*emir3-t41i*eeii2-t42i*emii2-t43i*eeii3-t44i*emii3; |
|||
emoi4=t41r*eeii2+t42r*emii2+t43r*eeii3+t44r*emii3+t41i*eeir2+t42i*emir2+t43i*eeir3+t44i*emir3; |
|||
|
|||
if (modespec == 1) begin |
|||
V(Opow1) <+ pow(eeor1,2)+pow(eeoi1,2); |
|||
V(Ophase1) <+ atan2(eeoi1,eeor1)*360.0/(2*`M_PI); |
|||
V(Opow2) <+ pow(eeor4,2)+pow(eeoi4,2); |
|||
V(Ophase2) <+ atan2(eeoi4,eeor4)*360.0/(2*`M_PI); |
|||
end |
|||
else if (modespec == 2) begin |
|||
V(Opow1) <+ pow(emor1,2)+pow(emoi1,2); |
|||
V(Ophase1) <+ atan2(emoi1,emor1)*360.0/(2*`M_PI); |
|||
V(Opow2) <+ pow(emor4,2)+pow(emoi4,2); |
|||
V(Ophase2) <+ atan2(emoi4,emor4)*360.0/(2*`M_PI); |
|||
end |
|||
V(Olam1) <+ lam; |
|||
V(Olam2) <+ lam; |
|||
end |
|||
|
|||
endmodule |
@ -0,0 +1,617 @@ |
|||
//VerilogA for ring,basicfilter_withv,veriloga |
|||
|
|||
`include "constants.vams" |
|||
`include "disciplines.vams" |
|||
|
|||
`define MAX_TABLE_SIZE 1000 |
|||
|
|||
module basicfilter_withv(Ipow1,Iphase1,Ilam1,Ipow2,Iphase2,Ilam2,Opow1,Ophase1,Olam1,Opow2,Ophase2,Olam2,Vbias); |
|||
parameter integer modespec = 1 from [1:2]; |
|||
parameter integer alpha_use_dBm = 1 from [0:1]; |
|||
parameter real l_bus = 1e-3 from [0:inf); |
|||
parameter real r_ring = 7.5e-6 from [0:inf); |
|||
parameter real phasedelay_bus_te = 0; |
|||
parameter real phasedelay_bus_tm = 0; |
|||
parameter real phasedelay_ring_te = 0; |
|||
parameter real phasedelay_ring_tm = 0; |
|||
parameter integer read_neff = 0 from [0:1]; |
|||
parameter string file_neff_bus_te = "./neff_bus_te.txt"; |
|||
parameter string file_neff_bus_tm = "./neff_bus_tm.txt"; |
|||
parameter string file_neff_ring_te = "./neff_ring_te.txt"; |
|||
parameter string file_neff_ring_tm = "./neff_ring_tm.txt"; |
|||
parameter string file_deltaneff_te = "./deltaneff_te.txt"; |
|||
parameter string file_deltaneff_tm = "./deltaneff_tm.txt"; |
|||
parameter real neff_bus_te = 2.6 from (0:inf); |
|||
parameter real neff_bus_tm = 2.6 from (0:inf); |
|||
parameter real neff_ring_te = 2.6 from (0:inf); |
|||
parameter real neff_ring_tm = 2.6 from (0:inf); |
|||
parameter real attenu_bus_te = 0 from [0:inf); |
|||
parameter real attenu_bus_tm = 0 from [0:inf); |
|||
parameter real attenu_ring_te = 0 from [0:inf); |
|||
parameter real attenu_ring_tm = 0 from [0:inf); |
|||
parameter real delta_neff_perv_te = 0; |
|||
parameter real delta_neff_perv_tm = 0; |
|||
parameter real delta_attenu_perv_te = 0; |
|||
parameter real delta_attenu_perv_tm = 0; |
|||
parameter real reffreq = 193.1T from (0:inf); |
|||
parameter real n_gv_bus_te = 4.2 from (0:inf); |
|||
parameter real n_gv_bus_tm = 4.2 from (0:inf); |
|||
parameter real n_gv_ring_te = 4.2 from (0:inf); |
|||
parameter real n_gv_ring_tm = 4.2 from (0:inf); |
|||
parameter real disper_bus_te = 0; |
|||
parameter real disper_bus_tm = 0; |
|||
parameter real disper_ring_te = 0; |
|||
parameter real disper_ring_tm = 0; |
|||
parameter integer read_coupling_ring = 0 from [0:1]; |
|||
parameter real coupling_ring_te_up = 0.145 from [0:1]; |
|||
parameter real coupling_ring_tm_up = 0.145 from [0:1]; |
|||
parameter real coupling_ring_te_down = 0.145 from [0:1]; |
|||
parameter real coupling_ring_tm_down = 0.145 from [0:1]; |
|||
parameter string file_coupling_ring_te_up = "./coupling_te.txt"; |
|||
parameter string file_coupling_ring_tm_up = "./coupling_tm.txt"; |
|||
parameter string file_coupling_ring_te_down = "./coupling_te.txt"; |
|||
parameter string file_coupling_ring_tm_down = "./coupling_tm.txt"; |
|||
//parameter real coupling_tem = 0; |
|||
|
|||
input Ipow1,Iphase1,Ilam1,Ipow2,Iphase2,Ilam2,Vbias; |
|||
output Opow1,Ophase1,Olam1,Opow2,Ophase2,Olam2; |
|||
electrical Ipow1,Iphase1,Ilam1,Ipow2,Iphase2,Ilam2,Opow1,Ophase1,Olam1,Opow2,Ophase2,Olam2,Vbias; |
|||
|
|||
real eeir2,eeii2,emir2,emii2,eeir3,eeii3,emir3,emii3; |
|||
real eeor1,eeoi1,emor1,emoi1,eeor4,eeoi4,emor4,emoi4; |
|||
real t11r,t11i,t12r,t12i,t13r,t13i,t14r,t14i,t21r,t21i,t22r,t22i,t23r,t23i,t24r,t24i,t31r,t31i,t32r,t32i,t33r,t33i,t34r,t34i,t41r,t41i,t42r,t42i,t43r,t43i,t44r,t44i; |
|||
real neff_bus_ter,neff_bus_tei,neff_bus_tmr,neff_bus_tmi; |
|||
real neff_ring_ter,neff_ring_tei,neff_ring_tmr,neff_ring_tmi; |
|||
real beta_bus_te,beta_bus_tm,beta_ring_te,beta_ring_tm; |
|||
real alpha_bus_te,alpha_bus_tm,alpha_ring_te,alpha_ring_tm; |
|||
real beta_bus_ter,beta_bus_tei,beta_bus_tmr,beta_bus_tmi,beta_ring_ter,beta_ring_tei,beta_ring_tmr,beta_ring_tmi; |
|||
real t_te_up,t_tm_up,t_te_down,t_tm_down; |
|||
real theta_ter,theta_tei,theta_tmr,theta_tmi; |
|||
real kappa_te_up,kappa_tm_up,kappa_te_down,kappa_tm_down; |
|||
real c1er,c1ei,c1em,c1mr,c1mi,c1mm,c2er,c2ei,c2em,c2mr,c2mi,c2mm,c3er,c3ei,c3em,c3mr,c3mi,c3mm; |
|||
real c1e1r,c1e1i,c1e2r,c1e2i,c1m1r,c1m1i,c1m2r,c1m2i; |
|||
real c2e1r,c2e1i,c2e2r,c2e2i,c2m1r,c2m1i,c2m2r,c2m2i; |
|||
real c3e1r,c3e1i,c3e2r,c3e2i,c3m1r,c3m1i,c3m2r,c3m2i; |
|||
real cber,cbei,cbmr,cbmi; |
|||
real l_ring=2*`M_PI*r_ring; |
|||
real freq,lam; |
|||
real neff_bus_ter_u,neff_bus_tmr_u,neff_ring_ter_u,neff_ring_tmr_u; |
|||
real neff_bus_tei_u,neff_bus_tmi_u,neff_ring_tei_u,neff_ring_tmi_u; |
|||
real coupling_ring_te_up_u,coupling_ring_tm_up_u,coupling_ring_te_down_u,coupling_ring_tm_down_u; |
|||
real attenu_bus_te_u,attenu_bus_tm_u,attenu_ring_te_u,attenu_ring_tm_u; |
|||
real delta_neff_ter,delta_neff_tei,delta_neff_tmr,delta_neff_tmi; |
|||
real phasedelay_bus_te_u=phasedelay_bus_te/360.0*2*`M_PI; |
|||
real phasedelay_bus_tm_u=phasedelay_bus_tm/360.0*2*`M_PI; |
|||
real phasedelay_ring_te_u=phasedelay_ring_te/360.0*2*`M_PI; |
|||
real phasedelay_ring_tm_u=phasedelay_ring_tm/360.0*2*`M_PI; |
|||
|
|||
integer file_te,file_tm; |
|||
integer file_bus_te,file_bus_tm,file_ring_te,file_ring_tm; |
|||
real neff_bus_te_lamdata[0:`MAX_TABLE_SIZE-1]; |
|||
real neff_bus_tm_lamdata[0:`MAX_TABLE_SIZE-1]; |
|||
real neff_ring_te_lamdata[0:`MAX_TABLE_SIZE-1]; |
|||
real neff_ring_tm_lamdata[0:`MAX_TABLE_SIZE-1]; |
|||
real neff_bus_te_data_r[0:`MAX_TABLE_SIZE-1]; |
|||
real neff_bus_te_data_i[0:`MAX_TABLE_SIZE-1]; |
|||
real neff_bus_tm_data_r[0:`MAX_TABLE_SIZE-1]; |
|||
real neff_bus_tm_data_i[0:`MAX_TABLE_SIZE-1]; |
|||
real neff_ring_te_data_r[0:`MAX_TABLE_SIZE-1]; |
|||
real neff_ring_te_data_i[0:`MAX_TABLE_SIZE-1]; |
|||
real neff_ring_tm_data_r[0:`MAX_TABLE_SIZE-1]; |
|||
real neff_ring_tm_data_i[0:`MAX_TABLE_SIZE-1]; |
|||
real coupling_ring_te_up_lamdata[0:`MAX_TABLE_SIZE-1]; |
|||
real coupling_ring_tm_up_lamdata[0:`MAX_TABLE_SIZE-1]; |
|||
real coupling_ring_te_up_data[0:`MAX_TABLE_SIZE-1]; |
|||
real coupling_ring_tm_up_data[0:`MAX_TABLE_SIZE-1]; |
|||
real coupling_ring_te_down_lamdata[0:`MAX_TABLE_SIZE-1]; |
|||
real coupling_ring_tm_down_lamdata[0:`MAX_TABLE_SIZE-1]; |
|||
real coupling_ring_te_down_data[0:`MAX_TABLE_SIZE-1]; |
|||
real coupling_ring_tm_down_data[0:`MAX_TABLE_SIZE-1]; |
|||
real delta_neff_te_vdata[0:`MAX_TABLE_SIZE-1]; |
|||
real delta_neff_tm_vdata[0:`MAX_TABLE_SIZE-1]; |
|||
real delta_neff_te_data_r[0:`MAX_TABLE_SIZE-1]; |
|||
real delta_neff_te_data_i[0:`MAX_TABLE_SIZE-1]; |
|||
real delta_neff_tm_data_r[0:`MAX_TABLE_SIZE-1]; |
|||
real delta_neff_tm_data_i[0:`MAX_TABLE_SIZE-1]; |
|||
integer num_lines_neff_bus_te,num_lines_neff_bus_tm,num_lines_neff_ring_te,num_lines_neff_ring_tm; |
|||
integer num_lines_coupling_te,num_lines_coupling_tm; |
|||
integer num_lines_deltaneff_te,num_lines_deltaneff_tm; |
|||
|
|||
integer i; |
|||
integer readfile_neff=0; |
|||
integer readfile_coupling_ring=0; |
|||
integer readfile_delta_neff=0; |
|||
|
|||
real iph2,iph3; |
|||
analog begin |
|||
if (V(Ilam2) == 0) begin |
|||
lam=V(Ilam1); |
|||
end |
|||
else if (V(Ilam1) == 0) begin |
|||
lam=V(Ilam2); |
|||
end |
|||
else begin |
|||
lam=V(Ilam2); |
|||
end |
|||
freq=`P_C/lam; |
|||
iph2=V(Iphase2)/360.0*2*`M_PI; |
|||
iph3=V(Iphase1)/360.0*2*`M_PI; |
|||
if (modespec == 1) begin |
|||
eeir2=sqrt(V(Ipow2))*cos(iph2); |
|||
eeii2=sqrt(V(Ipow2))*sin(iph2); |
|||
emir2=0; |
|||
emii2=0; |
|||
eeir3=sqrt(V(Ipow1))*cos(iph3); |
|||
eeii3=sqrt(V(Ipow1))*sin(iph3); |
|||
emir3=0; |
|||
emii3=0; |
|||
end |
|||
else if (modespec == 2) begin |
|||
eeir2=0; |
|||
eeii2=0; |
|||
emir2=sqrt(V(Ipow2))*cos(iph2); |
|||
emii2=sqrt(V(Ipow2))*sin(iph2); |
|||
eeir3=0; |
|||
eeii3=0; |
|||
emir3=sqrt(V(Ipow1))*cos(iph3); |
|||
emii3=sqrt(V(Ipow1))*sin(iph3); |
|||
end |
|||
|
|||
if (read_neff == 1) begin |
|||
if (readfile_neff == 0) begin |
|||
readfile_neff=1; |
|||
end |
|||
if (readfile_delta_neff == 0) begin |
|||
readfile_delta_neff=1; |
|||
end |
|||
end |
|||
else begin |
|||
delta_neff_ter=delta_neff_perv_te*V(Vbias); |
|||
delta_neff_tmr=delta_neff_perv_tm*V(Vbias); |
|||
beta_bus_te=2*`M_PI*reffreq/`P_C*(neff_bus_te)+2*`M_PI/`P_C*n_gv_bus_te*(freq-reffreq)-`M_PI*`P_C*disper_bus_te/pow(reffreq,2)*pow(freq-reffreq,2); |
|||
beta_bus_tm=2*`M_PI*reffreq/`P_C*(neff_bus_tm)+2*`M_PI/`P_C*n_gv_bus_tm*(freq-reffreq)-`M_PI*`P_C*disper_bus_tm/pow(reffreq,2)*pow(freq-reffreq,2); |
|||
beta_ring_te=2*`M_PI*reffreq/`P_C*(neff_ring_te+delta_neff_ter)+2*`M_PI/`P_C*n_gv_ring_te*(freq-reffreq)-`M_PI*`P_C*disper_ring_te/pow(reffreq,2)*pow(freq-reffreq,2); |
|||
beta_ring_tm=2*`M_PI*reffreq/`P_C*(neff_ring_tm+delta_neff_tmr)+2*`M_PI/`P_C*n_gv_ring_tm*(freq-reffreq)-`M_PI*`P_C*disper_ring_tm/pow(reffreq,2)*pow(freq-reffreq,2); |
|||
attenu_bus_te_u=attenu_bus_te; |
|||
attenu_bus_tm_u=attenu_bus_tm; |
|||
attenu_ring_te_u=attenu_ring_te+delta_attenu_perv_te*V(Vbias); |
|||
attenu_ring_tm_u=attenu_ring_tm+delta_attenu_perv_tm*V(Vbias); |
|||
if (alpha_use_dBm == 1) begin |
|||
alpha_bus_te=attenu_bus_te_u/10*ln(10); |
|||
alpha_bus_tm=attenu_bus_tm_u/10*ln(10); |
|||
alpha_ring_te=attenu_ring_te_u/10*ln(10); |
|||
alpha_ring_tm=attenu_ring_tm_u/10*ln(10); |
|||
end |
|||
else begin |
|||
alpha_bus_te=attenu_bus_te_u; |
|||
alpha_bus_tm=attenu_bus_tm_u; |
|||
alpha_ring_te=attenu_ring_te_u; |
|||
alpha_ring_tm=attenu_ring_tm_u; |
|||
end |
|||
end |
|||
|
|||
if (readfile_delta_neff == 1) begin |
|||
file_te=$fopen(file_deltaneff_te,"r"); |
|||
file_tm=$fopen(file_deltaneff_tm,"r"); |
|||
if (file_te == 0 && file_tm == 0) begin |
|||
$display("Error: cannot open file %s and %s",file_deltaneff_te,file_deltaneff_tm); |
|||
$finish; |
|||
end |
|||
if (file_te != 0) begin |
|||
$fscanf(file_te,"%d",num_lines_deltaneff_te); |
|||
for (i=0;i<num_lines_deltaneff_te;i=i+1) begin |
|||
$fscanf(file_te,"%f %f %f",delta_neff_te_vdata[i],delta_neff_te_data_r[i],delta_neff_te_data_i[i]); |
|||
end |
|||
if (file_tm == 0) begin |
|||
$display("Warning: cannot open file %s, using %s instead",file_deltaneff_tm,file_deltaneff_te); |
|||
num_lines_deltaneff_tm=num_lines_deltaneff_te; |
|||
for (i=0;i<num_lines_deltaneff_te;i=i+1) begin |
|||
delta_neff_tm_vdata[i]=delta_neff_te_vdata[i]; |
|||
delta_neff_tm_data_r[i]=delta_neff_te_data_r[i]; |
|||
delta_neff_tm_data_i[i]=delta_neff_te_data_i[i]; |
|||
end |
|||
end |
|||
end |
|||
if (file_tm != 0) begin |
|||
$fscanf(file_tm,"%d",num_lines_deltaneff_tm); |
|||
for (i=0;i<num_lines_deltaneff_tm;i=i+1) begin |
|||
$fscanf(file_tm,"%f %f %f",delta_neff_tm_vdata[i],delta_neff_tm_data_r[i],delta_neff_tm_data_i[i]); |
|||
end |
|||
if (file_te == 0) begin |
|||
$display("Warning: cannot open file %s, using %s instead",file_deltaneff_te,file_deltaneff_tm); |
|||
num_lines_deltaneff_te=num_lines_deltaneff_tm; |
|||
for (i=0;i<num_lines_deltaneff_tm;i=i+1) begin |
|||
delta_neff_te_vdata[i]=delta_neff_tm_vdata[i]; |
|||
delta_neff_te_data_r[i]=delta_neff_tm_data_r[i]; |
|||
delta_neff_te_data_i[i]=delta_neff_tm_data_i[i]; |
|||
end |
|||
end |
|||
end |
|||
$fclose(file_te); |
|||
$fclose(file_tm); |
|||
readfile_delta_neff=2; |
|||
end |
|||
|
|||
if (readfile_delta_neff == 2) begin |
|||
delta_neff_ter=$table_model(V(Vbias),delta_neff_te_vdata,delta_neff_te_data_r,"3E"); |
|||
delta_neff_tei=$table_model(V(Vbias),delta_neff_te_vdata,delta_neff_te_data_i,"3E"); |
|||
if (V(Vbias) < delta_neff_te_vdata[0]) begin |
|||
$display("Warning: V(Vbias) %f is out of range of the delta_neff_te table",V(Vbias)); |
|||
end |
|||
else if (V(Vbias) > delta_neff_te_vdata[num_lines_deltaneff_te-1]) begin |
|||
$display("Warning: V(Vbias) %f is out of range of the delta_neff_te table",V(Vbias)); |
|||
end |
|||
delta_neff_tmr=$table_model(V(Vbias),delta_neff_tm_vdata,delta_neff_tm_data_r,"3E"); |
|||
delta_neff_tmi=$table_model(V(Vbias),delta_neff_tm_vdata,delta_neff_tm_data_i,"3E"); |
|||
if (V(Vbias) < delta_neff_tm_vdata[0]) begin |
|||
$display("Warning: V(Vbias) %f is out of range of the delta_neff_tm table",V(Vbias)); |
|||
end |
|||
else if (V(Vbias) > delta_neff_tm_vdata[num_lines_deltaneff_tm-1]) begin |
|||
$display("Warning: V(Vbias) %f is out of range of the delta_neff_tm table",V(Vbias)); |
|||
end |
|||
end |
|||
|
|||
if (readfile_neff == 1) begin |
|||
file_bus_te=$fopen(file_neff_bus_te,"r"); |
|||
file_bus_tm=$fopen(file_neff_bus_tm,"r"); |
|||
file_ring_te=$fopen(file_neff_ring_te,"r"); |
|||
file_ring_tm=$fopen(file_neff_ring_tm,"r"); |
|||
if (file_bus_te == 0 && file_bus_tm == 0) begin |
|||
$display("Error: cannot open file %s and %s",file_neff_bus_te,file_neff_bus_tm); |
|||
$finish; |
|||
end |
|||
if (file_ring_te == 0 && file_ring_tm == 0) begin |
|||
$display("Error: cannot open file %s and %s",file_neff_ring_te,file_neff_ring_tm); |
|||
$finish; |
|||
end |
|||
if (file_bus_te != 0) begin |
|||
$fscanf(file_bus_te,"%d",num_lines_neff_bus_te); |
|||
for (i=0;i<num_lines_neff_bus_te;i=i+1) begin |
|||
$fscanf(file_bus_te,"%f %f %f",neff_bus_te_lamdata[i],neff_bus_te_data_r[i],neff_bus_te_data_i[i]); |
|||
end |
|||
if (file_bus_tm == 0) begin |
|||
$display("Warning: cannot open file %s, using %s instead",file_neff_bus_tm,file_neff_bus_te); |
|||
num_lines_neff_bus_tm=num_lines_neff_bus_te; |
|||
for (i=0;i<num_lines_neff_bus_te;i=i+1) begin |
|||
neff_bus_tm_lamdata[i]=neff_bus_te_lamdata[i]; |
|||
neff_bus_tm_data_r[i]=neff_bus_te_data_r[i]; |
|||
neff_bus_tm_data_i[i]=neff_bus_te_data_i[i]; |
|||
end |
|||
end |
|||
end |
|||
if (file_bus_tm != 0) begin |
|||
$fscanf(file_bus_tm,"%d",num_lines_neff_bus_tm); |
|||
for (i=0;i<num_lines_neff_bus_tm;i=i+1) begin |
|||
$fscanf(file_bus_tm,"%f %f %f",neff_bus_tm_lamdata[i],neff_bus_tm_data_r[i],neff_bus_tm_data_i[i]); |
|||
end |
|||
if (file_bus_te == 0) begin |
|||
$display("Warning: cannot open file %s, using %s instead",file_neff_bus_te,file_neff_bus_tm); |
|||
num_lines_neff_bus_te=num_lines_neff_bus_tm; |
|||
for (i=0;i<num_lines_neff_bus_tm;i=i+1) begin |
|||
neff_bus_te_lamdata[i]=neff_bus_tm_lamdata[i]; |
|||
neff_bus_te_data_r[i]=neff_bus_tm_data_r[i]; |
|||
neff_bus_te_data_i[i]=neff_bus_tm_data_i[i]; |
|||
end |
|||
end |
|||
end |
|||
$fclose(file_bus_te); |
|||
$fclose(file_bus_tm); |
|||
if (file_ring_te != 0) begin |
|||
$fscanf(file_ring_te,"%d",num_lines_neff_ring_te); |
|||
for (i=0;i<num_lines_neff_ring_te;i=i+1) begin |
|||
$fscanf(file_ring_te,"%f %f %f",neff_ring_te_lamdata[i],neff_ring_te_data_r[i],neff_ring_te_data_i[i]); |
|||
end |
|||
if (file_ring_tm == 0) begin |
|||
$display("Warning: cannot open file %s, using %s instead",file_neff_ring_tm,file_neff_ring_te); |
|||
num_lines_neff_ring_tm=num_lines_neff_ring_te; |
|||
for (i=0;i<num_lines_neff_ring_te;i=i+1) begin |
|||
neff_ring_tm_lamdata[i]=neff_ring_te_lamdata[i]; |
|||
neff_ring_tm_data_r[i]=neff_ring_te_data_r[i]; |
|||
end |
|||
end |
|||
end |
|||
if (file_ring_tm != 0) begin |
|||
$fscanf(file_ring_tm,"%d",num_lines_neff_ring_tm); |
|||
for (i=0;i<num_lines_neff_ring_tm;i=i+1) begin |
|||
$fscanf(file_ring_tm,"%f %f %f",neff_ring_tm_lamdata[i],neff_ring_tm_data_r[i],neff_ring_tm_data_i[i]); |
|||
end |
|||
if (file_ring_te == 0) begin |
|||
$display("Warning: cannot open file %s, using %s instead",file_neff_ring_te,file_neff_ring_tm); |
|||
num_lines_neff_ring_te=num_lines_neff_ring_tm; |
|||
for (i=0;i<num_lines_neff_ring_tm;i=i+1) begin |
|||
neff_ring_te_lamdata[i]=neff_ring_tm_lamdata[i]; |
|||
neff_ring_te_data_r[i]=neff_ring_tm_data_r[i]; |
|||
neff_ring_te_data_i[i]=neff_ring_tm_data_i[i]; |
|||
end |
|||
end |
|||
end |
|||
$fclose(file_ring_te); |
|||
$fclose(file_ring_tm); |
|||
readfile_neff=2; |
|||
end |
|||
|
|||
if (readfile_neff ==2) begin |
|||
neff_bus_ter_u=$table_model(lam,neff_bus_te_lamdata,neff_bus_te_data_r,"3E"); |
|||
neff_bus_tei_u=$table_model(lam,neff_bus_te_lamdata,neff_bus_te_data_i,"3E"); |
|||
if (lam < neff_bus_te_lamdata[0]) begin |
|||
$display("Warning: wavelength %e is out of range of the neff_bus_te table",lam); |
|||
end |
|||
else if (lam > neff_bus_te_lamdata[num_lines_neff_bus_te-1]) begin |
|||
$display("Warning: wavelength %e is out of range of the neff_bus_te table",lam); |
|||
end |
|||
neff_bus_tmr_u=$table_model(lam,neff_bus_tm_lamdata,neff_bus_tm_data_r,"3E"); |
|||
neff_bus_tmi_u=$table_model(lam,neff_bus_tm_lamdata,neff_bus_tm_data_i,"3E"); |
|||
if (lam < neff_bus_tm_lamdata[0]) begin |
|||
$display("Warning: wavelength %e is out of range of the neff_bus_tm table",lam); |
|||
end |
|||
else if (lam > neff_bus_tm_lamdata[num_lines_neff_bus_tm-1]) begin |
|||
$display("Warning: wavelength %e is out of range of the neff_bus_tm table",lam); |
|||
end |
|||
neff_ring_ter_u=$table_model(lam,neff_ring_te_lamdata,neff_ring_te_data_r,"3E"); |
|||
neff_ring_tei_u=$table_model(lam,neff_ring_te_lamdata,neff_ring_te_data_i,"3E"); |
|||
if (lam < neff_ring_te_lamdata[0]) begin |
|||
$display("Warning: wavelength %e is out of range of the neff_ring_te table",lam); |
|||
end |
|||
else if (lam > neff_ring_te_lamdata[num_lines_neff_ring_te-1]) begin |
|||
$display("Warning: wavelength %e is out of range of the neff_ring_te table",lam); |
|||
end |
|||
neff_ring_tmr_u=$table_model(lam,neff_ring_tm_lamdata,neff_ring_tm_data_r,"3E"); |
|||
neff_ring_tmi_u=$table_model(lam,neff_ring_tm_lamdata,neff_ring_tm_data_i,"3E"); |
|||
if (lam < neff_ring_tm_lamdata[0]) begin |
|||
$display("Warning: wavelength %e is out of range of the neff_ring_tm table",lam); |
|||
end |
|||
else if (lam > neff_ring_tm_lamdata[num_lines_neff_ring_tm-1]) begin |
|||
$display("Warning: wavelength %e is out of range of the neff_ring_tm table",lam); |
|||
end |
|||
beta_bus_te=2*`M_PI*freq/`P_C*(neff_bus_ter_u); |
|||
beta_bus_tm=2*`M_PI*freq/`P_C*(neff_bus_tmr_u); |
|||
beta_ring_te=2*`M_PI*freq/`P_C*(neff_ring_ter_u+delta_neff_ter); |
|||
beta_ring_tm=2*`M_PI*freq/`P_C*(neff_ring_tmr_u+delta_neff_tmr); |
|||
alpha_bus_te=4*`M_PI*neff_bus_tei_u/lam; |
|||
alpha_bus_tm=4*`M_PI*neff_bus_tmi_u/lam; |
|||
alpha_ring_te=4*`M_PI*(neff_ring_tei_u+delta_neff_tei)/lam; |
|||
alpha_ring_tm=4*`M_PI*(neff_ring_tmi_u+delta_neff_tmi)/lam; |
|||
end |
|||
|
|||
if (read_coupling_ring == 1) begin |
|||
if (readfile_coupling_ring == 0) begin |
|||
readfile_coupling_ring=1; |
|||
end |
|||
end |
|||
else begin |
|||
coupling_ring_te_up_u=coupling_ring_te_up; |
|||
coupling_ring_tm_up_u=coupling_ring_tm_up; |
|||
coupling_ring_te_down_u=coupling_ring_te_down; |
|||
coupling_ring_tm_down_u=coupling_ring_tm_down; |
|||
end |
|||
|
|||
if (readfile_coupling_ring == 1) begin |
|||
file_te=$fopen(file_coupling_ring_te_up,"r"); |
|||
file_tm=$fopen(file_coupling_ring_tm_up,"r"); |
|||
if (file_te == 0 && file_tm == 0) begin |
|||
$display("Error: cannot open file %s and %s",file_coupling_ring_te_up,file_coupling_ring_tm_up); |
|||
$finish; |
|||
end |
|||
if (file_te != 0) begin |
|||
$fscanf(file_te,"%d",num_lines_coupling_te); |
|||
for (i=0;i<num_lines_coupling_te;i=i+1) begin |
|||
$fscanf(file_te,"%f %f",coupling_ring_te_up_lamdata[i],coupling_ring_te_up_data[i]); |
|||
end |
|||
if (file_tm == 0) begin |
|||
$display("Warning: cannot open file %s, using %s instead",file_coupling_ring_tm_up,file_coupling_ring_te_up); |
|||
num_lines_coupling_tm=num_lines_coupling_te; |
|||
for (i=0;i<num_lines_coupling_te;i=i+1) begin |
|||
coupling_ring_tm_up_lamdata[i]=coupling_ring_te_up_lamdata[i]; |
|||
coupling_ring_tm_up_data[i]=coupling_ring_te_up_data[i]; |
|||
end |
|||
end |
|||
end |
|||
if (file_tm != 0) begin |
|||
$fscanf(file_tm,"%d",num_lines_coupling_tm); |
|||
for (i=0;i<num_lines_coupling_tm;i=i+1) begin |
|||
$fscanf(file_tm,"%f %f",coupling_ring_tm_up_lamdata[i],coupling_ring_tm_up_data[i]); |
|||
end |
|||
if (file_te == 0) begin |
|||
$display("Warning: cannot open file %s, using %s instead",file_coupling_ring_te_up,file_coupling_ring_tm_up); |
|||
num_lines_coupling_te=num_lines_coupling_tm; |
|||
for (i=0;i<num_lines_coupling_tm;i=i+1) begin |
|||
coupling_ring_te_up_lamdata[i]=coupling_ring_tm_up_lamdata[i]; |
|||
coupling_ring_te_up_data[i]=coupling_ring_tm_up_data[i]; |
|||
end |
|||
end |
|||
end |
|||
$fclose(file_te); |
|||
$fclose(file_tm); |
|||
|
|||
file_te=$fopen(file_coupling_ring_te_down,"r"); |
|||
file_tm=$fopen(file_coupling_ring_tm_down,"r"); |
|||
if (file_te == 0 && file_tm == 0) begin |
|||
$display("Error: cannot open file %s and %s",file_coupling_ring_te_down,file_coupling_ring_tm_down); |
|||
$finish; |
|||
end |
|||
if (file_te != 0) begin |
|||
$fscanf(file_te,"%d",num_lines_coupling_te); |
|||
for (i=0;i<num_lines_coupling_te;i=i+1) begin |
|||
$fscanf(file_te,"%f %f",coupling_ring_te_down_lamdata[i],coupling_ring_te_down_data[i]); |
|||
end |
|||
if (file_tm == 0) begin |
|||
$display("Warning: cannot open file %s, using %s instead",file_coupling_ring_tm_down,file_coupling_ring_te_down); |
|||
num_lines_coupling_tm=num_lines_coupling_te; |
|||
for (i=0;i<num_lines_coupling_te;i=i+1) begin |
|||
coupling_ring_tm_down_lamdata[i]=coupling_ring_te_down_lamdata[i]; |
|||
coupling_ring_tm_down_data[i]=coupling_ring_te_down_data[i]; |
|||
end |
|||
end |
|||
end |
|||
if (file_tm != 0) begin |
|||
$fscanf(file_tm,"%d",num_lines_coupling_tm); |
|||
for (i=0;i<num_lines_coupling_tm;i=i+1) begin |
|||
$fscanf(file_tm,"%f %f",coupling_ring_tm_down_lamdata[i],coupling_ring_tm_down_data[i]); |
|||
end |
|||
if (file_te == 0) begin |
|||
$display("Warning: cannot open file %s, using %s instead",file_coupling_ring_te_down,file_coupling_ring_tm_down); |
|||
num_lines_coupling_te=num_lines_coupling_tm; |
|||
for (i=0;i<num_lines_coupling_tm;i=i+1) begin |
|||
coupling_ring_te_down_lamdata[i]=coupling_ring_tm_down_lamdata[i]; |
|||
coupling_ring_te_down_data[i]=coupling_ring_tm_down_data[i]; |
|||
end |
|||
end |
|||
end |
|||
$fclose(file_te); |
|||
$fclose(file_tm); |
|||
readfile_coupling_ring=2; |
|||
end |
|||
|
|||
if (readfile_coupling_ring ==2) begin |
|||
coupling_ring_te_up_u=$table_model(lam,coupling_ring_te_up_lamdata,coupling_ring_te_up_data,"3E"); |
|||
coupling_ring_te_down_u=$table_model(lam,coupling_ring_te_down_lamdata,coupling_ring_te_down_data,"3E"); |
|||
if (lam < coupling_ring_te_up_lamdata[0] || lam < coupling_ring_te_down_lamdata[0]) begin |
|||
$display("Warning: wavelength %e is out of range of the coupling_ring_te table",lam); |
|||
end |
|||
else if (lam > coupling_ring_te_up_lamdata[num_lines_coupling_te-1] || lam > coupling_ring_te_down_lamdata[num_lines_coupling_te-1]) begin |
|||
$display("Warning: wavelength %e is out of range of the coupling_ring_te table",lam); |
|||
end |
|||
coupling_ring_tm_up_u=$table_model(lam,coupling_ring_tm_up_lamdata,coupling_ring_tm_up_data,"3E"); |
|||
coupling_ring_tm_down_u=$table_model(lam,coupling_ring_tm_down_lamdata,coupling_ring_tm_down_data,"3E"); |
|||
if (lam < coupling_ring_tm_up_lamdata[0] || lam < coupling_ring_tm_down_lamdata[0]) begin |
|||
$display("Warning: wavelength %e is out of range of the coupling_ring_tm table",lam); |
|||
end |
|||
else if (lam > coupling_ring_tm_up_lamdata[num_lines_coupling_tm-1] || lam > coupling_ring_tm_down_lamdata[num_lines_coupling_tm-1]) begin |
|||
$display("Warning: wavelength %e is out of range of the coupling_ring_tm table",lam); |
|||
end |
|||
end |
|||
|
|||
beta_bus_ter=beta_bus_te; |
|||
beta_bus_tei=-0.5*alpha_bus_te; |
|||
beta_bus_tmr=beta_bus_tm; |
|||
beta_bus_tmi=-0.5*alpha_bus_tm; |
|||
beta_ring_ter=beta_ring_te; |
|||
beta_ring_tei=-0.5*alpha_ring_te; |
|||
beta_ring_tmr=beta_ring_tm; |
|||
beta_ring_tmi=-0.5*alpha_ring_tm; |
|||
|
|||
t_te_up=sqrt(1-coupling_ring_te_up_u); |
|||
t_tm_up=sqrt(1-coupling_ring_tm_up_u); |
|||
t_te_down=sqrt(1-coupling_ring_te_down_u); |
|||
t_tm_down=sqrt(1-coupling_ring_tm_down_u); |
|||
kappa_te_up=sqrt(coupling_ring_te_up_u); |
|||
kappa_tm_up=sqrt(coupling_ring_tm_up_u); |
|||
kappa_te_down=sqrt(coupling_ring_te_down_u); |
|||
kappa_tm_down=sqrt(coupling_ring_tm_down_u); |
|||
theta_ter=beta_ring_ter*l_ring-phasedelay_ring_te_u; |
|||
theta_tei=beta_ring_tei*l_ring; |
|||
theta_tmr=beta_ring_tmr*l_ring-phasedelay_ring_tm_u; |
|||
theta_tmi=beta_ring_tmi*l_ring; |
|||
|
|||
c1e1r=kappa_te_up*kappa_te_down*exp(-theta_tei*0.5)*cos(theta_ter*0.5); |
|||
c1e1i=kappa_te_up*kappa_te_down*exp(-theta_tei*0.5)*sin(theta_ter*0.5); |
|||
c1e2r=t_te_up*t_te_down-exp(-theta_tei)*cos(theta_ter); |
|||
c1e2i=exp(-theta_tei)*sin(theta_ter); |
|||
c1em=pow(t_te_up*t_te_down-exp(-theta_tei)*cos(theta_ter),2)+pow(exp(-theta_tei)*sin(theta_ter),2); |
|||
c1er=(c1e1r*c1e2r-c1e1i*c1e2i)/c1em; |
|||
c1ei=(c1e1r*c1e2i+c1e1i*c1e2r)/c1em; |
|||
|
|||
c1m1r=kappa_tm_up*kappa_tm_down*exp(-theta_tmi*0.5)*cos(theta_tmr*0.5); |
|||
c1m1i=kappa_tm_up*kappa_tm_down*exp(-theta_tmi*0.5)*sin(theta_tmr*0.5); |
|||
c1m2r=t_tm_up*t_tm_down-exp(-theta_tmi)*cos(theta_tmr); |
|||
c1m2i=exp(-theta_tmi)*sin(theta_tmr); |
|||
c1mm=pow(t_tm_up*t_tm_down-exp(-theta_tmi)*cos(theta_tmr),2)+pow(exp(-theta_tmi)*sin(theta_tmr),2); |
|||
c1mr=(c1m1r*c1m2r-c1m1i*c1m2i)/c1mm; |
|||
c1mi=(c1m1r*c1m2i+c1m1i*c1m2r)/c1mm; |
|||
|
|||
c2e1r=t_te_up-t_te_down*exp(-theta_tei)*cos(theta_ter); |
|||
c2e1i=-t_te_down*exp(-theta_tei)*sin(theta_ter); |
|||
c2e2r=t_te_up*t_te_down-exp(-theta_tei)*cos(theta_ter); |
|||
c2e2i=exp(-theta_tei)*sin(theta_ter); |
|||
c2em=pow(t_te_up*t_te_down-exp(-theta_tei)*cos(theta_ter),2)+pow(exp(-theta_tei)*sin(theta_ter),2); |
|||
c2er=(c2e1r*c2e2r-c2e1i*c2e2i)/c2em; |
|||
c2ei=(c2e1r*c2e2i+c2e1i*c2e2r)/c2em; |
|||
|
|||
c2m1r=t_tm_up-t_tm_down*exp(-theta_tmi)*cos(theta_tmr); |
|||
c2m1i=-t_tm_down*exp(-theta_tmi)*sin(theta_tmr); |
|||
c2m2r=t_tm_up*t_tm_down-exp(-theta_tmi)*cos(theta_tmr); |
|||
c2m2i=exp(-theta_tmi)*sin(theta_tmr); |
|||
c2mm=pow(t_tm_up*t_tm_down-exp(-theta_tmi)*cos(theta_tmr),2)+pow(exp(-theta_tmi)*sin(theta_tmr),2); |
|||
c2mr=(c2m1r*c2m2r-c2m1i*c2m2i)/c2mm; |
|||
c2mi=(c2m1r*c2m2i+c2m1i*c2m2r)/c2mm; |
|||
|
|||
c3e1r=t_te_down-t_te_up*exp(-theta_tei)*cos(theta_ter); |
|||
c3e1i=-t_te_up*exp(-theta_tei)*sin(theta_ter); |
|||
c3e2r=t_te_up*t_te_down-exp(-theta_tei)*cos(theta_ter); |
|||
c3e2i=exp(-theta_tei)*sin(theta_ter); |
|||
c3em=pow(t_te_up*t_te_down-exp(-theta_tei)*cos(theta_ter),2)+pow(exp(-theta_tei)*sin(theta_ter),2); |
|||
c3er=(c3e1r*c3e2r-c3e1i*c3e2i)/c3em; |
|||
c3ei=(c3e1r*c3e2i+c3e1i*c3e2r)/c3em; |
|||
|
|||
c3m1r=t_tm_down-t_tm_up*exp(-theta_tmi)*cos(theta_tmr); |
|||
c3m1i=-t_tm_up*exp(-theta_tmi)*sin(theta_tmr); |
|||
c3m2r=t_tm_up*t_tm_down-exp(-theta_tmi)*cos(theta_tmr); |
|||
c3m2i=exp(-theta_tmi)*sin(theta_tmr); |
|||
c3mm=pow(t_tm_up*t_tm_down-exp(-theta_tmi)*cos(theta_tmr),2)+pow(exp(-theta_tmi)*sin(theta_tmr),2); |
|||
c3mr=(c3m1r*c3m2r-c3m1i*c3m2i)/c3mm; |
|||
c3mi=(c3m1r*c3m2i+c3m1i*c3m2r)/c3mm; |
|||
|
|||
cber=exp(beta_bus_tei*l_bus)*cos(-beta_bus_ter*l_bus-phasedelay_bus_te_u); |
|||
cbei=exp(beta_bus_tei*l_bus)*sin(-beta_bus_ter*l_bus-phasedelay_bus_te_u); |
|||
cbmr=exp(beta_bus_tmi*l_bus)*cos(-beta_bus_tmr*l_bus-phasedelay_bus_tm_u); |
|||
cbmi=exp(beta_bus_tmi*l_bus)*sin(-beta_bus_tmr*l_bus-phasedelay_bus_tm_u); |
|||
|
|||
t11r=c1er*cber-c1ei*cbei; |
|||
t11i=c1er*cbei+c1ei*cber; |
|||
t12r=0; |
|||
t12i=0; |
|||
t13r=c3er*cber-c3ei*cbei; |
|||
t13i=c3er*cbei+c3ei*cber; |
|||
t14r=0; |
|||
t14i=0; |
|||
t21r=0; |
|||
t21i=0; |
|||
t22r=c1mr*cbmr-c1mi*cbmi; |
|||
t22i=c1mr*cbmi+c1mi*cbmr; |
|||
t23r=0; |
|||
t23i=0; |
|||
t24r=c3mr*cbmr-c3mi*cbmi; |
|||
t24i=c3mr*cbmi+c3mi*cbmr; |
|||
t31r=c2er*cber-c2ei*cbei; |
|||
t31i=c2er*cbei+c2ei*cber; |
|||
t32r=0; |
|||
t32i=0; |
|||
t33r=c1er*cber-c1ei*cbei; |
|||
t33i=c1er*cbei+c1ei*cber; |
|||
t34r=0; |
|||
t34i=0; |
|||
t41r=0; |
|||
t41i=0; |
|||
t42r=c2mr*cbmr-c2mi*cbmi; |
|||
t42i=c2mr*cbmi+c2mi*cbmr; |
|||
t43r=0; |
|||
t43i=0; |
|||
t44r=c1mr*cbmr-c1mi*cbmi; |
|||
t44i=c1mr*cbmi+c1mi*cbmr; |
|||
|
|||
eeor1=t11r*eeir2+t12r*emir2+t13r*eeir3+t14r*emir3-t11i*eeii2-t12i*emii2-t13i*eeii3-t14i*emii3; |
|||
eeoi1=t11r*eeii2+t12r*emii2+t13r*eeii3+t14r*emii3+t11i*eeir2+t12i*emir2+t13i*eeir3+t14i*emir3; |
|||
emor1=t21r*eeir2+t22r*emir2+t23r*eeir3+t24r*emir3-t21i*eeii2-t22i*emii2-t23i*eeii3-t24i*emii3; |
|||
emoi1=t21r*eeii2+t22r*emii2+t23r*eeii3+t24r*emii3+t21i*eeir2+t22i*emir2+t23i*eeir3+t24i*emir3; |
|||
eeor4=t31r*eeir2+t32r*emir2+t33r*eeir3+t34r*emir3-t31i*eeii2-t32i*emii2-t33i*eeii3-t34i*emii3; |
|||
eeoi4=t31r*eeii2+t32r*emii2+t33r*eeii3+t34r*emii3+t31i*eeir2+t32i*emir2+t33i*eeir3+t34i*emir3; |
|||
emor4=t41r*eeir2+t42r*emir2+t43r*eeir3+t44r*emir3-t41i*eeii2-t42i*emii2-t43i*eeii3-t44i*emii3; |
|||
emoi4=t41r*eeii2+t42r*emii2+t43r*eeii3+t44r*emii3+t41i*eeir2+t42i*emir2+t43i*eeir3+t44i*emir3; |
|||
|
|||
if (modespec == 1) begin |
|||
V(Opow1) <+ pow(eeor1,2)+pow(eeoi1,2); |
|||
V(Ophase1) <+ atan2(eeoi1,eeor1)*360.0/(2*`M_PI); |
|||
V(Opow2) <+ pow(eeor4,2)+pow(eeoi4,2); |
|||
V(Ophase2) <+ atan2(eeoi4,eeor4)*360.0/(2*`M_PI); |
|||
end |
|||
else if (modespec == 2) begin |
|||
V(Opow1) <+ pow(emor1,2)+pow(emoi1,2); |
|||
V(Ophase1) <+ atan2(emoi1,emor1)*360.0/(2*`M_PI); |
|||
V(Opow2) <+ pow(emor4,2)+pow(emoi4,2); |
|||
V(Ophase2) <+ atan2(emoi4,emor4)*360.0/(2*`M_PI); |
|||
end |
|||
V(Olam1) <+ lam; |
|||
V(Olam2) <+ lam; |
|||
end |
|||
|
|||
endmodule |
@ -0,0 +1,140 @@ |
|||
//VerilogA for ring,basicreso,veriloga |
|||
|
|||
`include "constants.vams" |
|||
`include "disciplines.vams" |
|||
|
|||
module basicreso(Ipow,Iphase,Ilam,Opow,Ophase,Olam); |
|||
parameter integer modespec = 1 from [1:2]; |
|||
parameter integer alpha_use_dBm = 1 from [0:1]; |
|||
parameter real l_bus = 1e-3 from [0:inf); |
|||
parameter real r_ring = 7.5e-6 from [0:inf); |
|||
parameter real attenu_bus_te = 0 from [0:inf); |
|||
parameter real attenu_bus_tm = 0 from [0:inf); |
|||
parameter real attenu_ring_te = 0 from [0:inf); |
|||
parameter real attenu_ring_tm = 0 from [0:inf); |
|||
parameter real phasedelay_bus_te = 0; |
|||
parameter real phasedelay_bus_tm = 0; |
|||
parameter real phasedelay_ring_te = 0; |
|||
parameter real phasedelay_ring_tm = 0; |
|||
parameter real neff_te = 2.6 from (0:inf); |
|||
parameter real neff_tm = 2.6 from (0:inf); |
|||
parameter real coupling_ring_te = 0.145 from [0:1]; |
|||
parameter real coupling_ring_tm = 0.145 from [0:1]; |
|||
parameter real reffreq = 193.1T from (0:inf); |
|||
parameter real n_gv_te = 4.2 from (0:inf); |
|||
parameter real n_gv_tm = 4.2 from (0:inf); |
|||
parameter real disper_te = 0 from [0:inf); |
|||
parameter real disper_tm = 0 from [0:inf); |
|||
//parameter real coupling_tem = 0; |
|||
|
|||
input Ipow,Iphase,Ilam; |
|||
output Opow,Ophase,Olam; |
|||
electrical Ipow,Iphase,Ilam,Opow,Ophase,Olam; |
|||
|
|||
real eeir,eeii,emir,emii; |
|||
real eeor,eeoi,emor,emoi; |
|||
real t11r,t11i,t12r,t12i,t21r,t21i,t22r,t22i; |
|||
real beta_te,beta_tm; |
|||
real alpha_bus_te,alpha_bus_tm,alpha_ring_te,alpha_ring_tm; |
|||
real beta_bus_ter,beta_bus_tei,beta_bus_tmr,beta_bus_tmi,beta_ring_ter,beta_ring_tei,beta_ring_tmr,beta_ring_tmi; |
|||
real t_te,t_tm,theta_ter,theta_tei,theta_tmr,theta_tmi; |
|||
real c1e1r,c1e1i,c1e2r,c1e2i,c1m1r,c1m1i,c1m2r,c1m2i; |
|||
real c11r,c11i,c11m,c12r,c12i,c12m; |
|||
real c21r,c21i,c22r,c22i; |
|||
real l_ring=2*`M_PI*r_ring; |
|||
real freq; |
|||
real iph; |
|||
|
|||
analog begin |
|||
freq=`P_C/V(Ilam); |
|||
iph=V(Iphase)/360.0*2*`M_PI; |
|||
if (modespec == 1) begin |
|||
eeir=sqrt(V(Ipow))*cos(iph); |
|||
eeii=sqrt(V(Ipow))*sin(iph); |
|||
emir=0; |
|||
emii=0; |
|||
end |
|||
else if (modespec == 2) begin |
|||
eeir=0; |
|||
eeii=0; |
|||
emir=sqrt(V(Ipow))*cos(iph); |
|||
emii=sqrt(V(Ipow))*sin(iph); |
|||
end |
|||
|
|||
beta_te=2*`M_PI*reffreq/`P_C*neff_te+2*`M_PI/`P_C*n_gv_te*(freq-reffreq)-`M_PI*`P_C*disper_te/pow(reffreq,2)*pow(freq-reffreq,2); |
|||
beta_tm=2*`M_PI*reffreq/`P_C*neff_tm+2*`M_PI/`P_C*n_gv_tm*(freq-reffreq)-`M_PI*`P_C*disper_tm/pow(reffreq,2)*pow(freq-reffreq,2); |
|||
if (alpha_use_dBm == 0) begin |
|||
alpha_bus_te=attenu_bus_te; |
|||
alpha_bus_tm=attenu_bus_tm; |
|||
alpha_ring_te=attenu_ring_te; |
|||
alpha_ring_tm=attenu_ring_tm; |
|||
end |
|||
else if (alpha_use_dBm == 1) begin |
|||
alpha_bus_te=attenu_bus_te/10.0*ln(10); |
|||
alpha_bus_tm=attenu_bus_tm/10.0*ln(10); |
|||
alpha_ring_te=attenu_ring_te/10.0*ln(10); |
|||
alpha_ring_tm=attenu_ring_tm/10.0*ln(10); |
|||
end |
|||
|
|||
beta_bus_ter=beta_te; |
|||
beta_bus_tei=-0.5*alpha_bus_te; |
|||
beta_bus_tmr=beta_tm; |
|||
beta_bus_tmi=-0.5*alpha_bus_tm; |
|||
beta_ring_ter=beta_te; |
|||
beta_ring_tei=-0.5*alpha_ring_te; |
|||
beta_ring_tmr=beta_tm; |
|||
beta_ring_tmi=-0.5*alpha_ring_tm; |
|||
|
|||
t_te=sqrt(1-coupling_ring_te); |
|||
t_tm=sqrt(1-coupling_ring_tm); |
|||
theta_ter=beta_ring_ter*l_ring-phasedelay_ring_te/360.0*`M_PI*2; |
|||
theta_tei=beta_ring_tei*l_ring; |
|||
theta_tmr=beta_ring_tmr*l_ring-phasedelay_ring_tm/360.0*`M_PI*2; |
|||
theta_tmi=beta_ring_tmi*l_ring; |
|||
|
|||
c1e1r=1-t_te*exp(-theta_tei)*cos(theta_ter); |
|||
c1e1i=-t_te*exp(-theta_tei)*sin(theta_ter); |
|||
c1e2r=t_te-exp(-theta_tei)*cos(theta_ter); |
|||
c1e2i=exp(-theta_tei)*sin(theta_ter); |
|||
c11m=pow(t_te-exp(-theta_tei)*cos(theta_ter),2)+pow(exp(-theta_tei)*sin(theta_ter),2); |
|||
c11r=(c1e1r*c1e2r-c1e1i*c1e2i)/c11m; |
|||
c11i=(c1e1r*c1e2i+c1e1i*c1e2r)/c11m; |
|||
|
|||
c1m1r=1-t_tm*exp(-theta_tmi)*cos(theta_tmr); |
|||
c1m1i=-t_tm*exp(-theta_tmi)*sin(theta_tmr); |
|||
c1m2r=t_tm-exp(-theta_tmi)*cos(theta_tmr); |
|||
c1m2i=exp(-theta_tmi)*sin(theta_tmr); |
|||
c12m=pow(t_tm-exp(-theta_tmi)*cos(theta_tmr),2)+pow(exp(-theta_tmi)*sin(theta_tmr),2); |
|||
c12r=(c1m1r*c1m2r-c1m1i*c1m2i)/c12m; |
|||
c12i=(c1m1r*c1m2i+c1m1i*c1m2r)/c12m; |
|||
|
|||
c21r=exp(beta_bus_tei*l_bus)*cos(-beta_bus_ter*l_bus-phasedelay_bus_te/360.0*`M_PI*2); |
|||
c21i=exp(beta_bus_tei*l_bus)*sin(-beta_bus_ter*l_bus-phasedelay_bus_te/360.0*`M_PI*2); |
|||
c22r=exp(beta_bus_tmi*l_bus)*cos(-beta_bus_tmr*l_bus-phasedelay_bus_tm/360.0*`M_PI*2); |
|||
c22i=exp(beta_bus_tmi*l_bus)*sin(-beta_bus_tmr*l_bus-phasedelay_bus_tm/360.0*`M_PI*2); |
|||
|
|||
t11r=c11r*c21r-c11i*c21i; |
|||
t11i=c11r*c21i+c11i*c21r; |
|||
t12r=0; |
|||
t12i=0; |
|||
t21r=0; |
|||
t21i=0; |
|||
t22r=c12r*c22r-c12i*c22i; |
|||
t22i=c12r*c22i+c12i*c22r; |
|||
|
|||
eeor=t11r*eeir-t11i*eeii+t12r*emir-t12i*emii; |
|||
eeoi=t11r*eeii+t11i*eeir+t12r*emii+t12i*emir; |
|||
emor=t21r*eeir-t21i*eeii+t22r*emir-t22i*emii; |
|||
emoi=t21r*eeii+t21i*eeir+t22r*emii+t22i*emir; |
|||
|
|||
if (modespec == 1) begin |
|||
V(Opow) <+ eeor*eeor+eeoi*eeoi; |
|||
V(Ophase) <+ atan2(eeoi,eeor)*360.0/(2*`M_PI); |
|||
end |
|||
else if (modespec == 2) begin |
|||
V(Opow) <+ emor*emor+emoi*emoi; |
|||
V(Ophase) <+ atan2(emoi,emor)*360.0/(2*`M_PI); |
|||
end |
|||
V(Olam) <+ V(Ilam); |
|||
end |
|||
endmodule |
@ -0,0 +1,475 @@ |
|||
//VerilogA for ring,basicreso_withv,veriloga |
|||
|
|||
`include "constants.vams" |
|||
`include "disciplines.vams" |
|||
|
|||
`define MAX_TABLE_SIZE 1000 |
|||
|
|||
module basicreso_withv(Ipow,Iphase,Ilam,Opow,Ophase,Olam,Vbias); |
|||
parameter integer modespec = 1 from [1:2]; |
|||
parameter integer alpha_use_dBm = 1 from [0:1]; |
|||
parameter real l_bus = 1e-3 from [0:inf); |
|||
parameter real r_ring = 7.5e-6 from [0:inf); |
|||
parameter real phasedelay_bus_te = 0; |
|||
parameter real phasedelay_bus_tm = 0; |
|||
parameter real phasedelay_ring_te = 0; |
|||
parameter real phasedelay_ring_tm = 0; |
|||
parameter integer read_neff = 0 from [0:1]; |
|||
parameter string file_neff_bus_te = "./neff_bus_te.txt"; |
|||
parameter string file_neff_bus_tm = "./neff_bus_tm.txt"; |
|||
parameter string file_neff_ring_te = "./neff_ring_te.txt"; |
|||
parameter string file_neff_ring_tm = "./neff_ring_tm.txt"; |
|||
parameter string file_deltaneff_te = "./deltaneff_te.txt"; |
|||
parameter string file_deltaneff_tm = "./deltaneff_tm.txt"; |
|||
parameter real neff_bus_te = 2.6 from (0:inf); |
|||
parameter real neff_bus_tm = 2.6 from (0:inf); |
|||
parameter real neff_ring_te = 2.6 from (0:inf); |
|||
parameter real neff_ring_tm = 2.6 from (0:inf); |
|||
parameter real attenu_bus_te = 0 from [0:inf); |
|||
parameter real attenu_bus_tm = 0 from [0:inf); |
|||
parameter real attenu_ring_te = 0 from [0:inf); |
|||
parameter real attenu_ring_tm = 0 from [0:inf); |
|||
parameter real delta_neff_perv_te = 0; |
|||
parameter real delta_neff_perv_tm = 0; |
|||
parameter real delta_attenu_perv_te = 0; |
|||
parameter real delta_attenu_perv_tm = 0; |
|||
parameter real reffreq = 193.1T from (0:inf); |
|||
parameter real n_gv_bus_te = 4.2 from (0:inf); |
|||
parameter real n_gv_bus_tm = 4.2 from (0:inf); |
|||
parameter real n_gv_ring_te = 4.2 from (0:inf); |
|||
parameter real n_gv_ring_tm = 4.2 from (0:inf); |
|||
parameter real disper_bus_te = 0; |
|||
parameter real disper_bus_tm = 0; |
|||
parameter real disper_ring_te = 0; |
|||
parameter real disper_ring_tm = 0; |
|||
parameter integer read_coupling_ring = 0 from [0:1]; |
|||
parameter real coupling_ring_te = 0.145 from [0:1]; |
|||
parameter real coupling_ring_tm = 0.145 from [0:1]; |
|||
parameter string file_coupling_ring_te = "./coupling_te.txt"; |
|||
parameter string file_coupling_ring_tm = "./coupling_tm.txt"; |
|||
//parameter real coupling_tem = 0; |
|||
|
|||
input Ipow,Iphase,Ilam,Vbias; |
|||
output Opow,Ophase,Olam; |
|||
electrical Ipow,Iphase,Ilam,Opow,Ophase,Olam,Vbias; |
|||
|
|||
real eeir,eeii,emir,emii; |
|||
real eeor,eeoi,emor,emoi; |
|||
real t11r,t11i,t12r,t12i,t21r,t21i,t22r,t22i; |
|||
real neff_bus_ter,neff_bus_tei,neff_bus_tmr,neff_bus_tmi; |
|||
real neff_ring_ter,neff_ring_tei,neff_ring_tmr,neff_ring_tmi; |
|||
real beta_bus_te,beta_bus_tm,beta_ring_te,beta_ring_tm; |
|||
real alpha_bus_te,alpha_bus_tm,alpha_ring_te,alpha_ring_tm; |
|||
real beta_bus_ter,beta_bus_tei,beta_bus_tmr,beta_bus_tmi,beta_ring_ter,beta_ring_tei,beta_ring_tmr,beta_ring_tmi; |
|||
real t_te,t_tm,theta_ter,theta_tei,theta_tmr,theta_tmi; |
|||
real c1e1r,c1e1i,c1e2r,c1e2i,c1m1r,c1m1i,c1m2r,c1m2i; |
|||
real c11r,c11i,c11m,c12r,c12i,c12m; |
|||
real c21r,c21i,c22r,c22i; |
|||
real l_ring=2*`M_PI*r_ring; |
|||
real freq,lam; |
|||
real neff_bus_ter_u,neff_bus_tmr_u,neff_ring_ter_u,neff_ring_tmr_u; |
|||
real neff_bus_tei_u,neff_bus_tmi_u,neff_ring_tei_u,neff_ring_tmi_u; |
|||
real coupling_ring_te_u,coupling_ring_tm_u; |
|||
real attenu_bus_te_u,attenu_bus_tm_u,attenu_ring_te_u,attenu_ring_tm_u; |
|||
real delta_neff_ter,delta_neff_tei,delta_neff_tmr,delta_neff_tmi; |
|||
|
|||
integer file_te,file_tm; |
|||
integer file_bus_te,file_bus_tm,file_ring_te,file_ring_tm; |
|||
real neff_bus_te_lamdata[0:`MAX_TABLE_SIZE-1]; |
|||
real neff_bus_tm_lamdata[0:`MAX_TABLE_SIZE-1]; |
|||
real neff_ring_te_lamdata[0:`MAX_TABLE_SIZE-1]; |
|||
real neff_ring_tm_lamdata[0:`MAX_TABLE_SIZE-1]; |
|||
real neff_bus_te_data_r[0:`MAX_TABLE_SIZE-1]; |
|||
real neff_bus_te_data_i[0:`MAX_TABLE_SIZE-1]; |
|||
real neff_bus_tm_data_r[0:`MAX_TABLE_SIZE-1]; |
|||
real neff_bus_tm_data_i[0:`MAX_TABLE_SIZE-1]; |
|||
real neff_ring_te_data_r[0:`MAX_TABLE_SIZE-1]; |
|||
real neff_ring_te_data_i[0:`MAX_TABLE_SIZE-1]; |
|||
real neff_ring_tm_data_r[0:`MAX_TABLE_SIZE-1]; |
|||
real neff_ring_tm_data_i[0:`MAX_TABLE_SIZE-1]; |
|||
real coupling_ring_te_lamdata[0:`MAX_TABLE_SIZE-1]; |
|||
real coupling_ring_tm_lamdata[0:`MAX_TABLE_SIZE-1]; |
|||
real coupling_ring_te_data[0:`MAX_TABLE_SIZE-1]; |
|||
real coupling_ring_tm_data[0:`MAX_TABLE_SIZE-1]; |
|||
real delta_neff_te_vdata[0:`MAX_TABLE_SIZE-1]; |
|||
real delta_neff_tm_vdata[0:`MAX_TABLE_SIZE-1]; |
|||
real delta_neff_te_data_r[0:`MAX_TABLE_SIZE-1]; |
|||
real delta_neff_te_data_i[0:`MAX_TABLE_SIZE-1]; |
|||
real delta_neff_tm_data_r[0:`MAX_TABLE_SIZE-1]; |
|||
real delta_neff_tm_data_i[0:`MAX_TABLE_SIZE-1]; |
|||
integer num_lines_neff_bus_te,num_lines_neff_bus_tm,num_lines_neff_ring_te,num_lines_neff_ring_tm; |
|||
integer num_lines_coupling_te,num_lines_coupling_tm; |
|||
integer num_lines_deltaneff_te,num_lines_deltaneff_tm; |
|||
|
|||
integer i; |
|||
integer readfile_neff=0; |
|||
integer readfile_coupling_ring=0; |
|||
integer readfile_delta_neff=0; |
|||
|
|||
real iph; |
|||
|
|||
analog begin |
|||
lam=V(Ilam); |
|||
freq=`P_C/V(Ilam); |
|||
iph=V(Iphase)/360.0*2*`M_PI; |
|||
if (modespec == 1) begin |
|||
eeir=sqrt(V(Ipow))*cos(iph); |
|||
eeii=sqrt(V(Ipow))*sin(iph); |
|||
emir=0; |
|||
emii=0; |
|||
end |
|||
else if (modespec == 2) begin |
|||
eeir=0; |
|||
eeii=0; |
|||
emir=sqrt(V(Ipow))*cos(iph); |
|||
emii=sqrt(V(Ipow))*sin(iph); |
|||
end |
|||
|
|||
if (read_neff == 1) begin |
|||
if (readfile_neff == 0) begin |
|||
readfile_neff=1; |
|||
end |
|||
if (readfile_delta_neff == 0) begin |
|||
readfile_delta_neff=1; |
|||
end |
|||
end |
|||
else begin |
|||
delta_neff_ter=delta_neff_perv_te*V(Vbias); |
|||
delta_neff_tmr=delta_neff_perv_tm*V(Vbias); |
|||
beta_bus_te=2*`M_PI*reffreq/`P_C*(neff_bus_te)+2*`M_PI/`P_C*n_gv_bus_te*(freq-reffreq)-`M_PI*`P_C*disper_bus_te/pow(reffreq,2)*pow(freq-reffreq,2); |
|||
beta_bus_tm=2*`M_PI*reffreq/`P_C*(neff_bus_tm)+2*`M_PI/`P_C*n_gv_bus_tm*(freq-reffreq)-`M_PI*`P_C*disper_bus_tm/pow(reffreq,2)*pow(freq-reffreq,2); |
|||
beta_ring_te=2*`M_PI*reffreq/`P_C*(neff_ring_te+delta_neff_ter)+2*`M_PI/`P_C*n_gv_ring_te*(freq-reffreq)-`M_PI*`P_C*disper_ring_te/pow(reffreq,2)*pow(freq-reffreq,2); |
|||
beta_ring_tm=2*`M_PI*reffreq/`P_C*(neff_ring_tm+delta_neff_tmr)+2*`M_PI/`P_C*n_gv_ring_tm*(freq-reffreq)-`M_PI*`P_C*disper_ring_tm/pow(reffreq,2)*pow(freq-reffreq,2); |
|||
attenu_bus_te_u=attenu_bus_te; |
|||
attenu_bus_tm_u=attenu_bus_tm; |
|||
attenu_ring_te_u=attenu_ring_te+delta_attenu_perv_te*V(Vbias); |
|||
attenu_ring_tm_u=attenu_ring_tm+delta_attenu_perv_tm*V(Vbias); |
|||
if (alpha_use_dBm == 1) begin |
|||
alpha_bus_te=attenu_bus_te_u/10*ln(10); |
|||
alpha_bus_tm=attenu_bus_tm_u/10*ln(10); |
|||
alpha_ring_te=attenu_ring_te_u/10*ln(10); |
|||
alpha_ring_tm=attenu_ring_tm_u/10*ln(10); |
|||
end |
|||
else begin |
|||
alpha_bus_te=attenu_bus_te_u; |
|||
alpha_bus_tm=attenu_bus_tm_u; |
|||
alpha_ring_te=attenu_ring_te_u; |
|||
alpha_ring_tm=attenu_ring_tm_u; |
|||
end |
|||
end |
|||
|
|||
if (readfile_delta_neff == 1) begin |
|||
file_te=$fopen(file_deltaneff_te,"r"); |
|||
file_tm=$fopen(file_deltaneff_tm,"r"); |
|||
if (file_te == 0 && file_tm == 0) begin |
|||
$display("Error: cannot open file %s and %s",file_deltaneff_te,file_deltaneff_tm); |
|||
$finish; |
|||
end |
|||
if (file_te != 0) begin |
|||
$fscanf(file_te,"%d",num_lines_deltaneff_te); |
|||
for (i=0;i<num_lines_deltaneff_te;i=i+1) begin |
|||
$fscanf(file_te,"%f %f %f",delta_neff_te_vdata[i],delta_neff_te_data_r[i],delta_neff_te_data_i[i]); |
|||
end |
|||
if (file_tm == 0) begin |
|||
$display("Warning: cannot open file %s, using %s instead",file_deltaneff_tm,file_deltaneff_te); |
|||
num_lines_deltaneff_tm=num_lines_deltaneff_te; |
|||
for (i=0;i<num_lines_deltaneff_te;i=i+1) begin |
|||
delta_neff_tm_vdata[i]=delta_neff_te_vdata[i]; |
|||
delta_neff_tm_data_r[i]=delta_neff_te_data_r[i]; |
|||
delta_neff_tm_data_i[i]=delta_neff_te_data_i[i]; |
|||
end |
|||
end |
|||
end |
|||
if (file_tm != 0) begin |
|||
$fscanf(file_tm,"%d",num_lines_deltaneff_tm); |
|||
for (i=0;i<num_lines_deltaneff_tm;i=i+1) begin |
|||
$fscanf(file_tm,"%f %f %f",delta_neff_tm_vdata[i],delta_neff_tm_data_r[i],delta_neff_tm_data_i[i]); |
|||
end |
|||
if (file_te == 0) begin |
|||
$display("Warning: cannot open file %s, using %s instead",file_deltaneff_te,file_deltaneff_tm); |
|||
num_lines_deltaneff_te=num_lines_deltaneff_tm; |
|||
for (i=0;i<num_lines_deltaneff_tm;i=i+1) begin |
|||
delta_neff_te_vdata[i]=delta_neff_tm_vdata[i]; |
|||
delta_neff_te_data_r[i]=delta_neff_tm_data_r[i]; |
|||
delta_neff_te_data_i[i]=delta_neff_tm_data_i[i]; |
|||
end |
|||
end |
|||
end |
|||
$fclose(file_te); |
|||
$fclose(file_tm); |
|||
readfile_delta_neff=2; |
|||
end |
|||
|
|||
if (readfile_delta_neff == 2) begin |
|||
delta_neff_ter=$table_model(V(Vbias),delta_neff_te_vdata,delta_neff_te_data_r,"3E"); |
|||
delta_neff_tei=$table_model(V(Vbias),delta_neff_te_vdata,delta_neff_te_data_i,"3E"); |
|||
if (V(Vbias) < delta_neff_te_vdata[0]) begin |
|||
$display("Warning: V(Vbias) %f is out of range of the delta_neff_te table",V(Vbias)); |
|||
end |
|||
else if (V(Vbias) > delta_neff_te_vdata[num_lines_deltaneff_te-1]) begin |
|||
$display("Warning: V(Vbias) %f is out of range of the delta_neff_te table",V(Vbias)); |
|||
end |
|||
delta_neff_tmr=$table_model(V(Vbias),delta_neff_tm_vdata,delta_neff_tm_data_r,"3E"); |
|||
delta_neff_tmi=$table_model(V(Vbias),delta_neff_tm_vdata,delta_neff_tm_data_i,"3E"); |
|||
if (V(Vbias) < delta_neff_tm_vdata[0]) begin |
|||
$display("Warning: V(Vbias) %f is out of range of the delta_neff_tm table",V(Vbias)); |
|||
end |
|||
else if (V(Vbias) > delta_neff_tm_vdata[num_lines_deltaneff_tm-1]) begin |
|||
$display("Warning: V(Vbias) %f is out of range of the delta_neff_tm table",V(Vbias)); |
|||
end |
|||
end |
|||
|
|||
if (readfile_neff == 1) begin |
|||
file_bus_te=$fopen(file_neff_bus_te,"r"); |
|||
file_bus_tm=$fopen(file_neff_bus_tm,"r"); |
|||
file_ring_te=$fopen(file_neff_ring_te,"r"); |
|||
file_ring_tm=$fopen(file_neff_ring_tm,"r"); |
|||
if (file_bus_te == 0 && file_bus_tm == 0) begin |
|||
$display("Error: cannot open file %s and %s",file_neff_bus_te,file_neff_bus_tm); |
|||
$finish; |
|||
end |
|||
if (file_ring_te == 0 && file_ring_tm == 0) begin |
|||
$display("Error: cannot open file %s and %s",file_neff_ring_te,file_neff_ring_tm); |
|||
$finish; |
|||
end |
|||
if (file_bus_te != 0) begin |
|||
$fscanf(file_bus_te,"%d",num_lines_neff_bus_te); |
|||
for (i=0;i<num_lines_neff_bus_te;i=i+1) begin |
|||
$fscanf(file_bus_te,"%f %f %f",neff_bus_te_lamdata[i],neff_bus_te_data_r[i],neff_bus_te_data_i[i]); |
|||
end |
|||
if (file_bus_tm == 0) begin |
|||
$display("Warning: cannot open file %s, using %s instead",file_neff_bus_tm,file_neff_bus_te); |
|||
num_lines_neff_bus_tm=num_lines_neff_bus_te; |
|||
for (i=0;i<num_lines_neff_bus_te;i=i+1) begin |
|||
neff_bus_tm_lamdata[i]=neff_bus_te_lamdata[i]; |
|||
neff_bus_tm_data_r[i]=neff_bus_te_data_r[i]; |
|||
neff_bus_tm_data_i[i]=neff_bus_te_data_i[i]; |
|||
end |
|||
end |
|||
end |
|||
if (file_bus_tm != 0) begin |
|||
$fscanf(file_bus_tm,"%d",num_lines_neff_bus_tm); |
|||
for (i=0;i<num_lines_neff_bus_tm;i=i+1) begin |
|||
$fscanf(file_bus_tm,"%f %f %f",neff_bus_tm_lamdata[i],neff_bus_tm_data_r[i],neff_bus_tm_data_i[i]); |
|||
end |
|||
if (file_bus_te == 0) begin |
|||
$display("Warning: cannot open file %s, using %s instead",file_neff_bus_te,file_neff_bus_tm); |
|||
num_lines_neff_bus_te=num_lines_neff_bus_tm; |
|||
for (i=0;i<num_lines_neff_bus_tm;i=i+1) begin |
|||
neff_bus_te_lamdata[i]=neff_bus_tm_lamdata[i]; |
|||
neff_bus_te_data_r[i]=neff_bus_tm_data_r[i]; |
|||
neff_bus_te_data_i[i]=neff_bus_tm_data_i[i]; |
|||
end |
|||
end |
|||
end |
|||
$fclose(file_bus_te); |
|||
$fclose(file_bus_tm); |
|||
if (file_ring_te != 0) begin |
|||
$fscanf(file_ring_te,"%d",num_lines_neff_ring_te); |
|||
for (i=0;i<num_lines_neff_ring_te;i=i+1) begin |
|||
$fscanf(file_ring_te,"%f %f %f",neff_ring_te_lamdata[i],neff_ring_te_data_r[i],neff_ring_te_data_i[i]); |
|||
end |
|||
if (file_ring_tm == 0) begin |
|||
$display("Warning: cannot open file %s, using %s instead",file_neff_ring_tm,file_neff_ring_te); |
|||
num_lines_neff_ring_tm=num_lines_neff_ring_te; |
|||
for (i=0;i<num_lines_neff_ring_te;i=i+1) begin |
|||
neff_ring_tm_lamdata[i]=neff_ring_te_lamdata[i]; |
|||
neff_ring_tm_data_r[i]=neff_ring_te_data_r[i]; |
|||
end |
|||
end |
|||
end |
|||
if (file_ring_tm != 0) begin |
|||
$fscanf(file_ring_tm,"%d",num_lines_neff_ring_tm); |
|||
for (i=0;i<num_lines_neff_ring_tm;i=i+1) begin |
|||
$fscanf(file_ring_tm,"%f %f %f",neff_ring_tm_lamdata[i],neff_ring_tm_data_r[i],neff_ring_tm_data_i[i]); |
|||
end |
|||
if (file_ring_te == 0) begin |
|||
$display("Warning: cannot open file %s, using %s instead",file_neff_ring_te,file_neff_ring_tm); |
|||
num_lines_neff_ring_te=num_lines_neff_ring_tm; |
|||
for (i=0;i<num_lines_neff_ring_tm;i=i+1) begin |
|||
neff_ring_te_lamdata[i]=neff_ring_tm_lamdata[i]; |
|||
neff_ring_te_data_r[i]=neff_ring_tm_data_r[i]; |
|||
neff_ring_te_data_i[i]=neff_ring_tm_data_i[i]; |
|||
end |
|||
end |
|||
end |
|||
$fclose(file_ring_te); |
|||
$fclose(file_ring_tm); |
|||
readfile_neff=2; |
|||
end |
|||
|
|||
if (readfile_neff ==2) begin |
|||
neff_bus_ter_u=$table_model(lam,neff_bus_te_lamdata,neff_bus_te_data_r,"3E"); |
|||
neff_bus_tei_u=$table_model(lam,neff_bus_te_lamdata,neff_bus_te_data_i,"3E"); |
|||
if (lam < neff_bus_te_lamdata[0]) begin |
|||
$display("Warning: wavelength %e is out of range of the neff_bus_te table",lam); |
|||
end |
|||
else if (lam > neff_bus_te_lamdata[num_lines_neff_bus_te-1]) begin |
|||
$display("Warning: wavelength %e is out of range of the neff_bus_te table",lam); |
|||
end |
|||
neff_bus_tmr_u=$table_model(lam,neff_bus_tm_lamdata,neff_bus_tm_data_r,"3E"); |
|||
neff_bus_tmi_u=$table_model(lam,neff_bus_tm_lamdata,neff_bus_tm_data_i,"3E"); |
|||
if (lam < neff_bus_tm_lamdata[0]) begin |
|||
$display("Warning: wavelength %e is out of range of the neff_bus_tm table",lam); |
|||
end |
|||
else if (lam > neff_bus_tm_lamdata[num_lines_neff_bus_tm-1]) begin |
|||
$display("Warning: wavelength %e is out of range of the neff_bus_tm table",lam); |
|||
end |
|||
neff_ring_ter_u=$table_model(lam,neff_ring_te_lamdata,neff_ring_te_data_r,"3E"); |
|||
neff_ring_tei_u=$table_model(lam,neff_ring_te_lamdata,neff_ring_te_data_i,"3E"); |
|||
if (lam < neff_ring_te_lamdata[0]) begin |
|||
$display("Warning: wavelength %e is out of range of the neff_ring_te table",lam); |
|||
end |
|||
else if (lam > neff_ring_te_lamdata[num_lines_neff_ring_te-1]) begin |
|||
$display("Warning: wavelength %e is out of range of the neff_ring_te table",lam); |
|||
end |
|||
neff_ring_tmr_u=$table_model(lam,neff_ring_tm_lamdata,neff_ring_tm_data_r,"3E"); |
|||
neff_ring_tmi_u=$table_model(lam,neff_ring_tm_lamdata,neff_ring_tm_data_i,"3E"); |
|||
if (lam < neff_ring_tm_lamdata[0]) begin |
|||
$display("Warning: wavelength %e is out of range of the neff_ring_tm table",lam); |
|||
end |
|||
else if (lam > neff_ring_tm_lamdata[num_lines_neff_ring_tm-1]) begin |
|||
$display("Warning: wavelength %e is out of range of the neff_ring_tm table",lam); |
|||
end |
|||
beta_bus_te=2*`M_PI*freq/`P_C*(neff_bus_ter_u); |
|||
beta_bus_tm=2*`M_PI*freq/`P_C*(neff_bus_tmr_u); |
|||
beta_ring_te=2*`M_PI*freq/`P_C*(neff_ring_ter_u+delta_neff_ter); |
|||
beta_ring_tm=2*`M_PI*freq/`P_C*(neff_ring_tmr_u+delta_neff_tmr); |
|||
alpha_bus_te=4*`M_PI*neff_bus_tei_u/lam; |
|||
alpha_bus_tm=4*`M_PI*neff_bus_tmi_u/lam; |
|||
alpha_ring_te=4*`M_PI*(neff_ring_tei_u+delta_neff_tei)/lam; |
|||
alpha_ring_tm=4*`M_PI*(neff_ring_tmi_u+delta_neff_tmi)/lam; |
|||
end |
|||
|
|||
if (read_coupling_ring == 1) begin |
|||
if (readfile_coupling_ring == 0) begin |
|||
readfile_coupling_ring=1; |
|||
end |
|||
end |
|||
else begin |
|||
coupling_ring_te_u=coupling_ring_te; |
|||
coupling_ring_tm_u=coupling_ring_tm; |
|||
end |
|||
|
|||
if (readfile_coupling_ring == 1) begin |
|||
file_te=$fopen(file_coupling_ring_te,"r"); |
|||
file_tm=$fopen(file_coupling_ring_tm,"r"); |
|||
if (file_te == 0 && file_tm == 0) begin |
|||
$display("Error: cannot open file %s and %s",file_coupling_ring_te,file_coupling_ring_tm); |
|||
$finish; |
|||
end |
|||
if (file_te != 0) begin |
|||
$fscanf(file_te,"%d",num_lines_coupling_te); |
|||
for (i=0;i<num_lines_coupling_te;i=i+1) begin |
|||
$fscanf(file_te,"%f %f",coupling_ring_te_lamdata[i],coupling_ring_te_data[i]); |
|||
end |
|||
if (file_tm == 0) begin |
|||
$display("Warning: cannot open file %s, using %s instead",file_coupling_ring_tm,file_coupling_ring_te); |
|||
num_lines_coupling_tm=num_lines_coupling_te; |
|||
for (i=0;i<num_lines_coupling_te;i=i+1) begin |
|||
coupling_ring_tm_lamdata[i]=coupling_ring_te_lamdata[i]; |
|||
coupling_ring_tm_data[i]=coupling_ring_te_data[i]; |
|||
end |
|||
end |
|||
end |
|||
if (file_tm != 0) begin |
|||
$fscanf(file_tm,"%d",num_lines_coupling_tm); |
|||
for (i=0;i<num_lines_coupling_tm;i=i+1) begin |
|||
$fscanf(file_tm,"%f %f",coupling_ring_tm_lamdata[i],coupling_ring_tm_data[i]); |
|||
end |
|||
if (file_te == 0) begin |
|||
$display("Warning: cannot open file %s, using %s instead",file_coupling_ring_te,file_coupling_ring_tm); |
|||
num_lines_coupling_te=num_lines_coupling_tm; |
|||
for (i=0;i<num_lines_coupling_tm;i=i+1) begin |
|||
coupling_ring_te_lamdata[i]=coupling_ring_tm_lamdata[i]; |
|||
coupling_ring_te_data[i]=coupling_ring_tm_data[i]; |
|||
end |
|||
end |
|||
end |
|||
$fclose(file_te); |
|||
$fclose(file_tm); |
|||
readfile_coupling_ring=2; |
|||
end |
|||
|
|||
if (readfile_coupling_ring ==2) begin |
|||
coupling_ring_te_u=$table_model(lam,coupling_ring_te_lamdata,coupling_ring_te_data,"3E"); |
|||
if (lam < coupling_ring_te_lamdata[0]) begin |
|||
$display("Warning: wavelength %e is out of range of the coupling_ring_te table",lam); |
|||
end |
|||
else if (lam > coupling_ring_te_lamdata[num_lines_coupling_te-1]) begin |
|||
$display("Warning: wavelength %e is out of range of the coupling_ring_te table",lam); |
|||
end |
|||
coupling_ring_tm_u=$table_model(lam,coupling_ring_tm_lamdata,coupling_ring_tm_data,"3E"); |
|||
if (lam < coupling_ring_tm_lamdata[0]) begin |
|||
$display("Warning: wavelength %e is out of range of the coupling_ring_tm table",lam); |
|||
end |
|||
else if (lam > coupling_ring_tm_lamdata[num_lines_coupling_tm-1]) begin |
|||
$display("Warning: wavelength %e is out of range of the coupling_ring_tm table",lam); |
|||
end |
|||
end |
|||
|
|||
beta_bus_ter=beta_bus_te; |
|||
beta_bus_tei=-0.5*alpha_bus_te; |
|||
beta_bus_tmr=beta_bus_tm; |
|||
beta_bus_tmi=-0.5*alpha_bus_tm; |
|||
beta_ring_ter=beta_ring_te; |
|||
beta_ring_tei=-0.5*alpha_ring_te; |
|||
beta_ring_tmr=beta_ring_tm; |
|||
beta_ring_tmi=-0.5*alpha_ring_tm; |
|||
|
|||
t_te=sqrt(1-coupling_ring_te_u); |
|||
t_tm=sqrt(1-coupling_ring_tm_u); |
|||
theta_ter=beta_ring_ter*l_ring-phasedelay_ring_te/360.0*`M_PI*2; |
|||
theta_tei=beta_ring_tei*l_ring; |
|||
theta_tmr=beta_ring_tmr*l_ring-phasedelay_ring_tm/360.0*`M_PI*2; |
|||
theta_tmi=beta_ring_tmi*l_ring; |
|||
|
|||
c1e1r=1-t_te*exp(-theta_tei)*cos(theta_ter); |
|||
c1e1i=-t_te*exp(-theta_tei)*sin(theta_ter); |
|||
c1e2r=t_te-exp(-theta_tei)*cos(theta_ter); |
|||
c1e2i=exp(-theta_tei)*sin(theta_ter); |
|||
c11m=pow(t_te-exp(-theta_tei)*cos(theta_ter),2)+pow(exp(-theta_tei)*sin(theta_ter),2); |
|||
c11r=(c1e1r*c1e2r-c1e1i*c1e2i)/c11m; |
|||
c11i=(c1e1r*c1e2i+c1e1i*c1e2r)/c11m; |
|||
|
|||
c1m1r=1-t_tm*exp(-theta_tmi)*cos(theta_tmr); |
|||
c1m1i=-t_tm*exp(-theta_tmi)*sin(theta_tmr); |
|||
c1m2r=t_tm-exp(-theta_tmi)*cos(theta_tmr); |
|||
c1m2i=exp(-theta_tmi)*sin(theta_tmr); |
|||
c12m=pow(t_tm-exp(-theta_tmi)*cos(theta_tmr),2)+pow(exp(-theta_tmi)*sin(theta_tmr),2); |
|||
c12r=(c1m1r*c1m2r-c1m1i*c1m2i)/c12m; |
|||
c12i=(c1m1r*c1m2i+c1m1i*c1m2r)/c12m; |
|||
|
|||
c21r=exp(beta_bus_tei*l_bus)*cos(-beta_bus_ter*l_bus-phasedelay_bus_te/360.0*`M_PI*2); |
|||
c21i=exp(beta_bus_tei*l_bus)*sin(-beta_bus_ter*l_bus-phasedelay_bus_te/360.0*`M_PI*2); |
|||
c22r=exp(beta_bus_tmi*l_bus)*cos(-beta_bus_tmr*l_bus-phasedelay_bus_tm/360.0*`M_PI*2); |
|||
c22i=exp(beta_bus_tmi*l_bus)*sin(-beta_bus_tmr*l_bus-phasedelay_bus_tm/360.0*`M_PI*2); |
|||
|
|||
t11r=c11r*c21r-c11i*c21i; |
|||
t11i=c11r*c21i+c11i*c21r; |
|||
t12r=0; |
|||
t12i=0; |
|||
t21r=0; |
|||
t21i=0; |
|||
t22r=c12r*c22r-c12i*c22i; |
|||
t22i=c12r*c22i+c12i*c22r; |
|||
|
|||
eeor=t11r*eeir-t11i*eeii+t12r*emir-t12i*emii; |
|||
eeoi=t11r*eeii+t11i*eeir+t12r*emii+t12i*emir; |
|||
emor=t21r*eeir-t21i*eeii+t22r*emir-t22i*emii; |
|||
emoi=t21r*eeii+t21i*eeir+t22r*emii+t22i*emir; |
|||
|
|||
if (modespec == 1) begin |
|||
V(Opow) <+ eeor*eeor+eeoi*eeoi; |
|||
V(Ophase) <+ atan2(eeoi,eeor)*360.0/(2*`M_PI); |
|||
end |
|||
else if (modespec == 2) begin |
|||
V(Opow) <+ emor*emor+emoi*emoi; |
|||
V(Ophase) <+ atan2(emoi,emor)*360.0/(2*`M_PI); |
|||
end |
|||
V(Olam) <+ V(Ilam); |
|||
|
|||
end |
|||
|
|||
|
|||
endmodule |
@ -0,0 +1,80 @@ |
|||
//VerilogA for ring,idealfilter,veriloga |
|||
|
|||
`include "constants.vams" |
|||
`include "disciplines.vams" |
|||
|
|||
module idealfilter(Ipow1,Iphase1,Ilam1,Ipow2,Iphase2,Ilam2,Opow1,Ophase1,Olam1,Opow2,Ophase2,Olam2); |
|||
parameter real r = 10u from (0:inf); |
|||
parameter real alpha = 7.1029e3 from (0:inf); |
|||
parameter real t1_abs = 0.8 from [0:1]; |
|||
parameter real t1_theta = 0 from (-360:360); |
|||
parameter real t2_abs = 0.8 from [0:1]; |
|||
parameter real t2_theta = 0 from (-360:360); |
|||
parameter real neff = 3.42 from (0:inf); |
|||
|
|||
input Ipow1,Iphase1,Ilam1,Ipow2,Iphase2,Ilam2; |
|||
output Opow1,Ophase1,Olam1,Opow2,Ophase2,Olam2; |
|||
electrical Ipow1,Iphase1,Ilam1,Ipow2,Iphase2,Ilam2,Opow1,Ophase1,Olam1,Opow2,Ophase2,Olam2; |
|||
|
|||
real omega,L; |
|||
real a,theta; |
|||
real T1,T2; |
|||
real t1r,t1i,t2r,t2i; |
|||
real k1r,k1i,k2r,k2i; |
|||
real dr,di,u1r,u1i,u2r,u2i,u3r,u3i,u4r,u4i; |
|||
real ein1r,ein1i,ein2r,ein2i,eout1r,eout1i,eout2r,eout2i; |
|||
real c1r,c1i,c2r,c2i,c3r,c3i,c4r,c4i; |
|||
|
|||
analog begin |
|||
omega=2*`M_PI*`P_C/V(Ilam1); |
|||
L=2*`M_PI*r; |
|||
a=exp(-alpha*L/2); |
|||
theta=omega*neff*L/`P_C; |
|||
t1r=t1_abs*cos(t1_theta*`M_PI/180); |
|||
t1i=t1_abs*sin(t1_theta*`M_PI/180); |
|||
t2r=t2_abs*cos(t2_theta*`M_PI/180); |
|||
t2i=t2_abs*sin(t2_theta*`M_PI/180); |
|||
k1r=sqrt(1-pow(t1r,2)-pow(t1i,2)); |
|||
k2r=sqrt(1-pow(t2r,2)-pow(t2i,2)); |
|||
k1i=0; |
|||
k2i=0; |
|||
|
|||
dr=1-a*cos(theta)*t1r*t2r+a*cos(theta)*t1i*t2i-a*sin(theta)*t1r*t2i-a*sin(theta)*t1i*t2r; |
|||
di=a*cos(theta)*t1r*t2i+a*cos(theta)*t1i*t2r-a*sin(theta)*t1r*t2r+a*sin(theta)*t1i*t2i; |
|||
u1r=t1r-a*cos(theta)*t2r+a*sin(theta)*t2i; |
|||
u1i=t1i-a*cos(theta)*t2i-a*sin(theta)*t2r; |
|||
u2r=-sqrt(a)*(cos(theta/2)*k1r*k2r+cos(theta/2)*k1i*k2i+sin(theta/2)*k1r*k2i-sin(theta/2)*k1i*k2r); |
|||
u2i=-sqrt(a)*(sin(theta/2)*k1r*k2r+sin(theta/2)*k1i*k2i-cos(theta/2)*k1r*k2i+cos(theta/2)*k1i*k2r); |
|||
u3r=t2r-a*cos(theta)*t1r+a*sin(theta)*t1i; |
|||
u3i=t2i-a*cos(theta)*t1i-a*sin(theta)*t1r; |
|||
u4r=-sqrt(a)*(cos(theta/2)*k2r*k1r+cos(theta/2)*k2i*k1i+sin(theta/2)*k2r*k1i-sin(theta/2)*k2i*k1r); |
|||
u4i=-sqrt(a)*(sin(theta/2)*k2r*k1r+sin(theta/2)*k2i*k1i-cos(theta/2)*k2r*k1i+cos(theta/2)*k2i*k1r); |
|||
|
|||
c1r=(dr*u1r+di*u1i)/(pow(dr,2)+pow(di,2)); |
|||
c1i=(dr*u1i-di*u1r)/(pow(dr,2)+pow(di,2)); |
|||
c2r=(dr*u2r+di*u2i)/(pow(dr,2)+pow(di,2)); |
|||
c2i=(dr*u2i-di*u2r)/(pow(dr,2)+pow(di,2)); |
|||
c3r=(dr*u3r+di*u3i)/(pow(dr,2)+pow(di,2)); |
|||
c3i=(dr*u3i-di*u3r)/(pow(dr,2)+pow(di,2)); |
|||
c4r=(dr*u4r+di*u4i)/(pow(dr,2)+pow(di,2)); |
|||
c4i=(dr*u4i-di*u4r)/(pow(dr,2)+pow(di,2)); |
|||
|
|||
ein1r=V(Ipow1)*cos(V(Iphase1)/180.0*`M_PI); |
|||
ein1i=V(Ipow1)*sin(V(Iphase1)/180.0*`M_PI); |
|||
ein2r=V(Ipow2)*cos(V(Iphase2)/180.0*`M_PI); |
|||
ein2i=V(Ipow2)*sin(V(Iphase2)/180.0*`M_PI); |
|||
eout1r=c1r*ein1r-c1i*ein1i+c2r*ein2r-c2i*ein2i; |
|||
eout1i=c1i*ein1r+c1r*ein1i+c2i*ein2r+c2r*ein2i; |
|||
eout2r=c3r*ein2r-c3i*ein2i+c4r*ein1r-c4i*ein1i; |
|||
eout2i=c3i*ein2r+c3r*ein2i+c4i*ein1r+c4r*ein1i; |
|||
|
|||
V(Opow1) <+ eout1r*eout1r+eout1i*eout1i; |
|||
V(Ophase1) <+ atan2(eout1i,eout1r)/`M_PI*180.0; |
|||
V(Olam1) <+ V(Ilam1); |
|||
|
|||
V(Opow2) <+ eout2r*eout2r+eout2i*eout2i; |
|||
V(Ophase2) <+ atan2(eout2i,eout2r)/`M_PI*180.0; |
|||
V(Olam2) <+ V(Ilam2); |
|||
end |
|||
|
|||
endmodule |
@ -0,0 +1,47 @@ |
|||
//VerilogA for ring,idealreso,veriloga |
|||
|
|||
`include "constants.vams" |
|||
`include "disciplines.vams" |
|||
|
|||
module idealreso(Ipow,); |
|||
parameter real t_abs = 0.8 from [0:1]; |
|||
parameter real t_theta = 0 from (-360:360); |
|||
parameter real alpha = 7.1029e3 from (0:inf); |
|||
parameter real r = 10u from (0:inf); |
|||
parameter real neff = 3.42 from (0:inf); |
|||
|
|||
input Ipow,Iphase,Ilam; |
|||
output Opow,Ophase,Olam; |
|||
electrical Ipow, Iphase, Ilam, Opow, Ophase, Olam; |
|||
|
|||
real omega,L; |
|||
real a,theta; |
|||
// real T; |
|||
real tr,ti,a1,b1,c1,d1,ttr,tti; |
|||
real einr,eini,eoutr,eouti; |
|||
|
|||
analog begin |
|||
omega=2*`M_PI*`P_C/V(Ilam); |
|||
L=2*`M_PI*r; |
|||
a=exp(-alpha*L/2); |
|||
theta=omega*neff*L/`P_C; |
|||
tr=t_abs*cos(t_theta); |
|||
ti=t_abs*sin(t_theta); |
|||
a1=tr-a*cos(theta); |
|||
b1=ti-a*sin(theta); |
|||
c1=1-a*tr*cos(theta)+a*-1*ti*sin(theta); |
|||
d1=-a*-1*ti*cos(theta)-a*tr*sin(theta); |
|||
ttr=(a1*c1+b1*d1)/(c1*c1+d1*d1); |
|||
tti=(b1*c1-a1*d1)/(c1*c1+d1*d1); |
|||
|
|||
einr=V(Ipow)*cos(V(Iphase)/180.0*`M_PI); |
|||
eini=V(Ipow)*sin(V(Iphase)/180.0*`M_PI); |
|||
eoutr=ttr*einr-tti*eini; |
|||
eouti=tti*einr+ttr*eini; |
|||
|
|||
V(Opow) <+ eoutr*eoutr+eouti*eouti; |
|||
V(Ophase) <+ atan2(eouti,eoutr)/`M_PI*180.0; |
|||
V(Olam) <+ V(Ilam); |
|||
end |
|||
|
|||
endmodule |
@ -0,0 +1,351 @@ |
|||
//VerilogA for ring,nefffilter,veriloga |
|||
//Xuanqi Chen, Zhifei Wang, Yi-Shing Chang, Jiang Xu, Jun Feng, Peng Yang, Zhehui Wang, Luan H. K. Duong, ”Modeling and Analysis of Optical Modulators Based on Free-Carrier Plasma Dispersion Effect,” IEEE Transactions on Computer-Aided Design of Integrated Circuits and Systems (TCAD), vol. 39, no. 5, pp. 977-990, May 2020. |
|||
|
|||
`include "constants.vams" |
|||
`include "disciplines.vams" |
|||
|
|||
`define MAX_TABLE_SIZE 300000 |
|||
`define MAX_X_NUM 1000 |
|||
//500*500=250000 |
|||
|
|||
module nefffilter(Ipow1,Iphase1,Ilam1,Opow1,Ophase1,Olam1,Ipow2,Iphase2,Ilam2,Opow2,Ophase2,Olam2,Vbias,Gnd); |
|||
//Parameters |
|||
parameter real r = 10u from (0:inf); |
|||
parameter real phaseshift_ratio = 0.8407 from (0:1); |
|||
parameter real nref_coupler = 3.02 from (0:inf); |
|||
parameter real kappa_coupler = 2.15e6 from (0:inf); |
|||
parameter real l_coupler = 0.1u from (0:inf); |
|||
parameter real alpha_phaseshift_ref = 80 from (0:inf); |
|||
parameter real alpha_absorp = 1 from (0:inf); |
|||
parameter real alpha_wd = 1 from (0:inf); |
|||
parameter real rib_width = 0.4u from (0:inf); |
|||
parameter real pn_offset = 0 from [0:inf); |
|||
parameter real ni = 1e16 from (0:inf); |
|||
parameter real N_A = 5e23 from (0:inf); |
|||
parameter real N_D = 1e24 from (0:inf); |
|||
parameter real Lp = 2u from (0:inf); |
|||
parameter real Ln = 1u from (0:inf); |
|||
parameter real epsr_Si = 11.7; |
|||
parameter real Is = 1e-14 from (0:inf); |
|||
parameter real IBV = 1000u from (0:inf); |
|||
parameter real BV = 40 from (0:inf); |
|||
parameter real V0 = 1 from [0:inf); |
|||
parameter real Cj0 = 1.5p from [0:inf); |
|||
parameter real tau = 0.5n from (0:inf); |
|||
parameter real Rs = 55 from (0:inf); |
|||
parameter real emi = 1 from (0:inf); |
|||
parameter real Vt = 0.0259 from (0:inf); |
|||
parameter string neff_ps_filename = "../../../data/EIM/outputPN1.54-1.56-500.txt"; |
|||
parameter string neff_wg_filename = "../../../data/EIM/output-wg1.54-1.56-500.txt"; |
|||
|
|||
input Ipow1,Iphase1,Ilam1,Ipow2,Iphase2,Ilam2,Vbias; |
|||
output Opow1,Ophase1,Olam1,Opow2,Ophase2,Olam2; |
|||
inout Gnd; |
|||
electrical Ipow1,Iphase1,Ilam1,Ipow2,Iphase2,Ilam2,Vbias,Opow1,Ophase1,Olam1,Opow2,Ophase2,Olam2,Gnd; |
|||
electrical Nint; |
|||
|
|||
branch (Gnd,Nint) Iint; |
|||
branch (Nint,Gnd) CCj,CCd,Idd,RRs; |
|||
|
|||
//internal variables |
|||
real beta_cp; |
|||
real k_cp_r,k_cp_i; |
|||
real t_cp_r,t_cp_i; |
|||
real beta_wg; |
|||
real k_wg_r,k_wg_i; |
|||
real beta_ps; |
|||
real k_ps_r,k_ps_i; |
|||
real er,ei; |
|||
real p_mr_r,p_mr_i; |
|||
real E_in1_R,E_in1_I,E_in2_R,E_in2_I; |
|||
real E_out1_R,E_out1_I,E_out2_R,E_out2_I; |
|||
real t2r,t2i,p2r,p2i,k2r,k2i; |
|||
real c0r,c0i,c11r,c11i,c1r,c1i,c2r,c2i; |
|||
real cpr,cpi,cdr,cdi; |
|||
real alpha_phaseshift; |
|||
real W,Wdp,Wdn; |
|||
real eps,phi_bi,phi; |
|||
real N_avr; |
|||
real gd,Id,Cj,Cd; |
|||
real pn00,np00; |
|||
real lam; |
|||
real neff_waveguide,neff_phaseshift_ref,neff_phaseshift; |
|||
|
|||
//1550nm |
|||
real sigma_ne=-8.8E-22; |
|||
real sigma_nh=-8.5E-18; |
|||
real sigma_ae=8.5E-18; |
|||
real sigma_ah=6.0E-18; |
|||
|
|||
real xlength;//=0.6u; |
|||
integer xnum=`MAX_X_NUM+1; |
|||
integer xnum2=2*`MAX_X_NUM+1; |
|||
real x[0:`MAX_X_NUM]; |
|||
real np[0:`MAX_X_NUM]; |
|||
real pp[0:`MAX_X_NUM]; |
|||
real pn[0:`MAX_X_NUM]; |
|||
real nn[0:`MAX_X_NUM]; |
|||
real xx[0:2*`MAX_X_NUM+1]; |
|||
real n[0:2*`MAX_X_NUM+1]; |
|||
real p[0:2*`MAX_X_NUM+1]; |
|||
integer wi,wf; |
|||
real dalpha_e[0:2*`MAX_X_NUM+1]; |
|||
real dalpha_h[0:2*`MAX_X_NUM+1]; |
|||
real dalpha[0:2*`MAX_X_NUM+1]; |
|||
real sum_dalpha,dalpha_avr; |
|||
|
|||
integer ps_file, wg_file; |
|||
real width_start, width_end, width_step; |
|||
integer width_num; |
|||
real lam_start, lam_end, lam_step; |
|||
integer lam_num; |
|||
integer lam_near, width_near; |
|||
real tmp; |
|||
real lam_old=0; |
|||
real width_old=0; |
|||
real neff_table_ps[0:`MAX_TABLE_SIZE] = {0}; |
|||
real neff_lamtable_ps[0:`MAX_TABLE_SIZE] = {0}; |
|||
real neff_widthtable_ps[0:`MAX_TABLE_SIZE] = {0}; |
|||
real neff_table_wg[0:`MAX_TABLE_SIZE] = {0}; |
|||
real neff_lamtable_wg[0:`MAX_TABLE_SIZE] = {0}; |
|||
integer read_table_ps=1; |
|||
integer read_table_wg=1; |
|||
|
|||
integer i, j; |
|||
|
|||
analog initial begin |
|||
pn00=pow(ni,2)/N_D; |
|||
np00=pow(ni,2)/N_A; |
|||
|
|||
eps=epsr_Si*`P_EPS0; |
|||
phi_bi=`P_K*$temperature/`P_Q*ln(N_A*N_D/pow(ni,2)); |
|||
|
|||
N_avr=N_A*N_D/(N_A+N_D); |
|||
end |
|||
|
|||
analog begin |
|||
lam=V(Ilam1); |
|||
gd=(-Is*(exp(5)-1)+IBV)/(-5*emi*Vt + BV); |
|||
Id=Is*(limexp(V(Nint)/(emi*Vt))-1)+V(Nint)*gd; |
|||
if (V(Nint) >= V0) |
|||
Cj=0; |
|||
else |
|||
Cj=Cj0/sqrt(1-V(Nint)/V0); |
|||
//Cd=Id*tau/(emi*Vt); |
|||
Cd=Is*(exp(V(Nint)/(emi*Vt))-1)*tau/(emi*Vt); |
|||
|
|||
I(Iint) <+ V(Vbias)/Rs; |
|||
I(CCj) <+ Cj*ddt(V(CCj)); |
|||
I(CCd) <+ Cd*ddt(V(CCd)); |
|||
I(Idd) <+ Id; |
|||
V(RRs) <+ I(RRs)*Rs; |
|||
|
|||
E_in1_R=sqrt(V(Ipow1))*cos(V(Iphase1)/360.0*2*`M_PI); |
|||
E_in1_I=sqrt(V(Ipow1))*sin(V(Iphase1)/360.0*2*`M_PI); |
|||
E_in2_R=sqrt(V(Ipow2))*cos(V(Iphase2)/360.0*2*`M_PI); |
|||
E_in2_I=sqrt(V(Ipow2))*sin(V(Iphase2)/360.0*2*`M_PI); |
|||
|
|||
beta_cp = 2.0*`M_PI*nref_coupler/lam; |
|||
|
|||
k_cp_r=-sin(kappa_coupler*l_coupler) * sin(l_coupler*beta_cp); |
|||
k_cp_i=sin(kappa_coupler*l_coupler) * cos(l_coupler*beta_cp); |
|||
t_cp_r=cos(kappa_coupler*l_coupler) * cos(l_coupler*beta_cp); |
|||
t_cp_i=cos(kappa_coupler*l_coupler) * sin(l_coupler*beta_cp); |
|||
|
|||
phi=phi_bi-V(Nint); |
|||
if (phi<0) |
|||
phi=0; |
|||
|
|||
W=alpha_wd * sqrt(2.0*eps*phi/(`P_Q*N_avr)); |
|||
Wdp=N_D * W/(N_A+N_D); |
|||
Wdn=N_A * W/(N_A+N_D); |
|||
|
|||
xlength=rib_width/2; |
|||
|
|||
for (i=0; i<xnum; i=i+1) begin |
|||
x[i]=i*xlength/(xnum-1); |
|||
np[i]=np00*(exp(`P_Q*V(Nint)/(`P_K*$temperature))-1)*exp(-(x[i]-Wdp)/Ln)+np00; |
|||
if (x[i]>Wdp) begin |
|||
pp[i]=N_A; |
|||
end |
|||
else begin |
|||
pp[i]=0; |
|||
end |
|||
pn[i]=pn00*(exp(`P_Q*V(Nint)/(`P_K*$temperature))-1)*exp(-(x[i]-Wdn)/Lp)+pn00; |
|||
if (x[i]>Wdn) begin |
|||
nn[i]=N_D; |
|||
end |
|||
else begin |
|||
nn[i]=0; |
|||
end |
|||
if (np[i]<0) np[i]=0; |
|||
if (pn[i]<0) pn[i]=0; |
|||
end |
|||
|
|||
for (i=0; i<2*xnum; i=i+1) begin |
|||
if (i<xnum) begin |
|||
xx[i]=-x[xnum-1-i]; |
|||
n[i]=np[xnum-1-i]; |
|||
p[i]=pp[xnum-1-i]; |
|||
end |
|||
else begin |
|||
xx[i]=x[i-xnum]; |
|||
n[i]=nn[i-xnum]; |
|||
p[i]=pn[i-xnum]; |
|||
end |
|||
// if (abs(xx[i]+rib_width/2) < 0.001u) begin |
|||
// wi=i; |
|||
// $display("wi=%d",wi); |
|||
// end |
|||
// if (abs(xx[i]-rib_width/2) < 0.001u) begin |
|||
// wf=i; |
|||
// $display("wf=%d",wf); |
|||
// end |
|||
end |
|||
for (i=0; i<xnum2; i=i+1) begin |
|||
dalpha_e[i]=n[i]*sigma_ae*1e-4; |
|||
dalpha_h[i]=p[i]*sigma_ah*1e-4; |
|||
dalpha[i]=dalpha_e[i] + dalpha_h[i]; |
|||
end |
|||
|
|||
sum_dalpha=0; |
|||
for (i=0; i<xnum2; i=i+1) begin |
|||
sum_dalpha=sum_dalpha+dalpha[i]; |
|||
end |
|||
dalpha_avr=sum_dalpha/(xnum2); |
|||
alpha_phaseshift = alpha_phaseshift_ref + dalpha_avr; |
|||
|
|||
if (read_table_ps==0 || lam_old==0 || width_old==0) begin |
|||
read_table_ps=1; |
|||
end |
|||
|
|||
if (read_table_ps == 1) begin |
|||
ps_file=$fopen(neff_ps_filename,"r"); |
|||
if (ps_file==0) begin |
|||
$display("Error: cannot open ps_file %s",neff_ps_filename); |
|||
$finish; |
|||
end |
|||
// else |
|||
// $display("ps_file %s opened successfully",neff_ps_filename); |
|||
$fscanf(ps_file,"%f",width_start); |
|||
$fscanf(ps_file,"%f",width_end); |
|||
$fscanf(ps_file,"%d",width_num); |
|||
width_step = (width_end-width_start)/(width_num-1); |
|||
// $display("width_start=%f, width_end=%f, width_num=%f, width_step=%f",width_start,width_end,width_num,width_step); |
|||
$fscanf(ps_file,"%f",lam_start); |
|||
$fscanf(ps_file,"%f",lam_end); |
|||
$fscanf(ps_file,"%d",lam_num); |
|||
lam_step = (lam_end-lam_start)/(lam_num-1); |
|||
// for (i=0; i<width_num; i=i+1) begin |
|||
// $fscanf(ps_file,"%f",tmp); |
|||
// end |
|||
for (i=0; i<width_num; i=i+1) begin |
|||
for (j=0; j<lam_num; j=j+1) begin |
|||
$fscanf(ps_file,"%f",tmp); |
|||
neff_widthtable_ps[i*lam_num+j] = width_start+i*width_step; |
|||
neff_lamtable_ps[i*lam_num+j] = lam_start+j*lam_step; |
|||
neff_table_ps[i*lam_num+j] = tmp; |
|||
//$display("neff_widthtable_ps[%d]=%f, neff_lamtable_ps[%d]=%f, neff_table_ps[%d]=%f",i*lam_num+j,neff_widthtable_ps[i*lam_num+j],i*lam_num+j,neff_lamtable_ps[i*lam_num+j],i*lam_num+j,neff_table_ps[i*lam_num+j]); |
|||
end |
|||
end |
|||
$fclose(ps_file); |
|||
neff_widthtable_ps[width_num*lam_num+1] = 0; |
|||
neff_lamtable_ps[width_num*lam_num+1] = 0; |
|||
neff_table_ps[width_num*lam_num+1] = 0; |
|||
neff_widthtable_ps[width_num*lam_num+2] = 0; |
|||
neff_lamtable_ps[width_num*lam_num+2] = -1; |
|||
neff_table_ps[width_num*lam_num+2] = 0; |
|||
read_table_ps=2; |
|||
end |
|||
|
|||
if (read_table_ps == 2) begin |
|||
if (lam*1e6<lam_start || lam*1e6>lam_end) begin |
|||
$display("Warning: lam=%f is out of range [%f,%f]",lam*1e6,lam_start,lam_end); |
|||
end |
|||
if (Wdp*1e6<width_start || Wdp*1e6>width_end) begin |
|||
$display("Warning: Wdp=%f is out of range [%f,%f]",Wdp*1e6,width_start,width_end); |
|||
end |
|||
neff_phaseshift = $table_model(Wdp*1e6, lam*1e6, neff_widthtable_ps, neff_lamtable_ps, neff_table_ps, "3L,3L"); |
|||
end |
|||
|
|||
if (read_table_wg == 0|| lam_old==0 ) begin |
|||
read_table_wg=1; |
|||
end |
|||
|
|||
if (read_table_wg == 1) begin |
|||
wg_file=$fopen(neff_wg_filename,"r"); |
|||
if (wg_file==0) begin |
|||
$display("Error: cannot open wg_file %s",neff_wg_filename); |
|||
$finish; |
|||
end |
|||
$fscanf(wg_file,"%f",lam_start); |
|||
$fscanf(wg_file,"%f",lam_end); |
|||
$fscanf(wg_file,"%d",lam_num); |
|||
for (i=0; i<lam_num; i=i+1) begin |
|||
neff_lamtable_wg[i] = lam_start+i*lam_step; |
|||
end |
|||
for (j=0; j<lam_num; j=j+1) begin |
|||
$fscanf(wg_file,"%f",tmp); |
|||
neff_table_wg[j] = tmp; |
|||
end |
|||
read_table_wg=2; |
|||
$fclose(wg_file); |
|||
end |
|||
|
|||
if (read_table_wg == 2) begin |
|||
if (lam*1e6<lam_start || lam*1e6>lam_end) begin |
|||
$display("Warning: lam=%f is out of range [%f,%f]",lam*1e6,lam_start,lam_end); |
|||
end |
|||
neff_waveguide = $table_model(lam*1e6, neff_lamtable_wg, neff_table_wg, "3E"); |
|||
end |
|||
|
|||
beta_wg = 2.0*`M_PI*neff_waveguide/lam; |
|||
beta_ps = 2.0*`M_PI*neff_phaseshift/lam; |
|||
|
|||
k_wg_r=-alpha_phaseshift_ref; |
|||
k_wg_i=beta_wg; |
|||
|
|||
k_ps_r=-alpha_phaseshift*alpha_absorp; |
|||
k_ps_i=beta_ps; |
|||
|
|||
er = phaseshift_ratio*`M_PI*r*k_ps_r+(1.0-phaseshift_ratio)*`M_PI*r*k_wg_r; |
|||
ei = phaseshift_ratio*`M_PI*r*k_ps_i+(1.0-phaseshift_ratio)*`M_PI*r*k_wg_i; |
|||
p_mr_r = limexp(er)*cos(ei); |
|||
p_mr_i = limexp(er)*sin(ei); |
|||
|
|||
t2r=t_cp_r*t_cp_r-t_cp_i*t_cp_i; |
|||
t2i=2*t_cp_r*t_cp_i; |
|||
p2r=p_mr_r*p_mr_r-p_mr_i*p_mr_i; |
|||
p2i=2*p_mr_r*p_mr_i; |
|||
k2r=k_cp_r*k_cp_r-k_cp_i*k_cp_i; |
|||
k2i=2*k_cp_r*k_cp_i; |
|||
c0r=1-t2r*p2r+t2i*p2i; |
|||
c0i=-t2r*p2i-t2i*p2r; |
|||
c11r=1+(k2r-t2r)*p2r-(k2i-t2i)*p2i; |
|||
c11i=(k2r-t2r)*p2i+(k2i-t2i)*p2r; |
|||
c1r=t_cp_r*c11r-t_cp_i*c11i; |
|||
c1i=t_cp_r*c11i+t_cp_i*c11r; |
|||
c2r=k2r*p_mr_r-k2i*p_mr_i; |
|||
c2i=k2r*p_mr_i+k2i*p_mr_r; |
|||
cpr=(c0r*c1r+c0i*c1i)/(c0r*c0r+c0i*c0i); |
|||
cpi=(c0r*c1i-c0i*c1r)/(c0r*c0r+c0i*c0i); |
|||
cdr=(c0r*c2r+c0i*c2i)/(c0r*c0r+c0i*c0i); |
|||
cdi=(c0r*c2i-c0i*c2r)/(c0r*c0r+c0i*c0i); |
|||
E_out1_R=cpr*E_in1_R-cpi*E_in1_I+cdr*E_in2_R-cdi*E_in2_I; |
|||
E_out1_I=cpi*E_in1_R+cpr*E_in1_I+cdi*E_in2_R+cdr*E_in2_I; |
|||
E_out2_R=cdr*E_in1_R-cdi*E_in1_I+cpr*E_in2_R-cpi*E_in2_I; |
|||
E_out2_I=cdi*E_in1_R+cdr*E_in1_I+cpi*E_in2_R+cpr*E_in2_I; |
|||
|
|||
V(Opow1) <+ E_out1_R*E_out1_R+E_out1_I*E_out1_I; |
|||
V(Ophase1) <+ atan2(E_out1_I,E_out1_R)*360.0/(2*`M_PI); |
|||
V(Olam1) <+ V(Ilam1); |
|||
V(Opow2) <+ E_out2_R*E_out2_R+E_out2_I*E_out2_I; |
|||
V(Ophase2) <+ atan2(E_out2_I,E_out2_R)*360.0/(2*`M_PI); |
|||
V(Olam2) <+ V(Ilam2); |
|||
|
|||
lam_old=lam; |
|||
width_old=Wdp; |
|||
end |
|||
|
|||
|
|||
endmodule |
@ -0,0 +1,330 @@ |
|||
//VerilogA for ring,neffreso,veriloga |
|||
//Xuanqi Chen, Zhifei Wang, Yi-Shing Chang, Jiang Xu, Jun Feng, Peng Yang, Zhehui Wang, Luan H. K. Duong, ”Modeling and Analysis of Optical Modulators Based on Free-Carrier Plasma Dispersion Effect,” IEEE Transactions on Computer-Aided Design of Integrated Circuits and Systems (TCAD), vol. 39, no. 5, pp. 977-990, May 2020. |
|||
|
|||
`include "constants.vams" |
|||
`include "disciplines.vams" |
|||
|
|||
`define MAX_TABLE_SIZE 300000 |
|||
`define MAX_X_NUM 1000 |
|||
//500*500=250000 |
|||
|
|||
module neffreso(Ipow,Iphase,Ilam,Opow,Ophase,Olam,Vbias,Gnd); |
|||
//Parameters |
|||
parameter real r = 10u from (0:inf); |
|||
parameter real phaseshift_ratio = 0.8407 from (0:1); |
|||
parameter real nref_coupler = 3.02 from (0:inf); |
|||
parameter real kappa_coupler = 2.15e6 from (0:inf); |
|||
parameter real l_coupler = 0.1u from (0:inf); |
|||
parameter real alpha_phaseshift_ref = 80 from (0:inf); |
|||
parameter real alpha_absorp = 1 from (0:inf); |
|||
parameter real alpha_wd = 1 from (0:inf); |
|||
parameter real rib_width = 0.4u from (0:inf); |
|||
parameter real pn_offset = 0 from [0:inf); |
|||
parameter real ni = 1e16 from (0:inf); |
|||
parameter real N_A = 5e23 from (0:inf); |
|||
parameter real N_D = 1e24 from (0:inf); |
|||
parameter real Lp = 2u from (0:inf); |
|||
parameter real Ln = 1u from (0:inf); |
|||
parameter real epsr_Si = 11.7; |
|||
parameter real Is = 1e-14 from (0:inf); |
|||
parameter real IBV = 1000u from (0:inf); |
|||
parameter real BV = 40 from (0:inf); |
|||
parameter real V0 = 1 from [0:inf); |
|||
parameter real Cj0 = 1.5p from [0:inf); |
|||
parameter real tau = 0.5n from (0:inf); |
|||
parameter real Rs = 55 from (0:inf); |
|||
parameter real emi = 1 from (0:inf); |
|||
parameter real Vt = 0.0259 from (0:inf); |
|||
parameter string neff_ps_filename = "../../../data/EIM/outputPN1.54-1.56-500.txt"; |
|||
parameter string neff_wg_filename = "../../../data/EIM/output-wg1.54-1.56-500.txt"; |
|||
|
|||
input Ipow,Iphase,Ilam,Vbias; |
|||
output Opow,Ophase,Olam; |
|||
inout Gnd; |
|||
electrical Ipow,Iphase,Ilam,Opow,Ophase,Olam,Vbias,Nint,Gnd; |
|||
|
|||
branch (Gnd,Nint) Iint; |
|||
branch (Nint,Gnd) CCj,CCd,Idd,RRs; |
|||
|
|||
//internal variables |
|||
real beta_cp; |
|||
real k_cp_r,k_cp_i; |
|||
real t_cp_r,t_cp_i; |
|||
real beta_wg; |
|||
real k_wg_r,k_wg_i; |
|||
real beta_ps; |
|||
real k_ps_r,k_ps_i; |
|||
real c1r,c1i,c2r,c2i,cr,ci; |
|||
real er,ei; |
|||
real p_mr_r,p_mr_i; |
|||
real E_in_R,E_in_I,E_out_R,E_out_I; |
|||
real alpha_phaseshift; |
|||
real W,Wdp,Wdn; |
|||
real eps,phi_bi,phi; |
|||
real N_avr; |
|||
real gd,Id,Cj,Cd; |
|||
real pn00,np00; |
|||
real lam; |
|||
real neff_waveguide,neff_phaseshift_ref,neff_phaseshift; |
|||
|
|||
//1550nm |
|||
real sigma_ne=-8.8E-22; |
|||
real sigma_nh=-8.5E-18; |
|||
real sigma_ae=8.5E-18; |
|||
real sigma_ah=6.0E-18; |
|||
|
|||
real xlength;//=0.6u; |
|||
integer xnum=`MAX_X_NUM+1; |
|||
integer xnum2=2*`MAX_X_NUM+1; |
|||
real x[0:`MAX_X_NUM]; |
|||
real np[0:`MAX_X_NUM]; |
|||
real pp[0:`MAX_X_NUM]; |
|||
real pn[0:`MAX_X_NUM]; |
|||
real nn[0:`MAX_X_NUM]; |
|||
real xx[0:2*`MAX_X_NUM+1]; |
|||
real n[0:2*`MAX_X_NUM+1]; |
|||
real p[0:2*`MAX_X_NUM+1]; |
|||
integer wi,wf; |
|||
real dalpha_e[0:2*`MAX_X_NUM+1]; |
|||
real dalpha_h[0:2*`MAX_X_NUM+1]; |
|||
real dalpha[0:2*`MAX_X_NUM+1]; |
|||
real sum_dalpha,dalpha_avr; |
|||
|
|||
integer ps_file, wg_file; |
|||
real width_start, width_end, width_step; |
|||
integer width_num; |
|||
real lam_start, lam_end, lam_step; |
|||
integer lam_num; |
|||
integer lam_near, width_near; |
|||
real tmp; |
|||
real lam_old=0; |
|||
real width_old=0; |
|||
real neff_table_ps[0:`MAX_TABLE_SIZE] = {0}; |
|||
real neff_lamtable_ps[0:`MAX_TABLE_SIZE] = {0}; |
|||
real neff_widthtable_ps[0:`MAX_TABLE_SIZE] = {0}; |
|||
real neff_table_wg[0:`MAX_TABLE_SIZE] = {0}; |
|||
real neff_lamtable_wg[0:`MAX_TABLE_SIZE] = {0}; |
|||
integer read_table_ps=1; |
|||
integer read_table_wg=1; |
|||
|
|||
integer i, j; |
|||
|
|||
analog initial begin |
|||
pn00=pow(ni,2)/N_D; |
|||
np00=pow(ni,2)/N_A; |
|||
|
|||
eps=epsr_Si*`P_EPS0; |
|||
phi_bi=`P_K*$temperature/`P_Q*ln(N_A*N_D/pow(ni,2)); |
|||
|
|||
N_avr=N_A*N_D/(N_A+N_D); |
|||
end |
|||
|
|||
analog begin |
|||
lam=V(Ilam); |
|||
gd=(-Is*(exp(5)-1)+IBV)/(-5*emi*Vt + BV); |
|||
Id=Is*(limexp(V(Nint)/(emi*Vt))-1)+V(Nint)*gd; |
|||
if (V(Nint) >= V0) |
|||
Cj=0; |
|||
else |
|||
Cj=Cj0/sqrt(1-V(Nint)/V0); |
|||
//Cd=Id*tau/(emi*Vt); |
|||
Cd=Is*(exp(V(Nint)/(emi*Vt))-1)*tau/(emi*Vt); |
|||
|
|||
I(Iint) <+ V(Vbias)/Rs; |
|||
I(CCj) <+ Cj*ddt(V(CCj)); |
|||
I(CCd) <+ Cd*ddt(V(CCd)); |
|||
I(Idd) <+ Id; |
|||
V(RRs) <+ I(RRs)*Rs; |
|||
|
|||
E_in_R=sqrt(V(Ipow))*cos(V(Iphase)/360.0*2*`M_PI); |
|||
E_in_I=sqrt(V(Ipow))*sin(V(Iphase)/360.0*2*`M_PI); |
|||
|
|||
beta_cp = 2.0*`M_PI*nref_coupler/lam; |
|||
|
|||
//k_cp = 1j*sin(kappa_coupler*l_coupler) * limexp(1j*l_coupler*beta_cp) |
|||
k_cp_r=-sin(kappa_coupler*l_coupler) * sin(l_coupler*beta_cp); |
|||
k_cp_i=sin(kappa_coupler*l_coupler) * cos(l_coupler*beta_cp); |
|||
//t_cp = cos(kappa_coupler*l_coupler) * limexp(1j*l_coupler*beta_cp) |
|||
t_cp_r=cos(kappa_coupler*l_coupler) * cos(l_coupler*beta_cp); |
|||
t_cp_i=cos(kappa_coupler*l_coupler) * sin(l_coupler*beta_cp); |
|||
|
|||
phi=phi_bi-V(Nint); |
|||
if (phi<0) |
|||
phi=0; |
|||
|
|||
W=alpha_wd * sqrt(2.0*eps*phi/(`P_Q*N_avr)); |
|||
Wdp=N_D * W/(N_A+N_D); |
|||
Wdn=N_A * W/(N_A+N_D); |
|||
|
|||
xlength=rib_width/2; |
|||
|
|||
for (i=0; i<xnum; i=i+1) begin |
|||
x[i]=i*xlength/(xnum-1); |
|||
np[i]=np00*(exp(`P_Q*V(Nint)/(`P_K*$temperature))-1)*exp(-(x[i]-Wdp)/Ln)+np00; |
|||
if (x[i]>Wdp) begin |
|||
pp[i]=N_A; |
|||
end |
|||
else begin |
|||
pp[i]=0; |
|||
end |
|||
pn[i]=pn00*(exp(`P_Q*V(Nint)/(`P_K*$temperature))-1)*exp(-(x[i]-Wdn)/Lp)+pn00; |
|||
if (x[i]>Wdn) begin |
|||
nn[i]=N_D; |
|||
end |
|||
else begin |
|||
nn[i]=0; |
|||
end |
|||
if (np[i]<0) np[i]=0; |
|||
if (pn[i]<0) pn[i]=0; |
|||
end |
|||
|
|||
for (i=0; i<2*xnum; i=i+1) begin |
|||
if (i<xnum) begin |
|||
xx[i]=-x[xnum-1-i]; |
|||
n[i]=np[xnum-1-i]; |
|||
p[i]=pp[xnum-1-i]; |
|||
end |
|||
else begin |
|||
xx[i]=x[i-xnum]; |
|||
n[i]=nn[i-xnum]; |
|||
p[i]=pn[i-xnum]; |
|||
end |
|||
// if (abs(xx[i]+rib_width/2) < 0.001u) begin |
|||
// wi=i; |
|||
// $display("wi=%d",wi); |
|||
// end |
|||
// if (abs(xx[i]-rib_width/2) < 0.001u) begin |
|||
// wf=i; |
|||
// $display("wf=%d",wf); |
|||
// end |
|||
end |
|||
for (i=0; i<xnum2; i=i+1) begin |
|||
dalpha_e[i]=n[i]*sigma_ae*1e-4; |
|||
dalpha_h[i]=p[i]*sigma_ah*1e-4; |
|||
dalpha[i]=dalpha_e[i] + dalpha_h[i]; |
|||
end |
|||
|
|||
sum_dalpha=0; |
|||
for (i=0; i<xnum2; i=i+1) begin |
|||
sum_dalpha=sum_dalpha+dalpha[i]; |
|||
end |
|||
dalpha_avr=sum_dalpha/(xnum2); |
|||
alpha_phaseshift = alpha_phaseshift_ref + dalpha_avr; |
|||
|
|||
if (read_table_ps==0 || lam_old==0 || width_old==0) begin |
|||
read_table_ps=1; |
|||
end |
|||
|
|||
if (read_table_ps == 1) begin |
|||
ps_file=$fopen(neff_ps_filename,"r"); |
|||
if (ps_file==0) begin |
|||
$display("Error: cannot open ps_file %s",neff_ps_filename); |
|||
$finish; |
|||
end |
|||
// else |
|||
// $display("ps_file %s opened successfully",neff_ps_filename); |
|||
$fscanf(ps_file,"%f",width_start); |
|||
$fscanf(ps_file,"%f",width_end); |
|||
$fscanf(ps_file,"%d",width_num); |
|||
width_step = (width_end-width_start)/(width_num-1); |
|||
// $display("width_start=%f, width_end=%f, width_num=%f, width_step=%f",width_start,width_end,width_num,width_step); |
|||
$fscanf(ps_file,"%f",lam_start); |
|||
$fscanf(ps_file,"%f",lam_end); |
|||
$fscanf(ps_file,"%d",lam_num); |
|||
lam_step = (lam_end-lam_start)/(lam_num-1); |
|||
// for (i=0; i<width_num; i=i+1) begin |
|||
// $fscanf(ps_file,"%f",tmp); |
|||
// end |
|||
for (i=0; i<width_num; i=i+1) begin |
|||
for (j=0; j<lam_num; j=j+1) begin |
|||
$fscanf(ps_file,"%f",tmp); |
|||
neff_widthtable_ps[i*lam_num+j] = width_start+i*width_step; |
|||
neff_lamtable_ps[i*lam_num+j] = lam_start+j*lam_step; |
|||
neff_table_ps[i*lam_num+j] = tmp; |
|||
//$display("neff_widthtable_ps[%d]=%f, neff_lamtable_ps[%d]=%f, neff_table_ps[%d]=%f",i*lam_num+j,neff_widthtable_ps[i*lam_num+j],i*lam_num+j,neff_lamtable_ps[i*lam_num+j],i*lam_num+j,neff_table_ps[i*lam_num+j]); |
|||
end |
|||
end |
|||
$fclose(ps_file); |
|||
neff_widthtable_ps[width_num*lam_num+1] = 0; |
|||
neff_lamtable_ps[width_num*lam_num+1] = 0; |
|||
neff_table_ps[width_num*lam_num+1] = 0; |
|||
neff_widthtable_ps[width_num*lam_num+2] = 0; |
|||
neff_lamtable_ps[width_num*lam_num+2] = -1; |
|||
neff_table_ps[width_num*lam_num+2] = 0; |
|||
read_table_ps=2; |
|||
end |
|||
|
|||
if (read_table_ps == 2) begin |
|||
if (lam*1e6<lam_start || lam*1e6>lam_end) begin |
|||
$display("Warning: lam=%f is out of range [%f,%f]",lam*1e6,lam_start,lam_end); |
|||
end |
|||
if (Wdp*1e6<width_start || Wdp*1e6>width_end) begin |
|||
$display("Warning: Wdp=%f is out of range [%f,%f]",Wdp*1e6,width_start,width_end); |
|||
end |
|||
neff_phaseshift = $table_model(Wdp*1e6, lam*1e6, neff_widthtable_ps, neff_lamtable_ps, neff_table_ps, "3L,3L"); |
|||
end |
|||
|
|||
if (read_table_wg == 0|| lam_old==0 ) begin |
|||
read_table_wg=1; |
|||
end |
|||
|
|||
if (read_table_wg == 1) begin |
|||
wg_file=$fopen(neff_wg_filename,"r"); |
|||
if (wg_file==0) begin |
|||
$display("Error: cannot open wg_file %s",neff_wg_filename); |
|||
$finish; |
|||
end |
|||
$fscanf(wg_file,"%f",lam_start); |
|||
$fscanf(wg_file,"%f",lam_end); |
|||
$fscanf(wg_file,"%d",lam_num); |
|||
for (i=0; i<lam_num; i=i+1) begin |
|||
neff_lamtable_wg[i] = lam_start+i*lam_step; |
|||
end |
|||
for (j=0; j<lam_num; j=j+1) begin |
|||
$fscanf(wg_file,"%f",tmp); |
|||
neff_table_wg[j] = tmp; |
|||
end |
|||
read_table_wg=2; |
|||
$fclose(wg_file); |
|||
end |
|||
|
|||
if (read_table_wg == 2) begin |
|||
if (lam*1e6<lam_start || lam*1e6>lam_end) begin |
|||
$display("Warning: lam=%f is out of range [%f,%f]",lam*1e6,lam_start,lam_end); |
|||
end |
|||
neff_waveguide = $table_model(lam*1e6, neff_lamtable_wg, neff_table_wg, "3E"); |
|||
end |
|||
|
|||
beta_wg = 2.0*`M_PI*neff_waveguide/lam; |
|||
beta_ps = 2.0*`M_PI*neff_phaseshift/lam; |
|||
|
|||
k_wg_r=-alpha_phaseshift_ref; |
|||
k_wg_i=beta_wg; |
|||
|
|||
k_ps_r=-alpha_phaseshift*alpha_absorp; |
|||
k_ps_i=beta_ps; |
|||
|
|||
er = phaseshift_ratio*2.0*`M_PI*r*k_ps_r+(1.0-phaseshift_ratio)*2.0*`M_PI*r*k_wg_r; |
|||
ei = phaseshift_ratio*2.0*`M_PI*r*k_ps_i+(1.0-phaseshift_ratio)*2.0*`M_PI*r*k_wg_i; |
|||
p_mr_r = limexp(er)*cos(ei); |
|||
p_mr_i = limexp(er)*sin(ei); |
|||
|
|||
c1r = t_cp_r + p_mr_r*((k_cp_r*k_cp_r-k_cp_i*k_cp_i)-(t_cp_r*t_cp_r-t_cp_i*t_cp_i))-p_mr_i*(2.0*k_cp_r*k_cp_i-2.0*t_cp_r*t_cp_i); |
|||
c1i = t_cp_i + p_mr_i*((k_cp_r*k_cp_r-k_cp_i*k_cp_i)-(t_cp_r*t_cp_r-t_cp_i*t_cp_i))+p_mr_r*(2.0*k_cp_r*k_cp_i-2.0*t_cp_r*t_cp_i); |
|||
c2r = 1.0-p_mr_r*t_cp_r+p_mr_i*t_cp_i; |
|||
c2i = p_mr_r*t_cp_i+p_mr_i*t_cp_r; |
|||
cr=(c1r*c2r-c1i*c2i)/(c2r*c2r+c2i*c2i); |
|||
ci=(c1i*c2r+c1r*c2i)/(c2r*c2r+c2i*c2i); |
|||
E_out_R = cr*E_in_R-ci*E_in_I; |
|||
E_out_I = ci*E_in_R+cr*E_in_I; |
|||
|
|||
V(Opow) <+ E_out_R*E_out_R+E_out_I*E_out_I; |
|||
V(Ophase) <+ atan2(E_out_I,E_out_R)*360.0/(2*`M_PI); |
|||
V(Olam) <+ V(Ilam); |
|||
|
|||
lam_old=lam; |
|||
width_old=Wdp; |
|||
end |
|||
|
|||
|
|||
endmodule |
@ -0,0 +1,34 @@ |
|||
//VerilogA for tools,randbit,veriloga |
|||
|
|||
`include "constants.vams" |
|||
`include "disciplines.vams" |
|||
|
|||
module randbit(Vout); |
|||
parameter integer seed = 216529; |
|||
parameter real trise = 0 from [0:inf); |
|||
parameter real tfall = 0 from [0:inf); |
|||
parameter real tdelay = 0 from [0:inf); |
|||
parameter real tpulse = 1 from (0:inf); |
|||
parameter real vlow = 0 from (-inf:inf); |
|||
parameter real vhigh = 1 from (-inf:inf); |
|||
output Vout; |
|||
electrical Vout; |
|||
|
|||
real ctime,v; |
|||
real bit=0; |
|||
integer iseed=seed; |
|||
analog begin |
|||
@(initial_step) begin |
|||
v=vlow; |
|||
ctime=$abstime+tpulse; |
|||
end |
|||
|
|||
@(timer(ctime)) begin |
|||
bit=$random(iseed) & 1; |
|||
v=(vhigh-vlow)*bit+vlow; |
|||
ctime=$abstime+tpulse; |
|||
end |
|||
|
|||
V(Vout) <+ transition(v,tdelay,trise,tfall); |
|||
end |
|||
endmodule |
@ -0,0 +1,48 @@ |
|||
//VerilogA for tools,randbit_pam4,veriloga |
|||
|
|||
`include "constants.vams" |
|||
`include "disciplines.vams" |
|||
|
|||
module randbit_pam4(Vout); |
|||
parameter integer seed1 = 418674; |
|||
parameter integer seed2 = 416352; |
|||
parameter integer seed3 = 241412; |
|||
parameter real trise = 0 from [0:inf); |
|||
parameter real tfall = 0 from [0:inf); |
|||
parameter real tdelay = 0 from [0:inf); |
|||
parameter real tpulse = 1 from (0:inf); |
|||
parameter real vlow = 0 from (-inf:inf); |
|||
parameter real vpulse = 1 from (-inf:inf); |
|||
output Vout; |
|||
electrical Vout; |
|||
|
|||
real ctime,v,v1,v2,v3; |
|||
real bit1=0; |
|||
real bit2=0; |
|||
real bit3=0; |
|||
integer iseed1=seed1; |
|||
integer iseed2=seed2; |
|||
integer iseed3=seed3; |
|||
analog begin |
|||
@(initial_step) begin |
|||
v=vlow; |
|||
v1=0; |
|||
v2=0; |
|||
v3=0; |
|||
ctime=$abstime+tpulse; |
|||
end |
|||
|
|||
@(timer(ctime)) begin |
|||
bit1=$random(iseed1) & 1; |
|||
bit2=$random(iseed2) & 1; |
|||
bit3=$random(iseed3) & 1; |
|||
v1=(vpulse)*bit1; |
|||
v2=(vpulse)*bit2; |
|||
v3=(vpulse)*bit3; |
|||
v=v1+v2+v3+vlow; |
|||
ctime=$abstime+tpulse; |
|||
end |
|||
|
|||
V(Vout) <+ transition(v,tdelay,trise,tfall); |
|||
end |
|||
endmodule |
@ -0,0 +1,15 @@ |
|||
//VerilogA for tools,riout,veriloga |
|||
|
|||
`include "constants.vams" |
|||
`include "disciplines.vams" |
|||
|
|||
module riout(Ipow,Iphase,Vreal,Vimag); |
|||
input Ipow,Iphase; |
|||
output Vreal,Vimag; |
|||
electrical Ipow,Iphase,Vreal,Vimag; |
|||
|
|||
analog begin |
|||
V(Vreal) <+ V(Ipow)*cos(V(Iphase)); |
|||
V(Vimag) <+ V(Ipow)*sin(V(Iphase)); |
|||
end |
|||
endmodule |
@ -0,0 +1,13 @@ |
|||
//VerilogA for tools,vfreq,veriloga |
|||
|
|||
`include "constants.vams" |
|||
`include "disciplines.vams" |
|||
|
|||
module vfreq(Vlam); |
|||
parameter real freq = 1G from (0:inf); |
|||
output Vlam; |
|||
electrical Vlam; |
|||
analog begin |
|||
V(Vlam) <+ `P_C / freq; |
|||
end |
|||
endmodule |
Loading…
Reference in new issue