摘要:本篇博客具體包括SPI協(xié)議的基本原理、模式選擇以及時(shí)序邏輯要求,采用FPGA(EPCE4),通過SPI通信協(xié)議,對flash(W25Q16BV)存儲的固化程序進(jìn)行芯片擦除操作。
關(guān)鍵詞:SPI;Verilog HDL;Flash
【SPI協(xié)議通信模式】
SPI是Motorola公司推出的一種同步串行接口,是一種高速、全雙工、同步的通信總線,廣泛應(yīng)用于存儲器,數(shù)模轉(zhuǎn)換器,實(shí)時(shí)時(shí)鐘等。
優(yōu)點(diǎn):支持全雙工通信,通訊方式簡單,相對數(shù)據(jù)傳輸速率較快。
缺點(diǎn):沒有指定的流控制,沒有應(yīng)答機(jī)制,數(shù)據(jù)可靠性上存在缺陷。
SPI協(xié)議通過四根線進(jìn)行數(shù)據(jù)傳輸,即SCK(Serial Clock)、MOSI(Master Output Slave Input)、MISO(Master Input Slave Output)、/SS(Slave Select,低電平有效)(或/CS)。
接口處理方式:一主一從(左)、一主多從【星型鏈?zhǔn)健浚ㄓ遥㏒PI通信要求主機(jī)和從機(jī)具有同步的時(shí)鐘信號,傳輸速率直接受到時(shí)鐘頻率(SCLK)的影響。

信號線說明:
MOSI、MISO數(shù)據(jù)在SCK同步信號下傳輸,每個(gè)時(shí)鐘周期傳輸一位數(shù)據(jù),輸入輸出同步進(jìn)行,要保證MSB或LSB先行需一致。/SS從設(shè)備信號選擇線,由高變低,是SPI通訊的起始信號。當(dāng)從設(shè)備/SS線檢測到起始信號后,即為選中使能與主機(jī)通訊。/SS信號由低變高,為停止信號,從設(shè)備的選中狀態(tài)被取消。
注:SPI每次數(shù)據(jù)傳輸可以8位或16位為單位,每次傳輸?shù)膯挝粩?shù)不受限制。
SPI通信時(shí)鐘模式:
SPI通信加入了時(shí)鐘相位(CPHA)和時(shí)鐘極性(CPOL)的設(shè)置,通過組合CPOL和CPHA的不同設(shè)置,SPI共支持四種常見的時(shí)鐘配置模式。
| CPOL | CPHA |
|---|---|
| 時(shí)鐘極性,定義時(shí)鐘信號在空閑狀態(tài)下的電平 | 時(shí)鐘相位,定義數(shù)據(jù)采樣和轉(zhuǎn)換的時(shí)鐘邊沿 |
| CPOL=0:SCK空閑為低電平 | CPHA=0:SCK的第一個(gè)邊沿采樣數(shù)據(jù)并轉(zhuǎn)換輸出信號 |
| CPOL=1:SCK空閑為高電平 | CPHA=1:SCK的第二個(gè)邊沿采樣數(shù)據(jù)并轉(zhuǎn)換輸出信號 |
在CPHA指示為l時(shí), 數(shù)據(jù)就會在SCLK的第二個(gè)有效邊沿被采樣(/SS拉低后,空閑為高,為上升沿;空閑為低,下降沿),同時(shí)被鎖存到寄存器中;如果CPHA 清零,數(shù)據(jù)就會在SCLK的第一個(gè)有效邊沿被采樣(/SS拉低后,空閑為高,為下降沿;空閑為低,為上升沿),同時(shí)被鎖存起來。SPI的主從設(shè)備須配置相同的時(shí)序模式,見下圖。

【W(wǎng)25Q16BV操作說明】
板載Flash芯片型號:W25Q16BV;總?cè)萘繛?6M bit,即2M字節(jié);存儲陣列被分成8192個(gè)可編程頁,每頁容量256字節(jié);支持Standard SPI、Dual SPI和Quad SPI三種SPI通信協(xié)議,最大讀/寫傳輸速率達(dá)50MB/s。它支持多種擦除操作,包括扇區(qū)擦除(4KB)、塊擦除(32KB或64KB)以及全芯片擦除。
1、接口處理與結(jié)構(gòu)邏輯

