ADC and DAC on Red Pitaya Goal: Review the ADC and DAC digital - - PowerPoint PPT Presentation

adc and dac on red pitaya
SMART_READER_LITE
LIVE PREVIEW

ADC and DAC on Red Pitaya Goal: Review the ADC and DAC digital - - PowerPoint PPT Presentation

ADC and DAC on Red Pitaya Goal: Review the ADC and DAC digital interfaces. Understand the modifications to the Base Design to enable the ADC and DAC on the dev board. Meeting timing. Differences between 2017.2 and 2019.1.


slide-1
SLIDE 1

ADC and DAC on Red Pitaya

  • Goal:
  • Review the ADC and DAC digital interfaces.
  • Understand the modifications to the Base

Design to enable the ADC and DAC on the dev board.

  • Meeting timing.
  • Differences between 2017.2 and 2019.1.
  • These are things that can drive you crazy as a

designer.

  • Testing.
  • The board specific code was obtained

and modified from Red Pitaya Github and is intended for Vivado 2017.2.

slide-2
SLIDE 2

ADC Data Interface

slide-3
SLIDE 3

ADC Interface

  • Data is latched in FPGA/HDL with

always@(posedge ADCCLK) begin ADC_DA <= ADA; ADC_DB <= ADB; end Could use different clock sources No access to SPI for configuration.

slide-4
SLIDE 4

Timing Constraints

  • If (clock pad to CLK path) > (data pad to D + set_input_delay)

then there is a timing violation. _ _______________ _______________ ____________ DATA _X_______________X_______________X____________ |-------->| input delay _______ _______ ______ CLK _______/ \_______/ \_______/

slide-5
SLIDE 5

Timing Constraints

__ ____________ ____________ ________ DATA __XXXXX____________XXXXX____________XXXXX________ |------>| | input delay min | | |------------>| input delay max __ ________ ________ ____ CLK \_______/ \_______/ \_______/

slide-6
SLIDE 6

ADC Timing

  • Based on the info here I

would expect input delay to vary between 4 and 4.6 ns.

  • Actual value from board

manufacturer is 3.4 ns.

slide-7
SLIDE 7

ADC Clock Adjustments

slide-8
SLIDE 8

ADC Constraints

### ADC # ADC data set_property IOSTANDARD LVCMOS18 [get_ports {adc_da_i[*]}] set_property IOB TRUE [get_ports {adc_da_i[*]}] set_property IOSTANDARD LVCMOS18 [get_ports {adc_db_i[*]}] set_property IOB TRUE [get_ports {adc_db_i[*]}] # ADC A data set_property PACKAGE_PIN Y17 [get_ports {adc_da_i[0]}] ... set_property PACKAGE_PIN V16 [get_ports {adc_da_i[13]}] # ADC B data set_property PACKAGE_PIN R18 [get_ports {adc_db_i[0]}] ... set_property PACKAGE_PIN Y18 [get_ports {adc_db_i[13]}] set_property IOSTANDARD DIFF_HSTL_I_18 [get_ports adc_clk_i[*]] set_property PACKAGE_PIN U18 [get_ports adc_clk_i[1]] set_property PACKAGE_PIN U19 [get_ports adc_clk_i[0]] # Output ADC clock set_property IOSTANDARD LVCMOS18 [get_ports {adc_clk_o[*]}] set_property SLEW FAST [get_ports {adc_clk_o[*]}] set_property DRIVE 8 [get_ports {adc_clk_o[*]}] #set_property IOB TRUE [get_ports {adc_clk_o[*]}] set_property PACKAGE_PIN N20 [get_ports {adc_clk_o[0]}] set_property PACKAGE_PIN P20 [get_ports {adc_clk_o[1]}] # ADC clock stabilizer set_property IOSTANDARD LVCMOS18 [get_ports adc_cdcs_o] set_property PACKAGE_PIN V18 [get_ports adc_cdcs_o] set_property SLEW FAST [get_ports adc_cdcs_o] set_property DRIVE 8 [get_ports adc_cdcs_o] create_clock -period 8.000 -name adc_clk [get_ports adc_clk_i[1]] set_input_delay -clock adc_clk 3.400 [get_ports adc_da_i[*]] set_input_delay -clock adc_clk 3.400 [get_ports adc_db_i[*]]

slide-9
SLIDE 9

Data Format

  • Two’s complement is better for FPGA/DSP so

need to convert.

  • Can’t access SPI on the ADC so this is

