ad9361_dac HDL Worker

Detail

The ad9361_dac.hdl worker ingests signed Q0.15 I/Q samples from its in port, rounds them to signed Q0.11 I/Q samples, then passes them through an asynchronous First-In-First-Out (FIFO) buffer on to the dev_dac devsignal bus. The rounding is done in order to map to the AD9361’s 12-bit I/Q DAC bus. For more information on how ad9361_dac_sub.hdl handles the data from this worker’s dev_dac port, see Ad9361 dac sub (ad9361_dac_sub). The asynchronous FIFO is necessary in order to cross clock domains from control clock to dev_dac‘s dac_clk clock. Note that the control clock rate is considered static but platform-specific and that the clock rate of dac_clk is potentially runtime variable. The FIFO’s depth in number of samples is determined at build-time by the fifo_depth parameter property. The in port’s data width is also configurable via the IDATA_WIDTH_p parameter property, whose default value of 32 allows for a signed Q0.15 I/ Q0.15 Q input sample to be processed in a single control clock cycle. An underrun property indicates when invalid samples have been clocked in by the DAC due to the FIFO being empty.

The event_in port provides a port message-based mechanism (in the control plane clock domain) for turning on/off the AD9361 transmitter. Connection of this port is optional. If the port is disconnected, the transmitter will be on for the duration of an application.

The transmitter is powered on when:

  • the AD9361 is being initialized (typical duration is 200 ms), or

  • one or more ad9361_dac.hdl workers exist in the bitstream and

    • all ad9361_dac.hdl workers have their event_in ports disconnected and any are in the operating state, or

    • any ad9361_dac.hdl workers have their event_in ports connected and receive a txOn message (while in the operating state)

The transmitter is powered off when:

  • the AD9361 is not being initialized and

    • no ad9361_dac.hdl workers exist in the bitstream, or

    • one ad9361_dac.hdl worker exists in the bitstream and

      • is not in the operating state, or

      • is in operating state and has its event_in port connected but has not yet received a message on its event_in port,

      • is in operating state and has its event_in port connected and receives a txOff message on its event_in port

    • two ad9361_dac.hdl workers exist in the bitstream and

      • both workers are not in the operating state, or

      • no workers which are in the operating state and have their event_in port connected have yet received a message on their event_in port

      • both workers have received a txOff message on their event_in ports in succession (with no txOn messages in-between) while in the operating state

Note that the normal use case for utilizing both DAC channels (and thus using two ad9361_dac.hdl workers) is for MIMO applications. As such, the normal use case is to either have no even_in ports connected, causing the transmitter to default to on for the duration of an application, or to have all connected and to send the same txOn/txOff message to all event_in ports simultaneously.

Note that event_in messages exist in the control plane clock domain but the AD9361 registers them in the AD9361 FB_CLK domain, which may be slower than the control plane clock . The min_num_cp_clks_per_txen_event property enforces that tx events are properly synchronized to the AD9361 FB_CLK without losing any events by ensuring event_in messages are property spaced out. This is done by applying backpressure to the event_in port after each message is received. Backpressure is applied for min_num_cp_clks_per_txen_event - 1 number of control plane clocks after each event_in message is received. See property description for more info on calculation of the min_num_cp_clks_per_txen_event value. This property’s default value of 180 was calculated using the worst-case (lowest) AD9361 sampling rate, worst-case (highest) AD9361 TX FIR interpolation factor, and highest known control plane clock rate of 125 MHz. The AD9361 LVDS or CMOS single port full duplex DDR mode was used for the default calculation. This property’s value can be lowered for specific sampling rates / control plane clock rates if desired. Note that if using with a control plane clock rate of greater than 125 MHz, the default value should be overridden with a higher value.

Control Timing and Signals

Clock Domains

The AD9361 DAC device worker contains two clock domains: the clock from the control plane, and the dac_clk clock from the devsignal. It is expected that the control plane clock is faster than the dac_clk clock in order to prevent a FIFO underrun (monitored via the underrun property).

Latency

The latency from the input port to the devsignal data bus is both non-deterministic and dynamic. Non-determinism exists as a result of the data flowing through an asynchronous FIFO with each side in a different clock domain. Runtime dynamism exists as a result of the AD9361 DATA_CLK_P clock, and therefore the dac_clk clock rates, being runtime dynamic. The use of any FIFO, synchronous or asynchronous, between the input port and the devsignal also creates runtime dynamism in latency.

Backpressure

Backpressure is transferred from the devsignal’s dac_clk clock to the input port. The input port is expected to frequently experience backpressure in order to prevent a FIFO underrun. Backpressure is applied to the event_in port according to the min_num_cp_clks_per_txen_event property value.

Performance and Resource Utilization

Fmax refers to the maximum allowable clock rate for any registered signal paths within a given clock domain for an FPGA design. Fmax in the table below is specific only to this worker and represents the maximum possible Fmax for any OpenCPI bitstream built with this worker included. Note that the Fmax value for a given clock domain for the final bitstream is often worse than the Fmax specific to this worker, even if this worker is the only one included in the bitstream.

Table 110: Resource Utilization Table for worker: ad9361_dac

Configuration

OCPI Target

Tool

Version

Device

Registers (Typ)

LUTs (Typ)

Fmax (MHz) (Typ) control plane clock

Fmax (MHz) (Typ) dev_dac.dac_clk clock

Memory/Special Functions

0

zynq

Vivado

2017.1

xc7z020clg484-1

235

225

186

232

0

stratix4

Quartus

17.1.0

EP4SGX230KF40C2

232

315

N/A

N/A

0

virtex6

ISE

14.7

6vlx240tff1156-1

254

371

322.373

383.877

RAM64M: 8

Worker Properties

  • fifo_depth

    • Type: ulong

    • Access:

      • Parameter: True

      • Writable: False

      • Initial: False

      • Volatile: False

      • Read back: False

    • Default value: None

  • IDATA_WIDTH_p

    • Type: ushort

    • Access:

      • Parameter: True

      • Writable: False

      • Initial: False

      • Volatile: False

      • Read back: False

    • Default value: None

  • min_num_cp_clks_per_txen_event

    • Type: ushort

    • Access:

      • Parameter: False

      • Writable: False

      • Initial: True

      • Volatile: False

      • Read back: False

    • Default value: 180

Worker Ports

    Inputs:

  • IN

    • Protocol: iqstream

    • Optional: True

  • event_in

    • Protocol: tx_event

    • Optional: True

  • Interfaces (other than data I/O ports):

  • dev_dac

    • Type: devsignal

  • dev_tx_event

    • Type: devsignal

Worker Signals

  • present

    • Direction: out

    • Differential: false

    • Pin: false

  • dac_clk

    • Direction: in

    • Differential: false

    • Pin: false

  • dac_ready

    • Direction: out

    • Differential: false

    • Pin: false

  • dac_take

    • Direction: in

    • Differential: false

    • Pin: false

  • dac_data_I

    • Direction: out

    • Width: 12

    • Differential: false

    • Pin: false

  • dac_data_Q

    • Direction: out

    • Width: 12

    • Differential: false

    • Pin: false

  • txon_pulse

    • Direction: out

    • Differential: false

    • Pin: false

  • txoff_pulse

    • Direction: out

    • Differential: false

    • Pin: false

  • event_in_connected

    • Direction: out

    • Differential: false

    • Pin: false

  • is_operating

    • Direction: out

    • Differential: false

    • Pin: false

Utilization

Utilization reporting is not currently implemented.

References