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.

DAC3482: Getting oscillating output for a DC input

Part Number: DAC3482
Other Parts Discussed in Thread: CDCE62005

Tool/software:

I am evaluating the DAC3482 for a new product design. Currently I am using the DAC3482-EVM board, and the FMC adaptor board. I am driving the SPI using the supplied TI software DAC38x GUI.

I am generating a ramp using an in-house FPGA board. The ramp has been verified on an oscilloscope. I use the CDCE62005 secondary reference (on board crystal) to generate all the clocks including the FPGA input clock. This in turn generates the data clock and FIFO strobe signals.

What I would expect to see is my ramp on the output of the DAC. Instead, I see _nothing_ However, when I enable the mixer (which I would think I could bypass) I now see my ramp, but with an oscillation inside the envelope. Nothing I do seems to affect the frequency of the oscillation. Please help explain the following:

How do I configure the DAC to just output the DC signals sent in on the parallel bus (no mixer, no NCO, etc)?

What is causing the output I see?

Why do I need the mixer enabled?

We want to use this as a straight-forward DAC at 250MSPS. I do not see another alternative, but if you can suggest a better product, I am open to changing the design.

Thanks

Ben
Attachments: Traces

`default_nettype none
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:  RedWave Labs Ltd
// Engineer: BCK
// 
// Create Date: 07.11.2022 12:17:14
// Design Name: DAC3482
// Module Name: top
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: Drives ramp into DAC
// 
// Dependencies: 
// 
// Revision:1.0
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module top(
    output wire rx_serial,
    input wire tx_serial,
    output wire led_pl_green,
    output wire led_pl_red,
    output wire o_SYNTH_CTRL_CE,
    output wire[0:2] tp,
    output wire[15:0] D_P,
    output wire[15:0] D_N,
    
    output wire FIFO_ISTR_N,  
    output wire FIFO_ISTR_P,  
    input wire EVAL_FPGA_CLK_N,     
    input wire EVAL_FPGA_CLK_P,     
    output wire DATA_CLK_N,  
    output wire DATA_CLK_P,  
    output wire SYNC_N,       
    output wire SYNC_P       
    
    );
    
// use the startup block clock for the UART
wire sys_clk;
reg ce_off = 1'b0;
assign o_SYNTH_CTRL_CE = ce_off;

STARTUPE2 STARTUPE2
     (
     .CLK(1'b0),
      .GSR(1'b0),
      .GTS(1'b0),
      .KEYCLEARB(1'b1),
      .PACK(1'b0),
      .PREQ(),
      .USRCCLKO(1'b0),
      .USRCCLKTS(1'b0),
      .USRDONEO(1'b0),
      .USRDONETS(1'b1),

      .CFGCLK(),
      .CFGMCLK(sys_clk),
      .EOS()
  );

wire dac_data_clk;
reg [15:0] dac_data = 16'b0;
// module to convert single-ended data to LVDS:
dac_driver dac1 (
   .data_in(dac_data),
   .data_out_p(D_P),
   .data_out_n(D_N),
   .clk_in(dac_data_clk),
   .frame_n(FIFO_ISTR_N),  
   .frame_p(FIFO_ISTR_P),  
   .sync_n(SYNC_N),       
   .sync_p(SYNC_P)   
);
wire dac_data_clk_int;

// EVAL board generates a clock for us. Use as data clock
IBUFDS IBUFDS_dac_clk (
    .O(dac_data_clk_int),
    .IB(EVAL_FPGA_CLK_N), 
    .I(EVAL_FPGA_CLK_P)
);

OBUFDS  #(
   .IOSTANDARD("LVDS"), // Specify the output I/O standard
   .SLEW("FAST")           // Specify the output slew rate
    ) OBUFDS_dac_clk (
    .I(dac_data_clk_int), // Diff_p output (connect directly to top-level port)
    .OB(DATA_CLK_N), // Diff_n output (connect directly to top-level port)
    .O(DATA_CLK_P)
);

BUFG BUFG_clk (.I(dac_data_clk_int), .O(dac_data_clk));

// UART decoder 

(* mark_debug = "true" *) wire  [7:0] ser_data;
(* mark_debug = "true" *) wire dv;
wire uart_clk;
clock_divider #(.DIVISOR(10)) cd0 (sys_clk, uart_clk);//65kHz
assign  rx_serial = tx_serial; //echo back serial command

//564 at 65MHz is baud 115200
//6771 at 65MHz is baud 9600
uart_rx #( .CLKS_PER_BIT(677)) uart1
  (
   .i_Clock(uart_clk),
   .i_Rx_Serial(tx_serial),// inverted: names wrt PC!
   .o_Rx_DV(dv),
   .o_Rx_Byte(ser_data)
   );
// three modes. Constant value, triangle or sine
reg triangle_en = 1'b0;
reg [15:0] const_dac = 16'b0;
reg sine_en = 1'b0;

// command decoder

always @ (posedge(sys_clk))
begin
    case(ser_data) 
        "T": //start triangle output
            triangle_en <= 1'b1;
        "t": //stop triangle output
            triangle_en <= 1'b0;
        "0": //set constant to minimum (signed int)
            const_dac <= 16'hFFFF/2;
        "3": //set constant to 0.25 max (signed int)
            const_dac <= 16'h7FFF/4;
        "5": //set constant to 0.5 max (signed int)
            const_dac <= 16'h7FFF/2;
        "7"://set constant to 0.75 max (signed int)
            const_dac <= 16'h7FFF/4*3;
        "9": //set constant to max (signed int)
            const_dac <= 16'h7FFF;
        "S": //start sine wave output
            sine_en <= 1'b1;
        "s"://stop sine wave output
            sine_en <= 1'b0;
   endcase     
end
wire [7:0] sine;
reg [15:0] dac_value = 16'b0;
//reg [15:0] bit =16'b0;
reg dir = 1'b0;


always @ (posedge(dac_data_clk))
begin
    if(triangle_en) begin
        if(dir == 0)
            dac_value <= dac_value +1;
        if(dir == 1)
            dac_value <= dac_value -1;    
     end else begin
        dac_value <= const_dac;
    end 
    if(dac_value == 16'h7FFE )
        dir <= 1'b1; 
    if(dac_value == 16'h1 ) 
        dir <= 1'b0; 
    // walking bit used for digital testing:
    //bit <= 1<< dac_value[5:0];
end    


//convert triangle to sine using lookup:
sine_table st1 (.i_clk(dac_data_clk), .i_ce(sine_en), .i_phase(dac_value[7:0]), .o_val(sine));
always @(*) begin
    if(sine_en) 
        dac_data <= {1'b0, sine, 7'b0}; // largest value for signed int
    else 
        dac_data <= dac_value;
end

//various debug on LED and test-pins

wire dac_data_clk_div_1000;
clock_divider #(.DIVISOR(1000)) cd1 (dac_data_clk, dac_data_clk_div_1000);//300kHz
wire led_flash;
clock_divider #(.DIVISOR(32500000)) cd2 (sys_clk, led_flash);//2Hz

assign tp[0] = dac_data_clk_div_1000;
assign tp[1] = dv;
assign tp[2] = triangle_en;  
assign led_pl_green = led_flash;
assign led_pl_red = triangle_en;


endmodule

`default_nettype wire
, register settings, FPGA code.
   x00	   x0198
   x01	   x106E
   x02	   x8052
   x03	   xF000
   x04	   xFFFF
   x05	   x3E60
   x06	   x2800
   x07	   xFFFF
   x08	   x0000
   x09	   x8000
   x0A	   x0000
   x0B	   x0000
   x0C	   x0400
   x0D	   x2400
   x0E	   x0400
   x0F	   x0400
   x10	   x3000
   x11	   x0000
   x12	   x0000
   x13	   x0000
   x14	   x1388
   x15	   x0000
   x16	   x3333
   x17	   x3333
   x18	   x4C78
   x19	   x2804
   x1A	   x1410
   x1B	   x0800
   x1C	   x0000
   x1D	   x0000
   x1E	   x1111
   x1F	   x1110
   x20	   x4401
   x22	   x1B1F
   x23	   x00FF
   x24	   x0000
   x25	   x7A7A
   x26	   xB6B6
   x27	   xEAEA
   x28	   x4545
   x29	   x1A1A
   x2A	   x1616
   x2B	   xAAAA
   x2C	   xC6C6
   x2D	   x0001
   x2E	   x0000
   x2F	   x0000
   x30	   x7530
   x7F	   x0004
CDCE62005 Registers
Freq:0.000000MHz
Address	Data
00		01400100
01		811C0101
02		81400102
03		C1400103
04		01040104
05		29F01B65
06		44AE0016
07		165294A7
08		20001808

  • Hello Ben,

    First of all, thank you for the thoroughness of the post.

    The DAC3482 are balun/transformer coupled. The balun/transformer are bandpass by nature and will filter out all the DC signal. Therefore, with a ramp pattern, you can only observe the transient steps. The settled DC in each step are basically filtered out and passed to ground.

    Therefore, what you are seeing is within expectation. Please see if you can set it up in DC coupled fashion. (i.e. resistor termination to ground). 

    -Kang

  • Hi Kang, thanks for getting back to me. I should have said that we have removed the BALUN (very hard; took a lot of heat!) and placed 0R in place. Thank you thought for thinking of that.

  • I have now solved the issue. For some reason I had to double buffer the clock in Verilog. It seems that the output buffer was driving a weak (50mV) LVDS signal into the DAC. The other FPGA clocks are strong (~200mV) but for some reason the FPGA did not like driving a clock straight to the buffer.