Latch的产生和避免

Latch的产生和避免

designer

designer

FPGA

1 人赞同了该文章

在FPGA设计或者IC设计中,latch是一种对脉冲电平敏感的存储单元路径,可以在特定输入脉冲作用下改变电平。但由于往往设计为同步设计,Latch不可避免的毛刺是不愿意看到的;这种毛刺对下一级电路及时序收敛很不利,因而在设计中需要避免。

关于latch的产生,大多说人首先想到的是由于verilog代码中在if-else结构中缺少else或case结构中缺少default所导致,因此也往往在设计中要求if-else结构和case结构要写完整。但完整的if-else结构或case结构就能完全避免latch的产生么?我们看下列两段代码:

    always @(*)
    begin
    	if(enable)
    		data_out1=ina;
    	else
    		data_out2=ina;
    end

在vivado中进行Synthesis后显示warning:

同样,下述代码综合后也会提示有latch生成:

always @(*)
    begin
    	case(data_in)
    		0:	        out1=1'b1;
    		1,3:		out2=1'b1;
    		2,4,5,6,7: 	out3=1'b1;
    		default: 	out4=1'b1;
    	endcase
    end

上述代码之所以产生latch,个人观点:待赋值变量在个别分支条件下缺少相应赋值,即代码风格的问题。故为避免latch的产生,个人认为应做到如下几点:

1. if-else 和case-default必须配套,也就是出现if 必须出现else与之配套;有case必须在后面写一个default,针对case语句也可以增加综合指令 //synopsys full_case指令省略default语句。

2.在所有条件下,对信号都进行赋值,同时单个always模块尽量只对单一变量进行赋值。

最后就SIRF 2008年面试题为例进行说明

下面哪种写法会产生latch?为什么?

(1)
always @(*)
begin
   if(d)
   a = b;
end
(2)
always @(*)begin
   if(d)
      a = b;
   else
      a = a;
end
(3)
always @ (b or d)
    case(d)
       2’b00: a=b>>1;
       2’b11: c=b>>1;
       default:
       begin
          a=b;
          c=b;
       end
   endcase
(4)
always @(b or d)
 begin
    a = b;
    c = b;
    case (d)
        2’b00: a = b >> 1;
        2’b11: c = b >> 1;
    endcase
 end
(5)
always@(b or d)
 begin
    case (d) //synopsys full_case
        2’b00: a = b >> 1;
        2’b11: c = b >> 1;
    endcase
 end

代码(1)中由于缺少else分支,故而会产生锁存器

代码(2)if-else结构完整但由于为组合逻辑,而组合逻辑要想产生记忆功能,只能综合成锁存器

代码(3)中由于并未在所有情况下对所有信号值赋值故会产生latch

代码(4)中由于在选择语句之前给信号赋一个初值,故不会产生latch。但该种代码风格是按照软件的思维方式书写,故而不推荐使用,针对这种代码风格,针对时序电路也可以应用,下列两种代码综合出的电路没有差别,但不推荐第一种风格

(1)
always @(posedge clk or negedge reset_n)
    begin
        begin
        out1 <= 'd0;
        out2 <= 'd0;
        end
    if (!reset_n)
        begin
        out1 <= 'd0;
        out2 <= 'd0;
        end else if (enable)
        out1 <= in1;
    else
        out2 <= in1;
    end
(2)
always @(posedge clk or negedge reset_n)
    begin
    if (!reset_n)
        begin
        out1 <= 'd0;
        out2 <= 'd0;
        end else if (enable)
        begin
        out1 <= in1;
        out2 <= 'd0;
        end else
        begin
        out1 <= 0;
        out2 <= in1;
        end
    end

综合电路图

代码(5)中虽然有 //synopsys full_case但是依旧并未在所有情况下对所有信号值赋值故会产生latch( //synopsys full_case只能省掉default)。

  • 3
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
LATCH和DFF是数字电路设计中常用的两种存储元件。LATCH是一种逻辑门电路,可以存储一个比特的数据,而DFF是一种触发器,也可以存储一个比特的数据。它们之间有一些区别。 首先,LATCH和DFF在静态时序分析方面有所不同。由于LATCH毛刺敏感,可能会将毛刺锁存住,从而影响下一级电路,因此无法进行静态时序分析。而DFF则没有这个问题,可以进行静态时序分析。\[1\] 其次,在FPGA和ASIC中,LATCH和DFF的使用情况也不同。在ASIC中,使用LATCH可以节省门资源,因此LATCH的集成度比DFF高。而在FPGA中,由于没有标准的LATCH单元,而有DFF单元,因此在FPGA中使用LATCH需要更多的资源来实现。\[2\] 此外,LATCH的写法有四种,包括if_else不完整、case语句不完整、组合逻辑中自己自己赋值以及always块的敏感列表未列全。而为了避免产生LATCH,需要注意完整编写if_else和case语句,并避免在组合逻辑中自己自己赋值,同时在always块中列出完整的敏感列表。\[3\] 综上所述,LATCH和DFF是两种不同的存储元件,它们在静态时序分析、资源利用和写法等方面存在差异。 #### 引用[.reference_title] - *1* *3* [Latch的四种写法及为何要避免产生,以及Latch与DFF的区别?](https://blog.csdn.net/weixin_43755290/article/details/108639774)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [dff与latch的用法和区别](https://blog.csdn.net/kontrox/article/details/19620173)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值