module i2c_write( input clock, input start, output busy, output done, input [7:0] data, output reg sck = 1, output reg sda = 1 ); reg state_start = 0, state_data = 0, state_ack = 0, state_stop = 0; reg half_sck = 0; reg [3:0] bit = 0; // This is high in the cycle before a data transition occurs. wire transition = !half_sck && !sck; assign done = state_ack; assign busy = state_start || state_data || state_ack || state_stop; always @(posedge clock) begin // Generate SCK at half the incoming clock frequency if (state_data || state_ack || state_stop) begin half_sck <= ~half_sck; if (half_sck == 1) begin sck <= ~sck; end end case ({state_start, state_data, state_ack, state_stop}) 4'b0000: begin // Idle sck <= 1; sda <= 1; if (start) begin sda <= 0; state_start <= 1; end end 4'b1000: begin // Start sck <= 0; bit <= 0; half_sck <= 0; state_start <= 0; state_data <= 1; end 4'b0100: begin // Data if (transition) begin if (bit == 8) begin // Acknowledge bit // Drive it low here so we don't need a tristate output sda <= 0; state_data <= 0; state_ack <= 1; end else begin bit <= bit + 1; sda <= data[7 - bit[2:0]]; end end end 4'b0010: begin // Ack if (transition) begin state_ack <= 0; if (start) begin bit <= 1; sda <= data[7]; state_data <= 1; end else begin sda <= 0; state_stop <= 1; end end end 4'b0001: begin // Stop if (half_sck == 0 && sck == 1) begin sda <= 1; state_stop <= 0; end end endcase end endmodule