小弟写了一个操作WC24C08的代码,经检测发现从机无应答,望高手指教
不胜感激
module i2c_controller_top(clk,rst,scl,sda,dout);
input clk,rst;
//input [7:0]din;
output scl;
inout sda;
//input wr,rd;
output[7:0] dout;
parameter[19:0] start_a=20'b0000_0000_0000_0000_0001;
parameter[19:0] start_b=20'b0000_0000_0000_0000_0010;
parameter[19:0] start_c=20'b0000_0000_0000_0000_0100;
parameter[19:0] start_d=20'b0000_0000_0000_0000_1000;
parameter[19:0] stop_a=20'b0000_0000_0000_0001_0000;
parameter[19:0] stop_b=20'b0000_0000_0000_0010_0000;
parameter[19:0] stop_c=20'b0000_0000_0000_0100_0000;
parameter[19:0] stop_d=20'b0000_0000_0000_1000_0000;
parameter[19:0] write_a=20'b0000_0000_0001_0000_0000;
parameter[19:0] write_b=20'b0000_0000_0010_0000_0000;
parameter[19:0] write_c=20'b0000_0000_0100_0000_0000;
parameter[19:0] write_d=20'b0000_0000_1000_0000_0000;
parameter[19:0] read_a=20'b0000_0001_0000_0000_0000;
parameter[19:0] read_b=20'b0000_0010_0000_0000_0000;
parameter[19:0] read_c=20'b0000_0100_0000_0000_0000;
parameter[19:0] read_d=20'b0000_1000_0000_0000_0000;
parameter[19:0] ack_a=20'b0001_0000_0000_0000_0000;
parameter[19:0] ack_b=20'b0010_0000_1000_0000_0000;
parameter[19:0] ack_c=20'b0001_0000_0000_0000_0001;
parameter[19:0] ack_d=20'b0010_0000_1000_0000_0010;
parameter[19:0] idle=20'b0100_0000_1000_0000_0000;
//parameter ack_d=1000_0000_1000_0000_0000;
reg[7:0]clk_cnt;
reg[3:0]dcnt;
reg[19:0] state;
//reg clk_en;
reg sda_buf;
reg[1:0] cmd=0;
reg link;
reg rw=0;
reg scl;
reg[7:0] dout;
reg[7:0] din;
reg[6:0] cnt;
wire dcnt_done;
wire clk_en;
wire sda;
wire cnt_en=clk_cnt[6]&clk_cnt[5]&clk_cnt[4]&clk_cnt[3]&clk_cnt[2]&clk_cnt[1]&clk_cnt[0];
assign dcnt_done=~|dcnt;
//assign din=8'h0f;
assign clk_en=&clk_cnt;
assign sda=link?1'bz:sda_buf;
//assign go=wr^rd;
always@(posedge clk or negedge rst )begin
if(!rst)begin
clk_cnt<=8'd0;
//clk_en<=0;
end
else if(clk_en)begin
clk_cnt<=8'd0;
//clk_en<=0;
end
else clk_cnt<=clk_cnt+8'd1;
end
always@(posedge clk or negedge rst)begin
if(!rst)begin
sda_buf<=1;
scl<=1;
state<=idle;
dcnt<=0;
end
else if(clk_en) begin
case(state)
idle: begin
//sda_buf<=din;
//rw<=~rw;
dcnt<=4'd7;
cmd<=0;
link<=0;
sda_buf<=1;
scl<=1;
//if(go)
state<=start_a;
//else state<=idle;
end
start_a: begin
sda_buf<=1;
scl<=1;
state<=start_b;
end
start_b: begin
sda_buf<=0;
scl<=1;
state<=start_c;
end
start_c: begin
sda_buf<=0;
scl<=0;
state<=start_d;
end
start_d: begin
sda_buf<=0;
scl<=0;
if(rw==0)begin
state<=write_a;
/*if(cmd==0)
din<=8'ha0;
else if(cmd==1)
din<=8'd3;
else if(cmd==2)begin
cmd<=0;
//sda_buf<=din;
din<=8'h0f;
end*/
end
else begin
//state<=read_a;
if(cmd==3)begin
state<=read_a;
//cmd<=0;
end
else state<=write_a;
end
end
write_a: begin
if(cmd==0)
din=8'ha0;
else if(cmd==1)
din=8'd3;
else if(cmd==2)begin
if(rw==0) din=8'h0f;
else din=8'ha1;
end
scl<=0;
link<=0;
state<=write_b;
sda_buf<=din[dcnt];
end
write_b: begin
scl<=1;
sda_buf<=din[dcnt];
state<=write_c;
link<=0;
end
write_c: begin
scl<=1;
sda_buf<=din[dcnt];
state<=write_d;
link<=0;
end
write_d: begin
scl<=0;
link<=0;
dcnt<=dcnt-4'd1;
if(dcnt_done)begin
//link<=1;
sda_buf<=1;
dcnt<=4'd7;
state<=ack_a;
end
else state<=write_a;
end
ack_a: begin
scl<=1;
link<=1;
if(sda==0)begin
if(cmd==2'd2)begin
if(rw==1)
state<=start_a;
else begin state<=write_a; cmd<=0; end
end
cmd<=cmd+2'd1;
state<=write_a;
end
else state<=ack_b;
end
ack_b: begin
scl<=0;
link<=1;
if(sda==0)begin
if(cmd==2'd2)begin
if(rw==1)
state<=start_a;
else begin state<=write_a;cmd<=0;end
end
cmd<=cmd+2'd1;
state<=write_a;
end
else state<=ack_a;
end
read_a: begin
/*if(cmd==0)
din<=8'ha0;
else if(cmd==1)
din<=8'd3;
else if(cmd==2)
din<=8'ha1;
else if(cmd==3) begin
//sda_buf<=din;
cmd<=0;
end*/
scl<=0;
state<=read_b;
link<=1;
dout[dcnt]<=sda;
end
read_b: begin
scl<=1;
dout[dcnt]<=sda;
state<=read_c;
link<=1;
end
read_c: begin
scl=1;
dout[dcnt]<=sda;
state<=read_d;
link<=1;
end
read_d: begin
scl<=0;
dcnt<=dcnt-4'd1;
if(dcnt_done)begin
dcnt<=4'd7;
state<=stop_a;
end
else state<=read_a;
link<=1;
end
stop_a: begin
link<=0;
scl<=1;
sda_buf<=0;
state<=stop_b;
end
stop_b: begin
scl<=1;
sda_buf<=0;
state<=stop_c;
end
stop_c: begin
scl<=1;
sda_buf<=1;
state<=stop_d;
end
stop_d: begin
//scl<=1;
//sda<=1;
if(cmd==3) state<=stop_d;
state<=idle;
rw<=~rw;
end
endcase
end
//end
end
endmodule |