done in HDL.

//Verilog code //------------------------------------------------------------------// // ADC -------------------------------------------------------------// //------------------------------------------------------------------// wire adc_clk; IBUFDS i_clk (.I (adc_clk_i[1]), .IB (adc_clk_i[0]), .O (adc_clk)); assign adc_clk_o = 2'b10; // generating ADC clock is disabled assign adc_cdcs_o = 1'b1; //ADC clock duty cycle stabilizer is enabled //sync adc input data to adc_clk reg signed [13:0] adc_db_raw; reg signed [13:0] adc_da_raw; always@(posedge adc_clk) begin adc_db_raw <= {~adc_db_i[13], adc_db_i[12:0]}; //convert offset binary to signed (two's complement) adc_da_raw <= {~adc_da_i[13], adc_da_i[12:0]}; //convert offset binary to signed (two's complement) end //------------------------------------------------------------------//

slide-10
SLIDE 10

Works in 18.1 but not 19.1?

  • Need to look at:
  • Timing Summary.
  • Implementation.

Min Delay Paths

  • Slack (VIOLATED) : -0.935ns (arrival time - required time)

Source: adc_da_i[13] Destination: adc_da_raw_reg[13]/D

  • Bits [12:0]
  • Delay is added
  • No violation
  • Bit [13]
slide-11
SLIDE 11

Work-Around

//Verilog code //------------------------------------------------------------------// // ADC -------------------------------------------------------------// //------------------------------------------------------------------// wire adc_clk; IBUFDS i_clk (.I (adc_clk_i[1]), .IB (adc_clk_i[0]), .O (adc_clk)); assign adc_clk_o = 2'b10; // generating ADC clock is disabled assign adc_cdcs_o = 1'b1; //ADC clock duty cycle stabilizer is enabled //sync adc input data to adc_clk reg [13:0] adc_db_raw; reg [13:0] adc_da_raw; always@(posedge adc_clk) begin adc_db_raw <= adc_db_i; adc_da_raw <= adc_da_i; end wire signed [13:0] adc_db; wire signed [13:0] adc_da; assign adc_db = {~adc_db_raw[13], adc_db_raw[12:0]}; //convert offset binary to signed (two's comp) assign adc_da = {~adc_da_raw[13], adc_da_raw[12:0]}; //convert offset binary to signed (two's comp) //------------------------------------------------------------------//

slide-12
SLIDE 12

DAC Data Interface

slide-13
SLIDE 13

DAC Data Interface

  • Need 250 MHz to generate IQWRT and IOCLK.
  • Need 125 MHz to generate DATA_IN and IQ_SEL.
  • Use a PLL and ADC clk.
slide-14
SLIDE 14

Constraints

### DAC # data set_property IOSTANDARD LVCMOS33 [get_ports {dac_dat_o[*]}] set_property SLEW SLOW [get_ports {dac_dat_o[*]}] set_property DRIVE 4 [get_ports {dac_dat_o[*]}] #set_property IOB TRUE [get_ports {dac_dat_o[*]}] set_property PACKAGE_PIN M19 [get_ports {dac_dat_o[0]}] set_property PACKAGE_PIN M20 [get_ports {dac_dat_o[1]}] set_property PACKAGE_PIN L19 [get_ports {dac_dat_o[2]}] set_property PACKAGE_PIN L20 [get_ports {dac_dat_o[3]}] set_property PACKAGE_PIN K19 [get_ports {dac_dat_o[4]}] set_property PACKAGE_PIN J19 [get_ports {dac_dat_o[5]}] set_property PACKAGE_PIN J20 [get_ports {dac_dat_o[6]}] set_property PACKAGE_PIN H20 [get_ports {dac_dat_o[7]}] set_property PACKAGE_PIN G19 [get_ports {dac_dat_o[8]}] set_property PACKAGE_PIN G20 [get_ports {dac_dat_o[9]}] set_property PACKAGE_PIN F19 [get_ports {dac_dat_o[10]}] set_property PACKAGE_PIN F20 [get_ports {dac_dat_o[11]}] set_property PACKAGE_PIN D20 [get_ports {dac_dat_o[12]}] set_property PACKAGE_PIN D19 [get_ports {dac_dat_o[13]}] # control set_property IOSTANDARD LVCMOS33 [get_ports dac_wrt_o] set_property SLEW FAST [get_ports dac_wrt_o] set_property DRIVE 8 [get_ports dac_wrt_o] set_property IOSTANDARD LVCMOS33 [get_ports dac_sel_o] set_property SLEW FAST [get_ports dac_sel_o] set_property DRIVE 8 [get_ports dac_sel_o] set_property IOSTANDARD LVCMOS33 [get_ports dac_clk_o] set_property SLEW FAST [get_ports dac_clk_o] set_property DRIVE 8 [get_ports dac_clk_o] set_property IOSTANDARD LVCMOS33 [get_ports dac_rst_o] set_property SLEW FAST [get_ports dac_rst_o] set_property DRIVE 8 [get_ports dac_rst_o] #set_property IOB TRUE [get_ports dac_*_o] set_property PACKAGE_PIN M17 [get_ports dac_wrt_o] set_property PACKAGE_PIN N16 [get_ports dac_sel_o] set_property PACKAGE_PIN M18 [get_ports dac_clk_o] set_property PACKAGE_PIN N15 [get_ports dac_rst_o]

