总是会遇到有写文档中提到,不要生成锁存器。问题是

一: 什么叫锁存器

二 : 为什么不要生成锁存器

三 : 如何避免生成锁存器

好,现在就这三个问题,一一做出解答

一  什么叫锁存器

锁存器(Latch)是一种对脉冲电平敏感的存储单元电路,它们可以在特定输入脉冲电平作用下改变状态。锁存,就是把信号暂存以维持某种电平状态。锁存器的最主要作用是缓存,其次完成高速的控制其与慢速的外设的不同步问题,再其次是解决驱动的问题,最后是解决一个 I/O 口既能输出也能输入的问题。
      我的理解就是一个锁进信号并存储一段时间的电路,简称锁存器。
 
 
    二  为什么不要生成锁存器
      一种说法 : 把该信号的变化暂存起来,待敏感电平列表中的某一个信号变化时再起作用,纯组合逻辑电路不可能作到这一点,综合器会发出警告。综合工具会将Latch优化掉,造成前、后仿真结果不一致。
     第二种说法: 锁存器为电平触发,无效电平锁存,有效电平输入即反应到输出,由于延时不同容易产生毛刺。组合逻辑中数据不需要锁存,需要避免产生锁存器。FPGA资源中木有锁存器,需要触发器加逻辑门构成,消耗逻辑资源较多,但有时为了需要满足一些规范协议,会用到锁存器,总之FPGA用的很少。 而ASIC设计中,由于锁存器构成较简单,传输速度快,用锁存器可以有效提高集成度,所以用的比较多!
 
 
     三   如何避免生成锁存器
一份资料说  在case () 后面加上    //synthesis full_case。代码中//synthesis full_case 是综合命令,告知综合工具case中已是全部列举可能的情况,这样综合后无锁存器。又有人说他在以下代码中加入 //synthesis full_case 没有效果
 
