引言
現(xiàn)場可編程門陣列(FPGA)的出現(xiàn)是超大規(guī)模集成電路(VLSI)技術(shù)和計算機(jī)輔助設(shè)計(CAD)技術(shù)發(fā)展的結(jié)果。FPGA器件具有集成度高、體積小、可以通過用戶編程實現(xiàn)專門應(yīng)用的特點。這些特點非常適合大學(xué)計算機(jī)教學(xué)中的計算機(jī)硬件實驗。在計算機(jī)硬件實驗中,三態(tài)電路有著廣泛的應(yīng)用,例如構(gòu)建一個具有分時共享功能的總線電路就需要用到多個三態(tài)電路。傳統(tǒng)的實驗方法要先畫出原理圖,然后通過手工連線各個芯片來搭建三態(tài)電路。在基于FPGA的硬件實驗中,一種方法是利用圖形方式,在MAX+PLUSⅡ中畫出三態(tài)電路圖,并編譯完成實現(xiàn)三態(tài)的功能;另一種方法是直接用VHDL語言編寫出三態(tài)電路程序,同樣需要編譯完成實現(xiàn)三態(tài)的功能。但是,在MAX+PLUSⅡ環(huán)境下,應(yīng)用三態(tài)電路時常會遇到了很多問題,這些問題阻礙著用VHDL語言正確使用三態(tài)電路的功能。我們在FPGA應(yīng)用設(shè)計中也發(fā)現(xiàn)了類似問題,經(jīng)過仔細(xì)的分析和對多種不同實現(xiàn)方法的嘗試,最后掌握了正確的實現(xiàn)方法,同時也找出了一般方法出錯的原因。
在MAX+PLUSⅡ環(huán)境下最常見的三態(tài)應(yīng)用程序及問題
在MAX+PLUSⅡ環(huán)境下,由于軟件本身提供了三態(tài)總線電路的模塊,因此可以在VHDL編程時直接調(diào)用lpm_bustri模塊。下面是一個用VHDL編寫的8位單向總線電路的程序片斷:
entity tri_bus is
port(a,b: in std_logic_vector(7 downto 0);
aen,ben: in std_logic;
q:out std_logic_vector(7 downto 0));
end tri_bus;
architecture tri_bus_body of tri_bus is
component lpm_bustri
generic(lpm_width:positive);
port (data : in std_logic_vector(lpm_width-1 downto 0);
enabledt: in std_logic:=‘0’;
tridata:inout std_logic_vector(lpm_width-1 downto 0));
end component;
signal temp: std_logic_vector(7 downto 0);
begin
u1:lpm_bustri
generic map(lpm_width=》8)
port map(data=》a,enabledt=》aen,tridata=》temp);
u2:lpm_bustri
generic map(lpm_width=》8)
port map(data=》b,enabledt=》ben,tridata=》temp);
q《=temp;
end tri_bus_body;
以上程序很簡單,通過調(diào)用lpm中的三態(tài)模塊,以實現(xiàn)三態(tài)輸出傳輸至總線的功能。程序中將兩個三態(tài)模塊的輸出連接在一起,構(gòu)成一個8位總線,總線輸出結(jié)果取決于兩個三態(tài)模塊中哪一個的使能信號有效。這段程序理論上不存在問題,然而編譯卻無法通過!編譯器報錯,指出信號temp被多次賦值。
顯然,在u1和u2中有兩次出現(xiàn)tridata=》temp,但這對于三態(tài)電路來說是允許的,因為三態(tài)輸出是可以并聯(lián)的。那么是否因為lpm_bustri模塊不能正確實現(xiàn)三態(tài)功能呢?我們首先用圖形方式來驗證該模塊的功能。由于只是驗證,這里只設(shè)置了一位的數(shù)據(jù)輸入和輸出,如圖1,圖中a為數(shù)據(jù)輸入端,q為數(shù)據(jù)輸出端,aen為使能端。
圖 1
該圖形文件成功地通過了編譯,而且仿真結(jié)果表明,三態(tài)功能完全正確,即使能aen有效,輸出為a,使能aen無效,輸出為高阻。然后,我們又用圖形方式搭建了前面的VHDL程序邏輯,建好的圖形文件如圖2所示。
圖 2
這個圖形文件所示邏輯同前面VHDL程序的內(nèi)容完全相同。信號q的輸出取決于兩個使能端中哪一個有效。然而編譯還是出錯,這次指出的錯誤是兩個lpm_bustri的輸出tridata連接在一起了。
從理論上來說,兩個三態(tài)的輸出是可以接在一起的。為了證明這一點我們不再采用lpm_bustri模塊,而是在MAX+PLUSⅡ環(huán)境下用圖形方式直接畫出兩個三態(tài)元件,然后再將它們的輸出連接在一起,如圖3。
圖 3
這各圖形文件順利通過編譯!仿真結(jié)果也完全正確,當(dāng)aen使能有效,q輸出為a;當(dāng)ben使能有效,q輸出為b。如果沒有兩個使能端均無效,輸出為三態(tài),如果兩個使能端均有效,輸出結(jié)果為a和b的線與。(由于在實際總線電路中,aen和ben不可能同時有效,所以此種情況并不影響結(jié)果的正確性,我們只要知道這種情況下的輸出結(jié)果是兩個信號的線與就可以了。)
修改后的三態(tài)電路應(yīng)用程序
既然三態(tài)電路用圖形方式在MAX+PLUSⅡ環(huán)境下可以正確實現(xiàn),那么VHDL程序也應(yīng)該是可以的。前面編譯出錯的程序和電路都是因為用到了lpm_bustri模塊,如果不用它程序?qū)⑷绾涡薷哪兀吭谶@種疑問下我們改變了思路,修改后的VHDL程序如下:
library ieee;
use ieee.std_logic_1164.all;
entity tri_state is
port(a,b :in std_logic_vector(7 downto 0);
aen, ben :in std_logic;
q :out std_logic_vector(7 downto 0));
end tri_state;
architecture tri_state_body of tri_state is
signal control:std_logic_vector(1 downto 0);
begin
control(1)《=aen;
control(0)《=ben;
process(a,b,control)
begin
case control is
when “10”=》q《=a;
when “01”=》q《=b;
when others=》q《=(others=》‘Z’);
end case;
end process;
end tri_state_body;
這段VHDL程序同最初那段VHDL程序表達(dá)的功能是一樣的,當(dāng)aen使能有效,輸出為a,當(dāng)ben使能有效,輸出則為b,如果不是這兩種情況均輸出三態(tài)。這次經(jīng)過編譯和仿真,功能正確實現(xiàn)了。
分析不同程序不同結(jié)果的原因
為什么最初的VHDL程序和用lpm模塊搭建的圖形會出錯呢?帶著這個問題將兩個程序進(jìn)行對比便可找出問題的所在。在修改后的程序中,我們用了一個control二維數(shù)組來控制對輸出信號q的賦值,雖然輸出信號q也是有兩個輸入源a和b,但是程序控制了它們賦值的時間,也就是不可能同時被賦值,所以編譯器沒有報錯。而最初的程序的卻出現(xiàn)temp被多次賦值,再來看看源程序:
u1:lpm_bustri
generic map(lpm_width=》8)
port map(data=》a,enabledt=》aen,tridata=》temp);
u2:lpm_bustri
generic map(lpm_width=》8)
port map(data=》b,enabledt=》ben,tridata=》temp);
q《=temp;
其中,雖然實際中不可能讓三態(tài)的兩個使能同時有效,但是對于編譯器而言,它只能識別語句的邏輯,在上面那種邏輯下,aen和ben是完全可能同時有效的(僅僅是邏輯,只對語句而言)。如果這種情況發(fā)生,編譯器將無法正確對q賦值,所以報錯,提示信號temp被多次賦值,這完全是因為編譯器嚴(yán)謹(jǐn)?shù)慕Y(jié)果。
在一個編譯器中,語法的正確性檢查是基于一種規(guī)則和邏輯的,它是適用于一切的語言描述。雖然三態(tài)的輸出可以連接在一起,但是當(dāng)程序直接將它們連接在一起的時候(也就是多源賦值的時候),編譯器不可能因為程序編的是三態(tài)邏輯而通過這種潛在的錯誤,它的編譯原理是基于語句而不是編出來的結(jié)果。這樣就可以解釋為什么簡單的元件搭建出來的三態(tài)輸出連接在一起可以通過編譯,而用lpm模塊描述出來的和我們最初的三態(tài)程序描述出來的三態(tài)輸出卻不能通過編譯。因為它們都需要通過編譯器的語法檢查。而多源賦值又是一種潛在的錯誤,所以不能通過。那么有些人會不理解,都是圖形描述,為何簡單的元件搭建可以通過而高級的lpm模塊搭建卻不行?答案是高級的lpm模塊也是用語言編寫出來的,它也要通過編譯器的語法檢查。簡單的元件搭建可以通過是因為在兩個使能都成立的情況下,軟件可以將輸出信號按線與處理,從而避免了沖突和不確定性。那么如何利用lpm模塊實現(xiàn)三態(tài)的功能?這就要看如何運(yùn)用在具體的應(yīng)用中了。如果僅僅需要將兩個三態(tài)的輸出連接在一起,通過各自的使能端控制輸出的話,可以在一個原理圖中分別建立兩個單獨(dú)的lpm模塊,不要將它們的輸出端連接在一起(否則編譯器會報錯),然后直接編譯,編譯通過后可以在配置FPGA的時候?qū)⒔⒌膬蓚€lpm模塊的輸出連接到同一個管腳上,經(jīng)過驗證,這樣在應(yīng)用中也是可以正常實現(xiàn)三態(tài)功能的(因為其避免了在編譯前就將輸出口連接在一起而不能通過編譯的情況的發(fā)生)。
總結(jié)
通過以上的分析和說明,我們知道MAX+PLUSⅡ環(huán)境下,是可以正確實現(xiàn)三態(tài)電路應(yīng)用的。主要有三種方法:
① 用類似于我們上面改編出來的程序來實現(xiàn);
② 用自搭建的圖形描述實現(xiàn);
③ 在配置FPGA時再將不同的三態(tài)輸出端連接到同一個管腳上。
需要注意的是在編寫程序或者利用軟件本身提供的模塊搭建電路時要了解軟件自身或者所調(diào)用的模塊在編譯時是否會引起編譯器的沖突。在了解了編譯器編譯原理后,才能在編寫和調(diào)試程序時游刃有余,及時發(fā)現(xiàn)和改正問題。
創(chuàng)新觀點:本文指出了在MAX+PLUSⅡ環(huán)境下運(yùn)用三態(tài)電路常見錯誤的原因,并指明了幾種正確的實現(xiàn)方法。
責(zé)任編輯:gt
評論
查看更多