AN 901: Implementing Analog-to-Digital Converter Dual Link Design with Intel Agilex® 7 FPGA E-Tile JESD204C RX IP

ID 683537
Date 3/26/2023
Public
Document Table of Contents

1.3.1.5. Editing Simulation Testbench for Synchronized ADC to Intel Agilex® 7 Dual Link

The simulation testbench, tb_top.sv, is located in the simulation/models folder. Follow these steps to edit the testbench.
  1. Open the testbench (tb_top.sv) in a text editor.
  2. Add the LINK parameter at the localparam declaration section. Example:
    localparam LINK = 2;     // Number of IP core in the dual link design
  3. In the instantiation of the TX and RX JESD204C example design modules, include the LINK parameter. Example:
    intel_j204c_ed_rx #(
               .LINK           (LINK), 
    intel_j204c_ed_tx #(
               .LINK           (LINK), 
    
  4. Add the TX_REG and RX_REG text macros for each additional link. The additional IP instance in this example is intel_jesd204c_1 and the text macro is TX_REG_1 and RX_REG_1. Example:
    `define TX_REG_1  tb_top.u_intel_j204c_ed_tx.u_j204c_tx_ss.j204c_tx_ip.intel_jesd204c_1.intel_jesd204c.j204c_tx_base_inst.j204c_tx_csr_inst.j204c_tx_regmap_inst
    `define RX_REG_1 tb_top.u_intel_j204c_ed_rx.u_j204c_rx_ss.j204c_rx_ip.intel_jesd204c_1.intel_jesd204c.j204c_rx_base_inst.j204c_rx_csr_inst.j204c_rx_regmap_inst
    
  5. Comment out or delete the sysref_out port at the instantiation of the intel_j204c_ed_rx and intel_j204c_ed_tx subsystems.
    // Example in  Verilog
           //.sysref_out                 (sysref),
  6. Change the dimension and assignment of the following wires and registers:
    • reg [LINK-1:0] tx_link_error_reg = {LINK{1’b0}};
    • reg [LINK-1:0] rx_link_error_reg = {LINK{1’b0}};
    • reg [LINK-1:0] data_error_reg = {LINK{1’b0}};
    • reg [LINK-1:0] cmd_data_error_reg = {LINK{1’b0}};
    • wire [LINK*L-1:0] tx_serial_data;
    • wire [LINK*L-1:0] tx_serial_data_n;
    • wire [LINK*L-1:0] rx_serial_data;
    • wire [LINK*L-1:0] rx_serial_data_n;
    • wire [LINK-1:0] data_valid;
    • wire [LINK-1:0] data_error;
    • wire [LINK-1:0] tx_link_error;
    • wire [LINK-1:0] rx_link_error;
    • wire [LINK-1:0] rx_avst_ready;
    • wire [LINK-1:0][(TOTAL_SAMPLE*N)-1:0] rx_avst_data;
    • wire [LINK-1:0] cmd_data_valid;
    • wire [LINK-1:0] cmd_data_error;
    • wire [LINK-1:0][L*18-1:0] cmd_data;
    • wire [LINK-1:0] tx_err_sysref_lemc_err;
    • wire [LINK-1:0] tx_err_dll_data_invalid_err;
    • wire [LINK-1:0] tx_err_frame_data_invalid_err;
    • wire [LINK-1:0] tx_err_cmd_invalid_err;
    • wire [LINK-1:0] tx_err_tx_ready_err;
    • wire [LINK-1:0] tx_err_pcfifo_full_err;
    • wire [LINK-1:0] tx_err_tx_gb_underflow_err;
    • wire [LINK-1:0] tx_err_tx_gb_overflow_err;
    • wire [LINK-1:0] rx_err_sysref_lemc_err;
    • wire [LINK-1:0] rx_err_dll_data_ready_err;
    • wire [LINK-1:0] rx_err_frame_data_ready_err;
    • wire [LINK-1:0] rx_err_cmd_ready_err;
    • wire [LINK-1:0] rx_err_cdr_locked_err;
    • wire [LINK-1:0] rx_err_pcfifo_full_err;
    • wire [LINK-1:0] rx_err_pcfifo_empty_err;
    • wire [LINK-1:0] rx_err_lane_deskew_err;
    • wire [LINK-1:0] rx_err_invalid_sync_header;
    • wire [LINK-1:0] rx_err_invalid_eomb;
    • wire [LINK-1:0] rx_err_invalid_eoemb;
    • wire [LINK-1:0] rx_err_cmd_par_err;
    • wire [LINK-1:0] rx_err_crc_err;
    • wire [LINK-1:0] rx_err_rx_gb_underflow_err;
    • wire [LINK-1:0] rx_err_rx_gb_overflow_err;
    • wire [LINK-1:0] rx_err_sh_unlock_err;
    • wire [LINK-1:0] rx_err_emb_unlock_err;
    • wire [LINK-1:0] rx_err_eb_full_err;
    • wire [LINK-1:0] rx_err_ecc_corrected_err;
    • wire [LINK-1:0] rx_err_ecc_fatal_err;
  7. Scale the dimensions of the tx_ready, rx_ready, and rx_avst_ready assignments according to the number of links. Example for LINK = 2:
    //Scale the dimension to [number of link-1:0]
    assign tx_ready = &u_intel_j204c_ed_tx.all_tx_ready[1:0]; 
    assign rx_ready = &u_intel_j204c_ed_rx.all_rx_ready[1:0];
    assign rx_avst_ready = u_intel_j204c_ed_rx.rx_avst_ready[1:0];  
    
  8. Add the LINK parameter to the assignment statements for rx_serial_data and rx_serial_data_n as shown below:
    //Internal Loopback
    assign rx_serial_data = INTERNAL_SERIAL_LB ? {LINK*L{1'b0}} : tx_serial_data;      
    assign rx_serial_data_n = INTERNAL_SERIAL_LB ? {LINK*L{1'b0}} : tx_serial_data_n;
    
  9. Add an index to each assignment of the TX and RX IP error. Assign the errors for each link according to the TX and RX IP text macro. Example:
    //TX Error Link 0
    assign tx_err_sysref_lemc_err[0] = `TX_REG.tx_err_sysref_lemc_err;
    //TX Error Link 1
    assign tx_err_sysref_lemc_err[1] = `TX_REG_1.tx_err_sysref_lemc_err;
    //RX Error Link 0
    assign rx_err_sysref_lemc_err[0] = `RX_REG.rx_err_sysref_lemc_err;
    //RX Error Link 1
    assign rx_err_sysref_lemc_err[1] = `RX_REG_1.rx_err_sysref_lemc_err;
    
  10. Create the generation loops for the data and link error signals:
    genvar i;
    
       // Pass/Fail Mechanism
       //
        generate
        for (i=0; i<LINK; i=i+1) begin: LINK_ERROR
          // Make sure interrupts do not assert
          always @(posedge mgmt_clk or negedge tx_rst_n) begin
             if(!tx_rst_n) 
                tx_link_error_reg[i] <= 1'b0;
             else if (tx_link_error[i] !== 0)
                tx_link_error_reg[i] <= 1'b1;
             else
                tx_link_error_reg[i] <= tx_link_error_reg[i]; 
          end
    
          always @(posedge mgmt_clk or negedge rx_rst_n) begin
             if(!rx_rst_n)
                rx_link_error_reg[i] <= 1'b0;
             else if (rx_link_error[i] !== 0)
                rx_link_error_reg[i] <= 1'b1;
             else
                rx_link_error_reg[i] <= rx_link_error_reg[i];
          end
    
          always @ (posedge data_error or negedge rx_rst_n) begin
             if (!rx_rst_n)
                data_error_reg[i] <= 1'b0;
             else if (data_valid[i] === 1'b1)
                data_error_reg[i] <= 1'b1;
          end
    
          always @ (posedge cmd_data_error or negedge rx_rst_n) begin
             if (!rx_rst_n)
                cmd_data_error_reg[i] <= 1'b0;
             else if (cmd_data_valid[i] === 1'b1)
                cmd_data_error_reg[i] <= 1'b1;
          end
       end
       endgenerate
    
  11. To monitor the combined simulation results of the dual link, modify the test_passed assignment statement so that, if the IP in any of the links has an interrupt or error, the simulation reports failure:
    assign test_passed = (|rx_avst_data!==0) & (|data_error_reg===1'b0) & (|cmd_data_error_reg===1'b0) & (|tx_link_error_reg===1'b0) & (|rx_link_error_reg===1'b0) & (sh_lock_out===1'b1) & (emb_lock_out===1'b1);
  12. Edit the criteria for displaying the link error message for data_error_reg, cmd_data_error_reg, tx_link_error_reg, and rx_link_error_reg signals so that, if the IP in any of the links has an interrupt, the simulation reports failure. Example:
    wait(&data_valid===1'b1);        //AND the valid signals             
    wait(&cmd_data_valid===1'b1);	    //AND the valid signals             
        
    if (&data_valid===1'b1) begin           //AND the valid signals
       if (|data_error_reg===1'b1) begin    //OR the error signals
         $display("Pattern Checker(s): Data error(s) found!");
       end else begin
          $display("Pattern Checker(s): OK!");
       end       
    end else begin
       if (|rx_avst_data===0) begin  //OR the valid signals  
         $display("Pattern Checker(s): No valid data found!");
       end else begin
          if (|data_error_reg===1'b1) begin  //OR the error signals
            $display("Pattern Checker(s): Data error(s) found!");
          end else begin
            $display("Pattern Checker(s): OK!");
          end       
       end
    end
    
    if (&cmd_data_valid===1'b1) begin            //AND the valid signals
       if (|cmd_data_error_reg===1'b1) begin     //OR the error signals
         $display("Command Channel Pattern Checker(s): Data error(s) found!");
       end else begin
         $display("Command Channel Pattern Checker(s): OK!");
       end       
    end else begin
       if (|cmd_data===0) begin                  //OR the valid signals
         $display("Command Channel Pattern Checker(s): No valid data found!");
       end else begin
          if (|cmd_data_error_reg===1'b1) begin  //OR the error signals
            $display("Command Channel Pattern Checker(s): Data error(s) found!");
          end else begin
            $display("Command Channel Pattern Checker(s): OK!");
          end       
       end
    end 
    
    if (|tx_link_error_reg===1'b1) begin  //OR the error signals
       $display("JESD204C Tx Core(s): Tx link error(s) found!");
    end else begin
       $display("JESD204C Tx Core(s): OK!");
    end
                 
    if (|rx_link_error_reg===1'b1) begin  //OR the error signals
       $display("JESD204C Rx Core(s): Rx link error(s) found!");
    end else begin
       $display("JESD204C Rx Core(s): OK!");
    end