Hi all,
Recently I am stuck in modeling a pair of commuting caps between two branches. I have two caps with total C as Ctot, which are connected between ion-gnd and iop-gnd branches, respectively. When a signal called D comes, D*Ctot will stay at the ion branch while (1-D)*Ctot will stay at the iop branch. Since D may be different than the previous D_prev, there will part of the cap and its associated charge being switched to the other branch, depending D>D_prev or D<D_prev.
I realized that the charge on each branch maybe not conservative. But as a 3-terminal blackbox (iop,ion and gnd), the charge on the total two branches is conservative. Allowing for that, it seems the modeling of a single varactor (suggested by Ken
https://designers-guide.org/modeling/varactors.pdf) may not help. I try to build some codes, but there is huge current spike shown during the cap switching, which is intolerable for my use. It seems the lines for the charge dump are the troublemakers. But have no idea how to model this cap network in an elegant way. Can anyone help me? Thanks!
There should be some way to describe sudden capacitance and charge change in one capacitor. But I do not know how to integrate it in a clock-triggered event....
module switching_capacitor(d, dout, clk,iop,ion, gnd);
output dout, iop,gnd, ion ;
input d, clk;
electrical clk,d,d_prev,dout,gnd,iop,ion ; //d: input, dout: sampled d output at the current clock edge. d_prev: d from the previous clock dege.
parameter real Ctot=0;
parameter real vth_clk=0.5;
parameter integer dir = +1 from [-1:+1] exclude 0;
parameter real td_Z=0p; //Z switching speed.
parameter real tt_Z=1p;
real td_D=10p;
real tt_D=10p;
real D;
real D_prev;
real dD;
real vop_transition;
real von_transition;
integer is_Charge_to_ion;
real dQn;
real dQp;
integer nr_clock=0; //use nr_clock to mimic dirac function
analog begin
//using clk rising edge to record d of the current cycle
@(cross(V(clk) - vth_clk, dir)) begin
nr_clock=nr_clock+1; //clock counter used to generate dirac function
D=V(d);
D_prev=V(d_prev);
dD=abs(D-D_prev); // D change between the current cycle and the next cycle.
vop_transition=V(iop,gnd); //record iop and ion before the transition, in order to calculate the charge to be switched
von_transition=V(ion,gnd);
is_Charge_to_ion= (D>D_prev? 1:0); // if D>D_prev, part of the cap and its associated charge will be switched from Iop to Ion, or vice versa
dQn= Ctot*is_Charge_to_ion *dD*(vop_transition-von_transition); //If D>D_prev dQn=charge to be dumped to Ion from Iop, else dQn=0
dQp= Ctot*(1-is_Charge_to_ion)*dD*(von_transition-vop_transition); //If D<D_prev dQp=charge to be dumped to Iop from Ion, else dQp=0
end
//using clk falling edge to generate internal signal to record D from the previous cycle
@ (cross(V(clk)-vth_clk, -dir)) begin
D_prev= V(dout);
end
//d update
V(dout) <+ transition(D,td_D,tt_D); // dout generation
V(d_prev) <+ transition(D_prev,td_D,tt_D); // d_prev generation
//Cap update. During the update the charge conservation is not taken into account
I(ion,gnd)<+ Ctot* transition(D,td_Z,tt_Z)* ddt(V(ion,gnd)); //Cap size change: occurs between td_Z and td_Z+tt_Z;
I(iop,gnd)<+ Ctot* transition(1-D,td_Z,tt_Z)*ddt(V(iop,gnd)); //Cap size change: occurs between td_Z and td_Z+tt_Z;
//charge dump, from one branch to the opposite. it is dumped in the form of a current spike to mimic dirac function
I(ion,gnd)<+ -transition(dQn,td_Z,tt_Z)/tt_Z* ( transition(nr_clock, td_Z+tt_Z,tt_Z)-transition(nr_clock, td_Z+2*tt_Z,tt_Z)); // dump the charge from the decending branch to the ascending branch.
I(iop,gnd)<+ -transition(dQp,td_Z,tt_Z)/tt_Z* ( transition(nr_clock, td_Z+tt_Z,tt_Z)-transition(nr_clock, td_Z+2*tt_Z,tt_Z)); // (transition-transtion) is to mimic a delta current spike to inject
// the required charge. It is injected after cap size changing:
// between td_Z+tt_Z and td_Z+3*tt_Z. Put dQp/n into transtion between td_Z
// and td_Z+tt_Z is to aviod dQp/n of the previous cycle from being
// used in the current cycle.
end
endmodule