- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
It seems you don't initialize "stopcount" and go out of the s2 state.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
stopcount is initalised at the top. does it need to be defined as zero again? Also, i think it has something to do with msbcount. what do u think?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
i have been playing with my code, however the counts are just so unstable. Any better method you could suggest to get this working efficeintly?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The counters need to be in a clocked process otherwise they'll increment every time a signal in the sensitivity list changes and also you'll find it won't act the same way in hardware.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Do you think putting the counters in their own clk sensitive case statement would help? I hava feeling it wont work. Any strategies you can suggest?
As a side note, i have a master i2c core working on a pic. but im having trouble getting the fpga to send back and ack. Is this the right way to set up linking the pic to the fpga? [input from pic SDA]--------------------[bi-directional to/from audio codec] [input from pic SCL]--------------------[output to audio codec]- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Gee, you are a genious! Thanks for your help, it works well now!
I changed my code a bit though, instead of msbcount and all those case satements I just used a right shift operator and tested bit 7. Only problem now is simulating when SDA is forced low for the acknowledgement. I have tried forcing SDA low at the right point in the waveform, but it doesnt seem to work...anything special i need to do to simulate bi-directional pins?
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page