Verilog Code for I2C Protocol


[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 Bluetooth (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.

Get the full code with the following link
Kindly Disable your popups

Click Here to get the code





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




Master Model
 Slave Model

So Long

Verilog Code for Sequence Detector




SEQUENCE DETECTOR

Hola Amigos
Beginning with the simple theory about Sequence Detector. A sequence detector an algorithm which detects a sequence within a given set of bits. Of course the length of total bits must be greater than sequence that has to be detected.
Sequence detector basically is of two types –

a.      Overlapping
b.     Non Overlapping
In overlapping some of the last bits can also be used for the start of detection of next sequence within the given bits.



For Example Let the sequence be 11011 and given bits 1101101101101101
Now lets work on overlapping concept.
We have 5 bits here in 11011 hence we will have 5 states. Let em be A/B/C/D and E.
Initially pstate will be A.
Now

1.     Incoming bit is 1 (from 1101101101101101) and it matches with first bit of sequence hence jump to next B. Requirement(1011)
2.     Incoming bit is 1 (from 1101101101101101)and it matches with  first bit of requirement hence jump to state C. Requirement (011)
3.     Incoming bit is 0 (from 1101101101101101) and it matches with first bit of requirement hence jump to state D. Requirement (11)
4.     Incoming bit is 1 (from 1101101101101101) and it matches with first bit of requirement hence jump to state E. Requirement (1)
5.     Incoming bit is 0 (from 1101101101101101) and it matches with first bit of requirement hence jump to state A. Requirement (). Output is 1 as we have found a sequence


To be more clear here is a table-


Notice that state C has 11 and requires 011. Now if it receives 1 instead of zero then instead of resetting and going back to A it will remain at C because C has 11 which can be used for starting of 11011 . This is called Overlapping. Similarly after state E we have restart to detect sequence then instead of starting again from A we will jump to C since it already has some bits which can serve as starting point. Remember always jump to that state which can provide maximum starting bits of sequence . Here B has 1 which can also serve but it isn’t maximum.


          Ok again for better understanding we have 11011 then
11011  can serve as starting bit i.e state B
11011 can serve as starting bits i.e state C
11011 cannot serve as starting bits since sequence doesn’t start with 011
11011 cannot serve as starting bits since sequence doesn’t start with 1011



Here is the state diagram for this sequence. I am pretty sure you must have understood Overlapping till now. If No! you can contact or this state diagram should suffice.






Let's go step by step
(A) Idle state is A waiting for 1 which if it gets will jump to B else will remain to A

(B) If receives 1 will jump to C else will jup back to idle A 

(C) If receives 1 will remain at itself as it has 11 to start with however if it receives         0 then it will jump to state D


(D) If receives 0 will jump to state A else will jump to state E

(E) If receives 0 will jump to A else will jump to Cand output will be 1 which                   means that a sequence has been detected.



Now how many FFs do we require to make this machine. We have 5bits here so
by using this equation we can find
                                           2x-1<5<2x
Thus we get X = 3 hence 3 FFs

To design in verilog here is the code for both Overlap and NonOverlap-

//***************************************************************************//
module sequence_detector(sequence,overlap,detect,clk,q);
input [15:0]sequence;
reg [15:0]temp;
reg bitin;
input overlap;
input [4:0]detect;
input clk;
output reg q;
integer i=0;
reg [2:0]pstate;
parameter A = 3'b000, B = 3'b001, C = 3'b011, D = 3'b100, E = 3'b101;
initial begin
pstate <=A;
$monitor("Pstate=%d bit=%b q=%b",pstate,bitin,q);
end
always @(posedge clk)begin
if(i==0)
temp = sequence;
i = i + 1;
end
always @(posedge clk)begin
bitin = temp[15];
temp=temp<<1;
if(overlap==1'b1)begin
case(pstate)
A:
if(bitin==1'b1)begin
pstate = B;
q = 0;
end
else begin
pstate = A;
q = 0;
end
B:
if(bitin==1'b1)begin
pstate = C;
q = 0;
end
else begin
pstate = A;
q = 0;
end
C:
if(bitin==1'b0)begin
pstate = D;
q = 0;
end
else begin
pstate = C;
q = 0;
end
D:
if(bitin==1'b1)begin
pstate = E;
q = 0;
end
else begin
pstate = A;
q = 0;
end
E:
if(bitin==1'b1)begin
pstate = C;
q = 1;
end
else begin
pstate = A;
q = 0;
end
endcase
end
else if(overlap==1'b0) begin
case(pstate)
A:
if(bitin==1'b1)begin
pstate = B;
q = 0;
end
else begin
pstate = A;
q = 0;
end
B:
if(bitin==1'b1)begin
pstate = C;
q = 0;
end
else begin
pstate = A;
q = 0;
end
C:
if(bitin==1'b0)begin
pstate = D;
q = 0;
end
else begin
pstate = A;
q = 0;
end
D:
if(bitin==1'b1)begin
pstate = E;
q = 0;
end
else begin
pstate = A;
q = 0;
end
E:
if(bitin==1'b1)begin
pstate = A;
q = 1;
end
else begin
pstate = A;
q = 0;
end
endcase
end
end
endmodule

and here is the Test Bench
//*************************************************************************//
module sequence();
reg clk,overlap;
reg [4:0]detect;
reg [15:0]sequence;
wire q;

initial begin
clk = 0;
overlap = 1; //1 for overlap 0 for non overlap
sequence = 16'b1101101101101101;
detect = 5'b11011;
end
always #2 clk=!clk;
sequence_detector yeah(sequence,overlap,detect,clk,q);
endmodule
//**************************************************************************//

Here is the simulator output (Overlapping)

Here is the Console Output for Overlapping

Here is the simulator output (Non-Overlapping)

Here is the Console Output for NonOverlapping

Here is the State Table for this question

For the truth table here it is


D2 = X’*Y1 + X*Y2*Y0
D1 = X *Y0

D0 = X

Here is the data flow diagram

So Long 


      



Verilog code for BCD to 7 Segment Display


BCD TO 7-SEGMENT DISPLAY

Hola Amigos
BCD stands for Binary Coded Decimal which runs only till 9. The main objective is to convert the binary input to a decimal number to be displayed on 7-Segment Block which looks like this


Here is the truth table for this 

"s" Represents State and A-G represents pins of 7-Seg Display

Here is the code

module bcd(a,b,c);
input [3:0]a;  // the number
wire [3:0]a;
output [6:0]b;
reg [6:0]b;
output [6:0]c;
reg [6:0]c;
always @(a)
begin
if(a==0)begin
b = 7'b1111110;          // in terms of 7-Seg "abcdefg" i.e Here a/b/c/d/e/f are on i.e "1" and G is off "0"
c = 7'b0000000;         // for this pattern we have output as zero
end
else if(a==1)begin
b = 7'b0110000;
c = 7'b0000001;
end
else if(a==2)begin
b = 7'b1101101;
c = 7'b0000010;
end
else if(a==3)begin
b = 7'b1111001;
c = 7'b0000011;
end
else if(a==4)begin
b = 7'b0110011;
c = 7'b0000100;
end
else if(a==5)begin
b = 7'b1011011;
c = 7'b0000101;
end
else if(a==6)begin
b = 7'b1011111;
c = 7'b0000110;
end
else if(a==7)begin
b = 7'b1110000;
c = 7'b0000111;
end
else if(a==8)begin
b = 7'b1111111;
c = 7'b0001000;
end
else if(a==9)begin
b = 7'b1111011;
c = 7'b0001001;
end
else begin
b = 7'bxxxxxxx;
c = 7'bxxxxxxx;
end
end
endmodule
//***********************Test Bench*****************//
module BCD_to_7_B ();
reg [3:0]a;
wire [6:0]b;
wire [6:0]c;
initial
begin
a = 0;
#5 a = 1;
#5 a = 2;
#5 a = 5;
#5 a = 3;
#5 a = 4;
end

bcd b1(a,b,c);
endmodule

Here is the iSim Output displaying the testbench upto a = 4;



Feel free to contact for any flaws.

So Long


Verilog Code for Asynchronous Counters


ASYNCHRONOUS COUNTER


Asynchronous means in terms of simple definition without external clock synchronization.
The output always remains free from clock signal. 
     Generally the first FF is clocked with main external clock and each of next FF have output of previous FF as their clock. This helps in reducing the number of FFs and additional gates hence requires less complexity.
    Now coming to the special "MOD" term. It basically stands for modulus.

When you have to design a Mod-Y counter then the basic steps include
1. The equation -: 2x  = Y. 
2.  Now find value of X if you know basic Maths. You can use logarithms 

Thus after getting the value of X you basically get how many FFs are required hence you require X FFs to design Mod- Y UP or Down counter.

Here is the block diagram of Mod-16 or 4bit Asynchronous Counter



Now For Mod-16 we have value of X as 4 hence 4 FFs

Here is the code to test this



module dff(d,clk,q);
input d;
input clk;
wire d;
wire clk;
output q;
reg q;
initial
q = 1'b0;
always @(posedge clk)begin
q <= d;
end
endmodule
//************************Test Bench******************//
module FOURbit_up_B();
reg clk;
reg d;
wire [3:0]q;
initial
clk = 0;
always 
#1 clk = !clk;
dff a1(!q[0],clk,q[0]);
dff a2(!q[1],!q[0],q[1]);
dff a3(!q[2],!q[1],q[2]);
dff a4(!q[3],!q[2],q[3]);
endmodule



This was Aynchronous Up counter.
Pay attention here that clock input to each FF is ~Q (Q bar). Thus for Down counter the clock input after 1st FF will be from Q and not   ~Q (Q bar)

Here is the block diagram for 4 bit Down Asynchronous Counter


Notice the clock inputs to each FF after 1st FF.

Here is the code for Down Counter 4 bit



module dff(d,clk,q);
input d;
input clk;
wire d;
wire clk;
output q;
reg q;
initial
q = 1'b0;
always @(posedge clk)begin
q <= d;
end
endmodule

module FOURbit_up_B();
reg clk;
reg d;
wire [3:0]q;
initial
clk = 0;
always 
#1 clk = !clk;
dff a1(!q[0],clk,q[0]);
dff a2(!q[1],q[0],q[1]);
dff a3(!q[2],q[1],q[2]);
dff a4(!q[3],q[2],q[3]);
endmodule


and heres the simulation wave window from Xilinx iSim

Mail or Comment for any flaws here or if you have any doubts.

So Long


Self Balancing Robot using Machine Learning

Hola Amigos, I have always loved inverted pendulums. They are very fascinating to me and I play with them a lot. In real life, I have m...