微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > FPGA,CPLD和ASIC > verilog的always块内多个if else语句执行顺序问题

verilog的always块内多个if else语句执行顺序问题

时间:10-02 整理:3721RD 点击:
各位达人:verilog的always块内begin 和 end间语句若为阻塞语句赋值,则是顺序执行。若为非阻塞语句赋值,则为并行执行。
但是当一个always块内含有多个if else语句
执行顺序是怎么判断的?
是不是这样: 在一个always@begin end里面
若if else里面的语句是阻塞赋值语句,则是顺序执行,就是先执行了前面的if else语句,执行完了再执行后面的if else语句。
若if else里面的语句是非阻塞赋值语句,则各个if else语句间是并行执行的。
若两个if else 之间还有非阻塞赋值语句,则if else与非阻塞赋值语句都是并行执行的。
这样理解对么?
为了更好的请教大家,大家看下代码,告诉我执行顺序可以么?

  1. always@(posedge clk) begin

  2. if(...) data1 <= data2 else... //第一个if else语句
  3. a <= b;
  4. c <= d;
  5. if(...) data3 <= data4 else... //第二个if else语句

  6. end

复制代码

假设在posedge 时刻
{data1,data2,data3,data4,a,b,c,d}={4‘h1,4'h2,4'h3,4'h4,4'h5,4'h6,4'h7,4'h8}
结果:
{data1,data2,data3,data4,a,b,c,d}={2,2,4,4,6,6,8,8}
其实顺序都是顺序执行的,关键在于阻塞复制和非阻塞复制的“赋值”时刻。

这两个if else语句是先执行前一个,再执行后一个,可以这么理解么?

begin。end是顺序块,运行的时候是先判断一个再判断另外一个,但是更新值得时候都是在有效延更新



   begin and应该不算顺序块吧 和块内具体赋值语句有关~

begin end内部的阻塞或非阻塞都需要满足有效沿才动作,而这两个if else顺序执行和同时执行的结果没影响,是独立的。如果两个if else有对同一个变量做赋值动作,则可以体现出阻塞和非阻塞的差别!

这2个赋值,可能会导致无法综合
或者可以强制综合但有毛刺,并且结果还不可预知(既然竞争就看谁的路径短了,短的先被干掉)

遇到了同样的问题,感觉还是用阻塞性赋值思路比较清晰,一开始用的非阻塞性赋值无法实现功能,后来全变成阻塞性赋值就好了!

小编现在弄明白了吗,求指教!



    两个语句时刻执行的,相当于把两个语句拆开放在两个always @(posedge clk)执行,

学习学习。

always里面的if,else if,else if是顺序执行的吗
always@(posedge clk)   
        begin
                if(q==11)   
                        m<=0;
                else if(q==10)
                begin
                        if(m<3)   
                                y<=0;
                        else
                                y<=1;
                end
                else if(xx==1)
                        m<=m+3'b1;
        end
这里面的顺序是怎样的?


时序逻辑全部用非阻塞幅值,组合逻辑阻塞。



   十楼是正确的,没有先后顺序了,是独立的,相当于两个选择器



  无论哪种情况只会执行一条语句,何来顺序和并行?



反了。


改过了,误人子弟啊,知道咋用名字搞错了

一个always里只给一个变量赋值,如果有多个的,拆开写。多个变量在一个always里描述就是一个烂coding,不要去浪费时间去扯谁先谁后了,特别是if/else条件不一样时各个变量赋值不一样的情况,把自己都搞混淆了。简洁明了准确才是coding的目标。

begin  end 之间的代码是串行执行的,begin end间的<=也是串行执行的,比如:
begin
  a <= b;
  a <= c;
  d <= a;
end
最后a<=c起作用,a<=b相当于没起作用,是串行。a最后的值是c,而不是x(如果是并行,因为多驱动,值会是x)。
只不过赋给d的是a的老值,而不是c,这(非阻塞赋值)是用串行模拟并行的一种方法。但这并不是说begin end间的<=是并行,begin end间的代码是串行的,fork join间的是并行。多个always和initial间是并行。

@杰克淡定:这个小编说的比较好。写出来的代码容易看懂才是好代码。如果需要控制两个变量赋值我认为可以写两个always模块,这样代码简单易懂。个人意见,如有不对还请大神指出。

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top