Showing posts with label I2C. Show all posts
Showing posts with label I2C. Show all posts

I2C Verilog Code Explanation II









In my previous post, I explained working of I2C Verilog code. Same is continued here.

else if(left_bits == 10)begin
  if(sda == 0)begin
   left_bits <= 1;
   direction <= 1;
   temp <= temp_reserved;
  end
  else begin
   direction <= 1;
   alpha <= 0;
   left_bits <= left_bits + 1;
  end
end


When the ACK/NACK is received at 9 then at 10 it is compared with 1 and 0. If the acknowledgment received is 0 then left_bits is reset to its initial value that is 1. The direction is again set to 1 to make the Master ready to send data to Slave. The register TEMP which is now XXXXXXX gets renewed or say reset with a copy that we stored earlier i.e. in TEMP_RESERVED. If the received acknowledgment is 1 then direction will be changed to 1 because now the Master will have to send the address of register which stores data in the Slave. Setting ALPHA = 0 is not necessary here though. LEFT_BITS is again incremented.

else if(left_bits >=11 && left_bits <=17)begin
  alpha <= register[6];
  register <= register<<1;
  left_bits <= left_bits + 1;
end


From 11 to 17 i.e. 7 counts the Master will send the address of the register of the Slave from where data has to be retrieved. The process is same as I explained earlier to send Slave address hence I am not gonna repeat the same.

else if (left_bits >= 18 && left_bits <= 28)begin
  direction <=0;
  left_bits <= left_bits + 1;
end


From 18 to 28 the slave will send an ACK bit to tell the master that if the register address is matched or not. This happens on 19th cycle. However, there is a clock cycle delay here in Slave at this position. The SDA line is continuous from Master to Slave. Since we cannot do any operation on wires, therefore, we have to store data from wire to a register in the Slave in order to use it. However, storing this data results in an extra clock cycle, since values get updated after the clock cycle and not along with clock cycle for a non-blocking assignment (<=). For blocking assignment (=) the task is done first having the blocking assignment and the rest of the tasks are completed. 

Example
initial begin
a = 0;
c = 0;
end
always @(posedge clk)begin
  a <= a + 1;
  a <= a + 2;
  c <= c + 1;
  a <= a + 3;
  c <= c + 2;
end

After executing the above command if you are thinking that the result will be a = 6 and c = 3, then you are wrong !!.
The right answer is a = 3 and c = 2;

However, if you code like this snippet below using blocking assignments
always @(posedge clk)begin
  a = a + 1;
  a = a + 2;
  c = c + 1;
  a = a + 3;
  c = c + 2;
end
 The output will be a = 6 and c = 2;

Whenever we use non-blocking assignments each line of code does not depend on the previous line. They will occur simultaneously with the past data. Data is changed after the clock cycle ends and not immediately. In case of blocking assignment, the first line will be given first priority. After it's execution, the second line is executed. Data is changed immediately. 
Thus 
a <= a + 1; mean a = 0 + 1 = 1
a <= a + 2 means a = 0 + 2 = 2 . It won't depend on the previous calculation. 
a <= a + 3 means a = 0 + 3 = 3   It won't depend on the previous calculation
At the end of clock cycle a = 3

However,
a = a + 1 means a = 0 + 1 = 1. This will be executed immediately.
a = a + 2 means a = 1 + 2 = 3 This will be executed after the previous execution
a = a + 3 means a = 3 + 3 = 6.

Non-blocking assignments are used only when sequential conditions are present i.e. flip-flops. Blocking assignments are used for combinational blocks. I hope it is clear the difference between blocking and non-blocking assignments. 

To manage this bit delay in slave I had to use a blocking assignment. The Slave sends the 8-bit data stored in its register to Master by setting direction = 0 on the SDA line. 

else if(left_bits == 29)begin
  direction <= 1;
  alpha <= 1;
  left_bits <= left_bits + 1;
end


For the 29th count, the Master will set the direction 1 and the Slave will set the direction as 0 as it is the turn of Master to send the acknowledgment bit now informing the Slave that it has received the 8-bit data. The acknowledgment is sent by assigning ALPHA = 1 i.e. SDA is pulled high. 

else if(left_bits == 30)begin
  alpha <= 0;
  left_bits <= left_bits + 1;
end
else if(left_bits == 31)begin
  #2 alpha <= 1;
  left_bits <= left_bits + 1;
end
else if(left_bits == 32)
  a <= 0;
end

