Verilog 如果灵敏度列表中的变量缺失,将创建什么逻辑
这是我们十大公司提出的面试问题 代码1:Verilog 如果灵敏度列表中的变量缺失,将创建什么逻辑,verilog,system-verilog,register-transfer-level,Verilog,System Verilog,Register Transfer Level,这是我们十大公司提出的面试问题 代码1: always @(a or b or sel) begin if (sel == 1) c = a; else if (sel == 0) c =b; end 这将创建一个多路复用器 代码2:现在从灵敏度中删除“SEL”。它还会产生多路复用器吗? 下面的代码是什么?如果没有,将创建什么逻辑 always @(a or b) begin if (sel == 1) c = a; else if (sel == 0
always @(a or b or sel) begin
if (sel == 1)
c = a;
else if (sel == 0)
c =b;
end
这将创建一个多路复用器
代码2:现在从灵敏度中删除“SEL”。它还会产生多路复用器吗?
下面的代码是什么?如果没有,将创建什么逻辑
always @(a or b) begin
if (sel == 1)
c = a;
else if (sel == 0)
c =b;
end
是的,这仍然会合成一个多工器。综合工具将解释此RTL,就像灵敏度列表已完成一样 然而,这里出现了一个大问题,因为您将在RTL模拟中看到与栅极级模拟/实际硅不同的行为。在RTL模拟中,
c
仅在a
或b
更改时才会更改。如果只有多路复用器的选择信号sel
发生变化,您的输出c
在RTL模拟中不会发生变化
当打算创建组合逻辑时,通常建议使用
always @(*)
或
如果您可以使用SystemVerilog。这样做的优点是,您永远不会遇到与灵敏度列表相关的模拟/合成不匹配。后一个关键字还有一个优点,即您可以明确地告诉工具您想要创建组合逻辑(例如,而不是意外的锁存)
最后:米尔斯和卡明斯写了一篇伟大的论文。在许多其他问题中,这个问题在这里描述得非常好。我极力推荐大家看看这篇文章
好处:X射线传播和模拟与实际硅不匹配 正如您在评论中指出的,您想知道会发生什么是
sel===1'bx
。为了更好地理解这件事,我强烈推荐斯图尔特·萨瑟兰的作品。在这里,我将对您的具体示例作一个非常简短的总结
SystemVerilog中的条件块倾向于X乐观,在前面的文章中定义为:
X乐观被定义为[…]任何时候模拟都会将输入上的X值转换为操作或逻辑门上的0或1。[…]SystemVerilog可能过于乐观,这意味着当实际硅仍然模糊不清时,X在模拟中传播为0或1
当查看您的代码时,我们将看到sel===1'bx
不会传播到c
。相反,模拟器将保持先前的c
值并模拟锁存。这是过度的X乐观,并且是与实际硅的模拟不匹配,因为这里的选择线不是X:信号是1或0。换句话说,这将不是硅锁存器
一种解决方案是在模拟中使多路复用器X悲观,这样我们就可以检测到这种不确定的状态。为此,当sel
既不是0也不是1时,我们将X指定给c
:
always_comb
if (sel)
c = a;
else if (!sel)
c = b;
`ifndef SYNTHESIS // see footnote 2
else
c = 'x;
`endif
然而,这有一个问题,那就是它过于悲观。当a
和b
具有相同的值时,我们将清楚地知道c
在实际硅中具有什么值(无论sel
的值如何)
上述论文给出了条件运算符(?:
)作为可能的解决方案:
条件?表达式1:表达式2代码>
如果条件的计算结果为未知,则运算符将对表达式1和表达式2的值进行逐位比较。对于每个位位置,如果该位在两个表达式中均为0,则该位返回0。如果两位都是1,则返回1。如果每个表达式中的对应位不同,或Z或X不同,则会为该位返回一个X
因此,通过使用以下代码,我们将在上述两种解决方案之间达成妥协:
always_comb
c = sel ? a : b;
这里的缺点是,条件运算符不适合更复杂的表达式
总结了三种方法:
╭───────────╥─────────────────────────────────────────────────╮
│ input ║ sel(t) │
├───╥───╥───╫────────────┬─────────────┬────────────┬─────────┤
│sel║ a ║ b ║ optimistic │ pessimistic │ compromise │ silicon │
╞═══╬═══╬═══╬════════════╪═════════════╡════════════╪═════════╡
│ X ║ 0 ║ 0 ║ sel(t-1) │ X │ 0 │ 0 │
│ X ║ 0 ║ 1 ║ sel(t-1) │ X │ X │ 0/1 │
│ X ║ 1 ║ 0 ║ sel(t-1) │ X │ X │ 0/1 │
│ X ║ 1 ║ 1 ║ sel(t-1) │ X │ 1 │ 1 │
└───╨───╨───╨────────────┴─────────────┘────────────┴─────────┘
在他的论文中,Sutherland给出了另一个我同意的解决方案:最好使用断言来检测导致X的设计问题,而不是让X在设计中传播并花费大量时间寻找根本原因。对于您的特定代码,这可能如下所示:
always_comb
begin
assert (!$isknown(sel))
else $error("sel = X!");
if (sel)
c = a;
else if (!sel)
c = b;
end
1:这里我假设sel
是一个1位信号。否则,您将以闩锁结束
2:有关合成宏标识符的更多信息。是,这仍将合成为多路复用器1。综合工具将解释此RTL,就像灵敏度列表已完成一样
然而,这里出现了一个大问题,因为您将在RTL模拟中看到与栅极级模拟/实际硅不同的行为。在RTL模拟中,c
仅在a
或b
更改时才会更改。如果只有多路复用器的选择信号sel
发生变化,您的输出c
在RTL模拟中不会发生变化
当打算创建组合逻辑时,通常建议使用
always @(*)
或
如果您可以使用SystemVerilog。这样做的优点是,您永远不会遇到与灵敏度列表相关的模拟/合成不匹配。后一个关键字还有一个优点,即您可以明确地告诉工具您想要创建组合逻辑(例如,而不是意外的锁存)
最后:米尔斯和卡明斯写了一篇伟大的论文。在许多其他问题中,这个问题在这里描述得非常好。我极力推荐大家看看这篇文章
好处:X射线传播和模拟与实际硅不匹配
正如您在评论中指出的,您想知道会发生什么是sel===1'bx
。为了更好地理解这件事,我强烈推荐斯图尔特·萨瑟兰的作品。在这里,我将对您的具体示例作一个非常简短的总结
SystemVerilog中的条件块倾向于X乐观,在前面的文章中定义为:
X乐观主义被定义为[……]