Me and Latches...

L

laserbeak43

Hi there, Having another problem with latches. I've referred to our
last conversation about them a few months ago, but couldn't come to
any conclusions about what i'm doing wrong in my project.
Could someone please help? I get a warning that says:

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

My code goes:

------------------------------------------------------------------------------------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;

entity part4 is
port(
SW : in unsigned(2 downto 0);
KEY : in unsigned(0 downto 0);
HEX0 : out unsigned(6 downto 0)
);
end part4;


architecture behavioral of part4 is

signal s_sw : unsigned(2 downto 0);
signal s_key: std_logic;
signal s_out: unsigned(3 downto 0);
begin

s_sw <= SW;
s_key <= KEY(0);

hx : work.HEX port map (s_out, HEX0);

process(s_sw, s_out, s_key) begin

s_out <= (others => '0');
-- s_key <= (others => '0');
-- s_sw <= (others => '0');

if(s_sw(0) = '1') then

s_out <= "0000";

elsif(s_key = '0') then

case s_sw(2 downto 1) is
when "00" => s_out <= s_out;
when "01" => s_out <= s_out + 1;
when "10" => s_out <= s_out + 2;
when "11" => s_out <= s_out + 1;
end case;

end if;

end process;

end behavioral;
 
K

KJ

<snip>
Kudos for
- You remembered to assign a default value to s_out at the begining of
the process.
- It looks like you also got the sensitivity list correct.

But within the case statement you have the following assignments

when "00" => s_out <= s_out;
when "01" => s_out <= s_out + 1;
when "10" => s_out <= s_out + 2;
when "11" => s_out <= s_out + 1;

The combinatorial process is triggered by activity on s_out (and other
signals). So when it hits any of the above statements it will cause
s_out to update which will then re-trigger the process again. Any
time you have a signal assignment where signal 'x' is on both the left
and right hand side AND you're in either a combinatorial process or a
concurrent statement...you've either created a latch or a
combinatorial loop. However you view it, it's likely a design error.

Some suggestions:
- Don't use non-clocked processes. Too bad that the conversation that
was had a few months ago that you referred to either didn't suggest
this or that you didn't adhere to this advice.
- Simulate your design. In this case, the simulator would likely have
failed because an iteration limit was exceeded once any of the case
statement assignments was hit. The iteration limit exceeded is the
simulator's way of saying that after a large number of iterations, the
signal activity has not settled down to a stable value so the
simulator cannot advance to the next time step.
- During development, use synthesis tools only to
* Produce the final output file
* Get a heads up on things you haven't yet got around to simulating
such as * Entire blocks of code getting optomized away because of
unconnected inputs
** Multiple drivers on a net.
- Don't use synthesis tools for debug...the error messages aren't
always that helpful. Although I must admit in this case, I found it
very helpful and easy to understand where exactly to look

Kevin Jennings
 
Joined
Jan 29, 2009
Messages
152
Reaction score
0
In this block the assignments cause a latch to be generated; it refers to the old value of s_out, NOT the default you set before -- this has to do with signal assignment semantics in a process
Code:
case s_sw(2 downto 1) is
[B]when "00" => s_out <= s_out;
when "01" => s_out <= s_out + 1;
when "10" => s_out <= s_out + 2;
when "11" => s_out <= s_out + 1;[/B]
end case;
 
Last edited:
L

laserbeak43

Hello Kevin,
Thanks for your reply
The combinatorial process is triggered by activity on s_out (and other
signals).  So when it hits any of the above statements it will cause
s_out to update which will then re-trigger the process again.

Should I put the case statement in its own process?
 Any time you have a signal assignment where signal 'x' is on both the left
and right hand side AND you're in either a combinatorial process or a
concurrent statement...you've either created a latch or a
combinatorial loop.  However you view it, it's likely a design error.

Hmmm, do you think it'd be better if i made another signal and
assigned its value to s_out?
Some suggestions:
- Don't use non-clocked processes.  Too bad that the conversation that
was had a few months ago that you referred to either didn't suggest
this or that you didn't adhere to this advice.

