日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

dds信号发生器 fpga实现

發布時間:2024/3/24 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 dds信号发生器 fpga实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

目錄

  • 原理
  • 實現

原理

dds信號發生器:以rom為核心,外圍控制輸出地址,達到輸出不同頻率和相位或者幅度的結構。(這里不考慮ad轉換和濾波)
這里以正弦信號為例,用專用軟件或者matlab生成一組正弦信號值的文件,這里使用quartus自帶的ip核,將文件讀入rom。
剩下的就是控制輸出地址來達到改變頻率、相位和幅度的目的。

實現

這里分為3個模塊
一個模塊實現按鍵消抖
一個模塊實現dds具體功能
一個模塊為rom例化

按鍵消抖模塊
使用2個按鍵,模塊消抖后輸出高電平有效

module key_debounce #(parameter KEY_W = 2,TIME_20MS = 1000_000)(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 ;//檢測下降沿//計數器 檢測到下降沿的時候,開啟計數器延時20msalways @(posedge clk or negedge rst_n)begin if(!rst_n)begin cnt <= 0;endelse 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;//檢測到下降沿的時候,拉高計數器計數使能信號,延時結束時,再拉低使能信號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結束的時鐘周期,輸出按鍵的狀態,若按下輸出一個周期的高脈沖,否則輸出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模塊

這里輸入一個設置按鈕和設置完成按鈕
按下設置按鈕,臨時頻率步長寄存器加1,
按下設置完成按鈕,將頻率步長加上臨時頻率步長寄存器的值
最后一個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;endelse 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; //參數定義 key_debounce #(.KEY_W(2)) u_key(.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調試

總結:原理不難,就是實現的時候思路不容易清晰,這里只實現了頻率的改變,還可以實現相位的改變,如在dds模塊中加一個相位寄存器就行,加一個相位按鈕,按下相位就加90度,其實就是加整個正弦數據地址的1/4,我這里是1024長度,就可以設置為256,幅度的話,可以將rom輸出的值直接改變。更復雜的話,我就不知道了。

總結

以上是生活随笔為你收集整理的dds信号发生器 fpga实现的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。