生活随笔
收集整理的這篇文章主要介紹了
dds信号发生器 fpga实现
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
目錄
原理
dds信號發(fā)生器:以rom為核心,外圍控制輸出地址,達到輸出不同頻率和相位或者幅度的結(jié)構(gòu)。(這里不考慮ad轉(zhuǎn)換和濾波)
這里以正弦信號為例,用專用軟件或者matlab生成一組正弦信號值的文件,這里使用quartus自帶的ip核,將文件讀入rom。
剩下的就是控制輸出地址來達到改變頻率、相位和幅度的目的。
實現(xiàn)
這里分為3個模塊
一個模塊實現(xiàn)按鍵消抖
一個模塊實現(xiàn)dds具體功能
一個模塊為rom例化
按鍵消抖模塊
使用2個按鍵,模塊消抖后輸出高電平有效
module key_debounce input clk ,input rst_n ,input
[KEY_W-1:0
] key_in ,output reg
[KEY_W-1:0
] key_out //檢測到按下,輸出一個周期的高脈沖,其他時刻為0
);//信號定義reg
[19:0
] cnt
;wire add_cnt
;wire end_cnt
;reg add_flag
;reg
[KEY_W-1:0
] key_r0
;//同步按鍵輸入reg
[KEY_W-1:0
] key_r1
;//打拍wire
[KEY_W-1:0
] nedge
;//檢測下降沿//計數(shù)器 檢測到下降沿的時候,開啟計數(shù)器延時20msalways @
(posedge clk or negedge rst_n
)begin if
(!rst_n
)begin cnt
<= 0;end
else if
(add_cnt
)begin if
(end_cnt
)cnt
<= 0;else cnt
<= cnt +
1;end end assign add_cnt
= add_flag
;assign end_cnt
= add_cnt
&& cnt
== TIME_20MS-1
;//檢測到下降沿的時候,拉高計數(shù)器計數(shù)使能信號,延時結(jié)束時,再拉低使能信號always @
(posedge clk or negedge rst_n
)begin if
(!rst_n
)begin add_flag
<= 1'b0;end else if(nedge)begin add_flag <= 1'b1
;end
else if
(end_cnt
)begin add_flag
<= 1'b0;end end //同步按鍵輸入,并打一拍,以檢測下降沿always @(posedge clk or negedge rst_n)begin if(!rst_n)begin key_r0 <= {KEY_W{1'b1
}};key_r1
<= {KEY_W
{1'b1
}};end
else begin key_r0
<= key_in
;//同步key_r1
<= key_r0
;//打拍end endassign nedge
= ~key_r0
& key_r1
;//延時20ms結(jié)束的時鐘周期,輸出按鍵的狀態(tài),若按下輸出一個周期的高脈沖,否則輸出0always@
(posedge clk or negedge rst_n
)begin if
(~rst_n
)begin key_out
<= 0;end
else begin key_out
<= end_cnt?~key_r1:0
;end end endmodule
dds模塊
這里輸入一個設(shè)置按鈕和設(shè)置完成按鈕
按下設(shè)置按鈕,臨時頻率步長寄存器加1,
按下設(shè)置完成按鈕,將頻率步長加上臨時頻率步長寄存器的值
最后一個always塊一直將頻率賦值給相位控制器(實際上就是rom地址)
module dds
(input clk ,input rst_n ,input freq_set,input set_done,output
[9:0
] addr
);
//信號定義
reg
[7:0
] freq_tmp
;//頻率控制字
reg
[7:0
] freq
;reg
[9:0
] phas_add
;//相位累加器//頻率控制字變化
always@
(posedge clk or negedge rst_n
)beginif
(!rst_n
)beginfreq_tmp
<= 8'd0;endelse if(freq_set == 1'b1
)beginfreq_tmp
<= freq_tmp +
1'd1;endelse if(set_done)beginfreq_tmp <= 8'd1
;end
endalways@
(posedge clk or negedge rst_n
)beginif
(!rst_n
)beginfreq
<= 1'b1;endelse if(set_done)beginfreq <= freq + freq_tmp;end
endalways@(posedge clk or negedge rst_n)beginif(!rst_n)beginphas_add <= 1'b0
;end
else beginphas_add
<= phas_add + freq
;end
end
assign addr
= phas_add
;
endmodule
頂層
module dds_top
(input clk ,input rst_n ,input
[1:0
] key_in ,output
[7:0
] dout
);wire
[1:0
] key_out
;
//參數(shù)定義
key_debounce .clk
(clk
),.rst_n
(rst_n
),.key_in
(key_in
),.key_out
(key_out
) //檢測到按下,輸出一個周期的高脈沖,其他時刻為0
);
wire
[9:0
] addr
;
dds u_dds
(.clk
(clk
),.rst_n
(rst_n
),.freq_set
(key_out
[0] ),//頻率控制字.set_done
(key_out
[1] ),.addr
(addr
)
);rom1 rom1_inst
(.address
( addr
),.clock
( clk
),.q
( dout
));endmodule
signal tap調(diào)試
總結(jié):原理不難,就是實現(xiàn)的時候思路不容易清晰,這里只實現(xiàn)了頻率的改變,還可以實現(xiàn)相位的改變,如在dds模塊中加一個相位寄存器就行,加一個相位按鈕,按下相位就加90度,其實就是加整個正弦數(shù)據(jù)地址的1/4,我這里是1024長度,就可以設(shè)置為256,幅度的話,可以將rom輸出的值直接改變。更復雜的話,我就不知道了。
總結(jié)
以上是生活随笔為你收集整理的dds信号发生器 fpga实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。