I think i've heard this one before, The lab that I'm working on(the
altera labs that come with the DE2) tell me to use a button as the
clock though (KEY).
- Simulate your design.  In this case, the simulator would likely have
failed because an iteration limit was exceeded once any of the case
statement assignments was hit.  The iteration limit exceeded is the
simulator's way of saying that after a large number of iterations, the
signal activity has not settled down to a stable value so the
simulator cannot advance to the next time step.

Would signaltap be effective?
- During development, use synthesis tools only to
* Produce the final output file
* Get a heads up on things you haven't yet got around to simulating
such as * Entire blocks of code getting optomized away because of
unconnected inputs
** Multiple drivers on a net.
- Don't use synthesis tools for debug...the error messages aren't
always that helpful.  Although I must admit in this case, I found it
very helpful and easy to understand where exactly to look

although you make much sense, I do dread simulationa nd try to work
around it as much as possible. making a testcase seems to be 2 to 3
times longer than actually designing.
Which is why i asked if signaltap would be an easier route.

Thanks,
Malik
 
K

KJ

Hello Kevin,
Thanks for your reply


Should I put the case statement in its own process?

That wouldn't logically change anything.
Hmmm, do you think it'd be better if i made another signal and
assigned its value to s_out?

No, logically that wouldn't change anything either. The following are
both examples of combinatorial loops. The first is the form you
originally presented, the second is what you just proposed...they are
logically identical and each is a loop/latch. It won't solve the
problem

Ex 1: x <= x + 1;
Ex 2: x <= y + 1; y <= x;
I think i've heard this one before, The lab that I'm working on(the
altera labs that come with the DE2) tell me to use a button as the
clock though (KEY).


Would signaltap be effective?

Signaltap is not a simulator...so 'no' it would not be effective. Or
at best it would not be nearly as effective as a simulator. One can
always debug hardware if one has sufficient time...the more efficient
way is with a simulator whenever you can, hardware debug when you need
to find a clue to isolate where your sim is not covering an area.
although you make much sense, I do dread simulationa nd try to work
around it as much as possible.

Then you'll be at a disadvantage to those who do simulate and are
effective at it since they will be far more efficient at getting to
working designs then you will be...that's your choice to make, just
not one that many would recommend.
making a testcase seems to be 2 to 3
times longer than actually designing.

Your comparison is not relevent. Compare the testcase time to the
debug time.

Kevin Jennings
 
L

laserbeak43

That wouldn't logically change anything.

wouldn't the case being in it's own process prevent initialization
over and over, at least?
No, logically that wouldn't change anything either.  The following are
both examples of combinatorial loops.  The first is the form you
originally presented, the second is what you just proposed...they are
logically identical and each is a loop/latch.  It won't solve the
problem

Ex 1:  x <= x + 1;
Ex 2:  x <= y + 1;  y <= x;

