Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2507052
  • 博文数量: 319
  • 博客积分: 9650
  • 博客等级: 中将
  • 技术积分: 3881
  • 用 户 组: 普通用户
  • 注册时间: 2009-03-27 21:05
文章分类

全部博文(319)

文章存档

2017年(5)

2016年(10)

2015年(3)

2014年(3)

2013年(10)

2012年(26)

2011年(67)

2010年(186)

2009年(9)

分类:

2010-09-07 21:26:56


转自:http://blog.chinaaet.com/detail/9712.html

早期在写代码的时候,常常过分的追求速度和资源,却往往无法顾及到代码的稳定和可靠(即所谓的健壮性)。先拿下面这个简单的计数器代码说事。

reg[9:0] x_cnt;//x坐标计数器

 

always @(posedge clk or negedge rst_n)

    if(!rst_n) x_cnt <= 10'd0;

    else begin

        if(x_cnt == 10'd799) x_cnt <= 9'd0;

        else x_cnt <= x_cnt+1'b1; 

    end

         咋看一下,似乎代码很OK,没太有问题,一般来说,基本上是。如果要钻牛角尖挑刺,那么也很容易:如果x_cnt > 10’d799,是不是这个计数器x_cnt就罢工了?当然。这也许就是问题所在。但是话说回来,这个代码正常运行在常规复位或稳定环境中出问题的概率也是微乎其微(时序未收敛的情况另当别论)。只不过有那么一些极端的情况,比如,异步复位信号来了个毛刺,也就是概率小得可怜的让rst_n违反removal或recovery时序的事件出现了,这时候就可能出现本段开始所说的问题,那么x_cnt就罢工了,指不定系统就崩溃了。

         所以,要让这个代码更健壮一些,改进代码势在必行。

reg[9:0] x_cnt;//x坐标计数器

 

always @(posedge clk or negedge rst_n)

    if(!rst_n) x_cnt <= 10'd0;

    else begin

        if(x_cnt >= 10'd799) x_cnt <= 9'd0;

        else x_cnt <= x_cnt+1'b1; 

    end

 

         话说回来,特权指出这个问题并非空穴来风——乃是事出有因。解决了闪屏的AV图像这回犯上了一个新毛病(也许之前就有,只是注意力不在它):一开始运行时液晶都是实时的随摄像头而动,但是运行到某个时刻(一般是几分钟后)忽然定住了,图像不再变化。量量解码芯片的输出,时钟\同步信号都正常,排除硬件故障;那么问题肯定在FPGA本身,内部的时序是收敛的,IO接口上的VCLK和DB[7:0]时 序也收敛,只不过这上面还可能存一些不可预知的问题,那么问题定位到了外部数据接口的采集,尤其是视频帧的帧头检测上(这里有一个状态机,初步估计是它死 了,那么问题就归结到代码的健壮性上)。于是,仔细搜寻,问题锁定在和开篇提出的代码类似的计数器上,做了一点修改,其后上电验证几个小时问题不再复现。

         VCLK和DB[7:0]锁存数据目前似乎不能完全做到无误码,只不过像上面的问题即便帧检测不完全准确,但却是在人眼所能够觉察的范围之外。尤其在这种环境中,代码的健壮性将会得到体现。但是话说回来,下一版需要采取一些硬件上的措施,以提高这个接口的可靠性。

阅读(2622) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~