Post Go back to editing

Square wave output using fmcdaq2

Dear EngineerZone community


Please support.

I am currently creating a communication system.
The concept is to generate an information signal with vc707 and output it as a Square wave from the DAC (ad 9144) of fmcdaq2. Then, the output Square wave is input to the modulator and communication is carried out.

Before that, I am trying to output a Square wave of 1 kHz (offset 0V) from DAC (AD9144) of fmcdaq2.
How can I do it?

Can you create a design as per the user guide and store a Square wave in the buffer?

I can use both Linux / no-OS.

Yuta

Parents
  • Hi,

    I'm confused, ad9144 is a high speed dac (1GSPS), why do you want it to output a squarewave of 1KHz?
    The daq2 board has some filters on the output, you will have to change those to be able to transmit a sqare wave.

    Take a look at https://ez.analog.com/fpga/f/q-a/81027/daq2-kcu105-send-data-to-dac


    Are you familiar with our RF designs? If not, it may be of interest to you.

    www.analog.com/en/products/adrv9008-2.html

    www.analog.com/.../ad9361.html
    wiki.analog.com/.../adrv936x_rfsom

    Andrei

  • Thank you,Andrei

    I am sorry for confusing you.I wanted to generate a square wave of 1 kHz because the modulator used operates by inputting a square wave of about 1 kHz to 2 kHz.

    However, since the ADC/DAC I have is fmcdaq2, I would like to know haw to output a 1 kHz Square wave using fmcdaq2.

    I'm sorry. I looked at https://ez.analog.com/fpga/f/q-a/81027/daq2-kcu105-send-data-to-dac and I saw the URL and could understand changing the filter of fmcdaq2, but I could not understand which part to change specifically.

    Please tell me.

    Yuta

  • Hi,

    I use hdl_2018_r1 for hdl and 2018_R1 for no-OS.

    I could output rectangular wave.

    However, I would like to output a rectangular wave between 1 kHz and 10 kHz.
    How can I implement it by changing fmcdaq2.c?

  • Hi,


    Again, why don't you simply use a GPIO not the daq2 for that?
    A few ideas:

    1. You can use the software to toggle a register or send/change a value at your desired frequency.
    2. Use the software to write values directly in an HDL register(that you add), in the register map, as an example see dac_data_select_s (0x4418 REG_CHAN_CNTRL_7),

    Feed it to the data select multiplexer https://github.com/analogdevicesinc/hdl/blob/hdl_2018_r1/library/axi_ad9144/axi_ad9144_channel.v#L269

    3. Write in HDL something like:

    input [31: 0] increment //from the regmap

    reg [15:0] square_wave = 0;


    always @(pesedge clk) begin
       sawtooth_wave <= sawtooth_wave + increment;

       square_wave <= {16{sawtooth_wave[31]}}
    end

    The frequency of your square wave is core _clock/(2^32 * increment)
    use the above to calculate the value for increment.

    https://en.wikipedia.org/wiki/Numerically_controlled_oscillator

    You get the idea, output that trough the multiplexer mentioned above.

    Andrei

  • Hi, Thank you for your reply.

    I could understand what you said.

    However, I wanted to see the example ( dac_data_select_s (0x4418 REG_CHAN_CNTRL_7),) and I looked for it, but I could not find it.

    Where is it?

    Also, as described in the attached file, is it correct by adding the description of HDL (Number 3 of a few ideas) to axi_ad 9144_channnel.v and changing the multiplexer description to dac_data_sel_s == 4'h3 and 4'h3: dac_data <= square_wave; ? (from L266 toL290)

    // ***************************************************************************
    // ***************************************************************************
    // Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved.
    //
    // In this HDL repository, there are many different and unique modules, consisting
    // of various HDL (Verilog or VHDL) components. The individual modules are
    // developed independently, and may be accompanied by separate and unique license
    // terms.
    //
    // The user should read each of these license terms, and understand the
    // freedoms and responsibilities that he or she has by using this source/core.
    //
    // This core is distributed in the hope that it will be useful, but WITHOUT ANY
    // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
    // A PARTICULAR PURPOSE.
    //
    // Redistribution and use of source or resulting binaries, with or without modification
    // of this file, are permitted under one of the following two license terms:
    //
    //   1. The GNU General Public License version 2 as published by the
    //      Free Software Foundation, which can be found in the top level directory
    //      of this repository (LICENSE_GPL2), and also online at:
    //      <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
    //
    // OR
    //
    //   2. An ADI specific BSD license, which can be found in the top level directory
    //      of this repository (LICENSE_ADIBSD), and also on-line at:
    //      https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD
    //      This will allow to generate bit files and not release the source code,
    //      as long as it attaches to an ADI device.
    //
    // ***************************************************************************
    // ***************************************************************************
    
    `timescale 1ns/100ps
    
    module axi_ad9144_channel #(
    
      parameter CHANNEL_ID = 32'h0,
      parameter DATAPATH_DISABLE = 0) (
    
      // dac interface
    
      input                   dac_clk,
      input                   dac_rst,
      output  reg             dac_enable,
      output  reg [63:0]      dac_data,
      input       [63:0]      dma_data,
    
      // processor interface
    
      input                   dac_data_sync,
      input                   dac_dds_format,
    
      // bus interface
    
      input                   up_rstn,
      input                   up_clk,
      input                   up_wreq,
      input       [13:0]      up_waddr,
      input       [31:0]      up_wdata,
      output                  up_wack,
      input                   up_rreq,
      input       [13:0]      up_raddr,
      output      [31:0]      up_rdata,
      output                  up_rack);
    
      
    
      // internal registers
    
      reg     [63:0]  dac_pn7_data = 'd0;
      reg     [63:0]  dac_pn15_data = 'd0;
      reg     [15:0]  dac_dds_phase_0_0 = 'd0;
      reg     [15:0]  dac_dds_phase_0_1 = 'd0;
      reg     [15:0]  dac_dds_phase_1_0 = 'd0;
      reg     [15:0]  dac_dds_phase_1_1 = 'd0;
      reg     [15:0]  dac_dds_phase_2_0 = 'd0;
      reg     [15:0]  dac_dds_phase_2_1 = 'd0;
      reg     [15:0]  dac_dds_phase_3_0 = 'd0;
      reg     [15:0]  dac_dds_phase_3_1 = 'd0;
      reg     [15:0]  dac_dds_incr_0 = 'd0;
      reg     [15:0]  dac_dds_incr_1 = 'd0;
      reg     [63:0]  dac_dds_data = 'd0;
    
     
    
      // internal signals
    
      wire    [15:0]  dac_dds_data_0_s;
      wire    [15:0]  dac_dds_data_1_s;
      wire    [15:0]  dac_dds_data_2_s;
      wire    [15:0]  dac_dds_data_3_s;
      wire    [15:0]  dac_dds_scale_1_s;
      wire    [15:0]  dac_dds_init_1_s;
      wire    [15:0]  dac_dds_incr_1_s;
      wire    [15:0]  dac_dds_scale_2_s;
      wire    [15:0]  dac_dds_init_2_s;
      wire    [15:0]  dac_dds_incr_2_s;
      wire    [15:0]  dac_pat_data_1_s;
      wire    [15:0]  dac_pat_data_2_s;
      wire    [ 3:0]  dac_data_sel_s;
      wire    [63:0]  dac_pn7_data_i_s;
      wire    [63:0]  dac_pn15_data_i_s;
      wire    [63:0]  dac_pn7_data_s;
      wire    [63:0]  dac_pn15_data_s;
    
       // PN7 function
    
      function [63:0] pn7;
        input [7:0] din;
        reg   [63:0] dout;
        begin
          dout[15] = din[ 6] ^ din[ 5];
          dout[14] = din[ 5] ^ din[ 4];
          dout[13] = din[ 4] ^ din[ 3];
          dout[12] = din[ 3] ^ din[ 2];
          dout[11] = din[ 2] ^ din[ 1];
          dout[10] = din[ 1] ^ din[ 0];
          dout[ 9] = din[ 0] ^ din[ 6] ^ din[ 5];
          dout[ 8] = din[ 6] ^ din[ 4];
          dout[ 7] = din[ 5] ^ din[ 3];
          dout[ 6] = din[ 4] ^ din[ 2];
          dout[ 5] = din[ 3] ^ din[ 1];
          dout[ 4] = din[ 2] ^ din[ 0];
          dout[ 3] = din[ 1] ^ din[ 6] ^ din[ 5];
          dout[ 2] = din[ 0] ^ din[ 5] ^ din[ 4];
          dout[ 1] = din[ 6] ^ din[ 4] ^ din[ 5] ^ din[ 3];
          dout[ 0] = din[ 5] ^ din[ 3] ^ din[ 4] ^ din[ 2];
          dout[31] = din[ 4] ^ din[ 2] ^ din[ 3] ^ din[ 1];
          dout[30] = din[ 3] ^ din[ 1] ^ din[ 2] ^ din[ 0];
          dout[29] = din[ 2] ^ din[ 0] ^ din[ 1] ^ din[ 6] ^ din[ 5];
          dout[28] = din[ 1] ^ din[ 6] ^ din[ 0] ^ din[ 4];
          dout[27] = din[ 0] ^ din[ 6] ^ din[ 3];
          dout[26] = din[ 6] ^ din[ 2];
          dout[25] = din[ 5] ^ din[ 1];
          dout[24] = din[ 4] ^ din[ 0];
          dout[23] = din[ 3] ^ din[ 6] ^ din[ 5];
          dout[22] = din[ 2] ^ din[ 5] ^ din[ 4];
          dout[21] = din[ 1] ^ din[ 4] ^ din[ 3];
          dout[20] = din[ 0] ^ din[ 3] ^ din[ 2];
          dout[19] = din[ 6] ^ din[ 2] ^ din[ 5] ^ din[ 1];
          dout[18] = din[ 5] ^ din[ 1] ^ din[ 4] ^ din[ 0];
          dout[17] = din[ 4] ^ din[ 0] ^ din[ 3] ^ din[ 6] ^ din[ 5];
          dout[16] = din[ 3] ^ din[ 6] ^ din[ 2] ^ din[ 4];
          dout[47] = din[ 2] ^ din[ 5] ^ din[ 1] ^ din[ 3];
          dout[46] = din[ 1] ^ din[ 4] ^ din[ 0] ^ din[ 2];
          dout[45] = din[ 0] ^ din[ 3] ^ din[ 6] ^ din[ 5] ^ din[ 1];
          dout[44] = din[ 6] ^ din[ 2] ^ din[ 4] ^ din[ 0];
          dout[43] = din[ 1] ^ din[ 3] ^ din[ 6];
          dout[42] = din[ 0] ^ din[ 5] ^ din[ 2];
          dout[41] = din[ 6] ^ din[ 4] ^ din[ 5] ^ din[ 1];
          dout[40] = din[ 5] ^ din[ 3] ^ din[ 4] ^ din[ 0];
          dout[39] = din[ 4] ^ din[ 2] ^ din[ 3] ^ din[ 6] ^ din[ 5];
          dout[38] = din[ 3] ^ din[ 5] ^ din[ 1] ^ din[ 2] ^ din[ 4];
          dout[37] = din[ 2] ^ din[ 4] ^ din[ 0] ^ din[ 1] ^ din[ 3];
          dout[36] = din[ 1] ^ din[ 3] ^ din[ 6] ^ din[ 0] ^ din[ 5] ^ din[ 2];
          dout[35] = din[ 0] ^ din[ 2] ^ din[ 6] ^ din[ 4] ^ din[ 1];
          dout[34] = din[ 6] ^ din[ 1] ^ din[ 3] ^ din[ 0];
          dout[33] = din[ 0] ^ din[ 2] ^ din[ 6];
          dout[32] = din[ 6] ^ din[ 1];
          dout[63] = din[ 5] ^ din[ 0];
          dout[62] = din[ 4] ^ din[ 6] ^ din[ 5];
          dout[61] = din[ 3] ^ din[ 5] ^ din[ 4];
          dout[60] = din[ 2] ^ din[ 4] ^ din[ 3];
          dout[59] = din[ 1] ^ din[ 3] ^ din[ 2];
          dout[58] = din[ 0] ^ din[ 2] ^ din[ 1];
          dout[57] = din[ 6] ^ din[ 1] ^ din[ 5] ^ din[ 0];
          dout[56] = din[ 0] ^ din[ 4] ^ din[ 6];
          dout[55] = din[ 6] ^ din[ 3];
          dout[54] = din[ 5] ^ din[ 2];
          dout[53] = din[ 4] ^ din[ 1];
          dout[52] = din[ 3] ^ din[ 0];
          dout[51] = din[ 2] ^ din[ 6] ^ din[ 5];
          dout[50] = din[ 1] ^ din[ 5] ^ din[ 4];
          dout[49] = din[ 0] ^ din[ 4] ^ din[ 3];
          dout[48] = din[ 6] ^ din[ 3] ^ din[ 5] ^ din[ 2];
          pn7 = dout;
        end
      endfunction
      
      // PN15 function
    
      function [63:0] pn15;
        input [15:0] din;
        reg   [63:0] dout;
        begin
          dout[15] = din[14] ^ din[13];
          dout[14] = din[13] ^ din[12];
          dout[13] = din[12] ^ din[11];
          dout[12] = din[11] ^ din[10];
          dout[11] = din[10] ^ din[ 9];
          dout[10] = din[ 9] ^ din[ 8];
          dout[ 9] = din[ 8] ^ din[ 7];
          dout[ 8] = din[ 7] ^ din[ 6];
          dout[ 7] = din[ 6] ^ din[ 5];
          dout[ 6] = din[ 5] ^ din[ 4];
          dout[ 5] = din[ 4] ^ din[ 3];
          dout[ 4] = din[ 3] ^ din[ 2];
          dout[ 3] = din[ 2] ^ din[ 1];
          dout[ 2] = din[ 1] ^ din[ 0];
          dout[ 1] = din[ 0] ^ din[14] ^ din[13];
          dout[ 0] = din[14] ^ din[12];
          dout[31] = din[13] ^ din[11];
          dout[30] = din[12] ^ din[10];
          dout[29] = din[11] ^ din[ 9];
          dout[28] = din[10] ^ din[ 8];
          dout[27] = din[ 9] ^ din[ 7];
          dout[26] = din[ 8] ^ din[ 6];
          dout[25] = din[ 7] ^ din[ 5];
          dout[24] = din[ 6] ^ din[ 4];
          dout[23] = din[ 5] ^ din[ 3];
          dout[22] = din[ 4] ^ din[ 2];
          dout[21] = din[ 3] ^ din[ 1];
          dout[20] = din[ 2] ^ din[ 0];
          dout[19] = din[ 1] ^ din[14] ^ din[13];
          dout[18] = din[ 0] ^ din[13] ^ din[12];
          dout[17] = din[14] ^ din[12] ^ din[13] ^ din[11];
          dout[16] = din[13] ^ din[11] ^ din[12] ^ din[10];
          dout[47] = din[12] ^ din[10] ^ din[11] ^ din[ 9];
          dout[46] = din[11] ^ din[ 9] ^ din[10] ^ din[ 8];
          dout[45] = din[10] ^ din[ 8] ^ din[ 9] ^ din[ 7];
          dout[44] = din[ 9] ^ din[ 7] ^ din[ 8] ^ din[ 6];
          dout[43] = din[ 8] ^ din[ 6] ^ din[ 7] ^ din[ 5];
          dout[42] = din[ 7] ^ din[ 5] ^ din[ 6] ^ din[ 4];
          dout[41] = din[ 6] ^ din[ 4] ^ din[ 5] ^ din[ 3];
          dout[40] = din[ 5] ^ din[ 3] ^ din[ 4] ^ din[ 2];
          dout[39] = din[ 4] ^ din[ 2] ^ din[ 3] ^ din[ 1];
          dout[38] = din[ 3] ^ din[ 1] ^ din[ 2] ^ din[ 0];
          dout[37] = din[ 2] ^ din[ 0] ^ din[ 1] ^ din[14] ^ din[13];
          dout[36] = din[ 1] ^ din[14] ^ din[ 0] ^ din[12];
          dout[35] = din[ 0] ^ din[14] ^ din[11];
          dout[34] = din[14] ^ din[10];
          dout[33] = din[13] ^ din[ 9];
          dout[32] = din[12] ^ din[ 8];
          dout[63] = din[11] ^ din[ 7];
          dout[62] = din[10] ^ din[ 6];
          dout[61] = din[ 9] ^ din[ 5];
          dout[60] = din[ 8] ^ din[ 4];
          dout[59] = din[ 7] ^ din[ 3];
          dout[58] = din[ 6] ^ din[ 2];
          dout[57] = din[ 5] ^ din[ 1];
          dout[56] = din[ 4] ^ din[ 0];
          dout[55] = din[ 3] ^ din[14] ^ din[13];
          dout[54] = din[ 2] ^ din[13] ^ din[12];
          dout[53] = din[ 1] ^ din[12] ^ din[11];
          dout[52] = din[ 0] ^ din[11] ^ din[10];
          dout[51] = din[14] ^ din[10] ^ din[13] ^ din[ 9];
          dout[50] = din[13] ^ din[ 9] ^ din[12] ^ din[ 8];
          dout[49] = din[12] ^ din[ 8] ^ din[11] ^ din[ 7];
          dout[48] = din[11] ^ din[ 7] ^ din[10] ^ din[ 6];
          pn15 = dout;
        end
      endfunction
    
      assign dac_pn7_data_i_s  = ~dac_pn7_data;
      assign dac_pn15_data_i_s = ~dac_pn15_data;
    
      assign dac_pn7_data_s    = dac_pn7_data;
      assign dac_pn15_data_s   = dac_pn15_data;
    
    
    
    
      //my scripts
      
      input       [31:0]      increment,
      reg [15:0] square_wave = 0;
      
      always @(pesedge clk)begin
        sawtooth_wave <= sawtooth_wave + increment;
        square_wave <= {16{sawtooth_wave[31]}}
      end
      // dac data select
    
      always @(posedge dac_clk) begin
        dac_enable <= (dac_data_sel_s == 4'h3) ? 1'b1 : 1'b0;
        case (dac_data_sel_s)
          4'h7: dac_data <= dac_pn15_data_s;
          4'h6: dac_data <= dac_pn7_data_s;
          4'h5: dac_data <= dac_pn15_data_i_s;
          4'h4: dac_data <= dac_pn7_data_i_s;
          4'h3: dac_data <= square_wave;
          4'h2: dac_data <= dma_data;
          4'h1: dac_data <= { dac_pat_data_2_s, dac_pat_data_1_s,
                              dac_pat_data_2_s, dac_pat_data_1_s};
          default: dac_data <= dac_dds_data;
        endcase
      end
      
      
    
      // pn registers
    
      always @(posedge dac_clk) begin
        if (dac_data_sync == 1'b1) begin
          dac_pn7_data <= {64{1'd1}};
          dac_pn15_data <= {64{1'd1}};
        end else begin
          dac_pn7_data <= pn7(dac_pn7_data[55:48]);
          dac_pn15_data <= pn15(dac_pn15_data[63:48]);
        end
      end
    
      // dds
    
      always @(posedge dac_clk) begin
        if (dac_data_sync == 1'b1) begin
          dac_dds_phase_0_0 <= dac_dds_init_1_s;
          dac_dds_phase_0_1 <= dac_dds_init_2_s;
          dac_dds_phase_1_0 <= dac_dds_phase_0_0 + dac_dds_incr_1_s;
          dac_dds_phase_1_1 <= dac_dds_phase_0_1 + dac_dds_incr_2_s;
          dac_dds_phase_2_0 <= dac_dds_phase_1_0 + dac_dds_incr_1_s;
          dac_dds_phase_2_1 <= dac_dds_phase_1_1 + dac_dds_incr_2_s;
          dac_dds_phase_3_0 <= dac_dds_phase_2_0 + dac_dds_incr_1_s;
          dac_dds_phase_3_1 <= dac_dds_phase_2_1 + dac_dds_incr_2_s;
          dac_dds_incr_0 <= {dac_dds_incr_1_s[13:0], 2'd0};
          dac_dds_incr_1 <= {dac_dds_incr_2_s[13:0], 2'd0};
          dac_dds_data <= 64'd0;
        end else begin
          dac_dds_phase_0_0 <= dac_dds_phase_0_0 + dac_dds_incr_0;
          dac_dds_phase_0_1 <= dac_dds_phase_0_1 + dac_dds_incr_1;
          dac_dds_phase_1_0 <= dac_dds_phase_1_0 + dac_dds_incr_0;
          dac_dds_phase_1_1 <= dac_dds_phase_1_1 + dac_dds_incr_1;
          dac_dds_phase_2_0 <= dac_dds_phase_2_0 + dac_dds_incr_0;
          dac_dds_phase_2_1 <= dac_dds_phase_2_1 + dac_dds_incr_1;
          dac_dds_phase_3_0 <= dac_dds_phase_3_0 + dac_dds_incr_0;
          dac_dds_phase_3_1 <= dac_dds_phase_3_1 + dac_dds_incr_1;
          dac_dds_incr_0 <= dac_dds_incr_0;
          dac_dds_incr_1 <= dac_dds_incr_1;
          dac_dds_data <= { dac_dds_data_3_s, dac_dds_data_2_s,
                            dac_dds_data_1_s, dac_dds_data_0_s};
        end
      end
    
      generate
      if (DATAPATH_DISABLE == 1) begin
      assign dac_dds_data_0_s = 16'd0;
      end else begin
      ad_dds i_dds_0 (
        .clk (dac_clk),
        .dds_format (dac_dds_format),
        .dds_phase_0 (dac_dds_phase_0_0),
        .dds_scale_0 (dac_dds_scale_1_s),
        .dds_phase_1 (dac_dds_phase_0_1),
        .dds_scale_1 (dac_dds_scale_2_s),
        .dds_data (dac_dds_data_0_s));
      end
      endgenerate
      
      generate
      if (DATAPATH_DISABLE == 1) begin
      assign dac_dds_data_1_s = 16'd0;
      end else begin
      ad_dds i_dds_1 (
        .clk (dac_clk),
        .dds_format (dac_dds_format),
        .dds_phase_0 (dac_dds_phase_1_0),
        .dds_scale_0 (dac_dds_scale_1_s),
        .dds_phase_1 (dac_dds_phase_1_1),
        .dds_scale_1 (dac_dds_scale_2_s),
        .dds_data (dac_dds_data_1_s));
      end
      endgenerate
      
      generate
      if (DATAPATH_DISABLE == 1) begin
      assign dac_dds_data_2_s = 16'd0;
      end else begin
      ad_dds i_dds_2 (
        .clk (dac_clk),
        .dds_format (dac_dds_format),
        .dds_phase_0 (dac_dds_phase_2_0),
        .dds_scale_0 (dac_dds_scale_1_s),
        .dds_phase_1 (dac_dds_phase_2_1),
        .dds_scale_1 (dac_dds_scale_2_s),
        .dds_data (dac_dds_data_2_s));
      end
      endgenerate
      
      generate
      if (DATAPATH_DISABLE == 1) begin
      assign dac_dds_data_3_s = 16'd0;
      end else begin
      ad_dds i_dds_3 (
        .clk (dac_clk),
        .dds_format (dac_dds_format),
        .dds_phase_0 (dac_dds_phase_3_0),
        .dds_scale_0 (dac_dds_scale_1_s),
        .dds_phase_1 (dac_dds_phase_3_1),
        .dds_scale_1 (dac_dds_scale_2_s),
        .dds_data (dac_dds_data_3_s));
      end
      endgenerate
      
      // single channel processor
    
      up_dac_channel #(.CHANNEL_ID(CHANNEL_ID)) i_up_dac_channel (
        .dac_clk (dac_clk),
        .dac_rst (dac_rst),
        .dac_dds_scale_1 (dac_dds_scale_1_s),
        .dac_dds_init_1 (dac_dds_init_1_s),
        .dac_dds_incr_1 (dac_dds_incr_1_s),
        .dac_dds_scale_2 (dac_dds_scale_2_s),
        .dac_dds_init_2 (dac_dds_init_2_s),
        .dac_dds_incr_2 (dac_dds_incr_2_s),
        .dac_pat_data_1 (dac_pat_data_1_s),
        .dac_pat_data_2 (dac_pat_data_2_s),
        .dac_data_sel (dac_data_sel_s),
        .dac_iq_mode (),
        .dac_iqcor_enb (),
        .dac_iqcor_coeff_1 (),
        .dac_iqcor_coeff_2 (),
        .up_usr_datatype_be (),
        .up_usr_datatype_signed (),
        .up_usr_datatype_shift (),
        .up_usr_datatype_total_bits (),
        .up_usr_datatype_bits (),
        .up_usr_interpolation_m (),
        .up_usr_interpolation_n (),
        .dac_usr_datatype_be (1'b0),
        .dac_usr_datatype_signed (1'b1),
        .dac_usr_datatype_shift (8'd0),
        .dac_usr_datatype_total_bits (8'd16),
        .dac_usr_datatype_bits (8'd16),
        .dac_usr_interpolation_m (16'd1),
        .dac_usr_interpolation_n (16'd1),
        .up_rstn (up_rstn),
        .up_clk (up_clk),
        .up_wreq (up_wreq),
        .up_waddr (up_waddr),
        .up_wdata (up_wdata),
        .up_wack (up_wack),
        .up_rreq (up_rreq),
        .up_raddr (up_raddr),
        .up_rdata (up_rdata),
        .up_rack (up_rack));
      
    endmodule
    
    // ***************************************************************************
    // ***************************************************************************
    
      
    

    Please teach me.

  • Hi,

    This is the function you are looking for:https://github.com/analogdevicesinc/no-OS/blob/2018_R1/common_drivers/dac_core/dac_core.c#L176

    The code I gave you is to help you understand the principle, I see that you've taken it as it is.
    To get you faster to implementation: in principle, in the code you posted above "sawtooth_wave" is the same thing with "dac_dds_phase_0_0". Replacing sawtooth_wave with dac_dds_phase_0_0 will give you a square wave frequency equal with the DDS sine frequency. The data select and the value for frequency is all you have to modify in the software.
    Line 271 use dac_clk not clk.

    Andrei

  • Hi, Thank you for reply.

    I understood what you were saying. Thank you.

    I changed "sawtooth_wave" to "dac_dds_phase_0_0"  and changed "clk" to "dac_clk" in axi_9144_channel.v .

    And then I ran make in /library/axi_ad 9144 and then executed make in /projects/daq2/vc707.

    As a result, the build succeeded.

    However, when executed with SDK, no UART message was displayed and a noise waveform was output.

    Is it wrong to write mux?

      always @(posedge dac_clk) begin
        dac_enable <= (dac_data_sel_s == 4'h3) ? 1'b1 : 1'b0;
        case (dac_data_sel_s)
          4'h7: dac_data <= dac_pn15_data_s;
          4'h6: dac_data <= dac_pn7_data_s;
          4'h5: dac_data <= dac_pn15_data_i_s;
          4'h4: dac_data <= dac_pn7_data_i_s;
          4'h3: dac_data <= square_wave;
          4'h2: dac_data <= dma_data;
          4'h1: dac_data <= { dac_pat_data_2_s, dac_pat_data_1_s,
                              dac_pat_data_2_s, dac_pat_data_1_s};
          default: dac_data <= dac_dds_data;
        endcase
      end
      

    Or is it because the value is not stored in "implement"? In that case, how can I give a value to "imlpement"?

    please tell me.

  • Hi,

    What do you mean, no UART message?
    Have you changed anything else? Can you try the reference design hdf to confirm the issue appears for your changes?

    Andrei

  • Hi,

    I already answer the above question, something went wrong and I can't see my message.

    What do you mean, no UART message?
    Have you changed anything else? Can you try the reference design hdf to confirm the issue appears for your changes?

    "Also, I need to change the DMA_buffer of github.com/.../fmcdaq2.c, right?". Yes, you have to make sure you have selected the right path on the mux.

    Have you used before the xsdb from xilinx?
    you can connect to the PS7 and directly read and write registers after you initialize the system.

    Andrei

  • HI, Thank you for reply.

    I noticed that I made a mistake.The UART message was displayed properly. I'm sorry.

    In order to select the right path on the mux, I changed "DAC_SRC_ZERO" of L123 to "DAC_SRC_SQUARE"  in /no-OS/common_drivers/dac_core/dac_core.h. And I changed L640 to L654 in /no-OS/fmcdaq2/fmcdaq2.c as follows.

    #if DMA_BUFFER
    	ad9144_channels[0].sel = DAC_SRC_SQUARE;
    	ad9144_channels[1].sel = DAC_SRC_SQUARE;
    	dac_data_setup(&ad9144_core);
    
    	/*if(!dmac_start_transaction(ad9144_dma)) {
    		printf("daq2: transmit data from memory\n");
    	};*/
    #else
    	ad9144_channels[0].sel = DAC_SRC_DDS;
    	ad9144_channels[1].sel = DAC_SRC_DDS;
    	dac_data_setup(&ad9144_core);
    
    	printf("daq2: setup and configuration is done\n");
    #endif

    Others have not changed both hdl and no-OS. (Except axi_ad 9144_channel.v)

    Debugging was done, but 0 was output on the oscilloscope. What should I do?

    I used xsdb. 

    How can I connect to the PS7 and directly read and write registers?

  • Hi,

    adc and dac core setup at 500MHz that is bad.
    You have pn mismatch, This means your communication between FPGA and devices is not working.
    Let's start with this. What sampling rates do you intend to use, lane rates?

    Andrei

Reply Children
  • Hi, Thank you for your reply.

    I understood that.

    The sampling rate of the lane rate is as follows.

    In the above example, I am using case 3.

    switch (mode) {
    		case '4':
    			printf ("4 - ADC  600 MSPS; DAC  600 MSPS\n");
    			p_ad9523_param->pll2_vco_diff_m1 = 5;
    			(&p_ad9523_param->channels[DAC_FPGA_CLK])->
    					channel_divider = 2;
    			(&p_ad9523_param->channels[DAC_DEVICE_CLK])->
    					channel_divider = 1;
    			(&p_ad9523_param->channels[DAC_DEVICE_SYSREF])->
    					channel_divider = 128;
    			(&p_ad9523_param->channels[DAC_FPGA_SYSREF])->
    					channel_divider = 128;
    			(&p_ad9523_param->channels[ADC_FPGA_CLK])->
    					channel_divider = 2;
    			(&p_ad9523_param->channels[ADC_DEVICE_CLK])->
    					channel_divider = 1;
    			(&p_ad9523_param->channels[ADC_DEVICE_SYSREF])->
    					channel_divider = 128;
    			(&p_ad9523_param->channels[ADC_FPGA_SYSREF])->
    					channel_divider = 128;
    			p_ad9144_xcvr->reconfig_bypass = 0;
    			p_ad9144_param->lane_rate_kbps = 6000000;
    			p_ad9144_xcvr->lane_rate_kbps = 6000000;
    			p_ad9144_xcvr->ref_clock_khz = 300000;
    			p_ad9680_xcvr->reconfig_bypass = 0;
    			p_ad9680_param->lane_rate_kbps = 6000000;
    			p_ad9680_xcvr->lane_rate_kbps = 6000000;
    			p_ad9680_xcvr->ref_clock_khz = 300000;
    #ifdef XILINX
    			p_ad9144_xcvr->dev.lpm_enable = 0;
    			p_ad9144_xcvr->dev.qpll_enable = 0;
    			p_ad9144_xcvr->dev.out_clk_sel = 4;
    
    			p_ad9680_xcvr->dev.lpm_enable = 1;
    			p_ad9680_xcvr->dev.qpll_enable = 0;
    			p_ad9680_xcvr->dev.out_clk_sel = 4;
    #endif
    			break;
    		case '3':
    			printf ("3 - ADC  500 MSPS; DAC  500 MSPS\n");
    			p_ad9523_param->pll2_vco_diff_m1 = 3;
    			(&p_ad9523_param->channels[DAC_FPGA_CLK])->
    					channel_divider = 4;
    			(&p_ad9523_param->channels[DAC_DEVICE_CLK])->
    					channel_divider = 2;
    			(&p_ad9523_param->channels[DAC_DEVICE_SYSREF])->
    					channel_divider = 256;
    			(&p_ad9523_param->channels[DAC_FPGA_SYSREF])->
    					channel_divider = 256;
    			(&p_ad9523_param->channels[ADC_FPGA_CLK])->
    					channel_divider = 4;
    			(&p_ad9523_param->channels[ADC_DEVICE_CLK])->
    					channel_divider = 2;
    			(&p_ad9523_param->channels[ADC_DEVICE_SYSREF])->
    					channel_divider = 256;
    			(&p_ad9523_param->channels[ADC_FPGA_SYSREF])->
    					channel_divider = 256;
    			p_ad9144_xcvr->reconfig_bypass = 0;
    			p_ad9144_param->lane_rate_kbps = 5000000;
    			p_ad9144_xcvr->lane_rate_kbps = 5000000;
    			p_ad9144_xcvr->ref_clock_khz = 250000;
    			p_ad9680_xcvr->reconfig_bypass = 0;
    			p_ad9680_param->lane_rate_kbps = 5000000;
    			p_ad9680_xcvr->lane_rate_kbps = 5000000;
    			p_ad9680_xcvr->ref_clock_khz = 250000;
    #ifdef XILINX
    			p_ad9144_xcvr->dev.lpm_enable = 1;
    			p_ad9144_xcvr->dev.qpll_enable = 0;
    			p_ad9144_xcvr->dev.out_clk_sel = 4;
    
    			p_ad9680_xcvr->dev.lpm_enable = 1;
    			p_ad9680_xcvr->dev.qpll_enable = 0;
    			p_ad9680_xcvr->dev.out_clk_sel = 4;
    #endif
    			break;
    		case '2':
    			printf ("2 - ADC  500 MSPS; DAC 1000 MSPS\n");
    			p_ad9523_param->pll2_vco_diff_m1 = 3;
    			(&p_ad9523_param->channels[DAC_FPGA_CLK])->
    					channel_divider = 2;
    			(&p_ad9523_param->channels[DAC_DEVICE_CLK])->
    					channel_divider = 1;
    			(&p_ad9523_param->channels[DAC_DEVICE_SYSREF])->
    					channel_divider = 128;
    			(&p_ad9523_param->channels[DAC_FPGA_SYSREF])->
    					channel_divider = 128;
    			(&p_ad9523_param->channels[ADC_FPGA_CLK])->
    					channel_divider = 4;
    			(&p_ad9523_param->channels[ADC_DEVICE_CLK])->
    					channel_divider = 2;
    			(&p_ad9523_param->channels[ADC_DEVICE_SYSREF])->
    					channel_divider = 256;
    			(&p_ad9523_param->channels[ADC_FPGA_SYSREF])->
    					channel_divider = 256;
    			p_ad9144_xcvr->reconfig_bypass = 0;
    			p_ad9144_param->lane_rate_kbps = 10000000;
    			p_ad9144_xcvr->lane_rate_kbps = 10000000;
    			p_ad9144_xcvr->ref_clock_khz = 500000;
    			p_ad9680_xcvr->reconfig_bypass = 0;
    			p_ad9680_param->lane_rate_kbps = 5000000;
    			p_ad9680_xcvr->lane_rate_kbps = 5000000;
    			p_ad9680_xcvr->ref_clock_khz = 250000;
    #ifdef XILINX
    			p_ad9144_xcvr->dev.lpm_enable = 0;
    			p_ad9144_xcvr->dev.qpll_enable = 1;
    			p_ad9144_xcvr->dev.out_clk_sel = 4;
    
    			p_ad9680_xcvr->dev.lpm_enable = 1;
    			p_ad9680_xcvr->dev.qpll_enable = 0;
    			p_ad9680_xcvr->dev.out_clk_sel = 4;
    #endif
    			break;
    		default:
    			printf ("1 - ADC 1000 MSPS; DAC 1000 MSPS\n");
    			p_ad9144_xcvr->ref_clock_khz = 500000;
    			p_ad9680_xcvr->ref_clock_khz = 500000;
    			break;
    	}
    

    Yuta

  • Hi,

    The messages with SYSREF alignment  ERROR made me presume your link is down.
    The setup is ok, sorry for the miss understanding. I forgot that the software takes into consideration the clock ratio. https://github.com/analogdevicesinc/no-OS/blob/master/common_drivers/adc_core/adc_core.c#L114

    https://github.com/analogdevicesinc/hdl/blob/master/projects/daq2/common/daq2_bd.tcl#L143
    https://wiki.analog.com/resources/fpga/docs/axi_ad9144


    An example of how to use xsdb console

     

    $ xsdb
    
    ****** Xilinx System Debugger (XSDB) v2017.4.1
      **** Build date : Jan 30 2018-15:42:35
        ** Copyright 1986-2017 Xilinx, Inc. All Rights Reserved.
    
    
    xsdb% connect
    tcfchan#0
    xsdb% target
      1  APU
         2  ARM Cortex-A9 MPCore #0 (Running)
         3  ARM Cortex-A9 MPCore #1 (Running)
      4  xc7z045
    xsdb% target 2
    xsdb% stop
    Info: ARM Cortex-A9 MPCore #0 (target 2) Stopped at 0x113d0c (Suspended)
    xsdb% mrd -force 0x44A00000 
    44A00000:   DEADDEAD
    
    xsdb% mrd -force 0x44A00000
    44A00000:   DEADDEAD
    
    xsdb% mrd -force 0x44A10000 
    44A10000:   000A0062
    
    xsdb% mrd -force 0x44A04418
    44A04418:   00000000
    
    xsdb% mwr -force 0x44A04418 0x3
    xsdb% mrd -force 0x44A04418
    44A04418:   00000003
    
    xsdb% exit
    


    First, can you confirm the DDS generator works on your system?

    Andrei

  • Hi,

    After programming to the FPGA, I tried using xdbd.
    The results are shown below.

    xsdb% connect                                                                   
    tcfchan#0                                                                       
    xsdb% target                                                                    
      1  xc7vx485t
         2  MicroBlaze Debug Module at USER2
            3  MicroBlaze #0 (Stop)
    xsdb% target 3                                                                  
    xsdb% mrd -force 0x44A00000                                                     
    44A00000:   DEADDEAD
    
    xsdb% mrd -force 0x44A10000                                                     
    44A10000:   000A0062
    
    xsdb% mrd -force 0x44A04418                                                     
    44A04418:   00000000
    
    xsdb% mwr -force 0x44A04418 0x3                                                 
    xsdb% mrd -force 0x44A04418                                                     
    44A04418:   00000003
    
    xsdb% exit                                                                      
    exit

    After that I ran with SDK, but as before, PN mismatch occurred.

    Available sampling rates:
    	1 - ADC 1000 MSPS; DAC 1000 MSPS
    	2 - ADC  500 MSPS; DAC 1000 MSPS
    	3 - ADC  500 MSPS; DAC  500 MSPS
    	4 - ADC  600 MSPS; DAC  600 MSPS
    choose an option [default 1]:
    3 - ADC  500 MSPS; DAC  500 MSPS
    
    CPLL ENABLE
    
    CPLL ENABLE
    Tx link is enabled
    Measured Link Clock: 125 MHz
    Link status: DATA
    SYSREF captured: Yes
    SYSREF alignment ERROR
    Rx link is enabled
    Measured Link Clock: 125 MHz
    Link status: DATA
    SYSREF captured: Yes
    SYSREF alignment ERROR
    adc_setup adc core initialized (500 MHz).
    dac_setup dac core initialized (500 MHz).
    main ad9680 - PN9 sequence mismatch!
    main ad9680 - PN23 sequence mismatch!
    daq2: RX capture done.

    No waveform was output at all.

    After that, if you rewrite 0x44A04418 to 0x0 with xsbd, the sine waveform was output.

    Yuta

  • Hi,

    Any changes to hardware or clock/rates that you haven't mentioned?
    I've seen in other threads problems caused by ILA's with no timing issue reported. Do you have ILA's in the system?
    Better of can you start fresh on a new workspace hdl_2018_r1 and no-Os 2018_r1? Validate that the design is working, then add only the last discussed square wave generator in HDL.

    Andrei

  • Hi, thank you for your reply.

    There is not any change in hardware or clock / rate that I do not mention.

    There is no ILA in my system. Should I add ILA? Please tell me how to add if I should add ILA.

    I will try to start with a new workspace hdl_2018_r1 and no-Os 2018_r1.

    Yuta

  • Hi,

    Don't add any ILA's.
    Can you make a testbench and simulate the square wave generator?

    Andrei

  • Hi,

    I understood not adding ILA.
    Since I have not made a test bench, I am not simulating a square wave generator.
    I will try to create the test bench.

    Yuta

  • Hi, 

    I tried to start with a new workspace hdl_2018_r1 and no-Os 2018_r1.

    As a result of the execution, no error appeared on the UART screen, but the waveform was still not output.

  • And I tried creating a test bench, but I could not make it well. How should I change it?

    //square_wave.v
    
    
    `timescale 1ns / 1ps
    
    module square_wave(
    CLK,
    increment,
    dout
    );
    input  CLK;
    input [31:0]  increment;
    reg  [15:0]  wave = 0;
    reg  [15:0]  sawtooth_wave = 'd0;
    output dout;
    
    always @(posedge CLK)begin
      sawtooth_wave <= sawtooth_wave + increment;
      wave <= {16{sawtooth_wave[31]}};
    end
    
    square_wave i_square_wave(
    CLK,
    increment,
    //wave,
    //sawtooth_wave,
    dout
    );
    endmodule
    

    //square_wave_tb.v  //testbench
    
    `timescale 1ns / 1ps
     
    
    module square_wave_tb();
    reg          CLK;
    reg  [31:0]  increment;
    reg  [15:0]  wave = 0;
    reg  [15:0]  sawtooth_wave = 'd0;
    wire dout;
    square_wave i_square_wave(
    .CLK (CLK),
    .increment (increment),
    .wave (wave),
    .sawtooth_wave (sawtooth_wave),
    .dout (dout)
    );
    
    always
      begin
        #50 CLK =~CLK;
      end
       
    always @(posedge CLK)begin
      sawtooth_wave <= sawtooth_wave + increment;
      wave <= {16{sawtooth_wave[31]}};
    end
    
    endmodule

    Yuta

  • Hi,

    Use 16 bits for increment.
    Fix sawtooth_wave[31], you only have 16 bits there.

    Andrei