I2C slave

Discussion in 'VHDL' started by Frank Buss, Oct 16, 2006.

  1. Frank Buss

    Frank Buss Guest

    I've written a I2C slave core:


    It should work with 100 kB and 400 kB master devices and it supports
    sending and receiving multiple bytes and the repeated start condition.
    Stretching clock cycles is not supported, the host which uses the core must
    be fast enough.

    Currently I've tested it in a simulator, only, maybe someone could test it
    on real hardware, e.g. with the included testdevice and a hardware master,
    like built-in in some microcontrollers.

    I'm not sure about the communication concept: Currently it doesn't use
    handshaking, but the slave entity signals, that a byte was received and
    some cycles later releases this signal. I think it is easier to use, but
    maybe a more standard interface like Wishbone would be better?

    The licence is BSD and if you have bugfixes or other improvments, I'll add
    it and publish it again. When it is mature, I'll plan to submit it to
    Frank Buss, Oct 16, 2006
    1. Advertisements

  2. Frank Buss

    PeteS Guest

    Hi Frank

    I'll drop it in and test it on real hardware in a couple of weeks (when
    I get the latest and greatest back from fab and stuffing).

    One thing I did note: the SDA output should be either Hi Z or 0 - it
    should never be driven high. The standard actually specifies open
    collector, but Hi Z for high works the same way :)


    PeteS, Oct 16, 2006
    1. Advertisements

  3. Frank Buss

    Frank Buss Guest

    I don't see a problem. In the ports section I've defined this:

    sda_io: inout std_logic;

    And then in the architecture this:

    signal sda_o: std_logic := '1';
    signal sda_i: std_logic := '0';




    sda_io <= sda_o when sda_o = '0' else 'Z';
    sda_i <= '1' when sda_io /= '0' else '0';
    read_mode_o <= read_mode;

    At least this worked for my 1-wire implementation with Xilinx (
    http://www.frank-buss.de/vhdl/spartan3e.html ), which I've tested with real
    hardware, so I assume the synthesis tool infers something compatible with
    open collector for it, but I'm a VHDL beginner, so maybe there is a better

    BTW: is there any drawback to define "scl_i: in std_logic"? It's a I2C
    slave, only and I don't support clock stretching, so I hope it is ok to
    define it just as input.
    Frank Buss, Oct 16, 2006
  4. Frank Buss

    PeteS Guest

    Hi Frank
    My oops :)

    I was looking at the logical assignemtns, not the IO assignment at the

    As to SCL - it should be just an input as you don't support clock
    stretch, and that looks fine to me. Note I am more comfortable in 'that
    other HDL language' but as far as I can see this unit looks good.

    I'll drop it into my design and testbench tonight and see what happens!


    PeteS, Oct 16, 2006
  5. Frank Buss

    PeteS Guest

    I dropped this into a design I am doing (only at simulation stage as of
    yet) and all seems to operate properly.

    The one thing I notice is when I push the speed I get invalid data (but
    that's at a few 10s of Mb/s, which is _way_ beyond the spec). Might be
    useful to set a constraint or two to see if I can get more speed out of
    it. Of course, there's a lot of other stuff in the device I am
    simulating, so that's a pretty common issue.

    I will note that I usually push such things (I2C, SMBus, SPI etc) to at
    least 20x normal speed in simulation to account for PCB capacitance. If
    it still operates Post PAR at that, I know it'll operate properly at
    'normal' rates.

    If you don't mind, I might add some conditionals for SMBus (which has
    timeouts that can be useful in hotswap). I2C can lock up in such
    situations where SMBus can recover.




    PeteS, Oct 16, 2006
  6. Frank Buss

    Frank Buss Guest

    I think you'll get many problems with I2C at this speed, because you need
    very low resistors to load the parasitic capacitance in the open collector
    cicuit, but the I2C spec defines a special HS-mode up to 3.4 Mbit/s and
    gives some advice how to design the circuit for it. But there might be
    still problems if there are not enough FPGA clock cycles per I2C clock
    cycles (e.g. you have to delete the data hold counter section, which is
    needed for low speed, improve the bit and logic level handshaking speed
    I've read the SMBus specification and looks like it has some advantages,
    e.g. lowest speed is 10 kHz, which allows fast timeouts, so you can add it.

    But I don't think that it is absolute necessary to avoid lock ups, because
    for the slave a start or a stop signal resets the transfer state,
    regardless in which state it is. And for the master the I2C specification
    says, that if it doesn't receive an ACK, it should send a repeated start or
    a stop signal.
    Frank Buss, Oct 16, 2006
  7. Frank Buss

    PeteS Guest

    The issue is that I2C will send the repeated start / stop but never
    return to the idle state without a valid transition. SMBus incorporates
    a timeout to alleviate this issue. I've had to deal with this on real
    boards, so I know it's a real problem.

    I'll do that stuff tomorrow :)


    PeteS, Oct 16, 2006
  8. Frank Buss

    Frank Buss Guest

    Today I tested it with real hardware and the I2C address was detected with
    a reliability of about 20% only. And I discussed the code with a workmate
    and he excoriate the code, expecially the very long and complicated state
    machines. But don't worry, currently I'm rewriting it with many more simple
    processes instead of two big ones and the address detection works already
    with about 100% reliability :)
    Frank Buss, Oct 18, 2006
  9. Frank Buss

    ALuPin Guest

    Hi Frank,

    I am trying to simulate it with ModelsimDesigner.

    Where do I get the UNISIM library from ?

    ALuPin, Oct 19, 2006
  10. Frank Buss

    Frank Buss Guest

    You don't need it, this was a copy-and-paste error from another project.

    I've updated the project and I think the code is better now. A non-I2C
    conforming (but useful in real systems) timeout is included, to avoid
    lowering SDA too long. To filter out spikes (the I2C specification says 50
    ns has to be filtered) a 4 bit shift register accumulates SCL and SDA and
    rising and falling edges are detected only, if the shift register contains
    "1100" or "0011". I2C master writing to the slave worked on my new T-Rex.

    For testing writing, reading and combinations with repeated start, I've
    implemented a PCA9555 GPIO in VHDL and enhanced the testbench, which
    worked. Tomorrow I can test it with a hardware master, which already
    communicates with a PCA9555 chip.

    The new version:

    Frank Buss, Oct 20, 2006
  11. Frank Buss

    Frank Buss Guest

    There were still some bugs, which I didn't detect with the testbench, but
    now it works with real hardware: I've tested it in fast mode with a master
    of an ARM PXA and in standard mode with a master of a HCS08. The HCS08 test
    program is included, I've organized the directory structure to the
    recommendations of OpenCores, added some documentation with logic analyzer
    samples and commented the VHDL code a bit better. The new version:

    Frank Buss, Oct 21, 2006
  12. Frank Buss

    Frank Buss Guest

    A new version:


    While integrating it in a production system, I found a bug when the slave
    was sending multiple bytes: only the first data request was signaled by the
    i2c_slave core. After fixing it, sending and receiving 128 bytes in an
    endless loop, together with other devices on the same bus, works without

    And I've added and tested a Spartan 3 Start Kit project for the PCA9555
    test implementation.

    Today my OpenCores account was approved, the next release will be at
    Frank Buss, Oct 28, 2006
  13. Frank Buss


    Aug 14, 2007
    Likes Received:
    I2C slave - PCA9555 VHDL code.

    Dear Frank,

    could you please send me the PCA9555 final code?
    i can not find it.

    erezc, Aug 14, 2007
  14. Frank Buss


    Aug 14, 2007
    Likes Received:
    Minimal core frequency for PCA955 VHDL.

    Hi all,

    could you please advise the minimal Core frequency i can use in the PCA9555 VHDL code?
    erezc, Mar 26, 2008
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.