At the count 30 ALPHA is set to 0 as ACK is only of 1 bit. For the count 31 ALPHA is set to 1 i.e SDA is pulled high. No negative edge is present afterward here. For the count 32 "a" is set to 0 thus switching SCL line to 1. Since there is not negedge of SDA there SCL won't start clocking again which I have already explained earlier. #2 is the time delay to 2 ns to introduce the STOP condition. 

Fig - STOP Condition

Although #1 should be present there as in the above image I mistakenly added an extra clock cycle. You are free to experiment.

I'll explain the SLAVE code later.

So Long

I2C Verilog Code Explanation I


In this post, I am going to explain my previous post regarding I2C. You can visit the post by clicking here.



INOUT  SDA: The SDA line is the inout port because Master will send data, address along this line as well as the Slave will send ACK/ NACK along the same SDA line hence it has to be inout type.

OUTPUT REG SCL: The SCL line will be the output from Master to other Slaves. SCL is controlled by Master here by the register "a" in the code.

REG DIRECTION: This register will decide whether the direction of flow of data on the SDA line. The line assign sda = direction?alpha:1'bz. using the direction keyword.

Its equivalent code will be
 if(direction==1)
   sda = alpha;
 else if(direction==0)
  sda = 1'bz;

If Master sets the direction as 1 then sda = alpha. At the same moment, Slave must also have the direction set to 0 in order to allow data from Master. When the Slave wants to send the data then the Slave will set the direction as 1 and Master will set it as 0.

REG ALPHA: This register holds the bit that has to be sent on the SDA line. Since SDA is a wire, therefore it is not possible to use it inside always@ block.

REG [6:0] ADDRESS: This 7-bit register holds the 7bit register holds the address of the slave.

REG[7:0] TEMP: This 8-bit register holds the address of the slave along with RW bit that has to be sent on the SDA line.

REG[7:0] TEMP_RESERVED: This 8-bit register just holds a copy of TEMP register for future use.

TEMP = {ADDRESS,RW}: This concatenates the 7-bit address and 1 bit RW into an 8-bit register and stores the final data back in TEMP.
always @(posedge clk)begin
  if(a==0)
    scl <= 1;
  else if(a==1)
    scl <= !scl;
end

Here "a" is a switch. When "ON" it will clock the SCL line. When OFF it will pull up the SCL line HIGH. It is just a manual control for Master to control SCL.

always @(negedge sda)
  a <= 1;
As soon as the SDA line is pulled down, "a" is triggered to start SCL clock. This is the START condition. Although SDA has many negative edges it won't affect SCL because of above code. When we want a STOP condition then SDA is pulled HIGH first. Thus no negative edge occurs after that point and then "a" is triggered low which pulls SCL HIGH and STOP condition is achieved.
always @(negedge scl)begin
  #1 forever #2 scl2 <= !scl2;
SCL2 is an internal clock which starts as soon as SCL is triggered. This is done because we cannot use SCL for our operation. SDA only changes when SCL is LOW (See the LAST image in my post) and not on positive edge or negative edge. #1 is the delay of 1ns. SCL2 starts ticking after 1ns start of SCL. Using the posedge of SCL2 we achieve our required condition to change SDA when SCL is LOW.


Look at this image above. SDA changes when SCL is low (in middle). It neither changes at positive edge nor at the negative edge.

SDA changes at positive edge / negative edge of SCL2 which itself changes at LOW SCL.
Thus SCL and SCL2 are 1ns apart.
integer left_bits = 1;
LEFT_BITS is just a counter for proper operation that I used. It would create a havoc working without it.
always @(negedge scl2)begin
All the SDA operations are operated on a clocked edge of SCL2 not SCL to maintain I2C standard.
if(left_bits <= 8) begin
  alpha <= temp[7];
  temp <= temp<<1;
  left_bits <= left_bits + 1;
end

The above code above is pretty simple. It loops for 8 times in order to send 8 bits which include 7-bit Slave address and 1-bit RW. temp[7] is the MSB which has to be sent first on SDA. (bit by bit).
However, after sending the MSB we have to send the next bit i.e temp[6] therefore, I left shifted the temp bit which shifts 1 bit towards left.

Example:
If temp[7:0] = 10101010;
temp = temp<<1;  Here temp will be 0101010X

if I had used temp = temp<<<1; then temp would be 01010100.

If I had used temp = temp<<2; then temp would be 101010XX

