FPGA学习之 直接数字频率合成器(DDS)

Posted 满足没有

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了FPGA学习之 直接数字频率合成器(DDS)相关的知识,希望对你有一定的参考价值。

FPGA学习之 直接数字频率合成器(DDS)

DDS的原理:

直接数字频率合成器(Direct Digital Synthesizer, DDS)是一种把数字信号通过 D/A 转换成模拟信号的数字合成技术。它有查表法和计算法两种基本合成方法。由于查表法结构简单,只需要在 ROM中存放不同相位对应的幅度序列,然后通过相位累加器的输出对其寻址,经过数/模转换和低通滤波(LPF)输出便可以得到所需要的模拟信号。DDS系统主要有相位累加器、波形存储器、数模(D/A)转换器和低通滤波器等四大结构组成

这里,我们只通过改变频率控制字来达到控制波形频率的目的。

原理图:

代码部分:
顶层:

module dds_top(

    input               clk     ,
    input               rst_n   ,

    input   [1:0]       key_in  ,

    output  [7:0]       dout     //dds的输出

);

//信号定义
    wire    [1:0]       key_out     ;
	 wire					   clk_100m		;
	 wire						locked		;
	 
	 
//模块例化
    key_debounce /*#(.KEY_W(2)) */u_key(
	.clk		(clk	    ),
	.rst_n	    (rst_n      ),
	.key_in 	(key_in     ),
	.key_out	(key_out    ) //检测到按下,输出一个周期的高脉冲,其他时刻为0
);

    DDS u_DDS(
    .clk		(clk_100m   ),
	.rst_n	    (rst_n      ),
    .freq_set   (key_out[0] ),//设置频率控制字
    .set_done   (key_out[1] ),//设置完成
    .dout       (dout       ) //输出数据
    );


	pll u_pll(  //锁相环例化
	.areset	(~rst_n		),
	.inclk0	(clk			),
	.c0		(clk_100m	),
	.locked	(locked		)
	);

endmodule

DDS模块:

module DDS(
      input               clk		    ,
	input                  rst_n	    ,

    input               freq_set    ,//设置频率控制字
    input               set_done    ,//设置完成

    output  [7:0]       dout         //输出数据
);

//信号定义

    reg     [7:0]       fcw_tmp     ;   //频率控制字  0--255
    reg     [7:0]       fcw         ;   //中间寄存控制字
    reg     [9:0]       phase_accum ;   //相位累加器寄存器

    wire    [7:0]       q_out       ;

//fcw   
    always @(posedge clk or negedge rst_n)begin 
        if(!rst_n)begin
            fcw_tmp <= 0;
        end 
        else if(freq_set)begin 
            fcw_tmp <= fcw_tmp + 1;
        end 
        else if(set_done)begin 
            fcw_tmp <= 0;
        end 
    end

    always @(posedge clk or negedge rst_n)begin 
        if(!rst_n)begin
            fcw <= 1;
        end 
        else if(set_done)begin 
            fcw <= fcw + fcw_tmp;
        end 
    end

//phase_accum
    always @(posedge clk or negedge rst_n)begin 
        if(!rst_n)begin
            phase_accum <= 0;
        end 
        else begin 
            phase_accum <= phase_accum + fcw;
        end 
    end

//dout  

    assign dout = q_out;

//正弦波数据查找表
    rom	rom_inst (
	.address    (phase_accum       ),
	.clock      (clk               ),
	.q          (q_out             )
	);

    
endmodule

按键消抖模块:

//按键消抖模块
module key_debounce(
     input clk,
	  input rst_n,
	  input [1:0] key_in,
	  
	  output reg [1:0] key_out
	  );
	  
 //parameter KEY_W = 2;
 parameter TIME_20MS = 100000;
 
 //当检测到下降沿之后,计数使能拉高,计数器开始计数计时20ms
 
 reg [19:0] cnt;
 wire add_cnt;
 wire end_cnt;
 
 reg add_flag;
 wire nedge;
 	reg  [1:0] key_r0;
	reg  [1:0] key_r1;
 
 always@(posedge clk or negedge rst_n)begin
    if(~rst_n)
	    cnt <= 0;
		 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;
	
	//当检测到下降沿之后,使能信号拉高
	always@(posedge clk or negedge rst_n)begin
	    if(~rst_n)
		     add_flag <= 0;
			  else if(nedge)begin
			     add_flag <=1;
				  end
				  else if(end_cnt)begin
				  add_flag <=0;
				  end
				  end
	
	//进行同步打拍产生下降沿

	
	always@(posedge clk or negedge rst_n)begin
	    if(~rst_n)begin
		    key_r0<=1;
			 key_r1<=1;
			 end
			 else begin 
			key_r0 <= key_in;//同步
			key_r1 <= key_r0;//打拍
		end 
	end
	
	assign nedge = ~key_r0 & key_r1;
			 
	always@(posedge clk or negedge rst_n)begin
	    if(~rst_n)
		     key_out<=0;
			  else 
			  key_out<=end_cnt?~key_r1:0;
			  end
			  
	
	endmodule
		  

这里我们利用按键来控制频率控制字改变,两个按键,一个控制增加,一个将增加的值设置给频率控制字。通过频率控制字来改变寻址的地址,达到控制数据输出频率的目的。


上图就是我们要输出的波形,每个数据8bit,一共1024个。利用Mif_Maker2010软件画图并产生 .mif文件(存储图像中各点数据)。然后将其保存在ROM中,根据输入的地址读取相应的值。

signal tap仿真输出效果:

这是放大之后的图像,可以看到就是一个一个的点,我们控制步长(频率控制字)就可以改变它的频率

以上是关于FPGA学习之 直接数字频率合成器(DDS)的主要内容,如果未能解决你的问题,请参考以下文章

FPGA学习之 直接数字频率合成器(DDS)

FPGA学习之 直接数字频率合成器(DDS)

FPGA教程案例28基于FPGA的DDS直接数字频率合成器之一——原理介绍

FPGA+sin基于DDS(直接数字合成)的正弦信号发生器模块FPGA实现

FPGA教程案例29基于FPGA的DDS直接数字频率合成器之二——Verilog开发

FPGA教程案例30基于FPGA的DDS直接数字频率合成器之三——借助MATLAB进行频率精度分析