AnsweredAssumed Answered

Custom HDL code integration with AD HDL FW

Question asked by nikbartz on Apr 6, 2017
Latest reply on Apr 24, 2017 by sauka

Hello engineers,

we are using the FMCOMMS3 board with the Xilinx ZC706 board to design an FPGA-based LTE PHY-layer  (DL only transmitter) and we want to integrate our custom HDL code with the AD HDL firmware (hdl_2016_r1, Linux OS) without interfering with the rest of the preexisting functionality (e.g., generating CW tones, playback data from waveforms) and in particular with the calibration routines. We use an external clock source (40 MHz, 5 dBm) having previously removed the on-board crystal and populated C113 with a 100nF capacitor. We are using the 1.4, 5, 10 and 20 MHz LTE profiles to configure the AD9361 from the IIO application.


We have introduced the following code in the axi_ad9361_tx.v file

  always @(posedge dac_clk) begin
    // inject our data valid signal
    if (cc_reset == 1'b1) begin // cc_reset is an input port that comes from an instantiated VIO core in our HDL design
      dac_valid <= cc_valid_tx; // cc_valid_tx is the data valid at the output of our HDL code (input port herein)
      dma_dovf <= 1'd0; //connected to up_dac_common
      dma_dunf <= 1'd0; //connected to up_dac_common
    end else begin
      // original fw
      dac_valid <= (dac_rate_cnt == 8'd0) ? 1'b1 : 1'b0;
      dac_valid_i0 <= dac_valid;
      dac_valid_q0 <= dac_valid;
      dac_valid_i1 <= dac_valid & ~dac_r1_mode;
      dac_valid_q1 <= dac_valid & ~dac_r1_mode;
      dma_dovf <= dac_dovf;
      dma_dunf <= dac_dunf;
    // Mux DMA data with our data
  always @(posedge dac_clk) begin
    mux_ctrl <= cc_reset;
    case (mux_ctrl)
      1'b0: our_data_plus_dma_data_muxed <= {dac_data_q1, dac_data_i1, dac_data_q0, dac_data_i0};
      1'b1: our_data_plus_dma_data_muxed <= {16'h0, 16'h0, cc_data_q1, 4'b0000, cc_data_i1, 4'b0000};
      default: our_data_plus_dma_data_muxed <= 64'h0;


and also we have introduced the following code in the axi_ad9361_tx_channel.v file

  always @(posedge dac_clk) begin
    mux_ctrl <= cc_reset; // cc_reset is an input port that comes from an instantiated VIO core in our HDL design
        if (mux_ctrl == 1'b1) begin
        dac_data_out <= dma_data[15:4];
    end else begin
      case (dac_data_sel_s)
        4'h9: dac_data_out <= dac_pn_data;
        4'h8: dac_data_out <= adc_data;
        4'h3: dac_data_out <= 12'd0;
        4'h2: dac_data_out <= dma_data[15:4];
        4'h1: dac_data_out <= dac_pat_data[15:4];
        default: dac_data_out <= dac_dds_data[15:4];


The idea is that when our logic is on reset then the DMA channel can be used as usual e.g., to playback a waveform from the IIO application. When we deassert our reset we pass our data in the DMA channel.

We have the following three questions:

  • Is this an orthodox way to integrate our HDL logic?
  • Are we missing or making something wrong potentially resulting in issues related with calibration routines?
  • We are using the default device tree; do we need to apply any changes related to clock sources, calibration, digital tuning etc?

Thank you very much in advance.

Kind regards,