作為FPGA的愛好者,我們希望能夠更好的交流,更多的了解使用FPGA我們還能作哪些事情,能做到什么程度,能做到什么效果,這樣大家多這個行業(yè)會有更多的了解。 大家可以把一些不涉及秘密的源代碼公開于大家討論。這樣不僅能為初學(xué)者提供 學(xué)習(xí)的最佳資料(看一些枯燥的書是沒多大用的,個人感覺),也可以讓自己的項目能夠得到更多人的欣賞! 為了拋磚引玉,我先送上幾個源代碼 多進制數(shù)字頻率調(diào)制(MFSK)系統(tǒng)VHDL程序 --文件名:MFSK --功能:基于VHDL硬件描述語言,完成對基帶信號的MFSK調(diào)制 --說明:這里MFSK的M為4 --最后修改日期:2004.2.13 library ieee; use ieee.std_logic_arith.all; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity MFSK is port(clk :in std_logic; --系統(tǒng)時鐘 start :in std_logic; --開始調(diào)制信號 x :in std_logic; --基帶信號 y :out std_logic); --調(diào)制信號 end MFSK; architecture behav of MFSK is process(clk) process(clk,yy) --此進程完成對輸入基帶信號x的MFSK調(diào)制 begin if clk'event and clk='1' then if start='0' then y<='0'; -- if語句完成2位并行碼到4種載波的選通 elsif yy="00" then y<=not f(3); elsif yy="01" then y<=not f(2); elsif yy="10" then y<=not f(1); else y<=not f(0); end if; end if; end process; end behav;
--對輸入的基帶信號x進行串/并轉(zhuǎn)換,得到2位并行信號的yy begin if clk'event and clk='1' then if start='0' then q<=0; elsif q=0 then q<=1;xx(1)<=x;yy<=xx; elsif q=8 then q<=9;xx(0)<=x; else q<=q+1; end if; end if; end process; FPGA驅(qū)動LCD顯示中文字符“年”程序 --文件名:lcd_driver.vhd。 --功能:FGAD驅(qū)動LCD顯示中文字符“年”。 --最后修改日期:2004.3.24。 library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity lcd_driver is Port ( clk : in std_logic; --狀態(tài)機時鐘信號,同時也是液晶時鐘信號,其周期應(yīng)該滿足液晶數(shù)據(jù)的建立時間 reset:in std_logic; lcdda : out std_logic; --寄存器選擇信號 lcdrw : out std_logic; --液晶讀寫信號 lcden : out std_logic; --液晶時鐘信號 data : out std_logic_vector(7 downto 0)); --液晶數(shù)據(jù)信號 end lcd_driver;
architecture Behavioral of lcd_driver is type state is (set_dlnf,set_cursor,set_dcb,set _cgram,write _cgram,set_ddram,write_data); signal current_state:state; type ram2 is array(0 to 7) of std_logic_vector(7 downto 0); constant cgram:ram2:=(("00001000"),("00001111"),("00010010"), ("00001111"),("00001010"),("00011111"),("00000010"),("00000010"));--年字符數(shù)據(jù)存儲器 signal clkk : std_logic; begin
lcden <= clk ; --液晶時鐘信號 lcdrw <= '0' ; --寫數(shù)據(jù)
control:process(clk,reset,current_state) --液晶驅(qū)動控制器 variable cnt1: std_logic_vector(2 downto 0); begin if reset='0'then current_state<=set_dlnf; cnt1:=(others => '1'); lcdda<='0'; elsif rising_edge(clk)then current_state <= current_state ; lcdda <= '0'; case current_state is when set_dlnf=> data<="00111100";--3cH current_state<=set_cursor; when set_cursor=> data<="00000110";--06H current_state<=set_dcb; when set_dcb=> data<="00001111";--0fH current_state<=set_ cgram; when set_ cgram=> data<="01000000";--40H current_state<=write_ cgram; when write_ cgram=> --向CGRAM中寫入“年” lcdda<='1'; cnt1:=cnt1+1; data<=cgram(conv_integer(cnt1)); if cnt1 = "111" then current_state<=set_ddram; end if; when set_ddram=> --從第一行的起始地址開始顯示 data<="10000000";--80H current_state<=write_data; when write_data=> lcdda<='1'; data<="00000000"; --寫入字符“年” when others => null; end case; end if; end process; end Behavioral;
FPGA驅(qū)動LED靜態(tài)顯示 --文件名:decoder.vhd --功能:譯碼輸出模塊,LED為共陽接法 --最后修改日期:2004.3.24 library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity decoder is Port (seg:in std_logic_vector(3 downto 0 ); --四位二進制碼輸入 q3:out std_logic_vector(6 downto 0) ); --輸出LED七段碼 end decoder;
architecture Behavioral of decoder is begin process(seg) begin case seg is when "0000" => q3<="0000001";--0 when "0001" => q3<="1001111";--1 when "0010" => q3<="0010010";--2 when "0011" => q3<="0000110";--3 when "0100" => q3<="1001100" --4 when "0101" => q3<="0100100";--5 when "0110" => q3<="0100000";--6 when "0111" => q3<="0001111";--7 when "1000" => q3<="0000000";--8 when "1001" => q3<="0000100";--9 when others => q3<="1111111"; end case; end process; end Behavioral; 例2:FPGA驅(qū)動LED動態(tài)顯示(4位) --文件名:dynamic.vhd。 --功能:動態(tài)掃描模塊,位選信號高電平有效。 --最后修改日期:2004.3.24。 library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity dynamic is Port ( clk : in std_logic; reset: in std_logic; din1 : in std_logic_vector(6 downto 0); --譯碼后的數(shù)據(jù)信號1(4位2進制數(shù)據(jù) 通過例1中的decoder模塊譯碼得到din1,din2,din3,din4) din2 : in std_logic_vector(6 downto 0); --譯碼后的數(shù)據(jù)信號2 din3 : in std_logic_vector(6 downto 0); --譯碼后的數(shù)據(jù)信號3 din4 : in std_logic_vector(6 downto 0); --譯碼后的數(shù)據(jù)信號4 shift: out std_logic_vector(3 downto 0); --位選信號 bus4 : out std_logic_vector(6 downto 0)); --數(shù)據(jù)信號 end dynamic;
architecture Behavioral of dynamic is signal scan_clk:std_logic_vector(1 downto 0); begin process(clk,scan_clk,reset) --分頻進程 variable scan:std_logic_vector(17 downto 0); begin if reset='1' then scan:="000000000000000000"; scan_clk<="00"; elsif clk'event and clk='1'then scan:=scan+1; end if; scan_clk<=scan(17 downto 16); end process;
process(scan_clk,din1,din2,din3,din4) --掃描進程 begin case scan_clk is when "00"=> bus4<=din1; shift<="0001"; when "01"=> bus4<=din2; shift<="0010"; when "10"=> bus4<=din3; shift<="0100"; when "11"=> bus4<=din4; shift<="1000"; when others=> bus4<="0000000";shift<="0000"; end case; end process;
end Behavioral;
ADC0809 VHDL控制程序 --文件名:ADC0809.vhd --功能:基于VHDL語言,實現(xiàn)對ADC0809簡單控制 --說明:ADC0809沒有內(nèi)部時鐘,需外接10KHz~1290Hz的時鐘信號,這里由FPGA的系 --統(tǒng)時鐘(50MHz)經(jīng)256分頻得到clk1(195KHz)作為ADC0809轉(zhuǎn)換工作時鐘。 --最后修改日期:2004.3.20 library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; use ieee.std_logic_arith.all; entity ADC0809 is port ( d : in std_logic_vector(7 downto 0); --ADC0809輸出的采樣數(shù)據(jù) clk,eoc : in std_logic; --clk為系統(tǒng)時鐘,eoc為ADC0809轉(zhuǎn)換結(jié)束信號 clk1,start, ale,en: out std_logic; --ADC0809控制信號 abc_in :in std_logic_vector(2 downto 0); --模擬選通信號 abc_out :out std_logic_vector(2 downto 0); --ADC0809模擬信號選通信號 q : out std_logic_vector(7 downto 0)); --送至8個并排數(shù)碼管信號 end ADC0809; architecture behav of ADC0809 is type states is ( st0,st1, st2, st3, st4,st5,st6); --定義各狀態(tài)的子類型 signal current_state, next_state:states:=st0; signal regl :std_logic_vector(7 downto 0); --中間數(shù)據(jù)寄存信號 signal qq:std_logic_vector(7 downto 0); begin com:process(current_state,eoc) --規(guī)定各種狀態(tài)的轉(zhuǎn)換方式 begin case current_state is when st0=>next_state<=st1;ale<='0';start<='0';en<='0'; when st1=>next_state<=st2;ale<='1';start<='0';en<='0'; when st2=>next_state<=st3;ale<='0';start<='1';en<='0'; when st3=> ale<='0';start<='0';en<='0'; if eoc='1' then next_state<=st3; --檢測EOC的下降沿 else next_state<=st4; end if; when st4=> ale<='0';start<='0';en<='0'; if eoc='0' then next_state<=st4; --檢測EOC的上升沿 else next_state<=st5; end if; when st5=>next_state<=st6;ale<='0';start<='0';en<='1'; when st6=>next_state<=st0;ale<='0';start<='0';en<='1';regl<=d; when others=> next_state<=st0;ale<='0';start<='0';en<='0'; end case; end process; clock:process(clk) --對系統(tǒng)時鐘進行分頻,得到ADC0809轉(zhuǎn)換工作時鐘 begin if clk'event and clk='1' then qq<=qq+1; --在clk1的上升沿,轉(zhuǎn)換至下一狀態(tài) if QQ="01111111" THEN clk1<='1'; current_state <=next_state; elsif qq<="01111111" then clk1<='0'; end if; end if; end process; q<=regl; abc_out<=abc_in; end behav;
TLC5510 VHDL控制程序 --文件名:TLC5510.vhd --功能:基于VHDL語言,實現(xiàn)對高速A/D器件TLC5510控制 --最后修改日期:2004.3.20 library ieee; use ieee.std_logic_1164.all; entity tlc5510 is port(clk :in std_logic; --系統(tǒng)時鐘 oe :out std_logic; --TLC5510的輸出使能/OE clk1:out std_logic; --TLC5510的轉(zhuǎn)換時鐘 din:in std_logic_vector(7 downto 0); --來自TLC5510的采樣數(shù)據(jù) dout:out std_logic_vector(7 downto 0)); --FPGA數(shù)據(jù)輸出 end tlc5510; architecture behav of tlc5510 is signal q:integer range 3 downto 0; begin process(clk) --此進程中,把CLK 進行4分頻,得到TLC5510的轉(zhuǎn)換時鐘 begin if clk'event and clk='1' then if q=3 then q<=0; else q<=q+1; end if; end if; if q>=2 then clk1<='1'; --對系統(tǒng)CLK進行4分頻 else clk1<='0'; end if; end process; oe<='0'; --輸出使能賦低電平 dout<=din; --采樣數(shù)據(jù)輸出 end behav;
DAC0832 接口電路程序 --文件名:DAC0832.VHD --功能:產(chǎn)生頻率為762.9Hz的鋸齒波。 --最后修改日期:2004.3.18。 library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; use ieee.std_logic_arith.all; entity DAC0832 is port(clk:in std_logic; --系統(tǒng)時鐘 rst:in std_logic; --復(fù)位信號 ile:out std_logic; --數(shù)據(jù)鎖存允許信號 cont:out std_logic; --控制信號(WR1、WR2、CS、Xfer) data_out:out std_logic_vector(7 downto 0)); --波形數(shù)據(jù)輸出 end DAC0832; architecture behav of DAC0832 is signal q:integer range 0 to 63; --計數(shù)器 signal data:std_logic_vector(7 downto 0); --波形數(shù)據(jù) begin process(clk) begin if rst='1' then q<=0; --復(fù)位,對計數(shù)器q清零 elsif clk'event and clk='1' then if q=63 then q<=0; --此IF語句對系統(tǒng)時鐘進行64分頻 if data="11111111" then data<="00000000"; --此IF語句產(chǎn)生鋸齒波波形數(shù)據(jù) else data<=data+1; end if; else q<=q+1; end if; end if; end process; ile<='1';cont<='0';data_out<=data; --ile、cont賦值;波形數(shù)據(jù)輸出; end behav;
|