I hope I have cleared the difference between << and <<<. Similarly, we can use >> and >>> although it is of no use here.

NOTE: Initially, the direction is set to 1 in Master and 0 in slave i.e. Master is sending data on SDA line which SLAVE has to accept.
else if(left_bits == 9)begin
direction <= 0;
ack <= sda;
left_bits <= left_bits + 1;
end

After sending 8 bits direction is changed to 0 in Master and 1 in Slave. It is the turn of Master to accept from Slave. At this moment Slave, if the address is matched it will send 0 NACK or 1 if the address is not matched. ACK is opposite of NACK.

.....................
To be continued in next post.



I2C Verilog Code and working



I had already made a post regarding I2C long ago, however, in this post I am reposting I2C but with various changes. Some changes involve the using of Acknowledgement Bit by the Slave and Master, Same SDA line for slave address, register address as well as data. No extra data line is required to read the data from the slave. Everything can be seen on the SDA line along. This version of I2C in Verilog has the full support of adding *multiple* slaves.

Yes!! You can use multiple slaves at the same time. The only feature lacking that I am working on right now is the RW bit. The RW or better say Read/Write bit is present here but I have focussed only on the read operation here. I am working on the write operation too and will update soon for the latter.

For this I2C I had to grasp myself with the knowledge of the inout signal line in Xilinx. The SDA has to be an inout line or else it won't be a proper I2C model, despite serving the same functionality.

The Master will send 7-bit address along with RW bit on the SDA line and the corresponding slave will respond back with an ACK bit. After that Master will send the register address which will be acknowledged
by the slave with an ACK bit. Then the slave will send the 8-bit data from the received register to the Master. After receiving the data, Master will respond back with ACK bit and after a CC the I2C operation will end with the STOP bit.

The SCL line changes only when SDA is stable. The testbench I have used here only acts as a supervisor which provides a clock signal to Master. The Master is connected to the slave only with SDA and SCL line.

*DISCLAIMER: This Verilog Code only supports "Read" Operation. I'll continue with the "Write" operation later.

I have worked on this code using a different approach. If the Slave address that Master sends doesn't match with the Slave then it will keep on sending the same address. However, this approach is only applicable to 1 Slave. Consider the case where there are two slaves S1 and S2. If S1 address is matched then data exchange takes place between Master and S1. However, S2 will then inflict as the address won't match here. This will lead to an error on the SDA lines inform of X.

Thus to overcome this difficulty I have re-changed the code to NOT to send address, again and again, i.e if the address doesn't match then Master won't resend the address. Although a Master should keep on sending the address in real, my code faces a problem which I'll deal later.

As I have mentioned that I have used inout command in this code. Inout command should only be used using a tri-state buffer.

A tristate buffer is coded somewhat like this:
x <= direction?data:1'bZ;

A tristate buffer has an enable pin. When enabled (here direction == TRUE) then data will be transmitted. On the other case, when disabled (here direction == FALSE) then a high impedance is
sent thereby disconnecting the output from the input circuit. Consider A and B. When A is true then it is at higher potential. When B is false it is at a lower potential. As current flows from High to Low, this signal will blow from A(TRUE - 1) to B (FALSE Z). Similarly, if B is true and A is false then signal will flow from B to A.

While I was coding, I faced tremendous problems with switching between TRUE and FALSE in both Master and Slave. If both A and B are set to TRUE then you will get ZZZZZZZ (in blue color) as output. If both A and B are low you will get XXXXXX (in red color) as output. 

The signal line of type inout can only be a wire. It cannot be registered as reg type so to use it we have to use the "assign" keyword.

RW- 0 ACK = 1 Slave address matched

RW- 0 ACK = 0 Slave address not matched

Get Single Master Single Slave Code from here: Github I2C_Code

Master & Slave


Test Bench

NOTE - To restart the I2C transmission all you have to do is give a fork join condition
fork
#160 alpha <= 0;
#160 direction <= 1;
#162 left_bits <= 1;
join



Place this piece of code in the initial begin of the Master Code. Remember that you have to give sufficient #time condition to avoid conflict. With this you can you can pull SDA line low to restart I2C for a new data. However, data will too remain the same. Thus you will have to change the data by using #time syntax like this in Master

fork
#160 alpha <= 0;
#160 direction <= 1;
#162 left_bits <= 1;
#160 register = 7'b00011001; // 00011001 = 25 in decimal
#160 reg_temp = register;
join

In Slave you will have to enter new data in the array at location 25.

