Quartus error when using a VHDL function

Status
Not open for further replies.

shaiko

Advanced Member level 5
Joined
Aug 20, 2011
Messages
2,644
Helped
303
Reputation
608
Reaction score
297
Trophy points
1,363
Activity points
18,302
I wrote the following VHDL function to determine the clock period in nanoseconds of a certain frequency.
Code:
	function period_ns ( frequency_hz : unsigned ) return unsigned is 
	variable second : unsigned ( 31 downto 0 ) := "00111011100110101100101000000000" ; -- 1,000,000,000 ns  ( or 1 second )
	variable result : unsigned ( 31 downto 0 ) ;
	begin 
		result := restoring_divide ( second , resize ( frequency_hz , 32 ) ) ; -- restoring divide is another function I wrote in my package
		return result ;
	end function period_ns ;
In my entity I have an input defined as follows:
Code:
frequency_x : in unsigned ( frequency_x_width - 1 downto 0 ) ; -- "frequency_x_width" is an entity generic
I apply the function "period_ns" on "frequency_x" as follows:
Code:
constant period_ns_frequency_x ( frequency_x ' range ) := period_ns ( frequency_x ) ;
Note: the input "frequency_x" is driven by a constant and explicit value at the top entity.

When I synthesize my code. Quartus, gives the following errors:
Error (10346): VHDL error at package_functions.vhd(368): formal port or parameter "frequency_hz" must have actual or default value
Error (10657): VHDL Subprogram error at top.vhd(118): failed to elaborate call to subprogram "period_ns"

As I mentioned - although "frequency_x" is defined as an unsigned input - it is driven by an explicit value from the top entity. So I really don't see why synthesis fails.
 

I could be wrong, but I believe that you can't define a constant with anything but a constant value or a generic. An input port is not considered a constant even if it is ultimately connected to a constant at the top level.

I'm not sure what your doing is a good idea. Looks like you're writing a software library package with VHDL. The restoring_divide is probably written as a for loop and when it gets unrolled you'll have 32+ levels of logic.

Regards
 
Last edited:
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating
You're correct regarding the restoring divide. I'm well aware of the low speed of its unpipelined nature - but I don't use it for high performance applications.

I could be wrong, but I don't believe that you can't define a constant with anything but a constant value or a generic. An input port is not considered a constant even if it is ultimately connected to a constant at the top level.
That was my first thought...but I'm also not sure.
 

Well I know verilog won't allow it, I'm pretty sure VHDL has the same restriction. As coded it could be hooked up to something that is not a constant.
 
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating
Something interesting - instead of using the "period_ns" function directly, I tried the following:
Code:
constant period_ns_frequency_x : integer := 1000000000 / to_integer ( frequency_x ) ;
Works flawlessly! That really baffles me...
 

Quartus doesn't a 100 percent analysis of illegal VHDL constructs. The fact that a code compiles without errors doesn't assure that the code is synthesized to something meaningful.

In the present case you can refer to VHDL LRM 4.3.1.1 Constant declarations

This means period_ns_frequency_x will be only calculated at compile time. If the result depends on an actual port signal, no value will be calculated.

Apparently Quartus accepts the second syntax although the code is meaningless according to VHDL rules. In my view, it's question of limited interest why an error is generated in the first case.

I'm sure that you can find out what's the particular syntax detail Quartus finally stumbles upon, if you lack of anything better to do.
 
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating

I really don't see how my code violates any of the above. Although being an input port - "frequency_x" is a constact given a fixed and explicit value during compilation.
The fact that this value is set out of entity - doesn't make it "less constant". Would you agree?
 

Although being an input port - "frequency_x" is a constact given a fixed and explicit value during compilation.

I won't be completely surprized if a synthesis tool does understand this construct. But Quartus at least doesn't.

Quite clearly VHDL LRM doesn't account for this usage of ports. Generics are the right way to feed constant values.

What's your motivation to insist in trying the unsupported construct?
 
Last edited:
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating
What's your motivation to insist in trying the unsupported construct?
I want my code to be as versatile as possible.
Sure I can define "frequency_x" as a generic integer. But this will immediately constrain it to a 32 bit value.
I can also define "frequency_x" as a generic unsigned. But again, I'll have to specify the exact vector width.

If what I wrote worked - It would free me from having to constrain the vector width of my input ports when describing the entity.
A workaround for the lack of support for unconstrained arrays in VHDL...
 

In the present example, 32 bit integer is more than ever needed, because the unit is integer Hz. Yes, I can imagine cases where you want more resolution. But other than with port signal, excessive bit width of an unsigned generic costs nothing. The actual length can be set by another generic, as intended. So I don't see an actual problem.
 
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating
Yes, you can do that too. But that's not very pretty VHDL.
Are integers in VHDL 2008 also constrained?
 

Range of integer type is implementation dependant (32 bir being the standard), not specified in the VHDL standard.
 
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating
You're saying that the fact that an integer is 32 bits - is because of the design of the synthesis/simulation tool? And it has nothing to do with the language itself ??
 

You're saying that the fact that an integer is 32 bits - is because of the design of the synthesis/simulation tool? And it has nothing to do with the language itself ??
The VHDL language specifies a minimum range for integer, so all tools must use 32 bits or more to represent it. I don't know any tool that use more than 32 bits.
 
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating
Yes, thanks for the correction. 32 bit is minimum range:

The only predefined integer type is the type INTEGER. The range of INTEGER is implementation dependent, but it is guaranteed to include the range –2147483647 to +2147483647. It is defined with an ascending range.
 
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating
It's strange why Verilog tools don't have this limitation.
Thanks a lot for your help.
 

Verilog LRM has a quite similar specification:

Implementations may limit the maximum size of integer variables, but it shall be at least 32 bits.
 

Yet popular FPGA synthesis tools (ISE, Vivado, Quartus, Synplify) don't limit the integer values to 32 bits - right?
 

Yet popular FPGA synthesis tools (ISE, Vivado, Quartus, Synplify) don't limit the integer values to 32 bits - right?

I think all of them limit integers to 32 bits. There is no meaning with a synthesis tool that can handle larger integers than your simulation tool. How would you verify your design?
 
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…