Xilinx
HLS
Block Preview

Introduction

The Real AGC (linear) block multiplies the input by an adaptive gain and drives a control loop that pushes the output power toward a fixed target. The full per-sample loop is:

      y   = clamp( (x * gain) >> GAIN_FRAC , OUT_MIN , OUT_MAX )
    avg += (y*y - avg) >> AVG_SHIFT          (leaky power estimate)
    err  = TARGET - avg
    gain += err >> LOOP_SHIFT                 (integrator / loop filter)
    gain = clamp(gain, MIN_GAIN, MAX_GAIN)
  

It is a linear AGC: the gain is applied as a plain multiply and the error is driven from the mean-square (y*y) power estimate rather than a log/dB detector. gain is an unsigned fixed-point number with GainFrac fractional bits, so gain = 2^GainFrac corresponds to unity gain.

      IN ──▶(×)──▶[ clamp ]──▶ OUT
           ▲                  │
          gain ◀─[ loop ]◀─[ y*y avg ]◀─┘
  

When the output power sits below the target, err is positive and the integrator ramps the gain up; when it exceeds the target the gain ramps down. The steady state is reached when avg ≈ TARGET.

Pin Description

IN Input InputSize bit BIT VECTOR
Real input sample. Signed, Input Bit Width (InputSize) bits.
Default: Must be connected
CLK Input 1 bit BIT
System clock input. Default: Acquisition clock.
Default: Default Board Clock
RESET Input 1 bit BIT
HLS synchronous reset (ap_rst). Initialises gain to unity (2^GainFrac) and avg to 0. Default: Global reset.
Default: Default Board Reset
OUT Output OutputSize bit BIT VECTOR
Gain-controlled, power-normalised output = clamp((x*gain) >> GainFrac). Signed, Output Bit Width (OutputSize) bits, saturated to the output range.

Properties

Property window

Input Bit Width InputSize

Bit width of the input sample (signed).

Bit width of the signed input sample. Range 4 to 32, default 16. Changing this triggers a redesign.

Default: 16

Options: 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32

Output Bit Width OutputSize

Bit width of the output sample (signed). Typical: InputSize + 2.

Bit width of the signed output sample. Range 8 to 40, default 18. Output is saturated to this width. Typical value: InputSize + 2 for boost headroom. Changing this triggers a redesign.

Default: 18

Options: 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40

Gain Register Bit Width GainSize

Bit width of the internal gain (unsigned).

Bit width of the internal unsigned gain register. Range 12 to 24, default 18. Together with GainFrac it sets the maximum gain (≈ 2^(GainSize - GainFrac)). Changing this triggers a redesign.

Default: 18

Options: 12 13 14 15 16 17 18 19 20 21 22 23 24

Gain Fractional Bits GainFrac

Fractional bits of the gain (gain=2^GainFrac means unity).

Number of fractional bits of the gain. gain = 2^GainFrac is unity gain. Range 4 to 20, default 12. Also sets the minimum gain floor 2^(GainFrac-4) (= 1/16). Changing this triggers a redesign.

Default: 12

Options: 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

Target y^2 (log2) TargetLog2

Target power = 2^TargetLog2. For sinusoids set 1 bit lower than the complex AGC for the same audible level.

Target output power as a power of two: mean(y^2) = 2^TargetLog2. Range 8 to 40, default 25. For a sinusoid, set this one bit lower than the complex AGC to obtain the same amplitude (mean(y^2) = A^2/2 for a real tone). Does not force a redesign.

Default: 25

Options: 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40

Loop-filter Shift (slower = bigger) LoopShift

Integrator shift; larger = slower AGC. 12-20 typical.

Integrator (loop-filter) shift: gain += err >> LoopShift. Larger = slower, smoother AGC; smaller = faster tracking. Range 4 to 24, default 16 (12–20 typical). Does not force a redesign.

Default: 16

Options: 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24

Envelope Smoothing Shift AvgShift

Leaky IIR shift for the y^2 estimate. 4-10 typical.

Leaky-IIR shift for the y^2 power estimate: avg += (y*y - avg) >> AvgShift. Larger averages over more samples (steadier gain, slower envelope response). Range 0 to 16, default 6 (4–10 typical). Does not force a redesign.

Default: 6

Options: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

Usage

Control-loop model

Three state elements form the loop:

  1. avg — a leaky-integrator (first-order IIR) estimate of the output power E[y^2], updated as avg += (y*y - avg) >> AvgShift. This is a one-pole low-pass with time constant ~2^AvgShift samples; it smooths the instantaneous y*y so the loop reacts to envelope power rather than sample-by-sample ripple.
  2. err = TARGET - avg — the power error, where TARGET = 2^TargetLog2.
  3. gain — an integrator updated by gain += err >> LoopShift. A larger LoopShift makes each correction smaller, i.e. a slower, smoother AGC; a smaller value tracks faster but with more gain ripple / possible pumping.

