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