在线咨询
eetop公众号 创芯大讲堂 创芯人才网
切换到宽版

EETOP 创芯网论坛 (原名:电子顶级开发网)

手机号码,快捷登录

手机号码,快捷登录

找回密码

  登录   注册  

快捷导航
搜帖子
查看: 26904|回复: 54

[原创] 关于FPGA设计仿真和硬件实测不一致问题的讨论

[复制链接]
发表于 2011-10-28 16:05:48 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?注册

x
总结了一下本人项目中遇到的类似问题, 大家如果遇到可以从以下方面着手检查bug.

1.
寄存器未给初值;
一个良好的习惯就是每个寄存器变量都要在reset里面预先定义初值. 看下面一个例子:
reg [1:0] unini;
always@(posedge clk or negedge rst)
begin
     if(~rst)
         ;//未给定初值
     else
     begin
          unini<=2'd1;
   
          if(unini<2'd1)
              a<=b;  
     end
end
这个例子是笔者在做项目的时候真实经历的一个bug的一个简化描述,实际代码比这个要复杂得多,当时也是找了半天最后才发现是寄存器未给初值这个低级错误.

对于上段代码,仿真的时候,在rst之后的第一个clk上升沿,unini是未定态(即modelsim中的红线), 这个未定态是不满足下面unini<2'd1这个条件的,所以这个上升沿后a不会被赋值b; 而在第二个时钟上升沿之后才会满足条件而进行a<=b赋值;

但是在硬件实测的时候,寄存器里面的值一定是要么是1要么是0(一般默认的初值都是0),所以在第一个时钟上升沿就会进行a<=b的赋值,这样就造成了一个仿真结果和实测不符合的bug.


2.阻塞和非阻塞赋值混用.
阻塞和非阻塞赋值在always里面混用是RTL设计的大忌,即便你很了解阻塞和非阻塞的原理,还是可能因为疏忽造成难以发现的bug.看下面一段代码:
always@(posedge clk or negedge rst)
begin
     if(~rst)
     ...
     else
     begin
         if(a)
             c<=1'b1;//很早就将c赋值为1了
         else if(b)
             c=1'b0; //注释1
     end
end

reg state;
always@(posedge clk or negedge rst)
begin
     if(~rst)
         state<=1'b0;
     else
     begin

     case(state)
     1'b0:
     begin
          b<=1'b0;
          if(c)
              state<=1'b1;
          ...
      end
      1'b1:
      begin
      ....
          if(...)
          begin
              state<=1'b0;
              b<=1'b1;
              a<=1'b0;
          end
     end
     endcase
end

以上这段代码也是笔者在真实项目中的一个血的教训,在注释1处错误的使用了阻塞赋值,使得一个bug仿真的时候没有仿出来,实测的时候一个信号一个信号地查才最后定为到这个点.有兴趣的可以仿真一下,如果b在state=1状态时,clk的一个上升沿置1,state会立刻回到0状态.此时在state=0状态时如果a不为1,b为1,那么应该在下一个时钟上升沿之前c保持为1,所以state应该立刻转回1状态. 但是由于之前c=0用了阻塞赋值,在仿真的时候就state就不会转回1.而在实测的时候,虽然用了c=0阻塞赋值,但是仍然按照<=综合(综合软件在这种情况下会把=当做<=处理),
这样就导致了一个本该在仿真阶段暴露的bug未被及时发现.

3.时序收敛问题;
随着FPGA功能越来越强大,时序问题将变得越来越重要. 值得注意的是,以往时序问题往往因为setup time不满足,而随着fpga能跑的越来越快,hold time violation也会越来越多地出现.而hold violation主要解决方法有两种, 首先让信号跑在全局网络上,这样虽然慢,但是信号的skew也小. 其次可以通过插入LCELL等FPGA内延时原件来解决. 虽然时序是个大问题,不过一定要首先在确定功能正确后再着手动时序这快,你会发现绝大部分仿真通过但是实测不过的原因还是代码的功能有问题,而由于一些原因没有仿真到.

4.Multi-cornor Simulation
多种情况下仿真. 现在高端FPGA能做的事情已经很接近大规模的asic电路,而ASIC级别的复杂度的FPGA设计要求的是实测前要进行完备的功能验证.比如码流的长度\样式的多种变化,数据的不同输入速率等多种情况都要进行仿真.笔者极力推荐大家仿真时候尽量用system verilog这种高级仿真语言,其有条件随机激励和assertion等功能可以极大增强代码覆盖率,十分有助于发现那种普通定点看波形仿真发现不到的问题.记住一句话,复杂设计的仿真绝对不能局限在一点一点看波形,绝大多数的bug是要编程靠程序自动发现的!!
发表于 2011-10-28 20:46:23 | 显示全部楼层
这个经验很有价值啊,楼主真是个热心人
发表于 2011-10-28 23:11:51 | 显示全部楼层
楼主真是个热心人
发表于 2011-10-29 12:37:02 | 显示全部楼层
呵呵,仔细想一想
发表于 2011-10-29 23:01:51 | 显示全部楼层
Screenshot.JPG
你好,我仿真了一下,你说的第二个问题,c应该是能够在下一个时钟沿前保持1的吧?
不知道我弄的对不对?
发表于 2011-10-30 07:55:21 | 显示全部楼层
还是以软件的思路来考虑硬件的实现。
发表于 2011-11-4 10:12:21 | 显示全部楼层
学习中,谢谢楼主、、、
发表于 2011-11-4 10:24:16 | 显示全部楼层
最近遇到一个问题,板子热的时候结果就不对,加上风扇吹一会儿就正确了,这问题比较郁闷啊!
发表于 2011-11-11 19:28:51 | 显示全部楼层
set up 时间余量太小
发表于 2011-11-18 09:58:46 | 显示全部楼层
sdwsh说的很多。搂主的代码风格非常糟糕,不严格遵守RTL代码规范,仿真的结果根本不可信!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

站长推荐 上一条 /2 下一条

×

小黑屋| 关于我们| 联系我们| 在线咨询| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2024-4-25 12:58 , Processed in 0.027701 second(s), 6 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
快速回复 返回顶部 返回列表