From: sharp on
On Feb 17, 1:30 pm, Weng Tianxiang <wtx...(a)gmail.com> wrote:
>
> Here is another example showing Andy's point is not correct:
>
....
>          else
>            -- here an assignment statement is missing, but it doesn't
> generate latch version !!!
>            -- it is treated as a null statement.

It may recognize that the latch for State_A already provides the
necessary latch to hold the state, and that it doesn't need an
additional latch for State_NS. Recognizing that it can re-use the
value from an existing latch is different from not needing a latch at
all.

From: KJ on
On Feb 17, 1:30 pm, Weng Tianxiang <wtx...(a)gmail.com> wrote:
>    case State_A is
>       when S0 =>
>          if C01 = '1' then
>            State_NS <= S1;
>          elsif C02 = '1' then
>            State_NS <= S2;
>          else
>            -- here an assignment statement is missing, but it doesn't
> generate latch version !!!
>            -- it is treated as a null statement.

A 'null statement' in this particular instance means that State_NS
will not change. If it doesn't change, this obviously implies it must
hold it's current value. So if C01 and C02 are both not equal to '1'
then whatever value State_NS has, it will keep. This implies that a
hardware implementation will have to implement the following
combinatorial logic as part of the logic for State_NS

State_NS <= ... (logic that handles the C01=1 and the C02=1
conditions)
or not(C01) and not(C02) and State_NS;

The last 'or' term is what implements the 'missing else branch'.

When you have a condition where you have
- A combinatorial assignment (we do, State_NS)
- The assigned to signal is also on the right hand side (we do)

This situation is commonly referred to as a 'latch'. Maybe it
shouldn't be but many times it is. A better term, in my opinion,
would be a combinatorial loop, which is to say that the generating
logic for some signal depends on the value of that signal itself. In
FPGA designs, it is typically a flag that you may have a design error.

The simplest form of this is type of condition is an oscillator x <=
not(x);

> If you have a compiler of VHDL, try to compile it to see what happens
> with "else" and without "else".
>
Which tool are you using?

KJ
From: rickman on
Like Andy said, it is not the missing else that causes the latch to be
generated, it is the lack of an assignment in some path of the
process. The else is a control flow structure and has nothing to do
with assignments. Andy even gave you an example of when a missing
else will not generate a latch... when an assignment has been made
before or after the missing else...

I am pretty sure your example below *will* generate a latch.

On Feb 17, 1:30 pm, Weng Tianxiang <wtx...(a)gmail.com> wrote:
> On Feb 17, 9:50 am, Andy Peters <goo...(a)latke.net> wrote:
>
> > On Feb 17, 9:11 am, Weng Tianxiang <wtx...(a)gmail.com> wrote:
>
> > > On Feb 17, 7:36 am, Andy <jonesa...(a)comcast.net> wrote:
>
> > > > On Feb 17, 8:40 am, Weng Tianxiang <wtx...(a)gmail.com> wrote:
>
> > > > > Hi,
> > > > > Sometimes, when an if statement misses a "else" statement part in a
> > > > > two-process
> > > > > method for a state machine, a latch-type state machine would be built.
>
> > > > > I always wondering how the state machine is built: using all latches
> > > > > for the state machine
> > > > > or using only one latch for the state which misses a "else" statement
> > > > > part.
>
> > > > A latch type state machine is not built; the latch is only inserted
> > > > into the next state logic. A flip-flop still holds the current state.
>
> > > > I know the following is not the point of your post, but your example
> > > > implies that missing "else" statements generate latches.
>
> > > > This is not true.
>
> > > > Missing assignments generate latches. If a driven signal in a
> > > > combinatorial process is not assigned a value in a given execution of
> > > > the process, then the simulator has to remember what the last
> > > > assignment was. The synthesis tool generates a latch to create that
> > > > memory.
>
> > > > Similarly for a variable in a combinatorial process, if the variable
> > > > is read before it has been written in any given execution of that
> > > > process, a latch is created to remember the last assignment.
>
> > > > If I use a combinatorial process (extremely rarely in RTL), I make a
> > > > default assignment to every signal & variable driven by the process,
> > > > right up front, where it is always executed (and before any variables
> > > > are read). In the case of the next state logic, it would simply be
> > > > "state_ns <= state_a;". That way there is no need to code useless else
> > > > statements everywhere (and all the assignments that must otherwise be
> > > > included in them).
>
> > > > Andy
>
> > > Andy,
> > > I read your post carefully and found my point stands:
> > > "your example implies that missing "else" statements generate
> > > latches.
> > > This is not true. "
>
> > > This is true !!! Based on your claim: Missing assignments (in a
> > > combinational process) generate latches .
>
> > > If one misses "else" (in a combinational process), it misses an
> > > assignment statement.
>
> > > Weng
>
> > I think the other Andy's point is that missing an "else" clause in a
> > combinatorial process is a special case of the more general "missing
> > an assignment."
>
> > -a
>
> No.
>
> Here is another example showing Andy's point is not correct:
>
> Here is the code.
> Process_1 : process(RESET, CLK)
> begin
>    if RESET = '1' then
>       State_A <= S0;
>    elsif CLK'event and CLK = '1' then
>       State_A <= State_NS;
>    end if;
> end process;
>
> Process_2 : process(...)
> begin
>    case State_A is
>       when S0 =>
>          if C01 = '1' then
>            State_NS <= S1;
>          elsif C02 = '1' then
>            State_NS <= S2;
>          else
>            -- here an assignment statement is missing, but it doesn't
> generate latch version !!!
>            -- it is treated as a null statement.
-- it does not matter if it is a null statement. The
process has to *remember* the last value of State_NS since it is not
assigned, so a latch is generated. See below
>          end if;
>       when S1 =>  -- the followings are normal coding
>          ...;
>       when others =>
>          ...;
>    end case;
> end process;
>
> If you have a compiler of VHDL, try to compile it to see what happens
> with "else" and without "else".
>
> Weng