I was thinking of something that involved taking s_out out of the
process
initializing x to 0, then assigning x to s_out, outside of the
process.
or at least i am now...
Signaltap is not a simulator...so 'no' it would not be effective.  Or
at best it would not be nearly as effective as a simulator.  One can
always debug hardware if one has sufficient time...the more efficient
way is with a simulator whenever you can, hardware debug when you need
to find a clue to isolate where your sim is not covering an area.
:(

Then you'll be at a disadvantage to those who do simulate and are
effective at it since they will be far more efficient at getting to
working designs then you will be...that's your choice to make, just
not one that many would recommend.
I guess I should get used to it.
Your comparison is not relevent.  Compare the testcase time to the
debug time.

LOL true, I'd probably have moved on by now.

Thanks,
Malik
 
A

Andy

If you are supposed to use KEY as a clock, then why aren't you doing
it?

process(s_sw, s_key) begin -- changed sensitivity to clk and
reset only


s_out <= (others => '0');
-- s_key <= (others => '0');
-- s_sw <= (others => '0');


if(s_sw(0) = '1') then -- now this is async reset


s_out <= "0000";


elsif falling_edge(s_key) then -- and this is the clk


case s_sw(2 downto 1) is
when "00" => s_out <= s_out;
when "01" => s_out <= s_out + 1;
when "10" => s_out <= s_out + 2;
when "11" => s_out <= s_out + 1;
end case;


end if;


end process;

Note that this also eliminates your latch and combinatorial feedback
loop problems too.

s_sw must be synchronized to the s_key clock (either by protocol, e.g.
don't change the s_sw inputs while s_key is falling, or by using
explicit registers). If it is not, you could get some strange behavior
if s_sw changes when s_key falls.

And as valuable as simulation is, it is very difficult to use it to
find problems from improperly synchronized inputs...

Andy
 
R

rickman

If you are supposed to use KEY as a clock, then why aren't you doing
it?

        process(s_sw, s_key) begin -- changed sensitivity to clk and
reset only

                s_out <= (others => '0');
--              s_key <= (others => '0');
--              s_sw <= (others => '0');

                if(s_sw(0) = '1') then -- now this is async reset

                        s_out <= "0000";

                elsif falling_edge(s_key) then -- and this is the clk

                        case s_sw(2 downto 1) is
                                when "00" => s_out <= s_out;
                                when "01" => s_out <= s_out + 1;
                                when "10" => s_out <= s_out + 2;
                                when "11" => s_out <= s_out + 1;
                        end case;

                end if;

        end process;

Note that this also eliminates your latch and combinatorial feedback
loop problems too.

s_sw must be synchronized to the s_key clock (either by protocol, e.g.
don't change the s_sw inputs while s_key is falling, or by using
explicit registers). If it is not, you could get some strange behavior
if s_sw changes when s_key falls.

And as valuable as simulation is, it is very difficult to use it to
find problems from improperly synchronized inputs...

Andy

I am unclear as to what logic you are trying to generate. Is this
supposed to be a register? If so, you need to use code that will
generate a register. The above is not that. If you are trying to use
combinatorial logic to increment a value, the feedback loop you are
describing will never stabilize...

when "01" => s_out <= s_out + 1;
when "10" => s_out <= s_out + 2;
when "11" => s_out <= s_out + 1;

These three statements describe a value that is generated by the
output of an incrementing adder with itself as the input value. Do
you see the problem? Without putting a register in the loop the value
will increment, then increment again, and again... In fact, the
individual bits will propagate at different speeds and you will likely
get a random number generator running at top speed!

First, decide what logic you are trying to describe. After all, VHDL
is a Hardware Description Language. Decide on the logic you want, then
DESCRIBE it. Look up templates for registers and add your
combinatorial description to that. Or write your combinatorial logic
separately in concurrent statements and just put the register in the
clocked process.

Rick
 
K

KK6GM

I am unclear as to what logic you are trying to generate.  Is this
supposed to be a register?  If so, you need to use code that will
generate a register.  The above is not that.  If you are trying to use
combinatorial logic to increment a value, the feedback loop you are
describing will never stabilize...

when "01" => s_out <= s_out + 1;
when "10" => s_out <= s_out + 2;
when "11" => s_out <= s_out + 1;

These three statements describe a value that is generated by the
output of an incrementing adder with itself as the input value.  Do
you see the problem?  Without putting a register in the loop the value
will increment, then increment again, and again...  In fact, the
individual bits will propagate at different speeds and you will likely
get a random number generator running at top speed!

Doesn't

...elsif falling_edge(s_key) then...

generate a register? I'm just a beginner, but if it doesn't I'd like
to know why it doesn't.
 
R

rickman

Doesn't

  ...elsif falling_edge(s_key) then...

generate a register?  I'm just a beginner, but if it doesn't I'd like
to know why it doesn't.

It should. Why do you doubt it?

Rick
 
K

KK6GM

It should.  Why do you doubt it?

Rick- Hide quoted text -

- Show quoted text -
Your previous post made me that that you doubted it. Maybe I
misunderstood what you were trying to say.
 
R

rickman

Your previous post made me that that you doubted it. Maybe I
misunderstood what you were trying to say.

My apologies. I was reading the code from your first post, I didn't
see that Andy had shown you how to use the VHDL edge functions. From
your original code I wasn't sure if you were attempting to design a
register or if you were trying to design a combinatorial circuit.

Rick
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,904
Latest member
HealthyVisionsCBDPrice

Latest Threads

Top