verilog - 为什么verilog教程通常使reset异步?
问题描述
如果这有什么不同的话,这个问题是在 FPGA 综合的背景下进行的。数据表 (iCE40UP) 指出,每个逻辑单元都有一个带异步复位和时钟使能输入的 D 型触发器。
许多verilog教程介绍了顺序逻辑,例如:
always @(posedge clk)
begin
some_reg <= [...]
end
我熟悉时钟逻辑,这对我来说很直观。
然后引入的下一个概念通常是:
- 小心不要意外创建锁存器,因为您真正需要的是正确的寄存器。
always @(posedge clk or [pos|neg]edge reset)
always @(*)
在维基百科中,我读到了一些可怕的陈述,例如“如果系统依赖于任何连续输入,那么这些输入很可能容易受到亚稳态的影响。[...] 如果仲裁器或触发器的输入几乎同时到达,则电路很可能会穿过一个亚稳态点。”
冒着因为格式不正确而关闭我的问题的风险......我错过了什么?
异步复位是推荐的设计实践吗?不将复位视为任何其他输入并使其在下一个周期生效,可以获得什么?实际芯片的文档通常要求 RST* 引脚在多个时钟周期内保持低电平。
设计中的锁存器是否使其异步?我们如何确保在存在由时钟域之外的东西驱动的锁存器时观察到正确的时序?
什么时候会有人真正想要时钟设计中的锁存器?为什么 verilog 让意外创建一个变得如此容易?
谢谢!
看似相关的问题: - Verilog D-Flip-Flop not re-latch after asynchronous reset -如果我使用异步复位怎么办,我应该把它设为同步吗?
解决方案
同步与异步复位与 CPU 的大端与小端之争有一些相似之处。在许多情况下,这两种类型都同样有效。但是在某些情况下,任何一种类型都比另一种具有优势。在上电或断电等情况下,您可能没有有效的时钟,但您仍然需要复位才能使系统处于已知的被动状态,并避免危险的 I/O 故障。只有异步复位可以做到这一点。
如果您的设计包含缺少复位功能的寄存器,例如 RAM 块,那么在将 adr、数据和控制信号馈送到 RAM 的寄存器上使用异步复位可能会在复位发生时导致 RAM 内容损坏。因此,如果您需要在必须保留 RAM 内容的情况下进行热复位:对最接近 RAM 的逻辑使用同步热复位。
Altera 和 Xilinx 建议他们的客户只使用同步复位,这加剧了混乱。仅使用同步复位可以在 Altera 和 Xilinx 上很好地工作,因为它们都是基于 SRAM 的 FPGA 架构,因此上电故障永远不会成为问题。
但是,如果您想让您的设计可移植到其他架构,例如 ASIC 或闪存 FPGA,那么异步复位可能是更好的默认选择。
关于您关于异步复位引起的亚稳态的问题。那是对的。完全异步的复位信号会导致亚稳态。这就是为什么您必须始终同步低电平有效异步复位信号的上升沿。只有复位的下降沿可以完全异步。
仅同步上升沿由两个触发器完成。
闩锁:不,您几乎从不需要时钟设计中的闩锁。好的做法是让 DRC 在找到锁存器的情况下触发错误。
推荐阅读
- node.js - sequelize 创建具有生成值的列
- html - Cookie 栏没有关闭?
- reactjs - 在 reactjs 渲染中添加条件
- vba - VBA中的StringFromIID - 避免手动管理内存的好方法是什么?
- postgresql - Heroku / Postgres - 速度问题
- arrays - 有没有办法打印整个数组,而不仅仅是通过迭代它们来打印数组的内容?
- javascript - 在 Javascript 中导入的不同方式?
- apache-pulsar - Kubernetes 集群上的 Apache Pulsar
- c++ - unordered_map not being updated properly
- python - BadZipFile:在 heroku 上部署时文件不是 zip 文件