case State_A is
when S0 =>
State_NS <= S0;
if C01 = '1' then
State_NS <= S1;
elsif C02 = '1' then
State_NS <= S2;
else
-- here an assignment statement is missing, but it doesn't
generate latch version !!!
-- it is treated as a null statement.
end if;
Here the state is explicitly assigned, so it can still be calculated
from the inputs, in this case State_A, C01 and C02.

This is an HDL (Hardware Description Language). Don't try to come up
with a set of rules of how hardware will be generated based on control
flow constructs. The only thing that matters is what operations of
the hardware are being described and therefore what hardware is being
described.

Rick
From: rickman on
On Feb 17, 1:30 pm, Weng Tianxiang <wtx...(a)gmail.com> wrote:
> On Feb 17, 9:50 am, Andy Peters <goo...(a)latke.net> wrote:
>
>
>
> > On Feb 17, 9:11 am, Weng Tianxiang <wtx...(a)gmail.com> wrote:
>
> > > On Feb 17, 7:36 am, Andy <jonesa...(a)comcast.net> wrote:
>
> > > > On Feb 17, 8:40 am, Weng Tianxiang <wtx...(a)gmail.com> wrote:
>
> > > > > Hi,
> > > > > Sometimes, when an if statement misses a "else" statement part in a
> > > > > two-process
> > > > > method for a state machine, a latch-type state machine would be built.
>
> > > > > I always wondering how the state machine is built: using all latches
> > > > > for the state machine
> > > > > or using only one latch for the state which misses a "else" statement
> > > > > part.
>
> > > > A latch type state machine is not built; the latch is only inserted
> > > > into the next state logic. A flip-flop still holds the current state.
>
> > > > I know the following is not the point of your post, but your example
> > > > implies that missing "else" statements generate latches.
>
> > > > This is not true.
>
> > > > Missing assignments generate latches. If a driven signal in a
> > > > combinatorial process is not assigned a value in a given execution of
> > > > the process, then the simulator has to remember what the last
> > > > assignment was. The synthesis tool generates a latch to create that
> > > > memory.
>
> > > > Similarly for a variable in a combinatorial process, if the variable
> > > > is read before it has been written in any given execution of that
> > > > process, a latch is created to remember the last assignment.
>
> > > > If I use a combinatorial process (extremely rarely in RTL), I make a
> > > > default assignment to every signal & variable driven by the process,
> > > > right up front, where it is always executed (and before any variables
> > > > are read). In the case of the next state logic, it would simply be
> > > > "state_ns <= state_a;". That way there is no need to code useless else
> > > > statements everywhere (and all the assignments that must otherwise be
> > > > included in them).
>
> > > > Andy
>
> > > Andy,
> > > I read your post carefully and found my point stands:
> > > "your example implies that missing "else" statements generate
> > > latches.
> > > This is not true. "
>
> > > This is true !!! Based on your claim: Missing assignments (in a
> > > combinational process) generate latches .
>
> > > If one misses "else" (in a combinational process), it misses an
> > > assignment statement.
>
> > > Weng
>
> > I think the other Andy's point is that missing an "else" clause in a
> > combinatorial process is a special case of the more general "missing
> > an assignment."
>
> > -a
>
> No.
>
> Here is another example showing Andy's point is not correct:
>
> Here is the code.
> Process_1 : process(RESET, CLK)
> begin
>    if RESET = '1' then
>       State_A <= S0;
>    elsif CLK'event and CLK = '1' then
>       State_A <= State_NS;
>    end if;
> end process;
>
> Process_2 : process(...)
> begin
>    case State_A is
>       when S0 =>
>          if C01 = '1' then
>            State_NS <= S1;
>          elsif C02 = '1' then
>            State_NS <= S2;
>          else
>            -- here an assignment statement is missing, but it doesn't
> generate latch version !!!
>            -- it is treated as a null statement.
>          end if;
>       when S1 =>  -- the followings are normal coding
>          ...;
>       when others =>
>          ...;
>    end case;
> end process;
>
> If you have a compiler of VHDL, try to compile it to see what happens
> with "else" and without "else".
>
> Weng

