rfdc.hdl HDL Worker

Xilinx RF Data Converter Device Worker.

Description

For a full top-down description of the RF Data Converter Architecture, see the drc.rcc worker documentation. The rf_tx and rf_rx device worker signals expose the RF ports. The rx_clks and tx_clks device worker signals ingest the externally-supplied converter clocks. An additional sysref clock is ingested as well. The rfdc HDL primitive wraps a fixed configuration of the Xilinx RF Data Converter IP.

Worker Properties

  • axis_resetn

    • Type: bool

    • Access:

      • Parameter: False

      • Writable: True

      • Initial: False

      • Volatile: False

      • Read back: False

    • Default value: false

  • in0_sample_count

    • Type: ulong

    • Access:

      • Parameter: False

      • Writable: False

      • Initial: False

      • Volatile: True

      • Read back: False

    • Default value: None

  • in1_sample_count

    • Type: ulong

    • Access:

      • Parameter: False

      • Writable: False

      • Initial: False

      • Volatile: True

      • Read back: False

    • Default value: None

  • regs

    • Type: ulong

      • Array dimensions: ['16384']

    • Access:

      • Parameter: False

      • Writable: True

      • Initial: False

      • Volatile: True

      • Read back: False

    • Default value: 0

  • ocpi_buffer_size_out0

    • Type: ushort

    • Access:

      • Parameter: False

      • Writable: False

      • Initial: True

      • Volatile: False

      • Read back: False

    • Default value: 0

  • ocpi_blocked_out0

    • Type: ulong

    • Access:

      • Parameter: False

      • Writable: False

      • Initial: False

      • Volatile: True

      • Read back: False

    • Default value: None

  • ocpi_max_latency_out0

    • Type: ushort

    • Access:

      • Parameter: True

      • Writable: False

      • Initial: False

      • Volatile: False

      • Read back: False

    • Default value: None

  • ocpi_latency_out0

    • Type: ushort

    • Access:

      • Parameter: False

      • Writable: False

      • Initial: False

      • Volatile: True

      • Read back: False

    • Default value: None

  • ocpi_messages_out0

    • Type: ulong

    • Access:

      • Parameter: False

      • Writable: False

      • Initial: False

      • Volatile: True

      • Read back: False

    • Default value: None

  • ocpi_bytes_out0

    • Type: ulong

    • Access:

      • Parameter: False

      • Writable: False

      • Initial: False

      • Volatile: True

      • Read back: False

    • Default value: None

  • ocpi_buffer_size_out1

    • Type: ushort

    • Access:

      • Parameter: False

      • Writable: False

      • Initial: True

      • Volatile: False

      • Read back: False

    • Default value: 0

  • ocpi_blocked_out1

    • Type: ulong

    • Access:

      • Parameter: False

      • Writable: False

      • Initial: False

      • Volatile: True

      • Read back: False

    • Default value: None

  • ocpi_max_latency_out1

    • Type: ushort

    • Access:

      • Parameter: True

      • Writable: False

      • Initial: False

      • Volatile: False

      • Read back: False

    • Default value: None

  • ocpi_latency_out1

    • Type: ushort

    • Access:

      • Parameter: False

      • Writable: False

      • Initial: False

      • Volatile: True

      • Read back: False

    • Default value: None

  • ocpi_messages_out1

    • Type: ulong

    • Access:

      • Parameter: False

      • Writable: False

      • Initial: False

      • Volatile: True

      • Read back: False

    • Default value: None

  • ocpi_bytes_out1

    • Type: ulong

    • Access:

      • Parameter: False

      • Writable: False

      • Initial: False

      • Volatile: True

      • Read back: False

    • Default value: None

  • ocpi_buffer_size_out2

    • Type: ushort

    • Access:

      • Parameter: False

      • Writable: False

      • Initial: True

      • Volatile: False

      • Read back: False

    • Default value: 0

  • ocpi_blocked_out2

    • Type: ulong

    • Access:

      • Parameter: False

      • Writable: False

      • Initial: False

      • Volatile: True

      • Read back: False

    • Default value: None

  • ocpi_max_latency_out2

    • Type: ushort

    • Access:

      • Parameter: True

      • Writable: False

      • Initial: False

      • Volatile: False

      • Read back: False

    • Default value: None

  • ocpi_latency_out2

    • Type: ushort

    • Access:

      • Parameter: False

      • Writable: False

      • Initial: False

      • Volatile: True

      • Read back: False

    • Default value: None

  • ocpi_messages_out2

    • Type: ulong

    • Access:

      • Parameter: False

      • Writable: False

      • Initial: False

      • Volatile: True

      • Read back: False

    • Default value: None

  • ocpi_bytes_out2

    • Type: ulong

    • Access:

      • Parameter: False

      • Writable: False

      • Initial: False

      • Volatile: True

      • Read back: False

    • Default value: None

  • ocpi_buffer_size_out3

    • Type: ushort

    • Access:

      • Parameter: False

      • Writable: False

      • Initial: True

      • Volatile: False

      • Read back: False

    • Default value: 0

  • ocpi_blocked_out3

    • Type: ulong

    • Access:

      • Parameter: False

      • Writable: False

      • Initial: False

      • Volatile: True

      • Read back: False

    • Default value: None

  • ocpi_max_latency_out3

    • Type: ushort

    • Access:

      • Parameter: True

      • Writable: False

      • Initial: False

      • Volatile: False

      • Read back: False

    • Default value: None

  • ocpi_latency_out3

    • Type: ushort

    • Access:

      • Parameter: False

      • Writable: False

      • Initial: False

      • Volatile: True

      • Read back: False

    • Default value: None

  • ocpi_messages_out3

    • Type: ulong

    • Access:

      • Parameter: False

      • Writable: False

      • Initial: False

      • Volatile: True

      • Read back: False

    • Default value: None

  • ocpi_bytes_out3

    • Type: ulong

    • Access:

      • Parameter: False

      • Writable: False

      • Initial: False

      • Volatile: True

      • Read back: False

    • Default value: None

