请在下面查看我的Verilog测试平台代码。实际上,我想用一个或两个表达式替换所有if-else语句。这样的代码看起来非常松散和肮脏。有人可以告诉我如何使这段代码更紧凑。请注意,变量“ i”和“ len”是重点。
module xyz();
......
....some parts and variable declarations;
......
initial begin
for(i = 1; i <= 65535; i = i+1) begin
if (i <= 1) len = 1;
else if (i>1 & i <= 3) len = 2;
else if (i>3 & i <= 7) len = 3;
else if (i>7 & i <= 15) len = 4;
else if (i>15 & i <= 31) len = 5;
else if (i>31 & i <= 63) len = 6;
else if (i>63 & i <= 127) len = 7;
else if (i>127 & i <= 255) len = 8;
else if (i>255 & i <= 511) len = 9;
else if (i>511 & i <= 1023) len = 10;
else if (i>1023 & i <= 2047) len = 11;
else if (i>2047 & i <= 4095) len = 12;
else if (i>4095 & i <= 8191) len = 13;
else if (i>8191 & i <= 16383) len = 14;
else if (i>16383 & i <= 32767) len = 15;
else if (i>32767 & i <= 65535) len = 16;
// This is a task(integer, integer, integer, vector)
universal_test_task(len, 1, i, 16'hFFFF);
end
end
endmodule
该代码的主要目的是控制特定计数的位数。
答案 0 :(得分:2)
Verilog和System Verilog具有内置的系统功能$clog2()
,即,login-of-log2。
可以证明,正整数 k 的基数 b 中的位数是。
在您的情况下,您可以将所有if-else语句替换为单行:
len = $clog2(i+1)
同样,只要您为$ clog2提供一个在编译期间恒定的值,它就会得到所有主要综合工具的支持。
答案 1 :(得分:1)
这听起来像是递归 log2
函数的工作:
function int log2 (int i);
if (i <= 1)
return 0;
else
return log2(i/2) + 1;
endfunction
此函数是递归的,因为它会自行调用。它使用以下两个事实进行工作:
您的测试平台需要此功能,但是您会发现此功能实际上是可综合的。
https://www.edaplayground.com/x/3bTN
module xyz;
function int log2 (int i);
if (i <= 1)
return 0;
else
return log2(i/2) + 1;
endfunction
initial
begin
int len;
for (int i = 1; i <= 65535; i++)
begin
len = log2(i)+1;
$display("i=%d, len=%d", i, len);
end
end
endmodule
答案 2 :(得分:0)
在Verilog中,您可以使用三元运算符来实现该功能。
module test(i,len);
input wire [16:0] i;
output reg [16:0] len;
initial
begin
len = i> 32767 ? 16 :
i> 16383 ? 15 :
i> 8191 ? 14 :
i> 4095 ? 13 :
i> 2047 ? 12 :
i> 1023 ? 11 :
i> 511 ? 10 :
i> 255 ? 9 :
i> 127 ? 8 :
i> 63 ? 7 :
i> 31 ? 6 :
i> 15 ? 5 :
i> 7 ? 4 :
i> 3 ? 3 :
i> 1 ? 2 : 1 ;
$display(i,,,,,len);
end
endmodule
在系统Verilog中,$ clog2()将帮助您完成此操作
module test;
bit [16:0] i;
bit [5:0] b;
bit [16:0] len;
initial
begin
repeat(5)
begin
assert(std::randomize(i,b) with { b inside {[1:15]};
i == 2**b; });
len = $clog2(i)+1;
$display(i,,,,,len);
end
end
endmodule