Sim View of the code above in Xilinx




For Multi Slave I2C significant changes are required. Consider a case where we have two slaves named A and B. The master will send the address of A. In that case slave A will send acknowledgment bit (1 in this case) on the sda line. However, slave B will also send acknowledgment bit (0 in this case). This creates a problem as Verilog doesn't allow multiple drivers for a single wire. Even if I simulated I got ZZ as the acknowledgment because of that conflict.

It can be represented as follows


Thus to avoid this condition I used the Verilog keyword "wor". wor is logical OR of wires joint together.

In case if Slave A NACK = 0 and Slave B NACK = 1 then wor would output as 1(B) + 0(A) = 1

Similarly

0(A) + 0(B) = 0

0(A) + 1(B) = 0

1(A) + 1(B) = NOT POSSIBLE FOR I2C WITH SAME ADDRESS.


The following piece of code has a single master and 3 slaves. One thing I came to notice that all slaves code can remain same except the module name or else any change made to any slave would result in a change is every slave.


Multi Slave Code (Works Pretty well. Comment or message for any error)
To change slave address one can change it to desired address by changing address at line 22 of Master

To fully understand my code click HERE
So Long

I2C Verilog Code and working


I had already made a post regarding I2C long ago, however, in this post I am reposting I2C but with various changes. Some changes involve the using of Acknowledgement Bit by the Slave and Master, Same SDA line for slave address, register address as well as data. No extra data line is required to read the data from the slave. Everything can be seen on the SDA line along. This version of I2C in Verilog has the full support of adding *multiple* slaves.
Yes!! You can use multiple slaves at the same time. The only feature lacking that I am working on right now is the RW bit. The RW or better say Read/Write bit is present here but I have focussed only on the read operation here. I am working on the write operation too and will update soon for the latter.

For this I2C I had to grasp myself with the knowledge of the inout signal line in Xilinx. The SDA has to be an inout line or else it won't be a proper I2C model, despite serving the same functionality.

The Master will send 7-bit address along with RW bit on the SDA line and the corresponding slave will respond back with an ACK bit. After that Master will send the register address which will be acknowledged
by the slave with an ACK bit. Then the slave will send the 8-bit data from the received register to the Master. After receiving the data, Master will respond back with ACK bit and after a CC the I2C operation will end with the STOP bit.

The SCL line changes only when SDA is stable. The testbench I have used here only acts as a supervisor which provides a clock signal to Master. The Master is connected to the slave only with SDA and SCL line.

*DISCLAIMER: This Verilog Code only supports "Read" Operation. I'll continue with the "Write" operation later.

I have worked on this code using a different approach. If the Slave address that Master sends doesn't match with the Slave then it will keep on sending the same address. However, this approach is only applicable to 1 Slave. Consider the case where there are two slaves S1 and S2. If S1 address is matched then data exchange takes place between Master and S1. However, S2 will then inflict as the address won't match here. This will lead to an error on the SDA lines inform of X.

Thus to overcome this difficulty I have re-changed the code to NOT to send address, again and again, i.e if the address doesn't match then Master won't resend the address. Although a Master should keep on sending the address in real, my code faces a problem which I'll deal later.

As I have mentioned that I have used inout command in this code. Inout command should only be used using a tri-state buffer.

A tristate buffer is coded somewhat like this:
x <= direction?data:1'bZ;

A tristate buffer has an enable pin. When enabled (here direction == TRUE) then data will be transmitted. On the other case, when disabled (here direction == FALSE) then a high impedance is
sent thereby disconnecting the output from the input circuit. Consider A and B. When A is true then it is at higher potential. When B is false it is at a lower potential. As current flows from High to Low, this signal will blow from A(TRUE - 1) to B (FALSE Z). Similarly, if B is true and A is false then signal will flow from B to A.

While I was coding, I faced tremendous problems with switching between TRUE and FALSE in both Master and Slave. If both A and B are set to TRUE then you will get ZZZZZZZ (in blue color) as output. If both A and B are low you will get XXXXXX (in red color) as output. 

The signal line of type inout can only be a wire. It cannot be registered as reg type so to use it we have to use the "assign" keyword.

RW- 0 ACK = 1 Slave address matched

RW- 0 ACK = 0 Slave address not matched

Get Single Master Single Slave Code from here: Github I2C_Code

Master & Slave


Test Bench

