From e2d5716461a9c059417dccfa46bc33393c90ff7d Mon Sep 17 00:00:00 2001 From: cglcv Date: Tue, 27 Aug 2024 17:47:20 +0800 Subject: [PATCH] Release V1.0 --- 1.0/amp/edfa.va | 64 +++ 1.0/amp/soa.va | 69 +++ 1.0/laser/dfb.va | 124 ++++++ 1.0/laser/dhld.va | 108 +++++ 1.0/laser/eml.va | 201 +++++++++ 1.0/laser/qwld.va | 98 +++++ 1.0/laser/vcsel.va | 380 +++++++++++++++++ 1.0/lightsource/cw_maginput.va | 18 + 1.0/lightsource/cw_powinput.va | 19 + 1.0/lightsource/cw_realimageinput.va | 23 + 1.0/lightsource/led.va | 17 + 1.0/modulator/basicea.va | 95 +++++ 1.0/modulator/basicmz.va | 82 ++++ 1.0/modulator/idealam.va | 19 + 1.0/modulator/idealea.va | 23 + 1.0/modulator/idealfm.va | 22 + 1.0/modulator/idealmz.va | 23 + 1.0/modulator/idealpm.va | 18 + 1.0/modulator/neffmz.va | 584 +++++++++++++++++++++++++ 1.0/passive/chifilterbasic.va | 29 ++ 1.0/passive/chifiltergauss.va | 27 ++ 1.0/passive/gainbasic.va | 21 + 1.0/passive/jointer2.va | 31 ++ 1.0/passive/jointer3.va | 35 ++ 1.0/passive/jointerbasic.va | 134 ++++++ 1.0/passive/mmi1x2.va | 329 ++++++++++++++ 1.0/passive/mmi2x2.va | 331 ++++++++++++++ 1.0/passive/phasedelay.va | 24 ++ 1.0/passive/spliter2.va | 21 + 1.0/passive/spliter3.va | 26 ++ 1.0/passive/spliterbasic.va | 136 ++++++ 1.0/passive/wgarc.va | 150 +++++++ 1.0/passive/wgstrmodecp.va | 136 ++++++ 1.0/passive/wgstroptilen.va | 65 +++ 1.0/passive/xcouplerbasic.va | 284 ++++++++++++ 1.0/passive/xcouplerideal.va | 114 +++++ 1.0/pd/msmpd.va | 86 ++++ 1.0/pd/pinapd.va | 191 +++++++++ 1.0/pd/pinpd.va | 176 ++++++++ 1.0/ring/basicfilter.va | 243 +++++++++++ 1.0/ring/basicfilter_withv.va | 617 +++++++++++++++++++++++++++ 1.0/ring/basicreso.va | 140 ++++++ 1.0/ring/basicreso_withv.va | 475 +++++++++++++++++++++ 1.0/ring/idealfilter.va | 80 ++++ 1.0/ring/idealreso.va | 47 ++ 1.0/ring/nefffilter.va | 351 +++++++++++++++ 1.0/ring/neffreso.va | 330 ++++++++++++++ 1.0/tools/randbit.va | 34 ++ 1.0/tools/randbit_pam4.va | 48 +++ 1.0/tools/riout.va | 15 + 1.0/tools/vfreq.va | 13 + 51 files changed, 6726 insertions(+) create mode 100644 1.0/amp/edfa.va create mode 100644 1.0/amp/soa.va create mode 100644 1.0/laser/dfb.va create mode 100644 1.0/laser/dhld.va create mode 100644 1.0/laser/eml.va create mode 100644 1.0/laser/qwld.va create mode 100644 1.0/laser/vcsel.va create mode 100644 1.0/lightsource/cw_maginput.va create mode 100644 1.0/lightsource/cw_powinput.va create mode 100644 1.0/lightsource/cw_realimageinput.va create mode 100644 1.0/lightsource/led.va create mode 100644 1.0/modulator/basicea.va create mode 100644 1.0/modulator/basicmz.va create mode 100644 1.0/modulator/idealam.va create mode 100644 1.0/modulator/idealea.va create mode 100644 1.0/modulator/idealfm.va create mode 100644 1.0/modulator/idealmz.va create mode 100644 1.0/modulator/idealpm.va create mode 100644 1.0/modulator/neffmz.va create mode 100644 1.0/passive/chifilterbasic.va create mode 100644 1.0/passive/chifiltergauss.va create mode 100644 1.0/passive/gainbasic.va create mode 100644 1.0/passive/jointer2.va create mode 100644 1.0/passive/jointer3.va create mode 100644 1.0/passive/jointerbasic.va create mode 100644 1.0/passive/mmi1x2.va create mode 100644 1.0/passive/mmi2x2.va create mode 100644 1.0/passive/phasedelay.va create mode 100644 1.0/passive/spliter2.va create mode 100644 1.0/passive/spliter3.va create mode 100644 1.0/passive/spliterbasic.va create mode 100644 1.0/passive/wgarc.va create mode 100644 1.0/passive/wgstrmodecp.va create mode 100644 1.0/passive/wgstroptilen.va create mode 100644 1.0/passive/xcouplerbasic.va create mode 100644 1.0/passive/xcouplerideal.va create mode 100644 1.0/pd/msmpd.va create mode 100644 1.0/pd/pinapd.va create mode 100644 1.0/pd/pinpd.va create mode 100644 1.0/ring/basicfilter.va create mode 100644 1.0/ring/basicfilter_withv.va create mode 100644 1.0/ring/basicreso.va create mode 100644 1.0/ring/basicreso_withv.va create mode 100644 1.0/ring/idealfilter.va create mode 100644 1.0/ring/idealreso.va create mode 100644 1.0/ring/nefffilter.va create mode 100644 1.0/ring/neffreso.va create mode 100644 1.0/tools/randbit.va create mode 100644 1.0/tools/randbit_pam4.va create mode 100644 1.0/tools/riout.va create mode 100644 1.0/tools/vfreq.va diff --git a/1.0/amp/edfa.va b/1.0/amp/edfa.va new file mode 100644 index 0000000..2300baf --- /dev/null +++ b/1.0/amp/edfa.va @@ -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 diff --git a/1.0/amp/soa.va b/1.0/amp/soa.va new file mode 100644 index 0000000..c5c8154 --- /dev/null +++ b/1.0/amp/soa.va @@ -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 diff --git a/1.0/laser/dfb.va b/1.0/laser/dfb.va new file mode 100644 index 0000000..5e1adc5 --- /dev/null +++ b/1.0/laser/dfb.va @@ -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 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 diff --git a/1.0/lightsource/cw_maginput.va b/1.0/lightsource/cw_maginput.va new file mode 100644 index 0000000..9347530 --- /dev/null +++ b/1.0/lightsource/cw_maginput.va @@ -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 diff --git a/1.0/lightsource/cw_powinput.va b/1.0/lightsource/cw_powinput.va new file mode 100644 index 0000000..52dca98 --- /dev/null +++ b/1.0/lightsource/cw_powinput.va @@ -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 diff --git a/1.0/lightsource/cw_realimageinput.va b/1.0/lightsource/cw_realimageinput.va new file mode 100644 index 0000000..40f9ff9 --- /dev/null +++ b/1.0/lightsource/cw_realimageinput.va @@ -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 diff --git a/1.0/lightsource/led.va b/1.0/lightsource/led.va new file mode 100644 index 0000000..0f02f15 --- /dev/null +++ b/1.0/lightsource/led.va @@ -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 diff --git a/1.0/modulator/basicea.va b/1.0/modulator/basicea.va new file mode 100644 index 0000000..dfe30cd --- /dev/null +++ b/1.0/modulator/basicea.va @@ -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 `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 + // 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 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= 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; iWdp) 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 (ilam_end) begin + $display("Warning: lam=%f is out of range [%f,%f]",lam*1e6,lam_start,lam_end); + end + if (Wdp*1e6width_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 diff --git a/1.0/passive/chifilterbasic.va b/1.0/passive/chifilterbasic.va new file mode 100644 index 0000000..861feed --- /dev/null +++ b/1.0/passive/chifilterbasic.va @@ -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 diff --git a/1.0/passive/chifiltergauss.va b/1.0/passive/chifiltergauss.va new file mode 100644 index 0000000..d4167d5 --- /dev/null +++ b/1.0/passive/chifiltergauss.va @@ -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 diff --git a/1.0/passive/gainbasic.va b/1.0/passive/gainbasic.va new file mode 100644 index 0000000..a6dd680 --- /dev/null +++ b/1.0/passive/gainbasic.va @@ -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 diff --git a/1.0/passive/jointer2.va b/1.0/passive/jointer2.va new file mode 100644 index 0000000..33dda09 --- /dev/null +++ b/1.0/passive/jointer2.va @@ -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 diff --git a/1.0/passive/jointer3.va b/1.0/passive/jointer3.va new file mode 100644 index 0000000..01de8e5 --- /dev/null +++ b/1.0/passive/jointer3.va @@ -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 diff --git a/1.0/passive/jointerbasic.va b/1.0/passive/jointerbasic.va new file mode 100644 index 0000000..d35c471 --- /dev/null +++ b/1.0/passive/jointerbasic.va @@ -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 diff --git a/1.0/passive/mmi1x2.va b/1.0/passive/mmi1x2.va new file mode 100644 index 0000000..7e350f3 --- /dev/null +++ b/1.0/passive/mmi1x2.va @@ -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 + // 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 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 `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 + // 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 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 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 diff --git a/1.0/passive/wgarc.va b/1.0/passive/wgarc.va new file mode 100644 index 0000000..775e0c0 --- /dev/null +++ b/1.0/passive/wgarc.va @@ -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 diff --git a/1.0/passive/wgstrmodecp.va b/1.0/passive/wgstrmodecp.va new file mode 100644 index 0000000..a89b6cb --- /dev/null +++ b/1.0/passive/wgstrmodecp.va @@ -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 diff --git a/1.0/passive/wgstroptilen.va b/1.0/passive/wgstroptilen.va new file mode 100644 index 0000000..ef9ec58 --- /dev/null +++ b/1.0/passive/wgstroptilen.va @@ -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 diff --git a/1.0/passive/xcouplerbasic.va b/1.0/passive/xcouplerbasic.va new file mode 100644 index 0000000..352a3a9 --- /dev/null +++ b/1.0/passive/xcouplerbasic.va @@ -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 diff --git a/1.0/passive/xcouplerideal.va b/1.0/passive/xcouplerideal.va new file mode 100644 index 0000000..50cd313 --- /dev/null +++ b/1.0/passive/xcouplerideal.va @@ -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 diff --git a/1.0/pd/msmpd.va b/1.0/pd/msmpd.va new file mode 100644 index 0000000..d207941 --- /dev/null +++ b/1.0/pd/msmpd.va @@ -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 diff --git a/1.0/pd/pinapd.va b/1.0/pd/pinapd.va new file mode 100644 index 0000000..4bcec00 --- /dev/null +++ b/1.0/pd/pinapd.va @@ -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 \ No newline at end of file diff --git a/1.0/pd/pinpd.va b/1.0/pd/pinpd.va new file mode 100644 index 0000000..09022e6 --- /dev/null +++ b/1.0/pd/pinpd.va @@ -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 \ No newline at end of file diff --git a/1.0/ring/basicfilter.va b/1.0/ring/basicfilter.va new file mode 100644 index 0000000..a3a2dc7 --- /dev/null +++ b/1.0/ring/basicfilter.va @@ -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 diff --git a/1.0/ring/basicfilter_withv.va b/1.0/ring/basicfilter_withv.va new file mode 100644 index 0000000..0a57ac4 --- /dev/null +++ b/1.0/ring/basicfilter_withv.va @@ -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 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 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 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 diff --git a/1.0/ring/basicreso.va b/1.0/ring/basicreso.va new file mode 100644 index 0000000..f0deaae --- /dev/null +++ b/1.0/ring/basicreso.va @@ -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 diff --git a/1.0/ring/basicreso_withv.va b/1.0/ring/basicreso_withv.va new file mode 100644 index 0000000..3a15b55 --- /dev/null +++ b/1.0/ring/basicreso_withv.va @@ -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 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 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 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 diff --git a/1.0/ring/idealfilter.va b/1.0/ring/idealfilter.va new file mode 100644 index 0000000..3ea1069 --- /dev/null +++ b/1.0/ring/idealfilter.va @@ -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 diff --git a/1.0/ring/idealreso.va b/1.0/ring/idealreso.va new file mode 100644 index 0000000..c4e1506 --- /dev/null +++ b/1.0/ring/idealreso.va @@ -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 diff --git a/1.0/ring/nefffilter.va b/1.0/ring/nefffilter.va new file mode 100644 index 0000000..f2a4828 --- /dev/null +++ b/1.0/ring/nefffilter.va @@ -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; iWdp) 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 (ilam_end) begin + $display("Warning: lam=%f is out of range [%f,%f]",lam*1e6,lam_start,lam_end); + end + if (Wdp*1e6width_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; ilam_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 diff --git a/1.0/ring/neffreso.va b/1.0/ring/neffreso.va new file mode 100644 index 0000000..bb24eb4 --- /dev/null +++ b/1.0/ring/neffreso.va @@ -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; iWdp) 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 (ilam_end) begin + $display("Warning: lam=%f is out of range [%f,%f]",lam*1e6,lam_start,lam_end); + end + if (Wdp*1e6width_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; ilam_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 diff --git a/1.0/tools/randbit.va b/1.0/tools/randbit.va new file mode 100644 index 0000000..2a89a2c --- /dev/null +++ b/1.0/tools/randbit.va @@ -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 diff --git a/1.0/tools/randbit_pam4.va b/1.0/tools/randbit_pam4.va new file mode 100644 index 0000000..3821af5 --- /dev/null +++ b/1.0/tools/randbit_pam4.va @@ -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 diff --git a/1.0/tools/riout.va b/1.0/tools/riout.va new file mode 100644 index 0000000..e498996 --- /dev/null +++ b/1.0/tools/riout.va @@ -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 diff --git a/1.0/tools/vfreq.va b/1.0/tools/vfreq.va new file mode 100644 index 0000000..69aa883 --- /dev/null +++ b/1.0/tools/vfreq.va @@ -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