module i2c(SCL_io, SDA_io, clk, rst, write); input write, clk, rst; output SCL_io; inout SDA_io; reg[2:0] stopcount; reg[3:0] bitcount; reg[3:0] msbcount; reg[7:0] indata = 8'b01001010; reg SCL,SDA; reg[3:0] pres; //, next; parameter s0=4'b0000,s1=4'b0001,s2=4'b0010,s3=4'b0011,s4=4'b0100,s5=4'b0101,s6=4'b0110,s7=4'b0111,s8=4'b1000; always@(posedge clk) begin if(rst) begin pres <= s0; stopcount <= 0; bitcount <= 0; msbcount <= 0; end else begin case (pres) s0: begin if(write) pres <= s1; else pres <= s0; end s1: begin pres <= s2; end s2: begin stopcount <= stopcount + 1; if(stopcount == 4) pres <= s8; else begin case (msbcount) 1: if( indata[7] == 1'b1) pres <= s5; else pres <= s3; 2: if( indata[6] == 1'b1) pres <= s5; else pres <= s3; 3: if( indata[5] == 1'b1) pres <= s5; else pres <= s3; 4: if( indata[4] == 1'b1) pres <= s5; else pres <= s3; 5: if( indata[3] == 1'b1) pres <= s5; else pres <= s3; 6: if( indata[2] == 1'b1) pres <= s5; else pres <= s3; 7: if( indata[1] == 1'b1) pres <= s5; else pres <= s3; 8: if( indata[0] == 1'b1) pres <= s5; else pres <= s3; default: // It may be better to have default clause pres <= s2; endcase end end s3: begin pres <= s4; end s4: begin bitcount <= bitcount + 1; msbcount <= msbcount + 1; if(bitcount == 8) pres <= s7; else begin case (msbcount) 1: if( indata[7] == 1'b1) pres <= s5; else pres <= s3; 2: if( indata[6] == 1'b1) pres <= s5; else pres <= s3; 3: if( indata[5] == 1'b1) pres <= s5; else pres <= s3; 4: if( indata[4] == 1'b1) pres <= s5; else pres <= s3; 5: if( indata[3] == 1'b1) pres <= s5; else pres <= s3; 6: if( indata[2] == 1'b1) pres <= s5; else pres <= s3; 7: if( indata[1] == 1'b1) pres <= s5; else pres <= s3; 8: if( indata[0] == 1'b1) pres <= s5; else pres <= s3; default: // It may be better to have default clause pres <= s4; endcase end end s5: begin pres <= s6; end s6: begin bitcount <= bitcount + 1; msbcount <= msbcount + 1; if(bitcount == 8) pres <= s7; else begin case (msbcount) 1: if( indata[7] == 1'b1) pres <= s5; else pres <= s3; 2: if( indata[6] == 1'b1) pres <= s5; else pres <= s3; 3: if( indata[5] == 1'b1) pres <= s5; else pres <= s3; 4: if( indata[4] == 1'b1) pres <= s5; else pres <= s3; 5: if( indata[3] == 1'b1) pres <= s5; else pres <= s3; 6: if( indata[2] == 1'b1) pres <= s5; else pres <= s3; 7: if( indata[1] == 1'b1) pres <= s5; else pres <= s3; 8: if( indata[0] == 1'b1) pres <= s5; else pres <= s3; default: // It may be better to have default clause pres <= s6; endcase end end s7: begin if(~SDA) pres <= s2; else pres <= s7; // pres <= s2; ?? end s8: begin pres <= s0; end default: begin // It may be better to have default clause pres <= s0; end endcase end always @ (pres or write or stopcount or msbcount or indata or bitcount) begin case (pres) s0: begin SDA = 1'b1; SCL = 1'b1; end s1: begin SDA = 1'b0; SCL = 1'b1; end s2: begin SDA = 1'b0; SCL = 1'b0; end s3: begin SDA = 1'b0; SCL = 1'b1; end s4: begin SDA = 1'b0; SCL = 1'b0; end s5: begin SDA = 1'b1; SCL = 1'b1; end s6: begin SDA = 1'b1; SCL = 1'b0; end s7: begin SDA = 1'b1; SCL = 1'b1; end s8: begin SDA = 1'b1; SCL = 1'b0; end default: begin // You must have default clause here SDA = 1'b1; // ?? SCL = 1'b1; // ?? end endcase end assign SDA_io = SDA; assign SCL_io = SCL; endmodule