从硬编码if else if if configurable if else if if

时间:2016-08-17 19:43:49

标签: verilog

我有一个verilog可合成代码,如果有其他if语句。 它具有固定数量的if else if语句,如下所示。

always @ (*)
begin
    if (~a[0] && ~b[0] )
        c = 0;
    else if (~a[1] && ~b[1])
        c = 0;
    else if (~a[2] && ~b[2])
        c = 0;
    else if (~a[3] && ~b[3])
        c = 0;
    else if (~a[4] && ~b[4])
        c = 0;
    else
        c = 1;
end

现在我需要具有相同的功能,但是通过参数可以配置if else if语句的数量。请注意,需要维护通过if else if语句设置的优先级。我想我需要使用一个循环。但是使用for循环,它将是这样的:

always @ (*)
begin
    for (int i=0; i<param; i++)
    begin
        if (~a[i] && ~b[i] )
          c = 0;
        else
          c = 1;
     end
end

上面的代码不能模仿if else if结构。相反,它将使if语句不是所需的输出。 我猜生成可能有用,但不确定如何在此上下文中使用它。 任何人都可以建议我应该遵循的最佳方法。

谢谢, Anirban

3 个答案:

答案 0 :(得分:3)

对于这种特定情况,我们可以使用this article重新构造您的逻辑以完全避免循环:

assign c = ~|(~a & ~b);

首先将~a & ~b的结果作为多位值,将所有位一起或运算得到一位结果,然后将其反转。

这可以通过一系列reduction operator简化简化为优雅简单:

assign c = &(a | b);

答案 1 :(得分:1)

从技术上讲,你不关心优先权。您希望仅当a [i]和b [i]的任何组等于0时才将c设置为0,否则c应设置为1.这可以简化为:

c = &(a|b);

让我们假设:

reg [3:0] a = 'b0101;
reg [3:0] b = 'b1011;

运行此代码:

initial begin 
    $display("%b", a);
    $display("%b", b);
    $display("%b", a|b);
    $display("%b", &(a|b));
end

将返回1(你的其他声明):

# 0101
# 1011
# 1111
# 1 

但是当我们改变a和b的值时(a [1]和b [1]是0):

reg [3:0] a = 'b0101;
reg [3:0] b = 'b1001;

它将返回:

# 0101
# 1001
# 1101
# 0 

正是你想要的。

答案 2 :(得分:0)

您可以使用默认作业模仿最终的else

always @ (*)
begin
    c = 1;
    for (int i=0; i<param; i++)
    begin
        if (~a[i] && ~b[i] )
          c = 0;
     end
end