首先分配,然后重新分配if块,以替代Verilog中的if-(else if)-else

时间:2019-06-23 20:25:43

标签: logic verilog hardware hdl

最好先为变量分配一个值,然后重新分配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

vs

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

鉴于condition1和condition2是互斥的,我认为这两个模块都应综合相同的逻辑,而一个选择另一个则纯粹是美观的。我是否正确地认为了这一点,或者一个实现的合成方式与另一个实现不同?如果我的想法是正确的,那么社区中首选哪种方法?

编辑:在racraman评论后添加了互斥条件。

2 个答案:

答案 0 :(得分:0)

使用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

答案 1 :(得分:0)

关于您要询问的一般原则:走哪条路都没关系。合成器足够聪明,无论如何都可以解决它。对于仿真而言,首先执行默认分配的选项可能执行得更慢(尤其是在分配是非阻塞分配的情况下),但我不必担心。

我个人比较喜欢第二种,因为对于因果读者而言,更明显的是您已经涵盖了生成不需要的闩锁的基础(换句话说,您始终分配给var)。

说了这么多,您的示例(原则上)非常简单,在这种情况下,很明显,需要使用mux,您可能根本不需要始终阻塞,而应该使用{ {1}}和三元运算符。

我说“原则上”是因为您的逻辑没有任何意义。您说您的条件是互斥的,但是如果两个条件都不活跃怎么办?您是否真的需要一个锁存器来保留先前的输出?如果没有,为什么您完全有两个条件?