VHDL中的匹配模拟和后合成行为

时间:2016-08-04 23:33:37

标签: vhdl quartus

此问题是此处显示的另一个问题的扩展,VHDL Process Confusion with Sensitivity Lists

但是,如果得分低于50,我无法评论进一步的解释。

所以,我从链接遇到了同样的问题并接受了显示的答案。但是,现在我对推荐的方法感兴趣,以便将模拟与后合成行为相匹配。链接中接受的答案表明,不建议使用Level Sensitive Latches作为解决方案,因为它们会导致更多问题。所以我的问题是推荐的方法是什么?有吗?

换句话说,我想要实现在那篇文章中想要实现的目标,但这种方式不会导致更多问题。我需要我的灵敏度列表不被我的综合工具忽略。

此外,我是VHDL的新手,因此使用流程可能无法实现我想要的结果。我使用的是带有Quartus Prime 16.0的DE2-115。任何信息将不胜感激。

1 个答案:

答案 0 :(得分:2)

如果您使用VHDL编程基于FPGA的原型开发板,您会对该语言的综合语义感兴趣。它与语言参考手册(LRM)中描述的模拟语义有很大不同。更糟糕的是:它没有标准化,并且在综合工具之间有所不同无论如何,综合意味着从VHDL代码到数字硬件的转换。这里唯一推荐的方法是,对于仍然不清楚理解合成语义的初学者是:

先考虑硬件,然后再编码。

换句话说,在一张纸上绘制一个漂亮的硬件框图。并使用以下10条规则。严格。没有例外。决不。并且不要忘记仔细检查最后一个,它与其他人一样重要,但更难以验证。

  1. 用大矩形围绕图形。这是你的电路的边界。跨越此边界的所有内容都是输入或输出端口。 VHDL实体将描述这个边界。
  2. 清楚地将边缘触发的寄存器(例如方块)与组合逻辑(例如圆形块)分开。
  3. 请勿使用电平触发的锁存器。
  4. 仅使用上升沿触发的寄存器,并对所有寄存器使用相同的单个时钟。它的名字是clock。它来自外部,是所有方块的输入,只有它们。甚至不代表时钟,它对于所有方块都是相同的,你可以在图中隐含它。
  5. 表示具有命名和定向箭头的块之间的通信。对于块来自箭头,箭头是输出信号。对于箭头转到的块,箭头是输入信号。
  6. 箭头只有一个原点,但它们可以有多个目的地。如果箭头有多个目的地,请根据需要多次分叉箭头。
  7. 有些箭头来自大矩形之外。这些是实体的输入端口。输入箭头也不能是任何块的输出。
  8. 有些箭射向外面。这些是输出端口。输出箭头具有一个原点和一个目标:外部。输出箭头没有叉子。因此,输出箭头也不能作为其中一个块的输入。如果您想使用输出箭头作为某些块的输入,请插入一个新的圆形块将其拆分为两部分:新块的输入,您想要的叉子数量和输出箭头从新的街区到外面。新块将成为VHDL中的简单连续分配。一种透明的重命名。
  9. 所有不来自或来自外部的箭头都是内部信号。您将在架构中声明它们。
  10. 图中的每个循环必须包含至少一个方块。
  11. 如果您无法通过此方法找到描述所需功能的方法,则问题在于您想要的功能。不使用VHDL或合成器。这意味着您想要的功能是数字硬件。使用其他技术实现它。

    VHDL编码成为一个细节:

    • 每个方块一个同步过程,
    • 每个圆块一个组合过程。

    同步过程如下所示:

    process(clock)
    begin
      if rising_edge(clock) then
        o1 <= i1;
        ...
        on <= in;
      end if;
    end process;
    

    其中i1, i2,..., in所有箭头,用于输入图表的相应方块,而o1, ..., om所有箭头,用于输出相应的方块你的图表。除信号名称外,不要更改任何内容。没有。甚至不是一个角色。 OK?

    组合过程如下所示:

    process(i1, i2,... , in)
      <declarations>
    begin
      o1 <= <default_value_for_o1>;
      ...
      om <= <default_value_for_om>;
      <statements>
    end process;
    

    其中i1, i2,..., in所有箭头,用于输入图表的相应圆形块。 全部,不再有。不要忘记单箭头,不要添加任何其他内容。没有例外。决不。并且o1, ..., om所有箭头,其中输出图表的相应圆形块。 全部,不再有。请勿更改<declarations>以外的任何内容,输入的名称,输出的名称,<default_value_for_oi><statements>的值。 会忘记单个默认值分配。如果必须创建一个新的圆形块来分割主输出箭头,则相应的过程只是:

    process(i)
    begin
      o <= i;
    end process;
    

    你可以简化为:

    o <= i;
    

    没有封闭的流程声明。它是等效的并发信号分配。

    一旦你对这种编码风格感到满意,只有这样,你才会:

    简化图纸以简化设计。但首先要继续思考硬件。画在头上,而不是在一张纸上,但继续画画。

    使用异步重置:

    process(clock, reset)
    begin
      if reset = '1' then
        o <= reset_value_for_o;
      elsif rising_edge(clock) then
        o <= i;
      end if;
    end process;
    

    在一个组合过程中合并几个组合过程。这是微不足道的,只是对程序框图的简单重组。

    将一些组合进程与同步进程合并。但为了做到这一点,你必须回到你的方框图并添加第十一条规则:

    1. 通过在它们周围绘制一个外壳,将几个圆形块和至少一个方块组合在一起。还附上可以的箭头。如果箭头未到达或从机箱外部出来,请勿让箭头穿过机箱的边界。完成后,查看机箱的所有输出箭头。如果它们中的任何一个来自机箱的圆形块或者也是机箱的输入,则无法在同步过程中合并这些过程。
    2. 稍后您还将开始使用锁存器,时钟下降沿,多个时钟和时钟域之间的重新同步......但我们将在时机成熟时讨论这些。