芯路恒电子技术论坛

 找回密码
 立即注册
热搜: 合集
查看: 9652|回复: 8

小弟改了两天也不知道哪错了,求大佬指点指点

[复制链接]

该用户从未签到

2

主题

5

帖子

88

积分

初级会员

Rank: 3Rank: 3

积分
88
发表于 2020-4-20 14:14:10 | 显示全部楼层 |阅读模式
module i2c(clk,rst_n,cmd,go,rx_data,tx_data,scl,sda,sda_a,trans_done);

input clk;
input rst_n;
input [5:0]cmd;
input go;
output reg [7:0]rx_data;
input [7:0]tx_data;
output reg scl;
inout sda;
output reg sda_a;
output reg trans_done;



reg[6:0]cnt1;
reg[6:0]state;
reg en_cnt1;
reg aoe;
reg[4:0]cnt;


parameter sys_clock=50000000;
parameter scl_clock=400000;
localparam scl_cnt_m=sys_clock/scl_clock/2;

localparam
start1=6'b000001,
wr1=6'b000010,
ra1=6'b000100,
ack1=6'b001000,
noack1=6'b010000,
stop1=6'b100000;

localparam
idle=7'b0000001,
gen_sta=7'b0000010,
wr_data=7'b0000100,
rd_data=7'b0001000,
check_ack=7'b0010000,
gen_nck=7'b0100000,
gen_sto=7'b1000000;

assign sda=aoe?sda_a:1'bz;

always@(posedge clk or negedge rst_n)
if(!rst_n)begin
cnt1<=7'b0;
end
else if(en_cnt1)begin
if(cnt1==scl_cnt_m)
cnt1<=7'b0;
else
cnt1<=cnt1+1'b1;
end

