fradaric
Newbie level 5
Hei ,
I am making a verilog code for I2C in order to communicate with TMP100 , In my design I made the SCL globally, and I've given the slave addressing, pointer addressing etc with a 'always @(posedge scl)' block, so the clock transitions and sda transitions occurs at the same time but TMP 100 (temperature sensor) needs a setup time of 100ns. I couldn't able to provide it since I am using 'always @(posedge scl)'
How can I solve this issue? anyone have any idea?? please help me .... i've added testbench wave form here and also My I2C code is given below.
`timescale 1ns / 1ps
// Fradaric Joseph
// Ph: 09401015142
module I2C(
inout sda,
output scl,
output [15:0] temperature_out,
input clk,
output [2:0] ack_out,
output [1:0] ack_count1,
input reset
);
parameter clock_div=500; // I2C clock 50MHz/(500)=100KHz
//---------------------------I2C State Machine Variables----------------------
parameter Rxidle =0;
parameter Rxstart =1;
parameter RxPointeraddr =2;
parameter Rxstart1=3;
parameter Rxdata =4;
parameter Rxstop =5;
//-----------------------------------------------------------------------------
reg chk=0;
reg [2:0] ack;
reg [1:0] ack_count=0;
//reg poiter2=0;
//reg ack2=0;
//reg ack3=0;
//------------------------------------------------------------------------------
reg I2Cclk =1; // I2C clock
reg [8:0] clkclk=clock_div; // in order to divide 50MHz clock
reg sda_int =1; // making SDA high in initial state
reg [15:0] outreg =0;
reg [3:0] I2C_counter=0; // for giving the pointer address (000000-00(P1P0))
reg [3:0] bitaddrs7=4'b0001; // initializing via giving slave address(1001000-0(R/W))
reg [3:0] Rxcount=0;
reg [3:0] slaveaddrs=0; //receiving data from TMP 100
/// ----------------------------------------------------------------------------
reg [2:0] state =Rxidle ; // For State machine starting
assign scl =I2Cclk;// Generated Clock for I2C
assign temperature_out = outreg; // output from TMP 100
assign sda =sda_int; // Using SDA pin
assign ack_out=ack;
assign ack_count1=ack_count;
////------------------------------
always @ (posedge clk) /// --------------------- scl generation-----------------
begin
if(!chk)
begin
clkclk=clkclk - 1;
if(clkclk==0)
begin
I2Cclk=~I2Cclk;
clkclk =clock_div;
end
end
else I2Cclk=1'b1; end
////.............................................................................
always @(posedge I2Cclk )
if(reset)
begin
chk <=0;
outreg <=0;
I2C_counter <=0;
bitaddrs7 <=4'b0001;
Rxcount <=0;
slaveaddrs <=0;
ack <=0;
ack_count <=0;
I2Cclk <=1;
sda_int <=1;
clkclk <=clock_div;
end
always @(posedge I2Cclk )
begin
////....................................state machine............................
case (state)
//-------------------------------------------------------------------------------
Rxidle:
begin sda_int=1'b0; //---------------------start sda = 0
state =Rxstart;end
//-------------------------------------------------------------------------------
Rxstart:
begin
case(bitaddrs7)
// initial frame 1001000 Initializing slave address
1: begin
sda_int =1'b1;//---------------------sda 1
bitaddrs7=bitaddrs7+1; end
2: begin sda_int =1'b0;//---------------------sda 0
bitaddrs7=bitaddrs7+1; end
3: begin sda_int =1'b0;//---------------------sda 0
bitaddrs7=bitaddrs7+1; end
4: begin sda_int =1'b1;//---------------------sda 1
bitaddrs7=bitaddrs7+1; end
5: begin sda_int =1'b0;//---------------------sda 0
bitaddrs7=bitaddrs7+1; end
6: begin sda_int =1'b0;//---------------------sda 0
bitaddrs7=bitaddrs7+1; end
7: begin sda_int =1'b0;//---------------------sda=0
bitaddrs7=bitaddrs7+1; end
8: begin sda_int =1'b0;
ack_count=2'b00;
bitaddrs7=bitaddrs7+1; // R/W bit
end
9: begin if(sda==1'b0)
ack[0]=1;
state=RxPointeraddr; // Checking ack
end
endcase
end
//---------------------------------------------------------------------------------
RxPointeraddr:
// Pointer Address 000000-00(P1P0) for temperature register
begin
case(I2C_counter)
//---------------------sda = 0
0: begin sda_int =1'b0;
I2C_counter=I2C_counter+1;end
//---------------------sda = 0
1: begin sda_int =1'b0;
I2C_counter=I2C_counter+1;end
//---------------------sda = 0
2: begin sda_int =1'b0;
I2C_counter=I2C_counter+1; end
//---------------------sda = 0
3: begin sda_int =1'b0;
I2C_counter=I2C_counter+1; end
//---------------------sda = 0
4: begin sda_int =1'b0;
I2C_counter=I2C_counter+1;end
//---------------------sda = 0
5: begin sda_int =1'b0;
I2C_counter=I2C_counter+1;end
//---------------------sda = 0
6: begin sda_int =1'b0;
I2C_counter=I2C_counter+1;end
//---------------------sda = 0
7: begin sda_int =1'b0;
ack_count=2'b01;
I2C_counter=I2C_counter+1;end
8: begin if(sda==1'b0)
ack[1]=1'b0; state=Rxstart1;end // after pointer register sda line acknoledged by a low pulse
endcase
end
//-----------------------------------start+ slave address byte---------------------
Rxstart1:
begin
case(slaveaddrs)
// initial frame 1001000 Initializing slave address including start (case 0
0: begin sda_int=1'b0;
slaveaddrs=slaveaddrs+1; end
1: begin sda_int =1'b1;//---------------------sda 1
slaveaddrs=slaveaddrs+1; end
2: begin sda_int =1'b0;//---------------------sda 0
slaveaddrs=slaveaddrs+1; end
3: begin sda_int =1'b0;//---------------------sda 0
slaveaddrs=slaveaddrs+1; end
4: begin sda_int =1'b1;//---------------------sda 1
slaveaddrs=slaveaddrs+1; end
5: begin sda_int =1'b0;//---------------------sda 0
slaveaddrs=slaveaddrs+1; end
6: begin sda_int =1'b0;//---------------------sda 0
slaveaddrs=slaveaddrs+1; end
7: begin sda_int =1'b0;//---------------------sda=0
slaveaddrs=slaveaddrs+1; end
8: begin sda_int =1'b1;
slaveaddrs=slaveaddrs+1; // R/W bit high
ack_count=2'b10; end
9: begin if(sda==1'b0)
ack[2]=1;
state=Rxdata; // Checking ack
end
endcase
end
//----------------------------------Receiving Temperature Data --------------------------
Rxdata:
begin
case(Rxcount)
0: begin outreg[15]=sda;
Rxcount=Rxcount+1;end
1: begin outreg[14]=sda;
Rxcount=Rxcount+1;end
2: begin outreg[13]=sda;
Rxcount=Rxcount+1;end
3: begin outreg[12]=sda;
Rxcount=Rxcount+1;end
4: begin outreg[11]=sda;
Rxcount=Rxcount+1;end
5: begin outreg[10]=sda;
Rxcount=Rxcount+1;end
6: begin outreg[9]=sda;
Rxcount=Rxcount+1;end
7: begin outreg[8]=sda;
Rxcount=Rxcount+1;
ack_count=2'b11; end
// low pulse acknoledgment from TMP100
8: begin outreg[7]=sda;
if(!sda) ack[2]=1;
Rxcount=Rxcount+1;end
9: begin outreg[6]=sda ;
Rxcount=Rxcount+1;end
10: begin outreg[5]=sda ;
Rxcount=Rxcount+1;end
11: begin outreg[4]=sda;
Rxcount=Rxcount+1;end
12: begin outreg[3]=sda;
Rxcount=Rxcount+1;end
13: begin outreg[2]=sda;
Rxcount=Rxcount+1;end
14: begin outreg[1]=sda;
Rxcount=Rxcount+1;end
15: begin sda_int=1'b0;
// checking low pulse acknoledge frm TMP 100
state=Rxstop; end
endcase
end
//-----------------------------------------------------------------------------------------
Rxstop:
begin chk=1; sda_int=1'b1; end
endcase
end
endmodule
I am making a verilog code for I2C in order to communicate with TMP100 , In my design I made the SCL globally, and I've given the slave addressing, pointer addressing etc with a 'always @(posedge scl)' block, so the clock transitions and sda transitions occurs at the same time but TMP 100 (temperature sensor) needs a setup time of 100ns. I couldn't able to provide it since I am using 'always @(posedge scl)'
How can I solve this issue? anyone have any idea?? please help me .... i've added testbench wave form here and also My I2C code is given below.
`timescale 1ns / 1ps
// Fradaric Joseph
// Ph: 09401015142
module I2C(
inout sda,
output scl,
output [15:0] temperature_out,
input clk,
output [2:0] ack_out,
output [1:0] ack_count1,
input reset
);
parameter clock_div=500; // I2C clock 50MHz/(500)=100KHz
//---------------------------I2C State Machine Variables----------------------
parameter Rxidle =0;
parameter Rxstart =1;
parameter RxPointeraddr =2;
parameter Rxstart1=3;
parameter Rxdata =4;
parameter Rxstop =5;
//-----------------------------------------------------------------------------
reg chk=0;
reg [2:0] ack;
reg [1:0] ack_count=0;
//reg poiter2=0;
//reg ack2=0;
//reg ack3=0;
//------------------------------------------------------------------------------
reg I2Cclk =1; // I2C clock
reg [8:0] clkclk=clock_div; // in order to divide 50MHz clock
reg sda_int =1; // making SDA high in initial state
reg [15:0] outreg =0;
reg [3:0] I2C_counter=0; // for giving the pointer address (000000-00(P1P0))
reg [3:0] bitaddrs7=4'b0001; // initializing via giving slave address(1001000-0(R/W))
reg [3:0] Rxcount=0;
reg [3:0] slaveaddrs=0; //receiving data from TMP 100
/// ----------------------------------------------------------------------------
reg [2:0] state =Rxidle ; // For State machine starting
assign scl =I2Cclk;// Generated Clock for I2C
assign temperature_out = outreg; // output from TMP 100
assign sda =sda_int; // Using SDA pin
assign ack_out=ack;
assign ack_count1=ack_count;
////------------------------------
always @ (posedge clk) /// --------------------- scl generation-----------------
begin
if(!chk)
begin
clkclk=clkclk - 1;
if(clkclk==0)
begin
I2Cclk=~I2Cclk;
clkclk =clock_div;
end
end
else I2Cclk=1'b1; end
////.............................................................................
always @(posedge I2Cclk )
if(reset)
begin
chk <=0;
outreg <=0;
I2C_counter <=0;
bitaddrs7 <=4'b0001;
Rxcount <=0;
slaveaddrs <=0;
ack <=0;
ack_count <=0;
I2Cclk <=1;
sda_int <=1;
clkclk <=clock_div;
end
always @(posedge I2Cclk )
begin
////....................................state machine............................
case (state)
//-------------------------------------------------------------------------------
Rxidle:
begin sda_int=1'b0; //---------------------start sda = 0
state =Rxstart;end
//-------------------------------------------------------------------------------
Rxstart:
begin
case(bitaddrs7)
// initial frame 1001000 Initializing slave address
1: begin
sda_int =1'b1;//---------------------sda 1
bitaddrs7=bitaddrs7+1; end
2: begin sda_int =1'b0;//---------------------sda 0
bitaddrs7=bitaddrs7+1; end
3: begin sda_int =1'b0;//---------------------sda 0
bitaddrs7=bitaddrs7+1; end
4: begin sda_int =1'b1;//---------------------sda 1
bitaddrs7=bitaddrs7+1; end
5: begin sda_int =1'b0;//---------------------sda 0
bitaddrs7=bitaddrs7+1; end
6: begin sda_int =1'b0;//---------------------sda 0
bitaddrs7=bitaddrs7+1; end
7: begin sda_int =1'b0;//---------------------sda=0
bitaddrs7=bitaddrs7+1; end
8: begin sda_int =1'b0;
ack_count=2'b00;
bitaddrs7=bitaddrs7+1; // R/W bit
end
9: begin if(sda==1'b0)
ack[0]=1;
state=RxPointeraddr; // Checking ack
end
endcase
end
//---------------------------------------------------------------------------------
RxPointeraddr:
// Pointer Address 000000-00(P1P0) for temperature register
begin
case(I2C_counter)
//---------------------sda = 0
0: begin sda_int =1'b0;
I2C_counter=I2C_counter+1;end
//---------------------sda = 0
1: begin sda_int =1'b0;
I2C_counter=I2C_counter+1;end
//---------------------sda = 0
2: begin sda_int =1'b0;
I2C_counter=I2C_counter+1; end
//---------------------sda = 0
3: begin sda_int =1'b0;
I2C_counter=I2C_counter+1; end
//---------------------sda = 0
4: begin sda_int =1'b0;
I2C_counter=I2C_counter+1;end
//---------------------sda = 0
5: begin sda_int =1'b0;
I2C_counter=I2C_counter+1;end
//---------------------sda = 0
6: begin sda_int =1'b0;
I2C_counter=I2C_counter+1;end
//---------------------sda = 0
7: begin sda_int =1'b0;
ack_count=2'b01;
I2C_counter=I2C_counter+1;end
8: begin if(sda==1'b0)
ack[1]=1'b0; state=Rxstart1;end // after pointer register sda line acknoledged by a low pulse
endcase
end
//-----------------------------------start+ slave address byte---------------------
Rxstart1:
begin
case(slaveaddrs)
// initial frame 1001000 Initializing slave address including start (case 0
0: begin sda_int=1'b0;
slaveaddrs=slaveaddrs+1; end
1: begin sda_int =1'b1;//---------------------sda 1
slaveaddrs=slaveaddrs+1; end
2: begin sda_int =1'b0;//---------------------sda 0
slaveaddrs=slaveaddrs+1; end
3: begin sda_int =1'b0;//---------------------sda 0
slaveaddrs=slaveaddrs+1; end
4: begin sda_int =1'b1;//---------------------sda 1
slaveaddrs=slaveaddrs+1; end
5: begin sda_int =1'b0;//---------------------sda 0
slaveaddrs=slaveaddrs+1; end
6: begin sda_int =1'b0;//---------------------sda 0
slaveaddrs=slaveaddrs+1; end
7: begin sda_int =1'b0;//---------------------sda=0
slaveaddrs=slaveaddrs+1; end
8: begin sda_int =1'b1;
slaveaddrs=slaveaddrs+1; // R/W bit high
ack_count=2'b10; end
9: begin if(sda==1'b0)
ack[2]=1;
state=Rxdata; // Checking ack
end
endcase
end
//----------------------------------Receiving Temperature Data --------------------------
Rxdata:
begin
case(Rxcount)
0: begin outreg[15]=sda;
Rxcount=Rxcount+1;end
1: begin outreg[14]=sda;
Rxcount=Rxcount+1;end
2: begin outreg[13]=sda;
Rxcount=Rxcount+1;end
3: begin outreg[12]=sda;
Rxcount=Rxcount+1;end
4: begin outreg[11]=sda;
Rxcount=Rxcount+1;end
5: begin outreg[10]=sda;
Rxcount=Rxcount+1;end
6: begin outreg[9]=sda;
Rxcount=Rxcount+1;end
7: begin outreg[8]=sda;
Rxcount=Rxcount+1;
ack_count=2'b11; end
// low pulse acknoledgment from TMP100
8: begin outreg[7]=sda;
if(!sda) ack[2]=1;
Rxcount=Rxcount+1;end
9: begin outreg[6]=sda ;
Rxcount=Rxcount+1;end
10: begin outreg[5]=sda ;
Rxcount=Rxcount+1;end
11: begin outreg[4]=sda;
Rxcount=Rxcount+1;end
12: begin outreg[3]=sda;
Rxcount=Rxcount+1;end
13: begin outreg[2]=sda;
Rxcount=Rxcount+1;end
14: begin outreg[1]=sda;
Rxcount=Rxcount+1;end
15: begin sda_int=1'b0;
// checking low pulse acknoledge frm TMP 100
state=Rxstop; end
endcase
end
//-----------------------------------------------------------------------------------------
Rxstop:
begin chk=1; sda_int=1'b1; end
endcase
end
endmodule