- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello everyone!
I have some considerations about the implementation of twos complement in a filter/decimation design. The ADC used in the design is AD7401, which had also been discussed earlier about. We have talked about it in general in two topics at AlteraForum and I also found a related topic at edaboard.com in which FvM had given some answers. Links are provided below. http://www.alteraforum.com/forum/showthread.php?t=21560 (http://www.alteraforum.com/forum/showthread.php?t=21560) http://www.alteraforum.com/forum/showthread.php?t=22104 (http://www.alteraforum.com/forum/showthread.php?t=22104) http://www.edaboard.com/ftopic353078.html (http://www.edaboard.com/ftopic353078.html) My question is simple: after implementig the filter normally, how can I get it to 2's complement? FvM refers to shifting the decimator's output. Wouldn't it be the same if we substracted a value of 32768 (unsigned decimal) from the original output? What about the libraries (packages) and TYPES used? Should we use the IEEE numeric_std.all package? Should we define our vectors as signed instead of std_logic_vectors? I found a good reference about VHDL types (link below), but it rather confused me. http://www.synthworks.com/papers/vhdl_math_tricks_mapld_2003.pdf (http://www.synthworks.com/papers/vhdl_math_tricks_mapld_2003.pdf) I am in knowledge about the theoretical approach of how ones/twos complement works. Thanks to everybody in advance!Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I personally would always recommend the numeric_std package, as it defines all the operators needed and you can write much more clearly what you intend things to mean. Plus you can do signed and unsigned math in the same file that you cant with std_logic_vectors.
All integers are usually 2's compliment already. Unsigned or signed are already 2's compliment. unsigned numbers are just signed numbers with an implied '0' infront of them. are you actually talking about normalisation? eg. taking a value in the range 0 to 255 and getting into the range -128 to 127 (normalising around 128)? for this you would subtract half of the range from the result (128), as you already suggested. This would be quite simple in VHDL using the IEEE packages. Assuming you have a std_logic_vector input thats really an unsigned number: signal normalised : signed(filter_op'high+1 downto 0); variable temp : signed(filter_op'high+1 downto 0);
temp := signed('0' & filter_op); --make it a +ve signed number. Only need a variable as its a simple type conversion.
normalised <= temp - (2** (filter_op'length-1) ); --normalise it around 0
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
There are two things: Signed vs unsigned numbers and two's complement notation. Only signed numbers can have negative values. The value/magnitude of a 2's compliment negative number is found by complement and add 1. The msb of the number is the sign bit.
There are other bases for complement(one, nines, tens, etc). If the ADC can have a negative output, then is already in complement form -- no doubt 2's, not 1's. If it can only have positive output, then it will have either unsigned output, or the msb will always be 0 resulting in an unused msb in the output. If for some reason you want to convert a positive output to a negative value, complement and add 1; Be aware that there may be unexpected results if the msb is 1. If I remember correctly complement and add1 effectively does the subtract of 32768.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Often an ADC uses offset binary number representation, e.g. an input range of -1.. +1 V is represented by 0x0000 to 0xffff, with 0x8000 for zero input. You can convert offset binary to two's complement and vis versa by simply inverting the MSB, respectively XORing with 0x8000.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Ok, thanks to all of you!
XORing with x"8000" is actually the same as substracting 32768! Just tell me what types to use: it seems to work with std_logic_vector and the unsigned.all library. Should I switch to numeric_std? Should I make signed signals?- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Yes switch to numeric_std, and use:
- signed signals when information is signed - unsigned signals when information is unsigned - std_logic when information is just a bunch of bits. It makes the code easier to understand.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page