UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
Explorer
Explorer
11,024 Views
Registered: ‎01-12-2009

Vivado 2015.1: Simulator handles default values for std_logic_vector function parameters incorrectly

When elaborating a function that accepts std_logic_vector parameters, where the parameter has a default value, Vivado 2015.1 incorrectly uses the width of the default parameter value to determine the static width of the parameter.


The attached simple design demonstrates the issue. The xsim1.tcl script will run the simulation build. Under Windows, xsim1.bat will invoke xsim1.tcl.

 

The code is not meant to do anything useful. It is a cut-down extract from the original code where I found this issue. But, it does synthesize under Vivado. The original code works perfectly fine under ModelSim for simulation and synthesizes under Vivado and XST.

 

Assuming I have this correct, and there is not some reason that what xelab is doing is correct somehow, please log a CR.

 

If xelab is right in its error report, please explain why.

 

If this is a known issue, I have found no indication that it is, then if you have some good workaround please let me know what it is. So far, all I have found is to create separate overloaded versions of the function. For our main code, where this issue shows up a lot, that is a real pain.

 

Ian Lewis

www.mstarlabs.com

0 Kudos
6 Replies
Xilinx Employee
Xilinx Employee
11,003 Views
Registered: ‎09-13-2014

Re: Vivado 2015.1: Simulator handles default values for std_logic_vector function parameters incorrectly

Let's look at simple example

________________

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity xsim1 is
end xsim1;

architecture Behavioral of xsim1 is
function BadDefault_f(B: std_logic_vector := (0 => '0')) return std_logic_vector is
begin
return B;
end;
signal A, B, Q: std_logic_vector(3 downto 0) := (others => '0');
begin
A <= BadDefault_f(B);
end Behavioral;

________________

Accoding to IEEE LRM 1800-2008, section 4.2.2.1

 

'For those parameters with modes, the only mode that is allowed for formal parameters of a function is the
mode in (whether this mode is specified explicitly or implicitly). The object class shall be constant, signal,
or file. If no object class is explicitly given, constant is assumed'

 

So in the above example, formal parameter 'B' is of class 'constant'.

 

Again according to section 4.2.2.2

 

'For a nonforeign subprogram having a parameter whose type is an array or record, an implementation may
pass parameter values by copy, as for scalar types. In that case, after completion of the subprogram body, if
the mode is inout or out, the value of each subelement of the formal parameter is only copied back to the
corresponding subelement of the associated actual parameter if the subelement of the associated actual
parameter is not forced. If a parameter of mode out is passed by copy, then the range of each index position
of the actual parameter is copied in, and likewise for its subelements or slices. Alternatively, an
implementation may achieve these effects by reference; that is, by arranging that every use of the formal
parameter (to read or update its value) be treated as a use of the associated actual parameter throughout the
execution of the subprogram call. The language does not define which of these two mechanisms is to be
adopted for parameter passing, nor whether different calls to the same subprogram are to use the same
mechanism. The execution of a subprogram is erroneous if its effect depends on which mechanism is
selected by the implementation.'

 

So be it pass-by-value or reference, in each case, the constrain will get set according to actual( which is 3 downto 0 here) which is similar to writing

 

function BadDefault_f(B: std_logic_vector(3 downto 0) := (0 => '0')) return std_logic_vector is

 

and hence correct error by Xelab.

 

Solution:

Change the function prototype to

 

function BadDefault_f(B: std_logic_vector := (others => '0')) return std_logic_vector is

 

or 

 

