我看到一个类似于以下的Verilog语句:
欢迎提供任何反馈!
integer level = log(N)
(其中N是一个参数,level需要确定)。但是我知道在Verilog中不能使用复杂的数学语句,所以我想知道是否有解决上述问题的替代方案?欢迎提供任何反馈!
integer level = log(N)
(其中N是一个参数,level需要确定)。但是我知道在Verilog中不能使用复杂的数学语句,所以我想知道是否有解决上述问题的替代方案?如果您要进行基于2的对数运算,可以使用内置函数$clog2()
。
Verilog有自然对数函数($ln()
)、十进制对数函数($log10()
)和二进制对数上取整函数($clog2()
)。在常量表达式中,它们应该是可综合的,但实际支持工具的情况有所不同。
以下是可综合的Verilog代码:
module test(output [31:0] a, b, c);
assign a = 1000 * $ln(123);
assign b = 1000 * $log10(123);
assign c = 1000 * $clog2(123);
endmodule
yosys -p 'prep; write_verilog -noattr' test.v
)后:
module test(a, b, c);
output [31:0] a;
output [31:0] b;
output [31:0] c;
assign a = 32'd4812;
assign b = 32'd2090;
assign c = 32'd7000;
endmodule
但我知道在Verilog中无法进行复杂的数学运算。
首先,Verilog是一种硬件描述语言。硬件怎么描述log(N)
语句呢?现代FPGA由LUT、flops、小型嵌入式存储器、实现MAC(乘累加)基元的简单DSP组成。不能直接将log(N)
和其他复杂的数学语句映射到这些基元上。ASIC也是如此。
类比一下,处理器不会执行log(N)
。它调用一堆低级汇编指令来执行。这些汇编指令是log(N)
库(C、C++等)的一部分。
为了能够合成ASIC/FPGA的log(N)
,需要一个log(N)
IP核实例。
function bit [31:0] log_base_2 (bit [31:0] log_input);
bit [31:0] input_copy;
bit [31:0] log_out = 0;
input_copy = log_input;
while(input_copy > 0)begin
input_copy = input_copy >> 1;
log_out = log_out + 1;
end
log_out = log_out - 1;
if(log_input != (1 << log_out))
log_out = log_out + 1;
return log_out;
endfunction