加入星計(jì)劃,您可以享受以下權(quán)益:

  • 創(chuàng)作內(nèi)容快速變現(xiàn)
  • 行業(yè)影響力擴(kuò)散
  • 作品版權(quán)保護(hù)
  • 300W+ 專業(yè)用戶
  • 1.5W+ 優(yōu)質(zhì)創(chuàng)作者
  • 5000+ 長(zhǎng)期合作伙伴
立即加入
  • 正文
    • EEPROM驅(qū)動(dòng)設(shè)計(jì)
  • 推薦器件
  • 相關(guān)推薦
申請(qǐng)入駐 產(chǎn)業(yè)圖譜

FPGA零基礎(chǔ)學(xué)習(xí)之Vivado-EEPROM驅(qū)動(dòng)設(shè)計(jì)

2023/08/24
2347
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論

作者:李西銳??校對(duì):陸輝

大俠好,歡迎來(lái)到FPGA技術(shù)江湖。本系列將帶來(lái)FPGA的系統(tǒng)性學(xué)習(xí),從最基本的數(shù)字電路基礎(chǔ)開始,最詳細(xì)操作步驟,最直白的言語(yǔ)描述,手把手的“傻瓜式”講解,讓電子、信息、通信類專業(yè)學(xué)生、初入職場(chǎng)小白及打算進(jìn)階提升的職業(yè)開發(fā)者都可以有系統(tǒng)性學(xué)習(xí)的機(jī)會(huì)。

系統(tǒng)性的掌握技術(shù)開發(fā)以及相關(guān)要求,對(duì)個(gè)人就業(yè)以及職業(yè)發(fā)展都有著潛在的幫助,希望對(duì)大家有所幫助。本次帶來(lái)Vivado系列,EEPROM驅(qū)動(dòng)設(shè)計(jì)。話不多說(shuō),上貨。

EEPROM驅(qū)動(dòng)設(shè)計(jì)

EEPROM (Electrically Erasable Programmable read only memory)是指帶電可擦可編程只讀存儲(chǔ)器。是一種掉電后數(shù)據(jù)不丟失的存儲(chǔ)芯片。EEPROM可以在電腦上或?qū)S迷O(shè)備上擦除已有信息,重新編程。一般用在即插即用。

EEPROM(帶電可擦可編程只讀存儲(chǔ)器)是用戶可更改的只讀存儲(chǔ)器(ROM),其可通過(guò)高于普通電壓的作用來(lái)擦除和重編程(重寫)。不像EPROM芯片,EEPROM不需從計(jì)算機(jī)中取出即可修改。在一個(gè)EEPROM中,當(dāng)計(jì)算機(jī)在使用的時(shí)候可頻繁地反復(fù)編程,因此EEPROM的壽命是一個(gè)很重要的設(shè)計(jì)考慮參數(shù)。EEPROM是一種特殊形式的閃存,其應(yīng)用通常是個(gè)人電腦中的電壓來(lái)擦寫和重編程。我們以SANXIN-B04板卡上的EEPROM為例,向大家介紹一下其驅(qū)動(dòng)方式。EEPROM型號(hào)為24LC64。

從特征中我們可以看出一些信息:

1、兩線串行總線,使用IIC接口協(xié)議。

2、有自擦除/寫循環(huán)時(shí)間。

3、有32字節(jié)頁(yè)寫和單字節(jié)寫模式。

4、最大5ms的寫循環(huán)時(shí)間。

知道了以上信息之后,那么我們繼續(xù)往下看手冊(cè)。

在這段描述中,我們可以看出,24LC64是一個(gè)8K*8的一個(gè)存儲(chǔ)器,總共64K bit的容量。因?yàn)榇鎯?chǔ)深度為8K,也就意味著芯片的地址有需要有8K個(gè),也就是有8192個(gè),從0開始到8191,那么地址線的位寬就是13位。這也就是我們?cè)趯?a class="article-link" target="_blank" href="/baike/495939.html">時(shí)序圖中展示的高字節(jié)地址和低字節(jié)地址。此外,芯片的供電范圍是1.8V到5.5V。芯片有頁(yè)寫功能,最多可寫32字節(jié)。允許最多有8個(gè)芯片連接到相同的總線上。

管腳及功能介紹:

A0、A1、A2三個(gè)端口為片選輸入,當(dāng)這三個(gè)端口的電平與從機(jī)地址相同時(shí),該芯片被選中,這些管腳必須接電源或者地。

SDA是一個(gè)雙向總線用于傳輸?shù)刂泛蛿?shù)據(jù),在SCL為低電平的時(shí)候,正常的數(shù)據(jù)傳輸SDA是允許被改變的,如果在SCL為高電平期間改變就會(huì)被認(rèn)為是開始和停止條件。

