Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"Unclocked" sampling and latches in VHDL

Tags:

vhdl

I nearly always bump into this problem in VHDL, and it probably has to do with my way of thinking; so I hope someone can point out the right way to think about this.

Anyways, more than often, I start needing a variable (or rather, a "register"), which would basically copy the value of an input signal if the enable signal is say, low - and keep it's "last" value if the enable signal is high. (now that I wrote this, I see that, implicitly, sampling here would happen at raising edge - transition from low to high - of the enable signal; since as long as enable is active low, then for any small delta, the change of input propagates to the register, and so "overwrites" the value set from "previous" delta time).

And so, my first attempt is usually the simplest possible - to put something like this in my VHDL file:

wdata_reg <= wdata_in when (en_n = '0');  

... which implies an unclocked/asynchronous circuit - and while I do get in simulation results what I expect, ISE WebPack's xst sythnesizer, for example, barfs with:

WARNING:Xst:737 - Found 8-bit latch for signal <wdata_reg>. Latches may be generated from incomplete case or if statements. We do not recommend the use of latches in FPGA/CPLD designs, as they may lead to timing problems.

Then again, I guess what I just described (unclocked/asynchronous 'sampling' register) - is, by definition, a latch? So, I'm never sure if I want that there, or not.

On the other hand (if I remember correctly) I had once also tried to write code like this within a state machine (so, clocked):

...
IF en_n = '0' THEN
  wdata_reg <= wdata_in;
END IF;
...

... and, I believe, the compiler did not complain on this (and it worked as expected).

 

So, I guess, my question could be posed as: whenever I need to "sample" into a register, should I always do it from within a state machine (or a clocked circuit) - or is there an alternative? For instance, I can try to cheat over the "incomplete ... if statements" like this:

wd_read_o <= d_io when (wrd_n = '0') else wd_read_o;

... (in other words: ... else assign yourself to yourself) - but the compiler sees through my noobery, and spits out the ole WARNING:Xst:737 anyways :)

I would appreciate some guidance in how to think about this - so I don't bump into this dilemma each time I need a register :) Cheers!

like image 270
sdaau Avatar asked Nov 01 '11 19:11

sdaau


1 Answers

And so, my first attempt is usually the simplest possible - to put something like this in my VHDL file:

  wdata_reg <= wdata_in when (en_n = '0');  

Yep, that's a classic latch. It's a wire when en_n is zero, and when it's one wdata_reg will hold it's value as nothing is driving it.

Then again, I guess what I just described (unclocked/asynchronous 'sampling' register) - is, by definition, a latch? So, I'm never sure if I want that there, or not.

Latches are only really useful when crossing clock domains to avoid glitching. In general, you don't want them.

The version inside a clocked process will generate a register because it's clocked (surprise!). You now have two signals involved, a clock and an enable. The difference as far as VHDL is concerned is that one assignment happens continuously (the latch) and one happens only on the clock edge (the register)

So, I guess, my question could be posed as: whenever I need to "sample" into a register, should I always do it from within a state machine (or a clocked circuit) - or is there an alternative?

It needs to be in a clocked process. A register needs a clock.

For instance, I can try to cheat over the "incomplete ... if statements" like this:

wd_read_o <= d_io when (wrd_n = '0') else wd_read_o;

This is exactly the same statement as before. The else clause is inferred in the previous version. The important point is that when wrd_n is zero any transitions on d_io will happen on wd_read_o, that's not the behaviour of a register. It's a latch.

I would appreciate some guidance in how to think about this - so I don't bump into this dilemma each time I need a register :) Cheers!

Registers have a clock, so must be in a clocked process. Simple. (Forgive the repetition)


The other common way to infer latches without meaning to is if you have an asynchronous process that has a path through is which doesn't update a signal.

p_async : process (wibble, wobble)
begin
  if (wibble = '1' and wobble = '0') then
      next_reg_b <= data_in;
  end if;
end process;

If the if statement isn't true, next_reg_b wont be updated and will have to hold it's value. This creates a latch as it needs to store a value, but didn't want a latch (or even a register), just a bit a logic. The solution is to add a default assignment.

p_async : process (wibble, wobble, reg_b)
begin
  next_reg_b <= reg_b;
  if (wibble = '1' and wobble = '0') then
      next_reg_b <= data_in;
  end if;
end process;

Now next_reg_b is always assigned to, regardless of the state of wibble and wobble. No latch.

like image 139
Paul S Avatar answered Jan 03 '23 15:01

Paul S