上圖可以看到,除SPI經(jīng)典的四個(gè)引腳外,還有/WP和/HOLD,分別用于寫保護(hù)和輸入保持。對于不同倍率SPI協(xié)議,引腳使用搭配是有區(qū)別的。
W25Q16BV內(nèi)部存儲結(jié)構(gòu)的邏輯和功能組織見下圖,SPI接口負(fù)責(zé)接收命令和地址,并通過控制邏輯進(jìn)行解析和執(zhí)行。狀態(tài)寄存器(Status Register)用于存儲設(shè)備的狀態(tài)信息,如是否忙碌(BUSY位);寫控制通過IO2引腳控制,用于啟動寫操作;高電平生成器(High Voltage Generators)用于執(zhí)行如擦除等操作;控制邏輯(Control Logic)負(fù)責(zé)解析SPI接口接收到的命令,并根據(jù)需要控制存儲器的讀/寫操作。列解碼(Column Decode)和頁面緩沖(256-Byte Page Buffer)用于支持頁面的讀/寫操作。

存儲器部分被分割成32個(gè)塊(Block),單個(gè)塊區(qū)包含16個(gè)扇區(qū)(Sector),每個(gè)扇區(qū)又由16個(gè)頁組成,單頁存儲256字節(jié)數(shù)據(jù),共計(jì)32 x 16 x 16 x 256 ≈ 2M 字節(jié)。存儲器通過頁地址和字節(jié)地址來定位特定的數(shù)據(jù)位置。
24位地址線通過上述的層次結(jié)構(gòu)來映射整個(gè)存儲器的地址空間,具體見下面表格。
| 分區(qū) | 地址位 |
|---|---|
| 塊(Block)地址 | 23~16位(0x1F0000到0x1FFFFF) |
| 扇區(qū)(Sector)地址 | 15~12位(0x00F000到0x00FFFF) |
| 頁(Page)地址 | 11~8位 |
| 字節(jié)(Byte)地址 | 7~0位 |
2、指令與時(shí)序說明
軟件命令:W25Q16BV的指令集由30條基本指令組成,指令完全通過SPI總線控制。指令的啟動是通過/CS的下降邊緣來觸發(fā)的,/CS拉高前須完成指令輸入,否則無效。DI輸入的第一個(gè)字節(jié)提供指令代碼,DI輸入上的數(shù)據(jù)是在時(shí)鐘的上升沿采樣的,首先采樣的是最高有效位(MSB)。
指令的長度從單個(gè)字節(jié)到幾個(gè)字節(jié)不等,后面可能跟著地址字節(jié)、數(shù)據(jù)字節(jié)、虛擬字節(jié)(可選),在某些情況下,還可能是它們組合。所有的讀指令都可以在任何一個(gè)時(shí)鐘位之后完成。
| 指令 | 編碼 | 指令 | 編碼 |
|---|---|---|---|
| Write Enable | 06h | Write Disable | 04h |
| Sector Erase (4KB) | 20h | Block Erase (32KB) | 52h |
| Block Erase (64KB) | D8h | Chip Erase | C7h/60h |
| Continuous Read Mode Reset | FFh | Read Data | 03h |
| Fast Read | 0Bh | Write Status Register | 01h |
所有寫、編程或擦除指令必須在字節(jié)邊界上完成(即,在完整的8位數(shù)據(jù)被時(shí)鐘同步后,/CS被驅(qū)動為高)。如果不在字節(jié)邊界上完成,該指令將被終止。這一特性旨在保護(hù)設(shè)備免受意外寫入的影響。
當(dāng)內(nèi)存正在被編程或擦除,或者當(dāng)狀態(tài)寄存器正在被寫入時(shí),除了讀狀態(tài)寄存器指令之外的所有指令都將被忽略,直到編程或擦除周期完成。
電平切換時(shí)序要求:
下圖為Serial Input Timing,其中片選線/CS待輸入完成后拉高電平保持時(shí)間(tSHSL) (for Array Read Array Read / Erase or Program Read Status Registers) :至少7/40 ns;片選信號有效建立時(shí)間(tSLCH):至少為5ns;片選信號有效保持時(shí)間(tCHSH):至少為5ns。注意:讀指令/寫指令時(shí)鐘頻率最大為50Mhz。

