Using carry chain of counters for term count detect

Discussion in 'VHDL' started by rickman, Aug 14, 2009.

  1. rickman

    rickman Guest

    I typically use down counters that are loaded with an initial value
    and output a flag when reaching zero. Sometimes the tools use the
    carry chain and other times they don't. I seem to recall that this
    was discussed here a few months ago and someone posted a function or
    other VHDL code that would produce a carry chain every time. I
    typically use a MOD operator for the counter, but the code I saw used
    an integer for the count and subtracted one in the conditional of an
    IF, then used the same expression in the counter assignment if the
    result was not less than zero. It appears that this was optimized to
    share the same logic for both expressions.

    I can't find this thread. Anyone remember it and some keywords that
    would let me find it? There may be something wrong with Google
    groups. I search on "counter carry chain" and it finds *NO*
    results.

    Rick
     
    rickman, Aug 14, 2009
    #1
    1. Advertising

  2. rickman

    KJ Guest

    On Aug 14, 6:36 pm, rickman <> wrote:
    > I typically use down counters that are loaded with an initial value
    > and output a flag when reaching zero.  


    >
    > I can't find this thread.  Anyone remember it and some keywords that
    > would let me find it?  There may be something wrong with Google
    > groups.  I search on "counter carry chain" and it finds *NO*


    I think this is the link you're looking for. Andy's post from June 19
    is the 8th one in the thread.

    http://groups.google.com/group/comp...aa?q=down counter "Andy" group:comp.lang.vhdl

    Kevin Jennings
     
    KJ, Aug 15, 2009
    #2
    1. Advertising

  3. rickman

    rickman Guest

    On Aug 14, 9:17 pm, KJ <> wrote:
    > On Aug 14, 6:36 pm, rickman <> wrote:
    >
    > > I typically use down counters that are loaded with an initial value
    > > and output a flag when reaching zero.

    >
    > > I can't find this thread. Anyone remember it and some keywords that
    > > would let me find it? There may be something wrong with Google
    > > groups. I search on "counter carry chain" and it finds *NO*

    >
    > I think this is the link you're looking for. Andy's post from June 19
    > is the 8th one in the thread.
    >
    > http://groups.google.com/group/comp.lang.vhdl/browse_frm/thread/36d78...
    >
    > Kevin Jennings


    I guess that is the one. I don't see where they brought out the carry
    flag to use elsewhere though and when I implement this, I get two
    adders and the one generating the term count uses extra logic just to
    get the carry out of the chain. This is using the Lattice tools in
    their XP parts.

    I seem to recall making this work by adding an extra bit to the input
    value and separating the msb of the output as the carry. I'll give
    that a try.

    Rick
     
    rickman, Aug 16, 2009
    #3
  4. rickman

    Brian Davis Guest

    On Aug 15, 10:13 pm, rickman <> wrote:
    >
    > I seem to recall making this work by adding an extra bit to the input
    > value and separating the msb of the output as the carry. I'll give
    > that a try.
    >

    Not specific to your down counter problem, but I posted a
    snippet a few years back that showed operand padding to
    pull out the carry/overflow:

    http://www.fpga-faq.com/archives/99500.html#99517

    I'd first seen that in another post years ago,
    that I can't locate anymore...

    I've also noticed troubles with the google archive search,
    I've been using the archive search on fpga-faq.com instead

    http://www.fpga-faq.com/archives/index.html

    Brian
     
    Brian Davis, Aug 16, 2009
    #4
  5. rickman

    Andy Guest

    On Aug 14, 8:17 pm, KJ <> wrote:
    > On Aug 14, 6:36 pm, rickman <> wrote:
    >
    > > I typically use down counters that are loaded with an initial value
    > > and output a flag when reaching zero.  

    >
    > > I can't find this thread.  Anyone remember it and some keywords that
    > > would let me find it?  There may be something wrong with Google
    > > groups.  I search on "counter carry chain" and it finds *NO*

    >
    > I think this is the link you're looking for.  Andy's post from June 19
    > is the 8th one in the thread.
    >
    > http://groups.google.com/group/comp.lang.vhdl/browse_frm/thread/36d78...
    >
    > Kevin Jennings


    Wow, what's old is new again...

    I should note that since then, I have noticed that while the RTL view
    from Synplify indicates using the next bit (carry), the technology
    view sometimes comes up with something better, not necessarily using
    the carry chain the way one would expect.

    That said, I have never seen it do worse than a "count = 0"
    comparison.

    Also be aware that the "count - 1 < 0" (or "count + 1 > 2**n-1") trick
    only works with integer types, not with unsigned vector types.

    Andy
     
    Andy, Aug 16, 2009
    #5
  6. rickman

    JimLewis Guest

    Hi Rick,
    Integers and such are great for sim run time, however, if you are not
    getting the hardware you want, here is an array based algorithm that
    only uses one carry cell to implement the zero detect. It has a few
    extras that you may want to remove. BaseReg is the loadable base
    register. CntReg keeps the current count value. IntReg is a
    registered version of the zero detect.

    Best,
    Jim
    SynthWorks VHDL training


    TimerProc : process (Clk, nReset)
    variable Dec : unsigned(CntReg'Length downto 0) ;
    begin
    if (nReset = '0') then
    BaseReg <= (others => '0') ;
    CntReg <= (others => '0') ;
    IntReg <= '0' ;
    elsif rising_edge(Clk) then
    if (TimerSel = '1' and Read = '0') then
    BaseReg <= unsigned(DataIn) ;
    end if ;
    Dec := ('0' & CntReg) - 1 ;
    if (Dec(Dec'Left) = '1') then
    CntReg <= BaseReg ;
    else
    CntReg <= Dec(CntReg'Range);
    end if ;
    IntReg <= Dec(Dec'Left) ;
    end if ;
    end process ;
     
    JimLewis, Aug 17, 2009
    #6
  7. rickman

    Andy Guest

    That's about the cleanest example using vectors I've seen.

    I'm not sure it wouldn't be subject to the same final optimizations
    from Synplify (et al?), since those optimizations were related more to
    the entire carry chain than to just the end of it. Although outputting
    the carry bit in the IntReg register would likely give it a strong
    nudge towards preserving the carry bit intact (if not the entire
    chain). I've not checked any results from integer-coded
    implementations that also registered (count - 1 < 0) as a boolean
    output.

    Be careful if CntReg'Range is not "n downto 0".

    Andy
     
    Andy, Aug 17, 2009
    #7
  8. rickman

    rickman Guest

    On Aug 17, 12:15 pm, JimLewis <> wrote:
    > Hi Rick,
    > Integers and such are great for sim run time, however, if you are not
    > getting the hardware you want, here is an array based algorithm that
    > only uses one carry cell to implement the zero detect. It has a few
    > extras that you may want to remove. BaseReg is the loadable base
    > register. CntReg keeps the current count value. IntReg is a
    > registered version of the zero detect.
    >
    > Best,
    > Jim
    > SynthWorks VHDL training
    >
    > TimerProc : process (Clk, nReset)
    > variable Dec : unsigned(CntReg'Length downto 0) ;
    > begin
    > if (nReset = '0') then
    > BaseReg <= (others => '0') ;
    > CntReg <= (others => '0') ;
    > IntReg <= '0' ;
    > elsif rising_edge(Clk) then
    > if (TimerSel = '1' and Read = '0') then
    > BaseReg <= unsigned(DataIn) ;
    > end if ;
    > Dec := ('0' & CntReg) - 1 ;
    > if (Dec(Dec'Left) = '1') then
    > CntReg <= BaseReg ;
    > else
    > CntReg <= Dec(CntReg'Range);
    > end if ;
    > IntReg <= Dec(Dec'Left) ;
    > end if ;
    > end process ;


    I don't have any problem getting the basic counter to use the carry
    chain, but I can not get the carry out for other purposes. The result
    seems to depend on size and how the tool is invoked. If I use the
    Lattice tool, an 8 bit counter uses 3 LUTs to detect the terminal
    count. At 16 bits it duplicates the adder chain and pulls off the
    carry out. Using Synplify directly the technology view shows two
    adders while the RTL view shows one adder with 24 bits. The carry
    comes out of the top and the lower N bits are used for the counter.
    Go figure...

    Rick
     
    rickman, Aug 18, 2009
    #8
  9. rickman

    JimLewis Guest

    Hi Rick,
    This is what I like about vectors. You can generally force an
    implementation with the code and reduce the quirks that a given
    synthesis tool subjects you to.

    Cheers,
    Jim
     
    JimLewis, Aug 21, 2009
    #9
  10. rickman

    Andy Guest

    On Aug 20, 11:02 pm, JimLewis <> wrote:
    > This is what I like about vectors.  You can generally force an
    > implementation with the code and reduce the quirks that a given
    > synthesis tool subjects you to.


    Only if you are willing to constrain the code to keep certain terms
    from being optimized away. The same synthesis tool, on the same
    target, generally applies the same sets of "back end" (technology
    mapping) optimizations regardless of what data type was used in the
    RTL, since by the time those optimizations are applied, everything is
    a vector of bits. The operations, defined by the data types, give
    certain hints & constraints based on behavior, but the back end is
    still free to accept those hints or offer something it thinks is
    better (so long as it implements the prescribed behavior, at the
    boundaries of interest). And in my observations, when Synplify has
    abandoned the explicit, traditional carry implied by the RTL, the
    circuit it came up with was faster and/or smaller. I learned to quit
    wasting my time second guessing the synthesis tool's chosen
    implementation, as long as it met performance and resource
    constraints. I still use the subtract and compare condition only
    because it is easy enough to write and understand, and consistently
    gives equal or better results than a simple pre-subtraction compare to
    zero.

    I actually prefer some of the attributes of integer arithmetic that
    have flowed into the IEEE fixed point vector types (e.g. length
    expansion to cover the potential range of the results). Unfortunately,
    the subtraction of unsigned operands still returns an unsigned result.
    Arithmetically, that is not always the case. Like integer operations,
    you specify the arithmetic operation with the fixed point expression,
    and control the data path width by assigning it to objects of a
    specific type/subtype with whatever "resizing" operation is required.
    You could probably code this whole exercise in fixed point more easily
    than in unsigned.

    Andy
     
    Andy, Aug 21, 2009
    #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. Tuukka Toivonen

    Using carry-in adders with Synopsys

    Tuukka Toivonen, Dec 1, 2003, in forum: VHDL
    Replies:
    3
    Views:
    1,544
    Ian Poole
    Dec 2, 2003
  2. k2in5
    Replies:
    0
    Views:
    810
    k2in5
    Oct 6, 2006
  3. Bryan Parkoff

    Manipulate two 8-Bits using Carry?

    Bryan Parkoff, Sep 6, 2005, in forum: C++
    Replies:
    0
    Views:
    267
    Bryan Parkoff
    Sep 6, 2005
  4. Weng Tianxiang
    Replies:
    6
    Views:
    596
    glen herrmannsfeldt
    Sep 12, 2007
  5. Immortal Nephi

    Detect Carry Flag?

    Immortal Nephi, May 7, 2009, in forum: C++
    Replies:
    4
    Views:
    1,103
    Kirk Johnson
    May 10, 2009
Loading...

Share This Page