Worker Ports

    Inputs:

  • in0

    • Protocol: complex_short_timed_sample

    • Optional: True

  • in1

    • Protocol: complex_short_timed_sample

    • Optional: True

  • Outputs:

  • out0

    • Protocol: complex_short_timed_sample

    • Optional: True

  • out1

    • Protocol: complex_short_timed_sample

    • Optional: True

  • out2

    • Protocol: complex_short_timed_sample

    • Optional: True

  • out3

    • Protocol: complex_short_timed_sample

    • Optional: True

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

  • s_ctrl_axi

    • Type: devsignal

  • s_dac0_axi

    • Type: devsignal

  • s_dac1_axi

    • Type: devsignal

  • s_dac2_axi

    • Type: devsignal

  • s_dac3_axi

    • Type: devsignal

  • s_adc0_axi

    • Type: devsignal

  • s_adc1_axi

    • Type: devsignal

  • s_adc2_axi

    • Type: devsignal

  • s_adc3_axi

    • Type: devsignal

  • rawprops

    • Type: rawprop

Worker Signals

  • aw_addr

    • Direction: in

    • Width: 32

    • Differential: false

    • Pin: false

  • aw_valid

    • Direction: in

    • Differential: false

    • Pin: false

  • aw_prot

    • Direction: in

    • Width: 3

    • Differential: false

    • Pin: false

  • aw_ready

    • Direction: out

    • Differential: false

    • Pin: false

  • ar_addr

    • Direction: in

    • Width: 32

    • Differential: false

    • Pin: false

  • ar_valid

    • Direction: in

    • Differential: false

    • Pin: false

  • ar_prot

    • Direction: in

    • Width: 3

    • Differential: false

    • Pin: false

  • ar_ready

    • Direction: out

    • Differential: false

    • Pin: false

  • w_data

    • Direction: in

    • Width: 32

    • Differential: false

    • Pin: false

  • w_strb

    • Direction: in

    • Width: 4

    • Differential: false

    • Pin: false

  • w_valid

    • Direction: in

    • Differential: false

    • Pin: false

  • w_ready

    • Direction: out

    • Differential: false

    • Pin: false

  • r_data

    • Direction: out

    • Width: 32

    • Differential: false

    • Pin: false

  • r_resp

    • Direction: out

    • Width: 2

    • Differential: false

    • Pin: false

  • r_valid

    • Direction: out

    • Differential: false

    • Pin: false

  • r_ready

    • Direction: in

    • Differential: false

    • Pin: false

  • b_resp

    • Direction: out

    • Width: 2

    • Differential: false

    • Pin: false

  • b_valid

    • Direction: out

    • Differential: false

    • Pin: false

  • b_ready

    • Direction: in

    • Differential: false

    • Pin: false

  • rx_clks_p

    • Direction: in

    • Width: 4

    • Differential: false

    • Pin: true

  • rx_clks_n

    • Direction: in

    • Width: 4

    • Differential: false

    • Pin: true

  • tx_clks_p

    • Direction: in

    • Width: 1

    • Differential: false

    • Pin: true

  • tx_clks_n

    • Direction: in

    • Width: 1

    • Differential: false

    • Pin: true

  • sysref_p

    • Direction: in

    • Differential: false

    • Pin: true

  • sysref_n

    • Direction: in

    • Differential: false

    • Pin: true

  • rf_rxs_p

    • Direction: in

    • Width: 6

    • Differential: false

    • Pin: true

  • rf_rxs_n

    • Direction: in

    • Width: 6

    • Differential: false

    • Pin: true

  • rf_txs_p

    • Direction: out

    • Width: 3

    • Differential: false

    • Pin: true

  • rf_txs_n

    • Direction: out

    • Width: 3

    • Differential: false

    • Pin: true

