Re: [myhdl-list] fixed-point thoughts : part two
Brought to you by:
jandecaluwe
From: Angel E. <ang...@gm...> - 2013-09-05 05:05:12
|
Chris, very nice wrap up. You have a very easy to follow writing style :-) I have a couple of very smalll comments. See below: On Thu, Sep 5, 2013 at 5:28 AM, Christopher Felton <chr...@gm...> wrote: > > In part one I discussed fixed-point representation and introduced > /fixbv/ construction. Representation is only part of the fixed-point > functionality. In this conversation fixed-point operations and the > proposed *resize* function will be discussed. > > First, lets review fixed-point mathematics, given two fixed-point > variables, /x/ and /y/: > > x = fixbv(0, min=-8, max=8, res=1/16) # siii.ffff > y = fixbv(0, min=-1, max=1, rest=1/128) # s.fffffff > > Addition and subtraction require the operands to be aligned, > they don't necessarily need to be the same word-length (wl) but > the "point" needs to be aligned, using the above as operands: > > siii.ffff000 > + ssss.fffffff > -------------- > siiii.fffffff > > once the operands are aligned normal 2's complement addition/ > subtraction can be performed. The maximum result would be > 2*max(x.max,y.max) (or max(len(x),len(y))+1). If addition or > subtraction is attempted and the values are not aligned an error > will be thrown, example: > > >>> x = fixbv(0,min=-8,max=8,res=1/16.) > >>> y = fixbv(0,min=-1,max=1,res=1/128.) > >>> x + y > AssertionError: Add: points not aligned > fixbv(0.00, format=(8,3,4), ) and fixbv(0.00, format=(8,0,7), ) Personally I'd say "decimal points", i.e.: "AssertionError: Add: points not aligned" Or even: "AssertionError: Add: points not aligned in fixed point operation" > It is assumed the /fixbv/ operations will actually return an > /int/ same as /intbv/ operations > > >>> x1 = fixbv(2.5,min=-8,max=8,res=1/16.) > >>> x2 = fixbv(1.25,min=-8,max=8,res=1/16.) > >>> x1 + x2 > 15 > > When assigned to another /fixbv/ the value will fit in the > format of the accepting object. > > >>> x1 = fixbv(2.5,min=-8,max=8,res=1/16.) > >>> x2 = fixbv(1.25,min=-8,max=8,res=1/16.) > >>> z = fixbv(0,min=-16,max=16,res=1/16.) > >>> z[:] = x1 + x2 > fixbv(3.75, format=(9,4,4)) It seems a bit easy to forget the [:], but I guess that is the same as in the original intbv... > For multiplication the operands do not need to be aligned before > the operation but the "point" bookkeeping needs to be accounted > > siii.ffff > * s.fffffff > ----------------- > ssiii.fffffffffff (total 16 bits) > > An example using the example operands: > > >>> x = fixbv(1.5,min=-8,max=8,res=1/16.) > >>> y = fixbv(0.25,min=-1,max=1,res=1/128.) > >>> myhdl.bin(x*y, 16) > '00000.01100000000' # 3/2*1/4 = 3/8 = 1/4+1/8 > > The basic mathematical operations have been reviewed, we will > exclude division for now because we can achieve "division" > by multiplying by the fractional parts. > > The next topic: rounding and overflow handling. During operations > it is common not to maintain the maximum word-length through out a > chain of operations. When reducing the word-length rounding and > overflow come into play. > > Example, multiplying two numbers requires len(x)+len(y) bits or > x.max*y.max range. It is typical for the result to be *resized* > after an operation. In the previous multiply example, it may be > desired to only preserve four fraction bits: > > ssiii.ffff ffff fff > ~~~~~~~~ <- these bits remove > > The remaining bits will be rounded based on the removed bits, > there are different rounding methods that can be used. This is > a base feature of a fixed-point package. Also, when resizing > overflow (underflow) is also an issue. If the value being > resized does not fit, it needs to be saturated or wrapped. > > As eluded, the *resize* function is essential, the resize function > will need to be a convertible function. Logic will need to > be created to handle the rounding and overflow. > > The proposed *resized* function will look like: > > resize(val,format > [,round_mode='convergent'] > [,overflow_mode='saturate']) > > Example: > > z[:] = resize(x+y,z) Probably a basic question, but why do you need [:] here? Doesn't resize return a fixbv? Also, I don't think there is a way for Python to pass the resize function z's size while using the assignment syntax. If there was resize() would not need the second parameter, which would be cool. Maybe the converter could know though... An alternative could be to add a "set" or "assign" method to the fixbv class. This method would be equivalent to a resize followed by an assignment? The result would be: z.assign(x+y) Which would get rid of the need to use [:] (if there is any) and to use z both as a parameter to resize and as its output. Cheers, Angel |