Verilog HDL描述的组合逻辑环在FPGA实现时到底有什么问题?

描述

 

 课堂上给大家介绍代码规范的时候,反复强调不能出现组合逻辑环,具体就是组合逻辑所有的else语句要写全,case语句也要写全,但组合逻辑环到底有什么危害?下面就详细举例说明。

 

01

什么是组合逻辑环?

 

组合逻辑反馈环路是数字同步逻辑设计的大忌,它最容易因振荡、毛刺、时序违规等问题引起整个系统的不稳定和不可靠。 组合逻辑反馈环路是二种高风险的设计方式,主要原因如下:

1.组合反馈环的逻辑功能完全依赖于其反馈环路上组合逻辑的门延时和布线延时等,如果这些传播延时有任何改变,则该组合反馈环单元的整体逻辑功能将彻底改变,而且改变后的逻辑功能很难确定。

 2.组合反馈环的时序分析是无穷循环的时序计算,综合、实现等EDA 工具迫不得已一般必须主动割断其时序路径,以完成相关的时序计算。而不同的EDA工具对组合反馈环的处理方法各不相同,所以组合反馈环的最终实现结果有很多不确定因素。

 3.通常的综合工具在处理组合逻辑反馈问题时,将产生Latch,这将对时序造成许多问题。 

在用Verilog HDL进行可综合电路设计时,有很多情况都有可能产生组合逻辑环。

•在组合逻辑的组合进程中, 条件语句描述时应该指定所有条件下所有输出的状态,以避免锁存。比如if/case语句的所有分支必须定义全部的输出才可能避免出现锁存。

•在设计中,应该尽量避免使用锁存!因为锁存要占去大量的触发器资源,而且会对电路带来某种不稳定的隐患。

 

•所谓的latch,其实质是组合电路中有反馈!反馈的形成是利用到了前一个状态。

 

具体举例如下:

 

FPGA

 

FPGA

 

总结如下:

•组合电路描述中,条件判断语句必须指明所有条件分支情况下,被赋值信号的值。

•分支不完整,意味着电路需要在某种电平状态下,让被赋值的信号“保持原值”,这只能使用锁存电路实现。

 

 

 

02

一个实例

 

设计代码如下:

// **************************************************************

// COPYRIGHT(c)2015, Xidian University

// All rights reserved.

//

// IP LIB INDEX :  

// IP Name      :      

// File name    : 

// Module name  : 

// Full name    :  

//

// Author       : Liu-Huan 

// Email        : assasin9997@163.com 

// Data         : 

// Version      : V 1.0 

// 

// Abstract     : 

// Called by    :  

// 

// Modification history

// -----------------------------------------------------------------

// 

// 

//

// *****************************************************************

 

// *******************

// TIMESCALE

// ******************* 

`timescale 1ns/1ps 

 

// *******************

// INFORMATION

// *******************

//*******************

//DEFINE(s)

//*******************

//`define UDLY 1    //Unit delay, for non-blocking assignments in sequential logic

 

//*******************

//DEFINE MODULE PORT

//*******************

module  TOP   (     

           input    clk ,

           input    rst 

              ) ;

 

//*******************

//DEFINE LOCAL PARAMETER

//*******************

//parameter(s)

parameter IDLE  = 5'b0_0001 ;

parameter S1    = 5'b0_0010 ;

parameter S2    = 5'b0_0100 ;

parameter S3    = 5'b0_1000 ;

parameter S4    = 5'b1_0000 ;       

                

 

//*********************

//INNER SIGNAL DECLARATION

//*********************

//REGS

(* mark_debug = "true" *)reg [4:0] c_state ;

(* mark_debug = "true" *)reg [4:0] n_state ;  

 

reg [3:0] cnt ;

 

(* mark_debug = "true" *) reg [3:0] led ;

//WIRES

 

//*********************

//INSTANTCE MODULE

//*********************

 

//*********************

//MAIN CORE

//********************* 

