【问题标题】:VHDL block and guarded input - what does this code do?VHDL 块和受保护的输入 - 这段代码有什么作用?
【发布时间】:2018-01-12 21:17:09
【问题描述】:

我有以下来自初学者的 VHDL 教程:

   rising_edge: block(clk’event and clk = ‘1’)
    begin
        result <= guarded input or force after 10ns;
    end block rising_edge

说明文字是

“基本上我有一个叫做rising_edge的块,它是一个带有保护条件的块,它执行以下操作,它检查我们在时钟上有一个事件,并且时钟等于1,所以我们'正在有效地寻找所谓的上升沿。我们正在寻找时钟从 0 变为 1 的事件,如果是,那么我们可以有条件地分配结果,所以你会看到这里的结果变量说在 10 ns 后它是一个受保护的输入或强制可能看起来有点令人困惑,但考虑一下没有受保护的关键字。我们所做的只是分配输入或强制的评估结果,我们正在做所以,在这种情况下,信号结果的赋值只有在保护信号为真时才会执行,在我们的例子中,这意味着表达式的赋值,即输入或强制,只会发生在时钟的上升沿,因为它处于警戒状态。”

现在我一遍又一遍地阅读并在网上搜索,但对于这实际上在做什么却一无所知。有人可以温和地解释一下它的目的吗?

【问题讨论】:

  • 这是一个什么样的初学者教程?谨慎的表达方式......在我的经验中并不常见......
  • clk’event and clk = ‘1’ 不保证模拟器中的“0”到“1”转换(使用rising_edge(clk) 可以)。 clk'event 就是在这种情况下,clk 上的任何事件都从任何其他值变为“1”。上升沿确保从“0”到“1”的转换。
  • IEEE Std 1076-2008 11.2 Block statement "如果保护条件出现在保留字块之后,则在声明部分的开头隐式声明具有预定义类型 BOOLEAN 的简单名称 GUARD 的信号块,并且保护条件定义了该信号在任何给定时间的值(见 14.7.4)。保护条件的类型应为 BOOLEAN 类型。信号 GUARD 可用于控制在块(见 11.6)。{ 11.6 并发信号赋值语句)。你的教程来自哪里?
  • "rising_edge" 是 std_logic_1164 库中常用函数的名称。我不会重复使用这个词作为某个过程的标签...
  • 您正在使用的教程的链接可能有用。

标签: vhdl


【解决方案1】:

块本质上是一组并发语句。在实际使用方面,它与process 非常相似,只是它的范围有限,允许component 样式的信号映射(使用portport map)。它可用于提高可读性(请参阅this question),实际上并没有太多其他用途。块很少使用并且经常不支持合成(请参阅here)。据我(有限的)知识,使用块除了可读性之外没有其他优势。

因为你的块语句包含一个保护条件(clk'event and clk='1' 是这里的保护条件),所以它是一个保护块。在受保护的块内,声明为受保护的信号(如您的示例中)只有在保护条件评估为 true

时才会分配

只有当保护条件评估为true,即在clk 的上升沿时,才会执行已被保护的整个语句(即在您的情况下为input or force after 10ns)。因此,对于所有意图和目的,此块具有与

相同的行为
process(clk)
begin
    if clk'event and clk = '1' then
        result <= input or force after 10ns;
    end if;
end process;

我会说,这是一个糟糕的例子。一方面,正如其他人所说,block 的使用非常罕见,它们通常只用于非常高级的设计中。自 1993 年以来一直不鼓励使用 clk'event and clk = '1'(参见 here)。还应该再次提到,使用rising_edge 作为标签是一个糟糕的想法,就像使用force 作为信号名称一样(在VHDL 2008 中,force 是一个保留关键字,可用于将信号强制为一个值)。

【讨论】:

  • 啊,可怕的杰夫打败了我
  • 不,你提前了大约半分钟;)
  • “而且...一般只用于相当高级的设计”。好吧,这些年来我见过很多复杂程度不同的代码,但从未在实际应用程序的代码中遇到过任何blockstatements。通常有“更好”的方法来实现你想要的。例如,通过引入额外的层次结构。合成工具似乎更喜欢这个。
  • 我在 VITAL 兼容的设计中看到了它,我认为它甚至是那些需要的(尽管我自己从未做过任何 VITAL 工作)。除此之外,我非常同意。
【解决方案2】:

从这应该是一个初学者教程的想法出发,并且没有任何解释为什么使用这种不寻常的风格,一个更传统的实现将是:

process : (clk)
begin
  if (rising_edge(clk)) then
    result <= input or force after 10 ns;
  end if;
end process;

需要注意的几点:

  1. 这假定 inputforce 要么是信号,要么是实体的输入。
  2. 如果您的代码要在真实硬件设备中实现,则对信号分配延迟建模是不常见的。
  3. 您问题中的代码使用after 10ns;,无效;您需要在值和单位之间留一个空格(如我的代码中所示)。
  4. 假设您包含的标准 IEEE 库比我认为的 VHDL93 更新,您问题中的代码使用 rising_edge 作为标识符,而这实际上已经定义为函数。
  5. 您问题中的代码使用force 作为信号名称,而这也是自 VHDL2008 以来的保留语言关键字。

我给你的建议是找一个不同的教程。您发布的报价没有写清楚,您发布的代码似乎让您走上了一条奇怪的道路。我能想到的只是这个教程实际上非常非常古老。

【讨论】:

  • force 仅是 VHDL-2008 以来的关键字
猜你喜欢
  • 2022-12-20
  • 2023-02-03
  • 2010-11-07
  • 1970-01-01
  • 2011-04-13
  • 2011-05-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多