李槐生
(太原理工大學信息學院,山西 太原 030024)
隨著科技的進步,電子產品已經以各種各樣的形式進入到了千家萬戶。如人們每天接觸的MP3、手機、數碼相機、移動存儲設備等電子產品。數據的存儲是電子設備的關鍵技術之一。而目前應用最為廣泛的存儲介質就是NAND FLASH,它具有存儲容量大、價格低廉、速度快等優點。對NAND FLASH的控制可以直接使用專用的控制芯片,這種方法比較簡單,但是性價比較低,該芯片的部分功能得不到使用,造成浪費,兼容性較差。目前隨著FPGA(即現場可編程邏輯門陣列)技術的發展,越來越多的工程師選擇自己開發專用集成芯片。這種方法可以根據用戶特有的需求來量身打造,且IP核可以與其它系統很好地集成互聯,兼容性好。本設計就是用FPGA來實現了NAND FLASH的控制器,并通過測試驗證了該IP核。
本控制器所實現的是對NAND FLASH的讀、寫、擦除以及壞塊處理等操作,其中利用FPGA內部RAM資源設計出32 K緩存,用來暫存FLASH中的數據,并留下控制端口,與MCU系統進行互聯,使得MCU等對NAND FLASH進行操作時不需要考慮具體的控制時序以及壞塊等問題,只需關注存儲數據以及存儲位置即可,使得MCU代碼開發者不需要過多地考慮物理底層的設計,簡化開發難度。控制器基本架構框見圖1。

圖1 NAND FLASH控制器
本設計選用的NAND FLASH為三星公司的K9F5608U0B,其容量為32 M×8 Bit。它有2 048個塊,每塊32頁,每頁有528個字節,其中每頁的最后16個字節用來存儲ECC校驗碼。FPGA選用的是Xilinx公司所生產的XC3S1000-4-FT256C。
該模塊作為整個控制器的核心模塊,起到了協調各個子模塊運行以及實現與MCU通信的作用。主要實現以下功能:
(1)首先接收到MCU發送過來的讀寫命令以及起始地址和數據總數。
(2)根據接收到的上述數據,該模塊計算出起始塊地址、起始頁地址、終止塊地址、終止頁地址以及總共塊數、總共頁數。
(3)如果從MCU讀命令,則用one page read命令來啟動FLASH讀模塊,按頁連續讀取。
(4)如果從MCU寫命令,啟動FLASH寫模塊,并進行如下操作:①首先將起始塊中未涉及到的頁的內容用Sequential Row Read命令讀取出來,并放入緩沖中;②對終止塊中未涉及到的頁進行上述處理;③對所涉及到的塊,用erase命令全部擦除;④將緩沖的數據再放回到FLASH中原先的位置中;⑤開始從MCU接收數據,并用write命令,一頁一頁地寫進FLASH中;⑥在寫完之后,啟動壞塊處理模塊,對所涉及的塊進行掃描,確定壞塊。
K9F5608U0B的讀命令種類比較多,有READ1與READ2兩種。Read2命令讀取的是spare area,即存放ECC校驗位的區域;Read1又可分為Read one page與Sequential Row Read1 Operation兩種操作。Read one page即一次只能讀一頁,而Sequential Row Read1 Operation則可以連續讀取多頁。連續讀取的范圍僅限于本塊當中,即如果控制器不發送停止該讀命令的信號,則在讀完本塊的最后一頁后Flash會自動停止讀取。當然,大部分的命令識別工作已經由FLASH控制模塊實現了。讀操作模塊中所寫的狀態機部分代碼如下:
process(cu_st,read,r_b,counter_we,counter_re_cyc,counter_re)begin
case cu_st is
when por=>
when wait_cmd=>
when cmd_adr_input=>
when wait_busy=>
when wait_ready=>
when read_process=>
end case;
end process;
該狀態機與控制模塊配合便可實現FLASH讀命令的各種時序。

圖2 寫模塊流程圖
從控制模塊接收到啟動命令,在接收了要寫入的地址以及數據之后,開始啟動狀態機。寫命令之前要進行塊擦除,這個是由控制模塊來協調的。流程見圖2。首先寫入write命令(80 H),之后輸入地址,由于地址有3個字節,所以需要在3個WE周期將地址輸入。首先輸入列地址,之后兩個字節為行地址(即頁地址)。將ALE地址鎖存信號拉低,依次輸入一頁的數據。輸入program command(80 h),FLASH將R/B信號拉低,并開始寫入數據。寫完之后FLASH將R/B信號置高,FLASH控制器檢測到R/B的變化,則輸入read status command,從I/O 0口獲取反饋,如果是0,表明寫操作成功,否則失敗。
塊擦除(Block erase)命令每次擦除一塊,所以在系統設計中,要設計一個32 K緩沖。當要寫一塊數據時先將該塊中有用的數據存儲到緩沖中再進行擦除,防止數據的丟失。塊擦除的工作流程見圖3。

圖3 擦除模塊流程圖
首先寫建立擦除命令(60 h),然后寫塊地址,這兒的地址為兩個字節。之后寫擦除指令(D0 h),在擦除的過程中,R/B信號為低,擦除完成之后置高。這時控制器檢測到R/B的高電位,輸入read status command命令來讀取狀態。如果I/O 0為低說明擦除成功,為高則說明擦除失敗。
每塊flash難免會有壞塊,但第一塊要確保是正常的。廠商在出廠時就會在壞塊上有相應的標記。Flash在使用之前,所有的字節都為FFH,但如果是壞塊的話,廠商會在其第1或第2頁的列地址為517處設置成non-FF,即spare field的第六個字節為非全1。
當所設計的系統準確度要求非常高的時候,對flash首先要做一次檢測,確定有哪些壞塊,并建立一個表來存儲這些壞塊的地址。而且在以后正常使用后,還要在每次擦除以及寫操作之后讀取flash狀態,如果是狀態為error的話就將這塊的地址存儲到壞塊表中。
分別通過對讀、寫以及擦除模塊的仿真,驗證了該設計的正確性以及可行性。仿真結果見圖4。

圖4 仿真結果
NAND FLASH存儲器已經成了存儲介質的主流產品,而其控制器大部分是國外產品,加快集成電路設計行業的發展是我國的當務之急,利用FPGA可以設計出具有自主知識產權的IP核,并且增強了兼容性與靈活性。
[1]K9F5608U0B FLASH MEMORY datasheet.http://www.samsung.com.2003.
[2]曾祥萍.ISE集成開發環境下基于FPGA的數字設計.電腦知識與應用,No.12P.156-158.2006.
[3]楊之廉.超大規模集成電路設計方法學導論(第二版).清華大學出版社,1999.
[4]徐欣,于紅旗等.基于FPGA的嵌入式系統設計.北京:機械工業出版社,2005.