EDA编程,数字频率合成器
发布网友
发布时间:2022-04-25 11:49
我来回答
共1个回答
热心网友
时间:2024-01-21 11:51
DDS或DDFS是 Direct Digital Frequency Synthesis 的简称。DDS的工作原理是以数控振荡器的方式产生频率、相位可控制的正弦波。电路一般包括基准时钟、频率累加器、相位累加器、幅度/相位转换电路、D/A转换器和低通滤波器(LPF)。频率累加器对输入信号进行累加运算,产生频率控制数据K(frequency data或相位步进量)。相位累加器由N位全加器和N位累加寄存器级联而成,对代表频率的二进制码进行累加运算,是典型的反馈电路,产生累加结果。幅度/相位转换电路实质上是一个波形寄存器,以供查表使用。读出的数据送入D/A转换器和低通滤波器。
具体工作过程如下:
每来一个时钟脉冲fc,N位加法器将频率控制字K与累加寄存器输出的累加相位数据相加,把相加后的结果送至累加寄存器的数据输入端。其中相位累加器由N位加法器与N位累加寄存器级联构成,累加寄存器将加法器在上一个时钟脉冲作用后所产生的新相位数据反馈到加法器的输入端,以使加法器在下一个时钟脉冲的作用下继续与频率控制字K相加。这样,相位累加器在时钟作用下,不断对频率控制字K进行线性相位累加。由此可见,相位累加器在每一个时钟脉冲输入时,把频率控制字K累加一次,相位累加器输出的数据就是合成信号的相位,相位累加器的溢出频率就是DDS输出的信号频率。用相位累加器输出的数据作为波形存储器ROM的相位取样地址,可把存储在波形存储器内的波形抽样值(二进制编码)经查找表查出,完成相位到幅值转换。波形存储器的输出送到D/A转换器,D/A转换器将数字量形式的波形幅值转换成所要求合成频率的模拟量形式信号,由低通滤波器滤除杂散波和谐波以后,输出一个频率为fo的正弦波。输出频率fo与时钟频率fc之间的关系满足下式:Fo=K×Fc/2^N
其中fo为输出频率,fc为时钟脉冲,K为频率控制字。N为累加器的位数(字长)。
在软件MAX+PLUS Ⅱ中VHDL语言 仿真描述DDS输出的正弦波程序...
本设计中相位累加器的数据宽度N采用32位
LIBRARY IEEE; --DDS顶层设计
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY DDS_VHDL IS
PORT (CLK:IN STD_LOGIC;
FWORD: IN STD_LOGIC_VECTOR(7 DOWNTO 0); --频率控制字
PWORD: IN STD_LOGIC_VECTOR(7 DOWNTO 0); --相位控制字
FOUT: OUT STD_LOGIC_VECTOR(9 DOWNTO 0) );
END DDS_VHDL;
ARCHITECTURE one OF DDS_VHDL IS
COMPONENT REG32B
PORT (LOAD: IN STD_LOGIC;
DIN: IN STD_LOGIC_VECTOR(31 DOWNTO 0);
DOUT: OUT STD_LOGIC_VECTOR(31 DOWNTO 0));
END COMPONENT;
COMPONENT REG10B
PORT (LOAD: IN STD_LOGIC;
DIN: IN STD_LOGIC_VECTOR(9 DOWNTO 0);
DOUT: OUT STD_LOGIC_VECTOR(9 DOWNTO 0));
END COMPONENT;
COMPONENT ADDER32B
PORT (A: IN STD_LOGIC_VECTOR(31 DOWNTO 0);
B: IN STD_LOGIC_VECTOR(31 DOWNTO 0);
S: OUT STD_LOGIC_VECTOR(31 DOWNTO 0));
END COMPONENT;
COMPONENT ADDER10B
PORT (A: IN STD_LOGIC_VECTOR(9 DOWNTO 0);
B: IN STD_LOGIC_VECTOR(9 DOWNTO 0);
S: OUT STD_LOGIC_VECTOR(9 DOWNTO 0));
END COMPONENT;
COMPONENT SIN_ROM
PORT (address: IN STD_LOGIC_VECTOR(9 DOWNTO 0);
inclock: IN STD_LOGIC;
q: OUT STD_LOGIC_VECTOR(9 DOWNTO 0));
END COMPONENT;
SIGNAL F32B,D32B,DIN32B: STD_LOGIC_VECTOR(31 DOWNTO 0);
SIGNAL P10B,LIN10B,SIN10B: STD_LOGIC_VECTOR(9 DOWNTO 0);
BEGIN
F32B(27 DOWNTO 20)<=FWORD; F32B (31 DOWNTO 28)<="0000";
P10B(1 DOWNTO 0)<="00";
F32B(19 DOWNTO 0)<="00000000000000000000"; P10B(9 DOWNTO 2)<=PWORD;
u1: ADDER32B PORT MAP(A=>F32B,B=>D32B,S=>DIN32B);
u2: REG32B PORT MAP(DOUT=>D32B,DIN=>DIN32B,LOAD=>CLK);
u3: SIN_ROM PORT MAP(address=>SIN10B,q=>FOUT,inclock=>CLK);
u4: ADDER10B PORT MAP(A=>P10B,B=>D32B(31 DOWNTO 22),S=>LIN10B);
u5: REG10B PORT MAP(DOUT=>SIN10B,DIN=>LIN10B,LOAD=>CLK);
END one;
累加器的VHDL描述
累加器由N位加法器与N位累加寄存器级联构成,这里的N取32位。
LIBRARY IEEE; --32位加法器模块
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY ADDER32B IS
PORT (A,B: IN STD_LOGIC_VECTOR(31 DOWNTO 0);
S: OUT STD_LOGIC_VECTOR(31 DOWNTO 0));
END ADDER32B;
ARCHITECTURE behav OF ADDER32B IS
BEGIN
S<=A+B;
END behav;
LIBRARY IEEE; --32位寄存器模块
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY REG32B IS
PORT (Load: IN STD_LOGIC;
DIN: IN STD_LOGIC_VECTOR(31 DOWNTO 0);
DOUT: OUT STD_LOGIC_VECTOR(31 DOWNTO 0));
END REG32B;
ARCHITECTURE behav OF REG32B IS
BEGIN
PROCESS(LOAD,DIN)
BEGIN
IF (Load'EVENT AND Load='1') THEN
DOUT<=DIN;
END IF;
END PROCESS;
END behav;
移相加法器的数据宽度采用10位,即输出的D/A的精度是10位。
LIBRARY IEEE; --10位加法器模块
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY ADDER10B IS
PORT (A,B: IN STD_LOGIC_VECTOR(9 DOWNTO 0);
S: OUT STD_LOGIC_VECTOR(9 DOWNTO 0));
END ADDER10B;
ARCHITECTURE behav OF ADDER10B IS
BEGIN
S<=A+B;
END behav;
LIBRARY IEEE; --10位寄存器模块
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY REG10B IS
PORT (Load: IN STD_LOGIC;
DIN: IN STD_LOGIC_VECTOR(9 DOWNTO 0);
DOUT: OUT STD_LOGIC_VECTOR(9 DOWNTO 0));
END REG10B;
ARCHITECTURE behav OF REG10B IS
BEGIN
PROCESS(LOAD,DIN)
BEGIN
IF (Load'EVENT AND Load='1') THEN
DOUT<=DIN;
END IF;
END PROCESS;
END behav;
定制LPM_ROM初始化数据文件
rom_data.mif 10位正弦波数据文件,可用MATLAB/DSP Builder生成
WIDTH=10;
DEPTH=1024;
ADDRESS_RADIX=DEC;
DATA_RADIX=DEC;
CONTENT BEGIN
0:512; 1:515; 2:518; 3:521; 4:524; 5:527; 6:530; 7:533;
8:537; 9:540; 10:543; 11:546; 12:549; 13:552; 14:555; ....(略去部分数据)
1018:493; 1019:496; 1020:499; 1021:502; 1022:505; 1023:508;
END;
用于例化的波形数据ROM
用于例化的波形数据ROM文件
LIBRARY IEEE; --数据ROM
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY sin_rom IS
PORT (address: IN STD_LOGIC_VECTOR(9 DOWNTO 0);
inclock: IN STD_LOGIC;
q: OUT STD_LOGIC_VECTOR(9 DOWNTO 0));
END sin_rom;
ARCHITECTURE SYN OF sin_rom IS
SIGNAL sub_wire0: STD_LOGIC_VECTOR(9 DOWNTO 0);
COMPONENT lpm_rom --调用LPM ROM模块
GENERIC (lpm_width : NATURAL;
lpm_widthad : NATURAL;
lpm_address_control: STRING;
lpm_outdata : STRING;
lpm_file : STRING);
PORT (address: IN STD_LOGIC_VECTOR(9 DOWNTO 0);
inclock: IN STD_LOGIC;
q: OUT STD_LOGIC_VECTOR(9 DOWNTO 0));
END COMPONENT;
BEGIN
q<=sub_wire0(9 DOWNTO 0);
lpm_rom_component: lpm_rom GENERIC MAP(
LPM_WIDTH=>10,
LPM_WIDTHAD=>10,
LPM_ADDRESS_CONTROL=>"REGISTERED",
LPM_OUTDATA=>"UNREGISTERED",
LPM_FILE=>"ROM_DATA.mif") --ROM数据文件及其路径
PORT MAP(address=>address,inclock=>inclock,q=>sub_wire0);
END SYN;
这个太多咯,DDS基本原理书上或网上多得很, 一般在EDA技术的书上讲有VHDL语言实现DDS的代码、、