現(xiàn)場可編程門陣列FPGA 常常進(jìn)行大數(shù)據(jù)量的處理,數(shù)據(jù)的存儲便成了問題,利用SPI Flash 大容量、讀寫速度快、成本低廉以及數(shù)據(jù)在斷電后不丟失的特點,可以將配置數(shù)據(jù)存儲于SPI Flash 中[1] 。它比起傳統(tǒng)的并行總線接口Flash 來說節(jié)省了很多的I/ O 口資源,從而為系統(tǒng)功能的擴展提供了更多的可能。為此提出了一種基于FPGA 的SPI Flash 控制器的設(shè)計方法,并用Verilog HDL 實現(xiàn),在Isim 中得出仿真和驗證結(jié)果,最終應(yīng)用在自行設(shè)計的VGA顯示控制電路中得到成功應(yīng)用,而且可以擴展到所有類似系統(tǒng)中[2] 。
1 系統(tǒng)總體方案設(shè)計
FPGA 芯片采用的Spartan-6 系列的xc6slx9 芯片,封裝采用tqg-144,該系列FPGA 能提供高達(dá)400MHz 的工作時鐘,高達(dá)5 720 個高效的雙寄存器6 輸入查找表(LUT)和一系列豐富的內(nèi)置系統(tǒng)級模塊,采用成熟的45 nm 低功耗銅制程技術(shù)制造,實現(xiàn)了性價比與功耗的完美平衡。該芯片有9152 個邏輯單元(Logic Element),32 個18 kbyte 的Block RAM 模塊,16 個18伊18 bit 嵌入式乘法器,2 個鎖相環(huán)(PLL)和4個時鐘管理模塊(DCM)。在這款144 針tqg 封裝的FPGA 中,用戶可用I/ O 為102 個[3] ,可以滿足本系統(tǒng)的需求。
Flash 芯片采用的配置芯片是Winbond 公司的W25Q80BV 系列8 M bit 容量的SPI Flash,該芯片共由16 部分組成,每一部分有256 頁,每頁有256 個字節(jié)。該系列芯片具有先進(jìn)的寫保護(hù)機制,讀取數(shù)據(jù)的最大時鐘速率為50 MHz。工作的電壓范圍為2.7 V ~3.6 V,具有整體擦除和扇區(qū)擦除、靈活的頁編程指令和寫保護(hù)功能,數(shù)據(jù)保存至少20 y(year),每個扇區(qū)可承受100 000 次擦寫循環(huán)。SPI Flash 具有掉電保存能力,在系統(tǒng)上電時,F(xiàn)PGA 首先從配置芯片SPIFlash 中讀取編程數(shù)據(jù),并對FPGA 進(jìn)行加載。SPIFlash 的HOLD#和WP#管腳要接上拉電阻, 因為FPGA 上電時管腳為高阻態(tài),如無此上拉電阻,F(xiàn)LASH的HOLD#和WP#輸入為浮置狀態(tài),沒有確定的電平,進(jìn)而導(dǎo)致數(shù)據(jù)總線電平也不確定,這是不允許的。
本系統(tǒng)由串口、FPGA 和SPI Flash 構(gòu)成,系統(tǒng)整體框圖如圖1 所示。
圖1 中,F(xiàn)PGA 為電路核心,一方面接收來自PC串口的數(shù)據(jù),并將數(shù)據(jù)寫入Flash 中;一方面從Flash中讀出數(shù)據(jù);另一方面產(chǎn)生系統(tǒng)所需的各種控制信號。作為現(xiàn)場可編程器件,F(xiàn)PGA 能方便地?zé)氤绦騺砀淖兯墓δ埽栽谠O(shè)計調(diào)試時,可將。 bit 文件燒入FPGA 進(jìn)行在線調(diào)試,也可將。 mc文件程序直接下載到SPI Flash 中進(jìn)行功能驗證。
2 FPGA 內(nèi)部模塊設(shè)計
FPGA 的頂層文件包括七個模塊,如圖2 所示。
圖2 中,復(fù)位信號主要是同步外部的復(fù)位信號;DCM 模塊主要是倍頻和管理時鐘;串口接收模塊把從串口得到的數(shù)據(jù)緩存到FIFO;Flash 控制模塊主要是控制對外部SPI Flash 的讀寫,把從串口得到的數(shù)據(jù)存入到SPI Flash,并不斷把SPI Flash 中的數(shù)據(jù)送到串口發(fā)送模塊;CoreRAM 是Xilinx 專用的一個IP 核,本設(shè)計中用于FPGA 內(nèi)部數(shù)據(jù)的緩存;SPI 接口模塊為SPI Flash 提供串行時鐘,并實現(xiàn)數(shù)據(jù)的串并轉(zhuǎn)換。當(dāng)上層用戶發(fā)送指令要將FPGA 的配置數(shù)據(jù)存入SPI Flash 時,配置數(shù)據(jù)從串口接收模塊輸出給Flash 模塊, Flash 模塊將數(shù)據(jù)不斷提取到CoreRAM 中,CoreRAM 中的數(shù)據(jù)經(jīng)過Flash 模塊寫入到SPI Flash 中。當(dāng)系統(tǒng)重新上電要對FPGA 進(jìn)行配置時,將SPI Flash 中的數(shù)據(jù)讀入到Flash 模塊中,再將Flash 模塊中數(shù)據(jù)緩存在CoreRAM 中,最后將CoreRAM 中的數(shù)據(jù)提取給上層相應(yīng)的模塊,完成對FPGA 的配置。
從以上分析可以知道,F(xiàn)PGA 內(nèi)部的數(shù)據(jù)流向非常的明朗,模塊之間的關(guān)系也很確切,所以這個框圖的劃分具有一定的科學(xué)性。如果總體的框圖沒有劃分好,調(diào)試成功的可能性也是非常小的。另外,在升級的時候如果要改變數(shù)據(jù)的獲得方式,只要用新的程序替換串口接收模塊即可;如果要改變數(shù)據(jù)的顯示方式,只要用新的程序替換串口發(fā)送模塊即可。下面分別介紹各功能模塊的實現(xiàn)。
2. 1 串口接收和發(fā)送部分
串口發(fā)送和接收部分相似,串口接收部分是將來自PC 的串口數(shù)據(jù)發(fā)送到Flash 控制器中,而串口發(fā)送部分是將從Flash 中讀到的數(shù)據(jù)發(fā)送給PC 機,是串口接收的逆向過程,下面以串口發(fā)送部分為例進(jìn)行分析。串口接收模塊的框圖如圖3 所示。
圖3 中包含3 個子模塊,串口接收模塊接收來自PC 串口的數(shù)據(jù),為了使速度盡可能的快,設(shè)計用的波特率為115 200 bit/ s;緩存接口主要是把串口接收到的數(shù)據(jù)緩存到FIFO;FIFO 是例化的一個模塊,用作數(shù)據(jù)緩存。
2. 1. 1 串口接收
串口接收程序按照UART 的傳輸原理進(jìn)行程序設(shè)計,本設(shè)計省略了奇偶校驗部分,是按照10 bit 的串口傳輸方式設(shè)計的。串口程序的核心是一個接收狀態(tài)機,另外還包括接收同步、采樣時能生成和標(biāo)志位控制模塊。工作原理是來自串口的信號經(jīng)兩級寄存器同步后不斷被采樣,采樣后的信號到接收狀態(tài)機控制獲得串口數(shù)據(jù),如果接收完數(shù)據(jù),把接收到數(shù)據(jù)的標(biāo)志位置高告訴相關(guān)模塊已經(jīng)接收到新數(shù)據(jù),標(biāo)志位在標(biāo)志清零輸入置高后被清零,這時候標(biāo)志位再次置高說明接收到下一個的數(shù)據(jù)。標(biāo)志位清零的控制要注意清零位的置高周期數(shù),最好為一個周期,不能無限制地永遠(yuǎn)置高。串口接收模塊的核心狀態(tài)機的狀態(tài)轉(zhuǎn)換圖如圖4 所示。
idle:閑置狀態(tài)每個時鐘周期都采樣接收同步信號的值,一旦該信號的值為0 則轉(zhuǎn)入到下一個狀態(tài)。
first:準(zhǔn)備接收狀態(tài)采樣串口接收的起始位,在波特率的16 倍時鐘下采樣,如果6、7、8 次采樣中有兩次為低電平說明是起始位,轉(zhuǎn)入到下一個狀態(tài)(rxd),否則認(rèn)為該信號是干擾信號而轉(zhuǎn)入閑置狀態(tài)(idle)。
rxd:接收狀態(tài)把數(shù)據(jù)接收到并存入暫存寄存器,并產(chǎn)生標(biāo)志位的原始信號,接收結(jié)束是根據(jù)暫存寄存器的最低位來判斷結(jié)束的,同時在結(jié)束的時候判斷結(jié)束位是否為0,如果不為0,則拋棄接收到的數(shù)據(jù)后轉(zhuǎn)入到閑置狀態(tài)。
2. 1. 2 緩存接口
緩存接收模塊是一個相對簡單的模塊,它主要是把串口接收模塊接收到的數(shù)據(jù)存入到FIFO,由于串口接收的是8 bit 的數(shù)據(jù),F(xiàn)IFO 的寬度是16 bit,因此每次接收2 bit 數(shù)據(jù)再存入FIFO。緩存接口模塊包含一個控制狀態(tài)機,工作原理是一旦檢測到串口接收模塊的標(biāo)志位為高時就接收1 字節(jié)的數(shù)據(jù),并轉(zhuǎn)到接收下1 字節(jié)狀態(tài),這個狀態(tài)接收到第二個數(shù)據(jù),并把整個16 bit 的數(shù)據(jù)存入到FIFO,每次接收1 字節(jié)數(shù)據(jù)后都把清零標(biāo)志位置高清除串口接收模塊的標(biāo)志位。
FIFO 是在開發(fā)軟件中例化的一個模塊,為保持較高的速度,剛好用了一個M4K 塊,數(shù)據(jù)的寬度為16 bit,數(shù)據(jù)的存儲深度是256 個。本FIFO 讀數(shù)據(jù)和寫數(shù)據(jù)工作在不同的頻率上,讀數(shù)據(jù)的操作工作在較高的頻率上,寫數(shù)據(jù)的操作工作在較低的頻率上。本FIFO 也把內(nèi)部的其他模塊和跟數(shù)據(jù)的獲得模塊分離,如果要把串口獲得數(shù)據(jù)模塊改為其他方式就可以直接修改這部分即可。
2. 1. 3 寫緩沖FIFO
寫緩沖FIFO 指的是串口數(shù)據(jù)的暫存FIFO,在FLASH 主控制模塊中將用到的信號是這個FIFO 的“近空冶信號(w_fifo_aempty)。在每行顯示開始的時候都要檢測這個信號,如果w_fifo_aempty 信號為高電平,說明寫緩存FIFO 已經(jīng)有足夠的數(shù)據(jù)用來寫,這時候把FIFO 中的數(shù)據(jù)寫到FLASH 中,當(dāng)w_fifo_aempty 信號為低電平說明數(shù)據(jù)即將被讀空,這時候通過置w_fifo_re 使能停止向FLASH 寫數(shù)據(jù)。每一次這樣的一個過程至少寫入了突發(fā)數(shù)據(jù)傳輸?shù)臄?shù)據(jù)個數(shù)。
寫緩沖FIFO 的寫是uart_inf 這個模塊來控制的,只有在uart_rxd 接受完兩個字節(jié)的數(shù)據(jù)后把這個數(shù)據(jù)合成一個16 bit 的數(shù)據(jù)存入到FIFO,準(zhǔn)備好數(shù)據(jù)的同時把FIFO 的寫使能置為低電平一個周期即可以把數(shù)據(jù)寫入到FIFO 中。
2. 2 Flash 控制模塊
Flash 正常工作時必須嚴(yán)格按照Flash 的時序控制信號,F(xiàn)lash 主控制模塊在兩個有限狀態(tài)機的控制下來進(jìn)行,寫Flash 狀態(tài)機和讀Flash 狀態(tài)機。
由于Flash 的寫操作只能將數(shù)據(jù)1 改寫成為0,擦除操作才能將數(shù)據(jù)0 改寫為1。所以FPGA 剛上電時,程序首先對Flash 進(jìn)行擦除操作,將指定區(qū)域全寫為1。當(dāng)需要執(zhí)行寫Flash 的操作時,應(yīng)該首先把數(shù)據(jù)寫到FPGA 內(nèi)部的BlockRAM 中,然后按照Flash Datasheet 中的頁面編程時序向Flash 中寫入數(shù)據(jù)。Xilinx 公司為用戶提供了功能豐富的IP 核,設(shè)計中需要的BlockRAM 模塊可直接在ISE 中調(diào)用IP 核,F(xiàn)lash 主控制模塊可以控制存取BlockRAM 的地址和時間,并且按照Flash 的頁編程時序,將并行數(shù)據(jù)通過SPI 接口模塊轉(zhuǎn)換為串行數(shù)據(jù)后送入到Flash 中。W25Q80BV 的頁面編程指令的時序圖如圖5 所示。
圖5 中,首先拉低/ CS(片選信號),第1 個時鐘上升沿將頁面編程指令02H 送入Flash 內(nèi),然后輸入3 個字節(jié)的首地址,緊接著輸入編程數(shù)據(jù)。頁面編程一次最多可以輸入256 個字節(jié)的數(shù)據(jù),若超出256 個字節(jié),則僅保留最后輸入的256 個字節(jié)的數(shù)據(jù)。如果輸入低8 bit 不全為零的地址,從輸入的地址進(jìn)行編程,一直編程到該頁的最后,接著從該頁的起始地址進(jìn)行編程。同樣,輸入完數(shù)據(jù)后片選信號也必須拉高,否則頁面編程指令不被執(zhí)行[4] 。
按照寫Flash 的時序設(shè)計狀態(tài)機,當(dāng)寫使能有效時,狀態(tài)機由閑置狀態(tài)(idle)進(jìn)入傳輸寫使能指令狀態(tài)(tx_cmd),經(jīng)過寫使能指令等待狀態(tài)(wait1)進(jìn)入到傳輸擦除指令狀態(tài)(tx_erase),然后經(jīng)過傳輸擦除指令等待狀態(tài)(wait2) 后,擦除命令執(zhí)行完畢。接著執(zhí)行寫Flash 的操作,首先還是進(jìn)入傳輸寫使能指令狀態(tài)(tx_cmd)和寫使能等待狀態(tài),然后進(jìn)入傳輸頁面編程指令狀態(tài)(tx_pro),經(jīng)過三個字節(jié)的傳輸?shù)刂窢顟B(tài)(txadd)進(jìn)入到傳輸數(shù)據(jù)狀態(tài)(txdata),輸入完256 個字節(jié)的數(shù)據(jù)后,進(jìn)入到清除指令(clr_cmd)狀態(tài),最后恢復(fù)到閑置(idle)狀態(tài)。寫Flash 狀態(tài)機如圖6 所示。
當(dāng)需要執(zhí)行讀Flash 的操作時,應(yīng)該首先按照Flash 的讀數(shù)據(jù)指令時序?qū)⒋袛?shù)據(jù)轉(zhuǎn)化為并行數(shù)據(jù)讀入FPGA的BlockRAM 中,然后從BlockRAM 中將數(shù)據(jù)讀入到上層用戶。W25Q80BV 的讀數(shù)據(jù)指令的時序圖如圖7 所示。
由圖7 可以看出,W25Q80BV 的讀數(shù)據(jù)指令時序比較簡單,在/ CS( 片選信號) 信號拉低以后的時鐘第一個上升沿,按照高位在前低位在后的順序?qū)⒆x數(shù)據(jù)指令03H 送到Flash 中,接著將所需讀取內(nèi)容的3 個字節(jié)的首地址送入Flash,在輸入完畢后的第一個時鐘下降沿,該首地址所指向的8 bit 數(shù)據(jù)便會按照從高位到低位的順序輸出。輸出完畢后,地址會自動遞增,然后指向下一個地址。接著輸出下一個地址所指向的數(shù)據(jù),并且當(dāng)?shù)刂返竭_(dá)最高位后將會自動轉(zhuǎn)回到首地址000000h,按照上述操作循環(huán)執(zhí)行,就可讀出Flash 中所有的內(nèi)容,一直到拉高/ CS 片選信號為止[5] 。
按照讀Flash 的時序設(shè)計狀態(tài)機,F(xiàn)lash 中的數(shù)據(jù)只要按照讀時序要求就可以順利讀入FPGA 中進(jìn)行運算。狀態(tài)機由閑置狀態(tài)(idle) 進(jìn)入傳輸讀數(shù)據(jù)指令狀態(tài)(tx_cmd),讀數(shù)據(jù)指令同樣需要3 個字節(jié)的地址數(shù)據(jù)來指定讀取據(jù)存儲空間的起始地址,當(dāng)芯片被選中時,就可以一直不斷地從SPI Flash 中讀取數(shù)據(jù)。接著SPI Flash 控制器經(jīng)過傳輸?shù)刂罚╰xadd)狀態(tài)進(jìn)入到讀數(shù)據(jù)(rxdata) 狀態(tài),如果還有未傳輸完的數(shù)據(jù)(即byte_count 未計數(shù)到256),SPI Flash 控制器則繼續(xù)留在讀數(shù)據(jù)狀態(tài),直到所需讀取的數(shù)據(jù)都傳輸完后,再進(jìn)入到清除指令(clr_cmd)狀態(tài),最后恢復(fù)到閑置(idle)狀態(tài)。讀Flash 狀態(tài)機如圖8 所示。
2. 3 BlockRAM 模塊
由于本設(shè)計選用的Flash 容量較大,一般FPGA 沒有這么大的存儲空間,所以FPGA 中需要調(diào)用數(shù)據(jù)緩沖存儲器BlockRAM。它是由Xilinx 提供的IPCore,設(shè)計比較方便,而且靈活、高效、不容易出錯。BlockRAM有兩個完全獨立的端口科技進(jìn)入共享的存儲空間,兩個端口都有讀/ 寫接口。IP 允許使用者在FPGA 內(nèi)部快速建立優(yōu)化的存儲器資源,本系統(tǒng)采用單端口設(shè)計,在BlockRAM 屬性選擇中將端口A 的寬度選為8,將深度選為256,配置選項選為Read And Write(讀和寫),寫模式選為Write After Read。當(dāng)向BlockRAM 中寫數(shù)據(jù)時,將WEA 和ENA 置位,并輸入地址和數(shù)據(jù)即可;當(dāng)需要從BlockRAM 中讀數(shù)據(jù)時,由于采用了Read And Write 模式,所以只要將地址輸入給BlockRAM,就會順利的將指定地址的數(shù)據(jù)讀出[6] 。
2. 4 SPI 接口模塊
在此模塊中將設(shè)計分為三大塊:并行數(shù)據(jù)串行移位,分頻,串行數(shù)據(jù)并行移位。SPI Flash 的工作時鐘是由外部控制器提供的,本設(shè)計中主時鐘為48MHz,取4 點進(jìn)行采樣,每到一個采集點,時鐘翻轉(zhuǎn)一次,完成分頻,分頻得到的時鐘1 MHz 作為SPI Flash 的時鐘輸入。
由從Flash 控制器中得到的數(shù)據(jù)為并行數(shù)據(jù),但SPI Flash 為串行接口,所以SPI 接口模塊主要功能是將FPGA 發(fā)送的并行數(shù)據(jù)轉(zhuǎn)化為串行數(shù)據(jù)輸出給SPI Flash,系統(tǒng)由閑置狀態(tài)進(jìn)入并行數(shù)據(jù)串行移位狀態(tài),啟動延時模塊,s_do 的值要保持48伊8 個系統(tǒng)周期才能使得mosi 在一個SPI 周期輸出1 bit 數(shù)據(jù),同時移位寄存器左移1 bit,將最高位賦給mosi 輸出,如此反復(fù)直到輸出8 bit 數(shù)據(jù),為滿足SPI Flash 的響應(yīng)時間,系統(tǒng)增加傳輸?shù)却隣顟B(tài),經(jīng)過傳輸?shù)却隣顟B(tài)又回到閑置狀態(tài),完成了一個字節(jié)數(shù)據(jù)的寫入。
同樣,當(dāng)需要讀SPI Flash 中的數(shù)據(jù)時,將SPI Flash 中的串行數(shù)據(jù)轉(zhuǎn)化為并行數(shù)據(jù)送入FPGA 中,系統(tǒng)由閑置狀態(tài)進(jìn)入串行數(shù)據(jù)并行移位狀態(tài),在此狀態(tài)啟動延時模塊,SPI Flash 輸出1 bit 數(shù)據(jù)需要48個系統(tǒng)周期,輸出8 bit 數(shù)據(jù)就要48伊8 個系統(tǒng)周期,即s_di 要保持48伊8 個系統(tǒng)周期,首先將miso 的值賦給s_di[0],將s_di 左移一位,當(dāng)延時48 個周期后,反復(fù)上述操作,直到將8 bit miso 數(shù)據(jù)都輸出給s_di,經(jīng)過傳輸?shù)却隣顟B(tài)回到閑置狀態(tài),完成了一個字節(jié)數(shù)據(jù)的讀出。
3 系統(tǒng)仿真結(jié)果與分析
SPI Flash 控制器在Xilinx ISE12. 2 編程環(huán)境下實現(xiàn),結(jié)合自帶的仿真軟件Isim 進(jìn)行仿真。板上調(diào)試時鐘選為48 MHz,經(jīng)測試數(shù)據(jù)傳輸準(zhǔn)確無誤。由于篇幅有限,本文僅對寫Flash 和讀Flash 給出仿真波形圖并進(jìn)行分析。
3. 1 寫Flash 仿真與分析
寫Flash 仿真波形如圖9 所示。
由圖9 可以看出,當(dāng)SPI Flash 控制器進(jìn)入到傳輸數(shù)據(jù)(tx_data)狀態(tài),這時s_wr 變高(s_wr 在傳輸指令及數(shù)據(jù)地址時也保持為高電平狀態(tài)),并在整個字節(jié)的寫入程中保持高電平狀態(tài),在s_df 的控制下開始傳輸數(shù)據(jù),經(jīng)過8 個clk 周期SPI Flash 控制器通過一個移位寄存器將從s_do 獲取的用戶端數(shù)據(jù)逐位輸出給SPI Flash。
3. 2 讀Flash 仿真與分析
讀Flash 仿真波形如圖10 所示。
由圖10 可以看出,當(dāng)SPI Flash 控制器進(jìn)入到讀數(shù)據(jù)(rxdata)狀態(tài)時,spi_rd 變高,并在整個字節(jié)的讀數(shù)據(jù)過程中保持高電平狀態(tài),經(jīng)過8 個clk 周期SPI Flash 控制器通過一個移位寄存器將從SPI Flash 中讀取得的1 字節(jié)數(shù)據(jù)寄存起來,最后在通過s_di 輸出給用戶。
4 結(jié)語
本文以實際應(yīng)用為出發(fā)點, 實現(xiàn)了一個基于FPGA 的SPI Flash 控制器,并重點分析了其工作狀態(tài)轉(zhuǎn)換過程。該控制器能夠很好地實現(xiàn)對FPGA 芯片進(jìn)行在線配置,具有廣泛的應(yīng)用價值。該方法具有較高的可移植性,以及簡單方便的用戶接口,并且控制器經(jīng)過簡單的修改就可以用于控制其它型號的SPI Flash 芯片,因此具有很高的可兼容性。
評論