概述
FPGA具有高度實時的特性。這里討論基于FPGA設計一款簡單的正弦信號發生器。
DDS原理
Direct Digital frequency Synthesis如下圖所示:

3. DAC原理
這里DAC采用TLC5620,下面分別給出DAC的原理圖和時序圖。


4. ROM文件的生成
ROM波形可以通過MIF或HEX文件保存在FPGA的ram或rom模塊中,也可以自己編寫HDL文件存儲。這里我們采用后者。
利用win-tc或matlab生產所需格式的函數數據,參考C代碼如下:
#include "stdio.h"
#include "math.h"
#definePi 3.1416
#defineDEPTH 256
#defineLENTH DEPTH/2
intmain()
{
FILE*fp;
int j;
unsigned char i= 0;
unsigned char x= 0;
if((fp=fopen("d:\\sin.txt","w"))==NULL)
{
printf("can't open this file..\n");
exit(0);
}
for(j=0;j<DEPTH;j++)
{
x=(int)(LENTH+LENTH*sin(2*Pi*i/DEPTH - 0.5*Pi));
fprintf(fp," 'd%d: data = 'h%x;\n",i,x);
i++;
}
fprintf(fp,"\n");
fclose(fp);
printf("success\n");
return 0;
}5. DAC控制邏輯設計
module dac_ctrl( input clk, input rst_n, output reg dac_clk, output reg dac_load, output reg dac_ldac, output reg dac_dat, input [7:0] rom_dat, output reg [7:0] rom_addr, input [7:0] freq_ctrl ); //===================================== //The frequency of clk is divided by N parameter bitsize = 4; parameter N = 20; reg [bitsize:0] cnt0; always @(posedge clk or negedge rst_n) begin if(!rst_n) begin cnt0 <= 0; dac_clk <= 0; end else begin if(cnt0 < (N/2-1)) cnt0 <= cnt0 + 1'b1; else cnt0 <= 0; if(cnt0==0 && cnt1 >=1 && cnt1 <= 4'hb) dac_clk <= ~ dac_clk; else dac_clk <= dac_clk; end end wire clk_1M; assign clk_1M = (cnt0 == 0)?1'b1:1'b0; //====================================== reg [3:0] cnt1; always @(posedge clk or negedge rst_n) begin if(!rst_n) cnt1 <= 0; else if(clk_1M) cnt1 <= cnt1 + 1'b1; else cnt1 <= cnt1; end reg [7:0] cnt2; always @(posedge clk or negedge rst_n) begin if(!rst_n) cnt2 <= 0; else if(cnt1 == 4'hf) if(cnt2 != freq_ctrl) cnt2 <= cnt2 + 1'b1; else cnt2 <= 0; else cnt2 <= cnt2; end always @(posedge clk or negedge rst_n) begin if(!rst_n) rom_addr <= 0; else if(clk_1M && cnt1==4'hf && cnt2 == freq_ctrl) rom_addr <= rom_addr + 1'b1; else rom_addr <= rom_addr; end always @(cnt1) begin case(cnt1) 4'h2: begin dac_dat <= 1'b0; dac_load <= 1'b1; dac_ldac <= 1'b1; end 4'h3: begin dac_dat <= 1'b0; dac_load <= 1'b1; dac_ldac <= 1'b1; end 4'h4: begin dac_dat <= 1'b1; dac_load <= 1'b1; dac_ldac <= 1'b1; end 4'h5: begin dac_dat <= rom_dat[7]; dac_load <= 1'b1; dac_ldac <= 1'b1; end 4'h6: begin dac_dat <= rom_dat[6]; dac_load <= 1'b1; dac_ldac <= 1'b1; end 4'h7: begin dac_dat <= rom_dat[5]; dac_load <= 1'b1; dac_ldac <= 1'b1; end 4'h7: begin dac_dat <= rom_dat[4]; dac_load <= 1'b1; dac_ldac <= 1'b1; end 4'h8: begin dac_dat <= rom_dat[3]; dac_load <= 1'b1; dac_ldac <= 1'b1; end 4'h9: begin dac_dat <= rom_dat[2]; dac_load <= 1'b1; dac_ldac <= 1'b1; end 4'ha: begin dac_dat <= rom_dat[1]; dac_load <= 1'b1; dac_ldac <= 1'b1; end 4'hb: begin dac_dat <= rom_dat[0]; dac_load <= 1'b1; dac_ldac <= 1'b1; end 4'hc: begin dac_dat <= 1'b0; dac_load <= 1'b0; dac_ldac <= 1'b1; end 4'hd: begin dac_dat <= 1'bx; dac_load <= 1'b1; dac_ldac <= 1'b0; end default: begin dac_dat <= 1'bx; dac_load <= 1'b1; dac_ldac <= 1'b1; end endcase end endmodule
6. 測試結果

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。