Skip to content

ada4355: Add idelay calibration functionality #1690

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 11 additions & 7 deletions docs/library/axi_ada4355/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -122,19 +122,23 @@ base address to the registers relative address.
- 0x0000
- BASE
- See the `Base <#hdl-regmap-COMMON>`__ table for more details.
* - 0x0000
- 0x0000
- RX COMMON
* - 0x0010
- 0x0040
- ADC COMMON
- See the `ADC Common <#hdl-regmap-ADC_COMMON>`__ table for more details.
* - 0x0000
- 0x0000
- RX CHANNELS
* - 0x0100
- 0x0400
- ADC CHANNELS
- See the `ADC Channel <#hdl-regmap-ADC_CHANNEL>`__ table for more details.
* - 0x0000
* - 0x0200
- 0x0800
- IO_DELAY_CNTRL
- See the `I/O Delay Control <#hdl-regmap-IO_DELAY_CNTRL>`__ table for more details.

.. hdl-regmap::
:name: AXI_ADA4355
:no-type-info:

.. hdl-regmap::
:name: COMMON
:no-type-info:
Expand Down
37 changes: 37 additions & 0 deletions docs/regmap/adi_regmap_axi_ada4355.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
TITLE
AXI_ADA4355 (axi_ada4355_adc)
AXI_ADA4355
ENDTITLE

############################################################################################
############################################################################################

REG
0x0032
ENABLE_ERROR
ENABLE ERROR MASK
ENDREG

FIELD
[2] 0x00000000
ENABLE_FRAME_ERROR
RW
If set, enable frame error
ENDFIELD

FIELD
[1] 0x00000000
ENABLE_LANE_1_ERROR
RW
If set, enable lane 1 error
ENDFIELD

FIELD
[0] 0x00000000
ENABLE_LANE_0_ERROR
RW
If set, enable lane 0 error
ENDFIELD

############################################################################################
############################################################################################
3 changes: 3 additions & 0 deletions library/axi_ada4355/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ GENERIC_DEPS += ../common/up_xfer_cntrl.v
GENERIC_DEPS += ../common/up_xfer_status.v
GENERIC_DEPS += axi_ada4355.v
GENERIC_DEPS += axi_ada4355_if.v
GENERIC_DEPS += axi_ada4355_regmap.v

XILINX_DEPS += axi_ada4355_constr.ttcl
XILINX_DEPS += ../util_cdc/sync_bits.v
XILINX_DEPS += ../xilinx/common/ad_data_clk.v
XILINX_DEPS += ../xilinx/common/ad_data_in.v
XILINX_DEPS += ../xilinx/common/ad_dcfilter.v
Expand Down
44 changes: 35 additions & 9 deletions library/axi_ada4355/axi_ada4355.v
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ module axi_ada4355 #(

input delay_clk,

// error monitoring

output up_adc_pn_err,

// AXI interface

input s_axi_aclk,
Expand Down Expand Up @@ -102,6 +106,10 @@ module axi_ada4355 #(
wire adc_clk_s;
wire adc_rst_s;
wire delay_rst;
wire adc_pn_err_s;
wire up_adc_pn_err_s;
wire up_adc_pn_oos_s;
wire [ 2:0] enable_error_s;

wire up_rstn;
wire up_clk;
Expand All @@ -111,9 +119,9 @@ module axi_ada4355 #(
wire up_wr_s;
wire [13:0] up_addr_s;
wire [31:0] up_wdata_s;
wire [31:0] up_rdata_s [0:2];
wire up_rack_s [0:2];
wire up_wack_s [0:2];
wire [31:0] up_rdata_s [0:3];
wire up_rack_s [0:3];
wire up_wack_s [0:3];

reg [31:0] up_rdata_r;
reg up_rack_r;
Expand All @@ -127,12 +135,13 @@ module axi_ada4355 #(
assign adc_clk = adc_clk_s;
assign up_clk = s_axi_aclk;
assign up_rstn = s_axi_aresetn;
assign up_adc_pn_err = up_adc_pn_err_s;

