我们从2011年坚守至今,只想做存粹的技术论坛。  由于网站在外面,点击附件后要很长世间才弹出下载,请耐心等待,勿重复点击不要用Edge和IE浏览器下载,否则提示不安全下载不了

 找回密码
 立即注册
搜索
查看: 1395|回复: 1

[技术讨论] 波形发生程序

[复制链接]

该用户从未签到

6

主题

8

回帖

7

积分

一级逆天

积分
7

终身成就奖

QQ
发表于 2016-8-30 11:46:25 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区

您需要 登录 才可以下载或查看,没有账号?立即注册

×
8.23多功能波形发生器VHDL程序与仿真
--文件名:mine4.vhd
--功能:实现4种常见波形正弦、三角、锯齿、方波(AB)的频率、幅度可控输出(方波
--A的占空比也是可控的),可以存储任意波形特征数据并能重现该波形,还可完成
--各种波形的线形叠加输出。
--说明: SSS(前三位)和SW信号控制4种常见波形种哪种波形输出。4种波形的频率、
--幅度(基准幅度A)的调节均是通过updownset按键和4BCD码置入器以及一
--个置入档位控制信号(ss)完成的(AMP的调节范围是0~5V,调节量阶为1/51V)。
--其中方波的幅度还可通过u0d0调节输出数据的归一化幅值(AMP0)进行进一步
--细调(调节量阶为1/51*255V)。方波A的占空比通过zuzp按键调节(调节
--量阶1/64*T)。系统采用内部存储器——RAM实现任意输入波形的存储,程序只支
--持键盘式波形特征参数置入存储,posting 为进入任意波置入(set)、清除(clr)状态
--控制信号,SSS控制存储波形的输出。P180为预留端口,
--最后修改日期:2004.3.26
library ieee;
useieee.std_logic_1164.all;
useieee.std_logic_arith.all;
useieee.std_logic_unsigned.all;
entity mine4 is
port(clk : in std_logic;                                        --时钟信号输入
      set, clr, up, down, zu, zd : instd_logic;              --各个波形特征的调节触发信号
      posting : in std_logic;                                    --任意波键盘置入信号
         u0,d0,sw : instd_logic;           --方波AB的切换sw,和方波B的幅度调节按键
      ss : in std_logic_vector( 3 downto 0);                        --档位选择信号
      sss : in std_logic_vector( 4 downto 0);                       --波形选择信号
      Data3, Data2, Data1,Data0 : instd_logic_vector(3 downto 0); --BCD码输入
         p180 : outstd_logic;                                     --预留接口
      lcd : out std_logic_vector(7 downto0);                       --显示输出
      shift : out std_logic_vector(3 downto0);                      --位码输出
      dd, a : out std_logic_vector( 7 downto0));                    --波形、幅度数据输出
end mine4;
architecture behav ofmine4 is
subtype word isstd_logic_vector( 7 downto 0 );
type  unit is array(63 downto 0) of word;
signal ram : unit;
signal qqq : integerrange 0 to 250000000;
signal qq : integerrange 0 to 78125000;
signal tmp : integerrange 0 to 9999;
signal coun : integerrange 0 to 78125000;
signal coun0 : integerrange 0 to 250000000;
signal b : integerrange 0 to 78125000;
signal c : integerrange 0 to 500000000;
signal z, con : integerrange 0 to 63;
signal f :std_logic_vector( 7 downto 0 );
signal amp, amp0, d :std_logic_vector(7 downto 0);
signalbcd0,bcd1,bcd2,bcd3 : integer range 0 to 9;
signalbcd01,bcd11,bcd21,bcd31 : integer range 0 to 9;
signalbcd00,bcd10,bcd20,bcd30 : integer range 0 to 9;
signal y : integerrange 0 to 9;
signal addr : integerrange 0 to 63;
begin
qq<=781250 when ss="1000" else
      7812500 when ss="0100" else
      78125000 when ss="0010" else
      78125;
--qq信号对应SW=0时的档位选择信号SS,实现方波A和其他三种波形的频率预置
qqq<= 500000 when ss="1000" else  
      5000000 when ss="0100" else
      50000000 when ss="0010" else
50000;
--qqq信号对应SW=1时的档位选择信号SS,实现方波B的频率预置

