Wiki

This version is outdated by a newer approved version.DiffThis version (09 Oct 2021 13:44) is a draft.
Approvals: 0/1
The Previously approved version (27 Sep 2021 16:01) is available.Diff

This is an old revision of the document!


Timing-Division Duplexing (TDD) Controller

TDD (Time Division Duplex) mode allows the user to control the time period of the receive and transmit bursts.

The AXI TDD engine is a relatively simple peripheral originally intended to be used for TDD (wireless) communication systems. It solves the synchronization issue when transmitting and receiving multiple frames of data through multiple buffers.

Features

  • 6 independent output channels
  • Primary and secondary timing per channel
  • 24 bit accumulator
  • External (1 PPS, shared or from GPSDO, etc.) synchronization to work with multiple devices

Utilization

Device Family LUTs FFs
Xilinx Zynq UltraScale+ 990 2738

Files

Name Description
axi_tdd.v Verilog source for the peripheral.
ad_tdd_control.v Main TDD controller - manages the signals
up_tdd_cntrl.v up interface (Later bridged to AXIL)
cf_axi_tdd.c TDD Linux Driver
zynqmp-zcu102-rev10-ad9081-m8-l4-tdd.dts Device tree using TDD

Theory of Operation

The central idea of the TDD engine is “frame”-based operation, i.e. all the timing defined for the individual channels is relative to the beginning of a frame. The frame_length parameter controls the length of a single frame, while the burst_count parameter controls how many frames should be played after enabling the device (a value of 0 means frames will be repeated indefinitely). Another important aspect of the peripheral is the external synchronization capability, which allows the alignment of frames between multiple devices in different locations, for example using a GPSDO 1 PPS output.

This diagram tries to illustrate how the different channels can be enabled at different times relative to the beginning of a frame.

While the above graphic shows all channels being enabled in a stacked manner, they are completely independent of each other!

Connectivity

Detailed description

When there is asymmetry (caused by dynamically allocating the amount of time for uplink and downlink) between the data rates of the uplink and downlink, the IP is able to control when the RX buffer is read from and the TX buffer is played. There will be a fixed time offset between every i-th RX and TX sample, synchronizing the communication between the transmit and receive paths, as simple as possible, without using network synchronization.

AXI TDD divides data streams into frames and assigns different time slots to forward and reverse transmissions, sending and receiving the buffers in the initial order, and at specific and known times.

The TDD control contains 2 counters: a 24 bit free running counter for frames, and a 6 bit counter for bursts, the first one being compared with several configurable registers. Both counters can be configured to start from a certain value, through the corresponding registers (check the register map for TDD_COUNTER_INIT and TDD_BURST_COUNT).

The frame counter counts to the length of the current frame that is processed, and marks further if the end of the frame has been reached (also resetting the counter). Depending on the registers it is compared with, some control signals are turned on or off (for VCO and RF paths). The end of a burst is marked by the last burst and the end of the frame.

The frame counter is implemented using a state machine. When counter is working (ON state), and either the TDD is not enabled or it reached the end of burst, the counter in the next state will stop counting. When the counter is stopped (OFF state), it can be turned on again by enabling the TDD.

I/O Interface

Interface Pin Type Description
Core clock and reset
clk input Core clock signal
rst output Core reset signal
TDD control interface
tdd_enabled output Status signal
tdd_rx_vco_en output Output TDD control signal
tdd_tx_vco_en output Output TDD control signal
tdd_rx_rf_en output Output TDD control signal
tdd_tx_rf_en output Output TDD control signal
tdd_tx_valid output TX data flow control
tdd_rx_valid output RX data flow control
TDD sync interface
tdd_sync input SYNC input for frame synchronization (1 PPS)
tdd_sync_cntr output SYNC output for frame synchronization (1 PPS)
AXI4 Lite interface
s_axi_* Standard AXI Slave Memory Map interface

Register Map

Click to display ⇲

Click to hide ⇱

