5

我被告知使用'when'语句来制作多路复用器,但不要使用'if'语句,因为它会导致时序错误......我不明白这个......那么'if'和'when'有什么区别' ? 它们是否映射到硬件中的相同事物?

4

3 回答 3

3

好的,让我们首先讨论一下 if 和 when 语句之间的区别:

  • 两者都称为数据流设计元素。

当声明

  • 并发语句
  • 未在流程中使用,仅在体系结构中使用,因为流程是顺序执行

if 语句

  • 顺序语句
  • 在进程中使用,因为它是顺序语句,而不是在进程外使用

而且你知道多路复用器是一个不需要进程块的组件,因为它的行为不会随着输入的改变而改变,所以它会在进程之外,所以你必须使用 when 语句来编写它,因为它是并发语句......并且如果使用 if 语句编写,可能会出现时序错误。此外,所有参考资料和赛灵思帮助(如果您使用的是赛灵思)正在使用 when 语句而不是 if 语句编写多路复用器块

参考:数字设计原则与实践,John F. Wakerly,第 3 版

于 2010-03-09T23:35:12.003 回答
2

见这些:

基本上,if是顺序的,并且when是并发的。它们不映射到硬件中的同一事物... 此页面在底部描述了合成if语句所需的一些特殊注意事项。

于 2010-03-09T23:34:52.973 回答
1

两种编码风格都是完全有效的。

让我们回顾一些元素。从 HDL 开始,综合分两个主要步骤完成:

  1. 首先,分析 VHDL 以检测RTL 模板(由 RTL 元素组成:触发器、算术表达式、多路复用器、控制逻辑)。我们说这些元素是“推断的”(即,您必须使用正确的模板进行编码才能获得您最初想要的内容。您必须在编码之前想象这些元素是如何连接的)。
  2. 第二步是真正的逻辑综合,它考虑了特定的目标技术参数(可用的门类型、时序、面积、功率)。

这两个步骤清楚地将 RTL 功能需求(转向逻辑、计算)与技术突发事件(时间等)区分开来。

让我们回到第一步(RTL):

关于多路复用器,有几种编码风格是可能的:

  • 使用并发分配:

    y<= a1 当 cond1 else a2 当 cond2 else cond3;

  • 在进程中使用 if 语句:

    过程(a1,a2,a3,cond1,cond2)开始如果(cond1)然后y<=a1;elsif(cond2) 然后 y<=a2; 否则 y<=a3; 万一; 结尾;

  • 使用另一种并发分配 形式,适用于通用描述:如果 sel 是一个整数,而 muxin 是一个信号数组,那么:

    muxout <= muxin(sel); --将推断出一个多路复用器

请注意,这 3 种编码风格始终有效。还要注意,它们比简单的多路复用器“多一点”,因为编码风格强制存在优先级编码(如果是 elsif,当 else 时),这不是简单的基于方程的多路复用器的情况,实际上是对称的。

  • 使用 case 语句

    过程(a1,a2,a3,cond1,cond2)变量cond:std_logic(1 downto 0);开始条件 := cond2 & cond1; case cond 是 "01" => y<= a1; 当 "10" => y<= a2; 当其他人 => y<=a3; 结束案例;结尾;

  • 使用 select 语句(在我们的示例中,需要两个并发分配):

    sel <= cond2 & cond1; WITH sel SELECT y <= a1 WHEN "01", a2 WHEN "10", a3 WHEN OTHERS;

最后一点是关于抽象的兴起,即使对于 RTL 设计:合成器现在真的很成熟。看看 Jiri Gaisler LEON2 开源处理器的编码风格,以及他的编码风格(见这里)。他倾向于采用与经典书籍截然不同但完全有效的方法。

您应该始终了解 RTL 合成器将推断什么。

相反,行为合成让你(部分)忘记合成器会推断什么。但那是另一回事了。

于 2010-03-10T18:24:45.387 回答