整理一下--~~觉得还不错--~~其实latch就是在生成rtl图的时候,意想不到的寄存器,比如说if else或者case语句没有赋值完整,这样会有别的分支存在的时候,会导致一些寄存器会保留前一时刻的值,所以会多出一些寄存器。
例如
always@(posedge clk)
begin
    case(in_s)
    2'b11: out<=2'b11;
    2'b10: out<=2'b10;
    endcase
假如没有default语句的话,当为00或者01 的时候out就会保留前一个时钟的值,也就是hold住,所以rtl图的时候会多出来两个寄存器,专门对应11和10时候的寄存器。
 


有default语句时
always@(posedge clk)
begin
    case(in_s)
    2'b11: out<=2'b11;
    2'b10: out<=2'b10;
    default:out<=2'b00;
    endcase

 

如果变量没有在IF语句的每个分支中进行赋值,将会产生latch。比如:
   always @(*)
           begin
                if(condition)
                   b=a;
           end
这是一个基本的Latch。如果IF的条件中用到算术操作,如下面的例子
    reg condition1[31:0];
    always @(*)
           begin
                if(& condition1)
                   b=a;
           end
   则当condition1的多个位同时变化时,可能& condition1的值在发生变化时会产生一个瞬间的不稳定过程,所以尽量不要使用
算术操作作为条件。在一个好的设计中,condition应该是触发器的输出。

如果一个变量在同一个IF条件分支中先赎值然后读取,则不会产生latch,如下面的例子:
    reg condition;
    reg a;
    always @(*)
           begin:no_latch
                if(condition) begin
                   a=c1;
                   b=a;
                   end
                 else
                   b=c2;  
           end
   上面显然不会产生latch,因为a只是一个中间变量,a的值不必记录下来。
   如果先读取,后赎值,则会产生latch,如下面的例子:
    reg a;
    always @(*)
           begin:has_latch
                if(condition)
                   begin
                   b=a;
                   a=c1;
                   end   
                else
                  b=c2;
           end

    上面会产生latch,因为a的值必须记录下来

有哪些编码会产生latch。我们应该注意哪些情况来避免无谓的latch的出现?
    一切产生latch的情况都是:条件分支写的不完整,包括if...else和case。
    回避latch的最简单的办法是:所有if都带else,所有case都有default。此外,还要尽量使用<=赋值,尽量少使用=。
    有些latch是故意要使用的,有些是必须要避免的。可以通过查看综合器的输出来看哪些代码产生了latch,并相应的修改之。
    在写RTL的时候要做到所有if都带else,所有case都有default,剩下的问题留给综合器。
    Latch对于逻辑行为并无大的危害,倒是对器件的寿命会多少有些影响。
    latch问题是写RTL的基本问题。
    always @(*) 是回避latch的一个好办法。另外,SystemVerilog明确定义了always_ff和always_latch,为什么不用呢?