Address Bits Name Type Default Description
DWORD BYTE
0x0010 0x0040 REG_TDD_CONTROL_0 TDD Control & Status
[5] TDD_GATED_TX_DMAPATH RW 0x0 If this bit is set, the core requests data from the TX DMA, just when the data path is active. Otherwise will requests continuously on the adjusted rate. The purpose of this feature is to facilitate debug. This bit must be SET to preserve data integrity.
[4] TDD_GATED_RX_DMAPATH RW 0x0 If this bit is set, the core provides data for the RX DMA, just when the data path is active. Otherwise will provides continuously on the adjusted rate. The purpose of this feature is to facilitate debug. This bit must be SET to preserve data integrity.
[3] TDD_TXONLY RW 0x0 If this bit is set- the TDD controller ignores all the TX_* timing registers below and assumes continuous receive operation within a frame.
[2] TDD_RXONLY RW 0x0 If this bit is set- the TDD controller ignores all the RX_* timing registers below and assumes continuous transmit operation within a frame.
[1] TDD_SECONDARY RW 0x0 Enable the secondary transmit/receive on the active frame. If this bit is clear the controller only uses the _1 timing registers below. If this bit is set - the controller uses the _1 and _2 timing registers below.
[0] TDD_ENABLE RW 0x0 If set, enables the TDD controller- software must set this bit after programming all the registers that controls the tdd timing. Any device settings needs to be done (for example bring the AD9361 to the alert state) prior to to setting this bit. The controller keeps the frame counters in reset if this bit is reset. A 0 to 1 transition in this bit starts the frame counter and tdd mode of operation.
0x0011 0x0044 REG_TDD_CONTROL_1 TDD Control & Status
[7:0] TDD_BURST_COUNT RW 0x00 If set to 0x0 and enabled (TDD_ENABLE is set) - the controller operates in TDD mode as long as the TDD_ENABLE bit is set. If set to a non-zero value, the controller operates for the set number of frames and stops.
0x0012 0x0048 REG_TDD_CONTROL_2 TDD Control & Status
[23:0] TDD_COUNTER_INIT RW 0x000000 The controller sets the frame counter to this value when starting TDD operation. This is the starting offset value for the TDD frame counter.
0x0013 0x004c REG_TDD_FRAME_LENGTH TDD Control & Status
[23:0] TDD_FRAME_LENGTH RW 0x000000 The frame length is the terminal count for the 10ms counter running at the digital interface clock- as an example for a 245.76MHz clock it is 0x258000.
0x0014 0x0050 REG_TDD_SYNC_TERMINAL_TYPE TDD Control & Status
[0] TDD_SYNC_TERMINAL_TYPE RW 0x0 Set this bit, if the current terminal will generate the syncronization pulse, reset otherwise.
0x0018 0x0060 REG_TDD_STATUS TDD Control & Status
[0] TDD_RXTX_VCO_OVERLAP RO 0x0 This bit is asserted, if exist a time interval when both the TX and RX VCOs are powered up.
[1] TDD_RXTX_RF_OVERLAP RO 0x0 This bit is asserted, if exist a time interval when both the TX and RX RF datapath are powered up.
0x0020 0x0080 REG_TDD_VCO_RX_ON_1 TDD Control & Status
[23:0] TDD_VCO_RX_ON_1 RW 0x000000 Defines the offset (from frame count equal zero), when the RX VCO powers up at the first time. The controller enables the receive VCO, when the frame count reaches this value. The VCO may have to be enabled before data can be received. The user needs to make sure, that the RF device is in a state, from where this operation is valid.
0x0021 0x0084 REG_TDD_VCO_RX_OFF_1 TDD Control & Status
[23:0] TDD_VCO_RX_OFF_1 RW 0x000000 Defines the offset (from frame count equal zero), when the RX VCO powers down at the first time. The controller disables the receive VCO, when the frame count reaches this value. The user needs to make sure, that the RF device is in a state, from where this operation is valid.
0x0022 0x0088 REG_TDD_VCO_TX_ON_1 TDD Control & Status
[23:0] TDD_VCO_TX_ON_1 RW 0x000000 Defines the offset (from frame count equal zero), when the TX VCO powers up at the first time. The controller enables the transmit VCO, when the frame count reaches this value. The user needs to make sure, that the RF device is in a state, from where this operation is valid.
0x0023 0x008c REG_TDD_VCO_TX_OFF_1 TDD Control & Status
[23:0] TDD_VCO_TX_OFF_1 RW 0x000000 Defines the offset (from frame count equal zero), when the TX VCO powers down at the first time. The controller disables the transmit VCO when the frame count reaches this value. The user needs to make sure, that the RF device is in a state, from where this operation is valid.
0x0024 0x0090 REG_TDD_RX_ON_1 TDD Control & Status
[23:0] TDD_RX_ON_1 RW 0x000000 Defines the offset (from frame count equal zero), when the RX data path is activated at the first time. The controller enables the receive chain when the frame count reaches this value. The user needs to make sure, that the RF device is in a state, from where this operation is valid.
0x0025 0x0094 REG_TDD_RX_OFF_1 TDD Control & Status
[23:0] TDD_RX_OFF_1 RW 0x000000 Defines the offset (from frame count equal zero), when the RX data path is deactivated the first time. The controller disables the receive chain when the frame count reaches this value. The user needs to make sure, that the RF device is in a state, from where this operation is valid.
0x0026 0x0098 REG_TDD_TX_ON_1 TDD Control & Status
[23:0] TDD_TX_ON_1 RW 0x000000 Defines the offset (from frame count equal zero), when the TX data path is activated at the first time. The controller enables the transmit chain, when the frame count reaches this value. This register and the TX_DP_ON register controls the delay between the data path being activated and the time to actually push the transmit data through the transmit chain in the device.
0x0027 0x009c REG_TDD_TX_OFF_1 TDD Control & Status
[23:0] TDD_TX_OFF_1 RW 0x000000 Defines the offset (from frame count equal zero), when the TX data path is deactivated at the first time. The controller disables the transmit chain, when the frame count reaches this value. This register and the TX_DP_OFF register controls the delay between the data path being deactivated and the time to actually stop transmitting data through the transmit chain in the device.
0x0028 0x00a0 REG_TDD_RX_DP_ON_1 TDD Control & Status
[23:0] TDD_RX_DP_ON_1 RW 0x000000 Defines the offset (from frame count equal zero), when the controller starts to accept data from the digital interface for receive.
0x0029 0x00a4 REG_TDD_RX_DP_OFF_1 TDD Control & Status
[23:0] TDD_RX_DP_OFF_1 RW 0x000000 Defines the offset (from frame count equal zero), when the controller stops to accept data from the digital interface for receive.
0x002A 0x00a8 REG_TDD_TX_DP_ON_1 TDD Control & Status
[23:0] TDD_TX_DP_ON_1 RW 0x000000 Defines the offset (from frame count equal zero), when the controller starts to request data from the system memory for transmit. The data rate is controlled by the TDD controller.
0x002B 0x00ac REG_TDD_TX_DP_OFF_1 TDD Control & Status
[23:0] TDD_TX_DP_OFF_1 RW 0x000000 Defines the offset (from frame count equal zero), when the controller stop requesting data from the system memory for transmit.
0x0030 0x00c0 REG_TDD_VCO_RX_ON_2 TDD Control & Status
[23:0] TDD_VCO_RX_ON_2 RW 0x000000 The secondary pointer for VCO_RX_ON.
0x0031 0x00c4 REG_TDD_VCO_RX_OFF_2 TDD Control & Status
[23:0] TDD_VCO_RX_OFF_2 RW 0x000000 The secondary pointer for VCO_RX_OFF.
0x0032 0x00c8 REG_TDD_VCO_TX_ON_2 TDD Control & Status
[23:0] TDD_VCO_TX_ON_2 RW 0x000000 The secondary pointer for VCO_TX_ON.
0x0033 0x00cc REG_TDD_VCO_TX_OFF_2 TDD Control & Status
[23:0] TDD_VCO_TX_OFF_2 RW 0x000000 The secondary pointer for VCO_TX_OFF.
0x0034 0x00d0 REG_TDD_RX_ON_2 TDD Control & Status
[23:0] TDD_RX_ON_2 RW 0x000000 The secondary pointer for RX_ON.
0x0035 0x00d4 REG_TDD_RX_OFF_2 TDD Control & Status
[23:0] TDD_RX_OFF_2 RW 0x000000 The secondary pointer for RX_OFF.
0x0036 0x00d8 REG_TDD_TX_ON_2 TDD Control & Status
[23:0] TDD_TX_ON_2 RW 0x000000 The secondary pointer for TX_ON.
0x0037 0x00dc REG_TDD_TX_OFF_2 TDD Control & Status
[23:0] TDD_TX_OFF_2 RW 0x000000 The secondary pointer for TX_OFF.
0x0038 0x00e0 REG_TDD_RX_DP_ON_2 TDD Control & Status
[23:0] TDD_RX_DP_ON_2 RW 0x000000 The secondary pointer for RX_DP_ON.
0x0039 0x00e4 REG_TDD_RX_DP_OFF_2 TDD Control & Status
[23:0] TDD_RX_DP_OFF_2 RW 0x000000 The secondary pointer for RX_DP_OFF.
0x003A 0x00e8 REG_TDD_TX_DP_ON_2 TDD Control & Status
[23:0] TDD_TX_DP_ON_2 RW 0x000000 The secondary pointer for TX_DP_ON.
0x003B 0x00ec REG_TDD_TX_DP_OFF_2 TDD Control & Status
[23:0] TDD_TX_DP_OFF_2 RW 0x000000 The secondary pointer for TX_DP_OFF.

