zchong 发表于 2008-11-17 10:25:09

这个verilog写的I2C程序为何会报错,从fpga4fun上down的【恢复】

/ Example of I2C slave with 8-bits IO extender

// (c) 2005, 2008 fpga4fun.com, KNJN LLC







module I2Cslave(SDA, SCL, IOout);

inout SDA;

input SCL;

output  IOout;



// The 7-bits address that we want for our I2C slave

parameter I2C_ADR = 7'h27;



//////////////////////////

// I2C start and stop conditions detection logic

// That's the "black magic" part of this design...

// We use two wires with a combinatorial loop to detect the start and stop conditions

//  ... making sure these two wires don't get optimized away



wire SDA_shadow    /* synthesis keep = 1 */;

wire start_or_stop /* synthesis keep = 1 */;

assign SDA_shadow = (~SCL | start_or_stop) ? SDA : SDA_shadow;

assign start_or_stop = ~SCL ? 1'b0 : (SDA ^ SDA_shadow);

reg incycle;  

always @(negedge SCL or posedge start_or_stop) 

if(start_or_stop) 

        incycle <= 1'b0; 

else if(~SDA) 

        incycle <= 1'b1;



//////////////////////////

// Now we are ready to count the I2C bits coming in

reg  bitcnt;  // counts the I2C bits from 7 downto 0, plus an ACK bit

wire bit_DATA = ~bitcnt;  // the DATA bits are the first 8 bits sent

wire bit_ACK = bitcnt;  // the ACK bit is the 9th bit sent

reg data_phase;



always @(negedge SCL or negedge incycle)

if(~incycle)

begin

    bitcnt <= 4'h7;  // the bit 7 is received first

    data_phase <= 0;

end

else

begin

    if(bit_ACK)

    begin

            bitcnt <= 4'h7;

            data_phase <= 1;

    end

    else

            bitcnt <= bitcnt - 4'h1;

end



// and detect if the I2C address matches our own

wire adr_phase = ~data_phase;

reg adr_match, op_read, got_ACK;

reg SDAr;  always @(posedge SCL) SDAr<=SDA;  // sample SDA on posedge since the I2C spec specifies as low as 0祍 hold-time on negedge

reg  mem;

wire op_write = ~op_read;



always @(negedge SCL or negedge incycle)

if(~incycle)

begin

    got_ACK <= 0;

    adr_match <= 1;

    op_read <= 0;

end

else

begin

    if(adr_phase & bitcnt==7 & SDAr!=I2C_ADR) adr_match<=0;

    if(adr_phase & bitcnt==6 & SDAr!=I2C_ADR) adr_match<=0;

    if(adr_phase & bitcnt==5 & SDAr!=I2C_ADR) adr_match<=0;

    if(adr_phase & bitcnt==4 & SDAr!=I2C_ADR) adr_match<=0;

    if(adr_phase & bitcnt==3 & SDAr!=I2C_ADR) adr_match<=0;

    if(adr_phase & bitcnt==2 & SDAr!=I2C_ADR) adr_match<=0;

    if(adr_phase & bitcnt==1 & SDAr!=I2C_ADR) adr_match<=0;

    if(adr_phase & bitcnt==0) op_read <= SDAr;

    if(bit_ACK) got_ACK <= ~SDAr;  // we monitor the ACK to be able to free the bus when the master doesn't ACK during a read operation



    if(adr_match & bit_DATA & data_phase & op_write) mem <= SDAr;  // memory write

end



// and drive the SDA line when necessary.

wire mem_bit_low = ~mem];

wire SDA_assert_low = adr_match & bit_DATA & data_phase & op_read & mem_bit_low & got_ACK;

wire SDA_assert_ACK = adr_match & bit_ACK & (adr_phase | op_write);

wire SDA_low = SDA_assert_low | SDA_assert_ACK;

assign SDA = SDA_low ? 1'b0 : 1'bz;



assign IOout = mem;

endmodule







错误为

Error: The node "I2Cslave:inst|start_or_stop~0" has multiple drivers due to the always-enabled IO buffer "I2Cslave:inst|SDA~3"

编译环境为quartus II 7.2 Sp3

huayan 发表于 2008-11-17 21:54:02

帮ARMOK顶一下

armok 发表于 2008-11-17 21:10:31

zchong 发表于 2008-11-23 10:11:13

已解决,sda管脚我用了input,用bir就行了

huayan 发表于 2008-11-19 23:03:50

我晕...楼上谁拿了我的ID的...见鬼了..我刚上的呀

zchong 发表于 2008-11-21 17:37:02

高手都跑哪去了?

有谁做过 i2c slave的吗

zchong 发表于 2008-11-18 12:28:50

自己再顶一下

Eworm001 发表于 2011-1-2 00:54:59

回复【楼主位】zchong
/ example of i2c slave with 8-bits io extender
// (c) 2005, 2008 fpga4fun.com, knjn llc
module i2cslave(sda, scl, ioout);
inout sda;
input scl;
output ioout;
// the 7-bits address that we want for our i2c slave
parameter i2c_adr = 7'h27;
//////////////////////////
// i2c start and stop conditions detection logic
// that's the "black magic" part of this design...
// we use two wire......
-----------------------------------------------------------------------

回复【楼主位】zchong
-----------------------------------------------------------------------

想在此基础上增加一个IO ready标志位,不知道该如何修改?
页: [1]
查看完整版本: 这个verilog写的I2C程序为何会报错,从fpga4fun上down的【恢复】