When to use VHDL library std_logic_unsigned and numeric_std?
Asked Answered
S

2

9

I use VHDL-200X in ISE.I always use data type like std_logic_vector,std_logic,integer,boolean and real.Always use std_logic_vector convert to integer and reverse. My team mates ask me to use these three parts of library IEEE.

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

But someone said do not use IEEE.STD_LOGIC_UNSIGNED.ALL instead of IEEE.NUMERIC_STD.ALL.Because you have everything you need in numeric_std, and STD_LOGIC_UNSIGNED is not standard library. Here.

I confused about it and anybody can help?

Spatter answered 16/8, 2017 at 2:19 Comment(4)
See electronics.stackexchange.com/questions/188622/…Careerist
Nobody knows your team mates, and their intentions. They may just does not know this issue. I would ask them why they insist on using STD_LOGIC_ARITH and STD_LOGIC_UNSIGNED instead of numeric_std.Adviser
They say if you do no do any arithmetic operations you no need for numeric_std.@AdviserSpatter
Almost the same question.Thank you.@CareeristSpatter
I
26

Never use std_logic_arith or std_logic_**signed. Always use numeric_std when signed or unsigned values are needed. The former packages claim to be IEEE, but they aren't. They are vendor specific extensions from Synopsys or Mentor Graphics.

Both defined arithmetic operations on std_logic_vector based on the imported packages. This e.g. means you can't used signed and unsigned values in the same architecture.

Doing all math in integers has some drawbacks:

  • no uninitialized value
  • no 'X' propagation
  • limited to 32 bits
    (How to write a 64 bit counter?)
Incision answered 16/8, 2017 at 7:23 Comment(7)
But if I almost no need for 'signed' or 'unsigned' type when I writing a control function module?Spatter
What's the meaning of uninitialized value?What's the meaning of no 'X' propagation?Spatter
If you have no need for signed and unsigned values, then don't use any package other then just std_logic_1164 ... No need to load more unused types and operators into the current scope.Incision
For 'U': In simulation, you'll be able to see registers without default values, undriven signals, because they initialize to 'U' and circuits never reset. For 'X', even when viewing only top-level signals, you'll have the chance to see an internal X value on top-level, because errors ('X') are going through your design and are bubbling to the top. That's why we use std_logic instead of bit as a datatype.Incision
N.b. wrt language: "Latter" would refer to the second of two. Opposite would be "former", but in this context I would just repeat their names ;)Precondition
Thank you.@IncisionSpatter
@LiangHe: Please read this great paper on the importance of 'X' and 'X' propagation, this is the minimum in the industry. (I also use it for other purposes.)Glandule
R
8

My purist side agrees with @Pabbles. OTOH, my pragmatic side dissents. My pragmatic side wins, and hence, I recommend the following (until numeric_std_unsigned is supported):

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

For RTL design, I recommend that you use types signed and unsigned for all operations you consider to be math. This is my purist side.

In RTL, I never recommend doing math in std_logic_vector, instead, std_logic_unsigned is just there for a safety net. Consider that all relational operators are implicitly defined (=, /=, <, <=, >, >-). In a design, we do a lot of comparisons to values:

if A = "00001" then 
. . . 
if B = X"1A" then 

What happens if A is not 5 bits? What happens if B is not 8 bits? If you use the implicitly defined comparison, it is FALSE. If you use the comparison from std_logic_unsigned, it is ok if the sizes are different. If you are not using std_logic_unsigned, your testbench should find this issue.

Since "=" is ok to use with RTL, what if someone is doing an address decoder and writes:

Sel <= '1' when Addr > X"3FFF" else '0' ; 

If A is 16 bits, then it should work out ok. What if A is not 16 bits? Then it does a lexicographic (dictionary ordered) comparison. IE: "100" > "01111" is TRUE.

With std_logic_unsigned, these will be handled by unsigned math rules. Which for most cases is correct. Without std_logic_unsigned, these will result in FALSE. If you are not using std_logic_unsigned and you are careful with your testbenches, you should find this.

My concern is that if you don't use std_logic_unsigned then you have a potential that the circuit that you simulate will be different than the circuit that you synthesize (as the synthesis tools tend to create an implementation that is consistent with std_logic_unsigned). If you miss catching this in simulation, it will be real difficult to find in a review. Hence, I recommend std_logic_unsigned as a safety net when using ordinary relational operators.

Note that VHDL-2008 introduces the package numeric_std_unsigned and I plan on switching to that when it works across all synthesis tools.

My really strict side says that we should address the issues with the ordering operations (<, <=, >, >=) by creating additional packages that also overload them for std_logic_vector, and hence, use of them results in an error due to ambiguity. Note we cannot protect "=" this same way.

VHDL-2008 adds matching relational operations "?=", "?/=", "?>", ... when these are available in your synthesis tools, I recommend switching to these. The matching equality operations (?=, ?/=) require operands to be the same length - meaning compile error if they are not equal length. The matching ordering operations (?>, ?>=, ?<, ?<=) are only defined in a math package such as numeric_std or numeric_std_unsigned - hence, you cannot use them unless you are using an appropriate math package.

Rudolf answered 16/8, 2017 at 17:21 Comment(1)
Thank you. @Jim Lewis Very detailed answer.I have to have a time to read it.Spatter

© 2022 - 2024 — McMap. All rights reserved.