question about types in VHDL

Hi everyone, I am fairly new to VHDL and had several questions about types conversions that I've numbered for easiness of separating them. Any help would be greatly appreciated.

I am using signed type throughout my program. Now, there is one third party function that outputs std_logic_vector, that I have to use. The function looks like its std_logic_vector signal is in signed format (the sine wave with positive and negative values). 1. Can I just assume that it's in 2's compliment format similar to signed? In other words, how does STD_LOGIC_VECTOR holds signed numbers?

  1. I understand that if I would like to match it to my internal signals, I would have to cast that signal to SIGNED. So, can I do SIGNED(STD_LOGIC_VECTOR signal) to do that? What would be the result of the above statement? Would it take the signal inside and convert it to 2's comliment? That would be useless for me if the signal is already in 2's compliment. If that's not correct, please let me know how can go around this.

  1. I suppose STD_LOGIC_VECTOR can hold any format (1's, 2's or just magnitude) as long as you keep in mind in which context you are using it. However, the moment you start using SIGNED function, how does VHDL compiler recognize the numbers from then? Does it still treat them as STD_LOGIC_VECTOR and 'makes a note' for itself that it contains 2's compliement?

  2. I've read that ieee.std_logic_arith and ieee.numeric_std are mutually exclusive libraries that you cannot use at the same time. Maybe using one or another one would somehow answer my questions above..

Big thanks in advance! Kofeyok

Reply to
kofeyok
Loading thread data ...

I understand your confusion. Types and type conversion is possibly the hardest part of learning VHDL. I can't say I am an expert, but I have written many apps in VHDL and I think I have a handle on this. std_logic_vector (slv) makes no assumptions about the data that is being conveyed by the type. The ieee.numeric_std library defines a signed and unsigned type that support vectors of std_logic, but *do* make assumptions of the type of numbers they are being used to represent. Otherwise, I believe these three types are the same.

This makes a difference only when you are doing operations that rely on the nature of the number type. If you are just calculating parity, then you don't care if it is signed or unsigned. My recommendation is to convert (not cast) the type when you need to change it. This will be supported by the ieee.numeric_std library for most conversions you will want to do. to_signed() will convert an slv to a signed type. TO_STDLOGICVECTOR() will convert back. I believe I am using a custom package to convert using "to_slv" possibly just because it is less typing, but I believe I can convert directly from integer to slv. Check the description of your library.

The ieee.std_logic_arith is not an IEEE library at all. Likewise with IEEE.STD_LOGIC_UNSIGNED and IEEE.STD_LOGIC_SIGNED. Worst of all, the unsigned and signed libraries are mutually exclusive unless you explicitly identify which library you are using on each conversion function. So you can't use both signed and unsigned types in the same program without difficulty. I suggest that you stay away from these. Below are the common libraries I use.

Library ieee; Use ieee.std_logic_1164.all; Use ieee.numeric_std.all;

--
Rick "rickman" Collins

rick.collins@XYarius.com
 Click to see the full signature
Reply to
rickman

Thanks for the reply rickman.

That makes sence now. I see that passing of values between modules is done using slv.. but you can can convert (not cast) inside of each module. The signed port gives non-synthesizable code. At least my simulator refuses to simulate.

Thanks

Reply to
kofeyok

I don't know that it matters what types you use when passing signals between modules. Signed types should be just as synthesizable as any others. Also, simulators should work with code that is not synthesizable. My test benches are seldom synthesizable and they run just fine.

I expect you have some other problem that changing the type is masking rather than fixing. The only issues with various types is when you want to mix them in assignments or other expressions. I don't think there are any arithmetic operators defined for slv while signed and unsigned do have operators such as +, -, ... Otherwise they are the same, no?

--
Rick "rickman" Collins

rick.collins@XYarius.com
 Click to see the full signature
Reply to
rickman

Rickman, Just for my own edification, why do you prefer to convert rather than cast. Do you consider it bad style, not portable, personnel preference? I recently transitioned to using numeric_std, and it appeared to me that casting looked more readable when going from std_logic_vector to unsigned and then back to std_logic_vector. It simulated and synthesized without problems, although I have to admit that I did not look at the gate level netlist. Do you think I am missing something?

Thanks, Newman

Reply to
newman

I struggled a bit learning VHDL, mainly with the strong typing and how to get around it. I found that casting could not be used in all cases, and I am still not clear exactly what it does. For example, I am pretty sure you can not cast an integer to an SLV.

Conversion, on the other hand, is done with functions written in VHDL. Conversion functions are well defined, normally the source is available and I can even write my own.

--
Rick "rickman" Collins

rick.collins@XYarius.com
 Click to see the full signature
Reply to
rickman

Rickman, I looked up type conversion in Ashenden's 2'nd edition (page 49), and that is what I did. I think I just misinterpreted what was meant by convert and cast in your message.

Newman

Reply to
newman

One final note. I was looking up some conversions in numeric_std and discovered that I *was* using both conversion and casts in my code. What I thought was a "cast" is actually a "qualified expression". From a conversion package.

-- std_logic_vector, signed and unsigned types are "closely related" -- no type conversion functions are needed, use type casting or qualified -- expressions -- -- type1(object of type2) -- type1'(expression of type2)

So a type cast will look very much like a conversion, but can only be done between closely related types. The qualified expression is what I had some trouble using. I think I don't fully understand the rules for using them, but I beive it is similar where an expression can be interpreted as more than one type, e.g. "010110" can be a bit vector or an slv.

newman wrote:

--
Rick "rickman" Collins

rick.collins@XYarius.com
 Click to see the full signature
Reply to
rickman

Rickman, thanks for taking the time for the reply.

sig_out_slv One final note. I was looking up some conversions in numeric_std and

Reply to
newman

That is useful info. I always clutter up my code with type conversions/casts from slv to integer and back to slv. This is much simpler.

Thanks, I appreciate the comment.

--
Rick "rickman" Collins

rick.collins@XYarius.com
 Click to see the full signature
Reply to
rickman

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.