已經有幾年沒有接觸過VDHL或者Verilog了,在大二時,對VHDL是如此的熱愛,瘋狂得不用看仿真只通過看代碼就能知道問題所在,在那一年,我喜歡FPGA,喜歡了VHDL。
就在那一年,老師給我的項目失敗了,可能是自己技術不到家(那時連SDRAM工作原理還不懂,卻說要用VHDL實現SDRAM讀寫,當年還是有很多東西不了解,也沒有自己的一套學習方法),為了不讓老師失望,我決意轉向ARM,從此,我與FPGA、VHDL失去了交集,漸漸地,我把VHDL遺忘了。。。。。
其中在那一年,雖然主攻VHDL,但對Verilog也有作過少許學習(畢竟Verilog學習資料多),只是隨着時間的推移,Verilog與VHDL的轉換已成為過去。
今年,我又有機會與VHDL產生交集,其實是我主動向上司要求,我想研究FPGA、VHDL,可以減輕團隊的壓力。
好了,費話了一堆。現在的我又要從頭開始撿起VHDL了。
VHDL中的庫文件包含:
在VHDL中,少不了一些標准庫,如:std_logic這類聲明,都是來源於ieee這個庫的。
library ieee; use ieee.std_logic_1164.all;
VHDL中實體聲明:
和高級語言一樣,VHDL也要聲明,這時有點不同的是,這種聲明是用於對外的接口,即輸入/輸出都在這里聲明的。
entity CRC_Unit is port( iBitVal : in std_logic; iClock : in std_logic; iClear : in std_logic; oCRC : out std_logic_vector(4 downto 0) ); end CRC_Unit;
VHDL結構功能:
有了對外的接口外,還得有內部的處理,這樣才能算是一個整體。architecture 就是對實體的內部功能的描述。
architecture ClacCRC of CRC_Unit is signal inv : std_logic; signal CRC : std_logic_vector(4 downto 0); begin inv <= iBitVal xor CRC(4); process(iClock,iClear) begin if iClear = '1' then CRC <= (others =>'0'); elsif falling_edge(iClock) then CRC(4) <= CRC(3); CRC(3) <= CRC(2) xor inv; CRC(2) <= CRC(1); CRC(1) <= CRC(0) xor inv; CRC(0) <= inv; end if; end process; oCRC <= CRC; end ClacCRC;
到此,就把VHDL的結構簡述完畢。
別急,我還沒有說完,下面還會對各個部分進行分析。由於代碼已經在上文給出,下文將不會再重復代碼。
VHDL中的庫
VHDL中的庫有哪些?
std_logic_1164
std_logic_arith
std_logic_unsigned
std_logic_signed
除了系統自帶的庫外,自己也可以編寫自己的,編寫格式如下:
library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; package PackageName is component Component1 is PORT ( ... ); end component; component Component2 is PORT ( ... ); end component; end package;
格式和寫一個普通的VHDL文件差不多,不同的是,這個沒有實體,也沒有結構,只有包(component后面將描述)。
VHDL如何使用庫?
庫可以分為二大類,一類是系統自帶的標准庫,另一類的用戶自己編寫的,兩種類調用方式不太一樣。
上面代碼講到如何調用庫,如果使用標准庫,一般如下:
library ieee; --表示使用什么庫 use ieee.std_logic_1164.all; --表示使用庫中的具體的庫
其中std_logic_1164是在ieee庫中的,一般情況下,上而兩行代碼是必需的。
如果使用的是用戶自編寫庫,就要:
use work.PackageName.all; --work表示當前工作目錄
使用用戶自編寫的庫看起來就簡單多了,只要使用use就可以了,值得注意的是,work是指當前工作目錄,而PackageName就是包的名字,前面的講述到。
VHDL中的實體
VHDL中的實體就簡單多了,主要是對引腳(或接口)的輸入、輸出或者雙向作定義。
其中port();中的為對外引腳。
引腳分三種:
輸入使用關鍵字:in
輸出使用關鍵字:out
雙向使用關鍵字:inout
對不同引腳要定義具體類型,引腳常用只有兩種類型,一種是單點引腳,一種是多點引腳。(單點、多點引腳是我的說法,不一定正常,但能表示其意思)
單點引腳使用:std_logic
多點引腳使用:std_logic_vertor(x downto 0)
有點類似普通變量和數組變量,一個表示單線、一個表示集合了多條單線(類似總線)。
注:在port();中,最后一個引腳不要加分號!
VHDL中的architecture
在architecture中且在begin前聲明
1、信號。信號如其名,就是傳遞信號用的。
2、組件(component),組件就是其他已經寫好的VHDL,組件只是把其引腳復述一遍,用於后期數據處理。
architecture XXX of XXX_Unit is signal One:std_logic; --聲明信號 component Component1 is --聲明組件 port ( ... --具體一個實體的引腳 ); end component; begin ... end XXX;
組件是將一個已經寫好的VHDL模塊(實現某一功能的VHDL文件) ,加入本VHDL中的方式,但加入還不夠,還要使用port map,下文將描述。
在architecture中且在begin后
在begin后常用的有語句不多,主要有if...else...end if,if...elsif...elsif...end if,process,port map等(這些語句能實現大部分邏輯)。
architecture XXX of XXX_Unit is component CRC_Unit is port( iBitVal : in std_logic; iClock : in std_logic; iClear : in std_logic; oCRC : out std_logic_vector(4 downto 0) ); end component; signal bitVal : std_logic; signal clock : std_logic; signal clr : std_logic; signal crc : std_logic_vector(4 downto 0); begin oOut <= One; process(rst) --敏感信號列表 begin if rst = '0' then ... elsif ... end if; end process; u1:CRC_Unit port map(iBitVal => bitVal ,iClock => clock ,iClear => clr ,oCRC =>crc); end XXX;
在VHDL中,只要在architecture中的語句都會被同時執行,但process一點特別,同時執行的是整個process,而不是process里面的各行語句。process其實更像是一個塊,一個對外同時執行,對內順序執行的一個單元。
在process的括號中的rst,被稱為敏感信號列表,只要放在這括號中的數據發生變化,就會同時執行期間觸發process內部操作。即oOut <= One、process及port map同時執行。
port map是將原來component進architecture的組件進行使用,port map 后,會將對應的信號輸入或輸出。
VHDL architecture中的變量
變量需要聲明在process中,而且只能在process中被賦值,被調用。變量聲明在process中begin前。
process(rst) variable val : integer ; begin val := 10; end process;
VHDL architecture中的賦值
VHDL中有兩種賦值方式,一種是直接賦值,一種是延時賦值。還有一種不太像賦值,而是像指向的方式,port map (符號是"=>"),這里不把此方式當作賦值。
直接賦值:(賦值符號為":=" )
variable 就是直接的代表,當賦值后,左值將等於右值。
延時賦值:(賦值符號為"<=“ )
所有信號、引腳被賦值都是延時賦值。那什么是延時賦值?個人認為可以與實際電路理解(雖然不知是否正確)。信號可以看成一條線(引腳也是),當我在線的右端給出高電平的瞬間,左端的電平還沒有變化,因為從右到左需要一定的時間(那時間是光速),所以在同一周期作出了操作,但信號的值還沒有來得及改變,所以出現了延時賦值。
在VHDL中只有兩種賦值操作,如果想和高級語言一樣使用"="一般會出錯,因為在VHDL中"="是比較操作。
總結:
由於邊幅太長不利瀏覽,因此對VHDL、Verilog將以一個系列來講述。局限於本人技術有限,可能上文會有表達不通,或者表達不清的情況,如果有看不懂的,或者找出錯處的,歡迎大家提出。