功能描述:
          DDS的工作过程为:在参考时钟fc的作用下,相位累加器对频率控制字FCW进行线性累加,将其高W位作为地址码通过波形查值表ROM变换,产生D位对应信号波形的数字序列,再由数模转换器DAC将其转化为阶梯模拟电压波形后由具有内插作用的低通滤波器LPF将其平滑为连续的正弦波形作为输出。
       这里,我们主要考虑的方法是基于一种差值的方法来实现高位宽的ROM值输出。具体的方法如下所示:
	       首先,设计一个深度为2^16的小ROM。这个作为频率控制字的高16位的输入脚。作为输出的基本频率信号,通过这个方式,输出的正弦信号的分辨率为:457.763671875Hz。以这个频率分辨率的信号作为粗DDS输出信号。
	 
	        首先按原高16位的值输入到ROM中得到一组数据,然后在此基础上,加上1作为一组新的频率控制字输入到ROM,得到第二组数据。那么根据算法可知,这两组数据的差值为457.763671875Hz。
	`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date:    18:47:07 03/24/2012 
// Design Name: 
// Module Name:    dds_tops 
// Project Name: 
// Target Devices: 
// Tool versions: 
// Description: 
//
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//
//
module dds_tops(
                i_clk, //100M
  i_rst,
  o_carrier_slow,
  o_carrier_fast,
  o_lmda,
  o_carrier
             );
 
parameter DDS_VALUE = 48'd25893420468932;  //10.11911000Mhz
 
 
 
input              i_clk;
input              i_rst;
output signed[15:0]o_carrier_slow; 
output signed[15:0]o_carrier_fast;
output       [15:0]o_lmda;
output signed[15:0]o_carrier;
 
 
 
 
//产生慢频率载波
//产生慢频率载波
reg[13:0]Address_slow;
always @(posedge i_clk or posedge i_rst)
begin
     if(i_rst)
   begin
   Address_slow <= 14'd0;
   end
else begin
     Address_slow <= Address_slow + DDS_VALUE[47:34];
     end
end
rom_dds rom_dds_u1(
  .clka  (i_clk),
  .rsta  (i_rst),
  .addra (Address_slow),
  .douta (o_carrier_slow)
 );
 
 
 
//产生快频率载波
//产生快频率载波
reg[13:0]Address_fast;
always @(posedge i_clk or posedge i_rst)
begin
     if(i_rst)
   begin
   Address_fast <= 14'd0;
   end
else begin
     Address_fast <= Address_fast + (DDS_VALUE[47:34] + 14'd1);
     end
end
rom_dds rom_dds_u2(
  .clka  (i_clk),
  .rsta  (i_rst),
  .addra (Address_fast),
  .douta (o_carrier_fast)
 );
 
 
wire [47:0]slow_DDS;
wire [47:0]fast_DDS;
 
assign slow_DDS = {DDS_VALUE[47:34],34'd0};
assign fast_DDS = {DDS_VALUE[47:34]+1'b1,34'd0};
 
//进行lmda估计
//进行lmda估计
wire is_larger1;
 
lmda_check lmda_check_u(
  .i_clk      (i_clk), 
  .i_rst      (i_rst), 
  .i_slow_DDS (slow_DDS), 
  .i_jizh_DDS (DDS_VALUE), 
  .i_fast_DDS (fast_DDS), 
  .o_lmda     (), 
  .o_lmdas    (o_lmda),
  .is_larger1 (is_larger1),
  //test
  .diff1      (),
  .diff2      (),
  .divs       ()
   );
 
//进行差值,得到最后的计算结果
//lmda > 1 :((1/lmda) * fmax + fmin)/(1+(1/lmda))
//lmda < 1 :(fmax + lmda*fmin)/(1+lmda)
 
//计算1+lmda or 1+(1/lmda)
 
//lmda_roms lmda_roms_u(
// .clka  (i_clk),
// .rsta  (i_rst),
// .addra (o_lmda), // Bus [13 : 0] 
// .douta (douta)
// ); // Bus [15 : 0] 
 
wire signed[31:0]carrier_fast_lmda;
wire signed[31:0]carrier_slow_lmda;
 
multer multer_u1(
 .clk  (i_clk),
 .a    (o_carrier_fast),  
 .b    (o_lmda),  
 .sclr (i_rst),
 .p    (carrier_fast_lmda)
  );  
 
multer multer_u2(
 .clk  (i_clk),
 .a    (o_carrier_slow),  
 .b    (o_lmda),  
 .sclr (i_rst),
 .p    (carrier_slow_lmda)
  );  
 
 
reg signed[31:0]r1;
reg signed[31:0]r2;
reg signed[31:0]r3;
 
always @(posedge i_clk or posedge i_rst)
begin
     if(i_rst)
   begin
   r1 <= 32'd0;
   r2 <= 32'd0;
   r3 <= 32'd0;
   end
else begin
          if(is_larger1 == 1'b1)
  begin
        r1 <=   carrier_fast_lmda;
        r2 <=  {o_carrier_slow,o_carrier_slow[15],o_carrier_slow[15],o_carrier_slow[15],o_carrier_slow[15]
                        ,o_carrier_slow[15],o_carrier_slow[15],o_carrier_slow[15],o_carrier_slow[15]
   ,o_carrier_slow[15],o_carrier_slow[15],o_carrier_slow[15],o_carrier_slow[15]
   ,o_carrier_slow[15],o_carrier_slow[15],o_carrier_slow[15],o_carrier_slow[15]   
   };
        r3 <=  r1[31:1] + r2[31:1];  
  end
   else begin
        r1 <=  carrier_slow_lmda;
        r2 <= {o_carrier_fast,o_carrier_fast[15],o_carrier_fast[15],o_carrier_fast[15],o_carrier_fast[15]
                       ,o_carrier_fast[15],o_carrier_fast[15],o_carrier_fast[15],o_carrier_fast[15]
                 ,o_carrier_fast[15],o_carrier_fast[15],o_carrier_fast[15],o_carrier_fast[15]
                 ,o_carrier_fast[15],o_carrier_fast[15],o_carrier_fast[15],o_carrier_fast[15]  
  };
        r3 <=  r1[31:1] + r2[31:1]; 
          end   
     end
end
 
assign o_carrier = r3[31:15];
 
endmodule
在FPGA中,首先使用MODELSIM进行仿真,得到的仿真结果如下所示: 
	
	