概述
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进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。