Fight fire with fire! The two reports below show that both the
missing else and the missing assignment (which is also missing in the
missing else case) produce latches.

@W: CL117 :"C:\arius\boards\tdc_upgrade\tests\latchsynthtest.vhd":
57:4:57:7|Latch generated from process for signal Latch, probably
caused by a missing assignment in an if or case stmt
@W: CL117 :"C:\arius\boards\tdc_upgrade\tests\latchsynthtest.vhd":
40:4:40:7|Latch generated from process for signal Comb, probably
caused by a missing assignment in an if or case stmt

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity LatchSynthTest is
port(
CLK : in std_logic ;
RESET : in std_logic ;
C01 : in std_logic ;
C02 : in std_logic ;
LatchOutput : out std_logic ;
CombOutput : out std_logic
);
end LatchSynthTest ;

architecture behavior of LatchSynthTest is
SIGNAL Latch : std_logic;
SIGNAL Comb : std_logic;
SIGNAL LatchReg : std_logic;
SIGNAL CombReg : std_logic;

begin

CombOutput <= CombReg;
LatchOutput <= LatchReg;

Process_1 : process(RESET, CLK)
begin
if (RESET = '1') then
LatchReg <= '0';
CombReg <= '0';
elsif (rising_edge(CLK)) then
LatchReg <= Latch;
CombReg <= Comb;
end if;
end process;

CombProc : process(CombReg, C01, C02)
begin
case CombReg is
when '0' =>
if (C01 = '1') then
Comb <= '0';
elsif (C02 = '1') then
Comb <= '1';
else
-- Here an assignment statement is missing, but it doesn't
-- generate latch. It is treated as a null statement. -
Weng
end if;
when others =>
Comb <= '1';
end case;
end process;

LatchProc : process(LatchReg, C01, C02)
begin
case LatchReg is
when '0' =>
if C01 = '1' then
Latch <= '0';
elsif C02 = '1' then
Latch <= '1';
-- Here the else is missing, and it does
-- generate latch. It is treated as a null statement.
end if;
when others =>
Latch <= '1';
end case;
end process;

end behavior;

