歡迎您光臨本站 登入註冊首頁

NIOS整體開發結構基礎

admin @ 2014-03-26 , reply:0

概述

   上個例子中,我們使用VHDL語言,根據FPGA管腳與數碼管和按鍵管腳的連接,通過一系列的語句控制管腳電平的高低,從而讓FPGA實現數碼管顯示功能。可見,對於比較簡單……

    上個例子中,我們使用VHDL語言,根據FPGA管腳與數碼管和按鍵管腳的連接,通過一系列的語句控制管腳電平的高低,從而讓FPGA實現數碼管顯示功能。可見,對於比較簡單的功能實現,可以像這個例子中那樣,直接控制最底層資源,甚至對每個管腳在每個時刻的電平輸出了如指掌。
    但是,如果設計稍顯複雜,那麼對底層細節的過多關注就會成為一種累贅。
    試想我們平時在電腦上編寫C程序,比如在顯示器上輸出一行字,我們只用一句printf()即可完成,至於列印命令怎麼傳到顯示晶元上,哪個晶元管腳怎麼 變化,又怎麼傳到顯示器上輸出,諸如此類涉及底層硬體的問題,我們沒必要關注太多。於是,我們把用printf()這類高級語言描述設計邏輯的工作稱為軟 件設計。顯然,軟體只是一種抽象的看不見摸不著的東西,它的結構接近於人類思維邏輯。無論軟體再怎樣構思精妙,只有在硬體上才能體現出實際效果。
    做計算機開發應用程序的時候,硬體是現成的,軟硬體之間的橋樑早就由操作系統給你搭好了,我們只需專心完成軟體的構思和設計就OK。
    顯而易見,軟硬體的分工會給電子設計帶來極大的方便,自然有人把這種分工方式引進FPGA設計領域,琢磨著怎麼在小小的FPGA上也搞個軟硬體協同設計,負責硬體設計的和負責軟體的各司其職,最後pia一整合,效率倍增。
    來看看nios是怎麼做的。拿出DE2開發板,上面很多外設介面和與之連接的晶元,那是硬體,中間有一塊大的CycloneII晶元,裡面是空的,等著我 們編寫程序下載到裡面運行,前篇文章我們用最原始的方法寫了個數碼管控制器,這次我們換種方法,同樣是數碼管控制器,用軟硬體協同設計來完成。
    跟計算機對比,硬體我們有了,軟體就用C語言來寫,但是nios系統可沒提供WinXP,也就是說軟體和硬體之間的那座橋還得自己解決。
  
    看上圖,這座橋分為3個層次:硬體控制層,設備驅動層,硬體抽象層(簡稱HAL)。既然是軟硬體的過渡部分,那麼這3層的設計需要對硬體和軟體都有一定程度的了解,姑且稱之為“軟硬體混雜設計”吧。
    每一層所要完成的任務,就是整合和簡化硬體操作細節,整合,再整合,使其一目了然。
 
 
<1> 硬體控制層
    與硬體直接打交道的是硬體控制層。
    上面提到,搭“橋”的目的是讓軟體設計人員可以完全忽略硬體操作細節,因此,我們希望所有的硬體細節都能在這層解決,並向設備驅動層提供整齊的“介面”。之前的例子可看作硬體控制器的雛形,但還缺少與設備驅動層的介面。
    何為“整齊”呢?比如說,設計數碼管控制器,我想讓它顯示數字“5”,最好的方法是,我將數據“5”和表示“顯示”的命令從設備驅動層傳給硬體控制層,直 接告訴它:我要“數碼管”“顯示”“5”。至於要控制哪個管腳電平高低才能顯示“5”,全由硬體控制層負責。
    類似這樣分工合作的例子在日常生活中屢見不鮮。比如說,郵局要將一封信送給家住A小區的張三,郵遞員把信放入A小區的信箱,小區物業再去確認張三的具體住處,把信最終送到張三手中。
    類比可見,郵局相當於設備驅動,物業相當於硬體管理器,張三則是具體的硬體,郵局和物業之間的介面是物業提供的信箱,設備驅動和硬體管理層之間的介面,我們稱之為“寄存器”,同樣由硬體管理層提供,“寄存器”是兩層之間得以明確分工和相互聯繫的關鍵。
    設備驅動開發人員眼中的硬體就是一組寄存器的抽象,通過讀寫寄存器間接控制硬體行為。
    那麼,在數碼管控制器里加入一個數據寄存器和一個命令寄存器:
  
       data_reg存儲待顯示的數據,cmd_reg為‘1’時顯示,為‘0’時清空。
 
 
