Latches and flip flops

Discussion in 'VHDL' started by crazyrdx, Apr 1, 2006.

  1. crazyrdx

    crazyrdx Guest

    Hi ,

    I have been told that a design should not have latches, only flip
    flops. How do i differentiate between them in my vhdl code? Thanks

    crazyrdx, Apr 1, 2006
    1. Advertisements

  2. You should get knowledge about what is the "level sensitive latch" and
    the "edge-sensitive flipflop". That really basic stuff.

    if (reset='1') then
    elsif (enable='1') then
    end if;
    end process;

    if (reset='1') then
    elsif rising_edge(clock) then
    end if;
    end process;

    Ralf Hildebrandt, Apr 1, 2006
    1. Advertisements

  3. crazyrdx

    KJ Guest

    signal A, B, C : std_logic;

    An example of a latch

    if (A = '1') then
    C <= B;
    end if;
    end process;

    An example of a flop flop
    if rising_edge(A) then
    C <= B;
    end if;
    end process;

    Latches should not be used unless the underlying hardware directly supports
    them with a latch primitive AND you make sure that your code gets
    implemented using them. If you break down the 'latch' example into sum of
    products form you'll get the following:

    C <= (A and B) -- Term 1
    or (not(A) and C; -- Term 2

    The problem comes about when signal 'A' switches. Assuming that the
    underlying hardware is like common PLDs then what will be implemented will
    be darn near what I've got here. Ask yourself then what happens if the
    propogation delay to compute what I've called 'Term 1' and 'Term 2' are
    different. When 'A' switches from '1' to '0' and 'Term 1' gets computed
    slightly faster than 'Term 2' than 'C' will shut off instead of holding or
    latching. If you draw out the Karnaugh map for this equation and hark back
    to long forgotten digital logic classes, you may notice that you can add a
    redundant term that may solve your problem.

    C <= (A and B) -- Term 1
    or (not(A) and C -- Term 2
    or (B and C); -- Term 3

    Term 3 is the 'redundant' term that's been added. Logically the two
    equations implement the exact same logic. When implementing a latch this
    second form (with 'Term 3') will work flawlessly and not be sensitive to
    propogation delays in computing any of the 'Terms'.

    If you write your VHDL for a latch in the form with all 3 terms you're still
    not done. Now the problem is that every synthesizer tool in the world will
    spot the redundant logic term and reduce it right back out in the interest
    of saving resources and getting things down to the minimum amount of logic.
    All the synthesizer tools will also likely allow you some tool dependent way
    of letting you tell .it not to muck with the equation that you want it to
    implement exactly what you've written. That might seem like a 'solution'
    but you should really ask yourself how closely you want to tie your code to
    a particular tool or a particular device. As a general rule you shouldn't.
    Usually, all a 'latch' buys you above a flip flop is you capture the data a
    little bit sooner. Most of the time latches are not really needed a flip
    flop will do if you put some thought into it.

    As a final aside, the two additional ways I wrote the latch as a sum of
    products in VHDL obviously are also forms of latches. If you EVER see a
    signal on both sides of the assignment (i.e. signal 'C' in both of the sum
    of products forms) than that equation is also some form of latch. If you
    run your code through some form of implementation into a real part the tool
    will detect latches when it reports 'combinatorial loops' when it performs a
    timing analysis....just another check.

    KJ, Apr 1, 2006
  4. crazyrdx

    radarman Guest

    You also get latches when you don't fully flesh out if/else or case
    structures. This is a common problem I see all the time. For example:

    if( B = '1')
    A <= '1';
    elsif( C = '1' )
    A <= '0';
    end if;
    end process;

    What happens if both B and C are '0'? A must retain the last state, so
    you have essentially created a latch. I find the best way to avoid
    creating UNINTENTIONAL latches is to always create a default condition.
    Using the above example:

    A <= '0'; -- insert a default condition, so that the signal gets
    updated everytime the process is called.
    if( B = '1')
    A <= '1';
    elsif( C = '1' )
    A <= '0';
    end if;
    end process;

    This is a simple case, but it illustrates the idea of always assigning
    a signal a value during every pass to avoid latches. As a general rule,
    I write the following instead of using 'else'.

    process( <input signals> )
    Output <= <default_value>;
    if( <condition> )then
    Output <= <alternate_value>;
    end if;
    end process;

    For registers (D flip-flops), I always include as the very first line D
    <= Q, and use the two-process model. For example:

    process( reset_n, clk )
    if( reset_n = '0' )then
    A_q <= '0'';
    elsif( rising_edge(clk) )then
    A_q <= A_d;
    end if;
    end process;

    A_d <= A_q; -- insert as the default condition d <= q.
    if( B = '1')
    A_d <= '1';
    elsif( C = '1' )
    A_d <= '0';
    end if;
    end process;

    This virtually guarantees that you get the D flip-flop and
    combinational logic you are expecting. I generally recommend the two
    process model for synchronous designs anyway, because it enforces the
    idea of the clock explicitly. It also makes the demarcation between
    combinational and registered logic clear. Of course, for me it isn't
    generally optional. The company I work for requires the "two-process"
    model for all code written, and requires an explanation if you don't
    use it.

    Lastly, almost any circumstance where you might consider a latch, a D
    FF can be used instead. For example, I am working with a legacy
    application where the clock isn't fast enough to reliably sample
    "short" pulses. In this case, we use the input to clock a FF, which
    toggles between high and low. (d <= not q) The output is fed into an
    XOR type edge detector, which fires a single clock pulse every time the
    input flop changes state. This allows us to reliably detect short
    pulses that we might miss with a traditional sampling scheme - but
    still avoids the pitfalls of a traditional SR latch.
    radarman, Apr 7, 2006
  5. To avoid latches I use design rules
    that eliminate the possibility of
    latch inference.
    One way to do this is to base
    designs on this template:
    begin -- process template
    if reset = '1' then
    elsif rising_edge(clock) then
    end if;
    end process one;
    end architecture synth;

    For details see:

    -- Mike Treseler
    Mike Treseler, Apr 8, 2006
  6. crazyrdx

    KJ Guest

    This virtually guarantees that you get the D flip-flop and
    The single clocked process is pretty clear that there is a clock and doesn't
    require any extra gymnastics about remembering to have default assignments
    like 'A_d <= A_q'.
    Not sure why this demarcation is important to you. But when writing code
    that is intended to be synthesizable, as a general rule I only have clocked
    processes, the combinatorial logic are not in a process at all. When you
    can do that it totally avoids the problems of unintended latches due to
    missing cases or missing signals in the sensitivity list. For the few cases
    where it really is clearer to use statements only available in a process
    (i.e. if/case) then I'll use a process knowing that I need to inspect that
    code quite closely for just those issues, the FF processes do not need that

    For FFs you also don't have double the number of signals than you really
    need (i.e. A_d and A_q....'almost' every time I'm really only interested in
    the output of the FF, not the input). Cutting down on clutter in terms of
    how many signals there are in play has real value as well.

    But single versus dual process conventions seems to be more of a religion in
    itself ;)

    KJ, Apr 9, 2006
  7. Yes. One less thing to worry about.
    Any combinational logic that is needed needed is
    inferred from the clocked process. I could even declare a variable
    representing an asynchronous node inside the synchronous process if
    I had a reason to.
    Yes, this is a significant simplification
    of the design and simulation process.
    Indeed, let synthesis work out the wires.
    The only signals I _really_ need are to
    wire up the top level ports and entity instances.
    Yes, I can never predict personal preferences.
    Some like writing software in assembly language and
    some enjoy do-it-yourself logic synthesis.

    -- Mike Treseler
    Mike Treseler, Apr 10, 2006
    1. Advertisements

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.