1
\$\begingroup\$

If the std_logic_vector range is defined in such a way that its number of elements come to 0 or less than it, the array is said to have a null range. I am sure this is possible with any array in VHDL.

Now my simulator tool does give a warning for when this happens. However, I am wondering, why is null range allowed in VHDL? Shouldn't it just throw an error and fail to compile or simulate? What is the usage of null range in VHDL?

asked Jul 25, 2021 at 20:49
\$\endgroup\$
3
  • \$\begingroup\$ It's possible there is no intended use, the people programming the compiler and/or writing the standards for the language just didn't think "i don't see a point in doing this" was a valid reason to prevent people from doing something. \$\endgroup\$ Commented Jul 26, 2021 at 3:19
  • \$\begingroup\$ Not very clear. Is there any example code snippet? \$\endgroup\$ Commented Jul 26, 2021 at 4:26
  • \$\begingroup\$ Quite often the null range is a degenerate case, for example in a circuit configured by generics, where you want nothing to happen when generic SIZE = 0. Without null ranges you have to clutter your code with special case logic to handle cases like that. (With them, you still have to satisfy yourself the circuit behaves "correctly" for that case; i.e. does nothing) \$\endgroup\$ Commented Jul 26, 2021 at 11:41

1 Answer 1

3
\$\begingroup\$

The message simulators give when they encounter a NULL array is generally incorrect. They generally say something like:

Simulator 1:
# Warning: COMP96_0119: [..snip..] The range is 'null range'.
Simulator 2: 
# ** Warning: [..snip..] (vcom-1246) Range 0 downto 1 is null.

In VHDL, NULL arrays are not an error (things a tool can detect) or even erroneous (things a tool may not be able to detect, but are wrong). Instead they are handy to deal with boundary conditions. So the message is more of a "lint" message that they think is useful. Unfortunately as a developer of Open Source VHDL Verification Methodology (OSVVM) which uses NULL arrays (correctly) I find the current form of their messages problematic at the best - it confuses people and causes them to report a bug when there isn't one.

So the message should be clearly identified as a "Lint Warning" and not in any way imply that you made a mistake. It should be more like the "Warning: Possible infinite loop".

Maybe something like:

# Warning: Possible range constraint error. The range 0 downto 1 is null.

This situation is made more confusing since they use the same language when they talk about things they choose to ignore, but are actually illegal. Usage of a shared variable of an ordinary type is currently signaled as:

# Warning: [.. snip ..] Shared variable is not of a protected type. 

Since this one has been illegal since 1076-2002, it should be reported with different language, such as:

# Warning (suppressed Error): [.. snip ..] 1076-2002 requires a shared variable to be of a protected type. 

A NULL array in std_logic_vector is:

constant NULL_SLV : std_logic_vector := "" ;

One place we use them is to convert a std_logic to a math type like unsigned:

Y <= A_uv8 + ("" & CarryIn_std_logic) ; 

Where I use them most is on subprogram inputs to make the usage of the parameter optional:

 constant NULL_BIN : CovBinType(1 to 0) := (others => ( BinVal => ALL_RANGE, Action => integer'high, Count => 0, AtLeast => integer'high, Weight => integer'high )) ;
 ------------------------------------------------------------
 procedure AddCross(
 ------------------------------------------------------------
 ID : CoverageIDType ;
 Name : string ;
 AtLeast : integer ;
 Bin1, Bin2 : CovBinType ;
 Bin3, Bin4, Bin5, Bin6, Bin7, Bin8, Bin9, Bin10, Bin11, Bin12, Bin13,
 Bin14, Bin15, Bin16, Bin17, Bin18, Bin19, Bin20 : CovBinType := NULL_BIN
 ) ;

By doing this, AddCross can accept between 2 and 20 parameters of CovBinType. Internally then it has to detect if Bins Bin3 to Bin20 are NULL_BIN, something that is easy to check for. It is much better than having 19 different versions of basically the same thing.

answered Jul 26, 2021 at 20:22
\$\endgroup\$
3
  • \$\begingroup\$ Jim is it true that you came back to this forum after 4 years? \$\endgroup\$ Commented Jul 26, 2021 at 21:30
  • 2
    \$\begingroup\$ I keep busy with OSVVM and VHDL standards. \$\endgroup\$ Commented Jul 26, 2021 at 22:14
  • 1
    \$\begingroup\$ I might add that this is useful when entities have ports that, depending on some generics or for other reasons, may not be present, or whose size is irrelevant. E.g. with AXI4, the AWID port's width is IMPLEMENTATION DEFINED according to the standard, so it can be 0. So we may want to define an entity that is able to take an AXI4 bus with an AWID port of any size, including 0, by specifying that port as std_logic_vector(ID_SIZE-1 downto 0) for example, where ID_SIZE is a generic that may turn out to be 0. \$\endgroup\$ Commented Apr 14, 2022 at 15:43

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.