function BadDefault_f(B: std_logic_vector := (0 => '0', others => std_logic'left)) return std_logic_vector is

 

if the intention is to assign to only 0th element.

 

--dhiRAj

0 Kudos
Explorer
Explorer
10,987 Views
Registered: ‎01-12-2009

Re: Vivado 2015.1: Simulator handles default values for std_logic_vector function parameters incorrectly

Hello dhiRAj,


This does not sound right. In particular, what you say implies that you are evaluating the default parameter value in the case where you have an actual. The type of the port is to come from the formal or the default expression, not from both. Or, at least, that is how I understand it.

 

I think it is invalid to set an unconstrained default value such as (others => '0') for an unconstrained parameter such as std_logic_vector. At the least, no compiler I know of would allow it. And, extracting from LRM (IEEE Std 1076, 2000 Edition) "7.3.2.2 Array aggregates":

 

=================

The subtype of an array aggregate that has an others choice must be determinable from the context. That is,
an array aggregate with an others choice may only appear

...

b) As the default expression defining the default initial value of a port declared to be of a constrained
array subtype

...

=================

There are many other entries in this list of conditions where 'others' may be used, but all of them are related to the type of the target being constrained. Since std_logic_vector is not constrained, (others => '0') is not allowed.

 

 

While it is not exactly conclusive with respect to this context, LRM 7.3.3:

=================

7.3.3 Function calls
A function call invokes the execution of a function body. The call specifies the name of the function to be invoked and specifies the actual parameters, if any, to be associated with the formal parameters of the function. Execution of the function body results in a value of the type declared to be the result type in the declaration of the invoked function.

 

function_call ::=
function_name [ ( actual_parameter_part ) ]
actual_parameter_part ::= parameter_association_list

 

For each formal parameter of a function, a function call must specify exactly one corresponding actual parameter. This actual parameter is specified either explicitly, by an association element (other than the actual part open) in the association list, or in the absence of such an association element, by a default expression (see 4.3.2).

 

Evaluation of a function call includes evaluation of the actual parameter expressions specified in the call and evaluation of the default expressions associated with formal parameters of the function that do not have actual parameters associated with them. In both cases, the resulting value must belong to the subtype of the associated formal parameter. (If the formal parameter is of an unconstrained array type, then the formal parameter takes on the subtype of the actual parameter.) The function body is executed using the actual parameter values and default expression values as the values of the corresponding formal parameters.

=================

 

at least implies strongly that the type of the formal comes from actual or default expression, not from both.

 

In particular,

 

"Evaluation of a function call includes evaluation of the actual parameter expressions specified in the call and evaluation of the default expressions associated with formal parameters of the function that do not have actual parameters associated with them"

 

only applies the default expression in the case where the parameter has no actual.

 

I am not optimistic that I can, but I will try to find a more conclusive statement that the default expression is not to be evaluated in the case where there is an actual present, but I think it is quite clear by intent: the default expression provides the value in the case with no actual and it only has meaning in such a case.

 

Also, I have run this code through 4 different VHDL compilers and all of them except xelab agree that what I have is right. Those that agree include the Vivado synthesis elaboration.

 

Ian Lewis

www.mstarlabs.com

0 Kudos
Explorer
Explorer
10,972 Views
Registered: ‎01-12-2009

Re: Vivado 2015.1: Simulator handles default values for std_logic_vector function parameters incorrectly

Any more response on this? It is quite clear to me that what xelab is doing is wrong. - Ian
0 Kudos
Xilinx Employee
Xilinx Employee
10,965 Views
Registered: ‎09-13-2014

Re: Vivado 2015.1: Simulator handles default values for std_logic_vector function parameters incorrectly

Hi Ian,

 

Let me explain you based on your understanding

________

I think it is invalid to set an unconstrained default value such as (others => '0') for an unconstrained parameter such as std_logic_vector. At the least, no compiler I know of would allow it. And, extracting from LRM (IEEE Std 1076, 2000 Edition) "7.3.2.2 Array aggregates":

______

This is applicable for signal/variable declaration but the signal/variable at port level have different meaning because post elaboration/binding, these port becomes constraint based on actual hence (others => '0') is applicable and I assume all tool should be accepting that. You may try.

 

From text

 

__________

Evaluation of a function call includes evaluation of the actual parameter expressions specified in the call and evaluation of the default expressions associated with formal parameters of the function that do not have actual parameters associated with them. In both cases, the resulting value must belong to the subtype of the associated formal parameter. (If the formal parameter is of an unconstrained array type, then the formal parameter takes on the subtype of the actual parameter.) The function body is executed using the actual parameter values and default expression values as the values of the corresponding formal parameters.

__________

There is difference between evaluation and elaboration. Elaboration deal with semantic check while evaluation deal with value propagation, which happen during runtime for function/procedure call.

 

If you read the next statement in same text

 

___________

In both cases, the resulting value must belong to the subtype of the associated formal parameter. (If the formal parameter is of an unconstrained array type, then the formal parameter takes on the subtype of the actual parameter.) The function body is executed using the actual parameter values and default expression values as the values of the corresponding formal parameters

_________

This said two things

 

1> The constraint set according to actual parameter

2> Execution of function body depend both on actual value and default value but when the execution happen by reference in place of pass-by-value, the actual replaces the formal.

 

Regarding language ambiguity, being IEEE VHDL committee, I know it's there across different area as it's not always possible to expell each and every scenario explicitely.

 

Having said that, if you want this support in xelab, I can do that under 'relax' as according to you, other tools are supporting.

 

--dhiRAj

 

 

 

0 Kudos
Explorer
Explorer
10,936 Views
Registered: ‎01-12-2009

Re: Vivado 2015.1: Simulator handles default values for std_logic_vector function parameters incorrectly

Hello dhiRAj,

 

Sorry if I am being thick. And I appreciate your taking time to look at this issue.

 

However, while I think I understood what you said, I do not see how it can be valid to have an expression like  B: std_logic_vector := (others => '0') make sense anywhere.

 

It makes no difference where in the processing we look: compilation, elaboration, or anywhere else. The language does not provide the information to know the concrete type in the case of such an expression.

 

I took your simple example and modified the default expression for BadDefault_f() to (others => '0') in place of (0 => '0') as you suggested.

 

========

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity xsim1 is
end xsim1;

architecture Behavioral of xsim1 is
  function BadDefault_f(B: std_logic_vector := (others => '0')) return std_logic_vector is
  begin
  return B;
  end;
signal A, B, Q: std_logic_vector(3 downto 0) := (others => '0');
begin
A <= BadDefault_f;
end Behavioral;

========

 

Here is the result from

  ModelSim:

    ** Error: H:/Eng/MVhdl/Src/Top/Tests/Errors/xsim1/xsim1.vhd(8): (vcom-1076) OTHERS choice can not be used in unconstrained array aggregate.

 

  XST:

    ERROR:HDLCompiler:136 - "\\server1\ian\Eng\MVhdl\Src\Top\Tests\Errors\xsim1\xsim1a.vhd" Line 8: OTHERS choice cannot be used in unconstrained array aggregate.

 

  Vivado synthesis:

     ERROR: [Synth 8-211] could not evaluate expression: OTHERS in array aggregate without constraining context [h:/Eng/MVhdl/Src/Top/Tests/Errors/xsim1/xsim1a.vhd:8]

 

  xelab:

    ERROR: [VRFC 10-191] OTHERS is illegal aggregate choice for unconstrained target [h:/Eng/MVhdl/Src/Top/Tests/Errors/xsim1/xsim1.vhd:8]

 

So, none of these tools, not even xelab, will accept that unconstrained default expression for an unconstrained parameter to a function. And, that is what I expect.

 

I do not see any way for

   B: std_logic_vector := (others => '0')

 

to work anywhere in VHDL.

 

Both sides of the assignment are unconstrained. Unless there were a default width for an unconstrained array type, and I do not believe that VHDL has anything like that, there is no way for any processing of any kind to know what the concrete data type of B is in the case where there is no actual and the compiler has to use the default expression.

 

Of course, if there is an actual, then B does have a known width - that of the actual, but in that case the default expression is irrelevant.

 

I still think that what xelab is doing with a default expression like:

   (B: std_logic_vector := (0 => '0'))

 

is wrong. And, it certainly is different from what ModelSim, XST, and even Vivado's own synthesis elaboration does.

 

I do not think this is a matter of providing special relaxed handling to allow this kind of default expression. It should be allowed as part of the language: the default expression constrains the type of the formal in the case where the default expression is required.

 

If I am wrong, I appologize for wasting your time, but I do not think I am wrong.

 

Ian Lewis

www.mstarlabs.com

 

0 Kudos
3,051 Views
Registered: ‎08-17-2017

Re: Vivado 2015.1: Simulator handles default values for std_logic_vector function parameters incorrectly

Hiiiiii

I am implementing neural networks algorithm on FPGA. I called one of my functions in my package, but I got this error in following. Can anybody explain this kind of error for me cause there is nothing about it. Actually all of my functions in my package work perfectly except this function because of this error. I look forward to hear your answer.

 

ERROR: [VRFC 10-53] function is illegal in an expression.

 

Best regards

0 Kudos