slide-15
SLIDE 15

DAC Data Interface

  • Need 250 MHz to generate IQWRT
  • IQCLK nees -45 degree phase offset for 500 ps.
  • Need 125 MHz to generate DATA_IN and IQ_SEL.
  • Use a PLL and ADC clk.
  • Use ODDR SelectIO Resourse to interleave signals.
slide-16
SLIDE 16

PLL Instantiation

PLLE2_ADV #( .BANDWIDTH ("OPTIMIZED"), .COMPENSATION ("ZHOLD" ), .DIVCLK_DIVIDE ( 1 ), //VCO is at 125 x 8 = 1000.00 MHz (between 600 and 1200 MHz) .CLKFBOUT_MULT ( 8 ), .CLKFBOUT_PHASE ( 0.000 ), .CLKOUT0_DIVIDE ( 8 ), .CLKOUT0_PHASE ( 180.000 ), .CLKOUT0_DUTY_CYCLE ( 0.5 ), .CLKOUT1_DIVIDE ( 8 ), .CLKOUT1_PHASE ( 180.000 ), .CLKOUT1_DUTY_CYCLE ( 0.5 ), .CLKOUT2_DIVIDE ( 4 ), .CLKOUT2_PHASE ( 0.000 ), .CLKOUT2_DUTY_CYCLE ( 0.5 ), .CLKOUT3_DIVIDE ( 4 ), .CLKOUT3_PHASE (-45.000 ), .CLKOUT3_DUTY_CYCLE ( 0.5 ), .CLKOUT4_DIVIDE ( 4 ), // 4->250MHz .CLKOUT4_PHASE ( 0.000 ), .CLKOUT4_DUTY_CYCLE ( 0.5 ), .CLKOUT5_DIVIDE ( 4 ), .CLKOUT5_PHASE ( 0.000 ), .CLKOUT5_DUTY_CYCLE ( 0.5 ), .CLKIN1_PERIOD ( 8.000 ), .REF_JITTER1 ( 0.010 )) pll ( // Output clocks .CLKFBOUT (clk_fb ), .CLKOUT0 (adc_clk ), .CLKOUT1 (dac_clk_1x), .CLKOUT2 (dac_clk_2x), .CLKOUT3 (dac_clk_2p), // Input clock control .CLKFBIN (clk_fb ), .CLKIN1 (clk125 ), .CLKIN2 (1'b0 ), // Tied to always select the primary input clock .CLKINSEL (1'b1 ), // Ports for dynamic reconfiguration .DADDR (7'h0 ), .DCLK (1'b0 ), .DEN (1'b0 ), .DI (16'h0 ), .DO ( ), .DRDY ( ), .DWE (1'b0 ), // Other control and status signals .PWRDWN (1’b0 ), .RST (~FRSTN ));

slide-17
SLIDE 17

Port Description and ODDR

//14-bit 125 MHz Dual DAC

  • utput wire [13:0] dac_dat_o, // DAC combined data for channel A & B (DDR)
  • utput wire dac_wrt_o, // DAC write
  • utput wire dac_sel_o, // DAC channel select
  • utput wire dac_clk_o, // DAC clock
  • utput wire dac_rst_o, // DAC reset

