基於FPGA的I2C讀寫EEPROM

  I2C在芯片的配置中應用仍是不少的,好比攝像頭、VGA轉HDMI轉換芯片,以前博主分享過一篇I2C協議的基礎學習IIC協議學習筆記,這篇就使用Verilog來實現EEPROM的讀寫,進行一個簡單的I2C實戰應用。html

EEPROM

我使用的這個芯片是AT24C32,它手冊上還有一種AT24C64,其實操做都是同樣的,只是內存大小不一樣,AT24C32是32k(4096x8)AT24C64是64k(9=8192x8),數組

SCL設置爲頻率200Khz微信

SCL clk posedge data輸入EEPROMpost

SCL clk negedge data輸出EEPROM學習

SDA 雙向Pinurl

A2,A1,A0 Device Addr default all 0,只操做一片可懸空引腳。spa

WP 接地正常讀寫,WP接Vcc寫操做被禁止設計

字節尋址地址,是由12(AT24C32)或13bit(AT24C64)的地址組成,須要操做16位字地址高3或4位忽略便可。3d

Device Address    8’hA0寫器件地址,8’hA1讀器件地址code

寫字節操做

隨機讀字節操做

    我這個芯片是雙字節數據地址,因此在寫數據地址時要寫兩次,先是高字節後是低字節。

 

開始結束標誌

    這個I2C總線的時序是一致的。

 

EEPROM應答

    輸出應答scl的第九個週期給出,低電平應答。若是主機沒有收到應答,須要從新配置。

數據傳輸時序

    sda數據線在scl時鐘的降低沿中間變化,能夠避免產生誤觸開始結束標誌。

I2C Design

 

    i2c_start爲高電平有效,傳輸完成後會產生一個i2c_done結束標誌,表示操做完成。

I2C狀態轉移圖

I2C寫操做

(1)產生start位

(2)傳送器件地址ID_Address,器件地址的最後一位爲數據的傳輸方向位,R/W,低電平0表示主機往從機寫數據(W),1表示主機從從機讀數據(R)。這裏按照手冊給出的操做圖,應該是W即低電平。ACK應答,應答是從機發送給主機的應答,這裏不用管。

(3)傳送寫入器件寄存器地址,即數據要寫入的位置。一樣ACK應答不用管。

(4)傳送要寫入的數據。ACK應答不用管。

(5)產生stop信號。

I2C讀操做

(1)產生start信號

(2)傳送器件地址(寫ID_Address),這裏按照手冊給出的操做圖,最低位是W即低電平。ACK。

(3)傳送字地址(寫REG_Address),ACK。

(4)再次產生start信號

(5)再傳送一次器件地址,這裏根據手冊最低位是讀R高電平,ACK。

(6)讀取一個字節的數據,讀數據最後結束前無應答ACK信號。

(7)產生stop信號。

    讀寫操做的寫器件地址和寫數據地址操做是同樣的,狀態轉移圖中讀寫操做中這兩部分複用了,根據讀寫標誌來判斷。

    其餘部分沒啥好說的根據時序圖寫就好了,須要注意的一點是咱們應該在sclk的高電平的中間採樣數據,在sclk低電平的中間改變數據,當sclk爲高電平的時候,sda爲出現降低沿爲start位, sda出現上升沿爲stop位,因此在sclk爲高電平的時候sda應該保持穩定不能隨意亂動。這就又回到了數據傳輸有效的條件,只有在sclk爲低電平期間,才容許數據變化,在高電平期間,不容許數據變化,不然就會出現起始位或結束位。

    EEPROM有個仿真模型,在夏雨聞老師的書裏面就有,這個模型默認是200khz的sclk驅動,仿真的時候能夠將時間參數改小,我這裏也分享出來。

 

