This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

ADS6445EVM and DE4 communication bit errors

Other Parts Discussed in Thread: HSMC-ADC-BRIDGE, ADS6445

Hello,

I am using an ADS6445 EVM board connected to a Terasic DE4 FPGA board. The connection is through the HSMC-ADC-BRIDGE REV C. The ADC 125 MHz reference clock is generated using a CDCE6005 EVM board.

The ADC samples at 125 MSPS and communicates the digital data using 7 times serialization so the bit rate is 875 MHz. The data clock is 437.5 MHz. I am powering the EVM board using a 3.3V regulator.

In the FPGA I am using the ALTLVDS_RX megafunction to deserialize the data. This is fed the data clock and generates a core clock signal at 125 MHz. This core clock is used to clock the digital logic.

I am sending the digital data to an on-chip RAM which I can easily read using Altera's In-system memory content editor.

To test my setup, I put a 1 MHz sine signal into the ADC and plotted the data in Matlab. This data is shown in the figure. I am certain those spikes are caused by bit errors because their offset from the sine curve is almost always a power of two.

Does anyone have any suggestions as to how to get this thing working? I need this data to be reliable otherwise my project will be put under severe limitations. Thank you!


My timing constraints are as follows:
=======================================================================================
# Clocks from ADC
create_clock -name rx_data_clk_a -period 2.285714 -waveform {0 1.142857} [get_ports {a_CLKIN_p2}]
# Virtual clocks with waveform edges at the data edges
create_clock -name adc_launch_clk_a -period 2.285714 -waveform {0.571429 1.714286}
create_clock -name adc_launch_clk_a -period 2.285714 -waveform {0.571429 1.714286}
derive_pll_clocks
derive_clock_uncertainty
set_input_delay -clock { adc_launch_clk_a } -max 0.35   [get_ports {a_RX_p[*]*}]
set_input_delay -clock { adc_launch_clk_a } -min -0.35  [get_ports {a_RX_p[*]*}]
set_input_delay -clock { adc_launch_clk_a } -max 0.35   [get_ports {a_RX_p[*]*}] -clock_fall -add_delay
set_input_delay -clock { adc_launch_clk_a } -min -0.35  [get_ports {a_RX_p[*]*}] -clock_fall -add_delay
=======================================================================================


My Verilog code looks like the following:
=======================================================================================
/*********************************
******* PULL DATA FROM ADC *******
**********************************/

///////////////// RECIEVE /////////////////

// Define rx connections
wire                rx_core_clk_a;
wire                frame_clk_a;
wire                rx_data_clk_a;
wire    [7:0]            rx_in_a;
wire                rx_locked_a;

// Assign rx connections
assign            frame_clk_a = a_RX_p[16];
assign            rx_data_clk_a = a_CLKIN_p2;
assign            rx_in_a = a_RX_p[11:4];

deserialize    deserialize_inst (
    .rx_in ( {frame_clk_a, rx_in_a} ),
    .rx_inclock ( rx_data_clk_a ),
    .rx_locked ( rx_locked_a ),
    .rx_out ( rx_out_a ),
    .rx_outclock ( rx_core_clk_a )
);


/////////////////////////////////////////////////
////////////// PUSH DATA TO MEMORY //////////////
/////////////////////////////////////////////////


//////////// CREATE ADDRESS COUNTER ////////////////

reg    [11:0]        cnt;
wire                inc_cnt;
always_ff @(posedge rx_core_clk_a, negedge BUTTON[1]) begin
    if(!BUTTON[1])
        cnt <= 0;
    else if(inc_cnt)
        cnt <= cnt + 1;
    else
        cnt <= cnt;
end

assign inc_cnt = (cnt != 12'h0fff);


////////// INSTANTIATE RAM MEGAFUNCTION ///////////

// declare signals
wire    [11:0]    address;
wire    [255:0]    write_data;
wire                rden;
wire                wren;
wire    [255:0]    read_data;

// assign signals
assign address = cnt;
assign rden = 1'b0;
assign wren = inc_cnt; //1'b1;

ram    ram_inst (
    .address ( address ),
    .clock ( rx_core_clk_a ),
    .data ( {rx_locked_a, rx_out_a } ),
    .rden ( rden ),
    .wren ( wren ),
    .q ( read_data )
);
=======================================================================================

  • We fixed it. The issue was that we needed to enable differential termination on the LVDS input pins. This is done in the Quartus Assignment editor. (We thought setting it to LVDS did this termination but the termination is a separate setting)