原理:
基于ROM的直接数字式频率合成器(DDS)的结构主要是由相位累加器、正弦查找表、数模转换器(DAC)和低通滤波器等四个大的结构组成,其结构框图如下 :
输出频率的公式 : Fout = Fclk * Freq_World / 2N (N为相位累加器位宽)
输出信号频率分辨率 : △Fout = Fclk / 2N
一、相位累加器
略
二、正弦查找表
通过如下Matlab脚本生成10进制、65536点的正弦采样序列并将其保存在“init.coe”文件中,并在下面生成rom ip核时调用。
1 % Matlab代码:
2
3 % 相位累加器位宽
4 N = 16;
5 M = 2^N;
6 % 生成正弦抽样序列
7 n = 0:M-1;
8 x = sin(2*pi*n/M);
9 % 量化
10 y = round((x+1)*M/2);
11 plot(n,y);
12
13 % 生成.coe文件
14 init_vector = fopen('init.coe','wt');
15 fprintf(init_vector, 'memory_initialization_radix = 10;\nmemory_initialization_vector = ');
16 for i = 1:M
17 if mod(i-1,16) == 0
18 fprintf(init_vector, '\n');
19 end
20 fprintf(init_vector, '%4d,', y(i));
21 end
三、FPGA实现
通过计数器计数输出作为储存有正弦序列表的rom的地址进行寻址输出,详细原理“略”,具体实现见下:
1 `timescale 1ns / 1ps
2 //---------------------------------------------------------------------------
3 // Company :
4 // Engineer : Aqua
5 // Create Date : 2017/11/26
6 // Module Name : dds_module
7 // Project Name : dds_7z20.demo
8 // Target Devices : zynq7020
9 // Tool Versions : vivado 2017.1
10 // Description :
11 // Revision : v 1.0
12 //---------------------------------------------------------------------------
13 module dds_module#(
14 parameter Phase_Width = 16,
15 Dout_Width = 17
16 )(
17 input clk,
18 input rst,
19 input [Phase_Width-1:0] s_tphase_in,
20 output [Phase_Width-1:0] m_tphase_out,
21 output [Dout_Width-1:0] m_tdata_out
22 );
23
24 reg [15:0] PhaAcuml;
25 //------------------------相位累加器--------------------------
26 always@(posedge clk or posedge rst)
27 begin
28 if(rst)
29 PhaAcuml <&#61; &#39;b0;
30 else
31 PhaAcuml <&#61; PhaAcuml &#43; s_tphase_in;
32 end
33
34 assign m_tphase_out &#61; PhaAcuml;
35 //------------------------正弦查找表--------------------------
36 rom inst_rom (
37 .a (PhaAcuml), // input wire [15 : 0] a
38 .spo (m_tdata_out) // output wire [16 : 0] spo
39 );
40 endmodule
部分激励代码如下&#xff1a;
1 testbench部分代码&#xff1a;
2
3 //----------------------------------------------------------------------------
4 //
5 // Fout &#61; Fclk * s_tphase_in / 2^16 (相位位宽&#xff1a;16 bit)
6 //
7 //----------------------------------------------------------------------------
8 s_tphase_in <&#61; 16‘h0CCC; // 5MHz
9 s_tphase_in <&#61; 16&#39;h3333; // 20MHz
仿真波形&#xff1a;
1、设定输出正弦信号频率值&#xff1a;5MHz
2、设定输出正弦信号频率值&#xff1a;20MHz
四、应用&#xff08;Chirp信号&#xff09;
1 &#96;timescale 1ns / 1ps
2
3 // Company :
4 // Engineer :
5 // Create Date : 2017/11/26
6 // Module Name : dds_module_tb
7 // Project Name :
8 // Target Devices :
9 // Tool Versions :
10 // Description :
11 // Revision :
12
13 module dds_module_tb;
14
15 reg clk;
16 reg rst;
17 reg [15:0] s_tphase_in;
18 wire [15:0] m_tphase_out;
19 wire [16:0] m_tdata_out;
20
21 reg [19:0] count;
22
23 localparam idle &#61; &#39;d1,
24 rise &#61; &#39;d2,
25 fall &#61; &#39;d3;
26 reg [2:0] s_state;
27
28 localparam N &#61; &#39;d200,
29 s_tphase_min &#61; 16&#39;h0001,
30 s_tphase_max &#61; 16&#39;h3333,
31 step &#61; (s_tphase_max - s_tphase_min)/N;
32//--------------------------------------------------------------------------------------
33 dds_module uut (
34 .clk (clk),
35 .rst (rst),
36 .s_tphase_in (s_tphase_in),
37 .m_tphase_out (m_tphase_out),
38 .m_tdata_out (m_tdata_out)
39 );
40//--------------------------------------------------------------------------------------
41 initial
42 begin
43 clk &#61; 0;
44 rst &#61; 1;
45 #100
46 rst &#61; 0;
47 end
48//-------------------------------------------------------------------------------------
49 always&#64;(posedge clk or posedge rst)
50 begin
51 if(rst)
52 begin
53 s_tphase_in <&#61; &#39;b0;
54 count <&#61; 1;
55 s_state <&#61; idle;
56 end
57 else
58 begin
59 case(s_state)
60 idle : begin
61 s_state <&#61; rise;
62 count <&#61; 1;
63 end
64 rise : begin
65 if(count <&#61; N)
66 begin
67 count <&#61; count &#43; 1;
68 s_tphase_in <&#61; s_tphase_min &#43; step * count;
69 end
70 else
71 begin
72 count <&#61; 1;
73 s_state <&#61; fall;
74 end
75 end
76 fall : begin
77 if(count <&#61; N)
78 begin
79 count <&#61; count &#43; 1;
80 s_tphase_in <&#61; s_tphase_max - step * count;
81 end
82 else
83 begin
84 count <&#61; 1;
85 s_state <&#61; rise;
86 end
87 end
88 default : begin
89 s_state <&#61; idle;
90 end
91 endcase
92 end
93 end
94//----------------------------------------------------------------------------------
95 always#5 clk &#61; ~clk;
96
97 endmodule
设定输出Chirp信号频率值&#xff1a;0~20MHz