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?
-
\$\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\$Hearth– Hearth2021年07月26日 03:19:01 +00:00Commented Jul 26, 2021 at 3:19
-
\$\begingroup\$ Not very clear. Is there any example code snippet? \$\endgroup\$Mitu Raj– Mitu Raj2021年07月26日 04:26:07 +00:00Commented 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\$user16324– user163242021年07月26日 11:41:39 +00:00Commented Jul 26, 2021 at 11:41
1 Answer 1
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.
-
\$\begingroup\$ Jim is it true that you came back to this forum after 4 years? \$\endgroup\$quantum231– quantum2312021年07月26日 21:30:59 +00:00Commented Jul 26, 2021 at 21:30
-
2\$\begingroup\$ I keep busy with OSVVM and VHDL standards. \$\endgroup\$Jim Lewis– Jim Lewis2021年07月26日 22:14:43 +00:00Commented 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 isIMPLEMENTATION 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 anAWID
port of any size, including 0, by specifying that port asstd_logic_vector(ID_SIZE-1 downto 0)
for example, whereID_SIZE
is a generic that may turn out to be 0. \$\endgroup\$adentinger– adentinger2022年04月14日 15:43:16 +00:00Commented Apr 14, 2022 at 15:43