多功能波形發(fā)生器VHDL程序與仿真 --文件名:mine4.vhd。 --功能:實(shí)現(xiàn)4種常見(jiàn)波形正弦、三角、鋸齒、方波(A、B)的頻率、幅度可控輸出(方波 --A的占空比也是可控的),可以存儲(chǔ)任意波形特征數(shù)據(jù)并能重現(xiàn)該波形,還可完成 --各種波形的線形疊加輸出。 --說(shuō)明: SSS(前三位)和SW信號(hào)控制4種常見(jiàn)波形種哪種波形輸出。4種波形的頻率、 --幅度(基準(zhǔn)幅度A)的調(diào)節(jié)均是通過(guò)up、down、set按鍵和4個(gè)BCD碼置入器以及一 --個(gè)置入檔位控制信號(hào)(ss)完成的(AMP的調(diào)節(jié)范圍是0~5V,調(diào)節(jié)量階為1/51V)。 --其中方波的幅度還可通過(guò)u0、d0調(diào)節(jié)輸出數(shù)據(jù)的歸一化幅值(AMP0)進(jìn)行進(jìn)一步 --細(xì)調(diào)(調(diào)節(jié)量階為1/(51*255)V)。方波A的占空比通過(guò)zu、zp按鍵調(diào)節(jié)(調(diào)節(jié) --量階1/64*T)。系統(tǒng)采用內(nèi)部存儲(chǔ)器——RAM實(shí)現(xiàn)任意輸入波形的存儲(chǔ),程序只支 --持鍵盤(pán)式波形特征參數(shù)置入存儲(chǔ),posting 為進(jìn)入任意波置入(set)、清除(clr)狀態(tài) --控制信號(hào),SSS控制存儲(chǔ)波形的輸出。P180為預(yù)留端口, --最后修改日期: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; --時(shí)鐘信號(hào)輸入 set, clr, up, down, zu, zd : in std_logic; --各個(gè)波形特征的調(diào)節(jié)觸發(fā)信號(hào) posting : in std_logic; --任意波鍵盤(pán)置入信號(hào) u0,d0,sw : in std_logic; --方波A、B的切換sw,和方波B的幅度調(diào)節(jié)按鍵 ss : in std_logic_vector( 3 downto 0 ); --檔位選擇信號(hào) sss : in std_logic_vector( 4 downto 0 ); --波形選擇信號(hào) Data3, Data2, Data1,Data0 : in std_logic_vector(3 downto 0); --BCD碼輸入 p180 : out std_logic; --預(yù)留接口 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信號(hào)對(duì)應(yīng)SW=0時(shí)的檔位選擇信號(hào)SS,實(shí)現(xiàn)方波A和其他三種波形的頻率預(yù)置 qqq<= 500000 when ss="1000" else 5000000 when ss="0100" else 50000000 when ss="0010" else 50000; --qqq信號(hào)對(duì)應(yīng)SW=1時(shí)的檔位選擇信號(hào)SS,實(shí)現(xiàn)方波B的頻率預(yù)置 process(clk) --此進(jìn)程分別描述了各種波形的頻率、幅度(方波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);--存儲(chǔ)單位地址 if adr<64 then if set='1' then ram(adr)<=conv_std_logic_vector((conv_integer(Data1)*10 +conv_integer(Data0))*2,8); --對(duì)置入的任意波形數(shù)據(jù)進(jìn)行儲(chǔ)存 elsif clr='1' then adr:=0; --存儲(chǔ)器所有單元清零 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<qq then coun<=coun+tmp; b<=b+1; --頻率到采樣點(diǎn)間隔脈沖數(shù)轉(zhuǎn)換 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<qqq then coun0<=coun0+tmp; c<=c+1; 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對(duì)4種波形幅度調(diào)節(jié),u0、d0進(jìn)一步對(duì)方波進(jìn)行幅度調(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) --主要實(shí)現(xiàn)各波形幅度值到BCD碼的轉(zhuǎn)化,由于方波和其他三種波形的幅度調(diào)節(jié)方式、精 --度不同,因此對(duì)幅度的處理方式分兩種:“sss="00010" or sw='1'”是判斷輸出波形是否為 --方波(A或B),bcd00,bcd10,bcd20,bcd30是本進(jìn)程的輸出。 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; --幅值運(yùn)算 elsif count1=4999900 then count1:=count1+1; bcd00<=bcd0; bcd10<=bcd1; bcd20<=bcd2; bcd30<=bcd3; --數(shù)據(jù)輸出 else count1:=count1+1; --二進(jìn)制碼到BCD碼的數(shù)據(jù)轉(zhuǎn)換 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ù)譯碼動(dòng)態(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) --正弦波在一個(gè)周期內(nèi)時(shí)域上的64個(gè)采樣點(diǎn)的波形數(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;
|