002 I 2 C Verilogソースコード解析を実現

19973 ワード

ソースアドレス:http://www.opencores.org/projects/i2c/タイミングチャートオンラインペイントツール:https://wavedrom.com/図形描画ツール:https://app.diagrams.net/
1フレーム構造
002 I2C Verilog实现源码解析_第1张图片
i2c_master_top
在这里插入图片描述 002 I2C Verilog实现源码解析_第2张图片
  • 読んでいる間に一度だけデバイスアドレスS_を書きましたRD_DEV_ADDR 1は、1回目とは異なるアドレスの最下位ビットが1であり、読み出し
  • を示す.
  • S_WR_ERR_NACK:S_と書いてありますWR_DEV_ADDR、S_RD_DEV_ADDR 0、ACK
  • なし
  • start:S_WR_DEV_ADDR、S_RD_DEV_ADDR0、S_RD_DEV_ADDR1
  • stop:S_WR_STOP、S_RD_STOP
  • read:S_RD_DATA
  • write:S_WR_DEV_ADDR -> S_WR_DATA,S_RD_DEV_ADDR0 -> S_RD_REG_ADDR1
  • i2c_Al:仲裁失敗(arbitrament lose)、The stop signal is detected but no signal is requested.The host setting SDA is high,Actual SDA is low
  • done:ステータスジャンプを決定
  • i2c_master_byte_ctrl
    002 I2C Verilog实现源码解析_第3张图片 8ビットパラレルシリアル
    always @(posedge clk or negedge nReset)
    begin
      if (!nReset) // asynchronous reset
        sr <= #1 8'h0; //the"#"just for modelsim,it's not used when Analysis & Synthesis
      else if (rst==1) // synchronous reset
        sr <= #1 8'h0;
      else if (ld)  // load data
        sr <= #1 din; // write data to sda
      else if (shift)                               
        sr <= #1 {sr[6:0], core_rxd}; // read data from sda
    end
    

    8ビットカウンタ
    always @(posedge clk or negedge nReset)
    begin
      if (!nReset)
        dcnt <= #1 3'h0;
      else if (rst)
        dcnt <= #1 3'h0;
      else if (ld)                                 
        dcnt <= #1 3'h7;
      else if (shift)
        dcnt <= #1 dcnt - 3'h1;
    end
    
    assign cnt_done = ~(|dcnt);
    
  • core_ack:大条件
  • を更新
  • cnt_done:小条件を更新し、8ビットを更新すると次の状態
  • に入ることができます.
  • core_cmd:更新操作:I 2 C_CMD_NOP、I2C_CMD_START、I2C_CMD_STOP、I2C_CMD_WRITE、I2C_CMD_READ
  • cmd-ack:i2c_master_トップ中のdone,決定状態ジャンプ
  • i2c_master_bit_ctrl
    シリアル後の各ビットを出力し、各ビットの出力は5段階(a、b、c、d、i)に分けられ、startはeを1つ増やし、iはidleである
    002 I2C Verilog实现源码解析_第4张图片開始、読み書き、停止のタイミングは以下の通りである:在这里插入图片描述在这里插入图片描述 start 002 I2C Verilog实现源码解析_第5张图片 stop 002 I2C Verilog实现源码解析_第6张图片 read 002 I2C Verilog实现源码解析_第7张图片 read中のSDAは高抵抗状態であり、1ではない.このようにslaveはSDAを制御し、master write 002 I2C Verilog实现源码解析_第8张图片にデータを出力することができる
  • はそれぞれ5つの状態であるため、更新頻度は5*fSCLであり、fSCL=100 Khzの場合sys_clk=50でclk_div=99
  • startはスタートなので、eが複数あって、eの後はiですが、このiは実は後ろのその状態(read,write)の
  • です
    しんごうぜんしょり
    SDA、SCLのデータはそのままではなく、多くのfilter 002 I2C Verilog实现源码解析_第9张图片 Captureを経験しています.
    always @(posedge clk or negedge nReset)
    begin
        if (!nReset)
        begin
           cSCL <= #1 2'b00;
           cSDA <= #1 2'b00;
        end
        else if (rst)
        begin
           cSCL <= #1 2'b00;
           cSDA <= #1 2'b00;
        end
        else
        begin
           cSCL <= {cSCL[0],scl_i};
           cSDA <= {cSDA[0],sda_i};
        end
    end
    

    Filter
    always @(posedge clk or negedge nReset)//fSCL is the Operation control clock
    begin
        if(!nReset)
        begin
           fSCL <= 3'b111;
           fSDA <= 3'b111;
        end
        else if (rst)
        begin
           fSCL <= 3'b111;
           fSDA <= 3'b111;
        end
        else if (~|filter_cnt)             
        begin
           fSCL <= {fSCL[1:0],cSCL[1]};
           fSDA <= {fSDA[1:0],cSDA[1]};
        end
     end
    
  • filter_cnt周波数はfSCL周波数の4倍
  • である
    Synchronized、Delayed
    always @(posedge clk or negedge nReset)
    begin
        if (~nReset)
        begin
           sSCL <= #1 1'b1;
           sSDA <= #1 1'b1;
      
           dSCL <= #1 1'b1;
           dSDA <= #1 1'b1;
        end
        else if (rst)
        begin
           sSCL <= #1 1'b1;
           sSDA <= #1 1'b1;
           dSCL <= #1 1'b1;
           dSDA <= #1 1'b1;
        end
        else
        begin
         sSCL <= #1 &fSCL[2:1] | &fSCL[1:0] | (fSCL[2] & fSCL[0]);
           sSDA <= #1 &fSDA[2:1] | &fSDA[1:0] | (fSDA[2] & fSDA[0]);
           dSCL <= #1 sSCL;
           dSDA <= #1 sSDA;
        end
    end 
    
    // generate dout signal (store SDA on rising edge of SCL)
    always @(posedge clk)
        if(sSCL & ~dSCL) 
    		dout <= #1 sSDA;
    
  • 4倍周波数サンプリングSCLは、3つの連続ビット決定出力を用いて同期
  • を行う.
    仲裁失敗(Aribitration lost)
    //    :        ,         ,    SDA    ,    SDA    
    always @(posedge clk or negedge nReset)  
    begin
        if(~nReset)
           al <= #1 1'b0;
        else if(rst)
           al <= #1 1'b0;
        else
           al <= #1 (sda_chk & ~sSDA & sda_oen)|(|c_state & sto_condition & ~cmd_stop);
    end