SCL為串行時(shí)鐘,用于同步數(shù)據(jù)的傳輸,由主機(jī)發(fā)出。

寫保護(hù)管腳,這個(gè)管腳可以連接地、電源或懸空。如果懸空,這個(gè)管腳上的下拉電阻會(huì)讓芯片保持不被保護(hù)的狀態(tài)。如果連接到了地或者懸空,正常的存儲(chǔ)器操作是有效地,如果連接到了電源,寫操作是禁止的,讀操作不受影響。

在SCL為高電平時(shí),SDA由高變低被視為開始條件,所有的命令必須在開始條件之后。

在SCL為高電平時(shí),SDA由低變高被視為停止條件,所有的操作必須以停止條件結(jié)束。

端口介紹完,這里要著重說(shuō)明一下應(yīng)答信號(hào)。每次接收完8bit數(shù)據(jù),從機(jī)需要產(chǎn)生一個(gè)應(yīng)答信號(hào),主機(jī)必須產(chǎn)生一個(gè)額外的時(shí)鐘周期伴隨著應(yīng)答信號(hào)。注釋:芯片如果有內(nèi)部循環(huán)在進(jìn)程中的話,是不會(huì)產(chǎn)生應(yīng)答信號(hào)的。在時(shí)鐘為高電平的時(shí)候,芯片的應(yīng)答信號(hào)必須拉低SDA,并且在SCL低電平期間保持穩(wěn)定。

上圖為IIC總線的示意圖,其中開始條件與停止條件在上文已經(jīng)描述過(guò)。其次是數(shù)據(jù)的讀寫,在圖中,SCL為高電平時(shí),地址或應(yīng)答有效,那么我們就在數(shù)據(jù)有效的時(shí)候進(jìn)行采數(shù);在SCL為低電平時(shí),數(shù)據(jù)允許被改變,那么我們發(fā)送數(shù)據(jù)就在此時(shí)間段。

在了解了端口的作用及功能之后,我們做一個(gè)總結(jié):

1、起始條件:SCL為高電平,SDA由高變低。

2、停止條件:SCL為低電平,SDA由低變高。

3、數(shù)據(jù)接收在SCL高電平期間。

4、數(shù)據(jù)發(fā)送在SCL低電平期間。

5、A0、A1、A2、WP在電路圖中已經(jīng)全部接地,在代碼中我們不需要關(guān)注。

電路圖中可以看出,我們的EEPROM的控制管腳只有SCL和SDA。

設(shè)計(jì)框架

按照上面的框架,完成各部分代碼,最后在此框架的基礎(chǔ)上,再加上數(shù)碼管模塊,用來(lái)顯示從EEPROM里面讀出的數(shù)據(jù)。

新建工程:

新建好工程后,新建文件,開始寫代碼,首先是寫模塊。

寫時(shí)序如下圖。

我們以單字節(jié)寫為例,因?yàn)樵趯懙墓こ讨?,沒(méi)寫8bit,就要讀一次ACK,所以在此我得做法是,讀模塊只寫8bit的線性序列機(jī),代碼如下:

1   module iic_wr(2 3     input   wire        clk,4     input   wire        rst_n,5     6     input   wire        wr_en,7     input   wire  [7:0] wr_data,8     9     output  reg         wr_scl,10    output  reg         wr_sda,11    output  wire        wr_done12  );1314    parameter f_clk = 50_000_000;15    parameter f = 100_000;16    parameter t = f_clk / f / 4;17    18    reg   [11:0]    cnt;19    20    always @ (posedge clk, negedge rst_n)21    begin22    if(rst_n == 1'b0)23      cnt <= 12'd0;24    else if(wr_en)25      begin26      if(cnt == 32 * t - 1)27        cnt <= 12'd0;28      else29        cnt <= cnt + 1'b1;30      end31    else32      cnt <= 12'd0;33    end34    35    always @ (posedge clk, negedge rst_n)36    begin37    if(rst_n == 1'b0)38      begin39      wr_scl <= 1'b0;40      wr_sda <= 1'b0;41      end42    else if(wr_en)43      case(cnt)44      0         : begin wr_scl <= 1'b0; wr_sda <= wr_data[7]; end45      1 * t - 1 : begin wr_scl <= 1'b1; end46      3 * t - 1 : begin wr_scl <= 1'b0; end47      4 * t - 1 : begin wr_sda <= wr_data[6]; end48      5 * t - 1 : begin wr_scl <= 1'b1; end49      7 * t - 1 : begin wr_scl <= 1'b0; end50      8 * t - 1 : begin wr_sda <= wr_data[5]; end51      9 * t - 1 : begin wr_scl <= 1'b1; end52      11* t - 1 : begin wr_scl <= 1'b0; end53      12* t - 1 : begin wr_sda <= wr_data[4]; end54      13* t - 1 : begin wr_scl <= 1'b1; end55      15* t - 1 : begin wr_scl <= 1'b0; end56      16* t - 1 : begin wr_sda <= wr_data[3]; end57      17* t - 1 : begin wr_scl <= 1'b1; end58      19* t - 1 : begin wr_scl <= 1'b0; end59      20* t - 1 : begin wr_sda <= wr_data[2]; end60      21* t - 1 : begin wr_scl <= 1'b1; end61      23* t - 1 : begin wr_scl <= 1'b0; end62      24* t - 1 : begin wr_sda <= wr_data[1]; end63      25* t - 1 : begin wr_scl <= 1'b1; end64      27* t - 1 : begin wr_scl <= 1'b0; end65      28* t - 1 : begin wr_sda <= wr_data[0]; end66      29* t - 1 : begin wr_scl <= 1'b1; end67      31* t - 1 : begin wr_scl <= 1'b0; end68      default : ;69      endcase70    end 71    72    assign wr_done = (cnt == 32 * t - 1) ? 1'b1 : 1'b0;7374  endmodule