process(clk)
--此进程分别描述了各种波形的频率、幅度(方波A的占空比)调节以及各种波形的任意线
--形叠加等。
variable count4 :integer range 0 to 6250000;
variable count :integer range 0 to 78125000;
variable count3 :integer range 0 to 250000000;
variable count1 :integer range 0 to 12500000;
variable count0 :integer range 0 to 3249999;
variable ddd :std_logic_vector(9 downto 0);
variabledd0,dd1,dd2,dd3,dd4 : integer range 0 to 255;
variable adr : integerrange 0 to 63;
begin
if rising_edge(clk) then
    if posting='1' then                              
      if count4=6249999 then count4:=0;              
adr:=conv_integer(Data3)*10+conv_integer(Data2);--存储单位地址
        if adr<64 then   
          if set='1' thenram(adr)<=conv_std_logic_vector((conv_integer(Data1)*10
+conv_integer(Data0))*2,8); --对置入的任意波形数据进行储存
                elsif clr='1'then  adr:=0;                             --存储器所有单元清零
                  for i in 0 to63 loop
                     ram(i)<=(others=>'0');
                     end loop;
          end if;
        end if;
      else count4:=count4+1;
      end if;
    else
if set='1' then coun<=0; b<=0;coun0<=0;c<=0;z<=31;amp0<="01111111"; addr<=0;
tmp<=conv_integer(Data3)*1000+conv_integer(Data2)*100
+conv_integer(Data1)*10+conv_integer(Data0);      --频率数据
     amp<="01111111";                                     --幅值
      else
        if tmp>0 then
          if sw='0' then
            if coun<qq then coun<=coun+tmp;b<=b+1;    --频率到采样点间隔脉冲数转换  
            else
              if count=b then count:=1;
                if f=63 thenf<="00000000";
                else f<=f+1;
                end if;
                         ifsss="00010" then                                      --方波A
                  if con<=z then  dd<=amp0; con<=con+1;
                          elsif con=63 then con<=0; dd<="00000000";
                           elsecon<=con+1; dd<="00000000";
                  end if;
                elsif sss="10000"then dd<=d;                             --正弦波
                elsif sss="00100"then dd<=f(5 downto 0)&"00";              --锯齿波
                elsif sss="01000"then --三角波
                  if f>31 thendd<=("111111"-f(5 downto 0))&"00";
                  else dd<=f(5 downto0)&"00";
                  end if;
                         elsifsss="00001" then                                   --任意波
                  if addr<63 thendd<=ram(addr); addr<=addr+1;
                  elsif addr=63 thendd<=ram(63); addr<=0;
                  end if;
                else                                  --完成5种波形的线形叠加
                           ifsss(1)='1' then
                    if con<=z thencon<=con+1;
dd0:=conv_integer(amp0);      --方波波形数据dd0
                            else con<=con+1; dd0:=0;
                    end if;
                             end if;
                  if sss(4)='1' thendd1:=conv_integer(d);        --正弦波波形数据dd1
                  end if;
                  if sss(2)='1' thendd2:=conv_integer(f(5 downto 0)&"00");
                                                         --锯齿波波形数据dd2
                  end if;            
                             if sss(3)='1' then
                    if f>31 thendd3:=conv_integer(("111111"-f(5 downto 0))&"00");
                    else dd3:=conv_integer(f(5downto 0)&"00"); --三角波波形数据dd3
                    end if;
                  end if;
                  if sss(0)='1' then
                    if addr<63 thendd4:=conv_integer(ram(addr)); addr<=addr+1;
                    elsif addr=63 thendd4:=conv_integer(ram(63)); addr<=0;
                    end if;                                --任意波波形数据dd4
                  end if;
                        ddd:=conv_std_logic_vector((dd0+dd1+dd2+dd3+dd4),10);
--波形线形叠加输出
                            dd<=ddd(9 downto 2);
                end if;
              else count:=count+1;
              end if;
            end if;
          else
            if coun0<qqq thencoun0<=coun0+tmp; c<=c+1;
            else
              if count3<=c/2 thencount3:=count3+1; dd<=amp0;
              elsif count3=c then count3:=1;dd<="00000000";
              else count3:=count3+1;dd<="00000000";
              end if;
            end if;
          end if;  
        end if;
           if count1=12499999then count1:=0;                       --调方波A的占空比
             if zu='1' then
            if z<63 then z<=z+1;
            else z<=63;
            end if;
          elsif zd='1' then
            if z>0 then z<=z-1;
            else z<=0;
            end if;
          end if;
           elsecount1:=count1+1;
           end if;
        if count0=3249999 then count0:=0;