仿真模型代碼

  1 `timescale 1ns/1ns
  2 `define timeslice 1250
  3 //`define timeslice 300
  4 
  5 module EEPROM_AT24C64(
  6     scl, 
  7     sda
  8 );
  9     input scl;               //串行時鐘線
 10     inout sda;               //串行數據線
 11     
 12     reg out_flag;            //SDA數據輸出的控制信號
 13     
 14     reg[7:0] memory[8191:0]; //數組模擬存儲器
 15     reg[12:0]address;        //地址總線
 16     reg[7:0]memory_buf;      //數據輸入輸出寄存器
 17     reg[7:0]sda_buf;         //SDA數據輸出寄存器
 18     reg[7:0]shift;           //SDA數據輸入寄存器
 19     reg[7:0]addr_byte_h;     //EEPROM存儲單元地址高字節寄存器
 20     reg[7:0]addr_byte_l;     //EEPROM存儲單元地址低字節寄存器
 21     reg[7:0]ctrl_byte;       //控制字寄存器
 22     reg[1:0]State;           //狀態寄存器
 23     
 24     integer i;
 25     
 26     //---------------------------
 27     parameter  
 28         r7 = 8'b1010_1111,  w7 = 8'b1010_1110,   //main7
 29         r6 = 8'b1010_1101,  w6 = 8'b1010_1100,   //main6
 30         r5 = 8'b1010_1011,  w5 = 8'b1010_1010,   //main5
 31         r4 = 8'b1010_1001,  w4 = 8'b1010_1000,   //main4
 32         r3 = 8'b1010_0111,  w3 = 8'b1010_0110,   //main3
 33         r2 = 8'b1010_0101,  w2 = 8'b1010_0100,   //main2
 34         r1 = 8'b1010_0011,  w1 = 8'b1010_0010,   //main1
 35         r0 = 8'b1010_0001,  w0 = 8'b1010_0000;   //main0    
 36     //---------------------------
 37     
 38     assign sda = (out_flag == 1) ? sda_buf[7] : 1'bz;
 39     
 40     //------------寄存器和存儲器初始化---------------
 41     initial
 42     begin
 43         addr_byte_h    = 0;
 44         addr_byte_l    = 0;
 45         ctrl_byte    = 0;
 46         out_flag     = 0;
 47         sda_buf      = 0;
 48         State        = 2'b00;
 49         memory_buf   = 0;
 50         address      = 0;
 51         shift        = 0;
 52         
 53         for(i=0;i<=8191;i=i+1)
 54             memory[i] = 0;  
 55     end
 56 
 57     //啓動信號
 58     always@(negedge sda)
 59     begin
 60         if(scl == 1)
 61         begin
 62             State = State + 1;
 63             if(State == 2'b11)
 64                 disable write_to_eeprom;
 65         end 
 66     end
 67     
 68     //主狀態機
 69     always@(posedge sda)
 70     begin
 71         if(scl == 1)                //中止操做
 72             stop_W_R;
 73         else
 74         begin
 75             casex(State)
 76                 2'b01:begin
 77                     read_in;
 78                     if(ctrl_byte == w7 || ctrl_byte == w6 
 79                         || ctrl_byte == w5  || ctrl_byte == w4
 80                         || ctrl_byte == w3  || ctrl_byte == w2
 81                         || ctrl_byte == w1  || ctrl_byte == w0)
 82                     begin
 83                         State = 2'b10;
 84                         write_to_eeprom;    //寫操做                 
 85                     end
 86                     else
 87                         State = 2'b00;  
 88                         //State = State;         
 89                 end
 90                 
 91                 2'b11:
 92                     read_from_eeprom;               
 93                 
 94                 default:
 95                     State = 2'b00;          
 96             endcase     
 97         end 
 98     end     //主狀態機結束
 99     
100     //操做中止
101     task stop_W_R;
102     begin
103         State        = 2'b00;
104         addr_byte_h  = 0;
105         addr_byte_l  = 0;
106         ctrl_byte    = 0;
107         out_flag     = 0;
108         sda_buf      = 0;   
109     end
110     endtask
111     
112     //讀進控制字和存儲單元地址
113     task read_in;
114     begin
115         shift_in(ctrl_byte);
116         shift_in(addr_byte_h);
117         shift_in(addr_byte_l);      
118     end 
119     endtask
120     
121     //EEPROM的寫操做
122     task write_to_eeprom;
123     begin
124         shift_in(memory_buf);
125         address = {addr_byte_h[4:0], addr_byte_l};
126         memory[address] = memory_buf;       
127         State = 2'b00;
128     end
129     endtask
130     
131     //EEPROM的讀操做
132     task read_from_eeprom;
133     begin
134         shift_in(ctrl_byte);
135         if(ctrl_byte == r7 || ctrl_byte == w6 
136             || ctrl_byte == r5  || ctrl_byte == r4
137             || ctrl_byte == r3  || ctrl_byte == r2
138             || ctrl_byte == r1  || ctrl_byte == r0)
139         begin
140             address = {addr_byte_h[4:0], addr_byte_l};
141             sda_buf = memory[address];
142             shift_out;
143             State = 2'b00;
144         end
145     end
146     endtask
147     
148     //SDA數據線上的數據存入寄存器,數據在SCL的高電平有效
149     task shift_in;  
150         output[7:0]shift;
151         begin
152             @(posedge scl) shift[7] = sda;
153             @(posedge scl) shift[6] = sda;
154             @(posedge scl) shift[5] = sda;
155             @(posedge scl) shift[4] = sda;
156             @(posedge scl) shift[3] = sda;
157             @(posedge scl) shift[2] = sda;
158             @(posedge scl) shift[1] = sda;
159             @(posedge scl) shift[0] = sda;
160             
161             @(negedge scl)
162             begin
163                 #`timeslice;
164                 out_flag = 1;     //應答信號輸出
165                 sda_buf = 0;
166             end
167             
168             @(negedge scl)
169             begin
170                 #`timeslice;
171                 out_flag = 0;               
172             end         
173         end 
174     endtask
175     
176     //EEPROM存儲器中的數據經過SDA數據線輸出,數據在SCL低電平時變化
177     task shift_out;
178     begin
179         out_flag = 1;
180         for(i=6; i>=0; i=i-1)
181         begin
182             @(negedge scl);
183             #`timeslice;
184             sda_buf = sda_buf << 1;         
185         end
186         @(negedge scl) #`timeslice sda_buf[7] = 1;    //非應答信號輸出
187         @(negedge scl) #`timeslice out_flag = 0;
188     end
189     endtask
190 
191 endmodule 
192 //eeprom.v文件結束

       根據仿真模型仿真的話基本不會有什麼問題,須要注意的是操做的完成標誌。從仿真上看到輸入讀寫都沒問題,可是stop標誌沒產生好,仿真看到讀寫操做沒問題,但實際仍是不行的,須要嚴格按照EEPROM的手冊操做時序進行,差一點就不行。

    I2C的代碼我分享出來,我最後使用撥碼開關做爲讀寫使能,數碼管顯示讀出來的輸出,最後實現了對指定存儲地址讀寫數據。

I2C設計代碼點擊閱讀原文能夠查看。

  1 `timescale      1ns/1ps
  2 // *********************************************************************************
  3 // Project Name :       
  4 // Author       : NingHeChuan
  5 // Email        : ninghechuan@foxmail.com
  6 // Blogs        : http://www.cnblogs.com/ninghechuan/
  7 // File Name    : I2C_Ctrl_EEPROM.v
  8 // Module Name  :
  9 // Called By    :
 10 // Abstract     :
 11 //
 12 // CopyRight(c) 2018, NingHeChuan Studio.. 
 13 // All Rights Reserved
 14 //
 15 // *********************************************************************************
 16 // Modification History:
 17 // Date         By              Version                 Change Description
 18 // -----------------------------------------------------------------------
 19 // 2018/8/15    NingHeChuan       1.0                     Original
 20 //  
 21 // *********************************************************************************
 22 
 23 module I2C_Ctrl_EEPROM(
 24     input                   clk,
 25     input                   rst_n,
 26     input           [31:0]  eeprom_config_data,
 27     input                   i2c_start,          //1 valid
 28     inout                   i2c_sdat,
 29     output                  i2c_sclk,
 30     output                  i2c_done,
 31     output      reg [7:0]   i2c_rd_data 
 32 );
 33 
 34 
 35 //-------------------------------------------------------
 36 parameter       I2C_IDLE        =   'd0;
 37 parameter       I2C_START       =   'd1;
 38 parameter       I2C_WR_IDADDR   =   'd2;
 39 parameter       I2C_WR_ACK1     =   'd3;
 40 parameter       I2C_WR_REGADDR1 =   'd4;
 41 parameter       I2C_WR_ACK2     =   'd5;
 42 parameter       I2C_WR_REGADDR2 =   'd6;
 43 parameter       I2C_WR_ACK3     =   'd7;
 44 parameter       I2C_WR_DATA     =   'd8;
 45 parameter       I2C_WR_ACK4     =   'd9;
 46 parameter       I2C_WR_STOP     =   'd10;
 47 //-------------------------------------------------------
 48 parameter       I2C_RD_START    =   'd11;
 49 parameter       I2C_RD_IDADDR   =   'd12;
 50 parameter       I2C_RD_ACK      =   'd13;
 51 parameter       I2C_RD_DATA     =   'd14;
 52 parameter       I2C_RD_NPACK    =   'd15;
 53 parameter       I2C_RD_STOP     =   'd16;
 54 //i2c_sclk freq
 55 parameter       I2C_FREQ      =   250;    //50Mhz/200Khz/2 = 125
 56 parameter       TRANSFER      =   1;
 57 parameter       CAPTURE       =   125;
 58 //parameter       I2C_FREQ        =   60;    //50Mhz/200Khz/2 = 125
 59 //parameter       TRANSFER        =   1;
 60 //parameter       CAPTURE         =   30;
 61 parameter       SEND_BIT        =   8;
 62 
 63 //-------------------------------------------------------
 64 reg     [4:0]   pre_state;
 65 reg     [4:0]   next_state;
 66 //
 67 reg             i2c_sdat_r;
 68 wire            bir_en;
 69 //
 70 wire            transfer_en;
 71 wire            capture_en;
 72 reg             i2c_sclk_r;
 73 reg     [7:0]   sclk_cnt;
 74 //
 75 reg     [3:0]   tran_cnt;
 76 //
 77 wire    [7:0]   wr_device_addr = {eeprom_config_data[31:25], 1'b0};
 78 wire    [7:0]   rd_device_addr = {eeprom_config_data[31:25], 1'b1};
 79 wire            wr_rd_flag  =   eeprom_config_data[24];
 80 wire    [7:0]   reg_addr1   = eeprom_config_data[23:16];
 81 wire    [7:0]   reg_addr2   = eeprom_config_data[15:8];
 82 wire    [7:0]   wr_data     = eeprom_config_data[7:0];
 83 //
 84 reg             wr_ack1;
 85 reg             wr_ack2;
 86 reg             wr_ack3;
 87 reg             wr_ack4;
 88 reg             rd_ack1;
 89 
 90 //-------------------------------------------------------
 91 //i2c_sclk
 92 always @(posedge clk or negedge rst_n)begin
 93     if(rst_n == 1'b0)
 94         sclk_cnt <= 'd1;
 95     else if(sclk_cnt == I2C_FREQ - 1'b1)
 96         sclk_cnt <= 'd0;
 97     else 
 98         sclk_cnt <= sclk_cnt + 1'b1;
 99 end
100 
101 always @(posedge clk or negedge rst_n)begin
102     if(rst_n == 1'b0)
103         i2c_sclk_r <= 1'b0;
104     else if(sclk_cnt >= (I2C_FREQ>>2)*1 && sclk_cnt <= (I2C_FREQ>>2)*3)
105         i2c_sclk_r <= 1'b1;
106     else 
107         i2c_sclk_r <= 1'b0;
108 end
109 //
110 assign  transfer_en = (sclk_cnt == TRANSFER - 1)? 1'b1: 1'b0;
111 assign  capture_en  = (sclk_cnt == CAPTURE - 1)? 1'b1: 1'b0;
112 
113 //-------------------------------------------------------
114 always @(posedge clk or negedge rst_n)begin
115     if(rst_n == 1'b0)
116         tran_cnt <= 'd0;
117     else if(tran_cnt == SEND_BIT && transfer_en == 1'b1)
118         tran_cnt <= 'd0;
119     else if(((next_state == I2C_WR_IDADDR || next_state == I2C_WR_REGADDR1 || 
120         next_state ==I2C_WR_REGADDR2 || next_state == I2C_WR_DATA || 
121         next_state == I2C_RD_IDADDR) && transfer_en == 1'b1) || 
122         (next_state == I2C_RD_DATA && capture_en == 1'b1))
123         tran_cnt <= tran_cnt + 1'b1;
124     else 
125         tran_cnt <= tran_cnt;
126 end
127 
128 //-------------------------------------------------------
129 //FSM step1
130 always @(posedge clk or negedge rst_n)begin
131     if(rst_n == 1'b0)
132         pre_state <= I2C_IDLE;
133     else
134         pre_state <= next_state;
135 end
136 
137 //FSM step2
138 always @(*)begin
139     next_state = I2C_IDLE;
140     case(pre_state)
141     I2C_IDLE:
142         if(i2c_start == 1'b1 && transfer_en == 1'b1)
143             next_state = I2C_START;
144         else 
145             next_state = I2C_IDLE;
146     I2C_START:
147         if(transfer_en == 1'b1)
148             next_state = I2C_WR_IDADDR;
149         else 
150             next_state = I2C_START;
151     I2C_WR_IDADDR:
152         if(transfer_en == 1'b1 && tran_cnt == SEND_BIT)
153             next_state = I2C_WR_ACK1;
154         else
155             next_state = I2C_WR_IDADDR;
156     I2C_WR_ACK1:
157         if(transfer_en == 1'b1 && wr_ack1 == 1'b0)
158             next_state = I2C_WR_REGADDR1;
159         else if(transfer_en == 1'b1)
160             next_state = I2C_IDLE;
161         else 
162             next_state = I2C_WR_ACK1;
163     I2C_WR_REGADDR1:
164         if(transfer_en == 1'b1 && tran_cnt == SEND_BIT)
165             next_state = I2C_WR_ACK2;
166         else
167             next_state = I2C_WR_REGADDR1;
168     I2C_WR_ACK2:
169         if(transfer_en == 1'b1 && wr_ack2 == 1'b0)
170             next_state = I2C_WR_REGADDR2;
171         else if(transfer_en == 1'b1)
172             next_state = I2C_IDLE;
173         else 
174             next_state = I2C_WR_ACK2;
175     I2C_WR_REGADDR2:
176         if(transfer_en == 1'b1 && tran_cnt == SEND_BIT)
177             next_state = I2C_WR_ACK3;
178         else
179             next_state = I2C_WR_REGADDR2;
180     I2C_WR_ACK3:
181         if(transfer_en == 1'b1 && wr_ack3 == 1'b0 && wr_rd_flag == 1'b0)
182             next_state = I2C_WR_DATA;
183         else if(transfer_en == 1'b1 && wr_ack3 == 1'b0 && wr_rd_flag == 1'b1)
184             next_state = I2C_RD_START;
185         else if(transfer_en == 1'b1)
186             next_state = I2C_IDLE;
187         else 
188             next_state = I2C_WR_ACK3;
189     I2C_WR_DATA:
190         if(transfer_en == 1'b1 && tran_cnt == SEND_BIT)
191             next_state = I2C_WR_ACK4;
192         else
193             next_state = I2C_WR_DATA;
194     I2C_WR_ACK4:
195         if(transfer_en == 1'b1 && wr_ack4 == 1'b0)
196             next_state = I2C_WR_STOP;
197         else if(transfer_en == 1'b1)
198             next_state = I2C_IDLE;
199         else 
200             next_state = I2C_WR_ACK4;
201     I2C_WR_STOP:
202         if(transfer_en == 1'b1)
203             next_state = I2C_IDLE;
204         else 
205             next_state = I2C_WR_STOP;
206     I2C_RD_START:
207         if(transfer_en == 1'b1)
208             next_state = I2C_RD_IDADDR;
209         else 
210             next_state = I2C_RD_START;
211     I2C_RD_IDADDR:
212         if(transfer_en == 1'b1 && tran_cnt == SEND_BIT)
213             next_state = I2C_RD_ACK;
214         else
215             next_state = I2C_RD_IDADDR;
216     I2C_RD_ACK:
217         if(transfer_en == 1'b1 && rd_ack1 == 1'b0)
218             next_state = I2C_RD_DATA;
219         else if(transfer_en == 1'b1)
220             next_state = I2C_IDLE;
221         else 
222             next_state = I2C_RD_ACK;
223     I2C_RD_DATA:
224         if(transfer_en == 1'b1 && tran_cnt == SEND_BIT)
225             next_state = I2C_RD_NPACK;
226         else
227             next_state = I2C_RD_DATA;
228     I2C_RD_NPACK:
229         if(transfer_en == 1'b1)
230             next_state = I2C_RD_STOP;
231         else 
232             next_state = I2C_RD_NPACK;
233     I2C_RD_STOP:
234         if(transfer_en == 1'b1)
235             next_state = I2C_IDLE;
236         else 
237             next_state = I2C_RD_STOP;
238     default:next_state = I2C_IDLE;
239     endcase
240 end
241 
242 //FSM step3
243 always @(posedge clk or negedge rst_n)begin
244     if(rst_n == 1'b0)
245         i2c_sdat_r <= 1'b1;
246     else begin
247         case(next_state)
248         I2C_IDLE:   if(capture_en == 1'b1)  i2c_sdat_r <= 1'b1;
249         I2C_START:  if(capture_en == 1'b1)  i2c_sdat_r <= 1'b0;
250         I2C_WR_IDADDR:  if(transfer_en == 1'b1) i2c_sdat_r <= wr_device_addr['d7 - tran_cnt];
251         I2C_WR_REGADDR1:if(transfer_en == 1'b1) i2c_sdat_r <= reg_addr1['d7 - tran_cnt];
252         I2C_WR_REGADDR2:if(transfer_en == 1'b1) i2c_sdat_r <= reg_addr2['d7 - tran_cnt];
253         I2C_WR_DATA:    if(transfer_en == 1'b1) i2c_sdat_r <= wr_data['d7 - tran_cnt];
254         I2C_WR_ACK4:    if(transfer_en == 1'b1) i2c_sdat_r <= 1'b0;
255         I2C_WR_STOP:    if(capture_en == 1'b1) i2c_sdat_r <= 1'b1;
256         I2C_RD_START:   if(capture_en == 1'b1)  i2c_sdat_r <= 1'b0;
257         I2C_RD_IDADDR:  if(transfer_en == 1'b1) i2c_sdat_r <= rd_device_addr['d7 - tran_cnt];
258         I2C_RD_NPACK:   if(transfer_en == 1'b1) i2c_sdat_r <= 1'b0;
259         I2C_RD_STOP:    if(capture_en == 1'b1) i2c_sdat_r <= 1'b1;
260         default:        i2c_sdat_r <= i2c_sdat_r; 
261         endcase
262     end
263 end
264 
265 always @(posedge clk or negedge rst_n)begin
266     if(rst_n == 1'b0)begin
267         i2c_rd_data <= 8'b0;
268         wr_ack1   <= 1'b1;
269         wr_ack2   <= 1'b1;
270         wr_ack3   <= 1'b1;
271         wr_ack4   <= 1'b1;
272         rd_ack1   <= 1'b1;
273     end
274     else if(capture_en == 1'b1)begin
275         case(next_state)
276         I2C_WR_ACK1: wr_ack1 <= i2c_sdat;
277         I2C_WR_ACK2: wr_ack2 <= i2c_sdat;
278         I2C_WR_ACK3: wr_ack3 <= i2c_sdat;
279         I2C_WR_ACK4: wr_ack4 <= i2c_sdat;
280         I2C_WR_STOP: begin
281             wr_ack1   <= 1'b1;
282             wr_ack2   <= 1'b1;
283             wr_ack3   <= 1'b1;
284             wr_ack4   <= 1'b1;
285             rd_ack1   <= 1'b1;
286         end
287         I2C_RD_ACK: rd_ack1 <= i2c_sdat;
288         I2C_RD_DATA: i2c_rd_data['d7 - tran_cnt] <= i2c_sdat;
289         I2C_RD_STOP:begin
290             wr_ack1   <= 1'b1;
291             wr_ack2   <= 1'b1;
292             wr_ack3   <= 1'b1;
293             wr_ack4   <= 1'b1;
294             rd_ack1   <= 1'b1;
295         end
296         default:begin
297             i2c_rd_data <= i2c_rd_data;
298             wr_ack1 <= wr_ack1;
299             wr_ack2 <= wr_ack2;
300             wr_ack3 <= wr_ack3;
301             wr_ack4 <= wr_ack4;
302             rd_ack1 <= rd_ack1;
303         end
304         endcase
305     end
306     else begin
307         i2c_rd_data <= i2c_rd_data;
308         wr_ack1   <= wr_ack1;
309         wr_ack2   <= wr_ack2;
310         wr_ack3   <= wr_ack3;
311         wr_ack4   <= wr_ack4;
312         rd_ack1   <= rd_ack1;
313     end
314 end
315 
316 //-------------------------------------------------------
317 assign  bir_en = (pre_state == I2C_WR_ACK1 || pre_state == I2C_WR_ACK2 || pre_state == I2C_WR_ACK3 ||
318                   pre_state == I2C_WR_ACK4 || pre_state == I2C_RD_ACK || pre_state == I2C_RD_DATA)? 1'b0: 1'b1;
319 
320 assign  i2c_sdat = (bir_en == 1'b1)? i2c_sdat_r: 1'bz;
321 
322 assign  i2c_sclk = i2c_sclk_r;
323 assign  i2c_done = (pre_state == I2C_WR_STOP && next_state == I2C_IDLE ||
324                     pre_state == I2C_RD_STOP && next_state == I2C_IDLE)? 1'b1: 1'b0;
325 
326 endmodule 

 

轉載請註明出處:NingHeChuan(寧河川)

我的微信訂閱號:開源FPGA

若是你想及時收到我的撰寫的博文推送,能夠掃描左邊二維碼(或者長按識別二維碼)關注我的微信訂閱號

知乎ID:NingHeChuan

微博ID:NingHeChuan

原文地址:http://www.javashuo.com/article/p-ocuvkyrf-bg.html 

相關文章
相關標籤/搜索