DDS与DA
信號(hào)發(fā)生器
信號(hào)發(fā)生器是一種能提供各種頻率、輸出電平的電信號(hào)的設(shè)備,又稱信號(hào)源或振蕩器。其在各種電信系統(tǒng)的振幅、頻率、傳輸特性等電參數(shù)以及元器件的特性與參數(shù)的測(cè)量中得到了廣泛的應(yīng)用。
直接數(shù)字式頻率合成器
( Direct Digital Synthesizer,DDS)是一項(xiàng)關(guān)鍵的數(shù)字化技術(shù),其將先進(jìn)
的數(shù)字處理理論與方法引入頻率合成技術(shù),通過(guò)數(shù)/模轉(zhuǎn)換器將一系列數(shù)字量形式的信號(hào)轉(zhuǎn)換成模擬
量形式的信號(hào)。
DA9709芯片
***DA9709芯片***是雙通道,位寬 8bit 的芯片,速率高達(dá) 125MSPS,能夠滿足常用信號(hào)發(fā)生器、濾波信號(hào)輸出等需求。
DAC 芯片與 FPGA 相連的信號(hào)為: DA_CLKA、 DA_CLKB、 DAC_DA7-0、 DAC_DB7-0、DA_WRA、 DA_WRB 、 DAC_MODE 和 DAC_SLEEP。如下圖:
DA9709操作時(shí)序
注意
輸出電壓與 DAC_DA/B 的值成線性反比例關(guān)系,最低電壓為 0.48V,最高為 2.2V。需要注意的是,此范圍的電壓是由于外圍硬件電路特性的原因?qū)е碌?#xff0c;不同電路對(duì)應(yīng)的電壓范圍有所
不同。
實(shí)驗(yàn)實(shí)現(xiàn)目標(biāo)
采用采樣率大于 100M 的示波器,將其連接到開發(fā)板上,控制 DA 輸出不同頻率的正弦波,示波器顯示出對(duì)應(yīng)波形。輸出方式如下:
連續(xù)輸出 2 個(gè)周期為 6.25MHz 的正弦波,每個(gè)正弦波輸出 8 個(gè)采樣點(diǎn);
連續(xù)輸出 2 個(gè)周期為 3.125MHz 的正弦波,每個(gè)正弦波輸出 16 個(gè)采樣點(diǎn);
連續(xù)輸出 2 個(gè)周期為 1.5625MHz 的正弦波,每個(gè)正弦波輸出 32 個(gè)采樣點(diǎn);
連續(xù)輸出 2 個(gè)周期為 781250Hz 的正弦波,每個(gè)正弦波輸出 64 個(gè)采樣點(diǎn);
連續(xù)輸出 2 個(gè)周期為 390625Hz 的正弦波,每個(gè)正弦波輸出 128 個(gè)采樣點(diǎn);
連續(xù)輸出 2 個(gè)周期為 195312.5Hz 的正弦波,每個(gè)正弦波輸出 128 個(gè)采樣點(diǎn)。
正弦波的最高電壓是 2.2V,最低電壓是 0.48V。
verilog代碼
下面是我自己編寫的,寫法與明德楊的不同,但是大致框架是一樣的。
module dac9709(input wire sys_clk ,input wire sys_rst_n ,output wire dac_clk_a ,output wire dac_mode ,output reg [7:0] dac_data ,output wire dac_sleep ,output wire dac_wr_en );reg [1:0] cnt0 ; reg [7:0] cnt1 ; reg [1:0] cnt2 ; reg [2:0] cnt3 ; reg [7:0] addr ; reg [7:0] sin_data ; reg [2:0] sel_gap ; reg [7:0] sel_point ;wire flag1 ; wire flag2 ; wire flag3 ;assign flag1 = (cnt0 == (sel_gap - 1'b1))?1'b1:1'b0; assign flag2 = (cnt1 == (sel_point - 1'b1))?1'b1:1'b0; assign flag3 = (cnt2 == 1'b1)?1'b1:1'b0;always@ (posedge sys_clk or negedge sys_rst_n)if (sys_rst_n == 1'b0)cnt0 <= 2'd0;else if(flag1)cnt0 <= 2'd0;else cnt0 <= cnt0 + 1'b1;always@ (posedge sys_clk or negedge sys_rst_n)if (sys_rst_n == 1'b0)cnt1 <= 8'd0;else if(flag2)cnt1 <= 8'd0;else if(flag1)cnt1 <= cnt1 + 1'b1;elsecnt1 <= cnt1;always@ (posedge sys_clk or negedge sys_rst_n)if (sys_rst_n == 1'b0)cnt2 <= 2'd0;else if ((flag3)&&(flag2))cnt2 <= 2'd0;else if(flag2)cnt2 <= cnt2 + 1'b1; elsecnt2 <= cnt2;always @ (posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)cnt3 <= 3'd0;else if ((cnt3 == 3'd5)&&(flag3)&&(flag2))cnt3 <= 3'd0;else if ((flag3)&&(flag2))cnt3 <= cnt3 + 1'b1;elsecnt3 <= cnt3;always @ (*)begincase (cnt3)0:beginsel_gap <= 2'd1;sel_point <= 8'd8;end1:beginsel_gap <= 2'd1;sel_point <= 8'd16;end2:beginsel_gap <= 2'd1;sel_point <= 8'd32;end3:beginsel_gap <= 2'd1;sel_point <= 8'd64;end4:beginsel_gap <= 2'd1;sel_point <= 8'd128;end5:beginsel_gap <= 2'd2;sel_point <= 8'd128;enddefault : beginsel_gap <= 2'd1;sel_point <= 8'd8;endendcaseendalways @ (*) begincase (cnt3)0:addr = cnt1 *16;1:addr = cnt1 *8;2:addr = cnt1 *4;3:addr = cnt1 *2;4:addr = cnt1 *1;5:addr = cnt1 *1;default : addr = cnt1 *1;endcase endalways @ (*) begincase(addr)0 :sin_data<= 8'h7f;1 :sin_data<= 8'h85;2 :sin_data<= 8'h8c;3 :sin_data<= 8'h92;4 :sin_data<= 8'h98;5 :sin_data<= 8'h9e;6 :sin_data<= 8'ha4;7 :sin_data<= 8'haa;8 :sin_data<= 8'hb0;9 :sin_data<= 8'hb6;10 :sin_data<= 8'hbb;11 :sin_data<= 8'hc1;12 :sin_data<= 8'hc6;13 :sin_data<= 8'hcb;14 :sin_data<= 8'hd0;15 :sin_data<= 8'hd5;16 :sin_data<= 8'hda;17 :sin_data<= 8'hde;18 :sin_data<= 8'he2;19 :sin_data<= 8'he6;20 :sin_data<= 8'he9;21 :sin_data<= 8'hed;22 :sin_data<= 8'hf0;23 :sin_data<= 8'hf3;24 :sin_data<= 8'hf5;25 :sin_data<= 8'hf8;26 :sin_data<= 8'hf9;27 :sin_data<= 8'hfb;28 :sin_data<= 8'hfd;29 :sin_data<= 8'hfe;30 :sin_data<= 8'hfe;31 :sin_data<= 8'hff;32 :sin_data<= 8'hff;33 :sin_data<= 8'hff;34 :sin_data<= 8'hfe;35 :sin_data<= 8'hfe;36 :sin_data<= 8'hfd;37 :sin_data<= 8'hfb;38 :sin_data<= 8'hf9;39 :sin_data<= 8'hf8;40 :sin_data<= 8'hf5;41 :sin_data<= 8'hf3;42 :sin_data<= 8'hf0;43 :sin_data<= 8'hed;44 :sin_data<= 8'he9;45 :sin_data<= 8'he6;46 :sin_data<= 8'he2;47 :sin_data<= 8'hde;48 :sin_data<= 8'hda;49 :sin_data<= 8'hd5;50 :sin_data<= 8'hd0;51 :sin_data<= 8'hcb;52 :sin_data<= 8'hc6;53 :sin_data<= 8'hc1;54 :sin_data<= 8'hbb;55 :sin_data<= 8'hb6;56 :sin_data<= 8'hb0;57 :sin_data<= 8'haa;58 :sin_data<= 8'ha4;59 :sin_data<= 8'h9e;60 :sin_data<= 8'h98;61 :sin_data<= 8'h92;62 :sin_data<= 8'h8c;63 :sin_data<= 8'h85;64 :sin_data<= 8'h7f;65 :sin_data<= 8'h79;66 :sin_data<= 8'h72;67 :sin_data<= 8'h6c;68 :sin_data<= 8'h66;69 :sin_data<= 8'h60;70 :sin_data<= 8'h5a;71 :sin_data<= 8'h54;72 :sin_data<= 8'h4e;73 :sin_data<= 8'h48;74 :sin_data<= 8'h43;75 :sin_data<= 8'h3d;76 :sin_data<= 8'h38;77 :sin_data<= 8'h33;78 :sin_data<= 8'h2e;79 :sin_data<= 8'h29;80 :sin_data<= 8'h24;81 :sin_data<= 8'h20;82 :sin_data<= 8'h1c;83 :sin_data<= 8'h18;84 :sin_data<= 8'h15;85 :sin_data<= 8'h11;86 :sin_data<= 8'he;87 :sin_data<= 8'hb;88 :sin_data<= 8'h9;89 :sin_data<= 8'h6;90 :sin_data<= 8'h5;91 :sin_data<= 8'h3;92 :sin_data<= 8'h1;93 :sin_data<= 8'h0;94 :sin_data<= 8'h0;95 :sin_data<= 8'h0;96 :sin_data<= 8'h0;97 :sin_data<= 8'h0;98 :sin_data<= 8'h0;99 :sin_data<= 8'h0;100 :sin_data<= 8'h1;101 :sin_data<= 8'h3;102 :sin_data<= 8'h5;103 :sin_data<= 8'h6;104 :sin_data<= 8'h9;105 :sin_data<= 8'hb;106 :sin_data<= 8'he;107 :sin_data<= 8'h11;108 :sin_data<= 8'h15;109 :sin_data<= 8'h18;110 :sin_data<= 8'h1c;111 :sin_data<= 8'h20;112 :sin_data<= 8'h24;113 :sin_data<= 8'h29;114 :sin_data<= 8'h2e;115 :sin_data<= 8'h33;116 :sin_data<= 8'h38;117 :sin_data<= 8'h3d;118 :sin_data<= 8'h43;119 :sin_data<= 8'h48;120 :sin_data<= 8'h4e;121 :sin_data<= 8'h54;122 :sin_data<= 8'h5a;123 :sin_data<= 8'h60;124 :sin_data<= 8'h66;125 :sin_data<= 8'h6c;126 :sin_data<= 8'h72;127 :sin_data<= 8'h79; endcase endalways @ (posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)dac_data <= 8'd0;elsedac_data <= 255 - sin_data;assign dac_mode = 1'b1; assign dac_clk_a = ~ sys_clk; assign dac_sleep = 1'b0; assign dac_wr_en = dac_clk_a;endmodule仿真測(cè)試代碼
`timescale 1ns/1nsmodule dac_9709_tb();reg sys_clk ; reg sys_rst_n ;wire dac_clk_a ; wire dac_mode ; wire[7:0] dac_data ; wire dac_sleep ; wire dac_wr_en ;initial beginsys_clk = 1'b1;sys_rst_n = 1'b0;#21sys_rst_n = 1'b1;#100000$stop; endalways #10 sys_clk = ~sys_clk;dac9709 dac9709_inst( .sys_clk (sys_clk ), .sys_rst_n (sys_rst_n ),.dac_clk_a (dac_clk_a ), .dac_mode (dac_mode ), .dac_data (dac_data ), .dac_sleep (dac_sleep ), .dac_wr_en (dac_wr_en ));endmoduleMATLAB產(chǎn)生波形數(shù)據(jù)
上圖正弦波的數(shù)據(jù)可以通過(guò)matlab產(chǎn)生:
輸入以下命令:生成文件,復(fù)制即可。
modelsim仿真結(jié)果
大家不懂的可以與我交流!!!
***注:以上內(nèi)容借鑒了《明德楊至簡(jiǎn)設(shè)計(jì)原理與應(yīng)用》***總結(jié)
- 上一篇: re正则表达式匹配多行文本
- 下一篇: Graph Convolutional