NOTE - To restart the I2C transmission all you have to do is give a fork join condition
fork
#160 alpha <= 0;
#160 direction <= 1;
#162 left_bits <= 1;
join



Place this piece of code in the initial begin of the Master Code. Remember that you have to give sufficient #time condition to avoid conflict. With this you can you can pull SDA line low to restart I2C for a new data. However, data will too remain same. Thus you will have to change the data by using #time syntax like this in Master

fork
#160 alpha <= 0;
#160 direction <= 1;
#162 left_bits <= 1;
#160 register = 7'b00011001; // 00011001 = 25 in decimal
#160 reg_temp = register;
join

In Slave you will have to enter new data in the array at location 25.

Sim View of the code above in Xilinx




For Multi Slave I2C significant changes are required. Consider a case where we have two slaves named A and B. The master will send the address of A. In that case slave A will send acknowledgment bit (1 in this case) on the sda line. However, slave B will also send acknowledgment bit (0 in this case). This creates a problem as Verilog doesn't allow multiple drivers for a single wire. Even if I simulated I got ZZ as the acknowledgment because of that conflict.

It can be represented as follows


Thus to avoid this condition I used the Verilog keyword "wor". wor is logical OR of wires joint together.

In case if Slave A NACK = 0 and Slave B NACK = 1 then wor would output as 1(B) + 0(A) = 1

Similarly

0(A) + 0(B) = 0

0(A) + 1(B) = 0

1(A) + 1(B) = NOT POSSIBLE FOR I2C WITH SAME ADDRESS.


The following piece of code has a single master and 3 slaves. One thing I came to notice that all slaves code can remain same except the module name or else any change made to any slave would result in a change is every slave.


Multi Slave Code (Works Pretty well. Comment or message for any error)
To change slave address one can change it to desired address by changing address at line 22 of Master

To fully understand my code click HERE
So Long

Verilog Code for I2C Protocol


[THIS POST IS OUTDATED. VISIT NEW POST FOR I2C HERE ]

I2C PROTOCOL

Hola Amigos
I2C devices have been around us for a long time. If you have done any arduino projects with any peripherals such as Bluetooh (HC-05) or Gyroscope (MPU6050) or Barometer etc you might be surprised you have already used I2C devices. Yes

An I2C basically consists of a master microcontroller and a slave device which responds to the requests of the master. A slave cannot operate on its own. It can't even communicate with other slaves without having any permission from the master.
      You may have come across multi-master schematic but it becomes much more complex to handle such situation because of data leakage and also it requires more than 1 microcontrollers. So if you are using an I2C you cannot use any other non-I2C device on the same bus as both SDA and SCL lines are in conjunction with the I2C module. If you find this facility somewhere you are being fooled seriously !!!
 I2C works on 2 signals as SCL and SDA
                                           SCL - Serial Clock
                                           SDA- Serial Data
When SDA is having negedge and SCL is positive level triggered then we have start signal and with every SCL clock a bit is transferred. Combining up to eight bit the slave receives an address. Then come the R/W signal means whether the slave has to read or write from/to address. AT the very moment after R/W bit the last bit known as acknowledgment bit is sent. Then the slave sends bit by bit data and finalizing by the acknowledge bit and the process comes to a STOP.

Do remember that when SDA changes the SCL lines must remain stable hence SDA doesn't change at posedge or nedge of SCL and only on the level of SCL i.e. either 1 or 0.

Here is a demonstration


Pic Credit- Google
 You can easily see the working as I have explained in comparison to the diagrams.
 Ok Coming down to the code



Starting with Master module and with its inputs



clk = Normal clock
sda = serial data
scl = serial clock
data_wr = data that has to be written if rw = 0;
address = address of slave
register = address of register which has to be read
rw = read or write pin

Next, we move to the declaration of internal variables


temp = to copy address incoming
register2 = to copy register value
scl2x = clock with which sda works to change sda while scl is 0
i = internal counter
n = single counter for start and stop conditions

One must note that initially, we have sda and scl = 1 
After 5ns we turn sda to 0 to introduce start bit condition


From Line 28 to 30 :- we use n as a flag to start scl and scl2x to start bit transmitting
At Line 33 :- Temp stores the concatenated value of the address of slave then rw bit and                                                acknowledge bit
At Line 34:- Incoming register address is stored in register2 internal variable because further we will be using shift operators which doesn't work on wires and always does on reg data type.
At Line 36 :- If n==1 means start condition and if rw=1 means we have to read register thus                        scl will run upto 50 times
                       Similarly, for rw=1 means, we have to write scl will run 64 times.
                       The value 50 and 64 can be obtained by self-coding 




