The axi_ad9361 IP core interfaces to the AD9361 device. This documentation only covers the IP core and requires that one must be familiar with the device for a complete and better understanding.
More about the generic framework interfacing ADCs can be read here: axi_adc_ip, and for DACs: axi_dac_ip.
The axi_ad9361 cores architecture contains:
The IP supports both LVDS and CMOS Dual Port Full Duplex interfaces (configurable, see parameters section). It avoids all the programmable flavors of the device interface mess. The interface is in fact quite simple, in LVDS mode samples require two active clock edges and in CMOS mode a single edge. The samples are then delineated in-order using the FRAME signal. This is applicable to both DDR and SDR modes. There is a limitation though, the IP core does NOT support swapping of the data ports in CMOS mode. This option is left as a constraint. As an example the PZSDR projects uses SWAP on some boards based on the board layout.
Let's consider the 2R2T configuration, each frame consists of 4 samples in each direction. In LVDS-DDR mode that is 8 clock edges (4 full clock cycles) identified by a frame pattern of 8'b11110000. The IP interface logic simply collects data on consecutive 8 edges and deframes using the FRAME signal and outputs the samples. The device does the same in the transmit direction. In CMOS mode, the same is done over 4 clock edges.
The interface also provides a single clock tree for the entire core. This clock uses a global buffer that has the minimum skew all across the die. On Altera devices, this is done via the PLL and because the LVDS cores do NOT support a serialization factor of 2, runs at half the interface clock frequency. On Xilinx devices, this is done via the BUFG and the core and interface runs at the same clock frequency.
The core is tested to work only on Cyclone V Arrow SOC Kit. Since Altera does half-thought board designs that do not favor FMC bank allocations, we are incapable of validating the core on other devices.
1. Using MMCM 2. Using BUFIO/BUFR
1. Interface Logic Only 2. Disable DSP Functions 3. Removing AXI interface and Processor Control
The main purpose of all (including this) ADI IP cores is to provide a common, well-defined internal interface within the FPGA. This interface consists of the following signals per channel.
The enable signal is strictly for software use and is controlled by the corresponding register bit. The core simply reflects the programmed bit as an output port. In ADI reference projects, this bit is used to activate the channel of interest. It is then used by the PACK/UNPACK cores to route the data based on total number of channels and the selected number of channels. As an example, AXI_AD9361 supports a total of 4 channels 16bits each. This corresponds to a packed channel data width of 64bits. If software enables only two channels the packed 64bits of data is exclusively shared by the enabled 2 channels (each channel gets 32 bits of data).
The valid signal is sourced by the core to indicate a valid sample on the DATA port. In the receive (ADC) direction this indicates a valid sample and in the transmit (DAC) direction this indicates the current sample is being read by the core. The valid is simply a 'reflective' of the 'sampling rate'. Note that he cores always run at the interface clock. This is to avoid any customized clock handling or transfer within this core. However in many cases interface clock may not be the sampling clock. As an example for AD9361 the interface clock is 244Mhz for a sampling clock of 61MHz. That is each channel's sampling rate is 61MHz. This translates into the VALID signal being asserted once every 4 clocks. In cores where sampling rate is same as the interface clock, VALID is always asserted and may be safely ignored.
A common interpretation of this is that all channels has the same VALID behavior. This is NOT necessarily true. A majority of use cases may have this as a result of data path equivalency. However, if software decides to enable/disable functions differently among channels, the VALID signals of those channels will NOT be the same.
The DATA is the raw Analog samples. It follows two simple rules.
Name | Description | Default Value |
---|---|---|
ID | Core ID should be unique for each AD9361 IP in the system | 0 |
DEVICE_TYPE | Used to select between 7 Series (0), Virtex 6 (1) or Ultrascale (2) for Xilinx devices | 0 |
MODE_1R1T | Used to select between 2RX2TX (0) and 1RX1TX (1) mode. | 0 |
TDD_DISABLE | Setting this parameter the TDD control will not be implemented in the core. | 0 |
CMOS_OR_LVDS_N | Defines the physical interface type, set 1 for CMOS and 0 for LVDS | 0 |
ADC_DATAPATH_DISABLE | If set, the data path processing logic is not generated in the RX path, and the raw data is pushed directly to the DMA interface. | 0 |
ADC_USERPORTS_DISABLE | Disable the User Control ports in receive path. | 0 |
ADC_DATAFORMAT_DISABLE | Disable the Data Format control module. | 0 |
ADC_DCFILTER_DISABLE | Disable the DC Filter module. | 0 |
ADC_IQCORRECTION_DISABLE | Disable the IQ Correction module in receive path. | 0 |
DAC_DATAPATH_DISABLE | If set, the data path processing logic is not generated in the TX path, and the raw data is pushed directly to the physical interface. | 0 |
DAC_IODELAY_ENABLE | Set IO_DELAY control in transmit path. | 0 |
DAC_DDS_DISABLE | Disable the DDS modules in transmit path. | 0 |
DAC_USERPORTS_DISABLE | Disable the User Control ports in transmit path. | 0 |
DAC_IQCORRECTION_DISABLE | Disable the IQ Correction module in transmit path. | 0 |
IO_DELAY_GROUP | The delay group name which is set for the delay controller | “dev_if_delay_group” |
Interface | Pin | Type | Description |
---|---|---|---|
LVDS RX interface | |||
rx_clk_in_* | input | LVDS input clock | |
rx_frame_in_* | input | LVDS input frame signal | |
rx_data_in_* | input[ 5:0] | LVDS input data lines | |
CMOS RX interface | |||
rx_clk_in | input | CMOS input clock | |
rx_frame_in | input | CMOS input frame signal | |
rx_data_in | input[11:0] | CMOS input data lines | |
LVDS TX interface signals | |||
tx_clk_in_* | output | LVDS output clock | |
tx_frame_in_* | output | LVDS output frame signal | |
tx_data_in_* | output[ 5:0] | LVDS output data lines | |
CMOS TX interface signals | |||
tx_clk_in | output | CMOS input clock | |
tx_frame_in | output | CMOS input frame signal | |
tx_data_in | output[11:0] | CMOS input data lines | |
TDD control interface | |||
enable | output | ENSM control signal, see User Guide for more information | |
txnrx | output | ENSM control signal, see User Guide for more information | |
TDD sync interface | |||
tdd_sync | input | SYNC input for frame synchronization in TDD mode | |
tdd_sync_cntr | output | SYNC output for frame synchronization in TDD mode | |
Delay Clock | |||
delay_clk | input | Delay clock input for IO_DELAY control, connect to 200 Mhz clock | |
Transmit master/slave | |||
dac_sync_in | input | Synchronization signal of the transmit path for slave devices (ID>0) | |
dac_sync_out | output | Synchronization signal of the transmit path for master device (ID==0) | |
Core clock and reset | |||
l_clk | output | This clock should be used for further data processing | |
clk | input | Must be driven by l_clk |
|
rst | output | Core reset signal | |
DMA_RX interface | |||
adc_enable_* | output | If set, the channel is enabled (one for each channel) | |
adc_valid_* | output | Indicates valid data at the current channel (one for each channel) | |
adc_data_* | output[15:0] | Received data output (one for each channel) | |
adc_dovf | input | Data overflow, must be connected to the DMA | |
adc_dunf | input | Data underflow, must be connected to the DMA | |
adc_r1_mode | output | If set, core is functioning in single channel mode (one I/Q pair) | |
DMA_TX interface | |||
dac_enable_* | output | If set, the channel is enabled (one for each channel) | |
dac_valid_* | output | Indicates valid data request at the current channel (one for each channel) | |
dac_data_* | input[15:0] | Transmitted data output (one for each channel) | |
dac_dovf | input | Data overflow, must be connected to the DMA | |
dac_dunf | input | Data underflow, must be connected to the DMA | |
dac_r1_mode | output | If set, core is functioning in single channel mode (one I/Q pair) | |
AXI_S_MM interface | |||
s_axi_* | Standard AXI Slave Memory Map interface | ||
GPIO interface | |||
up_enable | input | GPI control of the ENABLE line in TDD mode, when HDL TDD control is DISABLED | |
up_txnrx | input | GPI control of the TXNRX line in TDD mode, when HDL TDD control is DISABLED | |
up_dac_gpio_in | input[31:0] | GPI ports connected to the AXI memory map for custom use | |
up_dac_gpio_out | output[31:0] | GPI ports connected to the AXI memory map for custom use | |
up_adc_gpio_in | input[31:0] | GPI ports connected to the AXI memory map for custom use | |
up_adc_gpio_out | output[31:0] | GPO ports connected to the AXI memory map for custom use |
The register map of the core contains instances of several generic register maps like ADC common, ADC channel, DAC common, DAC channel etc. The following table presents the base addresses of each instance, after that can be found the detailed description of each generic register map. The absolute address of a register should be calculated by adding the instance base address to the registers relative address.
Address | Name | Description | |||
DWORD | BYTE | ||||
0x0000 | 0x0000 | BASE | See the Base (common to all cores) table for more detail | ||
---|---|---|---|---|---|
0x0000 | 0x0000 | RX COMMON | See the ADC Common table for more detail | ||
0x0000 | 0x0000 | RX CHANNELS | See the ADC Channel table for more detail | ||
0x1000 | 0x4000 | TX COMMON | See the DAC Common table for more detail | ||
0x1000 | 0x4000 | TX CHANNELS | See the DAC Channel table for more detail | ||
0x2000 | 0x8000 | TDD CONTROL | See the Transceiver TDD Control table for more detail |
The software for this IP can be found as part of the FMCOMMS2/3/4/5 Reference Design at: No-Os Software.
Linux is supported also using ADI Linux repository