DDS block diagram
Experimental Manuals FII-PRA040 Risc-V

DAC9767 DDS Signal Source Experiment, AD9767 datasheet and use the AD9767 to design a signal source that can generate sine, square, triangle, and sawtooth waves – FII-PRA040 Altera Risc-V Experiment 19

Experiment 19 DAC9767 DDS Signal Source Experiment

19.1 Experiment Objective

  1. Learn about DDS (Direct Digital Synthesizer) related theoretical knowledge.
  2. Read the AD9767 datasheet and use the AD9767 to design a signal source that can generate sine, square, triangle, and sawtooth waves.

19.2 Experiment Implement

  1. Learn about DDS theoretical knowledge.
  2. On the basis of understanding the principle of DDS, combined with the theoretical knowledge, use AD9767 module and development board to build a signal source whose waveform, amplitude and frequency can be adjusted. (There are no specific requirements for the adjustment of waveform, amplitude, and frequency here, as long as the conversion can be adjusted by pressing a button).

19.3 Experiment

19.3.1 DDS Introduction

The DDS technology is based on the Nyquist sampling theorem. Starting from the phase of the continuous signal, the sine signal is sampled, encoded, and quantized to form a sine function table, which is stored in the ROM. During synthesis, phase increment is changed by changing the frequency word of the phase accumulator. Phase increment is what is called step size. The difference in phase increment results in different sampling points in a cycle. When the clock frequency, or the sampling frequency does not change, the frequency is changed by changing the phase. The block diagram is shown in Figure 19.1.

Figure 19.1 DDS block diagram

19.3.2 AD9767 Configuration Introduction


The AD9767 module uses ADI’s AD9767 DAC chip, which is a 14-bit, 125MSPS conversion rate high-performance DAC device. It supports the IQ output mode and can be used in the communications.

AD9767 interface timing requirements. As shown in Figure 19.2 below, when the rising edge of the clock comes, the data must remain stable for ts time. After the rising edge of the clock, the data must remain stable for th to be correct.


Figure 19.2 9767 interface timing diagram

19.3.3 Waveform Memory File Configuration


The waveform storage area file is dds_4096x10b_wave_init.coe. For the specific making process, refer to the use of the *.coe file in the experiment 9. The file containing the waveform information is stored in the ROM. After the project file is programmed into the FPGA, the FPGA directly reads the waveform information from the ROM and sends it to the AD9767 interface, and then outputs the corresponding waveform on the AD9767 module. The waveform storage is as shown in Figure 19.3.

Figure 19.3 Wave file storage

19.3.4 Program Design

1.The main program includes waveform selection, mode selection, frequency adjustment, and amplitude adjustment. The specific code is as follows:

module dac_9767_test(

input wire sys_clk_50m,

input wire rst_n,

(*mark_debug=”true”*) output mode,

output wire dac_clk,

output wire led ,

input wire mode_adjust,

input wire a_adjust,

input wire f_adjust,

input wire wave_adjust,

output reg [13:0] data_out

);

wire [9:0] douta ;

wire clk_50m ;

BUFG BUFG_inst (

.O(clk_50m),

.I(sys_clk_50m)

);

wire locked ;

wire clk_100m ;

pll_50_100 pll_50_100_inst

(

.clk_out1(clk_100m),

.clk_out2(dac_clk), //nclk_100m

.reset(0),

.locked(locked),

.clk_in1(clk_50m));

reg rst_n_g = 0 ;

always @ (posedge clk_100m)

rst_n_g<=locked &rst_n ;

wire A_ctrl ;

wire F_ctrl ;

wire wave_switch ;

wire mode_ctrl ;

reg [1:0] base_addr =0 ;

reg [3:0] base_A =0 ;

reg [1:0] a_st =0 ;

always @ (posedge clk_100m , negedge rst_n_g )

begin

if (~rst_n_g)

base_addr <=0;

else if (wave_switch)

base_addr <= base_addr +1 ;

else base_addr <= base_addr ;

end

always @ (posedge clk_100m , negedge rst_n_g )

begin

if (~rst_n_g)

begin

base_A <=1;

a_st <=0;

end

else begin case (a_st)

0: begin

base_A <=8;

a_st <=1;

end

1: begin

if (A_ctrl)

begin

a_st<=2 ;

base_A <=11;

end

else begin

a_st<=1 ;

base_A <=8;

end

end

2: begin

if (A_ctrl)

begin

a_st<=3;

base_A <=15;

end

else begin

a_st<=2;

base_A <=11;

end

end

3: begin

if (A_ctrl)

begin

a_st<= 1;

base_A <=8;

end

else begin

a_st<=3 ;

base_A <=15;

end

end

default :begin

base_A <=1;

a_st <=0;

end

endcase

end

end

always @ (posedge clk_100m , negedge rst_n_g )

