If you experience strange behaviors in this core (like reads turning into writes or different I2C regs being read/writen or so) take a logic analyzer and check the I2C lines to look for strange SCLK patterns (varying duty cycles, incomplete I2C operations,...).
This is what happened to me in a single master/slave I2C bus. After thoroughly studying the I2C controller core's code I've found the problem in the triggering of the arbitration lost signal in the bit controller (amazing because there is only one master!). This is due to a stop condition being detected at random places. To avoid this, I changed line 315 of the i2c_master_bit_ctrl.vhd from: ial <= (sda_chk and not sSDA and isda_oen) or (sto_condition and not cmd_stop); to: ial <= (sda_chk and not sSDA and isda_oen); Strangely enough, in the comments over this process it says: "-- 2) stop detected while not requested (detect during 'idle' state)" but this stop is being detected in all the states but the stop one, not only during the idle one. Anyways, as far as I know about the I2C bus, it is enough with checking this condition: "1) master drives SDA high, but the i2c bus is low" to trigger an arbitration lost.
This way everything runs perfect. My findings lead me to believe that the problem is in the sto_condition signal generation in the same file by line 269: sto_condition <= (sSDA and not dSDA) and sSCL; The problem is that this is checked every clock cycle, that is if your system runs at 50 MHz, the I2C lines which should run at around 400 KHz will be treated like a fast line, and the slow transitions in these lines (slow slew rate) may create a false stop condition that would trigger an arbitration lost.
My recommendation: put slew rate fast in the I2C lines and change line 315 as said above.
This core is good and well documented, the code is clean and easy to read. I will continue to use it as, after making this changes, everything goes fine now.
It might also be worthwhile adding some simple digital pulse suppression to the I2C clock and data lines to increase robustness (as recommended by the NXP I2C specification).
You want like a median filter (3 or 5 stages) running at say 16x the i2c clock frequency?
I implemented a 3stage median filter running at 4x the bit-control clock. That should catch any major glitches.
Richard