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

news2024/11/16 6:34:40

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;		//复位初始值
	end
	else begin
		in_r <= in;			//输入打一拍
		in_rr <= in_r;		//输入打两拍
	end
end
	
endmodule

然后再写个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 begin
	in = 0; 
	#30;
	repeat(8)begin			//循环8次;
		#10  in = in + 1; 	//输入递增1
	end  
	$stop;					//停止仿真
end

endmodule

这段测试代码的测试逻辑是:在复位完成后,每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.coloradmin.cn/o/1411433.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2024年AI全景预测

欢迎来到 2024 年人工智能和技术的可能性之旅。 在这里&#xff0c;每一个预测都是一个潜在的窗口&#xff0c;通向充满创新、变革、更重要的是类似于 1950 年代工业革命的未来。 20 世纪 50 年代见证了数字计算的兴起&#xff0c;重塑了行业和社会规范。 如今&#xff0c;人工…

VR全景如何引爆民宿热潮?

“尔滨”旅游热还未消散&#xff0c;好看的风景、好吃的美食统统安排起来&#xff0c;但是不知道大家出游对住的环境有没有讲究呢&#xff1f;很多人喜欢民宿的原因&#xff0c;就是因为游玩一整天&#xff0c;希望有一个温馨舒适的住处&#xff0c;来缓解身体、精神上的疲劳。…

中仕教育:事业单位考试考什么?

事业单位考试分为两个阶段&#xff0c;分别是笔试和面试&#xff0c;考试科目包括公共科目和专业科目两部分。 公共科目内容是公共基础知识、职业能力测试或申论。一种形式为&#xff1a;公共基础知识职业能力测试或职业能力测试申论。另一种形式为&#xff1a;公共基础申论。…

02-Redis持久化、主从与哨兵架构详解

文章目录 Redis持久化RDB快照&#xff08;snapshot&#xff09;bgsave的写时复制(COW)机制AOF&#xff08;append-only file&#xff09;AOF重写RDB 和 AOF &#xff0c;我应该用哪一个&#xff1f; Redis 4.0 混合持久化Redis数据备份策略&#xff1a; Redis主从架构redis主从…

Kerberos认证过程

Kerberos协议角色组成&#xff1a; Kerberos协议中存在三个角色&#xff0c;分别是&#xff1a; 客户端 (client)&#xff1a;发送请求的一方服务端&#xff08;server&#xff09;接受请求的一方钥匙分发中心(Key distribution KDC) 密钥分发中心又分为两个部分&#xff0…

Leetcode—30. 串联所有单词的子串【困难】

2023每日刷题&#xff08;九十五&#xff09; Leetcode—30. 串联所有单词的子串 实现代码 class Solution { public:vector<int> findSubstring(string s, vector<string>& words) {unordered_map<string, int> raw;// words单词个数int n words.siz…

勒索袭击新方式,提防注册机中注入的勒索病毒!

1 事件概述 近期&#xff0c;用户反馈称自己在使用某款“注册机”软件时候&#xff0c;系统中文件被不行加密。通过对受害用户提供的线索和样本进 行综合分析研判&#xff0c;发现了一款借助破解类工具进行传播的新型勒索软件&#xff0c;其会通过向桌面释放勒索信与收款码图片…

STC89C51单片机

本文为博主 日月同辉&#xff0c;与我共生&#xff0c;csdn原创首发。希望看完后能对你有所帮助&#xff0c;不足之处请指正&#xff01;一起交流学习&#xff0c;共同进步&#xff01; > 发布人&#xff1a;日月同辉,与我共生_单片机-CSDN博客 > 欢迎你为独创博主日月同…

Vue2 props组件通信

一、父组件向子组件传值 1、流程图 2、父组件代码 <template><div class"app"><UserInfo:usernameusername:ageage:isSingleisSingle:carcar:hobbyhobby></UserInfo></div> </template><script> import UserInfo from .…

JavaScript 学习笔记(JS进阶 Day2)

「写在前面」 本文为 b 站黑马程序员 pink 老师 JavaScript 教程的学习笔记。本着自己学习、分享他人的态度&#xff0c;分享学习笔记&#xff0c;希望能对大家有所帮助。推荐先按顺序阅读往期内容&#xff1a; 1. JavaScript 学习笔记&#xff08;Day1&#xff09; 2. JavaSc…

