Does if need else absolutely for synthesis to avoid latch?

F

fl

Guest
Hi,

I remember that it is said that if must have an else to avoid latch in the
synthesis process. I just begin working on a new, would-be large project.
In order to do it gradually, I do a pure functional simulation first.
The following code works for the simulation, but I don't find a way to add
else for the if loop having '**' lines.

The intention is to make the counter begins after an external signal 'start'
changes to '1', which is expected the pulse width is just one clock cycle.
When 'start' is '1', the last cnt <= cnt+1 runs. Then, 'start' is '0', but
cnt /= x"00". The first cnt <= cnt+1 will run.


Perhaps you expects have better idea to write this, even if my code works.
I would rather to hear from you.

Thanks,


............................
type START01 is range 0 to 1 ;

signal start_var : START01 := 0;
signal cnt : unsigned(7 downto 0) := (others => '0');

start_var <= start;
p_start: process (clk, reset)
begin
if (clk'event and clk = '1') then
if reset = '1' then
cnt <= x"00";
elsif start_var = 0 then
** if cnt /= x"00" then
cnt <= cnt + 1;
** end if;
else
cnt <= cnt + 1;
end if;
end if;
end process;
 
fl wrote:
Hi,

I remember that it is said that if must have an else to avoid latch in the
synthesis process. I just begin working on a new, would-be large project.
In order to do it gradually, I do a pure functional simulation first.
The following code works for the simulation, but I don't find a way to add
else for the if loop having '**' lines.

The intention is to make the counter begins after an external signal 'start'
changes to '1', which is expected the pulse width is just one clock cycle.
When 'start' is '1', the last cnt <= cnt+1 runs. Then, 'start' is '0', but
cnt /= x"00". The first cnt <= cnt+1 will run.


Perhaps you expects have better idea to write this, even if my code works.
I would rather to hear from you.

Thanks,


...........................
type START01 is range 0 to 1 ;

signal start_var : START01 := 0;
signal cnt : unsigned(7 downto 0) := (others => '0');

start_var <= start;
p_start: process (clk, reset)
begin
if (clk'event and clk = '1') then
if reset = '1' then
cnt <= x"00";
elsif start_var = 0 then
** if cnt /= x"00" then
cnt <= cnt + 1;
** end if;
else
cnt <= cnt + 1;
end if;
end if;
end process;

Latches are only created in a combinatorial process. Inside the
if (clk`event ..., you are in a clocked process. So instead you
will infer edge-triggered flip-flops. In this context there is
no need to code an else for every if. It is assumed that the
flip-flop will hold its current state if there is no else condition,
and that's in fact what you want.

Other than that, I would think the code more readable if you changed
the order to look more like "if start is asserted then count up, else
if count is not zero count up." The way you coded it does the same
thing, but seems like it's backwards to the way one would normally
think of it, i.e. you coded "if start is not asserted then count up
only if count is not zero, otherwise count up."

In the end, it's most likely you who will re-visit this code some time
down the road and scratch your head trying to figure out what it does.

--
Gabor
 
On 9/29/2015 11:41 AM, fl wrote:
Hi,

I remember that it is said that if must have an else to avoid latch in the
synthesis process. I just begin working on a new, would-be large project.
In order to do it gradually, I do a pure functional simulation first.
The following code works for the simulation, but I don't find a way to add
else for the if loop having '**' lines.

The intention is to make the counter begins after an external signal 'start'
changes to '1', which is expected the pulse width is just one clock cycle.
When 'start' is '1', the last cnt <= cnt+1 runs. Then, 'start' is '0', but
cnt /= x"00". The first cnt <= cnt+1 will run.


Perhaps you expects have better idea to write this, even if my code works.
I would rather to hear from you.

Thanks,


............................
type START01 is range 0 to 1 ;

signal start_var : START01 := 0;
signal cnt : unsigned(7 downto 0) := (others => '0');

start_var <= start;
p_start: process (clk, reset)
begin
if (clk'event and clk = '1') then
if reset = '1' then
cnt <= x"00";
elsif start_var = 0 then
** if cnt /= x"00" then
cnt <= cnt + 1;
** end if;
else
cnt <= cnt + 1;
end if;
end if;
end process;

The rule about latch generation only applies to code that is *not*
within a clocked IF statement. The lack of the ELSE clause or an
equivalent assignment implies that the previous value of the signal is
retained. This infers a FF of some sort. In a clocked IF statement a
clocked register is already inferred, so no harm.

BTW, you should use the function rising_edge(clk) rather than the
explicit term (clk'event and clk = '1'). The above code within the
clocked IF statement will run on such transitions as 'H' to '1' and 'U'
to '1'. Also it is just easier to read rising_edge(clk). Ditto
falling_edge(clk).

--

Rick
 

Welcome to EDABoard.com

Sponsor

Back
Top