Xilinx
HLS
Block Preview

Introduction

Identical to Component_NCO except that the Frequency Tuning Word is a top-level input pin instead of a synthesis-time constant. Wire it from a register slave in your design (SDK / register-file style) and you get a software-tunable LO.

      FTW ─┐
           │  ┌─────┐
           ├─►│ NCO ├── OUT_I / OUT_Q  (complex tone)
    CLK ─┘  └─────┘
  

Pin Description

FTW Input AccSize bit BIT VECTOR
Frequency Tuning Word, unsigned. AccSize bits. f_norm = unsigned(FTW) / 2^AccSize.
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). Default: Global reset.
Default: Default Board Reset
OUT_I Output OutSize bit BIT VECTOR
In-phase output = A * cos(phase). Signed, OutSize bits.
OUT_Q Output OutSize bit BIT VECTOR
Quadrature output = A * sin(phase). Signed, OutSize bits.

Properties

Property window

Phase Accumulator Width AccSize

Bit width of the phase accumulator. Sets both the frequency resolution and the FTW bus width.

Bit width of the phase accumulator, which is also the width of the FTW bus. Default 32.

Default: 32

Options: 16 20 24 28 32 40 48

Output Bit Width OutSize

Bit width of each I / Q output sample (signed)

Bit width of each signed I / Q output sample. Range 8..24, default 16.

Default: 16

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

LUT Address Bits LutAddrSize

log2 of the sin/cos LUT depth. Default 10 -> 1024 entries.

log2 of the sin/cos ROM depth. Default 10 (1024 entries).

Default: 10

Options: 8 9 10 11 12

Usage

FTW bus

FTW is an unsigned AccSize-bit std_logic_vector. The relationship between FTW and the emitted frequency is

      f_norm = unsigned(FTW) / 2^AccSize        (cycles / sample)
    f      = f_norm * Fs                      (Hz)
  

Interpretation is unsigned modulo 2^AccSize : setting FTW = 2^(AccSize-1) gives exactly Fs/2 (Nyquist) — anything higher aliases back.

Inside the HLS core the FTW port is declared ap_stable, meaning:

  • the accumulator samples it combinationally every clock,
  • changes are visible on the output within one clock cycle,
  • the value is not required to be stable across pipeline latency, so it can be updated at any time from the fabric.

Phase resolution and spurs

Same as Component_NCO : df/Fs = 1 / 2^AccSize, SFDR ~= 6 * LutAddrSize dB.

Firmware / driver helper

Converting a target frequency f (Hz) into an FTW word:

python
      def freq_to_ftw(f_hz, fs_hz, acc_size):
        return int(round((f_hz / fs_hz) * (1 << acc_size))) & ((1 << acc_size) - 1)
  

The Python testbench tb/nco/nco_tb.py uses exactly this formula.

Resources & Timing

  • Latency: 1 clock cycle

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

Same footprint as Component_NCO : two ROMs + one adder. The FTW bus adds no logic beyond routing.