From: Weng Tianxiang on
On Feb 17, 4:29 pm, rickman <gnu...(a)gmail.com> wrote:
> On Feb 17, 1:30 pm, Weng Tianxiang <wtx...(a)gmail.com> wrote:
>
>
>
>
>
> > On Feb 17, 9:50 am, Andy Peters <goo...(a)latke.net> wrote:
>
> > > On Feb 17, 9:11 am, Weng Tianxiang <wtx...(a)gmail.com> wrote:
>
> > > > On Feb 17, 7:36 am, Andy <jonesa...(a)comcast.net> wrote:
>
> > > > > On Feb 17, 8:40 am, Weng Tianxiang <wtx...(a)gmail.com> wrote:
>
> > > > > > Hi,
> > > > > > Sometimes, when an if statement misses a "else" statement part in a
> > > > > > two-process
> > > > > > method for a state machine, a latch-type state machine would be built.
>
> > > > > > I always wondering how the state machine is built: using all latches
> > > > > > for the state machine
> > > > > > or using only one latch for the state which misses a "else" statement
> > > > > > part.
>
> > > > > A latch type state machine is not built; the latch is only inserted
> > > > > into the next state logic. A flip-flop still holds the current state.
>
> > > > > I know the following is not the point of your post, but your example
> > > > > implies that missing "else" statements generate latches.
>
> > > > > This is not true.
>
> > > > > Missing assignments generate latches. If a driven signal in a
> > > > > combinatorial process is not assigned a value in a given execution of
> > > > > the process, then the simulator has to remember what the last
> > > > > assignment was. The synthesis tool generates a latch to create that
> > > > > memory.
>
> > > > > Similarly for a variable in a combinatorial process, if the variable
> > > > > is read before it has been written in any given execution of that
> > > > > process, a latch is created to remember the last assignment.
>
> > > > > If I use a combinatorial process (extremely rarely in RTL), I make a
> > > > > default assignment to every signal & variable driven by the process,
> > > > > right up front, where it is always executed (and before any variables
> > > > > are read). In the case of the next state logic, it would simply be
> > > > > "state_ns <= state_a;". That way there is no need to code useless else
> > > > > statements everywhere (and all the assignments that must otherwise be
> > > > > included in them).
>
> > > > > Andy
>
> > > > Andy,
> > > > I read your post carefully and found my point stands:
> > > > "your example implies that missing "else" statements generate
> > > > latches.
> > > > This is not true. "
>
> > > > This is true !!! Based on your claim: Missing assignments (in a
> > > > combinational process) generate latches .
>
> > > > If one misses "else" (in a combinational process), it misses an
> > > > assignment statement.
>
> > > > Weng
>
> > > I think the other Andy's point is that missing an "else" clause in a
> > > combinatorial process is a special case of the more general "missing
> > > an assignment."
>
> > > -a
>
> > No.
>
> > Here is another example showing Andy's point is not correct:
>
> > Here is the code.
> > Process_1 : process(RESET, CLK)
> > begin
> >    if RESET = '1' then
> >       State_A <= S0;
> >    elsif CLK'event and CLK = '1' then
> >       State_A <= State_NS;
> >    end if;
> > end process;
>
> > Process_2 : process(...)
> > begin
> >    case State_A is
> >       when S0 =>
> >          if C01 = '1' then
> >            State_NS <= S1;
> >          elsif C02 = '1' then
> >            State_NS <= S2;
> >          else
> >            -- here an assignment statement is missing, but it doesn't
> > generate latch version !!!
> >            -- it is treated as a null statement.
> >          end if;
> >       when S1 =>  -- the followings are normal coding
> >          ...;
> >       when others =>
> >          ...;
> >    end case;
> > end process;
>
> > If you have a compiler of VHDL, try to compile it to see what happens
> > with "else" and without "else".
>
> > Weng
>
> Fight fire with fire!  The two reports below show that both the
> missing else and the missing assignment (which is also missing in the
> missing else case) produce latches.
>
> @W: CL117 :"C:\arius\boards\tdc_upgrade\tests\latchsynthtest.vhd":
> 57:4:57:7|Latch generated from process for signal Latch, probably
> caused by a missing assignment in an if or case stmt
> @W: CL117 :"C:\arius\boards\tdc_upgrade\tests\latchsynthtest.vhd":
> 40:4:40:7|Latch generated from process for signal Comb, probably
> caused by a missing assignment in an if or case stmt
>
> library ieee;
> use ieee.std_logic_1164.all;
> use ieee.numeric_std.all;
>
> entity LatchSynthTest is
>   port(
>           CLK                   : in    std_logic ;
>           RESET                 : in    std_logic ;
>           C01                   : in    std_logic ;
>           C02                   : in    std_logic ;
>           LatchOutput   : out   std_logic ;
>           CombOutput    : out   std_logic
>           );
> end LatchSynthTest ;
>
> architecture behavior of LatchSynthTest is
>   SIGNAL Latch          : std_logic;
>   SIGNAL Comb           : std_logic;
>   SIGNAL LatchReg       : std_logic;
>   SIGNAL CombReg        : std_logic;
>
> begin
>
>   CombOutput    <= CombReg;
>   LatchOutput   <= LatchReg;
>
>   Process_1 : process(RESET, CLK)
>   begin
>     if (RESET = '1') then
>       LatchReg  <= '0';
>       CombReg   <= '0';
>     elsif (rising_edge(CLK)) then
>       LatchReg  <= Latch;
>       CombReg   <= Comb;
>     end if;
>   end process;
>
>   CombProc : process(CombReg, C01, C02)
>   begin
>     case CombReg is
>       when '0' =>
>         if (C01 = '1') then
>           Comb <= '0';
>         elsif (C02 = '1') then
>           Comb <= '1';
>         else
>           -- Here an assignment statement is missing, but it doesn't
>           -- generate latch.  It is treated as a null statement. -
> Weng
>         end if;
>       when others =>
>         Comb <= '1';
>     end case;
>   end process;
>
>   LatchProc : process(LatchReg, C01, C02)
>   begin
>     case LatchReg is
>       when '0' =>
>         if C01 = '1' then
>           Latch <= '0';
>         elsif C02 = '1' then
>           Latch <= '1';
>           -- Here the else is missing, and it does
>           -- generate latch.  It is treated as a null statement.
>         end if;
>       when others =>
>         Latch <= '1';
>     end case;
>   end process;
>
> end behavior;

Hi,
Thank you, Andy, Rick and everyone, I am wrong in the second point:
missing "else" or missing an assignment statement.

But my first point is how to generate a latch for a compiler. Rick,
can you see the floor plan to show how the latch is generated: for the
state only or for full states?

Weng