> 文档中心 > 【Verilog】常见bug之for循环

【Verilog】常见bug之for循环

Debug系列文章,想起哪个坑就把它埋了~

本文分享一个for循环的坑,见过了就别再踩了


在Verilog中,我们一般使用for语句进行循环操作。

假设场景:

        某项目中,前面代码用到了一个二维数组array[3:0][2:0],如果array[i] = 3’b111,就从S0状态跳转S1状态。这时,你想了两秒钟写出了如下代码:

for(i=0;i<4;i=i+1) begin: array_loop    if(array[i] == 3'b111) state <= S1;    else state <= S0;end

        然后,你看了眼代码没有问题,将模块代码整合到工程,编译下载程序到板子上,发现没有实现预期的功能。你就不停抓信号,终于定位到是这个状态机的问题,始终在S0,没有跳转到S1。怎么回事呢,你只得单独对这个模块进行仿真:

 明明条件满足了呀?(array[1] = 3’b111) 但是状态始终在S0呢?

这时,你请教了小组同事,他说:把else屏蔽掉,放到for前面

你试了试:

// ...state <= S0;    for(i=0;i<4;i=i+1) begin: array_loop if(array[i] == 3'b111)     state <= S1; //else     //state <= S0;end

又跑了仿真:

 呀,真的可以!

        这时候回过头再来想想for循环:for会在一个时钟周期循环完,那么它的最终结果呢?不就是最后一次循环变量时运行的结果。对应到上面代码,当i=1时,arrar[1] = 3’b111,满足条件;但是for会继续循环,最终变量为i=3,array[3] = 3’b110,不满足if条件,执行else语句,所以state = S0。如果,某次状态跳转到S1,那也只是恰好最后一个循环满足条件罢了。

        注释掉else语句,将state = S0放至for循环前面,意思就是状态默认为S0,只要当for语句满足条件,即状态跳转至S1。达到预期效果。

        这其实是我们初学Verilog的时候,被要求(组合逻辑)写完整if..else所导致的。也从侧面说明要活学活用。读死书,不如无书。

注:上述是典型的错误示范,正确顺序为: 方案设计——代码实现——仿真验证——上板调试。

        再假设一种场景:一个二维数组保存了某种一一对应的关系。比如A对应a,B对应b;现知道B,需要得到对应的b;这时候你可能想到了for循环来遍历整个二维数组,如果满足条件就将对应值赋值给某个变量。但如果你跟上面代码一样,后面跟了else语句的话,很可能得到错误的结果,除非恰好是最后一个循环满足条件。

后记

        本文只提供一种逻辑上的概念,并非对应实际项目。

        Debug系列文章,想起哪个写哪个,咱们下期见。