【问题标题】:Match Simulation and Post-Synthesis Behavior in VHDLVHDL 中的匹配仿真和综合后行为
【发布时间】:2016-08-04 23:33:37
【问题描述】:

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

但是,我的 Rep 点数少于 50,我无法发表评论以获得进一步的解释。

所以,我从链接中遇到了同样的问题并接受了显示的答案。但是,现在我对推荐的方法感兴趣,以便将模拟与综合后行为相匹配。链接中接受的答案指出不建议将级别敏感锁存器作为解决方案,因为它们会导致更多问题。所以我的问题是推荐的方法是什么?有吗?

换句话说,我想实现该帖子中试图实现的目标,但不会导致更多问题。我需要我的敏感度列表不会被我的综合工具忽略。

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

【问题讨论】:

  • 我需要我的敏感度列表不会被我的综合工具忽略。使用供应商推荐的顺序结构(如问题答案中所示)。条件或语句中的任何评估信号都应在敏感度列表中(在 -2008 中相当于使用保留字 all)。请参阅 Quartus Prime Standard Edition Handbook Vol 1, 12。推荐的 HDL 编码样式、寄存器和锁存器编码样式。模拟(结果未显示)似乎依赖于 CE 推断的锁存器,该锁存器未在综合中使用(并且不提供锁存器)。

标签: vhdl quartus


【解决方案1】:

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

首先考虑硬件,然后是代码。

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

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

如果你找不到用这种方法描述你想要的功能的方法,那么问题就出在你想要的功能上。不使用 VHDL 或合成器。这意味着您想要的功能是不是数字硬件。使用另一种技术实现它。

VHDL编码成为细节:

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

同步过程如下所示:

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

其中i1, i2,..., in所有 箭头,进入图表的相应方块,o1, ..., om所有 箭头,输出图表的相应方块。除了信号的名称外,不要更改任何内容。没有。连一个字符都没有。好吗?

组合过程如下所示:

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

其中i1, i2,..., in所有 箭头,它们进入图表的相应圆形块。 全部,仅此而已。不要忘记一个箭头,也不要添加任何其他东西。没有例外。绝不。其中o1, ..., om所有 箭头,它们输出图表的相应圆形块。 全部,仅此而已。除了&lt;declarations&gt;、输入名称、输出名称、&lt;default_value_for_oi&gt;&lt;statements&gt; 的值之外,不要更改任何内容。 不要忘记单个默认值分配。如果你必须创建一个新的圆形块来分割一个主要的输出箭头,相应的过程就是:

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. 在几个圆形方块和至少一个方形方块周围画一个围墙,将它们组合在一起。还附上可以的箭头。如果箭头不进出外壳外部,请勿让箭头穿过外壳边界。完成后,查看机箱的所有输出箭头。如果其中任何一个来自外壳的圆形块或也是外壳的输入,则无法将这些进程合并为同步进程。

稍后您还将开始使用锁存器、时钟下降沿、多个时钟和时钟域之间的再同步器……但我们将在时机成熟时讨论这些。

【讨论】:

  • 简而言之,使用 VHDL 进行数字硬件设计。
  • 很棒的信息,对您有很大帮助。我想我理解它是如何工作的,但是您是否对您描述的设计过程有视觉参考(例如视频教程),或者您描述的“框图设计过程”的正确名称是什么?
  • @Dylan:我开始在 SO 上贡献 VHDL 文档。要有耐心,总有一天你会发现这一切。
  • @Dylan 那么如何为 Renaud 的帖子点赞。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-11-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-24
相关资源
最近更新 更多