always @(posedge clk or posedge rst) begin

    if (rst == 1'b1) begin

        cnt <= 4'b0 ;

    end

    else begin

       cnt <= cnt+1'b1 ; 

    end

end

 

// 三段式状态机 验证 第二段 if无else的异常跳转

// 第一段  状态转移

always @(posedge clk or posedge rst) begin

    if (rst == 1'b1) begin

       c_state <= IDLE ; 

    end

    else begin

        c_state <= n_state ;

    end

end

 

// 第二段 计算下一状态

always @ (*) begin

    case ( c_state ) 

        IDLE : begin

            if ( cnt == 'b0 )

                n_state = S1 ;

        end

        S1 : begin

            if ( cnt == 'd2 )

                n_state = S2 ;

        end

        S2 : begin

            if ( cnt == 'd4 )

                n_state = S3 ;

        end

        S3 : begin

            if ( cnt == 'd8 )

                n_state = S4 ;

        end

        S4 : begin

            if ( cnt == 'd15 )

                n_state = IDLE ; 

        end

        default : begin

            n_state = IDLE ;

        end

    endcase

end

 

// 第三段 输出

always @(posedge clk or posedge rst) begin

    if (rst == 1'b1) begin

        led <= 4'b0 ;

    end

    else begin

       case ( n_state ) 

            IDLE : led <= 4'b0 ;

            S1   : led <= 4'd1 ;

            S2   : led <= 4'd2 ;

            S3   : led <= 4'd3 ;

            S4   : led <= 4'd4 ;

            default : begin

              led <= 4'd0 ;  

            end

        endcase 

    end

end

 

endmodule   

 


仿真激励代码如下:

`timescale 1ns / 1ps

//////////////////////////////////////////////////////////////////////////////////

// Company: 

// Engineer: 

// 

// Create Date: 2017/12/11 2030

// Design Name: 

// Module Name: test

// Project Name: 

// Target Devices: 

// Tool Versions: 

// Description: 

// 

// Dependencies: 

// 

// Revision:

// Revision 0.01 - File Created

// Additional Comments:

// 

//////////////////////////////////////////////////////////////////////////////////

module test ;

reg clk ;

reg rst ;

initial begin

    clk = 1'b0 ;

    rst = 1'b1 ;

    # 100 

    rst = 1'b0 ;

end

 

always # 5 clk = ~clk ;

 

TOP  U_TOP   (     

           .clk     (  clk ) ,

           .rst     (  rst ) 

              ) ;

 

endmodule

 


上面组合逻辑环的代码已经用红色字体显示。

 

先看前仿真结果:

FPGA

看不太清?让我们再看一张图。

FPGA

状态跳变正常,n_state[4:0]按照1、2、4、8、16、1......的顺序重复跳变,没有任何问题。

 

但在用FPGA工具(如vivado)进行综合时,会报警告:

 

FPGA

 

但是上板抓取信号,发现状态机异常跳转,如下图所示。

 

FPGA

此时的n_state[4:0]信号跳变状态为:1、2、4、8、9、1......,出现了9这样的一个状态!

 

此时,水落石出!出现组合逻辑环会给电路带来严重问题!

 

而上面的例子是显而易见的,一眼就能看出来,还有一些组合逻辑环,是在写代码时不小心引入的,并且是由多个always模块组成的,这种组合逻辑环在综合的时候也会报warning,必须要修改掉之后才能继续后续工作。否则,等真正上板调试时,规模稍微大点的设计如果要定位到这个错误估计也得花掉好几天的时间,所以代码规范至关重要!

 

 

03

组合逻辑环的好处

 

在实际芯片设计中,也是不允许出现组合逻辑环的。但组合逻辑环能够减少电路逻辑资源,降低电路功耗,具有很多优点。但是其难以被静态时序分析工具分析和计算,且难以生成功能验证向量和自动测试图形向量.针对此问题,很多人都提出了多种组合逻辑环转化方法,以解决硬件描述语言以及高级语言逻辑综合阶段所面临的组合逻辑环拆分问题。


审核编辑 :李倩

 


打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分