当前位置: 首页 > news >正文

FPGA设计中锁存器产生、避免与消除

FPGA设计中锁存器产生、避免与消除

  • 一、锁存器的产生
    • 1.1 组合逻辑中使用保持状态
    • 1.2 组合逻辑中的if-else语句或case语句未列出所有可能性
    • 1.3 小结
  • 二、锁存器的避免
  • 三、锁存器的消除
    • 3.1 情况一

一、锁存器的产生

  锁存器的产生主要有以下两种情况:(1)组合逻辑中使用保持状态;(2)组合逻辑中的if-else语句或case语句未列出所有可能性;

1.1 组合逻辑中使用保持状态

assign data_out = valid ? data_in : data_out; //变量保持当前值
always @(*) beginif(valid)data_out = data_in;elsedata_out = data_out; //变量保持当前值
end

1.2 组合逻辑中的if-else语句或case语句未列出所有可能性

  对于组合逻辑中,如果使用if-else语句,未补全else语句,则默认在其他条件下,数据均保持为原来的状态,那么也会产生锁存器。

//if-else语句缺少else
always @(*) beginif(valid)data_out = data_in;
end

  而如果在组合逻辑中使用case语句,未列出case中条件所有的可能性,则相当于对于未列出的那些情况,数据均保持为原来的状态,也会产生锁存器。

//case语句未列出所有可能性
always @(*) begincase(sel)2'b00: data_out = 2'b00;2'b01: data_out = data_in;endcase
end

1.3 小结

  那么,总而言之,言而总之。对于锁存器,其产生的原因可以总结为一点:想要通过组合逻辑保持数据不变。对于组合逻辑的实现,我们可以认为它是用很多门电路搭建而成的,那么,门电路与寄存器不同,其不具有保持当前状态的功能。也就是说,构成当前组合逻辑的电路中任何一个信号发生改变,都会导致输出结果发生改变。如果要通过组合逻辑实现保持数据的不变,那就只能产生锁存器了(可以参考《数字电子技术基础》第五版的SR触发器)。

二、锁存器的避免

  我们知道了锁存器的产生原因,就可以对症下药,在编写Verilog代码时注意编码风格,即可避免锁存器的产生。

(1)在组合逻辑中使用if-else语句时补全else语句

always @(*) beginif(sel)data_out = data_in;elsedata_out = 2'b00;
end

(2)在组合逻辑中使用case语句时,设置默认状态default,并默认状态下的数据进行赋值

always @(*) begincase(sel)xxx: data_out <= 2'b01;xxx: data_out <= data_in;default: data_out = 2'b00;endcase
end

(3)在组合逻辑中,不可一个变量赋值给变量自身

//错误示例
always @(*) beginif(sel)data_out = data_in;elsedata_out = data_out; //变量赋值给变量自身
end//正确示例
always @(*) beginif(sel)data_out = data_in;elsedata_out = 2'b00; //需要赋值一个准确的数值或者其他变量
end

三、锁存器的消除

  在FPGA设计过程中,有可能出现一些情况,必须使用组合逻辑,保证其实时性,且需要保持数据不变,保证其他运算的正确性。那么又该如何处理?

3.1 情况一

  假如我们要实现如下面时序图所示功能,输出data_out在有效信号valid的上升沿处锁存输入data_in的值,那么要如何实现?

在这里插入图片描述

  最开始考虑的是采用时序逻辑进行实现,代码如下。

always @(posedge sys_clk or negedge sys_rst_n) beginif(!sys_rst_n)data_out <= 'd0;else if(valid)data_out <= data_in;elsedata_out <= data_out;
end

  那么,采用时序逻辑实现,会导致延迟一怕,无法在有效信号valid的上升沿锁存数据,如下图所示。
在这里插入图片描述

  于是考虑使用组合逻辑进行实现,代码如下。

assign data_out = valid ? data_in : data_out;

  但是组合逻辑要实现保持状态,必然会产生锁存器。综合后会再Messages界面会警告出现锁存器,同时在Schematic中也可以看到出现了锁存器,如下图所示。而在我们的设计中,我们是不希望出现锁存器的,因为其不利于时序分析。

在这里插入图片描述
在这里插入图片描述

  那么,也可以采用组合逻辑+时序逻辑的方式实现,通过多使用一部分寄存器资源,来实现在valid上升沿处进行数据采样,且不产生锁存器,代码如下。重新综合后,可见锁存器消失,同时可以对齐进行仿真,时序符合前面的要求。

reg     [3:0]    r_data_in;always @(posedge sys_clk or negedge sys_rst_n)if(!sys_rst_n)r_data_in <= 'd0;elser_data_in <= data_in;assign data_out = valid ? data_in ? r_data_in;

在这里插入图片描述

http://www.lryc.cn/news/65552.html

相关文章:

  • 一份标准的软件测试方案模板
  • 【C++】-对于自定义类型的输入输出运算符重载
  • (详解)js中什么是宏任务、微任务?宏任务、微任务有哪些?又是怎么执行的?
  • Okta 即代码:云原生时代的身份管理
  • 数据结构(六)—— 二叉树(7)构建二叉树
  • 安装适用于Linux的Windows11子系统(WSL2)
  • 使用Spring的五大类注解读取和存储Bean
  • Vue3通透教程【十一】初探TypeScript
  • Linux环境安装iperf3(网络性能测试工具)
  • 回顾第一章
  • Jupyter Notebook入门教程
  • 独立按键识别
  • 【论文阅读】AlphaFold2阅读笔记
  • 机器学习基础知识之数据归一化
  • QCC51XX---pydbg_cmd集合
  • camx 马达的MSM_ACTUATOR_WRITE_DAC 操作
  • 【无人机】无人机平台的非移动 GPS 干扰器进行位置估计的多种传感器融合算法的性能分析(Matlab代码实现)
  • 一篇文章搞定《RecyclerView缓存复用机制》
  • Elasticsearch概述
  • 停车场收费系统
  • nodejs+vue+elementui学生毕业生离校系统
  • 儿童用灯哪个品牌好?推荐专业的儿童护眼台灯
  • 探究Android插件化开发的新思路——Shadow插件化框架
  • SimpleDateFormat和DateTimeFormatter的区别及使用详解
  • 边缘人工智能——nanodet模型实践指引,从标注数据集到实现部署文件
  • SASS的用法指南
  • MCSM面板一键搭建我的世界服务器-外网远程联机【内网穿透】
  • ( 数组和矩阵) 565. 数组嵌套 ——【Leetcode每日一题】
  • linux内核网络子系统初探---概述
  • java版工程项目管理系统源代码-功能清单 图文解析