FPGA學習(一)——產生頻率可控的正弦波
2018.5.17更新如下
作為小透明,沒想到隨手一寫的學習過程也能被看見,看到有人點贊也還是很高興的,希望能以後自己忘了,還能來看懂,如果對大家能有所幫助,那就再好不過了。
對於輸出的正弦波周期有兩種演算法,在這裡記錄一下。
因為和昨天使用的不是同一個文件,所以名稱會和昨天的不一樣,不過原理一樣。
另外,在模擬的時候可以不用添加約束文件,只需要模擬時可以直接跳過,如果需要下載進板子的話就必須要寫了。下一篇會介紹。
1.使用DDS輸出的最高位去計算,具體操作如圖
點擊兩次上圖3的圖標
可能會覺得頻率控制字可以控制輸出波形的頻率,而輸出位寬又可以計算輸出波形周期,那改變輸出波形會影響什麼呢?會影響輸出波形周期嗎?答案是不會。
具體看圖,我將輸出位寬改為10位的模擬結果。
輸出位寬影響的是輸出波形的幅度(0^◇^0)/
了解DDS的原理就明白了。
2.第二種就是昨天解釋原理時用頻率控制字控制輸出頻率時,fre_word取1的值。
具體演算法見原答案。
兩種區別就是一個取最高位,一個取最低位,剛開始容易理不清。
原答案如下
信號調製和解調功能。寫下其中過程當做自己的學習記錄吧。本篇講的是如何產生一個正弦波。
- 使用的軟體是Vivado 2016.4
- 實驗室板卡是Nexys Video
1.原理說明
採用的是自帶DDS IP核,DDS直接數字式頻率合成器(Direct Digital Synthesizer),相信所有人看到這個名字就覺得不會陌生。
DDS由頻率控制字(Frequency Control Word)寄存器、相位累加器(Phase Accumulator)和正餘弦查找表(Sine/Cosine LUT)三部分組成,通過控制相位累加器的位寬和查找表的位寬,可以實現不同頻率和動態範圍的正弦信號的產生。
關於DDS是如何產生我們需要的波形信號可以查看這篇文章:
用FPGA實現DDS任意波形發生器 | 電子創新網賽靈思中文社區而我們現在不用關心太多原理,經過實驗的過程,自然就能明白其工作原理。
我們只需要知道如何控制其輸出頻率就行了,首先記住兩個術語(jargon):
a. 相位累加器:Phase = Phase + fre_word,可以暫且理解為i = i + 1一樣的東西。
b. 頻率控制字:fre_word,這個東西的值直接影響輸出信號的頻率。
我們的輸出頻率就是由fre_word來控制。
具體怎麼算的呢?
DDS核頻率解析度計算公式如下:
其中Δθ就是我們的頻率控制字取值後文用fre_word表示,Bθ(n)是相位累加器位寬後文用B表示,fclk為DDS工作時鐘。
頻率解析度就是當Δθ=1時的fout。
先假如我們需要的信號頻率範圍:1M-10MHz,解析度0.01MHz。
取Δθ=1,fout=0.01MHz,B=10bit,我們可得DDS工作時鐘fclk=10.24MHz。
到這裡我們就知道,產生一個正弦波信號需要2部分即可:
- 時鐘分頻器(因為我們的軟體系統時鐘為100MHz,而我們算出的DDS工作時鐘為10.24MHz)
- DDS IP核
2.具體操作過程
打開vivado,新建工程
給工程命名,路徑不能出現中文
如圖勾選,我們後面自己建源文件
選擇板卡(這個板卡需要在安裝後自己添加了才會有),點擊接下來的next,finish。
添加源文件
取名
現在不用添加管腳,點擊ok,yes即可
添加IP 核,找到DDS,藍色的都是一樣的,隨便選一個雙擊
命名,選擇dds工作時鐘10.24MHz,選擇使用硬體參數,位寬根據前面計算的結果填寫(相位位寬就是我們的頻率控制字位寬,而輸出位寬影響ROM表深度 (大小為 表示輸出的正弦波一個周期的採樣值,因為DDS是數字信號經DA輸出模擬信號))。
選擇可編程(因為由fre_word控制),輸出sine,不需要觀測相位輸出
因為是10位,改為0000000001
查看summary,可知最小頻率為0.01MHz,點擊ok
點擊生成
用時鐘管理核生成時鐘分頻模塊,步驟如圖,不再描述
咦,,,,好像點擊圖片可以直接描述,第一次用知乎寫,還不會。。。。後面的圖片描述在圖片下方的描述區。。。
3.代碼只要所建名字一樣,可以直接複製使用
主程序`timescale 1ns / 1ps//////////////////////////////////////////////////////////////////////////////////// Company: // Engineer: // // Create Date: 2018/05/16 18:44:03// Design Name: // Module Name: ZXB// Project Name: // Target Devices: // Tool Versions: // Description: // // Dependencies: // // Revision:// Revision 0.01 - File Created// Additional Comments:// //////////////////////////////////////////////////////////////////////////////////module ZXB( input sysclk, input [9:0] fw_z//用vio就注釋這一句 ); wire CLK_10240K; ZXB_CLK ZXB_CLKinst ( // Clock out ports .clk_out1(CLK_10240K), // output clk_out1 // Clock in ports .clk_in1(sysclk)); // wire [9:0] fw_z; //用模擬就注釋這一句 wire [9:0] fre_word; wire fre_word_en; assign fre_word = fw_z; assign fre_word_en = 1b1; wire [7:0] dds_out; ZXB_DDS ZXB_DDSinst ( .aclk(CLK_10240K), // input wire aclk .s_axis_config_tvalid(fre_word_en), // input wire s_axis_config_tvalid .s_axis_config_tdata(fre_word), // input wire [15 : 0] s_axis_config_tdata .m_axis_data_tvalid(m_axis_data_tvalid), // output wire m_axis_data_tvalid .m_axis_data_tdata(dds_out) // output wire [7 : 0] m_axis_data_tdata );endmodule
頂層約束文件
set_property -dict {PACKAGE_PIN R4 IOSTANDARD LVCMOS33} [get_ports sysclk]#############################https://mp.weixin.qq.com/s/3WoAO4aHYTqTWLTnF56zMA關於時序約束#############################create_clock -period 10.000 -name sysclk -waveform {0.000 5.000} [get_ports sysclk]
模擬文件
`timescale 1ns / 1ps//////////////////////////////////////////////////////////////////////////////////// Company: // Engineer: // // Create Date: 2018/05/16 19:29:18// Design Name: // Module Name: ZXB_tb// Project Name: // Target Devices: // Tool Versions: // Description: // // Dependencies: // // Revision:// Revision 0.01 - File Created// Additional Comments:// //////////////////////////////////////////////////////////////////////////////////module ZXB_tb( ); reg clk;// wire [7:0] data; reg [9:0] fw_z; ZXB dut( .sysclk(clk), .fw_z(fw_z), // .led(data)); // 初始化 initial begin clk = 0; fw_z = 10b0000000001; end //產生100MHz時鐘信號 always begin #5 clk = ~clk; endendmodule
4.本來應該添上VIO和ILA的,不過沒有板子在,寫了也用不了,就不寫了,大概和這個差不多,主要區別就是VIO是外部板子給信號,而模擬就是軟體假裝的,所以在主程序中會有所不同。會Verilog就懂了。
5.第一次寫,很簡單的一個功能,居然寫了這麼多,說明理解還不是很到位,表達也不是很簡潔明了,ε=(′ο`*)))唉溜了溜了
推薦閱讀:
※mBlock & Arduino(9)舵機(Servo motor)控制
※學習單片機的幾個誤區
※ARM和單片機的區別
※精簡封裝技巧5----函數指針_鬧鐘
※eM4 OS設計中的可重入性
TAG:現場可編輯邏輯門陣列FPGA | 單片機 | 調幅AM |