//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