begin

if (~rst_n_g)

data_out <=0 ;

else data_out<= douta * base_A ;

end

reg [9:0] addr_r =0;

reg [9:0] addr_temp_F =1 ;

reg [3:0] f_st =0 ;

always @ (posedge clk_100m , negedge rst_n_g )

begin

if (~rst_n_g)

begin

addr_temp_F <= 0;

f_st <=0 ;

end

else begin case (f_st)

0 : begin

addr_temp_F <= 0 ;

f_st <= 1 ;

end

1 : begin

addr_temp_F <= 1 ;

if (F_ctrl)

f_st <= 2 ;

end

2 : begin

addr_temp_F <= 2 ;

if (F_ctrl)

f_st <= 3 ;

end

3 : begin

addr_temp_F <= 3 ;

if (F_ctrl)

f_st <= 4 ;

end

4 : begin

addr_temp_F <= 4 ;

if (F_ctrl)

f_st <= 5 ;

end

5 : begin

addr_temp_F <= 5 ;

if (F_ctrl)

f_st <= 6 ;

end

6 : begin

addr_temp_F <= 6 ;

if (F_ctrl)

f_st <= 7 ;

end

7 : begin

addr_temp_F <= 8 ;

if (F_ctrl)

f_st <= 1 ;

end

default : f_st <= 1 ;

endcase

end

end

always @ (posedge clk_100m , negedge rst_n_g )

begin

if (~rst_n_g)

addr_r <=0;

else

addr_r <=addr_r+1+addr_temp_F ;

end

(*mark_debug=”true”*)reg [11:0] addra=0 ;

always @ (posedge clk_100m , negedge rst_n_g )

begin

if (~rst_n_g)

addra <=0 ;

else addra<={base_addr, addr_r };

end

reg mode_r=0;

always @ (posedge clk_100m , negedge rst_n_g )

begin

if (~rst_n_g)

mode_r <=0 ;

else if (mode_ctrl) mode_r <=~mode_r;

else mode_r <= mode_r ;

end

assign mode=mode_r ;

assign led= ~mode_r ;

key_process (

.clk (clk_100m ) ,

.rst_n (rst_n_g ) ,

.key_switch (wave_adjust) ,

.key_adjust (a_adjust ) ,

.key_add (f_adjust ) ,

.key_sub (mode_adjust) ,

.flag_switch (wave_switch) ,

.flag_adjust (A_ctrl ) ,

.flag_add (F_ctrl ) ,

.flag_sub (mode_ctrl )

);

rom_dds_4096_10 rom_dds_4096_10_inst (

.clka(clk_100m), // input wire clka

.addra(addra), // input wire [11 : 0] addra

.douta(douta) // output wire [9 : 0] douta

);

endmodule

19.4 Experiment Verification

1. Pin assignment

Signal Name Port Description Network Name FPGA Pin
sys_clk_50m System clock C10_50MCLK G21
mode 9767 mode control IO24 AA14
wave_adjust Waveform selection key2 V5
a_adjust Amplitude selection key3 Y6
f_adjust Frequency selection key4 AB4
mode_adjust Mode selection key6 AA4
led Mode indicator light LED0 J5
dac_clk 9767 driving clock IO28 W13
rst_n System reset key1 Y4
data_out[0] AD9767 data bus IO1 U16
data_out[1] AD9767 data bus IO0 AA15
data_out[2] AD9767 data bus IO5 T16
data_out[3] AD9767 data bus IO4 V16
data_out[4] AD9767 data bus IO3 U17
data_out[5] AD9767 data bus IO6 R16
data_out[6] AD9767 data bus IO2 AB20
data_Out[7] AD9767 data bus IO7 AA20
data_out[8] AD9767 data bus IO29 AA13
data_out[9] AD9767 data bus IO30 Y12
data_out[10] AD9767 data bus IO31 Y13
data_out[11] AD9767 data bus IO27 AB13
data_out[12] AD9767 data bus IO26 AB14
data_out[13] AD9767 data bus IO25 R14

2.Board verification

After the FPGA development board is programmed, press the right key (mode), and the mode indicator led0 lights up.

Then waveform can be chosen according to UP key (waveform selection), RETURN key (amplitude selection), LEFT key (frequency selection). (This experiment is only to introduce the theoretical knowledge of DDS and verify its correctness. Therefore, only four types of waveforms are set, which are sine wave, square wave, triangle wave, and sawtooth wave. The frequency and amplitude are also randomly set.) Figure 19.4 below shows four waveforms of the oscilloscope measuring the output of the 9767 module.

Figure 19-4a Sine wave Figure 19-4b Square wave

Figure 19-4c Triangle wave Figure 19-4d Sawtooth wave

AD9767 PMOD Interface Development board high speed DA — FII-BD9767

Related posts

Leave a Comment