module datadistributor(datain,sel,enable,a,b,c,d);
input datain;
input[:] sel;
input enable;
output a;
output c;
output d;
output b;
reg a,b,c,d;
always @(datain or enable or sel)
begin
if(enable=='b1)
begin
case(sel)
'b00:a<=datain;
'b01:b<=datain;
'b10:c<=datain;
'b11:d<=datain;
default:a<=datain;
endcase
end
else
begin
a<='bz;
b<='bz;
c<='bz;
d<='bz;
end
end
endmodule

这个帖子的结论就是 //synthesis full_case 去除的是没有描述到的case情况所产生的锁存器。所以上述代码中产生的锁存器是无法通过这条简单的语句来消除的,好又有大神提及到

在 always 块的 if..else 语句中如果所列的条件不完整,综合时则会产生锁存器。

  example:
        always @(action) 
          if(action)  out1 <= 1'b1;
        没有考虑到 !action 的情况,默认out1保持不变,这就产生了锁存器。
                优化方法:1.列出 !action 的情况,2.对out1赋初始值
        1.always @(action) 
          if(action)  out1 <= 1'b1;
          else    out1 <= 1'b0;
|
        2.always @(action)  begin
          out <= 1'b0;
          if(action)  out1 <= 1'b1;
          end

满满以为这个我就可以大功告成,总算知道怎么样避免产生锁存器了。于是检查了一下我的代码,发现锁存器好多啊,比如这个

 //pulse_count  and  bit_count
reg [:] pulse_count = 'd0;
reg [:] bit_count = 'd0;
always @ (posedge i2c_clk) begin
if (curr_state == `IDLE) begin
pulse_count <= 'd0;
bit_count <= 'd0;
end else begin
if (pulse_count == 'd4) pulse_count <= 3'd0;
else if ((curr_state != `WAIT) || scl )
pulse_count <= pulse_count + 'd1;
if (((curr_state == `TX) || (curr_state == `RX)) && (pulse_count == 'd4)) begin
if (bit_count == 'd8) bit_count <= 4'd0;
else bit_count <= bit_count + 'd1;
end
end
end

第12行产生的真值表并不全面那么事产生了锁存器吗?这个是李亚民老师的代码

上面那位大神博文我只看了一半,后来才发现下面这么写:

但是,在描述时序逻辑的时候,也通常利用 if 语句的隐式条件对带时钟使能的 D 触发器建模

  example:
        always@(posedge clk, negedge rst_n)  begin
          if(!rst_n)  sum <= 0;
          else if(EN)  sum <= a+b;
        表示在时钟正沿来临时,如果 EN 为 1 ,则将 a+b 的值赋给 sum, 言下之意是如果 EN 为 0, 那么 sum 保持原值不变。这里综合工具会把代码综合成一个带时钟使能的 D 触发器。
 
 
 

结论 : 组合逻辑,有无效状态就会产生锁存器

(补充:看到博文说case 有优先级,可是我记得在特权的书上以及自己做的实验上是看到if  else 有优先级,case是并行处理的啊。当时我记得看的是RTL viewer,是不死后粗糙了点。是不是要去追寻到更底层去验证呢)

关于VerilogHDL生成的锁存器的更多相关文章

  1. FPGA代码设计规范整理

    1.设计中的FIFO.状态机接口需要有异常恢复状态和状态上报机制,格雷码电路防止被综合电路优化掉. a)自行设计的格雷码FIFO(一般用于连续数据流跨时钟域)用Synplify综合时,为了防止被优化需 ...

  2. IC芯片設計

    IC從生產目的上可以分成為通用IC(如CPU,DRAM,接口芯片等)和ASIC(ApplicationSpecificIntegreted Circuit)兩種,ASIC是因應專門用途而生產的IC.  ...

  3. Verilog学习笔记基本语法篇(五)········ 条件语句

    条件语句可以分为if_else语句和case语句两张部分. A)if_else语句 三种表达形式 1) if(表达式)          2)if(表达式)               3)if(表达 ...

  4. verilog 基础知识

    mealy型状态机的下一状态和输出取决于当前状态和当前输入: moore型状态机的下一状态和输出取决于当前状态和当前输入,但其输出仅取决于现在的状态: 基本门原语的输出端口必须写在端口列表的前面,基本 ...

  5. Oracle 11g数据库详解(2)

    FAILED_LOGIN_ATTEMPTS 用于指定连续登陆失败的最大次数 达到最大次数后,用户会被锁定,登陆时提示ORA-28000 UNLIMITED为不限制 精确无误差 是 实时 PASSWOR ...

  6. [整理]一个有关Latch(锁存器)的有趣问题

    起源 今天诳论坛,突然发现了一个有关latch的问题,由于对D Flip-Flop和Latch还有些疑问,就点击了进去,一看果然有些意思,也挺有学习意义的,于是本文就诞生了.喊出口号~Just not ...

  7. VerilogHDL常用的仿真知识

    在描述完电路之后,我们需要进行对代码进行验证,主要是进行功能验证.现在验证大多是基于UVM平台写的systemverilog,然而我并不会sv,不过我会使用verilog进行简单的验证,其实也就是所谓 ...

  8. VerilogHDL可综合设计的注意事项

    可综合的语法已经记录得差不多了,剩下一些遗留的问题,在这里记录一下吧. 一.逻辑设计 (1)组合逻辑设计 下面是一些用Verilog进行组合逻辑设计时的一些注意事项: ①组合逻辑可以得到两种常用的RT ...

  9. 【转载】FPGA 中的latch 锁存器

    以下这篇文章讲述了锁存器的一些概念和注意事项.原文标题及链接: FPGA 中的latch 锁存器 - 快乐至永远上的博客 - 与非博客 - 与网 http://www.eefocus.com/liuy ...

随机推荐

  1. google浏览器的安装

    很简单,命令行下安装命令:apt-get install google-chrome-stable(如安装不成功,输入apt-get -f install进行修复依赖,之后在菜单里就可以看到图标了) ...

  2. 转:CI配置SMARTY

    1.到相应站点下载Smarty的源码包:2.将源码包里面的libs文件夹copy到CI的项目目录下面的libraries文件夹下,并重命名为Smarty:3.在目录 application/libra ...

  3. 解读ECMAScript 6箭头函数

    箭头函数是ECMAScript 6最受关注的更新内容之一.它引入了一种用「箭头」(=>)来定义函数的新语法,它…它碉堡了~.箭头函数与传统的JavaScript函数主要区别在于以下几点: 对 t ...

  4. HDU 3584 Cube

    题目大意:给定一个体积为N*N*N立方体,每个单位小立方体A[x][y][z]里有一个值,初始值全部为0,我们可以对立方体进行一下两种操作: 0表示查询A[x][y][z]的奇偶性 1表示对子立方体的 ...

  5. Java输入输出流(1)

    1.什么是IO Java中I/O操作主要是指使用Java进行输入,输出操作. Java全部的I/O机制都是基于数据流进行输入输出,这些数据流表示了字符或者字节数据的流动序列.Java的I/O流提供了读 ...

  6. 【转】android开发中关于模拟器emulation的常见问题

    [转]android开发中关于模拟器emulation的常见问题 Trouble: 无法启动android模拟器,提示 XDM authorization key matches an existin ...

  7. python中的迭代

    #迭代Python的for循环不仅可以用在list或tuple上,还可以作用在其他可迭代对象上. #list这种数据类型虽然有下标,但很多其他数据类型是没有下标的,但是,只要是可迭代对象,无论有无下标 ...

  8. dict和set的使用

    使用dict和set dict Python内置了字典:dict的支持,dict全称dictionary,在其他语言中也称为map,使用键-值(key-value)存储,具有极快的查找速度. 举个例子 ...

  9. CodeForce 569A

    Time Limit:2000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u   Description Litt ...

  10. linux driver: input子系统

    <韦东山Linux视频第2期_从零写驱动\第13课第1节 输入子系统概念介绍_P.wmv> 本视频对输入子系统的结构进行了详细的剖析,通过本视频,可以了解到input核心包括了设备和han ...