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