I need to create an AGC algorithm on FPGA. I am using some basic algorithm, but I receive input signal in every clock cycle.
In AGC algorithm, in case I have sample x(1) and use it to calculate gain g(2), this gain should be applied on the next sample x(2). However, sample x(2) comes directly after x(1) and it takes multiple clock cycles before g(2) is ready.
Do you have some ideas on how to overcome this in FPGA? Is it even possible to create AGC on FPGA if data comes at every clock cycle?
Thank you very much in advance.
I think you need to read up on how digital agc is typically done. At its simplest, digital AGC consists of a threshold detector, integrator, and multiplier.
Here is an article I found:
Hi Neil. I've never seen that web page before! I see that the "Embedded" web site folks deleted the references I provided in that section of my DSP book. Most of what little I know about AGC I learned from DSP guru fred harris (of "Blackman-Harris window" fame). The references missing from that online article are:
 Harris, F. “T102: Digital Signal Processing for Digital Modems,” DSP World Spring Design Conf., Santa Clara, California, April 1999.
 Harris, F. “On the Design, Implementation, and Performance of a Microprocessor-Controlled AGC System for a Digital Receiver,” IEEE Military Communications Conf., San Diego, Caliornia, October 1988. Analog Devices, Inc. “80 MSPS, Dual-Channel WCDMA Receive Signal Processor (RSP) AD6634,” Data Sheet Rev. 0, 2002, pp. 28–34
That is really nice post. I think for anlitlog and log implementation in FPGA this would be appropriate supplementary material:
Computer Multiplication and Division Using
b2508 I think now you have all components of an AGC.
I suggest you to first try to implement it in Matlab/Python, then go for
HDL. Implementation of Antilog/Log can be tricky. However, if you understand paper that I have provided link on, it should not be so hard (just shifting, and taking care of signal format)
Any chance you or Rick explaining "in baby steps for dummies" how log/antilog approach sorts out the time constant problem.
I am not expert on AGC. Maybe that's something I can study and write about sometime in the future.
Ooh ooh! I get to use "homologous" in it's natural habitat!
Because if you do the naive AGC loop, then the loop gain is proportional to the AGC gain and (if I recall correctly) the signal level. The system isn't linear at all, but with an ACG setting that varies slowly enough it looks like a linear system with a wildly time-varying loop gain and, hence, time constant.
This SHOULD make sense if you work out the loop gains for a simple system with a constant-amplitude input.
If you do the log/antilog thing, then the AGC gain and signal strength show up as offsets (rather than multipliers). The system is homologous* to a nicely linear system. If you just use an integrator and a summation block (after putting your logs and antilogs in the right places) then you'll end up with a simple first-order system.
(Just a note -- the first time I designed an AGC loop was in analog; the crusty old guy I was working with said "oh, you don't want just an integrator, because it'll mess up how things sound". "Sound?" I said. "Oh right -- this is a data link." So if it's for AM radio, you may want to use a leaky integrator so it sounds right.)
* I got to use it! I got to use it!
AGC usually has three units. The first one is the magnitude calculator, the second one is the low pass filter for that magnitude, and the third one is the multiplier of the signal to the inverse value of the filtered magnitude. The low pass filter is not sharp but has rather low frequency band.
Thank you to all.
I do not have an option of oversampling so I switched from feedback to feedforward solution instead and it seems ok.
I have only one issue left. I do not understand how to achieve good attack or decay time. I tried using moving average filter (with filter of length N having all coefficients equal to 1/N) but it seems that I cannot achieve averaging by much more than 400 samples with my hardware. If my data has a rate of 20kHz then this 400 samples would be very quick and not pleasant for listening if gain suddenly increased.
Does anyone know reasonable sizes of attack/decay times and how they are implemented?
unfortunately I don't have any FPGA experience but I think normally in digital signal processors you should assume some delay due to the processing time.
In that case, why not calculate your gain based on a window consisting of several samples, longer or equal to the number of clock cycles to calculate it?
Are you aiming at truly instantaneous AGC anyway? It might not sound that nice. If you use a time constant longer than the averaging window, the length of the window is not a problem any more :)
For reference, check Giannoulis et al. "Digital Dynamic Range Compressor Design— A Tutorial and Analysis", J. Audio Eng. Soc. vol. 60, No. 6 (2012). Not exactly AGC, but DRC works on very similar principles - see section 2.3 Level Detection.
I do not know how you AGC loop looks exactly. However, I am sure you can do following:
-You can split your datapath into two datapath (one for calculation of gain, and another one ( delayed for few clock cycles (delay is equal to number of clock cycles needed to calculate gain g()).
- After this you could applied your gain g() to sample X2.
Is your loop feed forward or feed backward ???
I am not clear why AGC loop should work on sample by sample basis without any delay. Normally we check signal power over some time window, possibly then filter the error and then apply correction to incoming stream.
You should integrate your data otherwise, if the algorithm acts 'instantaneously', you will have built a clipper rather than an AGC. The integrator would be very simple, consuming little resource, and will smooth the gain changes. However, the integrator will limit the responsiveness of the system, so there would be overshoots etc. You could reduce this characteristic (it it was considered to be a problem) by putting a delay before the 'gain cell' of the AGC so that the control sidechain can 'look ahead' for any forthcoming peaks.
b2508 I see several good algorithm suggestions here, but assuming your current algorithm is fine as-is, do you have available a faster clock ? Or can you synthesize one from your current sampling clock ? For example if you use a 10x clock and sample every 10th sample, then you have 10 clocks to calculate g(2).