How can I convert a vector of say STD_logic_vector into an integer?
How can I convert a vector of say STD_logic_vector into an integer?
signal int : integer:
signal myvector : std_logic_vector(n downto 0)
int <= conv_integer('0'&myvector) ; --for unsigned conversion
int <= conv_integer(myvector); -- for signed conversion
Hope it helps
and how to convert an integer to std_logic_vector given that I don't want to use std_logic_arith as it's obsolute ?
Of course, you can use ieee.numeric_std instead of ieee.std_logic_arith. But as a fact, most vendor packages are still based on std_logic_arith. I prefer it, too. The above conversions are also from std_logic_arith.
integer to std_logic_vector conversion needs to clarify the intended numeric representation first, so you can either use TO_SIGNED() or TO_UNSIGNED() first, casting the result to STD_LOGIC_VECTOR:
slvsignal <= STD_LOGIC_VECTOR(TO_UNSIGNED(intval,bitlen));
Is it enough to cast the result, or I need to use TO_STDLOGICVECTOR function ? and what is the difference between the 2 cases ?Originally Posted by FvM
all conversion functions are described here for both numeric_std and std_logic_arith
Good, but what is the purpose for this function : TO_STDLOGICVECTOR ? .. and in general, what is the difference between type conversion and type casting ?Originally Posted by firefoxPL
There is no function "to_stdlogicvector" concerning integers. There is one, but this is to go from bit_vector to std_logic_vector. Bit_vectors are "arrays of bit" and defined in the VHDL standard library. But because the type "bit" is only ('0','1') it is hardly ever used, std_logic has augmented it.
There are castings from similar types to each other. Similar types are types that have a common ancestor. std_logic_vector, unsigned and signed have a common ancestor: "array of std_logic". So they are closely related and the built-in casting can be used: uns_sig <= unsigned(stdvec_sig) and stdvec_sig <= std_logic_vector(uns_sig). Built-in casting means just write the destination type and parentheses: destinationtype(...thing to be cast...)
integer (and subtypes natural and positive) are also closely related so you can cast between these: e.g. integer(0-natural(positive(3)))
But the "array of std_logic"-types are not closely related to the "integer"-types, so special conversion functions, defined in the IEEE packages are used. For numeric_std (the one and only official IEEE package! Please help stamp out the obsolete packages and only use numeric_std!) these are called to_something, with something="unsigned" or "signed". There is no to_std_logic_vector because this would not make sense. A std_logic_vector is supposed to be a collection of std_logics that doesn't represent a number. If you want to represent a number the "unsigned" and "signed" types are used, and this automatically makes it clear which representation should be assumed when converting (sign bit or not).
So if you really need to go from integer to a std_logic_vector, you first convert using a conversion function to whatever you want the representation to be (signed or unsigned). Then, you can use a built-in cast to interpret it as a std_logic_vector.
If the thing you represent is a number, it would of course be better to keep the signed or unsigned type. It is exactly the same vector as a std_logic_vector, but it retains the concept of "number", and you can do number-like things on them.
Personally I only use std_logic_vectors for
- groups of std_logics that are not a number, e.g. bitmasks, status bits, ...
- top-level I/O buses because synthesis tools have a tendency to write out netlists with "std_logic_vector" for buses, even if the original VHDL code specifies "signed" or "unsigned". This way, the synthesised netlist still plugs into the testbench without having to write wrappers.
Do you mean that , in all other situations, you declare your signals and even low-level-modules-ports to be of type signed/unsigned ? this is in order to have a meaningful number for the collection of bits they represent ?Originally Posted by vomit
Depends on what you call low-level modules. Of course, if the module exists already (IP cores, wizard-generated modules), then i just stick with that.
But for my own entities, yes, I define subtypes based on unsigned/signed.
This also provides for some additional type checking and easy naming of signals of that type:
The user of the code can now use the subtypes in the package for declaring the signals that need to be port mapped. Thanks to the "unsigned", he can do easy arithmetic on addresses, but still do bit-stuff like with std_logic_vector because unsigned is also an "array of std_logic". For the data bus, it can be argued that it is not strictly numeric. The choice for std_logic_vector or unsigned can be debated in this case.Code:package myentitypack is subtype t_AddressBus is unsigned(9 downto 0); subtype t_DataBus is std_logic_vector(7 downto 0); component myentity is ... port ( Address : t_AddressBus; Data : t_DataBus; ... ); end component myentity; end package myentitypack;
The trick with subtypes: compare it with C code, where you can use "int" everywhere, or make auxiliary typedefs to add additional type-safety to some functions. By adding typedefs you make sure the user doesn't mis-use a function outside the way it is intended. If the user wants to use some other std_logic_vector that happens to have the same length as a DataBus, he will be required to cast it "t_DataBus(myvector)" to confirm that this is really the intention and not a coincidence. This is good software practice.
What do you think if one uses std_logic_vector extensively and whenever he wants to carry out any number-based operation, he type-casts this std_logic_vector to a signed or unsigned type .. won't that remove all the types/subtypes headache from your design ?
For example, you define a signal as x:std_logic_vector .. and y:std_logic_vector .. then do the following:
z <= signed(x) * signed(y);
z <= unsigned(x) * unsigned(y);
and in what cases do you need to use the libraries, std_logic_signed and std_logic_unsigned ?
Whether or not it's a head-ache depends on what you're used to.
I'm used to seeing signed and unsigneds everywhere. So whenever I need the number there's a big chance I won't have to convert at all. After all, it's a number, so there is a big chance I'll do arithmetic on it (+1, load a counter with it, ...). The counters are of course also built out of unsigneds, after all they are numeric by definition.
It's more the opposite: on occasion I have to cast an unsigned to a std_logic_vector to interface with IP cores and toplevel I/O pins. Or to concatenate them into a microcontroller visible register where the "numeric" aspect is no longer valid. Casting can also be done within port maps, so it doesn't necessarily take auxiliary signals.
What you describe (having std_logic_vectors everywhere and casting locally) works perfectly, but is perhaps more dangerous (you have to decide/remember locally if the std_logic_vector is representing a signed or unsigned). I prefer to have dedicated subtypes to remind me for each signal type what it is: the range and (un)signedness. Whenever I need to go from 'apples' to 'oranges' I'm forced to think if and how they are compatible. This is an extra type safety. After all, that's why VHDL/ADA are strongly typed languages: to avoid mistakes.
My reasoning is simple and coherent: if it's an array of std_logics that represent a number without sign bit, don't use std_logic_vector but unsigned. Because that's exactly what unsigned was meant for. The same reasoning applies for signed. That way the entire meaning of the vector is contained in the type of the signal. This benefits readability and understandability.
Furthermore, there are some nice functions like "resize()" that work on signed and unsigned, and automatically take care of '0' or sign bit extension depending on the parameter type.
http://www.eda.org/rassp/vhdl/guidelines/1164qrc.pdf has a nice compact overview of the numeric_std library. Please throw away page 2 of that PDF, those are all vendor-specific packages, not IEEE.
Little remark: §2.4 "conversion functions" also calls the built-in cast operations (3 first items of §2.4) a "conversion function", this is strictly speaking not correct.
Now, to conclude, it looks to me like I don't need from IEEE except std_logic_1164 and numeric_std .. Am I correct ? those at least are enough for all basic operations ..
There is an official IEEE.math_real package, but I only use that for testbenches, more specifically for the nice random number functions.
There is also the IEEE.std_logic_textio for testbenches, but hasn't got anything to do with our discussion.
Don't use the signed/unsigned lookalikes from IEEE.std_logic_arith, IEEE.std_logic_signed or IEEE.std_logic_unsigned, these are obsoleted by IEEE.numeric_std.
go to conversion function in language templet