Verilog Code for I2C with RTL Schematic

Hi Guys,

Long time now. I was away dealing with my crappy life. Well, let's move to the main point as the title of this post suggests. This I2C is very much less complicated than all my previous I2C Verilog codes. The biggest surprise to my readers in this post is that this I2C has an RTL Schematic. I'll clear out everything about the code.

Let us begin.

I'll begin with the explanation of Master code first. I am assuming here that the readers have already read the I2C Basic post. If not then search this blog else move ahead.

In this I2C, I am assuming a few things.
1. It is a READ mode I2C only. No, Write mode. That would complicate a hell lot of stuff.
2. There is no malfunctioning with Master when it receives data from Slave, hence the acknowledge bit will be always 1(Not for Address matching).

What is in this I2C Code:
In this code, the master will send start bit and SCL will start. With this Master will start sending 7 bit Slave address. If the address does not match, it will restart i.e. keep on sending the same address. If the address matches, the Slave will send the acknowledgment. With acknowledgment, the Master will send the 8-bit register address.

Note: The code currently has no code to execute if register address matching fails. Might be updated later

After matching the register address, the Slave will send acknowledgment bit. After that, it will send the data associated with that register address. This will end with Stop bit.

Note: I still have some doubt on Start Bit and Stop bit.

To get the Master Code:
1. Disable Popups
2. Click Here to get the Master code
3. Click Here to get the Slave code

Master Code Description:

Line 1-4: I assume one knows what is this!!
Line 6: Register address from where data has to retrieve.
Line 7: SCL flag decides whether it is 1 or 0
Line 8: Slave_address of 7 bit. It contains the address of the Slave to be communicated.
Line 9: Start_Flag decides the start condition of I2C
Line 10: Status to signal the stop condition

Line 12: sda_val Value assigned to this will be sent through SDA line
Line 11: Direction chooses whether the signal is from or to.
Line 13:
Line 14: Contains slave address along with Read bit (hardcoded to 1)
Line 15: Count To count the clock
Line 16: Keep a Backup Copy of Slave Address
Line 17: Stores the Acknowledgement Bit
Line 18: Stores the data from Slave
Line 19: Used for START signaling
Line 20: Used for START signaling

Line 39-42: With falling SDA line checks if SCL is 1, then set A to 1
Line 46-50: If SDA is rising and SCL is 1 then set B to 1
Line 52: Set Start flag to ex-or of A and B
Line 54-58: With the rising clock, if start flag is 1, complement SCL(SCL clocking begins) else set SCL to1

Line 62-92: Check if SCL is 0 as SDA will only change when SCL is not changing. Then we will have to check the start flag. If it is set to 1, the transmission will begin. With first 8 counts, 7bit address and 1-bit read bit will be sent to Slave. SDA is of inout type which is a wire. This can only be used as a tri buffer. With count as 9, the direction will be set to 0 which sets the SDA line to 1'bZ. This will accept data from Slave now about the acknowledgment. For count as 10, we will set direction to 1
which means, Master will send data. The acknowledgment will be stored. If it is 1, which means the address is correct, we will send the register address from where we want data. If acknowledgment bit is 0, set count to 1 and retransmit the Slave address. This will keep on happening. When the count is 18, the direction is again changed to get the acknowledgment of register address. If 1, then proceed else NOTHING WILL HAPPEN as I HAVE NOT YET PUT A CODE WHICH WILL EXECUTE WHEN REGISTER ADDRESS FAILS.

Line 93-97: This will store the incoming data from Slave
Line 98-101: Acknowledgment informing the Slave about a successful transaction.
Line 102-105: Set SDA to 0 and status to 1
Line 108-110: If Status is 1, set SDA to 1.

Since SDA will always change when SCL is 0, Line 46-49 will never come true. However, we are deliberating setting SDA to 1 when SCL is 1 in Line 108-109. This will cause the code 46-49 to execute, which in turn set B to 1. Now with B set to 1, the start flag will be set to 0 in line 52. As the start flag is set to 0, Line 58 will execute which will set SCL permanently to 1. Thus I2C Connection closed.

RTL Schematic for RTL Lovers

For newbies, this is the hierarchy

Test.v is of Text Fixture type.
Master.v is Verilog File
Slave.v is Verilog File

Output (Slave Address Matched):

Output (Slave Address Mis-Matched):

Comment !!


  1. Working Thanks
    Are you gonna update it for register mismatch as I tried to code with different register address and got impedance lines

  2. Why would including the 'Write' mode involve hell lot of complications ?
    Ultimately the aim is to have an fully functioning i2c RTL right.

    1. Its because many "Internet Guys" haven't yet formulated the read mode yet. One should learn the art to tweak someone's code to create something even better. I love sharing my projects and not someone's homework. Well even the write mode is ready in my arsenal but I am still receiving messages from guys who still aren't able to understand read mode. Learning takes time. Some people learn fast while others learn slow.
      As for conplications, it isn't for me at all, but it will be overwhelming for others. Its just step by step.

  3. This comment has been removed by the author.