我有一个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
答案 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