<2> Avalon匯流排
       你可能會說,這有什麼?在每個硬體管理器和設備驅動之間都建立一個通道唄。這是最直接的辦法,但顯然不是最好的辦法。試想,城市為什麼要建高速公路呢?多 修幾十根羊腸小道不也一樣能跑車嗎?有人回答:為了收養路費唄。$%@&&! 小路上開車,速度慢且不說,管理協調是個大問題,是一條大公路容易管理,還是幾十根羊腸容易理順?
     好了,回到正題,nios系統需要一條“高速公路”,稱為“匯流排”,“匯流排仲裁器”則行使“交通管理局”的角色,控制數據的進出,並為每個硬體提供一個進 出“高速公路”的介面,用“地址”來標識這個介面的位置。nios採用的是Avalon匯流排,它有著一套介面規範:
       同步時鐘 clk
       片選信號 chipselect
       地址 address
       讀請求 read
       讀傳輸 readdata
       寫請求 write
       寫傳輸 writedata
       這些是比較重要的介面信號,其它的不一一列舉了。硬體控制器要接入匯流排,必須遵循介面規範,就像高速公路出口必須擺個收費站一樣。
  
       那麼在數碼管控制器里加入Avalon匯流排信號:
  
    既然加入了兩個寄存器和avalon信號,就需要對硬體邏輯進行必要改動,大致過程是,當chipselect和write有效時,將 write_data賦給address對應的寄存器;當chipselect和write有效時,將address對應寄存器的值賦給 read_data。另外,根據這兩個寄存器的內容決定數碼管輸出信號oSEG0。代碼不貼出來了,具體見工程壓縮包。

 <3> 設備驅動程序
    其實,“匯流排仲裁器”也可看作一種硬體控制器,只不過它管的不是具體的硬體,而是負責數據的傳輸。那麼它也有自己的設備驅動,封裝了匯流排操作的細節。既然匯流排是現成的,我們秉承“拿來主義”的原則,甭管它怎麼實現的,會用就行。
    例如,數碼管設備驅動要把數據“5”和“顯示”命令傳給數碼管控制器,設計兩個函數,由於數據和命令的傳遞必須經過匯流排,那麼需調用匯流排驅動函數IOWR(基地址, 偏移量, 數據),另外,讀取寄存器用到IORD(基地址, 偏移量),這兩個函數在<io.h>里。
       <io.h>的路徑是"..alterakits ios2_60componentsaltera_nios2HALinc"。
       至此,“橋”搭完。
  
    函數功能從字面上很好理解。剛才定義兩個寄存器時,data_reg在前面,所以偏移量是0,cmd_reg在後面,偏移量是1。××_REG_MSK稱 為掩碼,avalon匯流排數據介面共32位,但我們設計的data_reg位寬是3,cmd_reg位寬為1,掩碼的作用在於告知寄存器寬度,知道就行, 實際上用不著。××_REG_OFST是寄存器內的偏移量,這裡同樣用不著,先寫上吧。
    OK,我們的數碼管設備驅動文件正式出爐了,看看是不是簡潔明了很多啊?

 <4> 硬體抽象層(HAL)
    設備驅動程序封裝的僅僅是對某個寄存器的一次讀寫操作,功能單一,需要在硬體抽象層再做一次封裝。
    直接將這些函數列出來,一目了然,不作多餘的解釋了。
  
    至此,“橋”搭完。

[admin via 研發互助社區 ] NIOS整體開發結構基礎已經有3175次圍觀

http://cocdig.com/docs/show-post-42962.html