|
From: Stephen W. <st...@ic...> - 2008-08-15 16:24:42
|
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Let me try to cut this issue down to its essence: $clog2() is an integer function that takes a self-determined unsigned logic vector argument and returns an integer. $clog2() of x returns x. Since the argument is unsigned logic vector, a real argument is implicitly cast to unsigned logic vector. Real values an be +-Inf, NaN, or finite. +-Inf and NaN can be treated as X. Finite real values (64bit double) can be always represented in 1024 or fewer bits, so any finite real/realtime has a finite $clog2() result and we want to support the whole range. At compile time this is easily done (and there are patches in waiting to handle it). At run time the simplistic algorithm is obvious: Convert NaN/Inf to a vector of X, and convert all other finite values to its integer vector value. In non-self-determined contexts (i.e. assignment to an l-value with width-N) it is obvious that the low N bits are the width of the result, but in self-determined contexts, the width of the result of the cast is unspecified, but we know that any width of >=1024 will preserve the entire integer value of any finite double. So tell me how this will go wrong: Convert real values to 1024bit logic vectors: ~ Convert NaN and Inf to X. ~ Round all other finite values to the 1024 bits value. Pass the 1024 bit vector to $clog2(). ~ The result will be <11. Cary R. wrote: | --- On Thu, 8/14/08, Stephen Williams <st...@ic...> wrote: | |> | The problem is dealing with + or - infinity. Given the |> | definition for $clog2() both of these should return an |> | infinite number of 1's. |> |> Hmm... Given the stated purpose for $clog2, I would say |> that |> $clog2(Inf) should be X. The clog2 of Inf is not |> representable |> in any finite number of bits so I would just say so and |> have |> $clog2() return X if the input is Inf. | | That makes sense. I still say -1 is more the Verilog way | of doing it, convert and take the lower bits as needed. | We are doing conversions like this (converting to -1) in | other places! | |> BTW, the log() functions in C return EDOM or ERANGE for |> infinite |> arguments. | | It can also return Inf for positive infinity and NaN for | negative infinity, but given how $clog2() defines the | conversion of negative values -infinity looks a bit like | positive infinity. So both effectively return Inf. | |> | The next issue is with real to integer conversions. |> Basically |> | real to vvp_vector_4. $clog2() needs this functionality |> though |> | it will likely need to special case + and - infinity. We |> still |> | need to define what the function does for the infinities. |> I |> | need to figure this out again since I forgot to write it |> down, |> | but from memory we need at most 1024 bits to fully |> represent a |> | double. NaN can be represented as a single bit of x. The |> | infinities could be represented as all 1's or 0's |> depending on |> | the sign and to make them unique maybe add one extra |> digit to |> | distinguish them from the finite values. |> |> For the case of a double (64bit floating point with 11 bits |> of |> exponent) we can indeed represent the integer part of any |> possible |> value. I didn't think of that, but there you go, at |> least for |> when the expression can be fully evaluated at compile time. | | I have this fully working for anything that can be evaluated | at compile time. The sticking point is for people who pass | a variable to it or when it is used in a continuous assign, | since continuous assigns have almost non-existent constant | reduction. | |> I think we can get similar results with the %cvt/vr opcode |> with |> an appropriately sized width argument. | | That's effectively what I am doing. %cvt/vr uses the double | to vvp_vector4_t constructor that I wrote a few months ago. | The problem is what is the width? for the case of %cvt/vr | the compiler has told us how many bits we want. For $clog2() | we do not have that since this is an intermediate result. | |> | This all works fine until we try to work this into the |> | confines of the VPI interface. The fundamental problem is |> I |> | can ask to get the vector representation of a real |> number, |> | but how do you determine the number of bits/contained in |> | the vector? The way this is currently coded the number of |> | bits can change based on the value and if we made this |> fixed |> | we can't distinguish between 0 and minus infinity. |> vpiSize |> | is currently defined to be 1 for real values and making |> it |> | return the number of bits need to represent the current |> | valjue would break compiletf routines. |> |> I think this might be getting out of hand:-( I'm sure |> other tools |> cheat and just convert to a 64bit value. And I think that |> +-Inf |> should become x. | | I don't like cheating and if we do, what do we do for values | that are larger than will fit in 64 bits? | |> In any case, I think we can dance around the issue by |> having the |> compiler write a %cvt/vr instruction and forget trying to |> shove |> aleph numbers through VPI;-| | | We also have to address this for continuous assignments. | |> | A way to do this is to make $clog2() part of the runtime |> | and not be a VPI routine. This would give us direct |> access |> | to the vvp_vector_4 routines, but would require some form |> | of manual compiletf routine checking. I think this is the |> | only way to make this work correctly and that we need to |> | add hooks to support compiletf routines for functions |> | defined in the runtime. |> |> Have the compiler convert it to a large integer. Will that |> not work? | | I believe the compiler side of this works flawlessly. The | problem is when $clog2() is used with a variable or when it | is used in a continuous assign (they do not do proper | constant folding). Remember this function can be used as a | constant function. It does not have to be used that way. | |> Another thought: is there a VPI way to ask for the type of |> the |> argument and process it directly as a real value instead of |> doing a hackish semi-convert. vpi_get_value with a format |> of |> vpiObjType might help here. | | Yes you can get the type of the object, but the way I read | the definition of $clog2() it explicitly expects a real | value to be converted to an integer value. Well at least | negative values must be converted and to use the precise | conversion routine positive values must also be converted. | Not using this routine leaves you open to rounding errors, | etc. | |> | So the executive summary is, NaN or an argument with a |> | x will return 32 bits of x. Either + or - infinity will |> | return -1 and it ($clog2())needs to be added as a |> | runtime function not a vpi function. The runtime needs |> | some hooks to run compiletf like routines on function |> | defined in the runtime. We do not support at the VPI |> | level converting a real to a vector. |> |> The executive comments are that I think we should do this |> work in the %cvt/vr opcode and host pass a large vector to |> the $clog2 implementation. Is there anything wrong with |> passing |> a 1024bit vector to it? The argument to $clog2 is |> self-determined, |> so that should work. No? | | %cvt/vr is the wrong place for this, but yes a large fixed | size vector may work since we can explicitly check for -Inf | before we call vpi_get_value() for the result. Does this | all mean we are explicitly defining the vpiVectorVal | returned by vpi_get_value() when given a real argument to | have 1024 bits? | | Cary | | | | | ------------------------------------------------------------------------- | This SF.Net email is sponsored by the Moblin Your Move Developer's challenge | Build the coolest Linux based applications with Moblin SDK & win great prizes | Grand prize is a trip for two to an Open Source event anywhere in the world | http://moblin-contest.org/redirect.php?banner_id=100&url=/ | _______________________________________________ | Iverilog-devel mailing list | Ive...@li... | https://lists.sourceforge.net/lists/listinfo/iverilog-devel | - -- Steve Williams "The woods are lovely, dark and deep. steve at icarus.com But I have promises to keep, http://www.icarus.com and lines to code before I sleep, http://www.picturel.com And lines to code before I sleep." -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.4-svn0 (GNU/Linux) Comment: Using GnuPG with SUSE - http://enigmail.mozdev.org iD8DBQFIpa3UrPt1Sc2b3ikRAqnZAKCEf/lD4iRproPNCkIrIzWgNJBouACfWJTY DB+QDPkXmiyUI1/MW0nSY7g= =x8gk -----END PGP SIGNATURE----- |