寫使能(Write Enable ):該指令用于設(shè)置(狀態(tài)寄存器中)寫使能鎖存器(WEL)位為1,確保存儲器處于可寫狀態(tài)。

首先,將/CS(Chip Select)引腳拉低,SPI通信啟動。在CLK上升沿,將數(shù)據(jù)輸入(DI)引腳上的數(shù)據(jù)位設(shè)置為指令代碼“06h”,即0000 0110。完成后,將/CS引腳拉高,SPI通信的結(jié)束和寫使能完成。
讀操作(Read Data):這個(gè)指令允許從存儲器中順序地讀取一個(gè)或多個(gè)數(shù)據(jù)字節(jié)。首先,通過將/CS引腳拉低來啟動指令,將指令代碼“03h”(0000 0011)和一個(gè)24位地址(A23-A0)通過DI引腳移位輸入,代碼和地址位在CLK上升沿時(shí)被鎖定。最后,通過將/CS引腳拉高完成指令。

如果在擦除、編程或?qū)懭胫芷谡谶M(jìn)行時(shí)(BUSY=1)發(fā)出讀取數(shù)據(jù)指令,該指令將被忽略。
芯片全擦除操作(Chip Erase):Chip Erase 指令會將設(shè)備內(nèi)的所有存儲器設(shè)置為擦除狀態(tài),即所有位都設(shè)為1。

①擦除啟動:在執(zhí)行芯片擦除指令之前,必須先執(zhí)行一個(gè)“寫使能”指令,使設(shè)備能夠接受芯片擦除指令(狀態(tài)寄存器的WEL位必須等于1)。將/CS引腳拉低來啟動指令,移位輸入指令代碼“C7h”或“60h”,在第八位被鎖定后,/CS引腳須被拉高。
②擦除過程:/CS被拉高后,自計(jì)時(shí)的芯片擦除指令將開始執(zhí)行。芯片擦除周期(典型3s,最大10s)進(jìn)行期間,仍然可以通過“讀取狀態(tài)寄存器”指令來檢查BUSY位的狀態(tài)(BUSY位在芯片擦除周期期間為1)。
③擦除后的狀態(tài):WEL位會被置0,注意:存儲數(shù)據(jù)的任何部分受到塊保護(hù)(BP2、BP1和BP0)位的保護(hù),則不會執(zhí)行芯片擦除指令。
【Flash全擦除操作】
1、Quartus II進(jìn)行程序固化下載及擦除
燒錄程序方式:①將程序下載到FPGA內(nèi)部的SRAM之中,燒錄過程耗時(shí)較短,但掉電后程序丟失;②將程序固化到FPGA外部掛載的非易失性存儲器Flash芯片,掉電后程序不丟失。
在Quartus II的主界面中,選擇“File”菜單下的“Convert Programming Files”選項(xiàng),用于將編譯生成的特定文件(如sof文件)轉(zhuǎn)換為其他格式的文件,如jic文件,以便下載到FPGA板載的flash或其他目標(biāo)設(shè)備中,流程見下圖。

下載程序時(shí),目標(biāo).jic文件后,右下指示框很明顯看到下載至Flash(這里是EPCS16類似W25Q16),僅勾選Program/Configure 進(jìn)行程序固化下載,僅勾選Erase表示擦除Flash操作。

2、Verilog程序?qū)崿F(xiàn)Flash芯片擦除操作(SPI)
根據(jù)Flash讀/寫時(shí)序要求,片選信號拉低后,需進(jìn)行5ns(tSLCH≥5ns)等待時(shí)間,及后寫入寫使能指令。寫入完成后,再次進(jìn)行5ns(tCHSH≥5ns)等待,拉高片選線維持≥100ns,接續(xù)完成寫入操作指令流程。

Flash芯片數(shù)據(jù)讀操作的時(shí)鐘頻率(SCK)上限為50MHz,這里通過四分頻設(shè)定SCK頻率為12.5Mhz。單個(gè)時(shí)鐘周期寫入1 bit數(shù)據(jù),完整的單字節(jié)指令需要8個(gè)完整的SCK時(shí)鐘周期,即32個(gè)完整的系統(tǒng)時(shí)鐘,系統(tǒng)時(shí)鐘頻率為50MHz,完整指令的寫入需要640ns。

