为什么时序逻辑电路会落后一拍?

1、时序逻辑电路落后一拍?

FPGA初学者可能经常听到一句话:“时序逻辑电路,或者说用 <= 输出的电路会延迟(落后)一个时钟周期。”但在仿真过程中经常会发现不符合这一“定律”的现象–明明是在仿真时序逻辑,怎么输出不会落后一拍?

先来看一个简单的例子:把输入信号用时序逻辑电路寄存两次,即俗称的“打两拍”。Verilog代码如下:

module test(  input 				clk,	//系统时钟;  input				rst,	//系统复位,高电平有效;  input		[1:0]	in,		 output		[1:0]	out 
);reg [1:0]	in_r,in_rr;		//分别打一拍、打两拍assign out = in_rr;always@(posedge clk or posedge rst)begin if(rst)begin in_r <= 2'd0;		//复位初始值in_rr <= 2'd0;		//复位初始值endelse beginin_r <= in;			//输入打一拍in_rr <= in_r;		//输入打两拍end
endendmodule

然后再写个TB文件来仿真一下:

`timescale 1 ns/1 ns  
module tb_test();  //输入输出端口
reg			clk;  
reg			rst;  
reg [1:0]	in;
wire [1:0]	out; //例化被测试模块	
test  u_test (  .clk	(clk),  .rst	(rst),  .in		(in	),   .out	(out)  
);  //生成系统时钟,周期10ns;  
initial begin clk = 1;  forever #5 clk = ~clk;  
end//生成复位信号
initial begin rst = 1;#25;  rst = 0;  
end //生成输入信号(测试激励)
initial beginin = 0; #30;repeat(8)begin			//循环8次;#10  in = in + 1; 	//输入递增1end  $stop;					//停止仿真
endendmodule

这段测试代码的测试逻辑是:在复位完成后,每10ns依次对输入信号in执行+1操作,观察打一拍信号in_r和打两拍信号in_rr的变化。来看下仿真结果:
在这里插入图片描述

  • 输入信号in在每个时钟上升沿递增1,符合预期
  • 信号in_r原本应该落后信号in一个时钟周期,但上图中二者却完全同步,不符合预期!
  • 信号in_rr落后信号in_r一个时钟周期,符合预期

那么,是什么导致仿真结果与预期目的不符?

2、建立时间、保持时间和数据输出延迟

在FPGA设计中所用的底层时序逻辑单元是D触发器(DFF,D Flip-Flop),在理想状况下,可以认为DFF的变化是瞬态的,即输出从0到1或者从1到0,都是在一瞬间完成。但在实际使用中,这种瞬态变化显然不可能存在,所以寄存器的输出必定需要一些时间,而这个时间就是Tco。
在这里插入图片描述
上图是一张DFF的非理想状态下的数据传输示意图,为此需要明确3个概念:

  • Tsu:D端的数据必须在时钟上升沿到来之前的一定时间内就已经保持稳定,该时间被称为D触发器的建立时间(Tsu)。
  • Th:D端的数据必须在时钟上升沿到来之后的一定时间内继续保持稳定,该时间被称为D触发器的保持时间(Th)。
  • Tco:D端的数据不可能会在时钟上升沿出现的那一刻就立即更新到Q端,从时钟的上升沿到D端的数据稳定出现在Q端,也有一个时间,该时间称为寄存器的时钟到输出延迟(Tco)。

上面的概念理解两点即可:

  1. 如果不满足建立时间和保持时间要求,则DFF的输出可能会出现亚稳态,简单理解就是输出容易不正常,会出问题。
  2. 每个时钟上升沿(或下降沿)DFF都会从输入端采集数据并将其更新到输出端,但这个过程需要时间(Tco),所以数据的输出实际上会落后时钟上升沿一些时间。

3、时序逻辑电路落后一个周期的原因

接下来继续分析上面的仿真结果。
在这里插入图片描述

  • 在①处,信号in_r在发生变化,由于Tco的存在,所以in_r从0到1的时间是不会和上升沿同步的,会落后一点点。仿真波形表示的不是很明显,但也用了一个小小的斜坡来表示这一过程。
  • 在①处,信号in_r的变化会落后于上升沿,信号in_rr在①处采集到的值则仍是信号in_r未变化的值,即0。
  • 在②处,信号in_r的变化同上一个时钟①处类似。信号in_r的变化会落后于上升沿,信号in_rr在②处采集到的值则仍是信号in_r未变化的值,即1。

这样理解起来可能还是不够直观,没事,我们把代码做一些小小的改变:

in_r <= #1 in;			//输入打一拍
in_rr <= #1 in_r;		//输入打两拍

只是把输出语句加一个 “#1”,即输出会延迟1ns。聪明的你应该已经看出来了,这就是用来模拟Tco这个概念的。

在这里插入图片描述

继续看仿真结果,是不是一目了然?

  • 在①处,由于Tco的存在,所以in_rr采集到的in_r的值是0,所以in_rr输出也是0,而且输出会落后一个Tco时间(但是由于值相同,所以看不出来)
  • 在②处,由于Tco的存在,所以in_rr采集到的in_r的值是1,所以in_rr输出也是1,而且输出也会落后一个Tco时间

所以现在我们清楚了,时序逻辑电路的输出根本就不会落后一个时钟周期,而只会落后一个Tco时间。二者之所以看上去会落后一个周期,完全是由于前级输出的Tco时间存在,导致后级电路在当前时钟上升沿无法采集到最新值,而只能采集到前级未变化的值!

4、为什么把时序逻辑仿成了组合逻辑?

上面的仿真还有个问题悬而未决,那就是in_r是in被寄存后的信号,为啥没有落后in一个时钟周期?问题出在仿真机制和TB文件中对in的赋值方式上。

在TB中,我们是这么对in赋值的:

#10 in = in + 1; //输入递增1

注意看,用的是阻塞赋值“ = ”,阻塞赋值“ = ”一般用来描述组合逻辑,而非阻塞赋值“ <= "则一般用来描述时序逻辑。

虽然输入信号in是我们构建的一个虚拟向量,但对于被测试模块来说,这个激励仍然被视作是来自于上级模块的输出,所以需要指明它到底是一个组合逻辑的输出值还是一个时序逻辑的输出值。

如果它是用“ = ”来描述的,那它就是来自组合逻辑,而组合逻辑的输出是不与时钟上升沿有关的,它的输出几乎就是瞬时完成的。如果它是用“ <= ”来描述的,那它就是来自时序逻辑,而时序逻辑的输出则会落后时钟上升沿一个Tco时间。

回到上面的仿真结果,由于信号in使用“ = ”来赋值,所以它的每一次更新都几乎与时钟上升沿同步,并不会有Tco时间的存在,每一个上升沿后级的in_r信号都能采集到最新的in值,所以二者并不会有一个周期的延迟。

假如我们把信号in改成“ <= ”这种赋值方式:

#10 in <= in + 1; //输入递增1

那么仿真结果就是这样了:
在这里插入图片描述

这与我们最初料想的一致:打一拍信号in_r落后输入信号in一个时钟周期,打两拍信号in_rr后输入信号两个时钟周期。

如果说还有问题的话,就是输入信号in的变化没有很好的体现Tco时间,所以再修改一下:

#10 in <= #1 in + 1; //输入递增1

在这里插入图片描述

嗯,这样就没问题了。由于采用了“#1”这种赋值方式来模拟Tco的存在,所以你应该再也不会搞错信号在哪个时钟沿采样和哪个时钟沿变化了。

5、总结

  • 时序逻辑电路的输出不是瞬时发生的,而是需要一定的时间,这个时间就是Tco
  • 时序逻辑电路并没有真正意义上的落后一拍,落后一拍的原因是因为Tco的存在,导致在当前时钟上升沿无法采集到最新的值,而只能采集到未变化的值
  • 在仿真时,输入信号尽量用非阻塞赋值“<=”来模拟其来自寄存器的输出,这样的仿真结果更接近实际电路
  • 可以采用“#1”这种赋值方式来模拟Tco的存在,这可以在仿真时带来很大的便利

  • 📣您有任何问题,都可以在评论区和我交流📃!
  • 📣本文由 孤独的单刀 原创,首发于CSDN平台🐵,博客主页:wuzhikai.blog.csdn.net
  • 📣您的支持是我持续创作的最大动力!如果本文对您有帮助,还请多多点赞👍、评论💬和收藏⭐

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/245571.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C#winform上位机开发学习笔记13-串口助手显示系统时间功能添加

1.功能描述 在上位机中显示系统的实时时间 2.代码部分 步骤1&#xff1a;添加文本框控件并设置参数 #此处注意将BackColor颜色修改为非Control&#xff0c;即可正常显示ForeColor颜色&#xff0c;否则该颜色不变&#xff0c;原因暂且不明。 步骤2&#xff1a;添加timer控件…

GC26E31S国产芯片可替代AM26LV31E/TI,适用于马达编码等产品上

众所周知AM26LV31E是一款具有三态输出的四路差分线路驱动器。该驱动器具有15kV ESD&#xff08;HBM和IEC61000-4-2&#xff0c;气隙放电&#xff09;和8kV ESD&#xff08;IEC61000-4-2&#xff0c;接触放电&#xff09;保护。该器件旨在满足TIA /EIA-422-B和ITU建议V.11驱动器…

Dify学习笔记-知识库(六)

1、知识库 大多数语言模型采用较为陈旧的训练数据&#xff0c;并且对每次请求的上下文有长度限制。例如 GPT-3.5 是基于 2021 年的语料进行训练的&#xff0c;且有每次约 4K Token 的限制。这意味着开发者如果想让 AI 应用基于最新的、私有的上下文对话&#xff0c;必须使用类…

SpringCloudConfig+SpringCloudBus+Actuator+Git实现Eureka关键配置属性热更新(全程不重启服务)

文章目录 前言1.痛点2.解决方案3.具体实现3.1搭建热配置服务3.2编写配置文件3.3搭建版本控制仓库3.4Eureka-Client引入以下依赖3.5Eureka-Client微服务编写以下配置bootstrap.yml提前加载3.6分别编写测试Controller3.7测试效果3.8下线场景压测 4.SpringCloudBus优化5.写到最后 …

springboot-mybatis项目

一、后端开发环境搭建 1、File->New->Projet 2选择 Spring Initializr &#xff0c;然后选择默认的 url 点击next 3勾选Spring Web、SQL模板&#xff0c;next 4点击finish&#xff0c;搭建完成 二 数据库 1 新建数据库 2 执行sql建表 SET NAMES utf8mb4; SET FOREIGN…

爬虫js逆向分析——x平台(实现)

爬虫js逆向分析——x平台&#xff08;实现&#xff09; &#xff08;仅供学习&#xff0c;本案例只是分析流程没有账号&#xff09;网址&#xff1a;https://xuexi.chinabett.com/ 1.分析请求包格式 打开控制台&#xff0c;并勾选保存日志&#xff0c;然后点击登录看发送了什…

外贸邮件群发软件有哪些?邮件群发的系统?

外贸邮件群发软件哪个比较好&#xff1f;外贸开发信软件推荐&#xff1f; 对于许多外贸企业来说&#xff0c;邮件营销是一种非常有效的推广方式。那么&#xff0c;外贸邮件群发软件就成为了必备的工具。蜂邮EDM将为你揭秘几款主流的外贸邮件群发软件&#xff0c;助你更好地开展…

linux安装docker(入门一)

环境&#xff1a;centos 7(linux) 网站 官网: https://docs.docker.com/ Docker Hub 网站: https://hub.docker.com/ 容器官方概述 一句话概括容器&#xff1a;容器就是将软件打包成标准化单元&#xff0c;以用于开发、交付和部署。 容器镜像是轻量的、可执行的独立软件包 &…

shell脚本——条件语句与循环语句

目录 一、条件语句 1、test命令测试条件表达式 2、整数数值比较 3、字符串比较 4、逻辑测试&#xff08;短路运算&#xff09; 5、双中括号 二、if语句 1、 分支结构 1.1 单分支结果 1.2 双分支 1.3 多分支 2、case 一、条件语句 条件测试&#xff1a;判断某需求是…

【原神游戏开发日志3】登录和注册有何区别?

版权声明&#xff1a; ● 本文为“优梦创客”原创文章&#xff0c;您可以自由转载&#xff0c;但必须加入完整的版权声明 ● 文章内容不得删减、修改、演绎 ● 本文视频版本&#xff1a;见文末 ● 相关学习资源&#xff1a;见文末 前言 ● 这是我们原神游戏开发日记的第三期 ●…

OpenHarmony—TypeScript到ArkTS约束说明

对象的属性名必须是合法的标识符 规则&#xff1a;arkts-identifiers-as-prop-names 级别&#xff1a;错误 在ArkTS中&#xff0c;对象的属性名不能为数字或字符串。通过属性名访问类的属性&#xff0c;通过数值索引访问数组元素。 TypeScript var x { name: x, 2: 3 };c…

计算机网络 第5章(运输层)

系列文章目录 计算机网络 第1章&#xff08;概述&#xff09; 计算机网络 第2章&#xff08;物理层&#xff09; 计算机网络 第3章&#xff08;数据链路层&#xff09; 计算机网络 第4章&#xff08;网络层&#xff09; 计算机网络 第5章&#xff08;运输层&#xff09; 计算机…

Windows10上使Git Bash支持rsync命令操作步骤

rsync命令是linux上常用的工具之一&#xff0c;用于远程以及本地系统中拷贝/同步文件和文件夹。 Windows Git Bash默认并不支持rsync&#xff0c;如下图所示&#xff1a; 使Git Bash支持rsync命令操作步骤&#xff1a; 1.从https://repo.msys2.org/msys/x86_64/ 下…

Docker镜像的创建

基于现有镜像创建 先用现有镜像创建启动容器 docker run 再进入容器进行内容更新 docker exec -it 最后提交成新的镜像 docker commit 然后将修改后的容器提交为新的镜像&#xff0c;需要使用该容器的 ID 号创建新镜像 进入容器可查看相关性能 基于本地模板创…

测试C#调用OpenCvSharp和ViewFaceCore从摄像头中识别人脸

学习了基于OpenCvSharp获取摄像头数据&#xff0c;同时学习了基于ViewFaceCore的人脸识别用法&#xff0c;将这两者结合即是从摄像头中识别人脸。本文测试测试C#调用OpenCvSharp和ViewFaceCore从摄像头中识别人脸&#xff0c;并进行人脸红框标记。   新建Winform项目&#xf…

如何选择便捷安全的黄金交易平台?

黄金交易平台的介绍 黄金交易平台是一个提供方便、安全的方式进行黄金交易的网上平台。 投资者可以通过这些平台进行黄金的买卖&#xff0c;参与黄金市场的投资活动。 这些平台提供了一个简单易用的界面&#xff0c;让投资者可以方便地进行交易操作。 选择合适的黄金交易平台…

C++ 设计模式之责任链模式

【声明】本题目来源于卡码网&#xff08;卡码网KamaCoder&#xff09; 【提示&#xff1a;如果不想看文字介绍&#xff0c;可以直接跳转到C编码部分】 【设计模式大纲】 【简介】 --什么是责任链模式&#xff08;第21种设计模式&#xff09; 责任链模式是⼀种行为型设计模式&am…

windows下git pull超时,ping不通github

报错 ssh: connect to host github.com port 22: Connection timed out fatal: Could not read from remote repository. Please make sure you have the correct access rights and the repository exists. 解决办法 修改hosts 最后加一行&#xff0c;文件位置&#xff1a;…

redis主从复制薪火相传

一.主从复制 1、是什么 主机数据更新后根据配置和策略&#xff0c; 自动同步到备机的master/slaver机制&#xff0c;Master以写为主&#xff0c;Slave以读为主 2、能干嘛 读写分离&#xff0c;性能扩展&#xff08;主 写 从 读&#xff09; 容…

Vue中使用TypeScript:全面指南和最佳实践

🚀 欢迎来到我的专栏!专注于Vue3的实战总结和开发实践分享,让你轻松驾驭Vue3的奇妙世界! 🌈✨在这里,我将为你呈现最新的Vue3技术趋势,分享独家实用教程,并为你解析开发中的难题。让我们一起深入Vue3的魅力,助力你成为Vue大师! 👨‍💻💡不再徘徊,快来关注…