直接數字頻率合成器(Direct Digital Synthesizer,DDS),是一種頻率合成技術,具有相對帶寬大、頻率轉換速度快、相位分辨率高、連續性好等優點,在數字信號處理中常用于調制信號的生成,模塊設計較為簡單,頻率、相位容易控制,多用于無線通信領域。
DDS發生器的組成原理精髓在于對“模板”信號在單個周期內的采樣,在系統工作頻率一定的情況下,輸出信號頻率和周期內的取樣點數有著直接的關系,舉個栗子,假設基波信號 U(t)=sin(2pift+θ )=sin( 2pit ) ,* 在0~2Π內
等分周期,在相同的系統時鐘下采用不同的抽樣點數進行抽樣,如下圖所示:
以*Π/4 *為步進在單個周期內抽樣
以*Π/8 *為步進在單個周期內抽樣
可以很明顯看出,相同系統時鐘下使用不同的抽樣點數,可以得到不同的輸出頻率;基本組成架構如下,系統時鐘驅動頻率控制字(抽樣間隔)逐次累加生成存儲著基波數據ROM的對應抽樣地址,相位控制字主要用來決定基波的起始相位;
在FPGA中開辟一塊Block RAM用于存儲對應的“模板”信號,也就是要輸周期信號的一個完整周期,輸出數據位數決定采樣波形存儲ROM的寬度,數據深度與采樣精度有關,累加器用于按頻率控制字步長控制等間隔采樣精度,相位寄存器用于鎖定波形發生起始的位置,生成的周期數列作為ROM表的驅動地址,完成對"模板"信號不同頻率的抽樣;
模塊設計前需要先準備ROM初始化文件“ .coe ”,生成方式可以使用工具或者MATLAB,下面是個人使用的一個基于MATLAB的coe文件生成代碼;
clc;clear;close all;
width = 10;
depth = 2048;
t = linspace(0,2*pi,depth);
sin_val = sin(t);
% %cos_val = cos(t);
plot(t,sin_val,'--');
sin_val = fix(sin_val*(2^width-1)/2 + 0.5); %四舍五入
% %cos_val = fix(cos_val*(2^width-1)/2 + 0.5);
sin_val(find(sin_val< 0))=sin_val(find(sin_val< 0)) + 2^width; %求補碼
addr = [0:depth - 1];
file = fopen('sin1024.coe','wt');
fprintf(file,'MEMORY_INITIALIZATION_RADIX=10;n);
fprintf(file,'MEMORY_INITIALIZATION_VECTOR=n');
for i=1:depth
fprintf(file,'%04X : %04X;n',addr(i), sin_val(i));
end
fprintf(file,'END;n');
fclose(file);
模塊設計為便于修改添加部分參數定義,在有不同位寬需求時可以只修改參數和ROM模塊IP即可實現;頻率計算公式不在推到,直接給出:
其中K為頻率控制字,N為相位累加器位寬,f0為模塊輸出頻率,fC為系統時鐘頻率;舉個例子,設系統時鐘為50Mhz,相位寬度10Bit,要輸出1Mhz的信號,則K=(2^101)/50; *設計代碼如下,使用時只需添加ROM模塊的IP,然后就可以例化工程使用:
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: nhike
// Engineer: chenyivi
//
// Create Date: 2019/11/03 19:25:35
// Design Name:DDS_ROM_IP
// Module Name: DDS_ROM
// Project Name: DDS_ROM_IP
// Target Devices: zynq7010
// Tool Versions:1.0
// Description: WaveFrom
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module DDS_ROM(
clk, //系統時鐘
rst_n, //系統復位
Freword, //頻率控制參數
Phaword, //初始相位控制參數
WaveDataOut //輸出信號
);
parameter FrequencyBitWidth = 32;
parameter PhaseBitWidth =10;
parameter DataOutBitWidth= 10;
input clk;
input rst_n;
input [FrequencyBitWidth-1:0] Freword;
input [PhaseBitWidth-1:0] Phaword;
output [DataOutBitWidth-1:0] WaveDataOut;
reg [FrequencyBitWidth-1:0] Freword_temp;
reg [PhaseBitWidth-1:0] Phaword_temp;
wire [PhaseBitWidth-1:0] WaveAddData;
always@(posedge clk or negedge rst_n)begin //data latch.
if(!rst_n)begin
Freword_temp <= 32'b0;
Phaword_temp <= 10'b0;
end
else begin
Freword_temp <= Freword;
Phaword_temp <= Phaword;
end
end
reg [FrequencyBitWidth-1:0] cnt;
always @(posedge clk or negedge rst_n)begin //Sampling control.
if(!rst_n)
cnt <= 0;
else
cnt <= cnt + Freword_temp;
end
assign WaveAddData = cnt[FrequencyBitWidth-1:FrequencyBitWidth-(DataOutBitWidth + 1)] + Phaword_temp; //Data precision interception
WaveRom WaveRomBase (
.clka(clk),
.addra(WaveAddData),
.douta(WaveDataOut)
);
endmodule
下面是仿真結果和RTL:
以上實現均在Vivado中驗證,Quartus使用方法與上述一致;
-
合成器
+關注
關注
0文章
273瀏覽量
25360 -
頻率合成器
+關注
關注
5文章
219瀏覽量
32354 -
無線通信
+關注
關注
58文章
4570瀏覽量
143538 -
Verilog
+關注
關注
28文章
1351瀏覽量
110100 -
DDS
+關注
關注
21文章
634瀏覽量
152664
發布評論請先 登錄
相關推薦
評論