05ms612.txt ;*************************************************************************************************** ; LISTING - COMPLETE CODE LISTING ; ; "Solving the loop-analysis puzzle," EDN Europe, March 2000, pg 55 ; http://www.ednmag.com/ednmag/reg/2000/030200/05ms612.htm ;**************************************************************************************************** function $$loop( upstream_sig_name: string, dnstream_sig_name: string, run_name : label string ),SEALED { upstream_sig_name = $condition_sig_name(upstream_sig_name); if (upstream_sig_name == VOID) return; dnstream_sig_name = $condition_sig_name(dnstream_sig_name); if (dnstream_sig_name == VOID) return; local first_harmonic = 250; //Hz local last_harmonic = 8000; //Hz local sim_start = .001; //1ms delay to let loop settle //calculate constants used in the calculations local num_freqs =1 + log(last_harmonic/first_harmonic)/log(2); local sim_end = 1/first_harmonic + sim_start; local sample_freq = 32*last_harmonic; // sample at least 32 samples of highest //frequency //create local storage and file names local wf_index = $$get_aux_index(); local aux_wf1_name = $strcat("aux@@Gain_",wf_index); local aux_wf2_name = $strcat("aux@@Phase_",wf_index); local Gains = $create_vector(num_freqs); local Phases = $create_vector(num_freqs); local Freqs = $create_vector(num_freqs); //get transient data for loop input and output local upstream_sig_expr = $get_wvf_name(upstream_sig_name,VOID,run_name); local dnstream_sig_expr = $get_wvf_name(dnstream_sig_name,VOID,run_name); //calculate Fourier Transform: // F(jw)=integ(exp(-jwt)*f(t))dt // using Eulers Identity: // F(jw)=integ(cos(wt)*f(t))dt - j*integ(sin(wt)*f(t))dt // Setting A=integ(cos(wt)*f(t))dt and B=-integ(sin(wt)*f(t))dt // then |F(jw)| = sqrt(A**2+B**2) // and phase=arctan(B/A) // //variables used in the DFT calculation local freq_index; //index into frequency data local w; //current radian frequency local f; //current frequency local t; //current time step local rough_t; //approximate time step local up; //current upstream data point local dn; //current downstream data point local last_t = 0; // last time step local dt; //delta t local Aup=0, Adn=0, Bup=0, Bdn=0; local UpDc=0; local DnDc=0; //calculate DC value $clear_message(); $message($strcat("Calculating DC values:,@note); for (t=sim_start; t<=sim_end; t=t+1/sample_freq) { dt = t-last_t; up = $get_signal_value(upstream_sig_expr, t); dn = $get_signal_value(dnstream_sig_expr, t); UpDc = UpDc + up*dt; DnDc = DnDc + dn*dt; last_t = t-sim_start; } UpDc=UpDc/(sim_end-sim_start); DnDc=DnDc/(sim_end-sim_start); //calculate Fourier Transform for (freq_index=0; freq_index