设计要求:设计一个函数信号发生器,能产生方波,三角波,正弦波,阶梯波。
设计概述:信号的输出实质上是指电压幅度随时间的变化。根据这个原理我们就可以设计函数信号发生器了。FPGA里面产生的数据只能是数字信号,最终我们通过连接8bit的DA转换器就能将数字信号转换成电压信号,从而实现了信号发生器的功能。
本设计有5个模块组成,其中有:方波发生器,三角波发生器,正弦波发生器,阶梯波发生器,4选1选择器。下面是我设计的整个过程:
方波发生器:实质上是一段时间输出0,一段时间输出255的数字信号,当然这有8位的通道输出。
程序设计如下:
--工程名:方波发生器
--功能:产生方波,是通过交替送出全0和全1实现的,每32个时钟翻转一次
--时间:2010-12-17
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
entity sqaure is
port(clk,clr:in std_logic;
q:out integer range 0 to 255
);
end entity;
architecture behav of sqaure is
signal a:bit;
begin
process(clk,clr) --计数分频
variable cnt:integer range 0 to 32;
begin
if(clr='0') then
a<='0';
elsif clk'event and clk='1' then
if cnt<31 then --进行32分频
cnt:=cnt+1;
else
cnt:=0;
a<=not a;
end if;
end if;
end process;
process(clk,a) --信号输出
begin
if clk'event and clk='1' then
if a='1' then
q<=255;
else
q<=0;
end if;
end if;
end process;
end behav;
三角波发生器:实质上是先输出直线递增的数字信号,随后按照同样的斜率输出递减的数字信号。这样就能实现三角波的发生了。
程序设计如下:
--工程名:三角波信号发生器
--功能:产生的三角波以64个时钟为一个周期,输出q每次加减8。
--时间:2010-12-17
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
entity delta1 is
port(clk:in std_logic;--时钟信号
rst:in std_logic;--复位信号
q:out std_logic_vector(7 downto 0)); --输出信号
end entity;
architecture behav of delta1 is
begin
process(clk,rst)
variable tmp:std_logic_vector(7 downto 0);
variable a:std_logic;
begin
if(rst='0') then
tmp:="00000000";
elsif clk'event and clk='1' then
if(a='0') then
if(tmp="11111000") then --tmp=248
tmp:="11111111";
a:='1';--信号计数完成,下一次改成递减
else
tmp:=tmp+8;--递增
end if;
else
if tmp="00000111" then --tmp=7
tmp:="00000000";
a:='0';--信号计数完成,下一次改成递增
else
tmp:=tmp-8;--递减
end if;
end if;
end if;
q<=tmp;--信号输出
end process;
end behav;
正弦波发生器:这里我设计了64个状态,就是将一个周期的正弦波分成64分,在然后一份份的数字信号输出就可以了。具体怎么取值,用excel计算就可以了。自己手动计算也可以的哦。
具体程序设计如下:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
entity sin1 is
port(clk,clr:in std_logic;
d:out integer range 0 to 255);
end entity;
architecture behav of sin1 is
begin
process(clk,clr)
variable tmp:integer range 0 to 63;
begin
if clr='0' then
d<=0;
elsif clk'event and clk='1' then
if tmp=63 then
tmp:=0;
else
tmp:=tmp+1;
end if;
case tmp is
when 00=>d<=255; when 01=>d<=254;when 02=>d<=252;
when 03=>d<=249; when 04=>d<=245;when 05=>d<=239;
when 06=>d<=233; when 07=>d<=225;when 08=>d<=217;
when 09=>d<=207; when 10=>d<=197;when 11=>d<=186;
when 12=>d<=174; when 13=>d<=162;when 14=>d<=150;
when 15=>d<=137; when 16=>d<=124;when 17=>d<=112;
when 18=>d<=99; when 19=>d<=87; when 20=>d<=75;
when 21=>d<=64; when 22=>d<=53; when 23=>d<=43;
when 24=>d<=34; when 25=>d<=26; when 26=>d<=19;
when 27=>d<=13; when 28=>d<=8; when 29=>d<=4;
when 30=>d<=1; when 31=>d<=0; when 32=>d<=0;
when 33=>d<=1; when 34=>d<=4; when 35=>d<=8;
when 36=>d<=13; when 37=>d<=19; when 38=>d<=26;
when 39=>d<=34; when 40=>d<=43; when 41=>d<=53;
when 42=>d<=64; when 43=>d<=75; when 44=>d<=87;
when 45=>d<=99; when 46=>d<=112;when 47=>d<=124;
when 48=>d<=137; when 49=>d<=150;when 50=>d<=162;
when 51=>d<=174; when 52=>d<=186;when 53=>d<=197;
when 54=>d<=207; when 55=>d<=217;when 56=>d<=225;
when 57=>d<=233; when 58=>d<=239;when 59=>d<=245;
when 60=>d<=249; when 61=>d<=252;when 62=>d<=252;
when 63=>d<=255;
when others=>null;
end case;
end if;
end process;
end behav;
阶梯波发生器:实质上是一个直线递增的数字信号输出而已,和三角波发生没有什么差别。
--工程名:阶梯波信号发生器
--功能:改变该模块递增的常数,可以改变阶梯的个数
--时间:2010-12-17
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
entity ladder1 is
port(clk:in std_logic; --时钟信号
rst:in std_logic; --复位信号
q:out std_logic_vector(7 downto 0)); --输出信号
end entity;
architecture behav of ladder1 is
begin
process(clk,rst)
variable tmp:std_logic_vector(7 downto 0);
variable a:std_logic;
begin
if(rst='0') then --复位
tmp:="00000000";
elsif clk'event and clk='1' then
if a='0' then
if tmp="11111111" then
tmp:="00000000";
a:='1';
else
tmp:=tmp+16; --以常数递增
a:='1';
end if;
else
a:='0';
end if;
end if;
q<=tmp; --信号输出
end process;
end behav;
4选1模块
最后我们要将模块进行整合,就需要设计一个选通模块,进行选择。
具体程序设计如下:
--工程名:4选1模块选择器
--功能:选通模块作用
--时间:2010-12-17
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
entity select4_1 is
port(sel:in std_logic_vector(1 downto 0); --选择信号
d0,d1,d2,d3:in std_logic_vector(7 downto 0); --4个信号发生器通道
q:out std_logic_vector(7 downto 0)); --输出通道
end entity;
architecture behav of select4_1 is
begin
process(sel)
begin
case sel is --选择
when"00"=> q<=d0;
when"01"=> q<=d1;
when"10"=> q<=d2;
when"11"=> q<=d3;
end case;
end process;
end behav;
最后将所有模块就连接起来进行图形化设计;
进行仿真。
最后进行硬件调试,通过DA将8位的数字信号转化成电压信号就能完成了整个系统的设计了。
总结:通过设计这个简单的数字信号发生器,我彻底的了解了如何设计一个函数发生器。一直以来都想设计这个一个东西,所以今天终于完成了我一直以来的心愿了。但是这仅仅是开始,要设计一个很好信号发生器,需要使用DDS的技术,因此希望我以后更加再接再厉,慢慢稳健的成长起来。
文章评论(0条评论)
登录后参与讨论