【问题标题】:First assign and then reassign in if block as alternative to if-(else if)-else in Verilog首先分配,然后在 if 块中重新分配,以替代 Verilog 中的 if-(else if)-else
【发布时间】:2019-06-23 20:25:43
【问题描述】:

最好先给变量赋值,然后在 if 块中重新赋值,而不是使用 if-(else if)-else 块,其中 if 和 else 块中的赋值相同,else if 中的赋值块是不同的分配。

always @(*) begin
    if condition1 begin
        var = val1;
    end
    else if condition2 begin
        var = val2;
    end
    else begin
        var = val1;
    end
end

always @(*) begin
    var = val1;
    if condition2 begin
        var = val2;
    end
end

鉴于条件 1 和条件 2 是互斥的,我认为这两个块应该综合相同的逻辑,并且选择一个而不是另一个纯粹是审美。我的想法是正确的,还是一种实现的合成方式与另一种不同?如果我的想法是正确的,社区更喜欢哪种方法?

编辑:在 racraman 的评论之后添加了互斥标准。

【问题讨论】:

  • 两个代码块不一样;如果条件 1 和条件 2 都为真,则第一个返回 val1,而第二个返回 val2。
  • 你是对的。如果条件1 和条件2 互斥怎么办?在那种情况下他们会合成相同的东西吗?
  • Yes a 或将第二个代码块更改为“if condition2 && !条件1”。顺便说一句,我更喜欢第二种,所以可能很快就会写一个答案:)
  • 合成如何知道条件是互斥的?在您的情况下,将综合不同的逻辑。但案例 2 将与 if(condition2) var=val2; else var = val1; 相同
  • 有什么理由不考虑var = !condition1 && condition2 ? val2 : val1;(作为第一个示例的替代)或var = condition2 ? val2 : val1;(第二个示例)之类的东西吗?因为最终它将成为某种多路复用器,这样人们就可以直接“看到”它。

标签: logic verilog hardware hdl


【解决方案1】:

至于您所问的一般原则:您走哪条路线并不重要。合成器将足够聪明,无论如何都可以解决它。对于模拟,首先执行默认分配的选项可能执行得更慢(特别是如果分配是非阻塞的),但我不会担心。

就我个人而言,我更喜欢第二个,因为对于普通读者来说,你在生成不需要的闩锁方面已经涵盖了你的基础(换句话说,你总是分配给var)。

说了这么多,你的例子(原则上)非常简单,在这种特殊情况下,很明显需要一个多路复用器,你可能根本不需要一个 always 块,而应该只使用一个 @ 987654322@ 带三元运算符。

我说“原则上”是因为你的逻辑没有真正的意义。你说你的条件是互斥的,但是如果两个条件都不活跃会发生什么?你真的需要一个锁存器来保留之前的输出吗?如果不是,那你为什么有两个条件呢?

【讨论】:

  • 如果我使用always @(posedge clk) 而不是always @(*),它将如何改变?我将无法以与您描述的相同的方式使用分配。使用方法 2 而不是方法 1 来避免推断触发器,同时保持代码干净和易于理解,我是否仍然会更好?
  • 不可能推断出posedege clk 的闩锁,所以没有问题 - 一切都不同。我认为您需要返回并绘制您想要的时序图或电路图,并决定是否必须对其进行计时。
  • 我用assign 语句解决了我原来的问题。但是,我有一个脑电波(对我来说不常见),如果我有一个时钟设计会发生什么,并且如果我使用方法 1 并且忘记涵盖所有 if-else 条件与使用方法 2 时可能会冒着推断触发器的风险。
【解决方案2】:

在使用 always@(*) 块时,您最终可能会在设计中推断出无意的锁存器。 对于您提到的类型的赋值,最好使用三元运算符。

assign var = (cond1)?(val1):(cond2)?(val2):(val1); 
                                 //Assuming cond1 and cond2 are mutually exclusive

如果 cond1 和 cond2 可以同时发生,那么上面的 assign 可以更改为

 assign var = (cond1 && cond2)?(val1):(cond1)?(val1):(cond2)?(val2):(val1);
                                //Assuming val1 when both cond1/2 are high

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多