I2C Verilog的实现(一)

来源:互联网 发布:湖南云计算 编辑:程序博客网 时间:2024/06/01 10:15

TestBench 程序

`timescale 1ns / 1psmodule test(sda);regscl;inout sda;regsda_out;wiresda_in;reg[7:0]data;reg start_flag, stop_flag;assign sda = sda_out ? 1'bz : 1'b0;assign sda_in = sda;pullup( sda );I2CTEST testmine(.SDA(sda), .SCL(scl));initialbegin   scl = 0;sda_out = 0;data = 8'h27;start_flag = 0;#160000;start ( );endalways begin   #50000 scl = ~scl;   end   always @ (posedge start_flag)begin   repeat (8)      begin         wait ( scl == 0 );#20000;sda_out = data[7];#40000;data = data << 1;endwait (~ scl);#20000;sda_out = 1;#160000;stop ( );end always @ ( posedge stop_flag)begin//   sda_out = 0;//   #50000;   sda_out = 1;end   task start;   beginwait (scl == 0);#20000;sda_out = 1;wait ( scl == 1 );#20000;sda_out = 0;start_flag = 1;endendtasktask stop;beginwait ( scl == 0 );#20000;sda_out = 0;wait ( scl ==1 );#20000;sda_out = 1;stop_flag = 1;endendtaskendmodule


I2C程序

`timescale 1ns / 1psmodule I2CTEST(SDA, SCL);input SCL;inout SDA;// The 7-bits address that we want for our I2C slaveparameter I2C_ADR = 7'h13;//---------------------------------------------//start,stop condition judgement//---------------------------------------------wire start, stop;reg sda1, sda2;reg sda11;always @ ( posedge SCL )sda1 <= SDA;always @ ( negedge SCL )sda2 <= SDA;always @ ( negedge SCL )sda11 <= sda1;assign start = sda11 & (!sda2);assign stop = sda2 & ( !sda11 );//----------------------------------------------//count setting//----------------------------------------------reg [3:0]  bitcont;wire bit_ack = bitcont[3];always @ ( posedge SCL or posedge start)begin    if ( start )    bitcont <=  4'h6;    else    begin        if (bit_ack)        bitcont <= 4'h6;        else        bitcont <= bitcont -4'h1;    endend//-------------------------------------//get sda using posedge scl//-------------------------------------reg sdar;always @ ( posedge SCL ) sdar <= SDA;//----------------------------------------//address match//----------------------------------------reg addr_match, op_read;always @ ( negedge SCL or posedge start )begin    if ( start )    begin        addr_match <= 1'h1;        op_read <= 1'h0;    end    else    begin        if( (bitcont == 6) & (sdar != I2C_ADR[6])) addr_match <= 1'h0;        if( (bitcont == 5) & (sdar != I2C_ADR[5])) addr_match <= 1'h0;        if( (bitcont == 4) & (sdar != I2C_ADR[4])) addr_match <= 1'h0;        if( (bitcont == 3) & (sdar != I2C_ADR[3])) addr_match <= 1'h0;        if( (bitcont == 2) & (sdar != I2C_ADR[2])) addr_match <= 1'h0;        if( (bitcont == 1) & (sdar != I2C_ADR[1])) addr_match <= 1'h0;        if( (bitcont == 0) & (sdar != I2C_ADR[0])) addr_match <= 1'h0;        if( bitcont == 0 ) op_read <= sdar;    endend//-----------------------------------------------------------------------//send ack//-----------------------------------------------------------------------reg ack_assert;always @ ( negedge SCL )begin    if ( bit_ack & addr_match & op_read )    ack_assert <= 1'h1;    else    ack_assert <= 1'h0;end//-------------------------------------------------------------------------//control SDA line//-------------------------------------------------------------------------assign SDA = ack_assert ? 1'h0 : 1'hz;pullup ( SDA );endmodule



原创粉丝点击