... //------------------------------------------------------------------// // DAC -------------------------------------------------------------// //------------------------------------------------------------------// reg [13:0] dac_db = 0; reg [13:0] dac_da = 0; wire dac_rst; assign dac_rst = 1'b0; //generate a ramp for now always@(posedge dac_clk_1x) dac_db <= dac_db+1; always@(posedge dac_clk_1x) dac_da <= dac_da+1; // output signal rising falling clock enable reset ??? ODDR oddr_dac_clk (.Q(dac_clk_o ), .D1(1'b0 ), .D2(1'b1 ), .C(dac_clk_2p), .CE(1'b1), .R(1'b0 ), .S(1'b0)); ODDR oddr_dac_wrt (.Q(dac_wrt_o ), .D1(1'b0 ), .D2(1'b1 ), .C(dac_clk_2x), .CE(1'b1), .R(1'b0 ), .S(1'b0)); ODDR oddr_dac_sel (.Q(dac_sel_o ), .D1(1'b1 ), .D2(1'b0 ), .C(dac_clk_1x), .CE(1'b1), .R(dac_rst), .S(1'b0)); ODDR oddr_dac_rst (.Q(dac_rst_o ), .D1(dac_rst ), .D2(dac_rst ), .C(dac_clk_1x), .CE(1'b1), .R(1'b0 ), .S(1'b0)); ODDR oddr_dac_d13 (.Q(dac_dat_o[13]), .D1(dac_da[13]), .D2(dac_db[13]), .C(dac_clk_1x), .CE(1'b1), .R(dac_rst), .S(1'b0)); ODDR oddr_dac_d12 (.Q(dac_dat_o[12]), .D1(dac_da[12]), .D2(dac_db[12]), .C(dac_clk_1x), .CE(1'b1), .R(dac_rst), .S(1'b0)); ODDR oddr_dac_d11 (.Q(dac_dat_o[11]), .D1(dac_da[11]), .D2(dac_db[11]), .C(dac_clk_1x), .CE(1'b1), .R(dac_rst), .S(1'b0)); ODDR oddr_dac_d10 (.Q(dac_dat_o[10]), .D1(dac_da[10]), .D2(dac_db[10]), .C(dac_clk_1x), .CE(1'b1), .R(dac_rst), .S(1'b0)); ODDR oddr_dac_d09 (.Q(dac_dat_o[09]), .D1(dac_da[09]), .D2(dac_db[09]), .C(dac_clk_1x), .CE(1'b1), .R(dac_rst), .S(1'b0)); ODDR oddr_dac_d08 (.Q(dac_dat_o[08]), .D1(dac_da[08]), .D2(dac_db[08]), .C(dac_clk_1x), .CE(1'b1), .R(dac_rst), .S(1'b0)); ODDR oddr_dac_d07 (.Q(dac_dat_o[07]), .D1(dac_da[07]), .D2(dac_db[07]), .C(dac_clk_1x), .CE(1'b1), .R(dac_rst), .S(1'b0)); ODDR oddr_dac_d06 (.Q(dac_dat_o[06]), .D1(dac_da[06]), .D2(dac_db[06]), .C(dac_clk_1x), .CE(1'b1), .R(dac_rst), .S(1'b0)); ODDR oddr_dac_d05 (.Q(dac_dat_o[05]), .D1(dac_da[05]), .D2(dac_db[05]), .C(dac_clk_1x), .CE(1'b1), .R(dac_rst), .S(1'b0)); ODDR oddr_dac_d04 (.Q(dac_dat_o[04]), .D1(dac_da[04]), .D2(dac_db[04]), .C(dac_clk_1x), .CE(1'b1), .R(dac_rst), .S(1'b0)); ODDR oddr_dac_d03 (.Q(dac_dat_o[03]), .D1(dac_da[03]), .D2(dac_db[03]), .C(dac_clk_1x), .CE(1'b1), .R(dac_rst), .S(1'b0)); ODDR oddr_dac_d02 (.Q(dac_dat_o[02]), .D1(dac_da[02]), .D2(dac_db[02]), .C(dac_clk_1x), .CE(1'b1), .R(dac_rst), .S(1'b0)); ODDR oddr_dac_d01 (.Q(dac_dat_o[01]), .D1(dac_da[01]), .D2(dac_db[01]), .C(dac_clk_1x), .CE(1'b1), .R(dac_rst), .S(1'b0)); ODDR oddr_dac_d00 (.Q(dac_dat_o[00]), .D1(dac_da[00]), .D2(dac_db[00]), .C(dac_clk_1x), .CE(1'b1), .R(dac_rst), .S(1'b0)); //------------------------------------------------------------------//

slide-18
SLIDE 18

Loopback