{ NLMS.ASM performs the following normalized LMS algorithm implemented with a transversal FIR filter structure ***************************************************************** * 1) y(n)= w.u ( . = dot_product), y(n)= FIR filter output * * where w= [w0(n) w1(n) ... wN-1(n)]= filter weights * * and u=[ u(n) u(n-1) ... u(n-N+1)]= input samples in delay line* * n= time index, N= number of filter weights (taps) * * 2) e(n)= d(n)-y(n), e(n)= error signal & d(n)= desired output * * 3) wi(n+1)= wi(n)+normalized_stepsize*e(n)*u(n-i), 0 = Program Memory Data buffer of the filter weights Memory usage: pm code= 32 words, pm data= N words, dm data= N words } #define TAPS 5 #define ALPHA 0.1 #define GAMMA 0.1 #include "a:\global\macros.h" .GLOBAL nlms_init, nlms_alg; .SEGMENT/DM dm_data; .VAR deline_data[TAPS]; .ENDSEG; .SEGMENT/PM pm_data; .VAR weights[TAPS]; .ENDSEG; .SEGMENT/PM pm_code; nlms_init: b0=deline_data; m0=-1; l0=TAPS; {circular delay line buffer} b8=weights; b9=weights; m8=1; l8=TAPS; {circular weight buffer} l9=TAPS; f5=ALPHA; f11=GAMMA; {f11= E(0)= GAMMA} f9= 2.0; { f9= 2.0 for DIVIDE_ macro} f13=0.0; lcntr=TAPS, do clear_bufs until lce; clear_bufs: dm(i0,m0)=f13, pm(i8,m8)=f13; { clear delay line & weights} rts; nlms_alg: f14=f0*f0, dm(i0,m0)=f0, f4=pm(i8,m8); {f14= u(n)**2, store u(n) in delay line, f4= w0(n)} f8=f0*f4, f11=f11+f14, f0=dm(i0,m0), f4=pm(i8,m8); {f11= E(n-1)+u(n)**2, f8=u(n)*w0(n)} f12=f0*f4, f11=f11-f13, f0=dm(i0,m0), f4=pm(i8,m8); {f12= u(n-1)*w1(n), f11= E(n), f0= u(n-2), f4= w2(n)} lcntr=TAPS-3, do macs until lce; macs: f12=f0*f4, f8=f8+f12, f0=dm(i0,m0), f4=pm(i8,m8); {f12= u(n-i)*wi(n), f8= sum of prod, f0= u(n-i-1), f4= wi+1(n)} f12=f0*f4, f8=f8+f12, f14=f11; {f12= u(n-N+1)*wN-1(n),f14= E(n)} f2=f8+f12; {f2= y(n)} f6=f1-f2, f4=dm(i0,m0); {f6= e(n), f4= u(n)} f7=f6*f5; {f7= ALPHA*e(n)} DIVIDE(f1,f7,f14,f9,f0); {f1= normalized_stepsize*e(n)} f0=f1*f4, f12=pm(i8,m8); {f0= f1*u(n), f12= w0(n)} lcntr=TAPS-1, do update_weights until lce; f8=f0+f12, f4=dm(i0,m0), f12=pm(i8,m8); {f8= wi(n+1)} {f4= u(n-i-1), f12= wi+1(n)} update_weights: f0=f1*f4, pm(i9,m8)=f8; {f0=normalized_stepsize*e(n)*u(n-i-1)} {store wi(n+1)} rts(db); f8=f0+f12, f0=dm(i0,1); {f8= wN-1(n+1)} {i0 -> u(n+1) location in delay line} f13=f4*f4, pm(i9,m8)=f8; {f13= u(n-N)**2, store wN-1(n+1)} .ENDSEG;