功能描述:
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进行仿真,得到的仿真结果如下所示: