AXI ADF4030
The AXI ADF4030 Controller IP core provides AXI-Lite control of the ADF4030 fractional-N PLL and its associated bidirectional BSYNC signal. It generates up to 8 independently phase-adjusted trigger outputs, each synchronized to the BSYNC clock recovered from the ADF4030 device. The BSYNC signal can be either received from the ADF4030 (as a timing reference) or driven by the FPGA toward an external device, selectable at runtime.
Features
Bidirectional differential BSYNC interface (
IOBUFDS_DCIEN) with runtime direction controlBSYNC receiver with automatic period calibration (no external configuration required)
Internal BSYNC regeneration after calibration, with optional suppression
Optional BSYNC misalignment detection with latched error flag
Up to 8 independently phase-configurable trigger output channels
Per-channel enable and phase offset, adjustable while running
Optional trigger stretcher: aligns narrow trigger pulses to the next BSYNC edge before distributing to channels
Dual trigger source: external pin (synchronized) or software-generated
Full debug override: force all channel outputs to a known state via register
AXI4-Lite slave interface with 10-bit address space
All cross-clock-domain paths covered by explicit
set_false_pathconstraints
Files
Name |
Description |
|---|---|
Top-level module; wires all submodules and the IOBUFDS primitive. |
|
AXI register map with all CDC synchronizers. |
|
FSM that captures, calibrates, and regenerates the BSYNC signal. |
|
Per-channel FSM that phase-delays the trigger output relative to BSYNC. |
|
Stretches a narrow trigger pulse to the next BSYNC rising edge. |
|
Vivado IP-integrator packaging script. |
|
Template XDC with timing constraints for all CDC paths. |
Configuration Parameters
Name |
Description |
Default Value |
Choices/Range |
|---|---|---|---|
ID |
Instance identification number. Readable from the PERIPHERAL_ID register. |
0 |
|
FPGA_FAMILY |
Selects the |
0 |
Unknown (0), artix (1), kintex (2), virtex (3), zynq (4), versalprime (5), versalaicore (6), versalpremium (7) |
CHANNEL_COUNT |
Number of active trigger output channels. Range: 1 to 8. |
1 |
From 1 to 8. |
TRIGGER_STRETCH |
When set to 1, inserts a |
0 |
From 0 to 1. |
Interface
Physical Port |
Logical Port |
Direction |
Dependency |
|---|---|---|---|
s_axi_awaddr |
AWADDR |
in [9:0] |
|
s_axi_awprot |
AWPROT |
in [2:0] |
|
s_axi_awvalid |
AWVALID |
in |
|
s_axi_awready |
AWREADY |
out |
|
s_axi_wdata |
WDATA |
in [31:0] |
|
s_axi_wstrb |
WSTRB |
in [3:0] |
|
s_axi_wvalid |
WVALID |
in |
|
s_axi_wready |
WREADY |
out |
|
s_axi_bresp |
BRESP |
out [1:0] |
|
s_axi_bvalid |
BVALID |
out |
|
s_axi_bready |
BREADY |
in |
|
s_axi_araddr |
ARADDR |
in [9:0] |
|
s_axi_arprot |
ARPROT |
in [2:0] |
|
s_axi_arvalid |
ARVALID |
in |
|
s_axi_arready |
ARREADY |
out |
|
s_axi_rdata |
RDATA |
out [31:0] |
|
s_axi_rresp |
RRESP |
out [1:0] |
|
s_axi_rvalid |
RVALID |
out |
|
s_axi_rready |
RREADY |
in |
Physical Port |
Logical Port |
Direction |
Dependency |
|---|---|---|---|
s_axi_aclk |
CLK |
in |
Physical Port |
Logical Port |
Direction |
Dependency |
|---|---|---|---|
s_axi_aresetn |
RST |
in |
Physical Port |
Logical Port |
Direction |
Dependency |
|---|---|---|---|
device_clk |
CLK |
in |
Physical Port |
Logical Port |
Direction |
Dependency |
|---|---|---|---|
rstn |
RST |
Physical Port |
Direction |
Dependency |
Description |
|---|---|---|---|
bsync_p |
inout |
Positive leg of the differential BSYNC signal. Direction controlled at runtime by the DIRECTION control register bit. |
|
bsync_n |
inout |
Negative leg of the differential BSYNC signal. |
|
trigger |
in |
External trigger input. Asynchronous; synchronized to |
|
sysref |
out |
SYSREF output. Wired directly to the received |
|
trig_channel |
out [0:0] |
Phase-aligned trigger outputs, one per enabled channel. Width equals |
|
trig_request_out |
out |
Pre-channel trigger signal, after the optional stretcher. Asserted when the active trigger source fires, before per-channel phase adjustment. |
Register Map
The register map occupies a single 10-bit AXI4-Lite address space. All
registers are 32-bit wide and word-addressed; bits [1:0] of the AXI byte
address are ignored by the decoder. The TRIG_CHANNEL registers
(0x07–0x0E) are always present regardless of CHANNEL_COUNT;
registers beyond the instantiated channel count read as zero and writes to
their TRIG_PHASE fields are silently ignored. The TRIG_CHANNEL_EN
field in the CONTROL register also silently ignores writes to bits above
CHANNEL_COUNT-1.
Theory of Operation
BSYNC Signal Handling
The bsync_p / bsync_n differential pair can either be received from the
ADF4030 or driven out toward an external device, selected by the DIRECTION bit
in the CONTROL register (default: receive). The IOBUFDS_DCIEN Xilinx
primitive is used for the bidirectional I/O; its IBUFDISABLE input gates
the receiver when the FPGA is in drive mode.
When receiving (DIRECTION=1), the bsync_generator module operates as
follows:
IDLE — waits for the first rising edge on the
bsync_p/ninput. A 3-stage pipeline on the registered signal reduces the probability of metastability propagating into the rest of the design.BSYNC_EDGE — waits for a confirmed stable rising edge.
CALIB — measures the BSYNC half-period by counting
device_clkcycles while the signal is high, recording the result inratio_counter. Once calibration completes,BSYNC_READYis asserted and the measured half-period is visible in theBSYNC_RATIOdebug field.BSYNC_GEN — regenerates a local copy of the BSYNC clock using the calibrated ratio. The regenerated signal is driven back out through the
IOBUFDS_DCIENwhen DIRECTION=0 andDISABLE_INTERNAL_BSYNC=0.BSYNC_ALIGNMENT_ERROR — entered (and latched) if
ENABLE_MISALIGN_CHECK=1 and a subsequent BSYNC edge arrives at a different phase than the reference. ASW_RESETis required to recover.
The bsync_event pulse is generated on every rising edge of the BSYNC signal,
regardless of FSM state. Trigger channels use this pulse to synchronize their
phase counting.
Trigger Path
The active trigger source is selected by the SELECT_TRIG bit:
SELECT_TRIG=0 — a software trigger is issued by writing 1 to the MANUAL_TRIGGER register. The pulse crosses to
device_clkviasync_event.SELECT_TRIG=1 — the external
triggerpin is used, synchronized todevice_clkby a two-flop synchronizer (ad_rst).
When TRIGGER_STRETCH=1, the active source first passes through the
trigger_bsync_stretcher, which uses a set/reset latch to hold the trigger
asserted until the next BSYNC rising edge acknowledges it. This ensures channels
never miss a narrow pulse.
When ENABLE_DEBUG_TRIG=1, both the trigger source and the stretcher are
bypassed. All enabled channel outputs are driven with the value of the
DEBUG_TRIG bit.
Per-Channel Phase Adjustment
Each trigger_channel instance runs a 4-state FSM on device_clk:
IDLE — waits until the channel is enabled (
ch_en=1) andBSYNC_READY=1.TRIG_EDGE — waits for both a trigger event and a
bsync_eventto coincide in the same clock cycle.PHASE_READ — latches the current phase target from the register map (CDC-synchronised).
TRIG_ADJUST — counts
trig_phasecycles of delay, then assertstrig_outfor exactlybsync_ratiocycles, producing one trigger pulse per bsync_ratio-aligned window.
The effective delay from the trigger+BSYNC coincidence to the output rising edge is:
A TRIG_PHASE value of 0 places the output pulse as late as possible within
the current BSYNC window. Increasing TRIG_PHASE advances the pulse earlier.
The TRIG_STATE field in each channel register reflects the current FSM state
and is useful for diagnosing whether a channel is waiting for BSYNC, waiting for
a trigger, or actively adjusting its output.
Clock Domain Crossing
The IP operates across two asynchronous clock domains: s_axi_aclk (register
map) and device_clk (functional logic). All paths are handled in
axi_adf4030_regmap.sv using ADI CDC primitives:
Signal(s) |
Primitive |
Direction |
|---|---|---|
Control bits (direction, select_trig, sw_reset, disable_internal_bsync, enable_misalign_check, enable_debug_trig, debug_trig) |
|
AXI → device_clk |
|
|
AXI → device_clk |
|
|
AXI → device_clk |
|
|
AXI → device_clk |
|
|
device_clk → AXI |
|
|
device_clk → AXI |
|
|
device_clk → AXI |
All corresponding set_false_path constraints are generated at build time
from the axi_adf4030_constr.ttcl template.
Software Considerations
Recommended bring-up sequence:
Set DIRECTION=1 (receive) in the CONTROL register.
Wait for
BSYNC_READY=1 in the DEBUG register. This confirms that the BSYNC period has been measured and the regenerated clock is stable.Configure per-channel
TRIG_PHASEvalues in the TRIG_CHANNEL registers. Phase registers are only writable while the corresponding channel enable bit is set (TRIG_CHANNEL_EN[n]=1).Set the desired trigger source via
SELECT_TRIG.Enable individual channels by setting bits in
TRIG_CHANNEL_EN.Issue triggers via the external pin or the MANUAL_TRIGGER register.
To recover from a BSYNC_ALIGNMENT_ERROR, write 1 to the SW_RESET bit. This
restarts the bsync_generator FSM from IDLE without resetting the AXI
interface or the phase register values.
Known Limitations
The IP is Xilinx-only: the bidirectional BSYNC uses
IOBUFDS_DCIEN, which is a Xilinx-specific primitive. No Intel/Altera variant is provided.The maximum supported
CHANNEL_COUNTis 8. The TRIG_CHANNEL register array always occupies 8 entries (addresses 0x07–0x0E); registers beyondCHANNEL_COUNTread as zero.BSYNC_RATIOis a 16-bit field. The maximum measurable BSYNC half-period is 65535device_clkcycles.The
trigger_bsync_stretcheruses an asynchronous set/reset latch on the trigger signal edge. The bsync_stretcher module should only be used when setup/hold ontriggerrelative toexternal_bsynccannot be guaranteed.
References
HDL IP core at library/axi_adf4030
ADF4030 product page