原創博客,轉(zhuǎn)载請注明(míng)出(chū)处:數字(zì)信(xìn)号(hào)处理專題(tí)(1)——DDS函(hán)數發(fà)生(shēng)器环(huán)路(lù)Demo - 沒(méi)落(là)騎士 - 博客園(yuán)
https://www.cnblogs.com/moluoqishi/p/9396734.html
一(yī)、前(qián)言
会(huì)FPGA硬(yìng)件(jiàn)描述語(yǔ)言、設計(jì)思(sī)想(xiǎng)和(hé)接口(kǒu)協議,掌握些基本(běn)的(de)算法是(shì)非(fēi)常重(zhòng)要(yào)的(de),因(yīn)此(cǐ)開(kāi)設本(běn)專題(tí)探讨些基于(yú)AD DA數字(zì)信(xìn)号(hào)处理系(xì)統的(de)一(yī)些簡單算法,在(zài)數字(zì)通(tòng)信(xìn) 信(xìn)号(hào)分(fēn)析與(yǔ)檢测等領域都会(huì)或(huò)多(duō)或(huò)少(shǎo)有(yǒu)應(yìng)用(yòng)。我(wǒ)们(men)還(huán)是(shì)從老(lǎo)生(shēng)常談的(de)DDS函(hán)數發(fà)生(shēng)器開(kāi)始,講解(jiě)DAC ADC基本(běn)使用(yòng)以(yǐ)及(jí)DDS算法原理與(yǔ)設計(jì)方(fāng)式。
二(èr)、設計(jì)預期(qī)
功能(néng):基于(yú)ROM的(de)頻率可(kě)調DDS正(zhèng)弦函(hán)數發(fà)生(shēng)器
DAC ADC型号(hào)與(yǔ)設計(jì)參數:DAC为(wèi)AD9708,更(gèng)新速率125MSPS,精度(dù)8bit;ADC为(wèi)AD9280,采樣(yàng)率32MSPS,精度(dù)8bit。由(yóu)于(yú)ADC采樣(yàng)率限制,設計(jì)使用(yòng)32MHZ頻率时(shí)鐘(zhōng)更(gèng)新與(yǔ)采樣(yàng)數據(jù),并将ROM深度(dù)定(dìng)義为(wèi)1024.
验(yàn)證手(shǒu)段(duàn):MATLAB産生(shēng)正(zhèng)弦函(hán)數,經(jīng)过(guò)8bit量(liàng)化(huà)後(hòu)存儲在(zài)ROM中(zhōng),數據(jù)經(jīng)过(guò)DAC 電(diàn)缆(lǎn) ADC环(huán)回(huí)到(dào)FPGA,ILA抓取(qǔ)ADC接收(shōu)數據(jù)波(bō)形,观察对(duì)比發(fà)送與(yǔ)接收(shōu)數據(jù)是(shì)否相近(jìn)。
三(sān)、DDS原理
这(zhè)里(lǐ)只(zhī)介紹DDS的(de)基本(běn)思(sī)想(xiǎng),關(guān)于(yú)詳细(xì)原理,請參考:【图(tú)文(wén)】DDS原理_百(bǎi)度(dù)文(wén)庫 https://wenku.baidu.com/view/11cfbf85a0116c175f0e4818.html
实際上(shàng),DDS的(de)核心(xīn)就(jiù)是(shì)将正(zhèng)弦或(huò)餘弦函(hán)數存儲在(zài)ROM中(zhōng),利用(yòng)相位累加特(tè)性(xìng)通(tòng)过(guò)采用(yòng)不(bù)同(tóng)的(de)步长对(duì)ROM尋址的(de)方(fāng)式産生(shēng)頻率可(kě)調正(zhèng)弦波(bō)。另(lìng)外(wài)需要(yào)注意(yì)産生(shēng)信(xìn)号(hào)的(de)頻率範圍要(yào)滿足奈奎斯特(tè)采樣(yàng)定(dìng)理,該定(dìng)理支持(chí)若想(xiǎng)无失真(zhēn)恢複原始信(xìn)号(hào),采樣(yàng)頻率必須大于(yú)等于(yú)信(xìn)号(hào)最(zuì)高(gāo)頻率成(chéng)分(fēn)的(de)2倍。反(fǎn)过(guò)来(lái)说(shuō):産生(shēng)信(xìn)号(hào)的(de)最(zuì)高(gāo)頻率小于(yú)等于(yú)最(zuì)高(gāo)頻率成(chéng)分(fēn)的(de)1/2.采樣(yàng)頻率即为(wèi)FPGA是(shì)时(shí)鐘(zhōng)頻率。为(wèi)防止信(xìn)号(hào)混疊,一(yī)般取(qǔ)最(zuì)高(gāo)頻率成(chéng)分(fēn)的(de)1/3.
四(sì)、MATLAB産生(shēng)正(zhèng)弦序列.coe文(wén)件(jiàn)及(jí)ROM初始化(huà)
MATLAB産生(shēng)頻率为(wèi)1/2*pi标(biāo)準正(zhèng)弦序列。验(yàn)證无誤後(hòu),在(zài)VIVADO中(zhōng)調用(yòng)Block Memory Generator IP核,配置为(wèi)單口(kǒu)ROM,使用(yòng)刚才産生(shēng)的(de)系(xì)數文(wén)件(jiàn)初始化(huà)ROM地(dì)址數據(jù)。
五(wǔ)、DAC ADC驅動(dòng)
該設計(jì)使用(yòng)的(de)DAC ADC均为(wèi)为(wèi)低速并口(kǒu)轉(zhuǎn)換芯片(piàn),无需配置,只(zhī)要(yào)FPGA給(gěi)出(chū)时(shí)鐘(zhōng)信(xìn)号(hào),并輸出(chū)/入(rù)并行數據(jù)即可(kě)。根(gēn)據(jù)AD9708 datasheet时(shí)序图(tú),其在(zài)时(shí)鐘(zhōng)上(shàng)升(shēng)沿采樣(yàng),故FPGA在(zài)輸出(chū)时(shí)鐘(zhōng)下(xià)降沿更(gèng)新數據(jù)可(kě)滿足建立與(yǔ)保持(chí)时(shí)間(jiān)要(yào)求。ADC同(tóng)樣(yàng)上(shàng)升(shēng)沿開(kāi)始更(gèng)新數據(jù),接收(shōu)端在(zài)时(shí)鐘(zhōng)是(shì)上(shàng)升(shēng)沿采集數據(jù),这(zhè)樣(yàng)每一(yī)时(shí)鐘(zhōng)周期(qī)可(kě)以(yǐ)采到(dào)上(shàng)一(yī)拍送出(chū)的(de)數據(jù)。
六(liù)、函(hán)數發(fà)生(shēng)器及(jí)测試工程設計(jì)
1 `timescale 1ns / 1ps
2
3 module sin_generator#(parameter FCW_W = 16,
4 DAC_W = 8)
5 (
6 input clk,//DAC采樣(yàng)时(shí)鐘(zhōng) 由(yóu)PLL産生(shēng)
7 input rst_n,
8
9 input [FCW_W-1:0] fcw,
10 output [DAC_W-1:0] dac_data,
11 output dac_clk
12 );
13
14 reg [ (FCW_W-1):0] sum ;
15 wire [9:0] addra;
16 //reg [9:0] addra;//地(dì)址测試信(xìn)号(hào)
17 wire ena;
18 wire [7:0] douta;
19
20 //相位累加器
21 //时(shí)鐘(zhōng)下(xià)降沿産生(shēng)數據(jù) DAC上(shàng)升(shēng)沿采樣(yàng)
22 always @(negedge clk or negedge rst_n )begin
23 if(rst_n==0) begin
24 sum <= (0) ;
25 end
26 else begin
27 sum <= (sum+fcw) ;
28 end
29 end
30
31 assign addra = sum[FCW_W-1-:10];
32
33 //rom地(dì)址测試
34 /*always @(posedge clk or negedge rst_n )begin
35 if(rst_n==0) begin
36 addra <= (0) ;
37 end
38 else begin
39 addra <= (addra+1) ;
40 end
41 end*/
42
43
44 blk_mem_gen_0 u_bram (
45 .clka(clk), // input wire clka
46 .ena(ena), // input wire ena
47 .addra(addra), // input wire [9 : 0] addra
48 .douta(douta) // output wire [7 : 0] douta
49 );
50 assign ena = 1'b1;
51 //輸出(chū)信(xìn)号(hào)
52 assign dac_data = douta;
53 assign dac_clk = ~clk;
54
55 endmodule
函(hán)數發(fà)生(shēng)器模块(kuài)由(yóu)輸入(rù)端口(kǒu)fcw數值确定(dìng)頻率控制字(zì)。测試工程頂层包(bāo)括差分(fēn)时(shí)鐘(zhōng)轉(zhuǎn)單端时(shí)鐘(zhōng)原語(yǔ),用(yòng)于(yú)産生(shēng)DAC ADC时(shí)鐘(zhōng)的(de)PLL 函(hán)數發(fà)生(shēng)器模块(kuài),生(shēng)成(chéng)特(tè)定(dìng)頻率控制字(zì)的(de)VIO IP核,還(huán)有(yǒu)接收(shōu)端ADC數據(jù)采樣(yàng)邏輯以(yǐ)及(jí)ILA 調試IP核。
> 1 `timescale 1ns / 1ps
2
3
4 module DDS_Demo_top
5 #(parameter AD_DA_W = 8)
6 (
7 input sys_clk_p,
8 input sys_clk_n,
9 input rst_n,
10
11 output [AD_DA_W-1:0] DAC_data,
12 output DAC_clk,
13
14 input [AD_DA_W-1:0] ADC_data,
15 output ADC_clk
16 );
17
18 localparam FCW_W = 16;
19
20 wire sys_clk_ibufg;
21 wire clk_dac,clk_adc;
22 reg [ (AD_DA_W-1):0] data_ad ;
23
24 wire [FCW_W-1 : 0] probe_out0;
25 wire [AD_DA_W*2-1:0] probe0;
26
27 //ADC接口(kǒu)信(xìn)号(hào)
28 //ADC在(zài)时(shí)鐘(zhōng)上(shàng)升(shēng)沿後(hòu)送出(chū)數據(jù),FPGA下(xià)一(yī)个(gè)上(shàng)升(shēng)沿采樣(yàng)
29 assign ADC_clk = clk_adc;
30
31 always @(posedge clk_adc or negedge rst_n )begin
32 if(rst_n==0) begin
33 data_ad <= (0) ;
34 end
35 else begin
36 data_ad <= (ADC_data) ;
37 end
38 end
39
40
41 /***************************************子模块(kuài)例化(huà)***************************************/
42 IBUFGDS #
43 (
44 .DIFF_TERM ("FALSE"),
45 .IBUF_LOW_PWR ("FALSE")
46 )
47 u_ibufg_sys_clk
48 (
49 .I (sys_clk_p),
50 .IB (sys_clk_n),
51 .O (sys_clk_ibufg)
52 );
53
54 clk_wiz_0 u_pll
55 (
56 // Clock out ports
57 .clk_out1(clk_dac), // output clk_out1
58 .clk_out2(clk_adc), // output clk_out2
59 // Status and control signals
60 .resetn(rst_n), // input resetn
61 .locked(), // output locked
62 // Clock in ports
63 .clk_in1(sys_clk_ibufg)); // input clk_in1
64
65 sin_generator#(.FCW_W(FCW_W),
66 .DAC_W(AD_DA_W))
67 u_sin_gen
68 (
69 .clk (clk_dac) ,//DAC采樣(yàng)时(shí)鐘(zhōng) 由(yóu)PLL産生(shēng)
70 .rst_n (rst_n) ,
71 .fcw (probe_out0) ,
72 .dac_data (DAC_data) ,
73 .dac_clk (DAC_clk) //由(yóu)clk_dac産生(shēng)
74 );
75
76 //debug cores
77 vio_0 u_vio (
78 .clk(clk_dac), // input wire clk
79 .probe_out0(probe_out0) // output wire [15 : 0] probe_out0
80 );
81
82 ila_0 u_ila (
83 .clk(clk_adc), // input wire clk
84 .probe0(probe0) // input wire [15:0] probe0
85 );
86
87 assign probe0[7:0] = DAC_data;
88 assign probe0[15:8] = ADC_data;
89
90 endmodule
最(zuì)後(hòu)添加引脚約束(shù)文(wén)件(jiàn):
> 1 #################################clock && reset###############################################
2 create_clock -period 5 [get_ports sys_clk_p]
3 set_property PACKAGE_PIN R4 [get_ports {sys_clk_p}]
4 set_property IOSTANDARD DIFF_SSTL15 [get_ports {sys_clk_p}]
5
6 set_property PACKAGE_PIN T6 [get_ports rst_n]
7 set_property IOSTANDARD LVCMOS15 [get_ports rst_n]
8
9 #####################DAC PIN connect J4 expansion interface##########################
10 set_property PACKAGE_PIN H14 [get_ports {DAC_clk}]
11 set_property IOSTANDARD LVCMOS33 [get_ports {DAC_clk}]
12
13 set_property PACKAGE_PIN J14 [get_ports {DAC_data[7]}]
14 set_property IOSTANDARD LVCMOS33 [get_ports {DAC_data[7]}]
15 set_property PACKAGE_PIN H15 [get_ports {DAC_data[6]}]
16 set_property IOSTANDARD LVCMOS33 [get_ports {DAC_data[6]}]
17 set_property PACKAGE_PIN J15 [get_ports {DAC_data[5]}]
18 set_property IOSTANDARD LVCMOS33 [get_ports {DAC_data[5]}]
19 set_property PACKAGE_PIN G13 [get_ports {DAC_data[4]}]
20 set_property IOSTANDARD LVCMOS33 [get_ports {DAC_data[4]}]
21 set_property PACKAGE_PIN H13 [get_ports {DAC_data[3]}]
22 set_property IOSTANDARD LVCMOS33 [get_ports {DAC_data[3]}]
23 set_property PACKAGE_PIN J21 [get_ports {DAC_data[2]}]
24 set_property IOSTANDARD LVCMOS33 [get_ports {DAC_data[2]}]
25 set_property PACKAGE_PIN J20 [get_ports {DAC_data[1]}]
26 set_property IOSTANDARD LVCMOS33 [get_ports {DAC_data[1]}]
27 set_property PACKAGE_PIN G16 [get_ports {DAC_data[0]}]
28 set_property IOSTANDARD LVCMOS33 [get_ports {DAC_data[0]}]
29
30 #####################ADC PIN connect J4 expansion interface##########################
31
32 set_property PACKAGE_PIN D22 [get_ports {ADC_clk}]
33 set_property IOSTANDARD LVCMOS33 [get_ports {ADC_clk}]
34
35 set_property PACKAGE_PIN G21 [get_ports {ADC_data[7]}]
36 set_property IOSTANDARD LVCMOS33 [get_ports {ADC_data[7]}]
37 set_property PACKAGE_PIN G22 [get_ports {ADC_data[6]}]
38 set_property IOSTANDARD LVCMOS33 [get_ports {ADC_data[6]}]
39 set_property PACKAGE_PIN H20 [get_ports {ADC_data[5]}]
40 set_property IOSTANDARD LVCMOS33 [get_ports {ADC_data[5]}]
41 set_property PACKAGE_PIN G20 [get_ports {ADC_data[4]}]
42 set_property IOSTANDARD LVCMOS33 [get_ports {ADC_data[4]}]
43 set_property PACKAGE_PIN J22 [get_ports {ADC_data[3]}]
44 set_property IOSTANDARD LVCMOS33 [get_ports {ADC_data[3]}]
45 set_property PACKAGE_PIN H22 [get_ports {ADC_data[2]}]
46 set_property IOSTANDARD LVCMOS33 [get_ports {ADC_data[2]}]
47 set_property PACKAGE_PIN K21 [get_ports {ADC_data[1]}]
48 set_property IOSTANDARD LVCMOS33 [get_ports {ADC_data[1]}]
49 set_property PACKAGE_PIN K22 [get_ports {ADC_data[0]}]
50 set_property IOSTANDARD LVCMOS33 [get_ports {ADC_data[0]}]
51
52 clk_pin
53
七(qī)、实验(yàn)結果(guǒ)分(fēn)析
依據(jù)之前(qián)的(de)參數和(hé)DDS信(xìn)号(hào)頻率公式,所(suǒ)生(shēng)成(chéng)正(zhèng)弦函(hán)數頻率最(zuì)好(hǎo)在(zài)32/2^16~32/3MHZ之內(nèi),使用(yòng)VIO改變(biàn)頻率控制字(zì)數值,观察ILA抓取(qǔ)的(de)發(fà)送與(yǔ)接收(shōu)數據(jù)模拟形式波(bō)形。任意(yì)給(gěi)出(chū)三(sān)組頻率範圍內(nèi)波(bō)形,頻率依次(cì)由(yóu)低到(dào)高(gāo)。
總(zǒng)體(tǐ)来(lái)講還(huán)是(shì)比較簡單。搭建好(hǎo)DAC ADC环(huán)路(lù),後(hòu)面(miàn)可(kě)以(yǐ)验(yàn)證些濾波(bō) 同(tóng)步算法,或(huò)者(zhě)做些數字(zì)頻率計(jì)、示波(bō)器之類(lèi)的(de)实用(yòng)設計(jì)。
- 沒(méi)落(là)騎士 - 博客園(yuán)








