//VerilogA for passive,mmi2x2,veriloga //Xuanqi Chen, Zhifei Wang, Yi-Shing Chang, Jiang Xu, Jun Feng, Peng Yang, Zhehui Wang, Luan H. K. Duong, ”Modeling and Analysis of Optical Modulators Based on Free-Carrier Plasma Dispersion Effect,” IEEE Transactions on Computer-Aided Design of Integrated Circuits and Systems (TCAD), vol. 39, no. 5, pp. 977-990, May 2020. `include "constants.vams" `include "disciplines.vams" `define MAX_MODES 200 `define MAX_ITER 10000 `define IDX_NUM 50000 `define TOLERANCE 0.0000000001 module mmi2x2(Ipow1,Iphase1,Ilam1,Ipow2,Iphase2,Ilam2,Opow1,Ophase1,Olam1,Opow2,Ophase2,Olam2); parameter real design_lam = 1.55e-6 from (0:inf); parameter real n_ps = 3.45 from (0:inf); parameter real n_sub = 1.45 from (0:inf); parameter real width_MMI = 3e-6 from (0:inf); parameter real width_port = 0.45e-6 from (0:inf); parameter real port_offset = 0.75e-6 from (0:inf); parameter real thickness = 0.22e-6 from (0:inf); parameter real alpha_mmi = 80 from (0:inf); input Ipow1,Iphase1,Ilam1,Ipow2,Iphase2,Ilam2; output Opow1,Ophase1,Olam1,Opow2,Ophase2,Olam2; electrical Ipow1,Iphase1,Ilam1,Ipow2,Iphase2,Ilam2,Opow1,Ophase1,Olam1,Opow2,Ophase2,Olam2; real ulam, ulam0, uwidth_in, uwidth_MMI, uoffset, uthickness, alpha0; real k1_ref, kc_ref; integer mode_num, mode_num_ref; real beta_x_MMI, beta_in, beta_x_in; real neff_MMI[0:`MAX_MODES]; real beta_MMI[0:`MAX_MODES]; real length_MMI; real ky_in, gamma_in; real ky_MMI[0:`MAX_MODES]; real gamma_MMI[0:`MAX_MODES]; real c0; real c0_dis[0:`MAX_MODES]; real icoff[0:`MAX_MODES]; real delta_beta; real ocoff_r[0:`MAX_MODES]; real ocoff_i[0:`MAX_MODES]; real c1r, c1i, c2r, c2i; real in1r, in1i, in2r, in2i, out1r, out1i, out2r, out2i; real sum_outfield1, sum_outfield2, sum_outfield3, sum_outfield4; real sum_singlemode1,sum_singlemode2,sum_singlemode3,sum_singlemode4; real border; integer i, j; real p=1; real h; analog function real findzeropoint_rect_x; input x_lower_input, x_upper_input, Vx; real x_lower_input, x_upper_input, Vx; real iter_count; real x_lower, x_upper; real y_mid; real y_lower, x_mid; begin findzeropoint_rect_x = -1; x_lower = x_lower_input; x_upper = x_upper_input; iter_count = 0; y_mid = 1; while (iter_count<`MAX_ITER && abs(y_mid) > `TOLERANCE) begin x_mid = (x_lower + x_upper) / 2; y_lower = tan(x_lower / 2) - sqrt(pow(Vx,2) - pow(x_lower,2)) / x_lower; y_mid = tan(x_mid / 2) - sqrt(pow(Vx,2) - pow(x_mid,2)) / x_mid; if (abs(y_mid) < `TOLERANCE) begin findzeropoint_rect_x = x_mid; end if (y_mid * y_lower < 0) x_upper = x_mid; else x_lower = x_mid; iter_count = iter_count + 1; end if (findzeropoint_rect_x == -1) $display("No zero point found in the given range. Please try again with different range."); end endfunction analog function real findzeropoint_rect_y; input x_lower_input, x_upper_input, Vy, m; real x_lower_input, x_upper_input, Vy, m; real iter_count; real x_lower, x_upper; real y_mid; real y_lower, x_mid; begin x_lower = x_lower_input; x_upper = x_upper_input; iter_count = 0; y_mid = 1; findzeropoint_rect_y = -1; while (iter_count<`MAX_ITER && abs(y_mid) > `TOLERANCE) begin x_mid = (x_lower + x_upper) / 2; y_lower = tan(x_lower / 2 - m * `M_PI / 2) - sqrt((pow(Vy,2) - pow(x_lower,2))) / x_lower; y_mid = tan(x_mid / 2 - m * `M_PI / 2) - sqrt((pow(Vy,2) - pow(x_mid,2))) / x_mid; if (abs(y_mid) < `TOLERANCE) findzeropoint_rect_y = x_mid; if (y_mid * y_lower < 0) x_upper = x_mid; else x_lower = x_mid; iter_count = iter_count + 1; end if (findzeropoint_rect_y == -1) $display("No zero point found in the given range. Please try again with different range."); end endfunction analog function real eim_rect; input lam, width, thickness, n_ps, n_sub, numflag, mode_index; real lam, width, thickness, n_ps, n_sub; integer numflag, mode_index; real k1, Vx, yx, hx, beta_x, neff_x_MMI, Vy, yy, hxy; real beta_xy[0:`MAX_MODES]; real neff_xy[0:`MAX_MODES]; real beta_xy_out[0:`MAX_MODES]; real neff_xy_out[0:`MAX_MODES]; integer i, m, mode_num; begin k1=2*`M_PI*n_ps/lam; Vx=2*`M_PI/lam*thickness*sqrt((pow(n_ps,2)-pow(n_sub,2))); yx=findzeropoint_rect_x(1e-6,min(`M_PI,Vx),Vx); hx=yx/thickness; beta_x=sqrt(pow(k1,2)-pow(hx,2)); neff_x_MMI=lam*beta_x/(2*`M_PI); Vy=2*`M_PI/lam*width*sqrt((pow(neff_x_MMI,2)-pow(n_sub,2))); i=0; m=0; while (m*`M_PI=Vy // 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