Logarithm in Verilog

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!

7

5 Answers

If it is a logarithm base 2 you are trying to do, you can use the built-in function $clog2().

The answer to ADDRESS WIDTH from RAM DEPTH describes a couple ways to evaluate constant logarithms in this situation.

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 

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.

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 

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

You Might Also Like