Commit 3a8c6a9d authored by unknown's avatar unknown
Browse files

new module for the control of the I2C mux and expanders

parent 5fcddb19
//============================================================================================\\
//################################## Module Information ##################################\\
//============================================================================================\\
//
// Company: CERN (BE-BI)
//
// File Name: I2cExpAndMuxMaster.v
//
// File versions history:
//
// DATE VERSION AUTHOR DESCRIPTION
// - <date> <version> Andrea Boccardi <description>
//
// Language: Verilog 2005
//
// Description:
//
// The requests are level sensitive and accepted when the module is not busy.
//
//============================================================================================\\
//############################################################################################\\
//============================================================================================\\
`timescale 1ns/100ps
module I2cExpAndMuxMaster
//==================================== Global Parameters ===================================\\
#( parameter g_SclHalfPeriod = 10'd256)
//======================================== I/O ports =======================================\\
(
//==== Clocks & Resets ====\\
input Clk_ik,
input Rst_irq,
//==== Status and Requests====\\
output reg Busy_o,
input IoExpWrReq_i,
input IoExpRdReq_i,
input I2cMuxEnChReq_i,
input I2cMuxIntRdReq_i,
input FifoAccessReq_i,
output reg IoExpWrOn_oq,
output reg IoExpRdOn_oq,
output reg I2cEnChOn_oq,
output reg I2cMuxRdIntOn_oq,
output reg FifoAccessOn_oq,
output reg NewByteRead_op,
output reg [7:0] ByteOut_ob8,
output reg AckError_op,
// IO Expanders parameters:
input [2:0] IoExpAddr_i,
input [1:0] IoExpRegAddr_ib2,
input [7:0] IoExpData_ib8,
// I2C Mux parameters:
input I2cMuxAddress_i,
input [1:0] I2cMuxChannel_ib2,
// FIFO access programming interface:
output FifoFull_o,
output FifoEmpty_o,
input [10:0] FifoCommand_ib11,
input FifoCommandWr_i,
output reg FifoWriteDone_op,
output reg FifoWriteAck_o,
output reg FifoReadDone_op,
output reg [7:0] FifoByteRead_ob8,
//==== I2C Bus ====\\
inout Scl_ioz,
inout Sda_ioz
);
//======================================= Declarations =====================================\\
//==== Local parameters ====\\
// FSM:
localparam s_Idle = 4'h0,
s_FetchCommand = 4'h1,
s_StartExecution = 4'h2,
s_StartSda1 = 4'h3,
s_StartScl1 = 4'h4,
s_StartSda0 = 4'h5,
s_StartScl0 = 4'h6,
s_SendScl0 = 4'h7,
s_SendScl1 = 4'h8,
s_GetScl0 = 4'h9,
s_GetScl1 = 4'ha,
s_StopSda0 = 4'hb,
s_StopScl1 = 4'ha,
s_StopSda1 = 4'hb;
// Command sequence ROM:
localparam c_IoExpWriteSeq = 3'd0,
c_IoExpReadSeq = 3'd1,
c_I2cMuxIntReadSeq = 3'd2,
c_I2cMuxEnChSeq = 3'd3,
c_FifoSeq = 3'd4;
// Commands:
localparam c_SendStartBit = 3'd1,
c_SendStopBit = 3'd2,
c_SendByte = 3'd3,
c_GetByte = 3'd4,
c_GoToIdle = 3'b0; //Comment: required also in FIFO mode to close stop the transaction
//==== Wires & Regs ====\\
// FSM
reg [3:0] State_qb4, NextState_ab4;
wire AnyRequest_a = IoExpWrReq_i || IoExpRdReq_i || I2cMuxIntRdReq_i || I2cMuxEnChReq_i || FifoAccessReq_i;
// Support Logic
reg [2:0] Command_b3;
reg [9:0] SclCounter_c10;
reg [3:0] BitCounter_c4;
reg SclOe_e, SdaOe_e;
reg I2CAck;
reg [7:0] ShReg_b8;
reg [2:0] ActiveSequence_b3;
// FIFO connections
wire [10:0] FifoDout_b11;
reg FifoRead;
// Command Sequences
reg [2:0] IoExpAddr_qb3;
reg [1:0] IoExpRegAddr_qb2;
reg [7:0] IoExpData_qb8;
reg [10:0] IoExpWriteSeq_b11, IoExpReadSeq_b11;
reg I2cMuxAddress_q;
reg [1:0] I2cMuxChannel_qb2;
reg [10:0] I2cMuxReadSeq_b11, I2cMuxEnChSeq_b11;
//======================================= User Logic =======================================\\
//==== I2C command's sequences ====\\
always @(posedge Clk_ik)
if (~Busy_o && (IoExpWrReq_i || IoExpRdReq_i)) begin
IoExpAddr_qb3 <= #1 IoExpAddr_ib3;
IoExpRegAddr_qb2 <= #1 IoExpRegAddr_ib2;
IoExpData_qb8 <= #1 IoExpData_ib8;
end
always @(posedge Clk_ik)
if (~Busy_o && (I2cMuxIntRdReq_i || I2cMuxEnChReq_i)) begin
I2cMuxAddress_q <= #1 I2cMuxAddress_i;
I2cMuxChannel_qb2 <= #1 I2cMuxChannel_ib2;
end
// Writing a value in a register of one IO expander
always @(posedge Clk_ik) case(CommandPointer_b4)
4'd0: IoExpWriteSeq_b11 <= #1 {c_SendStartBit, 8'h0};
4'd1: IoExpWriteSeq_b11 <= #1 {c_SendByte, 4'b0100, IoExpAddr_qb3, 1'b0}; //Comment: Selection of the Slave in write mode
4'd2: IoExpWriteSeq_b11 <= #1 {c_SendByte, 6'b0, IoExpRegAddr_qb2}; //Comment: Writing the Register address
4'd3: IoExpWriteSeq_b11 <= #1 {c_SendByte, IoExpData_qb8}; //Comment: Writing the Register Value
4'd4: IoExpWriteSeq_b11 <= #1 {c_SendStopBit, 8'h0};
default: IoExpWriteSeq_b11 <= #1 {c_GoToIdle, 8'h0};
// Reading a value from a register of one IO expander
always @(posedge Clk_ik) case(CommandPointer_b4)
4'd0: IoExpReadSeq_b11 <= #1 {c_SendStartBit, 8'h0};
4'd1: IoExpReadSeq_b11 <= #1 {c_SendByte, 4'b0100, IoExpAddr_qb3, 1'b0}; //Comment: Selection of the Slave in write mode
4'd2: IoExpReadSeq_b11 <= #1 {c_SendByte, 6'b0, IoExpRegAddr_qb2}; //Comment: Writing the Register address
4'd3: IoExpReadSeq_b11 <= #1 {c_SendStartBit, 8'h0}; //Comment: Repeated start (new cycle)
4'd4: IoExpReadSeq_b11 <= #1 {c_SendByte, 4'b0100, IoExpAddr_qb3, 1'b1}; //Comment: Selection of the Slave in read mode
4'd5: IoExpReadSeq_b11 <= #1 {c_GetByte, 8h1}; //Comment: Read of the last Byte (single read)
4'd6: IoExpReadSeq_b11 <= #1 {c_SendStopBit, 8'h0};
default: IoExpReadSeq_b11 <= #1 {c_GoToIdle, 8'h0};
// Reading the value of the interrupt and configuration status of one I2C mux
always @(posedge Clk_ik) case(CommandPointer_b4)
4'd0: I2cMuxReadSeq_b11 = {c_SendStartBit, 8'h0};
4'd1: I2cMuxReadSeq_b11 = {c_SendByte, 6'h38, I2cMuxAddress_q, 1'b1}; //Comment: Selection of the Slave in read mode
4'd2: I2cMuxReadSeq_b11 = {c_GetByte, 8h1}; //Comment: Read of the last Byte (single read)
4'd3: I2cMuxReadSeq_b11 = {c_SendStopBit, 8'h0};
default: I2cMuxReadSeq_b11 = {c_GoToIdle, 8'h0};
// Enabling one channel of a I2C mux (and disabling all the others)
always @(posedge Clk_ik) case(CommandPointer_b4)
4'd0: I2cMuxEnChSeq_b11 = {c_SendStartBit, 8'h0};
4'd1: I2cMuxEnChSeq_b11 = {c_SendByte, 6'h38, ~I2cMuxAddress_q, 1'b0}; //Comment: Selection of the other Slave in Write mode
4'd2: I2cMuxEnChSeq_b11 = {c_SendByte, 5'b0, 3'b0}; //Comment: Disabling all channels
4'd3: I2cMuxEnChSeq_b11 = {c_SendStopBit, 8'h0};
4'd4: I2cMuxEnChSeq_b11 = {c_SendStartBit, 8'h0};
4'd5: I2cMuxEnChSeq_b11 = {c_SendByte, 6'h38, I2cMuxAddress_q, 1'b0}; //Comment: Selection of the other Slave in Write mode
4'd6: I2cMuxEnChSeq_b11 = {c_SendByte, 5'b0, 1'b1, I2cMuxChannel_qb2}; //Comment: Enabling the desired channel
4'd7: I2cMuxEnChSeq_b11 = {c_SendStopBit, 8'h0};
default: I2cMuxEnChSeq_b11 = {c_GoToIdle, 8'h0};
// User custom sequence (always to be closed by a back to idle command!)
generic_fifo_dc_gray #(.dw(11), .aw(4))
i_CommandFifo (
.rd_clk(Clk_ik),
.wr_clk(Clk_ik),
.rst(1'b1),
.clr(Rst_irq),
.din(FifoCommand_ib11),
.we(FifoCommandWr_i),
.dout(FifoDout_b11),
.re(FifoRead),
.full(FifoFull_o),
.empty(FifoEmpty_o));
//==== State Machine ====\\
always @(posedge Clk_ik) State_qb4 <= #1 Rst_irq ? s_Idle : NextState_ab4;
always @* begin
NextState_ab4 = State_qb4;
case(State_qb4)
// Waiting for a request
s_Idle: if (AnyRequest_a) NextState_ab4 = s_FetchCommand;
// Fetching and decoding the command
s_FetchCommand: if (~FifoEmpty_o || ActiveSequence_b3!=c_FifoSeq) NextState_ab4 = s_StartExecution;
s_StartExecution: if (Command_b3 == c_SendStartBit) NextState_ab4 = s_StartSda1;
else if (Command_b3 == c_SendByte) NextState_ab4 = s_SendScl0;
else if (Command_b3 == c_GetByte) NextState_ab4 = s_GetScl0;
else if (Command_b3 == c_SendStopBit) NextState_ab4 = s_StopSda0,
else if (Command_b3 == c_GoToIdle) NextState_ab4 = s_Idle;
// Start bit sequence
s_StartSda1: if (SclCounter_c10==g_SclHalfPeriod) NextState_ab4 = s_StartScl1;
s_StartScl1: if (SclCounter_c10==g_SclHalfPeriod) NextState_ab4 = s_StartSda0;
s_StartSda0: if (SclCounter_c10==g_SclHalfPeriod) NextState_ab4 = s_StartScl0;
s_StartScl0: if (SclCounter_c10==g_SclHalfPeriod) NextState_ab4 = s_FetchCommand;
// Byte sending sequence
s_SendScl0: if (SclCounter_c10==g_SclHalfPeriod) NextState_ab4 = (BitCounter_c4==4'd9) ? s_FetchCommand : s_SendScl1;
s_SendScl1: if (SclCounter_c10==g_SclHalfPeriod) NextState_ab4 = s_SendScl0;
// Byte getting sequence
s_GetScl0 : if (SclCounter_c10==g_SclHalfPeriod) NextState_ab4 = (BitCounter_c4==4'd9) ? s_FetchCommand : s_GetScl1;
s_GetScl1 : if (SclCounter_c10==g_SclHalfPeriod) NextState_ab4 = s_GetScl0;
// Stop bit sequence
s_StopSda0: if (SclCounter_c10==g_SclHalfPeriod) NextState_ab4 = s_StopScl1;
s_StopScl1: if (SclCounter_c10==g_SclHalfPeriod) NextState_ab4 = s_StopSda1;
s_StopSda1: if (SclCounter_c10==g_SclHalfPeriod) NextState_ab4 = s_FetchCommand;
// Protection from bad state condition
default: NextState_ab4 = s_Idle;
endcase
end
always @(posedge Clk_ik) begin
// Default assignments
Busy_o <= #1 NextState_ab4 != s_Idle;
IoExpWrOn_oq <= #1 Busy_o && ActiveSequence_b3 == c_IoExpWriteSeq;
IoExpRdOn_oq <= #1 Busy_o && ActiveSequence_b3 == c_IoExpReadSeq;
I2cEnChOn_oq <= #1 Busy_o && ActiveSequence_b3 == c_I2cMuxIntReadSeq;
I2cMuxRdIntOn_oq <= #1 Busy_o && ActiveSequence_b3 == c_I2cMuxEnChSeq;
FifoAccessOn_oq <= #1 Busy_o && ActiveSequence_b3 == c_FifoSeq;
SclOe_e <= #1 1'b0;
SdaOe_e <= #1 1'b0;
I2cMuxWriteDone_op <= #1 1'b0;
I2cMuxReadDone_op <= #1 1'b0;
IoExpWriteDone_op <= #1 1'b0;
IoExpReadDone_op <= #1 1'b0;
FifoWriteDone_op <= #1 1'b0;
FifoReadDone_op <= #1 1'b0;
FifoRead <= #1 1'b0;
NewByteRead_op <= #1 1'b0;
AckError_op <= #1 1'b0;
// Reset conditions (if different from default)
if (Rst_irq) begin
BitCounter_c4 <= #1 4'b0;
SclCounter_c10 <= #1 10'b0;
I2CAck <= #1 1'b0;
ShReg_b8 <= #1 8'b0;
Command_b3 <= #1 3'b0;
I2cMuxWriteAck_o <= #1 1'b0;
I2cMuxByteRead_ob8 <= #1 8'b0;
IoExpWriteAck_o <= #1 1'b0;
IoExpByteRead_ob8 <= #1 8'b0;
FifoWriteAck_o <= #1 1'b0;
FifoByteRead_ob8 <= #1 8'b0;
Busy_o <= #1 1'b1;
CommandPointer_b4 <= #1 4'h0;
ActiveSequence_b3 <= #1 3'b0;
IoExpWrOn_oq <= #1 1'b0;
IoExpRdOn_oq <= #1 1'b0;
I2cEnChOn_oq <= #1 1'b0;
I2cMuxRdIntOn_oq <= #1 1'b0;
FifoAccessOn_oq <= #1 1'b0;
ByteOut_ob8 <= #1 8'b0;
end else case(State_qb4)
// Waiting for a request
s_Idle : begin
CommandPointer_b4 <= #1 4'h0;
if (IoExpWrReq_i) ActiveSequence_b3 <= #1 c_IoExpWriteSeq;
else if (IoExpRdReq_i) ActiveSequence_b3 <= #1 c_IoExpReadSeq;
else if (I2cMuxIntRdReq_i) ActiveSequence_b3 <= #1 c_I2cMuxIntReadSeq;
else if (I2cMuxEnChReq_i) ActiveSequence_b3 <= #1 c_I2cMuxEnChSeq;
else if (FifoAccessReq_i) ActiveSequence_b3 <= #1 c_FifoSeq;
end
// Fetching and decoding the command
s_FetchCommand: begin
NewByteRead_op <= #1 Command_b3 == c_GetByte;
ByteOut_ob8 <= #1 ShReg_b8;
AckError_op <= #1 Command_b3 == c_SendByte && I2CAck;
CommandPointer_b4 <= #1 CommandPointer_b4 + 1'b1;
FifoRead <= #1 ~FifoEmpty_o && ActiveSequence_b3==c_FifoSeq;
case (ActiveSequence_b3)
c_IoExpWriteSeq: {Command_b3, ShReg_b8} <= #1 IoExpWriteSeq_b11;
c_IoExpReadSeq: {Command_b3, ShReg_b8} <= #1 IoExpReadSeq_b11;
c_I2cMuxIntReadSeq: {Command_b3, ShReg_b8} <= #1 I2cMuxReadSeq_b11;
c_I2cMuxEnChSeq: {Command_b3, ShReg_b8} <= #1 I2cMuxEnChSeq_b11;
c_FifoSeq: {Command_b3, ShReg_b8} <= #1 FifoDout_b11;
default: {Command_b3, ShReg_b8} <= #1 {c_GoToIdle, 8'h0};
endcase
end
s_StartExecution : begin
BitCounter_c4 <= #1 4'h0;
SclCounter_c10 <= #1 10'h0;
if (NextState_ab4==s_GetScl0) I2CAck <= #1 ShReg_b8[0];
end
// Start bit sequence
s_StartSda1 : begin
SdaOe_e <= #1 1'b0;
if (NextState_ab4 != State_qb4) SclCounter_c10 <= #1 'h0;
else if (Sda_ioz) SclCounter_c10 <= #1 SclCounter_c10 + 1'b1;
else SclCounter_c10 <= #1 'h0;
end
s_StartScl1 : begin
SclOe_e <= #1 1'b0;
if (NextState_ab4 != State_qb4) SclCounter_c10 <= #1 'h0;
else if (Scl_ioz) SclCounter_c10 <= #1 SclCounter_c10 + 1'b1;
else SclCounter_c10 <= #1 'h0;
end
s_StartSda0 : begin
SdaOe_e <= #1 1'b1;
if (NextState_ab4 != State_qb4) SclCounter_c10 <= #1 'h0;
else if (!Sda_ioz) SclCounter_c10 <= #1 SclCounter_c10 + 1'b1;
else SclCounter_c10 <= #1 'h0;
end
s_StartScl0 : begin
SclOe_e <= #1 1'b1;
if (NextState_ab4 != State_qb4) SclCounter_c10 <= #1 'h0;
else if (!Scl_ioz) SclCounter_c10 <= #1 SclCounter_c10 + 1'b1;
else SclCounter_c10 <= #1 'h0;
end
// Byte sending sequence
s_SendScl0 : begin
SclOe_e <= #1 1'b1;
if (NextState_ab4 != State_qb4) SclCounter_c10 <= #1 'h0;
else if (!Scl_ioz) SclCounter_c10 <= #1 SclCounter_c10 + 1'b1;
else SclCounter_c10 <= #1 'h0;
if (SclCounter_c10[8:0]==g_SclHalfPeriod[9:1]) SdaOe_e <= #1 BitCounter_c4[3] ? 1'b0 : !ShReg_b8[7];
end
s_SendScl1 : begin
SclOe_e <= #1 1'b0;
if (NextState_ab4 != State_qb4) begin
BitCounter_c4 <= #1 BitCounter_c4 + 1'b1;
SclCounter_c10 <= #1 'h0;
ShReg_b8[7:1] <= #1 ShReg_b8[6:0];
I2CAck <= #1 Sda_ioz;
end else if (Scl_ioz) SclCounter_c10 <= #1 SclCounter_c10 + 1'b1;
else SclCounter_c10 <= #1 'h0;
end
// Byte getting sequence
s_GetScl0 : begin
SclOe_e <= #1 1'b1;
SdaOe_e <= #1 (BitCounter_c4==4'd8) ? !I2CAck : 1'b0;
if (NextState_ab4 != State_qb4) SclCounter_c10 <= #1 'h0;
else if (!Scl_ioz) SclCounter_c10 <= #1 SclCounter_c10 + 1'b1;
else SclCounter_c10 <= #1 'h0;
end
s_GetScl1 : begin
SclOe_e <= #1 1'b0;
if (NextState_ab4 != State_qb4) begin
BitCounter_c4 <= #1 BitCounter_c4 + 1'b1;
SclCounter_c10 <= #1 'h0;
ShReg_b8 <= #1 (BitCounter_c4==4'd8) ? ShReg_b8 : {ShReg_b8[6:0], Sda_ioz};
end else if (Scl_ioz) SclCounter_c10 <= #1 SclCounter_c10 + 1'b1;
else SclCounter_c10 <= #1 'h0;
end
// Stop bit sequence
s_StopSda0 : begin
SdaOe_e <= #1 1'b1;
if (NextState_ab4 != State_qb4) SclCounter_c10 <= #1 'h0;
else if (!Sda_ioz) SclCounter_c10 <= #1 SclCounter_c10 + 1'b1;
else SclCounter_c10 <= #1 'h0;
end
s_StopScl1 : begin
SclOe_e <= #1 1'b0;
if (NextState_ab4 != State_qb4) SclCounter_c10 <= #1 'h0;
else if (Scl_ioz) SclCounter_c10 <= #1 SclCounter_c10 + 1'b1;
else SclCounter_c10 <= #1 'h0;
end
s_StopSda1 : begin
SdaOe_e <= #1 1'b0;
if (NextState_ab4 != State_qb4) SclCounter_c10 <= #1 'h0;
else if (Sda_ioz) SclCounter_c10 <= #1 SclCounter_c10 + 1'b1;
else SclCounter_c10 <= #1 'h0;
end
// Protection from bad state condition
default: begin
SclOe_e <= #1 1'b0;
SdaOe_e <= #1 1'b0;
BitCounter_c4 <= #1 'h0;
SclCounter_c10 <= #1 'h0;
I2CAck <= #1 CommandReg_qb32[0];
ShReg_b8 <= #1 CommandReg_qb32[7:0];
end
endcase
end
assign Scl_ioz = SclOe_e ? 1'b0 : 1'bz;
assign Sda_ioz = SdaOe_e ? 1'b0 : 1'bz;
endmodule
\ No newline at end of file
`timescale 1ns/1ns
module pca9534 (
input [3:0] A_ib3,
inout [7:0] IO_iob8,
output Int_on,
inout Scl_io,
inout Sda_io
);
localparam c_MinPerDown = 2500;
wire SlaveAddress_b7 = {4'b0100, a_ib3};
reg [7:0] OutputPortRegister_b8 = 8'hFF;
reg [7:0] PolarityInversionRegister_b8 = 8'h00;
reg [7:0] ConfigurationRegister_b8 = 8'hFF;
integer ShCount = 0;
reg [3:0] State=1;
reg [7:0] Mem_m [255:0];
reg [7:0] ByteAddr_b8;
reg RdWrBit;
reg Scl_q = 1'bz, Sda_q = 1'bz;
integer i;
reg [7:0] ShReg;
assign Scl_io = Scl_q;
assign Sda_io = Sda_q;
localparam s_Idle = 1,
s_Addressing = 2,
s_WrRdSel = 3,
s_AckAddress = 4,
s_ByteAddr = 5,
s_AckByteAddr = 6,
s_GetByte = 7,
s_SendAckData = 8,
s_SendByte = 9,
s_GetAckByte = 10;
always@(negedge Sda_io)
if (Scl_io) begin
State = s_Addressing; //Start Bit
ShCount = 'h0;
end
always@(posedge Sda_io)
if (Scl_io) begin
State = s_Idle; //Stop Bit
end
always@(posedge Scl_io) case (State)
s_Addressing: begin
ShReg = {ShReg[6:0], Sda_io};
ShCount = ShCount + 1;
if (ShCount == 7) begin
State = (ShReg[6:0]==SlaveAddress_b7) ? s_WrRdSel : s_Idle;
end
end
s_WrRdSel: begin
RdWrBit = Sda_io;
State = s_AckAddress;
end
s_AckAddress: begin
ShCount = 0;
if (RdWrBit) begin
State = s_SendByte;
if (ByteAddr_b8 == 8'h00) ShReg = IO_iob8^PolarityInversionRegister_b8;
if (ByteAddr_b8 == 8'h01) ShReg = OutputPortRegister_b8;
if (ByteAddr_b8 == 8'h02) ShReg = PolarityInversionRegister_b8;
if (ByteAddr_b8 == 8'h03) ShReg = ConfigurationRegister_b8;
end else begin
State = s_ByteAddr;
end
end
s_ByteAddr: begin
ByteAddr_b8 = {ByteAddr_b8[6:0], Sda_io};
ShCount = ShCount + 1;
if (ShCount == 8) State = s_AckByteAddr;
end
s_AckByteAddr: begin
State = s_GetByte;
ShCount = 0;
end
s_GetByte: begin
ShReg = {ShReg[6:0], Sda_io};
ShCount = ShCount + 1;
if (ShCount == 8) begin
State = s_SendAckData;
if (ByteAddr_b8 == 8'h01) OutputPortRegister_b8 = ShReg;
if (ByteAddr_b8 == 8'h02) PolarityInversionRegister_b8 = ShReg;
if (ByteAddr_b8 == 8'h03) ConfigurationRegister_b8 = ShReg;
end
end
s_SendAckData:begin
ShCount = 0;
State = s_GetByte;
end
s_SendByte: begin
ShReg = {ShReg[6:0], 1'b0};
ShCount = ShCount + 1;
if (ShCount == 8) begin
State = s_GetAckByte;
if (ByteAddr_b8 != 8'h00) ByteAddr_b8 = ByteAddr_b8 + 1; //The increment isn't quite clear from the datasheet
else ShReg = IO_iob8^PolarityInversionRegister_b8; //New sampling
if (ByteAddr_b8 == 8'h01) ShReg = OutputPortRegister_b8;
if (ByteAddr_b8 == 8'h02) ShReg = PolarityInversionRegister_b8;
if (ByteAddr_b8 == 8'h03) ShReg = ConfigurationRegister_b8;
end
end
s_GetAckByte: begin
ShCount = 0;
State = Sda_io ? s_Idle : s_SendByte;
end
endcase
always@(negedge Scl_io) begin
Scl_q = 1'b0;
#c_MinPerDown;
case (State)
s_Addressing: begin
Sda_q = 1'bz;
#100;
Scl_q = 1'bz;
end
s_WrRdSel: begin
Sda_q = 1'bz;
#100;
Scl_q = 1'bz;
end
s_AckAddress: begin
Sda_q = 1'b0;
#100;
Scl_q = 1'bz;
end
s_ByteAddr: begin
Sda_q = 1'bz;
#100;
Scl_q = 1'bz;
end
s_AckByteAddr: begin
Sda_q = 1'b0;
#100;
Scl_q = 1'bz;
end
s_GetByte: begin
Sda_q = 1'bz;
#100;
Scl_q = 1'bz;
end
s_SendAckData:begin
Sda_q = 1'b0;
#100;
Scl_q = 1'bz;
end
s_SendByte: begin
Sda_q = ShReg[7] ? 1'bz : 1'b0;
#100;
Scl_q = 1'bz;
end
s_GetAckByte: begin
Sda_q = 1'bz;
#100;
Scl_q = 1'bz;
end
default: begin
Sda_q = 1'bz;
#100;
Scl_q = 1'bz;
end
endcase
end
assign IO_iob8[0] = ConfigurationRegister_b8[0] ? 1'bz : OutputPortRegister_b8[0];
assign IO_iob8[1] = ConfigurationRegister_b8[1] ? 1'bz : OutputPortRegister_b8[1];
assign IO_iob8[2] = ConfigurationRegister_b8[2] ? 1'bz : OutputPortRegister_b8[2];
assign IO_iob8[3] = ConfigurationRegister_b8[3] ? 1'bz : OutputPortRegister_b8[3];
assign IO_iob8[4] = ConfigurationRegister_b8[4] ? 1'bz : OutputPortRegister_b8[4];
assign IO_iob8[5] = ConfigurationRegister_b8[5] ? 1'bz : OutputPortRegister_b8[5];
assign IO_iob8[6] = ConfigurationRegister_b8[6] ? 1'bz : OutputPortRegister_b8[6];
assign IO_iob8[7] = ConfigurationRegister_b8[7] ? 1'bz : OutputPortRegister_b8[7];
endmodule