[myhdl-list] 2's compliment wrap (long post)
Brought to you by:
jandecaluwe
From: Christopher F. <chr...@gm...> - 2011-04-11 22:15:23
|
The signed 2's compliment wrap has come up before but it was embedded in other threads. I thought I would bring the topic up again. In many digital filters take advantage of the 2's compliment wrap property. One such example is the CIC filter (http://www.myhdl.org/doku.php/projects:gcicexample). Standard FIR and IIR filter implementations might exploit this property as well. The "wrap" behavior in this context is similar to an unsigned wrap. The "bits" behave the same but the "value" is signed. When the bit-vector wraps it goes from negative to positive. And there is an intermediate wrap as well, that half-way point, when we go one past the max positive value the value changes positive to negative. Example for a signed 3-bit word the following are the signed values for the range 3,-4. bin signed ----+-------- 000 0 001 1 010 2 011 3 100 -4 101 -3 110 -2 111 -1 000 0 001 1 To declare a Signal of signed type in MyHDL x = Signal(intbv(0, min=-4, max=4)) This type has all the desired features of an Int (as described in Jan D's "These Ints are made ..."). But I have not found a good way to do handle the 2's compliment wrap in MyHDL, yet. The unsinged wrap has been discussed before and there are a couple solutions, one being to explicitly use the mod operator, example. x = Signal(intbv(0)[16:]) ... x.next = (x + 1) % 2**16 For unsigned integers this works great. And it is has the benefit of being explicit and efficient. Someone looking at the code knows what is happening and the resulting hardware will be as expected, i.e. no additional hardware to handle the wrap inherent to a register word. For the signed case, I have thought of only two options: 1. "Cast" to an unsigned then cast back 2. Explicitly define the logic to describe the behavior. Option 1, produces the desired circuit but seems like there should be a better option? Option 2 is complicated and doesn't automatically simplify (addition hardware is generated). Option 2 I incorrectly posted on the wiki as an example (will fix soon). Any hints or ideas? Maybe one method would be to have a wrap() function (or whatever might be a good name). Similar to the concat() function. The wrap() function can work for signed and unsigned. And can automatically handle the "values" of the types. For conversion, nothing has to happen, just identified that the user wants the behavior of the wrap. A user has to explicitly use a wrap the default boundary checks are still used but can be overridden by a user. Thanks Chris Felton |