# Unknown problem with I2C on Spartan 3-E {VERILOG}

I have a Spartan 3-E board.I was using the inbuilt Xilinx SRL 16 (16 bit concatenated shift registers) for I2C communication.I verified successful implementation by displaying the number of "Acks" received on LEDs i.e (I had an internal counter which would increment if SDA was pulled low during the 9th clock cycle).My problem starts when instead of using the Xilinx SRL primitive, I built my custom 8bit Left Shift Register.I had to do this because the system has to be kept idle for some time and only a few specific registers need to be programmed so I can't rely on the auto increment feature.Any way, I haven't been able to verify I2C comm. as before, despite keeping all other aspects the same and ensuring absolutely zero difference between simulation patterns of the earlier successful design and this new one. I am sharing my code and would be extremely grateful to anyone who could have a look.

------------------8-bit SRL----------------

module CustomSRL(
input [7 : 0] Value,
input LE,
input CE,
input clk_i2c,
output Q
);
reg [7 : 0] SRL_8;
always @ (posedge clk_i2c)
begin
if(CE) begin
if(LE) SRL_8 <= Value;
else   SRL_8 <= {SRL_8[6 : 0],1'b0};
end
end
assign Q = SRL_8[7];
endmodule


UPDATE :

I was just experimenting and realized that when I replace my custom Shift Register (provided above) with the SRL16 E primitive, the design works.This is very surprising.I tried to make small changes to the logic by using a simple register with a Load Enable and a multiplexer to single out the bits.However, that doesn't work either.

Why is it that the SRL16E primitive design works but not the others? I have provided code for my shift register (serial in,serial out, parallel synchronous load) module above.The simulation results are the same for all three designs.

Can anyone offer an explanation for this apparently bizarre behavior? Sending Values to 8 bit Shift Register :

always @ (*)
begin
case (Byte_Counter)
0 : LUT <= 8'h56;                                   //Device Addres
2 : LUT <= i2c_val;                             //Data
5 : LUT <= 8'h7E;                                   //STOP & START
default : LUT <= 8'hFF;
endcase
end

always @ (*)
begin
case (Reg_Counter)
1 :begin i2c_address <= 8'h00; i2c_val <= 8'h02;    end
2 :begin i2c_address <= 8'h03; i2c_val <= 8'h00;   end
3 :begin i2c_address <= 8'h05; i2c_val <= 8'h09;   end
4 :begin i2c_address <= 8'h07; i2c_val <= 8'h07;   end
5 :begin i2c_address <= 8'h09; i2c_val <= 8'h00;    end
default : begin i2c_address <=8'h00; i2c_val <= 8'h00;   end
endcase
end


Variable LUT is loaded into the 8 bit Shift Register on the 9th(when SDA=high impedance) clock cycle.

One thing that I'd like to add is that I tried to register the outputs of the multiplexers before packing it off to the 8-bit SRL by :

always @ (posedge clk_i2c) temp <= LUT;


However, that hasn't worked either, but I do get one interesting warning :

INFO:Xst:2260 - The FF/Latch <i2c_ADV7171/temp_6> in Unit <Verilog> is equivalent to the following FF/Latch : <i2c_ADV7171/temp_4>


As far as I can tell, this shouldn't happen because temp[6] and temp[4] aren't throughout equal.

• The picture added is of the STARTING CONDITION. I am using PULL UPS on both SCL and SDA. – Ahmed Ali Abbasi Mar 5 '17 at 15:51
• In the picture I think that I see SDA falling just before SCL turns low. The SDA must be valid as long as SCL is high. The SDA is allowed to change at the same moment the SCL turns low for I2C, but not for the SMBus. For the SMBus the SDA may only change after the SCL has turned low (that is safer). – Jot Mar 6 '17 at 23:15
• I have reconfirmed that the SDA line goes low before SDA for I2C communication.Plus, this exact waveform works when I use a Xilinx SRL16E primitive, instead of using the SRL I've coded above. Other then that, I 've also tried to use a simple 16 bit register and mux out the outputs, one by one, which hasn't worked either.Could you take a look at the SRL module in the code above? It simulates perfectly but doesn't work. – Ahmed Ali Abbasi Mar 7 '17 at 6:09