DDS设计 1.实例说明
直接数字合成器DDS,是一种数字式的频率合成器,它的优点是易于控制,频率切换速度块,此实例通过ROM查找法用VHDL语言实现了DDS的功能。 2.设计原理
DDS要产生一个sinwt的正弦信号的方法是:在每次系统时钟的触发沿到来时,输出相应的幅度值,每次相应的增值为wT(T为系统时钟周期)。要得到每次相应相位的幅度值,一种简单的方法是查表,即将0—2π的正弦函数值分为n份,将各点的幅度值存到ROM中,再用一个相位累加器每次累加相位值wT,得到当前的相位值,通过查找ROM得到当前的幅度值。
DDS工作过程:每次系统时钟的上升沿到来时,相位累加器(24位)中的值累加上频率寄存器(24位)中的值,再用累加器的高12位作为地址进行ROM查表,查到的值送到D/A进行转换。
采用ROM压缩技术。将0—2π的幅度值只存储0—π/2的部分。 3.程序说明:
程序分3个部分:数据输入部分,相位累加部分和ROM查找部分,系统时钟用clk表示;
在数据输入部分,输入信号rec高电平表示让系统读取新的频率控制字,只有在clk上升沿时rec为高电平才将输入的ftw信号读入频率寄存器中。读取后输出一个周期的ack高电平信号表示接收应答;
在相位累加部分,每次clk上升沿到来时,将频率寄存器的值加到相位累加器中,并将上一次的累加值高12位输出作为查找ROM地址使用。其中最高两位赋给信号s_1和s_2用来表示相位的区间,其他10位用来生成ROM地址;
ROM查找部分,对s_1和s_2进行判断,确定相位的区间,将各个区间的地址和ROM数据对应到0—π/2区间,因为ROM中实际上只存储了0—π/2区间的数据。区间π/2—π中与区间0—π/2幅度相同的相位相加为π,即区间π/2—π中地址为x的数据对应区间0—π/2中地址3FF—x的数据,可由x取反得到。区间π—3π/2的幅度为负,地址为x的数据对应区间0—π/2中相同地址的数据取反。区间3π/2—2π的幅度为负,地址为x的数据对应区间0—π/2中3FF—x地址的数据取反;
ROM中的数据均为有符号数据,最高位为符号位,“0”表示正,“1”表示负,负数用二进制补码形式表示。整数取反再加1,得到相应的负数;
library ieee;
use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; use ieee.std_logic_arith.all; entity dds_dds is
port(ftw:in std_logic_vector(23 downto 0);--频率控制字 clk:in std_logic; --系统时钟 rec:in std_logic; --接收信号使能 out_q:out std_logic_vector(9 downto 0);--幅度值输出 ack:out std_logic); --接受应答信号 end dds_dds;
architecture hev of dds_dds is
signal rom_out:std_logic_vector(9 downto 0);
signal frq_reg,phase_adder:std_logic_vector(23 downto 0); signal rom_address,address:std_logic_vector(9 downto 0); signal s_1,s_2,a_1,a_2,a:std_logic;
component dds_dds_rom --元件例化 port(address:in std_logic_vector(9 downto 0); q:out std_logic_vector(9 downto 0)); end component; begin data:dds_dds_rom port map(address,rom_out);
datain:process(clk,rec,a,clk) --数据输入部分 begin if clk'event and clk='1'then if rec='1'then --rec为1则读取ftw数据 frq_reg<=ftw; ack<='1'; a<='1'; end if; if a='1'then --a与ack内容相同,在判断是使用 ack<='0'; a<='0'; end if; end if; end process;
phase_add:process(clk) --相位累加部分 begin
if (clk'event and clk='1')then phase_adder<=phase_adder+frq_reg; --相位累加 rom_address(0)<=phase_adder(12); rom_address(1)<=phase_adder(13); rom_address(2)<=phase_adder(14); rom_address(3)<=phase_adder(15); rom_address(4)<=phase_adder(16); rom_address(5)<=phase_adder(17); rom_address(6)<=phase_adder(18); rom_address(7)<=phase_adder(19); rom_address(8)<=phase_adder(20); rom_address(9)<=phase_adder(21); s_2<=phase_adder(22); s_1<=phase_adder(23); end if; end process;
lookfor_rom:process(clk,s_1,s_2,a_1,a_2,rom_out,rom_address)--ROM查找部分 begin if clk'event and clk ='1'then a_1<=s_1; a_2<=s_2; end if; if s_1='0'and s_2='0'then --将各区间地址对应到0—π/2的地址 address(9 downto 0)<=rom_address(9 downto 0); elsif s_1='0'and s_2='1'then --not rom_address=3FF-rom_address address(9 downto 0)<=not rom_address(9 downto 0); elsif s_1='1'and s_2='0'then address(9 downto 0)<=rom_address(9 downto 0); elsif s_1='1'and s_2='1'then address(9 downto 0)<=not rom_address(9 downto 0); end if; if a_1='0'and a_2='0'then --将各区间幅度对应到0—π/2的幅度 out_q(9 downto 0)<=rom_out(9 downto 0); elsif a_1='0'and a_2='1'then out_q(9 downto 0)<=rom_out(9 downto 0); elsif a_1='1'and a_2='0'then out_q(9 downto 0)<=not rom_out(9 downto 0)+\ elsif a_1='1'and a_2='1'then --负数通过对整数取反加1得到 out_q(9 downto 0)<=not rom_out(9 downto 0)+\ end if; end process; end hev;
library ieee;
use ieee.std_logic_1164.all; entity dds_dds_rom is --ROM元件创建 port(address:in std_logic_vector(9 downto 0); q:out std_logic_vector(9 downto 0)); end dds_dds_rom;
architecture hev of dds_dds_rom is begin
q<=address; end hev;
百度搜索“77cn”或“免费范文网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,免费范文网,提供经典小说教育文库DDS的VHDL实现在线全文阅读。
相关推荐: