Initial commit
This commit is contained in:
89
i2c_io_output.sv
Normal file
89
i2c_io_output.sv
Normal file
@@ -0,0 +1,89 @@
|
||||
`timescale 1ps/1ps
|
||||
`default_nettype none
|
||||
|
||||
module i2c_io_output #(parameter [6:0] I2C_ADDR = 7'h5a,
|
||||
parameter IO_BYTES_COUNT = 2,
|
||||
localparam DATA_WIDTH = IO_BYTES_COUNT * 8)
|
||||
(input wire clock,
|
||||
input wire reset,
|
||||
|
||||
input wire i_scl,
|
||||
input wire i_sdi,
|
||||
output wire o_sdo,
|
||||
|
||||
output reg [DATA_WIDTH-1:0] o_data);
|
||||
|
||||
/* -------- I2C Receiver -------- */
|
||||
logic [7:0] i2c_data;
|
||||
logic i2c_strobe;
|
||||
logic i2c_start;
|
||||
logic i2c_stop;
|
||||
logic i2c_ack;
|
||||
|
||||
i2c_receiver i2c_receiver_impl
|
||||
(.clock(clock), .reset(reset),
|
||||
.i_scl(i_scl), .i_sdi(i_sdi), .o_sdo(o_sdo),
|
||||
.o_data(i2c_data),
|
||||
.o_strobe(i2c_strobe),
|
||||
.o_start(i2c_start),
|
||||
.o_stop(i2c_stop),
|
||||
.i_ack(i2c_ack));
|
||||
|
||||
/* -------- FSM -------- */
|
||||
enum int unsigned {
|
||||
ST_IDLE = 0,
|
||||
ST_RECEIVE_ADDR,
|
||||
ST_RECEIVE_BYTE,
|
||||
ST_COMPLETE
|
||||
} state;
|
||||
|
||||
localparam BYTE_CNTR_W = $clog2(IO_BYTES_COUNT);
|
||||
|
||||
logic [BYTE_CNTR_W-1:0] byte_cntr;
|
||||
logic [DATA_WIDTH-1:0] data;
|
||||
|
||||
always_ff @(posedge clock)
|
||||
if (reset) begin
|
||||
state <= ST_IDLE;
|
||||
byte_cntr <= '0;
|
||||
end
|
||||
else begin
|
||||
if (i2c_stop)
|
||||
state <= ST_IDLE;
|
||||
case (state)
|
||||
ST_IDLE: begin
|
||||
if (i2c_start)
|
||||
state <= ST_RECEIVE_ADDR;
|
||||
end
|
||||
|
||||
ST_RECEIVE_ADDR: begin
|
||||
if (i2c_strobe)
|
||||
if (i2c_data == {I2C_ADDR, 1'b0}) begin
|
||||
i2c_ack <= 1'b1;
|
||||
byte_cntr <= '0;
|
||||
state <= ST_RECEIVE_BYTE;
|
||||
end
|
||||
else begin
|
||||
i2c_ack <= 1'b0;
|
||||
state <= ST_IDLE;
|
||||
end
|
||||
end
|
||||
|
||||
ST_RECEIVE_BYTE: begin
|
||||
if (i2c_strobe) begin
|
||||
data <= {data[DATA_WIDTH-8-1:0], i2c_data}; // MSB first
|
||||
byte_cntr <= byte_cntr + 1'b1;
|
||||
|
||||
if (byte_cntr == BYTE_CNTR_W'(IO_BYTES_COUNT-1))
|
||||
state <= ST_COMPLETE;
|
||||
end
|
||||
end
|
||||
|
||||
ST_COMPLETE: begin
|
||||
o_data <= data;
|
||||
state <= ST_IDLE;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
endmodule // i2c_io_output
|
||||
Reference in New Issue
Block a user