--updown4种波形幅度调节,u0d0进一步对方波进行幅度调节
             if u0='1' then
                  ifamp0<"11111111" then amp0<=amp0+1;
                  elseamp0<="11111111";
                  end if;
                elsif d0='1'then
                  ifamp0>"00000000" then amp0<=amp0-1;
   elseamp0<="00000000";
                  end if;
          elsif up='1' then
            if amp<"11111111" thenamp<=amp+1;
            else amp<="11111111";
            end if;
          elsif down='1' then
            if amp>"00000000" thenamp<=amp-1;
            else amp<="00000000";
            end if;
          end if;
        else count0:=count0+1;
        end if;
      end if;
end if;
end if;
end process;
a<=amp;                        --将幅值输出。

cov_a:process(clk,amp,amp0)         
--主要实现各波形幅度值到BCD码的转化,由于方波和其他三种波形的幅度调节方式、精
--度不同,因此对幅度的处理方式分两种:“sss="00010" or sw='1'”是判断输出波形是否为
--方波(AB),bcd00,bcd10,bcd20,bcd30是本进程的输出。
variable count :integer range 0 to 50004225;
variable counter :integer range 0 to 500055;
variable count1,count0: integer range 0 to 4999999;
begin
if rising_edge(clk) then
    if sss="00010" or sw='1' thencount0:=0;                                  --方波
      if count1=4999999 then count1:=0;bcd0<=0; bcd1<=0; bcd2<=0; bcd3<=0;
count:=(conv_integer(amp))*(conv_integer(amp0))*769; --幅值运算
     elsif count1=4999900 then count1:=count1+1;
bcd00<=bcd0; bcd10<=bcd1; bcd20<=bcd2;bcd30<=bcd3;  --数据输出
      else count1:=count1+1;                         --二进制码到BCD码的数据转换
        if count>9999999 thencount:=count-10000000; bcd0<=bcd0+1;
        elsif count>999999 thencount:=count-1000000; bcd1<=bcd1+1;
        elsif count>99999 thencount:=count-100000; bcd2<=bcd2+1;
        elsif count>9999 thencount:=count-10000; bcd3<=bcd3+1;
        else null;
        end if;
      end if;
    else count1:=0;                                        --正弦波、三角波、锯齿波
      if count0=4999999 thencounter:=conv_integer(amp)*1961;
count0:=0; bcd01<=0; bcd11<=0; bcd21<=0;bcd31<=0;
         elsif count0=4999000then bcd00<=bcd01; bcd10<=bcd11; bcd20<=bcd21;
bcd30<=bcd31; count0:=count0+1;
      else count0:=count0+1;
           if counter>99999then counter:=counter-100000; bcd01<=bcd01+1;
        elsif counter>9999 thencounter:=counter-10000; bcd11<=bcd11+1;
        elsif counter>999 thencounter:=counter-1000; bcd21<=bcd21+1;
        elsif counter>99 thencounter:=counter-100; bcd31<=bcd31+1;
        else null;
        end if;
      end if;
    end if;
  end if;
end process;

process(clk)                             --输出波形幅度(峰-峰值)数据译码动态显示
variable count :integer range 0 to 499999;
begin
if rising_edge(clk) then
    if count<=124999 then y<=bcd00;count:=count+1; shift<="0111"; lcd(0)<='0';
    elsif count<=249999 then y<=bcd10;count:=count+1; shift<="1011";lcd(0)<='1';
    elsif count<=374999 then y<=bcd20;count:=count+1; shift<="1101";lcd(0)<='1';
    elsif count<499999 then y<=bcd30;count:=count+1; shift<="1110";lcd(0)<='1';
    elsif count=499999 then y<=bcd30;count:=0; shift<="1110";lcd(0)<='1';
    end if;
