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