mosi信號輸出采用了狀態(tài)機(jī)轉(zhuǎn)移的邏輯方法:
| 狀態(tài) | 說明 | 狀態(tài) | 說明 |
|---|---|---|---|
| IDLE | 空閑初始狀態(tài),等待觸發(fā)信號 | WR_EN | 發(fā)送寫使能指令 |
| DELAY | 等待狀態(tài),保持時(shí)序 | CH_ER | 芯片擦除指令發(fā)送 |
當(dāng)key_flag信號有效時(shí),從IDLE轉(zhuǎn)移到WR_EN狀態(tài),在WR_EN和CH_ER狀態(tài)中,分別寫入相應(yīng)的寫使能和指令后,等待tCHSH時(shí)間,然后拉高片選信號。在WR_EN狀態(tài)寫入指令后,轉(zhuǎn)移到DELAY狀態(tài)等待tSHSL時(shí)間。在DELAY狀態(tài)等待完成后,轉(zhuǎn)移到CH_ER狀態(tài),返回IDLE狀態(tài)。相關(guān)代碼如下:
parameter IDLE =4'b0001,WREN =4'b0010,DELAY=4'b0100,CH_ER=4'b1000;parameter WREN_CODE =8'b0000_0110,CH_ER_CODE =8'b1100_0111; always@(posedgesys_clkornegedgesys_rst)beginif(!sys_rst)state <= IDLE; ? ?elsecase(state) ? ? ? ? ? ? IDLE :if(key_flag)state <= WREN; ? ? ? ? ? ? WREN :if((cnt_byte ==?3'd2)&&(cnt_clk ==?5'd31))state <= DELAY; ? ? ? ? ? ? DELAY:if((cnt_byte ==?3'd3)&&(cnt_clk ==?5'd31))state <= CH_ER; ? ? ? ? ? ? CH_ER:if((cnt_byte ==?3'd6)&&(cnt_clk ==?5'd31))state <= IDLE; ? ? ? ? ? ?default:state <= IDLE; ? ? ? ?endcaseendalways?@(posedge?sys_clk?ornegedge?sys_rst)beginif(!sys_rst)mosi <=?1'b0; ? ?elseif((state == WREN)&&(cnt_byte ==?3'd2)) mosi <=?1'b0; ? ?elseif((state == CH_ER)&&(cnt_byte ==?3'd6)) mosi <=?1'b0; ? ?elseif((state == WREN)&&(cnt_byte ==?3'd1)&&(cnt_sck ==?2'd0)) ? ? ? ? mosi <= WREN_CODE[7?- cnt_bit]; ? ?elseif((state == CH_ER) && (cnt_byte ==?3'd5) && (cnt_sck ==?2'd0)) ? ? ? ? mosi <= CH_ER_CODE[7?- cnt_bit];end
而對于其他的信號邏輯處理:cnt_clk作為預(yù)期設(shè)定單位間距(640ns)的計(jì)數(shù)器,cnt_byte根據(jù)其完成7個(gè)階段的轉(zhuǎn)換。sck為寫操作的時(shí)鐘信號,cnt_sck作為其在有效時(shí)間段內(nèi)計(jì)數(shù)器,使得sck按sys_clk四分配輸出。
always@(posedgesys_clkornegedgesys_rst)beginif(!sys_rst) cnt_clk <=?5'd0; ? ?elseif(state != IDLE)cnt_clk <= cnt_clk +?1'b1; ?//位寬清零endalways?@(posedge?sys_clk?ornegedge?sys_rst)beginif(!sys_rst)cnt_byte <=?3'd0; ? ?elseif((cnt_byte ==?3'd6)&&(cnt_clk ==?5'd31))cnt_byte <=?3'd0; ? ?elseif(cnt_clk ==?5'd31) cnt_byte <= cnt_byte +?1'b1;endalways?@(posedge?sys_clk?ornegedge?sys_rst)beginif(!sys_rst)cnt_sck <=?2'd0; ? ?elseif((state == WREN)&&(cnt_byte ==?3'd1))cnt_sck <= cnt_sck +?1'b1; ?//位寬清零elseif((state == CH_ER)&&(cnt_byte ==?3'd5))cnt_sck <= cnt_sck +?1'b1; ?//位寬清零endalways?@(posedge?sys_clk?ornegedge?sys_rst)beginif(!sys_rst)cnt_bit <=?3'd0; ? ?elseif(cnt_sck ==?2'd2)cnt_bit <= cnt_bit +?1'b1;endalways?@(posedge?sys_clk?ornegedge?sys_rst)beginif(!sys_rst)ss_n <=?1'b1; ? ?elseif(key_flag)ss_n <=?1'b0; ? ?elseif((cnt_byte ==?3'd2)&&(cnt_clk ==?5'd31)&&(state == WREN))ss_n <=?1'b1; ? ?elseif((cnt_byte ==?3'd3)&&(cnt_clk ==?5'd31)&&(state == DELAY))ss_n <=?1'b0; ? ?elseif((cnt_byte ==?3'd6)&&(cnt_clk ==?5'd31)&&(state == CH_ER))ss_n <=?1'b1;endalways?@(posedge?sys_clk?ornegedge?sys_rst)beginif(!sys_rst)sck <=?1'b0; ? ?elseif(cnt_sck ==?2'd0)sck <=?1'b0; ? ?elseif(cnt_sck ==?2'd2)sck <=?1'b1;end
導(dǎo)入仿真文件,對芯片擦除操作進(jìn)行仿真,由于該操作耗時(shí)長,仿真前在Flash參數(shù)文件縮放擦除周期至4000ns。從上圖仿真結(jié)果可以看到,在4710ns處,F(xiàn)lash啟動芯片擦除,在8710ns結(jié)束擦除操作。


根據(jù)仿真結(jié)果顯示,sys_clk拉高后,程序正常工作,當(dāng)檢測到key_flag為高電平后,片選線SS_n拉低,指令操作開啟。等待一個(gè)有效建立時(shí)間后(這里是640ns,便于編寫代碼),sck正式輸出八段時(shí)鐘切換(12.5Mhz)。首先,按寫使能指令,輸出一個(gè)時(shí)序(0000_0110,06h)。等待一個(gè)片選線建立時(shí)間后拉高,進(jìn)入等待狀態(tài)(≥100ns,640ns)接續(xù)完成芯片擦除指令的錄入。cnt_byte和state的狀態(tài),隨cnt_clk時(shí)鐘計(jì)數(shù)變換。

-
FPGA
+關(guān)注
關(guān)注
1654文章
22276瀏覽量
629919 -
FlaSh
+關(guān)注
關(guān)注
10文章
1715瀏覽量
154635 -
SPI協(xié)議
+關(guān)注
關(guān)注
0文章
23瀏覽量
8784 -
通信總線
+關(guān)注
關(guān)注
0文章
47瀏覽量
10164
原文標(biāo)題:Flash驅(qū)動控制--芯片擦除(SPI協(xié)議)
文章出處:【微信號:gh_9d70b445f494,微信公眾號:FPGA設(shè)計(jì)論壇】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
基于FPGA的SPI Flash控制器的設(shè)計(jì)方案
基于FPGA的SPI Flash控制器的設(shè)計(jì)方案
實(shí)現(xiàn)簡單的SPI讀寫FLASH的方法
FPGA實(shí)現(xiàn)的SPI協(xié)議
FPGA零基礎(chǔ)學(xué)習(xí):SPI 協(xié)議驅(qū)動設(shè)計(jì)
PCI總線協(xié)議的FPGA實(shí)現(xiàn)及驅(qū)動設(shè)計(jì)
基于FPGA 的SPI Flash 控制器設(shè)計(jì)及驗(yàn)證
Flash存儲芯片的硬件設(shè)計(jì)
基于FPGA的SPI協(xié)議及設(shè)計(jì)實(shí)現(xiàn)
實(shí)現(xiàn)簡單的SPI讀寫FLASH
FPGA實(shí)現(xiàn)的SPI協(xié)議(二)----基于SPI接口的FLASH芯片M25P16的使用
FPGA實(shí)現(xiàn)的SPI協(xié)議(一)----SPI驅(qū)動
基于FPGA的SPI Flash控制器的設(shè)計(jì)方案

FPGA實(shí)現(xiàn)基于SPI協(xié)議的Flash驅(qū)動控制芯片擦除
評論