always @(*) begin
up_rdata_r = 'h00;
up_rack_r = 'h00;
up_wack_r = 'h00;
for(j = 0; j <= 2; j=j+1) begin
for(j = 0; j <= 3; j=j+1) begin
up_rack_r = up_rack_r | up_rack_s[j];
up_wack_r = up_wack_r | up_wack_s[j];
up_rdata_r = up_rdata_r | up_rdata_s[j];
Expand Down Expand Up @@ -168,15 +177,15 @@ module axi_ada4355 #(
.adc_iqcor_coeff_2(),
.adc_pnseq_sel(),
.adc_data_sel(),
.adc_pn_err(1'b0),
.adc_pn_err(adc_pn_err_s),
.adc_pn_oos(1'b0),
.adc_or(),
.adc_read_data(),
.adc_status_header('b0),
.adc_crc_err('b0),
.up_adc_crc_err(),
.up_adc_pn_err(),
.up_adc_pn_oos(),
.up_adc_pn_err(up_adc_pn_err_s),
.up_adc_pn_oos(up_adc_pn_oos_s),
.up_adc_or(),
.up_usr_datatype_be(),
.up_usr_datatype_signed(),
Expand Down Expand Up @@ -224,8 +233,8 @@ module axi_ada4355 #(
.up_pps_status(1'b0),
.up_pps_irq_mask(),
.up_adc_ce(),
.up_status_pn_err(1'b0),
.up_status_pn_oos(1'b0),
.up_status_pn_err(up_adc_pn_err_s),
.up_status_pn_oos(up_adc_pn_oos_s),
.up_status_or(1'b0),
.up_drp_sel(),
.up_drp_wr(),
Expand Down Expand Up @@ -279,6 +288,8 @@ module axi_ada4355 #(
.adc_data(adc_data),
.adc_valid(adc_valid),
.aresetn(up_rstn),
.adc_pn_err(adc_pn_err_s),
.enable_error(enable_error_s),
.sync_n(sync_n));

// adc delay control
Expand All @@ -305,6 +316,21 @@ module axi_ada4355 #(
.up_rdata(up_rdata_s[2]),
.up_rack(up_rack_s[2]));

axi_ada4355_regmap i_regmap(
.up_rstn(up_rstn),
.up_clk(up_clk),
.up_wreq(up_wreq_s),
.up_waddr(up_waddr_s),
.up_wdata(up_wdata_s),
.up_wack(up_wack_s[3]),
.up_rreq(up_rreq_s),
.up_raddr(up_raddr_s),
.up_rdata(up_rdata_s[3]),
.up_rack(up_rack_s[3]),
.clk_div(adc_clk_s),
.enable_error_sync(enable_error_s),
.adc_rst(adc_rst_s));

// up bus interface

up_axi i_up_axi(
Expand Down
17 changes: 17 additions & 0 deletions library/axi_ada4355/axi_ada4355_constr.ttcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
###############################################################################
## Copyright (C) 2025 Analog Devices, Inc. All rights reserved.
# SPDX short identifier: ADIBSD
###############################################################################

<: set ComponentName [getComponentNameString] :>
<: setOutputDirectory "./" :>
<: setFileName [ttcl_add $ComponentName "_constr"] :>
<: setFileExtension ".xdc" :>
<: setFileProcessingOrder late :>

set_property ASYNC_REG TRUE \
[get_cells -quiet -hierarchical *cdc_sync_stage1_reg*] \
[get_cells -quiet -hierarchical *cdc_sync_stage2_reg*]

set_false_path -quiet \
-to [get_cells -quiet -hierarchical -filter {NAME =~ *i_enable_sync/cdc_sync_stage1_reg* && IS_SEQUENTIAL}]
75 changes: 56 additions & 19 deletions library/axi_ada4355/axi_ada4355_if.v
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,9 @@ module axi_ada4355_if #(

// Output data
output [15:0] adc_data,
output adc_valid
output adc_valid,
output adc_pn_err,
input [ 2:0] enable_error
);

// Use always DDR mode for SERDES, useful for SDR mode to adjust capture
Expand All @@ -86,6 +88,8 @@ module axi_ada4355_if #(
FRAME_SHIFTED = 3'h2,
RESET = 3'h3;
localparam [ 7:0] pattern_value = 8'hF0;
localparam [15:0] expected_pattern_lane_0 = 16'h5554;
localparam [15:0] expected_pattern_lane_1 = 16'hAAA8;

wire clk_in_s;
wire out_ibufmrce_clock;
Expand Down Expand Up @@ -120,6 +124,7 @@ module axi_ada4355_if #(
reg [ 1:0] serdes_valid = 2'b00;
reg [ 1:0] serdes_valid_d = 2'b00;
reg [ 2:0] shift_cnt = 3'd0;
reg [ 4:0] delay = 5'd0;
reg [15:0] serdes_data;
reg [15:0] serdes_data_d;
reg [ 7:0] serdes_frame;
Expand All @@ -130,6 +135,12 @@ module axi_ada4355_if #(
reg bufr_alignment;
reg bufr_alignment_bufr;
reg [ 2:0] state = 3'h0;
reg frame_err_r;
reg data_err_lane_0_r;
reg data_err_lane_1_r;
reg [15:0] lane_0_mask = 16'h5555;
reg [15:0] lane_1_mask = 16'hAAAA;
reg [15:0] test_pattern;

IBUFGDS i_clk_in_ibuf(
.I(dco_p),
Expand Down Expand Up @@ -275,38 +286,40 @@ module axi_ada4355_if #(
end

assign adc_clk = adc_clk_div;
assign adc_pn_err = ((data_err_lane_0_r & enable_error[0]) | (data_err_lane_1_r & enable_error[1]) |
(frame_err_r & enable_error[2]));

assign data_in_p = {d1a_p, d0a_p};
assign data_in_n = {d1a_n, d0a_n};

assign {data_0[0],data_1[0]} = data_s0; // f-e latest bit received
assign {data_0[1],data_1[1]} = data_s1; // r-e
assign {data_0[2],data_1[2]} = data_s2; // f-e
assign {data_0[3],data_1[3]} = data_s3; // r-e
assign {data_0[4],data_1[4]} = data_s4; // f-e
assign {data_0[5],data_1[5]} = data_s5; // r-e
assign {data_0[6],data_1[6]} = data_s6; // f-e
assign {data_0[7],data_1[7]} = data_s7; // r-e oldest bit received
assign {data_1[0],data_0[0]} = data_s0; // f-e latest bit received
assign {data_1[1],data_0[1]} = data_s1; // r-e
assign {data_1[2],data_0[2]} = data_s2; // f-e
assign {data_1[3],data_0[3]} = data_s3; // r-e
assign {data_1[4],data_0[4]} = data_s4; // f-e
assign {data_1[5],data_0[5]} = data_s5; // r-e
assign {data_1[6],data_0[6]} = data_s6; // f-e
assign {data_1[7],data_0[7]} = data_s7; // r-e oldest bit received

// For DDR dual lane interleave the two sedres outputs;

always @(posedge adc_clk_div) begin
serdes_data = {data_0[7],
data_1[7],
data_0[6],
serdes_data = {data_1[7],
data_0[7],
data_1[6],
data_0[5],
data_0[6],
data_1[5],
data_0[4],
data_0[5],
data_1[4],
data_0[3],
data_0[4],
data_1[3],
data_0[2],
data_0[3],
data_1[2],
data_0[1],
data_0[2],
data_1[1],
data_0[0],
data_1[0]};
data_0[1],
data_1[0],
data_0[0]};

serdes_frame = {frame_s7,
frame_s6,
Expand All @@ -325,6 +338,10 @@ module axi_ada4355_if #(
end
end

always @(posedge adc_clk_div) begin
test_pattern <= adc_data_shifted;
end

always @(posedge adc_clk_div) begin
if (serdes_reset_d) begin
state <= INIT;
Expand All @@ -337,10 +354,27 @@ module axi_ada4355_if #(
state <= CNT_UPDATE;
end else begin
frame_shifted <= {serdes_frame, serdes_frame_d} >> shift_cnt;
if (expected_pattern_lane_0 == (test_pattern & lane_0_mask)) begin
data_err_lane_0_r <= 1'b0;
end else begin
data_err_lane_0_r <= 1'b1;
end
if (expected_pattern_lane_1 == (test_pattern & lane_1_mask)) begin
data_err_lane_1_r <= 1'b0;
end else begin
data_err_lane_1_r <= 1'b1;
end
state <= INIT;
end
end
CNT_UPDATE : begin
if (shift_cnt == 3'b111) begin
frame_err_r <= 1'b1;
state <= RESET;
end
else begin
frame_err_r <= 1'b0;
end
shift_cnt <= shift_cnt + 1;
state <= FRAME_SHIFTED;
end
Expand All @@ -351,6 +385,9 @@ module axi_ada4355_if #(
RESET : begin
shift_cnt <= 0;
state <= INIT;
frame_err_r <= 1'b0;
data_err_lane_0_r <= 1'b0;
data_err_lane_1_r <= 1'b0;
end
default :
state <= INIT;
Expand Down
4 changes: 4 additions & 0 deletions library/axi_ada4355/axi_ada4355_ip.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,18 @@ adi_ip_files axi_ada4355 [list \
"$ad_hdl_dir/library/common/up_adc_common.v" \
"$ad_hdl_dir/library/common/up_adc_channel.v" \
"$ad_hdl_dir/library/common/up_axi.v" \
"$ad_hdl_dir/library/util_cdc/sync_bits.v" \
"$ad_hdl_dir/library/xilinx/common/up_xfer_cntrl_constr.xdc" \
"$ad_hdl_dir/library/xilinx/common/ad_rst_constr.xdc" \
"$ad_hdl_dir/library/xilinx/common/up_xfer_status_constr.xdc" \
"$ad_hdl_dir/library/xilinx/common/up_clock_mon_constr.xdc" \
"axi_ada4355_constr.ttcl" \
"axi_ada4355_regmap.v" \
"axi_ada4355_if.v" \
"axi_ada4355.v" ]

adi_ip_properties axi_ada4355
adi_ip_ttcl axi_ada4355 "axi_ada4355_constr.ttcl"

adi_ip_add_core_dependencies [list \
analog.com:$VIVADO_IP_LIBRARY:util_cdc:1.0 \
Expand Down
Loading
Loading