ZYNQ学习:Verilog语言心得(五)

编写模块时,遇到了信号仿真变成红色未定态X的问题,经过仔细检查,发现是always块内部编写出现错误,这里进行记录:

错误代码:

    //key_f
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(!sys_rst_n)
            key_f <= 1'b1; 
        if(cnt_L > delay)
            key_f <= 1'b0;
        else if(cnt_H > delay)
            key_f <= 1'b1;
        else 
            key_f <= key_f;
        end

错误波形:

可以看到在达到设置的计数器之前,key_f信号一直是未定状态。

这是由于代码编写时第二个if前面忘记加else导致的。

没有加else导致代码逻辑变成这样:

如果通过复位下降沿或者时钟上升沿,进入了always;

开始判断一下复位信号,如果为低,将key_f信号置为高电平,然后本应退出模块。

但是这里继续运行后面的if,前两项if计数器因为程序刚开始,计数器初值都赋的是0,所以没有进入if,直接进入最后的else;

虽然前面进行了赋值,但是这里还在过程块内,并行执行的过程块并不知道key_f的值,所以右侧是未定状态,在过程块结束后,key_f被赋值两次第一次是1,第二次是未定,以最后一次为准,所以前面全是未定状态。

(关于为什么赋值两次以第二次为准,可以看下一篇测试文章,我现在也不知道结果等下试试)

这里我又测试了一下,加入了更多逻辑,这里已经非常混乱,又加了两行if else

    //key_f
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(!sys_rst_n)
            key_f <= 1'b1; 
        if(cnt_L > delay)
            key_f <= 1'b0;
        else if(cnt_H > delay)
            key_f <= 1'b1;
        else 
            key_f <= key_f;
        if(cnt_L < delay)
            key_f <= 1'b1;
        else
            key_f <= 1'b0;
        end

这样就有可能被赋值三次,所以当加了太多if else之后前面的全都失效了,下面是波形图

把上面的逻辑全部注释掉,结果也是一样的:

    //key_f
    always @(posedge sys_clk or negedge sys_rst_n) begin
        // if(!sys_rst_n)
            // key_f <= 1'b1; 
        // if(cnt_L > delay)
            // key_f <= 1'b0;
        // else if(cnt_H > delay)
            // key_f <= 1'b1;
        // else 
            // key_f <= key_f;
        if(cnt_L < delay)
            key_f <= 1'b1;
        else
            key_f <= 1'b0;
        end

没有任何区别。

总结

1.always块中只写一个{if else if ……else}组合,是合理的,如果写了大量{if else if ……else}组合就会导致赋值非常混乱,前面的很多逻辑就会失效,会带来很多问题

2.在一个always块中,前面对一个变量赋值之后,后面是无法调取变量的最新值的,调取的还是上一次的值,需要注意

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值