在寫模塊中,我們選擇在SCL低電平中心位置發(fā)送數(shù)據(jù),那么為了方便我們寫線性序列機(jī),我們將四分之一SCL周期看做是一個(gè)單位時(shí)間T,總共8bit時(shí)間,所以計(jì)數(shù)器需要計(jì)數(shù)32個(gè)T。

讀模塊代碼如下:

1   module iic_rd(2 3     input   wire          clk,4     input   wire          rst_n,5     6     input   wire          rd_sda,7     input   wire          rd_en,8     9     output  reg           rd_scl,10    output  reg   [7:0]   rd_data,11    output  wire          rd_done12  );1314    parameter f_clk = 50_000_000;15    parameter f = 100_000;16    parameter t = f_clk / f / 4;17    18    reg   [11:0]    cnt;19    20    always @ (posedge clk, negedge rst_n)21    begin22    if(rst_n == 1'b0)23      cnt <= 12'd0;24    else if(rd_en)25      begin26      if(cnt == 32 * t - 1)27        cnt <= 12'd0;28      else29        cnt <= cnt + 1'b1;30      end31    else32      cnt <= 12'd0;33    end3435    always @ (posedge clk, negedge rst_n)36    begin37    if(rst_n == 1'b0)38      begin39      rd_scl <= 1'b0;40      rd_data <= 8'd0;41      end42    else if(rd_en)43      case(cnt)44      0         : begin rd_scl <= 1'b0; end45      1 * t - 1 : begin rd_scl <= 1'b1; end46      2 * t - 1 : begin rd_data[7] <= rd_sda; end47      3 * t - 1 : begin rd_scl <= 1'b0; end48      5 * t - 1 : begin rd_scl <= 1'b1; end49      6 * t - 1 : begin rd_data[6] <= rd_sda; end50      7 * t - 1 : begin rd_scl <= 1'b0; end51      9 * t - 1 : begin rd_scl <= 1'b1; end52      10* t - 1 : begin rd_data[5] <= rd_sda; end53      11* t - 1 : begin rd_scl <= 1'b0; end54      13* t - 1 : begin rd_scl <= 1'b1; end55      14* t - 1 : begin rd_data[4] <= rd_sda; end56      15* t - 1 : begin rd_scl <= 1'b0; end57      17* t - 1 : begin rd_scl <= 1'b1; end58      18* t - 1 : begin rd_data[3] <= rd_sda; end59      19* t - 1 : begin rd_scl <= 1'b0; end60      21* t - 1 : begin rd_scl <= 1'b1; end61      22* t - 1 : begin rd_data[2] <= rd_sda; end62      23* t - 1 : begin rd_scl <= 1'b0; end63      25* t - 1 : begin rd_scl <= 1'b1; end64      26* t - 1 : begin rd_data[1] <= rd_sda; end65      27* t - 1 : begin rd_scl <= 1'b0; end66      29* t - 1 : begin rd_scl <= 1'b1; end67      30* t - 1 : begin rd_data[0] <= rd_sda; end68      31* t - 1 : begin rd_scl <= 1'b0; end69      default : ;70      endcase71    end72    73    assign rd_done = (cnt == 32 * t - 1) ? 1'b1 : 1'b0;7475  endmodule

在控制模塊中,我們可以將每個(gè)bit分解開進(jìn)行寫,比如起始條件:

類比以上寫法,停止條件也是如此。

在控制模塊中我們使用狀態(tài)機(jī)來(lái)完成數(shù)據(jù)的寫入以及ACK的判斷。我們?cè)诘谝粋€(gè)狀態(tài)中,可以加入一個(gè)按鍵來(lái)啟動(dòng)整個(gè)過(guò)程的開始。

