Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
16602 Discussions

Determine address width in Verilog HDL with $clog2

Altera_Forum
Honored Contributor II
6,812 Views

Dear all, 

 

Does anybody know how to use the Verilog HDL $clog2 math function with the Quartus II software?  

 

I am trying to use the clog2 (=ceil(log2(x))) function to calculate the address width needed for a RAM block with x number of words, since I think it's a bit silly to have to input two different parameter values in a parametrized module when the parameters are equivalent. However, when I try to compile my design in Quartus, I get the follwing error: 

 

Error (10174): Verilog HDL Unsupported Feature error at VPP.v(82): system function "$clog2" is not supported for synthesis 

 

Any idea what I did wrong? Thanks in advance. 

 

Faruk
0 Kudos
8 Replies
Altera_Forum
Honored Contributor II
3,852 Views

In quartus, you have to use the so called "constant functions". This is a function that operates only on cosntants, and so can be used during the first steps of the synthesis: 

 

For example : 

 

 

module pulse(input Clk, input Reset, output Pulse); parameter COUNTS = 33; reg count; assign Pulse = count == 0; always @(posedge Clk or posedge Reset) if (Reset) count <= 0; else count <= count + 1; //ceil of the log base 2 function integer CLogB2; input Depth; integer i; begin i = Depth; for(CLogB2 = 0; i > 0; CLogB2 = CLogB2 + 1) i = i >> 1; end endfunction endmodule 

 

Stefaan
0 Kudos
Altera_Forum
Honored Contributor II
3,852 Views

Hello Stefaan, 

 

Thanks very much, I was able to use your code example to calculate the address widths.  

 

By the way, the IEEE Verilog standard mentions that the constant function must be defined locally within the module. This would mean that every time I would like to use the CLogB2 function I have to define the function within that module (locally). I guess that one way to solve this is to define useful functions in a header file and include the header when necessary: 

 

main.v 

module main(..) `include "MathFun.vh" parameter address_width=CLogB2(num_words); endmodule  

 

MathFun.vh 

//ceil of the log base 2 function integer CLogB2; input Depth; integer i; begin i = Depth; for(CLogB2 = 0; i > 0; CLogB2 = CLogB2 + 1) i = i >> 1; end endfunction  

 

Another way would be to try convince Altera that a function such as log2 is actually very useful in the real world ...(and that they should listen to the IEEE guys who have $clog2 as part of the standard :) ) 

 

Faruk
0 Kudos
Altera_Forum
Honored Contributor II
3,852 Views

Faruk, 

 

I put the function in the module everytime (I copy it in at the bottom every time). It's not that much work, and the functionality stays like you wrote it. For example if for some reason the function has to change, it can affect all your files that include MathFun.vh. I know in this case it will be unlikely that the CLogB2 function will change... 

 

Although for altera it can be outside the module, but this is not standard, and can cause problems with some simulators.  

 

 

Stefaan
0 Kudos
Altera_Forum
Honored Contributor II
3,852 Views

 

--- Quote Start ---  

 

Although for altera it can be outside the module, but this is not standard, and can cause problems with some simulators.  

 

--- Quote End ---  

 

 

 

Quartus II allows global functions if you are compiling with SystemVerilog extensions. Otherwise, you should get an error.
0 Kudos
Altera_Forum
Honored Contributor II
3,852 Views

Put the function into a package, and then call it from anywhere. I do it in package utils and then call it with utils::clog2() 

 

Simple and organized, and there is no need to add an include.
0 Kudos
Altera_Forum
Honored Contributor II
3,852 Views

Quartus II 9.1 supports the built-in $clog2 function from Verilog 2005 in all Verilog and SystemVerilog modes. Yes, this technically goes beyond the standard but also matches the behavior of other tools.

0 Kudos
Altera_Forum
Honored Contributor II
3,852 Views

 

--- Quote Start ---  

In quartus, you have to use the so called "constant functions". This is a function that operates only on cosntants, and so can be used during the first steps of the synthesis: 

 

For example : 

 

 

module pulse(input Clk, input Reset, output Pulse); parameter COUNTS = 33; reg count; assign Pulse = count == 0; always @(posedge Clk or posedge Reset) if (Reset) count <= 0; else count <= count + 1; //ceil of the log base 2 function integer CLogB2; input Depth; integer i; begin i = Depth; for(CLogB2 = 0; i > 0; CLogB2 = CLogB2 + 1) i = i >> 1; end endfunction endmodule 

 

Stefaan 

--- Quote End ---  

 

 

Thanks for your code Stefaan 

 

Can u please guide me if this were the case of a floor function instead of ceiling? My code includes a portion where i have to calculate the floor log of a variable. Your function worked great for a ceiling computation. Can u help me with floor function? Thanks alot
0 Kudos
Altera_Forum
Honored Contributor II
3,852 Views

$rtoi (real to integer ) is a floor function

0 Kudos
Reply