Daniel Hall
Daniel Hall

Reputation: 854

VHDL inferring latches

I have a question on VHDL. The code below is for a +/- 2 degree thermostat it works and simulates well, but I have a few unexplained warnings one of them in particular is really bugging me.

LIBRARY IEEE;
USE IEEE.std_logic_1164.all, IEEE.std_logic_arith.all;
ENTITY thermo IS
    PORT    (
            Tset, Tact: in integer;
            Heaton:     out std_logic
            );
 END ENTITY thermo;

 ARCHITECTURE sequential OF thermo IS
BEGIN
    PROCESS (Tact, Tset) IS
    VARIABLE ONOFF: std_logic;
    BEGIN
        IF Tact <= (Tset - 2) then
            ONOFF := '1';
        ELSIF Tact >= (Tset + 2) then
            ONOFF := '0';
        ELSE ONOFF := ONOFF;
        END IF;
        Heaton <= ONOFF;
END PROCESS;
END ARCHITECTURE sequential;    

The warning message thats bugging me is this:

Warning (10631): VHDL Process Statement warning at thermo.vhd(19): inferring latch(es) for signal or variable "ONOFF", which holds its previous value in one or more paths through the process<

Like I said the code works ok on ModelSim but this makes me think i am going about things the wrong way. Any suggestions ? Thanks Danny J

Upvotes: 1

Views: 10670

Answers (2)

Martin Zabel
Martin Zabel

Reputation: 3659

You have described a SR latch for the signal ONOFF. This works fine in simulation but makes problems in FPGAs as well as digital circuits build from discrete components.

Your latch is set when the expression Tact <= (Tset - 2) is true. Now image a point in time, when the latch is currently in state '0' and Tact = Tset. Thus, the latch keps '0' as expected. This works as long as Tact is not changing. Now let the temperature fall to Tact = Tset-1. According to the above expression, the latch should keep in state '0'. But, this cannot be ensured in real hardware because the expression is not evaluated at once. Instead the multi-bit comparator for the <= operator may produce a glitch because the comparator itself is composed of several gates. If one of these gates is switching faster than another one, there might be an intermediate result, where the expression is true and, thus, your latch becomes '1'.

To notify the designer, that latches are susceptible for glitches, the synthesis compiler issues the above warning. To circumvent this problem, the FPGA offers D flip-flops which state is only updated on clock-edges. The timing analyzer of the FPGA toolchain ensures, that the evaluation of the above expression is completed before the next rising (or falling) clock-edge. So, the designer has not to worry about glitches!

You can describe a clock-edge triggered SR flip-flop in VHDL which is then mapped to the D flip-flop of the FPGA by the synthesis tool. The code style is as follows:

signal Q : std_logic; -- declare signal in the declarations part of the architecture
...
process(clock)
begin
  if rising_edge(clock) then -- flip-flop triggered at the rising clock edge
    if set_expression then
      Q <= '1';
    elsif reset_expression then
      Q <= '0';
    end if;
  end if;
end if;

The state of the SR flip-flop is saved in the signal Q. I have used a signal instead of an variable here, because variables are harder to debug. (I recommend to use signals as often as possible.) In this code example, if both set_expression and reset_expression are both true, then the "set" takes precedence. (Can be flipped if required.) If none of the expressions is true, then the old state is saved as required by a flip-flop.

Upvotes: 3

Morten Zilmer
Morten Zilmer

Reputation: 15934

The process is specified to hold the current value of ONOFF with the line:

ELSE ONOFF := ONOFF;

Holding the value based on combinatorial inputs, like Tact and Tset, requires a latch, as reported in the warning, since usually latches means that the designer created code with an unintentional side effect.

If you want to keep the state, then consider making a clocked process instead; a template is provided in this answer.

If you want a combinatorial output, then get ridge of the internal ONOFF process variable, and make sure that an explicit value is assigned in all branches of the if statement.

Upvotes: 2

Related Questions