在ACK讀取的狀態(tài),我們?cè)赟CL高電平中心讀取ACK的值,在此狀態(tài)結(jié)束時(shí)判斷ACK的值是否為0,如果為0說(shuō)明響應(yīng)正確,狀態(tài)繼續(xù)往下,否則返回起始條件狀態(tài)。

在頂層代碼中,我們需要加入三態(tài)門來(lái)控制雙端口。

在寫好代碼之后,出現(xiàn)了一個(gè)問(wèn)題,那就是我們無(wú)法仿真,因?yàn)閱渭兊目床ㄐ?,?huì)發(fā)現(xiàn)我們得不到正確的ACK,導(dǎo)致狀態(tài)一直無(wú)法繼續(xù)。因此我們將使用仿真模型來(lái)進(jìn)行仿真,在仿真模型中,端口為芯片的控制端口。

在此模型中需要我們注意的一點(diǎn)就是,寫循環(huán)時(shí)間定義的為5ms時(shí)間,如果大家覺(jué)得時(shí)間太長(zhǎng),可以自行修改。

仿真代碼如下:

1   `timescale 1ns/1ps2 3   module iic_tb;4     5     reg            clk;6     reg            rst_n;7     reg            key;8     9     wire  [2:0]     sel;10    wire  [7:0]     seg;11    wire            SCL;12    wire            SDA;13    14    defparam iic_inst.jitter_inst.t = 10;15    16    pullup(SDA);17    18    initial begin19    clk = 0;20    rst_n = 0;21    key = 1;22    #100;23    rst_n = 1;24    #1000;25    key = 0;26    #1000;27    key = 1;28    #1000000;29    $stop;30    end31    32    always #10 clk = ~clk;33    34    iic iic_inst(3536    .clk        (clk),37    .rst_n      (rst_n),38    .key        (key),39    40    .sel        (sel),41    .seg        (seg),42    .SCL        (SCL),43    .SDA        (SDA)44  );4546    M24LC64 M24LC64_inst(47    .A0       (1'b0), 48    .A1       (1'b0), 49    .A2       (1'b0), 50    .WP       (1'b0), 51    .SDA      (SDA), 52    .SCL      (SCL)53    );5455  endmodule

寫好代碼之后,我們打開仿真波形進(jìn)行觀察。

在仿真波形中可以看出,我們讀出來(lái)的數(shù)據(jù)跟寫入的數(shù)據(jù)時(shí)一致的,即表明驅(qū)動(dòng)正確。需要注意的是,在寫循環(huán)時(shí)間內(nèi),我們發(fā)送的命令,芯片是不接收的,所以會(huì)出現(xiàn)起始條件、寫控制字、ACK三個(gè)狀態(tài)一直循環(huán),直到數(shù)據(jù)寫入完成,仿真模型才會(huì)返回ACK。此時(shí),狀態(tài)繼續(xù)往下進(jìn)行,直至結(jié)束。

我們從仿真模型中讀出的數(shù)據(jù),高電平是為高阻的,模型無(wú)法拉高,所以我們?cè)诜抡嬷锌梢宰孕猩侠?,這樣才能看到完整且正確的數(shù)據(jù)。

至此,我們實(shí)驗(yàn)正確。

推薦器件

更多器件
器件型號(hào) 數(shù)量 器件廠商 器件描述 數(shù)據(jù)手冊(cè) ECAD模型 風(fēng)險(xiǎn)等級(jí) 參考價(jià)格 更多信息
A3P1000-FG256I 1 Microsemi Corporation Field Programmable Gate Array, 24576 CLBs, 1000000 Gates, 350MHz, CMOS, PBGA256, 17 X 17 MM, 1.60 MM HEIGHT, 1 MM PITCH, FBGA-256
$74.11 查看
LFE3-35EA-8FN484C 1 Lattice Semiconductor Corporation Field Programmable Gate Array, 500MHz, 33000-Cell, PBGA484, 23 X 23 MM, LEAD FREE, FPBGA-484

ECAD模型

下載ECAD模型
$48.92 查看
M2GL060TS-1VF400I 1 Microchip Technology Inc Field Programmable Gate Array, PBGA400
$1215.61 查看

相關(guān)推薦

登錄即可解鎖
  • 海量技術(shù)文章
  • 設(shè)計(jì)資源下載
  • 產(chǎn)業(yè)鏈客戶資源
  • 寫文章/發(fā)需求
立即登錄

任何技術(shù)的學(xué)習(xí)就好比一個(gè)江湖,對(duì)于每一位俠客都需要不斷的歷練,從初入江湖的小白到歸隱山林的隱世高人,需要不斷的自我感悟自己修煉,讓我們一起仗劍闖FPGA乃至更大的江湖。