002 I 2 C Verilogソースコード解析を実現
19973 ワード
ソースアドレス:http://www.opencores.org/projects/i2c/タイミングチャートオンラインペイントツール:https://wavedrom.com/図形描画ツール:https://app.diagrams.net/
1フレーム構造
i2c_master_top
読んでいる間に一度だけデバイスアドレス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
8ビットパラレルシリアル
8ビットカウンタ 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である
開始、読み書き、停止のタイミングは以下の通りである: start stop read read中のSDAは高抵抗状態であり、1ではない.このようにslaveはSDAを制御し、master write にデータを出力することができるはそれぞれ5つの状態であるため、更新頻度は5*fSCLであり、fSCL=100 Khzの場合sys_clk=50でclk_div=99 startはスタートなので、eが複数あって、eの後はiですが、このiは実は後ろのその状態(read,write)の です
しんごうぜんしょり
SDA、SCLのデータはそのままではなく、多くのfilter Captureを経験しています.
Filter filter_cnt周波数はfSCL周波数の4倍 である
Synchronized、Delayed 4倍周波数サンプリングSCLは、3つの連続ビット決定出力を用いて同期 を行う.
仲裁失敗(Aribitration lost)
1フレーム構造
i2c_master_top
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);
シリアル後の各ビットを出力し、各ビットの出力は5段階(a、b、c、d、i)に分けられ、startはeを1つ増やし、iはidleである
開始、読み書き、停止のタイミングは以下の通りである: start stop read read中のSDAは高抵抗状態であり、1ではない.このようにslaveはSDAを制御し、master write にデータを出力することができる
しんごうぜんしょり
SDA、SCLのデータはそのままではなく、多くのfilter 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
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;
仲裁失敗(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