Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

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:
  • Like
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.
 
  • Like
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
If the assignment symbol ":=" followed by an expression is present in a constant declaration, the expression specifies the value of the constant; the type of the expression must be that of the constant. The value of a constant cannot be modified after the declaration is elaborated.

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.
 
  • Like
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating
If the assignment symbol ":=" followed by an expression is present in a constant declaration, the expression specifies the value of the constant; the type of the expression must be that of the constant. The value of a constant cannot be modified after the declaration is elaborated.

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:
  • Like
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.
 
  • Like
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.
 
  • Like
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.
 
  • Like
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.
 
  • Like
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?
 
  • Like
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating
Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top