【c语言】扫雷

前言&#xff1a; 扫雷是一款经典的单人益智游戏&#xff0c;它的目标是在一个方格矩阵中找出所有的地雷&#xff0c;而不触碰到任何一颗地雷。在计算机编程领域&#xff0c;扫雷也是一个非常受欢迎的项目&#xff0c;因为它涉及到许多重要的编程概念&#xff0c;如数组、循环…

HNU-编译原理-甘晴void学习感悟

前言 熬过煎熬的考试周、复习以及更加煎熬的等成绩&#xff0c;查到成绩的那一刻&#xff0c;心里还是挺开心的。 虽然我没有完全学懂这门课程&#xff0c;但我还是兢兢业业地通过了课程的考试&#xff0c;拿到了这门课程的认可。 记录一下自己对编译原理的学习感悟&#xf…

虹科分享丨汽车技术的未来:Netropy如何测试和确保汽车以太网的性能

来源&#xff1a;艾特保IT 虹科分享丨汽车技术的未来&#xff1a;Netropy如何测试和确保汽车以太网的性能 原文链接&#xff1a;https://mp.weixin.qq.com/s/G8wihrzqpJJOx5i0o63fkA 欢迎关注虹科&#xff0c;为您提供最新资讯&#xff01; #汽车以太网 #车载网络 #Netropy …

【格密码基础】基于LWE问题的密码系统

目录 一. 介绍 二. LWE密码方案简单介绍 三. LWE经典归约 四. LWE性质 五. LWE的鲁棒性 一. 介绍 在2005年&#xff0c;Regev基于LWE问题提出了一个新的公钥密码方案。该方案可实现语义安全&#xff08;semantic security&#xff09;&#xff0c;其中误差率&#xff08;…

2023年我国民用无人机产业规模超过1200亿元,低空经济时代来临

2023年我国民用无人机产业规模超过1200亿元&#xff0c;低空经济时代来临 根据最新数据显示&#xff0c;2023年中国的民用无人机产业规模已经超过了1200亿元&#xff0c;稳居全球榜首。预计到2025年&#xff0c;这个数字将突破2000亿元&#xff0c;届时低空经济对国民经济的综…

SpringBoot 自定义Filter 提前返回 CORS 错误 处理前后端分离跨域配置无效问题解析

前言 浏览器有跨域限制&#xff0c;非同源策略 (协议、主机名或端口不同) 被视为跨域请求&#xff0c;解决跨域有跨域资源共享(CORS)、反向代理和 JSONP的方式。本篇通过 SpringBoot 的资源共享配置 (CORS) 来解决前后端分离项目的跨域&#xff0c;以及从原理上去解决跨域配置…

docker指令存档

目录 Docker 1、概念 2、架构图 3、安装 4、Docker怎么工作的&#xff1f; 5、Docker常用命令 帮助命令 镜像命令 1、查看镜像 2、帮助命令 3、搜索镜像 4、拉取镜像 5、删除镜像 容器命令 1、启动 2、查看运行的容器 3、删除容器 4、启动&停止 其他命令…

开始学习Vue2(axios和Vuex)

一、Axios 1、Axios 简介 Axios 是一个基于 promise 网络请求库 &#xff0c;作用于node.j s 和浏 览器中。它是 isomorphic 的(即同一套代码可以运行在浏览器 和 node.js 中)。在服务端它使用原生 node.js http 模块, 而在 客户端 (浏览端) 则使用 XMLHttpRequests。 …

滴滴开源小程序框架 Mpx 新特性:局部运行时能力增强

Mpx 是滴滴开源的一款增强型跨端小程序框架&#xff0c;自 2018 年立项开源以来如今已经进入第六个年头&#xff0c;在这六年间&#xff0c;Mpx 根植于业务&#xff0c;与业务共同成长&#xff0c;针对小程序业务开发中遇到的各类痛点问题提出了解决方案&#xff0c;并在滴滴内…

C语言实现插入排序算法(附带源代码)

插入排序 插入排序&#xff08;英语&#xff1a;Insertion Sort&#xff09;是一种简单直观的排序算法。它的工作原理是通过构建有序序列&#xff0c;对于未排序数据&#xff0c;在已排序序列中从后向前扫描&#xff0c;找到相应位置并插入。插入排序在实现上&#xff0c;通常…