Reputation: 101
I've a statement in verilog looking like integer level = log(N)
(Where N is a parameter and level is to be determined) But I understand I cannot do complex math statements in verilog, so I'm wondering if there is an alternative solution to the above problem?
Any feedback appreciated!
Upvotes: 10
Views: 52703
Reputation: 1282
I like to think of (logarithm base n of value) as answering the question "How many base n digits do I need to represent 'value' independent numbers?" (Keeping in mind that 0 counts as a number)
Thinking of it that way, you can implement your own log base 2 in SystemVerilog:
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
Upvotes: 1
Reputation: 8255
Verilog has functions for natural logarithm ($ln()
), decadic logarithm ($log10()
) and ceiling of binary logarithm ($clog2()
). In constant expressions they should be synthesizable, but actual support by tools varies.
The following is synthesizable Verilog code:
module test(output [31:0] a, b, c);
assign a = 1000 * $ln(123);
assign b = 1000 * $log10(123);
assign c = 1000 * $clog2(123);
endmodule
E.g. after RTL synthesis with Yosys (e.g. 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
Upvotes: 5
Reputation: 156
If it is a logarithm base 2 you are trying to do, you can use the built-in function $clog2()
.
Upvotes: 11
Reputation: 796
But I understand I cannot do complex math statements in Verilog
Verilog is first and foremost a hardware description language. What hardware log(N)
statement is describing? Modern FPGAs consist of LUTs, flops, small embedded memories, simple DSPs that implement MAC (multiply-accumulate) primitives. log(N)
and other complex math statements cannot be mapped directly into those primitives. The same goes with ASICs.
By analogy, log(N)
doesn't get executed by a processor. It calls a bunch of lower-level assembly instructions to do so. Those assembly instructions are part of the log(N)
library (C, C++, etc.)
To be able to synthesize log(N)
for ASIC/FPGA it requires an instance of a log(N)
IP core.
Upvotes: 2
Reputation: 4866
The answer to ADDRESS WIDTH from RAM DEPTH describes a couple ways to evaluate constant logarithms in this situation.
Upvotes: 5