![]() |
|
|
|
#1 |
|
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 RP crazyrdx |
|
|
|
|
#2 |
|
Posts: n/a
|
crazyrdx wrote:
> 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 You should get knowledge about what is the "level sensitive latch" and the "edge-sensitive flipflop". That really basic stuff. process(reset,enable,data_in) begin if (reset='1') then my_latch<='0'; elsif (enable='1') then my_latch<=data_in; end if; end process; process(reset,clock) begin if (reset='1') then my_flipflop<='0'; elsif rising_edge(clock) then my_flipflop<=data_in; end if; end process; Ralf Ralf Hildebrandt |
|
|
|
#3 |
|
Posts: n/a
|
Given
signal A, B, C : std_logic; An example of a latch process(A) begin if (A = '1') then C <= B; end if; end process; An example of a flop flop process(A) begin 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 "crazyrdx" <> wrote in message news: oups.com... > 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 > > RP > KJ |
|
|
|
#4 |
|
Posts: n/a
|
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: process(A,B,C) begin 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: process(A,B,C) begin 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> ) begin 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 ) begin if( reset_n = '0' )then A_q <= '0''; elsif( rising_edge(clk) )then A_q <= A_d; end if; end process; process(A_q,B,C) begin 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 |
|
|
|
#5 |
|
Posts: n/a
|
crazyrdx wrote:
> 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 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 init_regs; elsif rising_edge(clock) then update_regs; end if; update_ports; end process one; end architecture synth; For details see: http://home.comcast.net/~mike_treseler/ -- Mike Treseler Mike Treseler |
|
|
|
#6 |
|
Posts: n/a
|
> 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. 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'. > It also makes the demarcation between combinational and registered logic > clear. 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 inspection. 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 KJ |
|
|
|
#7 |
|
Posts: n/a
|
KJ wrote:
> 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'. Yes. One less thing to worry about. > ... 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. 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. > When you > can do that it totally avoids the problems of unintended latches due to > missing cases or missing signals in the sensitivity list. Yes, this is a significant simplification of the design and simulation process. > 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. Indeed, let synthesis work out the wires. The only signals I _really_ need are to wire up the top level ports and entity instances. > But single versus dual process conventions seems to be more of a religion in > itself 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 |
|