always@(posedge clk or negedge rst_n)
if(!rst_n)begin
scl<=1'b1;
end
else if(en_cnt1)begin
if(cnt1==7'b0)
scl<=1'b1;
else if(cnt1==scl_cnt_m)
scl<=1'b0;
else
scl<=scl;
end



always@(posedge clk or negedge rst_n)
if(!rst_n)begin
state<=idle;
sda_a<=1'b1;
aoe<=1'b0;
end

else begin
case(state)
idle:begin
trans_done<=1'b0;
if(go)begin
en_cnt1<=1'b1;
if(cmd & start1)
state<=gen_sta;
else if(cmd & wr1)
state<=wr_data;
else if(cmd & ra1)
state<=rd_data;
end
else
state<=idle;
en_cnt1<=1'b0;
end

gen_sta:begin


if(scl_cnt_m)begin
if(cnt==5'd3)
cnt<=5'd0;
else
cnt<=cnt+1'b1;
end
case(cnt)
0:begin sda_a<=1;  aoe<=1'b0; end   
1:begin scl<=1'b1;end
2:begin sda_a<=0;  scl<=1'b1;end
3:begin scl<=1'b0;end
default:begin sda_a<=1'b1;scl<=1'b1;end
endcase
if(cnt==3)begin
if(cmd & wr1)
state<=wr_data;
else if(cmd & ra1)
state<=rd_data;
end
else
state<=gen_sta;
end

wr_data:begin
if(cnt==5'd31)
cnt<=5'd0;
else
cnt<=cnt+1'b1;
case(cnt)
0,4,8,12,16,20,24,28:begin sda_a<=tx_data[7:0];  aoe<=1'b1; end   
1,5,9,13,17,21,25,29:begin scl<=1'b1;end
2,6,10,14,18,22,26,30:begin sda_a<=0;  scl<=1'b1;end
3,7,11,15,19,23,27,31:begin scl<=1'b0;end
default:begin sda_a<=1'b1;scl<=1'b1;end
endcase
if(cnt==5'd3)begin
if(cmd & ack1)
state<=check_ack;
end
else
state<=wr_data;
end

check_ack:begin
if(scl_cnt_m)begin
if(cnt==5'd3)
cnt<=5'd0;
else
cnt<=cnt+1'b1;
end
case(cnt)
0:begin
scl<=1'b0;
aoe<=1'b1;
if(cmd & ack1)
sda_a<=1'b0;
else if(cmd & noack1)
sda_a<=1'b1;
end   
1:begin scl<=1'b1;end
2:begin sda_a<=0;  scl<=1'b1;end
3:begin scl<=1'b0;end
default:begin sda_a<=1'b1;scl<=1'b1;end
endcase
if(cnt==5'd3)begin
if(cmd & stop1)
state<=gen_sto;
trans_done<=1'b1;
end
else
state<=check_ack;
trans_done<=1'b0;
end


rd_data:begin
if(cnt==5'd31)
cnt<=5'd0;
else
cnt<=cnt+1'b1;
case(cnt)
0,4,8,12,16,20,24,28:begin scl<=1'b0;  aoe<=1'b0; end   
1,5,9,13,17,21,25,29:begin scl<=1'b1;end
2,6,10,14,18,22,26,30:begin rx_data<={rx_data[6:0],sda_a}; scl<=1'b1;end
3,7,11,15,19,23,27,31:begin scl<=1'b0;end
default: begin sda_a<=1'b1;scl<=1'b0;end
endcase
if(cnt==5'd3)begin
if(cmd & noack1)
state<=gen_nck;
end
else
state<=rd_data;
end

gen_nck:begin
if(scl_cnt_m)begin
if(cnt==5'd3)
cnt<=5'd0;
else
cnt<=cnt+1'b1;
end
case(cnt)
0:begin
scl<=1'b0;
aoe<=1'b1;
if(cmd & ack1)
sda_a<=1'b0;
else if(cmd & noack1)
sda_a<=1'b1;
else
sda_a<=sda_a;
end

1:begin scl<=1'b1;end
2:begin sda_a<=0;  scl<=1'b1;end
3:begin scl<=1'b0;end
default:begin sda_a<=1'b1;scl<=1'b1;end
endcase
if(cnt==5'd3)begin
if(cmd & stop1)
state<=gen_sto;
trans_done<=1'b1;
end
else
state<=gen_nck;
trans_done<=1'b0;
end

gen_sto:begin
state<=idle;
end

endcase
end


endmodule






QQ截图20200420141043.png
回复

使用道具 举报

  • TA的每日心情
    萌哒
    2021-12-9 09:57
  • 0

    主题

    6

    帖子

    873

    积分

    高级会员

    Rank: 6Rank: 6

    积分
    873
    发表于 2020-4-20 17:40:58 | 显示全部楼层
    huwenbao 发表于 2020-4-20 17:26
    懂了,我第二个是内部产生的驱动时钟,然后第3个模块要引用该时钟,就把第3个always@(posedge scl
    or r ...

    要把scl换成clk_1----------------------------------------------------------------------------------------------------------------------------------------------------------
    回复 支持 1 反对 0

    使用道具 举报

  • TA的每日心情
    萌哒
    2021-12-9 09:57
  • 0

    主题

    6

    帖子

    873

    积分

    高级会员

    Rank: 6Rank: 6

    积分
    873
    发表于 2020-4-20 15:25:24 | 显示全部楼层
    你的问题在于 scl重复赋值了。

    第二个 always 和第三个 always 都在给scl赋值。

    所以,你的语法是错误的。你可以将 第二个 always块删除,就正确了。
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    2

    主题

    5

    帖子

    88

    积分

    初级会员

    Rank: 3Rank: 3

    积分
    88
     楼主| 发表于 2020-4-20 16:15:42 | 显示全部楼层
    韩新 发表于 2020-4-20 15:25
    你的问题在于 scl重复赋值了。

    第二个 always 和第三个 always 都在给scl赋值。

    但是我第二个always块是产生i2c的工作时钟,删了它那不没了工作时钟
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    萌哒
    2021-12-9 09:57
  • 0

    主题

    6

    帖子

    873

    积分

    高级会员

    Rank: 6Rank: 6

    积分
    873
    发表于 2020-4-20 16:35:21 | 显示全部楼层
    本帖最后由 韩新 于 2020-4-20 16:44 编辑

    你的时钟不是在第三个 always块中产生了么?-----------------------------------------------------------------------------------------------------------------------------------
    12.png
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    萌哒
    2021-12-9 09:57
  • 0

    主题

    6

    帖子

    873

    积分

    高级会员

    Rank: 6Rank: 6

    积分
    873
    发表于 2020-4-20 16:41:27 | 显示全部楼层
    i2c驱动时钟和i2c的时钟是俩回事---------------------------------------------------------------------------------------------------------------------------------
    1.png
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    萌哒
    2021-12-9 09:57
  • 0

    主题

    6

    帖子

    873

    积分

    高级会员

    Rank: 6Rank: 6

    积分
    873
    发表于 2020-4-20 17:06:43 | 显示全部楼层
    你的第二个模块是产生模块内的驱动时钟(clk_1),而这个时钟是要放到第三个always 块内 always @(posedge clk_1  or negedge rst)
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    2

    主题

    5

    帖子

    88

    积分

    初级会员

    Rank: 3Rank: 3

    积分
    88
     楼主| 发表于 2020-4-20 17:26:58 | 显示全部楼层
    韩新 发表于 2020-4-20 17:06
    你的第二个模块是产生模块内的驱动时钟(clk_1),而这个时钟是要放到第三个always 块内 always @(posedge ...

    懂了,我第二个是内部产生的驱动时钟,然后第3个模块要引用该时钟,就把第3个always@(posedge scl
    or rst_n)就可以了吧
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    2

    主题

    5

    帖子

    88

    积分

    初级会员

    Rank: 3Rank: 3

    积分
    88
     楼主| 发表于 2020-4-20 19:02:57 | 显示全部楼层
    是这样改吗,我这个驱动时钟要做为第3个模块的时钟..................
    QQ截图20200420190047.png
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|小黑屋|Archiver|芯路恒电子技术论坛 |鄂ICP备2021003648号

    GMT+8, 2024-4-27 09:51 , Processed in 0.125203 second(s), 36 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc. Template By 【未来科技】【 www.wekei.cn 】

    快速回复 返回顶部 返回列表