In comp.arch.fpga rickman <(EMail Removed)> wrote:
> I am converting an integer equation to use numeric_std data types and
> it looks rather awkward. Here is the equation...
> PhaseStep <= (IntgrPhase + (PROPGAIN * DataCount) + FreqStep) mod
> MODULUS;
> The names in caps are integer constants, PhaseStep and FreqStep are
> unsigned while IntgrPhase and DataCount are signed, all four the same
> length, 16 bits. The true range of DataCount will be very limited so
> it is invalid that it will cause an overflow of the result.
How big can the values be? The result can't overflow because
of the MOD. (It can't exceed MODULUS1), but multiplying two
16 bit integers can reach 32 or so (signed or unsigned?) bits.
> In fact,
> it is considered an operational error if any of this causes an
> overflow in the result... that is the inputs must have been out of
> whack, not the circuit. So I'm not worried about the math at that
> level. I'm concerned about how to get the circuit I want without a
> lot of difficult typing of syntax.
If DataCount can't get so big, then a lookup table based on the
constant PROPGAIN would be easy and fast. That is, do:
PhaseStep <= (IntgrPhase + ((PROPGAIN * DataCount)mod MODULUS) + FreqStep)
mod MODULUS;
Then, depending on the size of IntgrPhase and FreqStep, another
table or some simple adder logic could do the second modulus.
It is somewhat easier if MODULUS is a power of two, but you can
still do it even if it isn't. Another possibility so to multiply
DataCount by an appropriately scaled PROPGAIN such that a power of
two modulus can be used, then multply the result to get the correct
MODULUS. You have to be careful with rounding, but I believe
that can be done. Doing division by multiplication with an
appropriately scaled reciprocal is common, and the rounding is
well understood. It isn't quite as obvious for mod, but I believe
it can still be done. (The latter assumes you have hardware
multipliers available, as many current FPGAs have.)
 glen
