Awkward Arithmetic

Discussion in 'VHDL' started by rickman, Mar 15, 2010.

  1. rickman

    rickman Guest

    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. 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.

    I just want this stuff to be added to produce a 16 bit result. When
    doing this using integer arithmetic it all works well. In simulation
    it only barfs if a value exceeds its range and the synthesis result
    uses the correct number of bits in the implementation. I don't see it
    using any extra bits in the calculations which makes sense, why
    calculate bits you aren't using in the end?

    To add the signed and unsigned values, I believe I will have to add a
    bit to the unsigned FreqStep before adding to the signed values. The
    significant bits will not flow into the added bit, so it can be
    dropped in the end. But this will complicate the result a lot.

    PhaseStep <= resize(unsigned(IntgrPhase + (PROPGAIN * DataCount) +
    signed(resize(FreqStep,STEPWIDTH+1)) mod MODULUS), STEPWIDTH);

    Am I making this more complicated than it needs to be? If I just
    convert FreqStep to signed without the resize, it will treat the msb
    as a sign bit and corrupt the value, right? I guess the fact that I
    call it a signed value doesn't change the circuit, but it will change
    the simulation, right?

    The other thing I could do is to convert them all to integer and then
    back, but that is no less messy.

    Any ideas on a way to make this expression simpler?

    Rick
    rickman, Mar 15, 2010
    #1
    1. Advertising

  2. In comp.arch.fpga rickman <> 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 MODULUS-1), 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
    glen herrmannsfeldt, Mar 15, 2010
    #2
    1. Advertising

  3. rickman

    Andy Guest

    This may be a silly question, but why do you need to convert it to
    signed/unsigned? If it works in integer, leave it be... The simulation
    will be much faster, and the circuit just as good. Glen sounds like
    he's got some good implementation ideas, but if you're primarily
    interested in expressing the problem in a simple readable way, integer
    types are the clear winner. This is one of those golden examples of
    why I like integers so much!

    Or do you want it to be scalable to > 31 bits? That would be an
    example of why I want integer to be bigger!

    Andy
    Andy, Mar 15, 2010
    #3
  4. rickman

    rickman Guest

    On Mar 15, 6:12 pm, Andy <> wrote:
    > This may be a silly question, but why do you need to convert it to
    > signed/unsigned? If it works in integer, leave it be... The simulation
    > will be much faster, and the circuit just as good. Glen sounds like
    > he's got some good implementation ideas, but if you're primarily
    > interested in expressing the problem in a simple readable way, integer
    > types are the clear winner. This is one of those golden examples of
    > why I like integers so much!
    >
    > Or do you want it to be scalable to > 31 bits? That would be an
    > example of why I want integer to be bigger!
    >
    > Andy


    Thanks for the reply.

    No, I don't need > 31 bits. I just am using this in a case where all
    the connecting signals are signed/unsigned rather than integer. The
    various parameters are just shifting factors rather than arbitrary
    scale factors. In the integer approach I used a multiplication while
    a shift might be more appropriate with a vector although I think the
    impact is more clear using the multiply. After all, it is
    implementing a formula...

    The issue is not if my math is good. The only question I have is
    whether there is a better way to express it in VHDL.

    BTW, I think I need parens around the stuff the mod is acting on, if
    nothing else a bit more clarity...

    Rick
    rickman, Mar 15, 2010
    #4
  5. rickman

    Andy Guest

    Though it won't help with signed/unsigned issues, you may also want to
    look at the fixed point package. It automatically promotes result
    sizes to maintain accuracy for multiplication, addision and
    subtraction. You can use it for "integer" math by simply specifying
    your LSB index at 0. The idea is that intermediate result or operand
    resizing is not usually needed with fixed point, just a final resize
    prior to storage (like the implied resize that happens with integers).

    I really wish they had gone the extra step to make ufixed - ufixed =
    sfixed, but alas, that did not happen (not that it would be an issue
    in your problem). With that, we'd have 99% of the flexibility of
    integers (automatic signed and size promotion), with virtually
    unlimited data sizes, at reduced simulation performance (compared to
    integer, not signed/unsigned).
    Andy
    Andy, Mar 16, 2010
    #5
  6. rickman

    rickman Guest

    On Mar 16, 9:04 am, Andy <> wrote:
    > Though it won't help with signed/unsigned issues, you may also want to
    > look at the fixed point package. It automatically promotes result
    > sizes to maintain accuracy for multiplication, addision and
    > subtraction. You can use it for "integer" math by simply specifying
    > your LSB index at 0. The idea is that intermediate result or operand
    > resizing is not usually needed with fixed point, just a final resize
    > prior to storage (like the implied resize that happens with integers).
    >
    > I really wish they had gone the extra step to make ufixed - ufixed =
    > sfixed, but alas, that did not happen (not that it would be an issue
    > in your problem). With that, we'd have 99% of the flexibility of
    > integers (automatic signed and size promotion), with virtually
    > unlimited data sizes, at reduced simulation performance (compared to
    > integer, not signed/unsigned).
    > Andy


    Actually, after converting the calculation to signed/unsigned types,
    it was still pretty groady, so I changed it back to integer and split
    it up. I need to optimize this design for size and I find that easier
    if I separate the arithmetic functions so I can more easily see how
    they are being implemented.

    I had originally used integer because it make the calculations easy,
    but doubted that this was the best way to express the calculations
    because of the mess of converting the inputs from signed/unsigned and
    back. As it turned out mixing signed and unsigned is still pretty
    messy.

    Rick
    rickman, Mar 17, 2010
    #6
  7. rickman

    jacko Guest

    Looks like a phase controlled DCO. Maybe the frequency/phase d/dt fm
    effect can be used? It does look messy, modulus if its a power of 2
    should be easy to remove by a (x downto y) subrange select. If modulus
    is n/(n-1) then consider MASH or bitstream delta sigma. OR use a fixed
    point overflow clock gating. Has anyone ever tried n/(n-2) via up/down
    clock gating of an n divider??

    Cheers Jacko
    jacko, Mar 17, 2010
    #7
  8. rickman

    rickman Guest

    On Mar 17, 11:33 am, jacko <> wrote:
    > Looks like a phase controlled DCO. Maybe the frequency/phase d/dt fm
    > effect can be used? It does look messy, modulus if its a power of 2
    > should be easy to remove by a (x downto y) subrange select. If modulus
    > is n/(n-1) then consider MASH or bitstream delta sigma. OR use a fixed
    > point overflow clock gating. Has anyone ever tried n/(n-2) via up/down
    > clock gating of an n divider??
    >
    > Cheers Jacko


    Gating (or enabling actually) a divider to adjust a clock rate will
    give you the average rate you need, but it results in a jitter about
    equal to the output clock period, i.e. 100%. Using a DCO results in
    an output jitter equal to one reference clock period.

    In my DCO the modulus is a power of two and there is no need to do
    anything with the range. When the counter reaches its max count of
    2^n-1 it just naturally overflows, as does unsigned arithmetic in
    numeric_std. But integer arithmetic doesn't, so I have to use the mod
    operator.

    If you want a modulus that isn't a power of 2, you can build the
    counter so it loads modulus-1 and counts down giving a carry out at
    0. I knew I had no need to use a modulus that wasn't a power of two,
    so I wrote the code without considering that.

    Rick
    rickman, Mar 19, 2010
    #8
  9. rickman

    jacko Guest

    True. Reducing jitter does need a higher clock speed. and a stable
    power supply.
    jacko, Mar 22, 2010
    #9
  10. rickman

    rickman Guest

    On Mar 22, 8:23 am, jacko <> wrote:
    > True. Reducing jitter does need a higher clock speed. and a stable
    > power supply.


    Yes, without that stable power supply, your lsbs might get lost in the
    digital noise...

    what???

    Rick
    rickman, Mar 22, 2010
    #10
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. joshc
    Replies:
    5
    Views:
    552
    Keith Thompson
    Mar 31, 2005
  2. beginner

    Awkward format string

    beginner, Aug 1, 2007, in forum: Python
    Replies:
    11
    Views:
    492
    beginner
    Aug 2, 2007
  3. Steven Woody
    Replies:
    3
    Views:
    358
    James Kanze
    Jul 11, 2008
  4. Ben Phillips
    Replies:
    6
    Views:
    867
    Roger Lindsjö
    Aug 23, 2008
  5. Joe Snodgrass

    Compilation of Awkward Syntax

    Joe Snodgrass, Apr 27, 2013, in forum: C++
    Replies:
    25
    Views:
    464
    Stuart
    May 7, 2013
Loading...

Share This Page