end if;
case y is                               --7段码译码
    when 0 => lcd(7 downto1)<="0000001";
    when 1 => lcd(7 downto1)<="1001111";
    when 2 => lcd(7 downto1)<="0010010";
    when 3 => lcd(7 downto1)<="0000110";
    when 4 => lcd(7 downto1)<="1001100";
    when 5 => lcd(7 downto1)<="0100100";
    when 6 => lcd(7 downto1)<="0100000";
    when 7 => lcd(7 downto1)<="0001111";
    when 8 => lcd(7 downto1)<="0000000";
    when 9 => lcd(7 downto1)<="0000100";
when others => lcd(7 downto 1)<="0000001";
end case;
end process;

ym:process(clk)                  --正弦波在一个周期内时域上的64个采样点的波形数据
begin
if rising_edge(clk) then
case f is
when "00000000"=>d<="11111111"  ; when"00000001"=> d<="11111110"  ;
when "00000010"=>d<="11111100"  ;when"00000011"=> d<="11111001"  ;
when "00000100"=> d<="11110101"  ; when "00000101"=>d<="11101111"  ;
when "00000110"=>d<="11101001"  ;when"00000111"=> d<="11100001"  ;
when "00001000"=>d<="11011001"  ; when"00001001"=> d<="11001111"  ;
when "00001010"=>d<="11000101"  ;when"00001011"=> d<="10111010"  ;
when "00001100"=>d<="10101110"  ; when"00001101"=> d<="10100010"  ;
when "00001110"=>d<="10010110"  ;when"00001111"=> d<="10001001"  ;
when "00010000"=>d<="01111100"  ; when"00010001"=> d<="01110000"  ;
when "00010010"=>d<="01100011"  ;when"00010011"=> d<="01010111"  ;
when "00010100"=>d<="01001011"  ; when"00010101"=> d<="01000000"  ;
when "00010110"=>d<="00110101"  ;when"00010111"=> d<="00101011"  ;
when "00011000"=>d<="00100010"  ; when"00011001"=> d<="00011010"  ;
when "00011010"=>d<="00010011"  ;when"00011011"=> d<="00001101"  ;
when "00011100"=>d<="00001000"  ; when"00011101"=> d<="00000100"  ;
when "00011110"=>d<="00000001"  ;when"00011111"=> d<="00000000"  ;
when "00100000"=>d<="00000000"  ; when"00100001"=> d<="00000001"  ;
when "00100010"=>d<="00000100"  ;when"00100011"=> d<="00001000"  ;
when "00100100"=>d<="00001101"  ; when"00100101"=> d<="00010011"  ;
when "00100110"=>d<="00011010"  ;when"00100111"=> d<="00100010"  ;
when "00101000"=>d<="00101011"  ; when"00101001"=> d<="00110101"  ;
when "00101010"=>d<="01000000"  ;when"00101011"=> d<="01001011"  ;
when "00101100"=>d<="01010111"  ; when"00101101"=> d<="01100011"  ;
when "00101110"=>d<="01110000"  ;when"00101111"=> d<="01111100"  ;
when "00110000"=>d<="10001001"  ; when"00110001"=> d<="10010110"  ;
when "00110010"=>d<="10100010"  ;when"00110011"=> d<="10101110"  ;
when "00110100"=>d<="10111010"  ; when"00110101"=> d<="11000101"  ;
when "00110110"=>d<="11001111"  ;when"00110111"=> d<="11011001"  ;
when "00111000"=>d<="11100001"  ; when"00111001"=> d<="11101001"  ;
when "00111010"=>d<="11101111"  ;when"00111011"=> d<="11110101"  ;
when "00111100"=>d<="11111001"  ; when"00111101"=> d<="11111100"  ;
when "00111110"=>d<="11111110"  ;when"00111111"=> d<="11111111"  ;
when others=> null;
end case;
end if;
end process;
p180<='1';
end behav;
回复

使用道具 举报

该用户从未签到

6

主题

2173

回帖

10

积分

二级逆天

积分
10

终身成就奖优秀斑竹奖

QQ
发表于 2016-12-11 08:59:36 | 显示全部楼层
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

每日签到,有金币领取。


Copyright ©2011-2024 NTpcb.com All Right Reserved.  Powered by Discuz! (NTpcb)

本站信息均由会员发表,不代表NTpcb立场,如侵犯了您的权利请发帖投诉

( 闽ICP备2024076463号-1 ) 论坛技术支持QQ群171867948 ,论坛问题,充值问题请联系QQ1308068381

平平安安
TOP
快速回复 返回顶部 返回列表