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

总结了一下本人项目中遇到的类似问题, 大家如果遇到可以从以下方面着手检查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是要编程靠程序自动发现的!!

业务联系请加个人微信号:jack_eetop 或 QQ:228265511

全力打造中国电子工程师微信第一品牌!

(0)

相关推荐

  • 电力电子FPGA仿真技术浅析

    扫取二维码获取

  • 三菱PLC之置位SET复位RST的功能及拓展仿真实验

    三菱PLC之置位SET复位RST的功能及拓展仿真实验

  • 【精品博文】从零开始学FPGA系列练习一:计数器设计

    啦啦啦,我又开始写博客了,希望这次能一直坚持下去,养成总结的好习惯脉冲功能描述:当收到en=1时,dout产生一个宽度为10的高电平脉冲.信号列表:信号名I\O位宽clkI1enI1doutO1波形图 ...

  • 【精选博文】勇敢的芯伴你玩转Altera FPGA:3-8译码器实验

    所谓3-8译码器,大家可以baidu或bing一下.相信学习FPGA的读者一定都上过数字电路的课程,所以这里对3-8译码器功能的实现给个真值表,如表8.1所示,一目了然. 表8.1 3-8译码器真值表 ...

  • 【Verilog】阻塞和非阻塞赋值引申出的原则分析

    参考来源:<Verilog数字系统设计(夏宇闻)> 在介绍<[Verilog]深入理解阻塞和非阻塞赋值的不同>时得到下面几个原则: 原则1:时序电路建模时,用非阻塞赋值. 原则 ...

  • 【精品博文】xilinx和altera学习FPGA好方法

    学几年fpga也是学的一坨屎,是因为你没遇到好的人给你带路,也没有好的公司给你练习. xilinx的FPGA学习方法,一个是芯片手册,XILINX的芯片手册不太好搜索,现在有专门的软件DOCnav的, ...

  • 高级FPGA设计技巧!多时钟域和异步信号处理解决方案

    有一个有趣的现象,众多数字设计特别是与FPGA设计相关的教科书都特别强调整个设计最好采用唯一的时钟域.换句话说,只有一个独立的网络可以驱动一个设计中所有触发器的时钟端口.虽然这样可以简化时序分析以及减 ...

  • 听大神聊FPGA设计:豁然开朗

    FPGA是可编程芯片,因此FPGA的设计方法包括硬件设计和软件设计两部分.硬件包括FPGA芯片电路.存储器.输入输出接口电路以及其他设备,软件即是相应的HDL程序以及最新才流行的嵌入式C程序. 目前微 ...

  • Keil的软件仿真和硬件仿真

    一.软件仿真 Keil有很强大的软件仿真功能,通过软件仿真可以发现很多将要出现的问题,Keil的仿真可以查看很多硬件相关的寄存器,通过观察这些寄存器值的变化可以知道代码有没有正常运行.这样可以避免频繁 ...

  • 谈谈Xilinx FPGA设计的实现过程

    绪论 FPGA编译流程是指将一个FPGA设计从普通RTL描述转换为比特流所需要的一系列步骤.编译流程的顺序会有所不同,这取决于所使用的工具.然而,任何Xilinx FPGA的编译都将包含8个基本步骤: ...

  • 无招胜有招-Vivado非工程模式下的FPGA设计流程

    参考:UG892 UG835Vivado集成开发工具为设计者提供了非工程模式下的FPGA设计流程.在Vivado非工程模式下,FPGA开发人员可以更加灵活地对设计过程的每个阶段进行控制,从而进一步提高 ...

  • FPGA设计之时序约束

    约束流程 说到FPGA时序约束的流程,不同的公司可能有些不一样.反正条条大路通罗马,找到一种适合自己的就行了.从系统上来看,同步时序约束可以分为系统同步与源同步两大类.简单点来说,系统同步是指FPGA ...

  • FPGA设计EtherCAT主站的方法和常见问题

    作者从事EtherCAT等实时工业网络及运控产品的开发多年.基于FPGA的EtherCAT主站,是不少公司的明智选择.无论是实时性,灵活性,还是性价比均可有很好的保证. 一.基于FPGA的EtherC ...

  • FPGA设计原则总结

    FPGA设计原则总结

  • EETOP倾心奉献:史上最全数字IC&FPGA设计合集!

    ASIC前后端设计经典的细节讲解 ASIC前后端设计经典的细节讲解 干货!ASIC牛人之经典总结 Verilog基本电路设计(包括:时钟域同步.无缝切换. 异步FIFO.去抖滤波) 数字前端及FPGA ...