原创 VHDL实验四:函数信号发生器设计

2010-12-20 16:50 4826 5 5 分类: FPGA/CPLD

设计要求:设计一个函数信号发生器,能产生方波,三角波,正弦波,阶梯波。


设计概述:信号的输出实质上是指电压幅度随时间的变化。根据这个原理我们就可以设计函数信号发生器了。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的技术,因此希望我以后更加再接再厉,慢慢稳健的成长起来。

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
5
关闭 站长推荐上一条 /3 下一条