Altera_Forum
Honored Contributor
18 years agoI2C code help
Hello. Im in the stages of designing an I2C interface to the audio codec on my fpga. Its very simple, as im new to verilog and still in debugging stages. One snag is when Im attempting to read certain bits of a parallel input. My code, in state s2, seems alright but it goes unstable in simulation when leaving s2. Can you think of what is wrong, or an alternative way of coding my problem?
module i2c(SCL_io, SDA_io, clk, rst, write);
input write, clk, rst;
output SCL_io;
inout SDA_io;
reg stopcount = 0;
reg bitcount = 0;
reg msbcount = 0;
reg indata = 8'b01001010;
reg SCL,SDA;
reg pres, next;
parameter s0=4'b0000,s1=4'b0001,s2=4'b0010,s3=4'b0011,s4=4'b0100,s5=4'b0101,s6=4'b0110,s7=4'b0111,s8=4'b1000;
always@(posedge clk)
begin
if(rst) pres=s0;
else pres=next;
end
always @ (pres or write or stopcount or msbcount or indata or bitcount)
begin
case (pres)
s0: begin
SDA = 1'b1;
SCL = 1'b1;
if(write) next=s1;
else next=s0;
end
s1: begin
SDA = 1'b0;
SCL = 1'b1;
next=s2;
end
s2: begin
SDA = 1'b0;
SCL = 1'b0;
stopcount <= stopcount + 1;
if(stopcount == 4) next=s8;
else
begin
case (msbcount)
1: begin
if( indata == 1'b1)
next=s5;
else next=s3;
end
2: begin
if( indata == 1'b1)
next=s5;
else next=s3;
end
3: begin
if( indata == 1'b1)
next=s5;
else next=s3;
end
4: begin
if( indata == 1'b1)
next=s5;
else next=s3;
end
5: begin
if( indata == 1'b1)
next=s5;
else next=s3;
end
6: begin
if( indata == 1'b1)
next=s5;
else next=s3;
end
7: begin
if( indata == 1'b1)
next=s5;
else next=s3;
end
8: begin
if( indata == 1'b1)
next=s5;
else next=s3;
end
endcase
end
end
s3: begin
SDA = 1'b0;
SCL = 1'b1;
next=s4;
end
s4: begin
SDA = 1'b0;
SCL = 1'b0;
bitcount <= bitcount+1;
msbcount <= msbcount+1;
if(bitcount == 8) next=s7;
else
begin
case (msbcount)
1: begin
if( indata== 1'b1)
next=s5;
else next=s3;
end
2: begin
if( indata== 1'b1)
next=s5;
else next=s3;
end
3: begin
if( indata== 1'b1)
next=s5;
else next=s3;
end
4: begin
if( indata== 1'b1)
next=s5;
else next=s3;
end
5: begin
if( indata== 1'b1)
next=s5;
else next=s3;
end
6: begin
if( indata== 1'b1)
next=s5;
else next=s3;
end
7: begin
if( indata== 1'b1)
next=s5;
else next=s3;
end
8: begin
if( indata== 1'b1)
next=s5;
else next=s3;
end
endcase
end
end
s5: begin
SDA = 1'b1;
SCL = 1'b1;
next=s6;
end
s6: begin
SDA = 1'b1;
SCL = 1'b0;
bitcount <= bitcount+1;
msbcount <= msbcount+1;
if(bitcount == 8) next=s7;
else
begin
case (msbcount)
1: begin
if( indata== 1'b1)
next=s5;
else next=s3;
end
2: begin
if( indata== 1'b1)
next=s5;
else next=s3;
end
3: begin
if( indata== 1'b1)
next=s5;
else next=s3;
end
4: begin
if( indata== 1'b1)
next=s5;
else next=s3;
end
5: begin
if( indata== 1'b1)
next=s5;
else next=s3;
end
6: begin
if( indata== 1'b1)
next=s5;
else next=s3;
end
7: begin
if( indata== 1'b1)
next=s5;
else next=s3;
end
8: begin
if( indata== 1'b1)
next=s5;
else next=s3;
end
endcase
end
end
s7: begin
SDA = 1'b1;
SCL = 1'b1;
if(~SDA) next=s2;
else next=s7;
next=s2;
end
s8: begin
SDA = 1'b1;
SCL = 1'b0;
next=s0;
end
endcase
end
assign SDA_io = SDA;
assign SCL_io = SCL;
endmodule