Linux IIO Driver

The linux driver defines an iio interface. The driver can be instantiated in the device tree as follows:

	axi_tdd_0: axi-tdd-0@9c460000 {
		compatible = "adi,axi-tdd-1.00";
		reg = <0x9c460000 0x10000>;
		clocks = <&zynqmp_clk PL0_REF>, <&hmc7044 6>;
		clock-names = "s_axi_aclk", "intf_clk";
	};
The driver needs to know which clock is driving the main clock input clk to calculate the required register values from the times provided to the iio attributes (T / clk_rate).

The resulting IIO device looks like this, where there is one channel per combination of rx, tx and primary, secondary. Keep in mind that these channels are only used to structure their attributes, and don't carry any information themselves.

	iio:device2: axi-core-tdd
		4 channels found:
			data1:  (output, WARN:iio_channel_get_type()=UNKNOWN)
			6 channel-specific attributes found:
				attr  0: dp_off_ms value: 0
				attr  1: dp_on_ms value: 0
				attr  2: off_ms value: 0
				attr  3: on_ms value: 0
				attr  4: vco_off_ms value: 0
				attr  5: vco_on_ms value: 0
			data1:  (input, WARN:iio_channel_get_type()=UNKNOWN)
			6 channel-specific attributes found:
				attr  0: dp_off_ms value: 0
				attr  1: dp_on_ms value: 0
				attr  2: off_ms value: 0
				attr  3: on_ms value: 0
				attr  4: vco_off_ms value: 0
				attr  5: vco_on_ms value: 0
			data0:  (output, WARN:iio_channel_get_type()=UNKNOWN)
			6 channel-specific attributes found:
				attr  0: dp_off_ms value: 0
				attr  1: dp_on_ms value: 0
				attr  2: off_ms value: 0
				attr  3: on_ms value: 0
				attr  4: vco_off_ms value: 0
				attr  5: vco_on_ms value: 0
			data0:  (input, WARN:iio_channel_get_type()=UNKNOWN)
			6 channel-specific attributes found:
				attr  0: dp_off_ms value: 0
				attr  1: dp_on_ms value: 0
				attr  2: off_ms value: 0
				attr  3: on_ms value: 0
				attr  4: vco_off_ms value: 0
				attr  5: vco_on_ms value: 0
		10 device-specific attributes found:
				attr  0: burst_count value: 0
				attr  1: counter_int value: 0
				attr  2: dma_gateing_mode value: rx_tx
				attr  3: dma_gateing_mode_available value: rx_tx rx_only tx_only none
				attr  4: en value: 0
				attr  5: en_mode value: rx_tx
				attr  6: en_mode_available value: rx_tx rx_only tx_only
				attr  7: frame_length_ms value: 0
				attr  8: secondary value: 0
				attr  9: sync_terminal_type value: 0
		1 debug attributes found:
				debug attr  0: direct_reg_access value: 0x10061
		No trigger on this device
resources/fpga/docs/axi_tdd.1633779880.txt.gz · Last modified: 09 Oct 2021 13:44 by Adrian Costina