飘渺仙的个人空间 https://blog.eetop.cn/1309847 [收藏] [复制] [分享] [RSS]

空间首页 动态 记录 日志 相册 主题 分享 留言板 个人资料

日志

复位中的隐藏的“惊天陷阱”

已有 5366 次阅读| 2015-10-15 09:00

使用verilog进行时序逻辑设计时,为了保证电路的正常工作,往往会引入复位(rst_n)信号。虽然Steve kilts在《advanced fpga design》的2.4节中详细讨论和分析了复位信号对整个设计的面积和时序所带来的影响。但是作为一个菜鸟级programer or coding farmer对于那些东西还是没有吃透的。为了保证功能小编儿还是在每一个always块语句的开头都加了那么一句:if (!rst_n) out_d<=8d0;在一次实践中小编在某个底层文件upi_sch_curr_blk引入了下面的一段代码:

always @ (posedge clk or negedge rst_n) begin 

    if (!rst_n)                               

        curr_blk <= upi_start_blk ;           

    else if (!upi_conf_ready)                 

        curr_blk <= upi_start_blk ;           

    else if (valid)                           

        curr_blk <= upi_next_blk  ;           

    else                                      

        curr_blk <= curr_blk ;                

end                                           

经过quartus跑完之后发现有报warning,具体如下:“ Warning (13004): Presettable and clearable registers converted to equivalent circuits with latches. Registers power-up to an undefined state, and DEVCLRn places the registers in an undefined state.

令人头疼的是将该warning展开后,其下面还有一大堆子条目,类似如下:“ Warning (13310): Register "upi_sch_curr_blk:mch_curr_blk_80[0].mch_curr_blk_inst|curr_blk[0]" is converted into an equivalent circuit using register "upi_sch_curr_blk: mch_curr_blk_80[0]. mch_curr_blk_inst|curr_blk[0]~_emulated" and latch "upi_sch_curr_blk: mch_curr_blk_80[0]. mch_curr_blk_inst|curr_blk[0]~1"

更为糟糕的是,在小编的顶层文件中,对该模块调用了80次。引用代码如下:

genvar i    ;                                                       

generate                                                            

    for (i=0; i<80; i=i+1) begin:mch_curr_blk_80                    

        upi_sch_curr_blk # (8)                                      

            mch_curr_blk_inst   (                                   

                .clk            (    clk_125m                     ),

                .rst_n          (    rst_n                        ),

                .upi_start_blk  (    upi_stat_blk[8*i+:8]         ),

                .upi_next_blk   (    upi_next_blk_ram_rdd         ),

                .valid          (    ch80_valids[i]               ),

                .upi_conf_ready (    upi_conf_ready[i]            ),

                                                                    

                .curr_blk       (    mux80_in_curr_blks[8*i+:8]   ) 

            );                                                      

    end                                                             

endgenerate                                                         

可想而知,当时的告警信息是多么的密集和令人眼花缭乱。更为糟糕的是,告警显示设计中引入了大量的latch,而这使得时序变的非常的糟糕,在默认1000MHz的约束下,整个时序只能跑到160M.哈哈哈,好在有一大堆的前人遇到过这种情况。小编儿在一个altera的外文论坛上发现了一个类似的例子。在热心网友的回复中,有这样一段话:“I'm having the same problem, it seems Quartus won't start (reset) a register with a value coming from a certain bus or wire with preset or clear. Did you solve this? ”虽然笔者没大明白什么意思,但是笔者似乎也明白了点什么。于是对最底层的设计进行了如下修改。

always @ (posedge clk or negedge rst_n) begin

    if (!rst_n)                              

        curr_blk <= {(BLK_NUM_WITH){1'd0}} ; 

    else if (!upi_conf_ready)                

        curr_blk <= upi_start_blk ;          

    else if (valid)                          

        curr_blk <= upi_next_blk  ;          

    else                                     

        curr_blk <= curr_blk ;               

end                                          

再进行综合时,笔者发现告警没有了。哈哈,又学到了一手:电路复位时,最好将寄存器清零或者赋值某个特定的值,最好不要在复位状态下将某一组总线赋值给寄存器。

    笔者猜测,可能是因为设计中的复位时异步复位,在异步复位状态下对寄存器赋值时可能会被综合其误认为是异步设计,从而又引入锁存器。


点赞

评论 (0 个评论)

facelist

您需要登录后才可以评论 登录 | 注册

  • 关注TA
  • 加好友
  • 联系TA
  • 0

    周排名
  • 0

    月排名
  • 0

    总排名
  • 0

    关注
  • 1

    粉丝
  • 0

    好友
  • 0

    获赞
  • 1

    评论
  • 535

    访问数
关闭

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

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

GMT+8, 2024-4-27 17:03 , Processed in 0.018747 second(s), 6 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
返回顶部