多功能波形發(fā)生器VHDL程序與仿真
?
?
?
?
--文件名:mine4.vhd。?
?
--功能:實現(xiàn)4種常見波形正弦、三角、鋸齒、方波(A、B)的頻率、幅度可控輸出(方波
?
?
--A的占空比也是可控的),可以存儲任意波形特征數(shù)據(jù)并能重現(xiàn)該波形,還可完成
?
?
--各種波形的線形疊加輸出。
?
?
--說明: SSS(前三位)和SW信號控制4種常見波形種哪種波形輸出。4種波形的頻率、
?
?
--幅度(基準幅度A)的調(diào)節(jié)均是通過up、down、set按鍵和4個BCD碼置入器以及一
?
?
--個置入檔位控制信號(ss)完成的(AMP的調(diào)節(jié)范圍是0~5V,調(diào)節(jié)量階為1/51V)。
?
?
--其中方波的幅度還可通過u0、d0調(diào)節(jié)輸出數(shù)據(jù)的歸一化幅值(AMP0)進行進一步
?
?
--細調(diào)(調(diào)節(jié)量階為1/(51*255)V)。方波A的占空比通過zu、zp按鍵調(diào)節(jié)(調(diào)節(jié)
?
?
--量階1/64*T)。系統(tǒng)采用內(nèi)部存儲器——RAM實現(xiàn)任意輸入波形的存儲,程序只支
?
?
--持鍵盤式波形特征參數(shù)置入存儲,posting 為進入任意波置入(set)、清除(clr)狀態(tài)
?
?
--控制信號,SSS控制存儲波形的輸出。P180為預留端口,
?
?
--最后修改日期:2004.3.26。
?
?
library ieee;
?
?
use ieee.std_logic_1164.all;
?
?
use ieee.std_logic_arith.all;
?
?
use ieee.std_logic_unsigned.all;
?
?
entity mine4 is
?
?
port(clk : in std_logic;??????????????????????????????????????? --時鐘信號輸入
?
?
????? set, clr, up, down, zu, zd : in std_logic;????????????? --各個波形特征的調(diào)節(jié)觸發(fā)信號
?
?
????? posting : in std_logic;??????????????????????????????????? --任意波鍵盤置入信號
?
?
?????? ? u0,d0,sw : in std_logic;????????? ?--方波A、B的切換sw,和方波B的幅度調(diào)節(jié)按鍵
?
?
????? ss : in std_logic_vector( 3 downto 0 );??????????????????????? --檔位選擇信號
?
?
????? sss : in std_logic_vector( 4 downto 0 );?????????????????????? --波形選擇信號
?
?
????? Data3, Data2, Data1,Data0 : in std_logic_vector(3 downto 0); --BCD碼輸入
?
?
?????? ? p180 : out std_logic;????????????????????????????????????? --預留接口
?
?
????? lcd : out std_logic_vector(7 downto 0);?????????????????? ????--顯示輸出
?
?
????? shift : out std_logic_vector(3 downto 0);????????????????????? --位碼輸出
?
?
????? dd, a : out std_logic_vector( 7 downto 0));??????????????????? --波形、幅度數(shù)據(jù)輸出
?
?
end mine4;
?
?
architecture behav of mine4 is
?
?
subtype word is std_logic_vector( 7 downto 0 );
?
?
type? unit is array(63 downto 0) of word;
?
?
signal ram : unit;
?
?
signal qqq : integer range 0 to 250000000;
?
?
signal qq : integer range 0 to 78125000;
?
?
signal tmp : integer range 0 to 9999;
?
?
signal coun : integer range 0 to 78125000;
?
?
signal coun0 : integer range 0 to 250000000;
?
?
signal b : integer range 0 to 78125000;
?
?
signal c : integer range 0 to 500000000;
?
?
signal z, con : integer range 0 to 63;
?
?
signal f : std_logic_vector( 7 downto 0 );
?
?
signal amp, amp0, d : std_logic_vector(7 downto 0);
?
?
signal bcd0,bcd1,bcd2,bcd3 : integer range 0 to 9;
?
?
signal bcd01,bcd11,bcd21,bcd31 : integer range 0 to 9;
?
?
signal bcd00,bcd10,bcd20,bcd30 : integer range 0 to 9;
?
?
signal y : integer range 0 to 9;
?
?
signal addr : integer range 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,實現(xiàn)方波A和其他三種波形的頻率預置
?
?
qqq<= 500000 when ss="1000" else?
?
?
????? 5000000 when ss="0100" else
?
?
????? 50000000 when ss="0010" else
?
?
50000;
?
?
--qqq信號對應SW=1時的檔位選擇信號SS,實現(xiàn)方波B的頻率預置
?
?
?
?
?
process(clk)
?
?
--此進程分別描述了各種波形的頻率、幅度(方波A的占空比)調(diào)節(jié)以及各種波形的任意線
?
?
--形疊加等。
?
?
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);
?
?
variable dd0,dd1,dd2,dd3,dd4 : integer range 0 to 255;
?
?
variable adr : integer range 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' then ram(adr)<=conv_std_logic_vector((conv_integer(Data1)*10
?
?
+conv_integer(Data0))*2,8); --對置入的任意波形數(shù)據(jù)進行儲存
?
?
????????????? ? elsif clr='1' then? adr:=0;??????????????????????? ?????--存儲器所有單元清零
?
?
????????????? ??? for i in 0 to 63 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);????? --頻率數(shù)據(jù)
?
?
????? amp<="01111111";???????????????????????????????????? --幅值
?
?
????? else
?
?
??????? if tmp>0 then
?
?
????????? if sw='0' then
?
?
??????????? if coun
?
?
??????????? else
?
?
????????????? if count=b then count:=1;
?
?
??????????????? if f=63 then f<="00000000";
?
?
??????????????? else f<=f+1;
?
?
??????????????? end if;
?
?
???????????????????? ??? if sss="00010" then????????????????????????????? ????????--方波A
?
?
????????????????? if con<=z then? dd<=amp0; con<=con+1;
?
?
???????????????????? ????? elsif con=63 then con<=0; dd<="00000000";
?
?
???????????????????? ????? else con<=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 then dd<=("111111"-f(5 downto 0))&"00";
?
?
????????????????? else dd<=f(5 downto 0)&"00";
?
?
?? ???????????????end if;
?
?
???????????????????? ??? elsif sss="00001" then?????????????????????????????????? --任意波
?
?
????????????????? if addr<63 then dd<=ram(addr); addr<=addr+1;
?
?
????????????????? elsif addr=63 then dd<=ram(63); addr<=0;
?
?
????????????????? end if;
?
?
?????????????? ?else????????????????????????????????? --完成5種波形的線形疊加
?
?
???????????????????? ????? if sss(1)='1' then
?
?
??????????????????? if con<=z then con<=con+1;
?
?
dd0:=conv_integer(amp0);????? --方波波形數(shù)據(jù)dd0
?
?
???????????????????? ??????? else con<=con+1; dd0:=0;
?
?
??????????????????? end if;
?
?
??????????????????????????? ? end if;
?
?
?????? ???????????if sss(4)='1' then dd1:=conv_integer(d);??????? --正弦波波形數(shù)據(jù)dd1
?
?
????????????????? end if;
?
?
????????????????? if sss(2)='1' then dd2:=conv_integer(f(5 downto 0)&"00");
?
?
????????????????????????????????????????????????????????? --鋸齒波波形數(shù)據(jù)dd2
?
?
?????????? ???????end if;???????????
?
?
??????????????????????????? ? if sss(3)='1' then
?
?
??????????????????? if f>31 then dd3:=conv_integer(("111111"-f(5 downto 0))&"00");
?
?
??????????????????? else dd3:=conv_integer(f(5 downto 0)&"00"); --三角波波形數(shù)據(jù)dd3
?
?
??????????????????? end if;
?
?
?????????????? ???end if;
?
?
????????????????? if sss(0)='1' then
?
?
??????????????????? if addr<63 then dd4:=conv_integer(ram(addr)); addr<=addr+1;
?
?
??????????????????? elsif addr=63 then dd4:=conv_integer(ram(63)); addr<=0;
?
?
??????????????????? end if;??????????????????????? ????????--任意波波形數(shù)據(jù)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
?
?
??????????? else
?
?
????????????? if count3<=c/2 then count3:=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=12499999 then count1:=0;?????????????????????? --調(diào)方波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;
?
?
?????? ??? else count1:=count1+1;
?
?
?????? ??? end if;
?
?
??????? if count0=3249999 then count0:=0;
?
?
--up、down對4種波形幅度調(diào)節(jié),u0、d0進一步對方波進行幅度調(diào)節(jié)
?
?
?????? ????? if u0='1' then
?
?
????????????? ??? if amp0<"11111111" then amp0<=amp0+1;
?
?
????????????? ??? else amp0<="11111111";
?
?
????????????? ??? end if;
?
?
????????????? ? elsif d0='1' then
?
?
????????????? ??? if amp0>"00000000" then amp0<=amp0-1;
?
?
?? else amp0<="00000000";
?
?
????????????? ??? end if;
?
?
????????? elsif up='1' then
?
?
??????????? if amp<"11111111" then amp<=amp+1;
?
?
??????????? else amp<="11111111";
?
?
??????????? end if;
?
?
????????? elsif down='1' then
?
?
??????????? if amp>"00000000" then amp<=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)????????
?
?
--主要實現(xiàn)各波形幅度值到BCD碼的轉化,由于方波和其他三種波形的幅度調(diào)節(jié)方式、精
?
?
--度不同,因此對幅度的處理方式分兩種:“sss="00010" or sw='1'”是判斷輸出波形是否為
?
?
--方波(A或B),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' then count0:=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; ?--數(shù)據(jù)輸出
?
?
????? else count1:=count1+1;???????????????????????? --二進制碼到BCD碼的數(shù)據(jù)轉換
?
?
?????? ?if count>9999999 then count:=count-10000000; bcd0<=bcd0+1;
?
?
??????? elsif count>999999 then count:=count-1000000; bcd1<=bcd1+1;
?
?
??????? elsif count>99999 then count:=count-100000; bcd2<=bcd2+1;
?
?
??????? elsif count>9999 then count:=count-10000; bcd3<=bcd3+1;
?
?
??????? else null;
?
?
??????? end if;
?
?
????? end if;
?
?
??? else count1:=0;??????????????????????????????????????? --正弦波、三角波、鋸齒波
?
?
????? if count0=4999999 then counter:=conv_integer(amp)*1961;
?
?
count0:=0; bcd01<=0; bcd11<=0; bcd21<=0; bcd31<=0;
?
?
?????? ? elsif count0=4999000 then bcd00<=bcd01; bcd10<=bcd11; bcd20<=bcd21;
?
?
bcd30<=bcd31; count0:=count0+1;
?
?
????? else count0:=count0+1;
?
?
?????? ??? if counter>99999 then counter:=counter-100000; bcd01<=bcd01+1;
?
?
??????? elsif counter>9999 then counter:=counter-10000; bcd11<=bcd11+1;
?
?
? ??????elsif counter>999 then counter:=counter-1000; bcd21<=bcd21+1;
?
?
??????? elsif counter>99 then counter:=counter-100; bcd31<=bcd31+1;
?
?
??????? else null;
?
?
??????? end if;
?
?
????? end if;
?
?
??? end if;
?
?
? end if;
?
?
end process;
?
?
?
?
?
process(clk)?????????????????????? ??????--輸出波形幅度(峰-峰值)數(shù)據(jù)譯碼動態(tài)顯示
?
?
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 downto 1)<="0000001";
?
?
??? when 1 => lcd(7 downto 1)<="1001111";
?
?
??? when 2 => lcd(7 downto 1)<="0010010";
?
?
??? when 3 => lcd(7 downto 1)<="0000110";
?
?
??? when 4 => lcd(7 downto 1)<="1001100";
?
?
??? when 5 => lcd(7 downto 1)<="0100100";
?
?
??? when 6 => lcd(7 downto 1)<="0100000";
?
?
??? when 7 => lcd(7 downto 1)<="0001111";
?
?
??? when 8 => lcd(7 downto 1)<="0000000";
?
?
??? when 9 => lcd(7 downto 1)<="0000100";
?
?
when others => lcd(7 downto 1)<="0000001";
?
?
end case;
?
?
end process;
?
?
?
?
?
ym:process(clk)????????????????? --正弦波在一個周期內(nèi)時域上的64個采樣點的波形數(shù)據(jù)
?
?
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;
?
?
評論
查看更多