Because the error feeds an integrator, the loop has zero steady-state power error (within quantisation): at lock avg ≈ 2^TargetLog2.

Target power note (real vs complex)

For a pure sinusoid of amplitude A, the real signal has mean(y^2) = A^2 / 2, whereas a complex tone A*(cos + j*sin) has |.|^2 = A^2 at every sample. The two AGCs therefore lock a sinusoid to different amplitudes for the same TargetLog2. To get the same output level from this real AGC as from the complex AGC, set TargetLog2 one bit lower here.

Fixed-point datapath and bit widths

All signal data is signed two’s complement; the gain is unsigned.

  • IN : signed InputSize bits.
  • OUT : signed OutputSize bits, clamped (saturated) to [-2^(OutputSize-1), 2^(OutputSize-1) - 1]. Typical OutputSize = InputSize + 2 to give the AGC headroom to boost small inputs without immediate clipping.
  • gain : unsigned GainSize bits, GainFrac fractional bits. Unity = 2^GainFrac.
  • Product x * gain : InputSize + GainSize bits, arithmetic-shifted right by GainFrac to align back to sample scale.
  • Power estimate avg and y*y : signed 2*OutputSize + 8 bits — wide enough to hold the squared full-scale output plus 8 guard bits for the leaky-integrator accumulation.
  • Gain update is computed in GainSize + 4 bits to avoid overflow during the clamp.

Gain limits (clamp)

The gain integrator is bounded to keep the loop stable and prevent runaway on silence:

      MIN_GAIN = 2^(GainFrac - 4)          ->  linear min = 1/16  (-24 dB)
    MAX_GAIN = 2^GainSize - 1            ->  linear max ≈ 2^(GainSize - GainFrac)
  

With the defaults (GainSize = 18, GainFrac = 12) the gain ranges from 1/16 up to ≈ 2^6 = 64 (about +36 dB). Widen GainSize to allow more boost of very weak signals.

Feedback / state registers and reset

RESET is the HLS synchronous reset (ap_rst). On reset the loop state is initialised to a safe starting point:

  • gain = 2^GainFrac (unity gain), so the very first output equals the input (scaled to OUT) before the loop adapts.
  • avg = 0, so the loop initially sees maximum positive error and begins ramping the gain toward the target at the rate set by LoopShift.

After release the AGC converges to the target power over roughly 2^LoopShift (loop) combined with 2^AvgShift (envelope smoothing) samples; the dominant term is normally LoopShift.

Latency and throughput

  • #pragma HLS PIPELINE II=1 : one sample per clock.
  • 1-clock latency (registered output).
  • All data ports use the ap_none interface — no ready/valid handshake. Every tuning value (TargetLog2, LoopShift, AvgShift, gain format) is baked in at synthesis time; no top-level control pins are created.

Tuning guidance

  • TargetLog2 — sets the output level: mean(y^2) = 2^TargetLog2, i.e. RMS ≈ 2^(TargetLog2/2). Keep RMS comfortably below 2^(OutputSize-1) to leave crest-factor headroom before the output clamp engages.
  • LoopShift (12–20 typical) — attack/decay speed. Larger = slower and smoother, less pumping; smaller = faster tracking of level changes.
  • AvgShift (4–10 typical) — envelope smoothing. Larger averages the power over more samples (steadier gain, slower response to bursts).

Typical applications

  • Constant-level audio / IF ahead of an FM/AM demodulator or a fixed-threshold detector.
  • Fading compensation on a real IF channel (slow LoopShift).
  • Normalising a variable-amplitude stream so a downstream fixed-point stage sees a predictable dynamic range.
  • Squelch-friendly leveling — the MIN_GAIN floor stops the loop from amplifying noise to full scale during silence.

Resources & Timing

  • Latency: 1 clock cycle

  • Throughput: 1 sample per clock (II=1)

Implemented with Vitis HLS. Single-multiplier signal path (x * gain) plus one squarer (y*y) for the power estimate — roughly two DSP48 slices, half the arithmetic of the complex AGC. Three state registers: gain, avg, and the pipelined output. No BRAM. On ap_rst, gain resets to unity (2^GainFrac) and avg to 0. The output clamp (saturation) and the gain-integrator clamp (MIN_GAIN..MAX_GAIN) keep the loop bounded and stable.