This piece of code is for stop bit condition.

At Line 55 :- Till value of i reaches 9 we will grab bit by bit from temp
                       Here temp is having 6 bit slave address and 2 bits of rw and ack. Thus each bit                          is being read by shifting temp one by one and reading its MSB
                       Same is happening after Line 60 to get the address of the register
At Line 65 :- if rw ==0 we will receive data which has to be written hence the same process is                              followed too.

Here is the full code -:

Master Code-:
module master(data,address,clk,rw,sda,scl,register,data_wr);
output reg sda;
input [7:0] data;
input [7:0] data_wr;
reg [7:0]data_wr_dup;
input clk;
input rw;
output reg scl;
input [6:0] address;
input [7:0] register;
reg [8:0] temp;
reg [7:0] register2;
reg pstate;
reg scl2x;
reg ack;
reg a;
integer i;
integer n;
initial begin
i = 0;
n = 0;
scl2x = 0;
ack = 1'b1;
sda = 1;
scl = 1;
#5 sda = 0;  //START BIT condition starts here
end
                                                always @(negedge sda)
                                                if(scl==1)
                                                n=1;
always @(posedge clk)begin
ack = 0;
temp = {address,rw,ack};
register2 = register;
data_wr_dup = data_wr;
if(n==1 && rw==1)
repeat(50)begin
#2 scl <= !scl;n=0;
#1 scl2x <= !scl2x;n=0;
end
else if(n==1 && rw==0)
repeat(64) begin
#2 scl = !scl;
#1 scl2x = !scl2x;n=0;
end
end
always @(posedge clk)begin
if(i==25 && rw==1)
repeat(2)
#1 scl2x = !scl2x;
else if(i==32 && rw==0)
repeat(2)
#1 scl2x = !scl2x;end
always @(posedge scl2x)begin
if(i<=9)begin
sda = temp[8];
temp = temp<<1;
end
else if(i==12 || i==13)
sda = 1'b0;
else if(i>=14)begin
sda = register2[7];
register2 = register2<<1;
end
if(rw==0 && i>=23)begin
sda = data_wr_dup[7];
data_wr_dup = data_wr_dup<<1;
end
i = i + 1;
if(i>32 && rw ==0)
sda= 1;
else if(i>25 && rw==1)
sda = 1;
end
slave slv(data,sda,scl);
endmodule


And here is the code for Slave-:

module slave(out,sda,scl);
input sda;
input scl;
output reg [7:0]out;
integer j = 0;
reg [6:0]temp;
reg [7:0]add;
reg rw;
reg [7:0]register_address;
reg bitin;
reg [7:0]storage[0:38];
initial
storage[37]=16;
parameter address = 7'b1101001;
always @(posedge scl)begin
//if({sda,scl}==2'b01)begin
bitin = sda;
if(j<8)
temp = {temp,bitin};
if(j==8)
            if(bitin==0)
                        rw = 0;
            else
                        rw = 1;
j = j +1 ;
if(temp==address && (j>15 && j<24) && rw==1)begin
            add = {add,bitin};
end
if(temp==address && rw == 0 && j>15 && j!=24 && j<33)begin
            add = {add,bitin};
end
else if(j==24)
            register_address = add;
if(j==33 && rw==0)
storage[register_address]=add;
out = storage[add];
end
endmodule

And here is the testbench _-:

module tbmast;

            // Inputs
            reg [6:0] address;
            reg [7:0] register;
            reg [7:0] data;
            reg [7:0] data_wr;
            reg clk;
            reg rw;

            // Outputs
            wire sda;
            wire scl;

            // Instantiate the Unit Under Test (UUT)
            master uut (
                        .address(address),
                        .register(register),
                        .clk(clk),
                        .rw(rw), 
                        .sda(sda),
                        .scl(scl),
                        .data(data),
                        .data_wr(data_wr)
            );

            initial begin
                        // Initialize Inputs
                        address = 105;
                        register = 7'b0100101;
                        clk = 0;
                        rw = 0;
                        data_wr = 20;

                        // Wait 100 ns for global reset to finish
                        #100;
       
                        // Add stimulus here

            end
      always
                        #1 clk = !clk;
endmodule

Here is the waveform for rw==0 means write a data to register
Better ZOOM it




Master Model
 Slave Model

So Long