The Xilinx RF Data Converter (RFDC) has 3 generations (https://www.xilinx.com/products/intellectual-property/rf-data-converter.html). The following is a non-comprehensive list of capabilities:

  1. Number of RF ADCs range from 0 to 16 (generation-dependent)

  2. Number of RF DACs range from 0 to 16 (generation-dependent)

  3. ADC number of sample bits ranges from 12 bits to 14 bits (generation-dependent)

  4. DAC number of sample bits is 14

  5. ADC RF direction conversion sampling rates vary and are up to 5.9 Gsps (generation-dependent) and are specified at build-time by the IP generator GUI

  6. DAC RF direction conversion sampling rates vary and are up to 10 Gsps (generation-dependent) and are specified at build-time by the IP generator GUI

  7. Digital decimation/interpolation rates range from 1x to 40x (generation-dependent)

  8. Clock source/routing is complicated and the Xilinx IP generator GUI indicates valid/invalid configurations

  9. ADCs and DACs are organized by tiles in a manner that adds significant complexity

Build Configurations

This worker and its underlying rfdc primitive only support the following RFDC configuration(s):

  • config 0

    • Generation 3 ZU48DR (xczu48dr-ffvg1517-2-e)

    • 2 I/Q ADCs (Tiles 224, 226)

    • 2 I/Q DACs (Tile 231)

    • 14-bit ADC (14-bit I, 14-bit Q, data alignment within 16-bit AXI-Stream interface is determined by Xilinx IP generation - see its documentation)

    • 14-bit DAC (14-bit I, 14-bit Q, data alignment within 16-bit AXI-Stream interface is determined by Xilinx IP generation - see its documentation)

    • ADC RF direction conversion sampling rate of 3.6 Gsps

    • DAC RF direction conversion sampling rate of 3.6 Gsps

    • Digital decimation/interpolation rate of 40x (3.6 Gsps / 40 = 90 Msps at AXI-Stream ports)

    • Digital complex mixer (fine frequency control) enabled for every converter (fixed at 390.95 MHz for rx1/rx2/tx2 and 20 for tx1)

Clock Domains

  • ctl clock - the 100 MHz OpenCPI control plane clock that all AXI-Lite interfaces and ports within this worker operate at

  • clk_90 clock - inside the rfdc HDL primitive, the RF Data Converter IP outputs a clock at a power-of-2-divided-rate of the sampling clock (3.6 Gsps/16 = 225 MHz) which then is passed through a Xilinx clock wizard IP to convert from a single 225 MHz clock output to a signal 90 MHz clock used for, and required by, all AXI-Stream ports, which is then crossed over to the ctl clock domain. Also note that all rfdc.vhd signals labelled rx_aclks or tx_aclks are actually the single clk_90 signal and clock domain

  • sys clock - this clock is simply passed in from an external signal to the rfdc HDL primitive and its internal RF Data Converter IP

  • 225 MHz clock - (not exposed external to the rfdc HDL primitive - see clk_90 description)

Resets

  • ctl_in.reset - the active-high 100 MHz OpenCPI control plane reset which is used to reset the rfdc HDL primitive, and its internal RF Data Convert IP, AXI-Lite interface

  • props_in.axis_resetn - an additional active-low 100 MHz OpenCPI control plane reset which is used asynchronously to keep the AXI-Stream ports (which are on the clk_90 domain) in reset longer according the Xilinx RF Data Converter IP Power-On Reset requirements related to the external sampling clock initialization

  • clk_90_reset - active-high reset in the clk_90 domain used for all AXI-Stream ports of the rfdc HDL primitive and its internal RF Data Converter IP (erroneously labelled as std_logic_vector rx_aresets in rfdc.vhd which is really all a single reset)

  • clk_90_reset_n - active-low version of clk_90 (erroneously labelled as std_logic_vector rx_aresetns in rfdc.vhd which is really all a single reset)

Constraints - IMPORTANT

This worker was designed and tested using the Xilinx-documented IP flow which creates a managed IP project and uses the output XCI file for integration into the final implementation phase that occurs within OpenCPI HDL assembly builds for Xilinx. This XCI file is exported during the rfdc HDL primitive build process, and contains constraints for all clocks related to the RF data converter IP. OpenCPI does not have a well-supported mechanism for exporting and including XCI files. See this project’s hdl/assemblies directory for examples of how this XCI was included with custom build.tcl files which are imported into OpenCPI using its undocumented HdlPreOptHook GNU Make variable in assembly makefiles. By following this flow, users can see the Xilinx RF data converter clocks show up in the final static timing analysis report (assembly container…/target/…/timing.out is the file name at the time of writing this document).

Design Philosophy

The rfdc.hdl worker contains a fixed number of WSI ports according to the previously mentioned ADC/DAC configuration(s). Future support for additional configuration(s) require detailed investigation of the common functionality, especially the clock configuration, and incorporating additional parameter properties (and mapping them to underlying rfdc primitive VHDL generics) and OpenCPI ports in the worker’s component specification (and mapping them to underlying rfdc primitive AXI-Stream ports), and enabling the parameter-controlled configuration via a worker build.xml.

AXI-Lite Register Access

The permissible address space per OpenCPI HDL worker has limited documentation. Because runtime exceptions were occurring when putting all possible Xilinx RFDC IP registers within the rfdc.hdl worker’s property space, the IP address space was segmented in 16 KB segments across the following workers according to a similar segmentation within the RF Data Converter IP itself:

  • rfdc.hdl

  • rfdc_dac_config_0.hdl

  • rfdc_dac_config_1.hdl

  • rfdc_dac_config_2.hdl

  • rfdc_dac_config_3.hdl

  • rfdc_adc_config_0.hdl

  • rfdc_adc_config_1.hdl

  • rfdc_adc_config_2.hdl

  • rfdc_adc_config_3.hdl

The overarching software in drc.rcc knows about this segmentation and forwards each libmetal register access to the proper HDL worker.

rfdc HDL Primitive

The primitive consists of a Makefile, Vivado TCL script, and a VHDL wrapper module and corresponding VHDL package. The following build steps are performed:

  1. Create Xilinx Managed IP Project (“a special project for managing customizations and output products of specified IP” (https://docs.xilinx.com/r/en-US/ug896-vivado-ip/Using-Manage-IP-Projects) which is well-suited to wrapping Xilinx IP in OpenCPI HDL primitives).

  2. Instance the Xilinx RF Data Converter IP

  3. Configure the Xilinx RF Data Converter IP as previously mentioned

  4. Export Xilinx RF Data Converter IP instantiation templates

  5. Perform Xilinx RF Data Converter IP synthesis

  6. Write Xilinx RF Data Converter IP VHDL stub file

  7. Instance the Xilinx clock wizard IP

  8. Configure the Xilinx clock wizard IP for 225 MHz to 90 MHz clock conversion

  9. Export Xilinx clock wizard IP instantiation templates

  10. Perform Xilinx clock wizard IP synthesis

  11. Write Xilinx clock wizard IP VHDL stub file

The generic_pcie primitive was used as an example for Xilinx IP managed project creation and synthesis. The rfdc primitive contains a fixed number of AXI-Stream ports according to the previously mentioned configuration(s). Future support for additional configuration(s) requires highly detailed investigation of the common functionality, especially the clock configuration, and incorporating additional VHDL generics and/or AXI-Stream ports in the rfdc primitive. The rfdc primitive instances a custom AXI-Lite interconnect that properly forwards the worker-segmented property spaces to the single AXI-Lite slave interface on the Xilinx IP module.