我在verilog中有一个看起来像的语句integer level = log(N)
(其中N是一个参数,级别要确定)但我知道我不能在verilog中做复杂的数学语句,所以我想知道是否有上述问题的替代解决方案?
任何反馈表示赞赏!
如果它是以 2 为底的对数,则可以使用内置函数$clog2()
。
来自 RAM DEPTH 的地址宽度的答案描述了在这种情况下评估常数对数的几种方法。
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进行 RTL 合成之后(例如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、触发器、小型嵌入式存储器、实现 MAC(乘法累加)原语的简单 DSP 组成。log(N)
和其他复杂的数学语句不能直接映射到这些原语中。ASIC 也是如此。
以此类推,log(N)
不会由处理器执行。它调用一堆较低级别的汇编指令来执行此操作。这些汇编指令是log(N)
库的一部分(C、C++ 等)
为了能够log(N)
为 ASIC/FPGA 进行综合,它需要一个log(N)
IP 核的实例。
我喜欢将(值的以 n 为底的对数)视为回答“我需要多少个以 n 为底的数字来表示‘值’独立数字?”的问题。(请记住,0 算作数字)
这么想,你可以在 SystemVerilog 中实现自己的日志库 2:
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