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...