Verilog has a bunch of math system functions.

I'm trying to use $floor in my Verilog code but I'm getting this message: System function call floor is not allowed here

Does anyone know why I'm getting this message?

I have to say that before asking here I googled and couldn't find any solution.

This is my code to test $floor:

module floor_test();

  parameter kCols = 3;
  integer kCenterX = $floor(kCols / 2);


Thanks in advance

  • 3
    \$\begingroup\$ The keyword is here. Where are you using that function? Some code please. \$\endgroup\$
    – Oldfart
    Commented Jan 19, 2018 at 9:09
  • \$\begingroup\$ That is really not enough code to answer the question "what is 'here'?". \$\endgroup\$ Commented Jan 19, 2018 at 9:20
  • \$\begingroup\$ I wrote a simple code to test. I just want to learn how to use that function in Verilog. \$\endgroup\$
    – user204415
    Commented Jan 19, 2018 at 9:30

3 Answers 3


First note that $floor is a system function supported in IEEE1364-2005 (Verilog-2005) and IEEE1800 (SystemVerilog). Earlier versions of Verilog (IEEE1364-1995 and IEEE1364-2001) do not have $floor in the language.

The synthesizable portion of of Verilog and SystemVerilog is a subset of the languages. What constitutes as synthesizable isn't universal, but there is general concusses. The latest official synthesis guildlines I could find was IEC 62142-2005 (note: costs money or IEEE Xplore membership to read the document) and is based on Verilog-2001. Even today I don't see full compliance to this standard. For example I've seen little support for (* attributes *) even though it was explicitly added to IEEE1364-2001 for synthesizer to use. The best SystemVerilog paper I can find is this paper and mentions various supported features of semi-anonymous synthesizers as of 2014. $floor was not mentioned but doesn't mean there isn't support.

I cannot think of a technical reason why mathematical system functions shouldn't be be supported. Demand and competition tend to drive the synthesis support. Features that can gain or retain paying paying customers get top priority. Hence there is common support for $bits and $clog2. But low support for (* attributes *) because all vendors already used comments (// and /* */) for attributes as work around before IEEE1364-2001 release.

You do not need $floor for 3/2. With most programing and HDL languages, an integral divided by an integral will always return an integral which is the floor value. 3.0/2 or 3/2.0 on on the other hand will cast the integral to a real and will return 1.5. This value will be rounded when assigned to an integral (.5 will round down).

If you really need $floor or $ceil, try using it to assign a parameter. Your error message says "not allowed here", so there is a change support is limited to parameter usage. SytemVerilog type casting is another possibility to help with conversion (if your synthesizer supports it); ex. int'(), 10'(), PARAM'().

Also, be aware you can define the type of a parameter. If the type is note defined then integer is assumed. Note some synthesizer do not support real parameters. Others

parameter M = 3/2; // M is an inferred integer type (signed), value 1
parameter [3:0] N = 1; // N is an explicit 4-bit type (unsigned)
parameter R0 = 3.6; // R0 is an inferred real type
parameter real R1 = 4/3; // R1 is an explicit real type, value 1.33333...

There's a distinction in verilog (and most/all hardware languages) between synthesisable and non-synthesisable code.

Synthesisable code is intended to be used to define the hardware that's actually going to go into your target FPGA. As such, it will be a subset of everything verilog knows about.

Non-synthesisable code is intended to help with writing test benches, initialisation, general housekeeping, so that you don't have to drop out into another language just to do file access or floating point math.

Is your verilog setup happy that you're not intending to synthesise 'floor'?

  • \$\begingroup\$ I know that. What I think it's happening is that those functions are not allowed in Verilog but SystemVerilog. So, I think I should move to SystemVerilog and Vivado, since SystemVerilog is not supported in ISE. Am I right sir? \$\endgroup\$
    – user204415
    Commented Jan 19, 2018 at 10:33

Changing to System Verilog should allow you to use $floor on local parameters, comparable to this source. As @Neil_UK has pointed out, this is a non-synthesizable function, that should only be used for testing.

I can't comment so I'll add this here: This source states that ISE indeed doesn't support System Verilog. From experience I know that Quartus does.


Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.