std_logic_vector signals in sensitivity list process

On Jan 9, 5:26 pm, "KJ" <kkjenni...@sbcglobal.net> wrote:
neeraj2...@gmail.com> wrote in message

news:64865f33-5f8b-4bc4-96c2-dce6c3ac26dd@j20g2000hsi.googlegroups.com...



On Jan 7, 9:51 pm, Mike Treseler <mike_trese...@comcast.net> wrote:
Steven Kauffmann wrote:
During the place and route process I
receive errors that the signal result_ready is going to be trimmed. If
I turn off the option "trim unconnected signals" the error disappears.
But I don't know if this is a good solution to solve the problem.

Any signal or variable that does not
affect an output port is ignored for synthesis.
If the signal "result_ready" is just used for debug,
ignore the warning.
Otherwise, use it to drive a handshake output port.

I was wondering how the synthesis tool considers result_ready to be
"unconnected."
Doesn't
result_ready <= not (result_ready);
mean that result_ready is actually connected somewhere (to the input
of the inverter, in this case)?

It does only if the logic that depends on 'result_ready' has not been
optomized away because that logic doesn't affect a top level output pin.

Logic gets optomized away when there is not top level output pin of the
device that gets affected by any of the outputs of that logic. That doesn't
mean that the outputs of all entities necessarily need to be directly
connected to pins though since a signal could be the input to some other
logic that does affect an output pin.

As an example, let's say you write code for a free running counter and the
output of that entity is a simple pulse that goes active for one clock cycle
when the counter reaches 1000. Let's say that output then feeds into an
accumulator that when it sees this pulse, latches and holds it set until
some external read signal from an output pin is set (perhaps an external CPU
polling to see what the status is). In response to that read signal, the
accumulator outputs the result of the accumulator and then clears itself
when the read ends.

Now, the free running counter entity has no direct connection to any
external I/O pins but it affects logic that does have such a connection (the
accumulator). But let's say at the top level of your design you neglect to
connect the output pin of the counter entity to the input of the
accumulator. In that situation, the synthesis logic would see that the
counter logic can be optomized away since it doesn't affect any output pins
simply because you didn't connect things properly.

Or, presumably the free running counter has a clock input and a reset input.
What if you connect the reset to a constant that happens to be '1', or the
clock to a constant. Again, the whole thing gets optomized away.

In all of these cases, you can stare at your counter code all day looking
for something wrong that would explain why it is getting optomized away and
you won't find it because the problem is not with the counter code, but with
how that counter is being connected to other logic.

In any case, the way you go about finding these problems is to simulate. If
you do so, you should find that functionally the design is not doing what it
should be doing for some reason. Once you find that reason, run it through
synthesis again.

Kevin Jennings

Thank you, Kevin, for that explanation. This is a really enlightening
thread!
 
<neeraj2608@gmail.com> wrote in message
news:64865f33-5f8b-4bc4-96c2-dce6c3ac26dd@j20g2000hsi.googlegroups.com...
On Jan 7, 9:51 pm, Mike Treseler <mike_trese...@comcast.net> wrote:
Steven Kauffmann wrote:
During the place and route process I
receive errors that the signal result_ready is going to be trimmed. If
I turn off the option "trim unconnected signals" the error disappears.
But I don't know if this is a good solution to solve the problem.

Any signal or variable that does not
affect an output port is ignored for synthesis.
If the signal "result_ready" is just used for debug,
ignore the warning.
Otherwise, use it to drive a handshake output port.


I was wondering how the synthesis tool considers result_ready to be
"unconnected."
Doesn't
result_ready <= not (result_ready);
mean that result_ready is actually connected somewhere (to the input
of the inverter, in this case)?
It does only if the logic that depends on 'result_ready' has not been
optomized away because that logic doesn't affect a top level output pin.

Logic gets optomized away when there is not top level output pin of the
device that gets affected by any of the outputs of that logic. That doesn't
mean that the outputs of all entities necessarily need to be directly
connected to pins though since a signal could be the input to some other
logic that does affect an output pin.

As an example, let's say you write code for a free running counter and the
output of that entity is a simple pulse that goes active for one clock cycle
when the counter reaches 1000. Let's say that output then feeds into an
accumulator that when it sees this pulse, latches and holds it set until
some external read signal from an output pin is set (perhaps an external CPU
polling to see what the status is). In response to that read signal, the
accumulator outputs the result of the accumulator and then clears itself
when the read ends.

Now, the free running counter entity has no direct connection to any
external I/O pins but it affects logic that does have such a connection (the
accumulator). But let's say at the top level of your design you neglect to
connect the output pin of the counter entity to the input of the
accumulator. In that situation, the synthesis logic would see that the
counter logic can be optomized away since it doesn't affect any output pins
simply because you didn't connect things properly.

Or, presumably the free running counter has a clock input and a reset input.
What if you connect the reset to a constant that happens to be '1', or the
clock to a constant. Again, the whole thing gets optomized away.

In all of these cases, you can stare at your counter code all day looking
for something wrong that would explain why it is getting optomized away and
you won't find it because the problem is not with the counter code, but with
how that counter is being connected to other logic.

In any case, the way you go about finding these problems is to simulate. If
you do so, you should find that functionally the design is not doing what it
should be doing for some reason. Once you find that reason, run it through
synthesis again.

Kevin Jennings
 
On Jan 7, 9:51 pm, Mike Treseler <mike_trese...@comcast.net> wrote:
Steven Kauffmann wrote:
During the place and route process I
receive errors that the signal result_ready is going to be trimmed. If
I turn off the option "trim unconnected signals" the error disappears.
But I don't know if this is a good solution to solve the problem.

Any signal or variable that does not
affect an output port is ignored for synthesis.
If the signal "result_ready" is just used for debug,
ignore the warning.
Otherwise, use it to drive a handshake output port.
I was wondering how the synthesis tool considers result_ready to be
"unconnected."
Doesn't
result_ready <= not (result_ready);
mean that result_ready is actually connected somewhere (to the input
of the inverter, in this case)?
 
S

Steven Kauffmann

Guest
Hello all,

I have some questions about how to use std_logic_vector signals in the
sensitivity list of a process.

First of all, is the sensitivity list like a comparator in hardware
and does it continuously checks if the value changes? Or is the
sensitivity list only important when simulating the design?

If I use a std_logic_vector signal in the sensitivity list, are all
the bits of this signal compared or is only one bit(MSB of LSB) used?

Is there a difference between those two sensitivity lists?

process(port_a(4 downto 0))
begin
-- do something
end process

process(port_a(3), port_a(2), port_a(1), port_a(0))
begin
-- do something
end process

Regards

Steven
 
Steven,

Sensitivity lists are relevant only in simulation. A synthesizer
should warn you, however, if you have any signals missing from your
sensitivity list, so as to let you know that you may have a simulation/
synthesis mismatch.

I believe your two examples would be dealt with in the same way, you
could also just do the following...

process(port_a)
begin
-- do something
end process

Regards,
John

On Dec 21, 7:42 am, Steven Kauffmann <steven.kauffm...@gmail.com>
wrote:
Hello all,

I have some questions about how to use std_logic_vector signals in the
sensitivity list of a process.

First of all, is the sensitivity list like a comparator in hardware
and does it continuously checks if the value changes? Or is the
sensitivity list only important when simulating the design?

If I use a std_logic_vector signal in the sensitivity list, are all
the bits of this signal compared or is only one bit(MSB of LSB) used?

Is there a difference between those two sensitivity lists?

process(port_a(4 downto 0))
begin
-- do something
end process

process(port_a(3), port_a(2), port_a(1), port_a(0))
begin
-- do something
end process

Regards

Steven
 
Steven Kauffmann wrote:

Is there a difference between those two sensitivity lists?
Yes, one has 5 bits and the other has 4 bits ;)


Note that the use of asynchronous processes is usually optional.
Using a synchronous process template eliminates concerns about
sensitivity lists and many other things.
__
sync_template : process(reset, clock) is
-- declarations here
begin
if reset = '1' then
init_regs;
elsif rising_edge(clock) then
update_regs;
end if;
update_ports;
end process sync_template;
__
-- Mike Treseler
 
On Dec 21, 3:49 pm, paragon.j...@gmail.com wrote:
Steven,

Sensitivity lists are relevant only in simulation. A synthesizer
should warn you, however, if you have any signals missing from your
sensitivity list, so as to let you know that you may have a simulation/
synthesis mismatch.
So this means that the process below is not working when it's
implemented in hardware this because the sensitivity list is ignored
and so the process will never be updated?

process(port_a)
begin
-- do something
end process;

I believe your two examples would be dealt with in the same way, you
could also just do the following...

process(port_a)
begin
-- do something
end process

Regards,
John

On Dec 21, 7:42 am, Steven Kauffmann <steven.kauffm...@gmail.com
wrote:

Hello all,

I have some questions about how to use std_logic_vector signals in the
sensitivity list of a process.

First of all, is the sensitivity list like a comparator in hardware
and does it continuously checks if the value changes? Or is the
sensitivity list only important when simulating the design?

If I use a std_logic_vector signal in the sensitivity list, are all
the bits of this signal compared or is only one bit(MSB of LSB) used?

Is there a difference between those two sensitivity lists?

process(port_a(4 downto 0))
begin
-- do something
end process

process(port_a(3), port_a(2), port_a(1), port_a(0))
begin
-- do something
end process

Regards

Steven
 
On Dec 24, 3:10 am, Steven Kauffmann <steven.kauffm...@gmail.com>
wrote:

So this means that the process below is not working when it's
implemented in hardware this because the sensitivity list is ignored
and so the process will never be updated?

process(port_a)
begin
-- do something
end process;
Not quite. VHDL is fundamentally a simulation language, which, when
written using certain common styles, allow it to be used as a source
language for hardware synthesis. This code really could have two ways
to interpret it: one in a simulation environment, which is exactly
what the official language definition explains, and one interpretation
as a hardware description, which is fuzzier. The idea behind using
certain common coding styles is to make sure the behaviour of your
code in simulation and synthesis are the same. That's what's meant by
"synthesis/simulation mismatch".

For simulation purposes, a process with a sensitivity list will run
exactly once at initialization (although in no particular order w.r.t.
other processes' initialization steps), and when the signal changes.
If you specify the wrong sensitivity list by accident, your process
won't respond as you expect (either ignoring events on the signal you
wanted to use, or firing at apparently random other times).

Generally, if you just want a process that responds asynchronously,
immediately, to a set of signals, (like if you're writing a simple
logic gate or an asynchronous memory read), you can skip the
sensitivity list altogether and the compiler will figure out the right
sensitivity list automatically, by looking at every signal that gets
read in the process. You want to either specify every signal correctly
or specify no signals at all in the sensitivity list. Otherwise
there's a good chance that you messed up.

Your question about "comparator in hardware" doesn't quite catch the
idea. If you wanted to follow this analogy, think of a process as
specifying some kind of piece of logic that might be a mixture of
clocked and combinatorial. The sensitivity list defines those inputs
which, if they have an event on them, may cause the output to change.
This means that those signals are either directly connected to the
circuit output through gates, or are used as clock input edges. (This
is admittedly a sloppy analogy.)

When you want to write something behind a clocked register (like a
counter, state machine, etc), you typically _only_ specify the clock
signal in the sensitivity list. Then you put the entire body of the
process inside an "if rising_edge(clk)..." statement. The combination
of these two things tells the synthesizer to generate the
combinatorial logic specified inside the "if" statement, with a flop
on each output signal you assign to. This again, is admittedly a
sloppy description of the synthesis process :)

If you write processes that don't follow one of these three styles
(clocked, combinatorial with no sensitivity, or combinatorial with
complete sensitivity), you're either doing the wrong thing (if you're
a beginner) or are trying to do something fancy (if you're a more
advanced user). If you're trying to be fancy as an advanced user,
there's still a good chance you're wrong, at least the first few
times :)

And so as to make sure to answer your last question:

process(port_a)
blah blah...

will run in simulation at initialization and when any subelement on
port_a (or port_a in its entirety) changes. In hardware, as long as
port_a is the only signal you look at inside your process, you should
be generating a simple combinatorial function of port_a. If
"blah_blah_bah" reads signals _other_ than port_a, or doesn't have the
complete sensitivity list (as in the 4 vs 5 signal discrepancy Mike
pointed out), you're most likely generating something which you didn't
want, regardless of whether you're simulating or synthesizing.

Hope this helps,

- Kenn
 
The way the sensitivity list is synthesized is going to dependon the tool
being used. Aside from an extra bit in the sensitivity list the two would
function the same. But synthesis could be completely different. In our
synthesis tool the "sensitivity list" is completely ignored in some
situations. We actually have a coding guide for our tool that states how
the sensitivity list will be synthesized based on the code inside the block.

Check to see if your synthesis tool has a coding guide for using sensitivity
lists.


"Steven Kauffmann" <steven.kauffmann@gmail.com> wrote in message
news:34820e7c-fd96-4d1b-bbd7-bf8355536d3e@q3g2000hsg.googlegroups.com...
Hello all,

I have some questions about how to use std_logic_vector signals in the
sensitivity list of a process.

First of all, is the sensitivity list like a comparator in hardware
and does it continuously checks if the value changes? Or is the
sensitivity list only important when simulating the design?

If I use a std_logic_vector signal in the sensitivity list, are all
the bits of this signal compared or is only one bit(MSB of LSB) used?

Is there a difference between those two sensitivity lists?

process(port_a(4 downto 0))
begin
-- do something
end process

process(port_a(3), port_a(2), port_a(1), port_a(0))
begin
-- do something
end process

Regards

Steven
 
"Dwayne Dilbeck" <ddilbeck@yahoo.com> wrote in message
news:13no3pnikq54b6@corp.supernews.com...
The way the sensitivity list is synthesized is going to dependon the tool
being used.
The only 'tool dependency' would be because the tool does not conform to the
VHDL LRM.

Aside from an extra bit in the sensitivity list the two would function the
same.
Well, they would likely synthesize to the exact same thing....but the
synthesized result would differ from that of simulation because of the
different signals in the sensitivity list. The 'correct' one would be the
simulation result, the synthesized result would be wrong.

But synthesis could be completely different. In our synthesis tool the
"sensitivity list" is completely ignored in some situations.
Bragging about LRM non-compliance??

We actually have a coding guide for our tool that states how the
sensitivity list will be synthesized based on the code inside the block.

I prefer the approved standards myself as opposed to a vendor's shortcuts.

Check to see if your synthesis tool has a coding guide for using
sensitivity lists.

Check the LRM instead.

I admit that I do prefer the usual synthesizer's ignoring of the sensitivity
list and putting up a warning to indicate when I have an incomplete list or
a signal that does not belong but that not being the standard, but I MUCH
MORE strongly prefer simulation results to match synthesized results.

But by not using processes other than clocked ones where 'clock' (or 'clock'
and 'reset') is the extent of the sensitivity list means I normally don't
even have to bother with this issue at all.

Kevin Jennings
 
Bragging about LRM non-compliance??
Uhm...NO....I hate non conformance, but that is a battle I lost a long time
ago.
When ever we have non-conformance it is caused by one of three issues. 1)
We screed up, 2) A competitor screwed up and we now have to match thier
functionality, or 3) the customer requested we have an alterante path that
is not compliant.

The comment to check his vendors RTL style guide was to address items 2 and
3. If his problem is due to item #1, then it has to be fixed. But cases 2
and 3 are more common in my experience. Granted...My company will break LRM
for any customer that waves enough money at us.(As will most EDA companies)
It just drives me crazy when we make non-conformance a default option
becuase a customer wants it.

I have actually seen two seperate companies want LRM non conformance, but
implemented differently. Niether wanted to use a command line switch to
activate it. Both were holding up big money deals until they got thier
enhancement. Nasty.
 
On Jan 2, 5:31 pm, "KJ" <kkjenni...@sbcglobal.net> wrote:
"Dwayne Dilbeck" <ddilb...@yahoo.com> wrote in message

news:13no3pnikq54b6@corp.supernews.com...> The way the sensitivity list is synthesized is going to dependon the tool
being used.

The only 'tool dependency' would be because the tool does not conform to the
VHDL LRM.

Aside from an extra bit in the sensitivity list the two would function the
same.

Well, they would likely synthesize to the exact same thing....but the
synthesized result would differ from that of simulation because of the
different signals in the sensitivity list. The 'correct' one would be the
simulation result, the synthesized result would be wrong.

But synthesis could be completely different. In our synthesis tool the
"sensitivity list" is completely ignored in some situations.

Bragging about LRM non-compliance??

We actually have a coding guide for our tool that states how the
sensitivity list will be synthesized based on the code inside the block.

I prefer the approved standards myself as opposed to a vendor's shortcuts.

Check to see if your synthesis tool has a coding guide for using
sensitivity lists.

Check the LRM instead.

I admit that I do prefer the usual synthesizer's ignoring of the sensitivity
list and putting up a warning to indicate when I have an incomplete list or
a signal that does not belong but that not being the standard, but I MUCH
MORE strongly prefer simulation results to match synthesized results.

But by not using processes other than clocked ones where 'clock' (or 'clock'
and 'reset') is the extent of the sensitivity list means I normally don't
even have to bother with this issue at all.

Kevin Jennings
Let's face it, the 800 lb gorilla (Synopsys) decided a long time ago
that they were going to ignore sensitivity lists in synthesis, and
everyone else followed suit, because customers (waiving money) wanted
tools that work "just like Synopsys", instead of "just like the LRM".
Ditto for std_logic_arith, etc.

It really galls me that when we requested that Synopsys add a command
line feature (like modelsim) to only compile certain design unit types
found in the file(s) (i.e. only architectures, etc.). They replied
that the LRM prohibited such a practice! One could argue that the LRM
prohibits out of order compilation of units within one file (an ncsim
and modelsim option), and I seriously doubt that interpretation was
intended by the authors, but it says nothing requiring compiling every
design unit in a file.

Andy
 
Bragging about LRM non-compliance??
Uhm...NO....I hate non conformance, but that is a battle I lost a long time
ago.
When ever we have non-conformance it is caused by one of three issues. 1)
We screed up, 2) A competitor screwed up and we now have to match thier
functionality, or 3) the customer requested we have an alterante path that
is not compliant.

The comment to check his vendors RTL style guide was to address items 2 and
3. If his problem is due to item #1, then it has to be fixed. But cases 2
and 3 are more common in my experience. Granted...My company will break LRM
for any customer that waves enough money at us.(As will most EDA companies)
It just drives me crazy when we make non-conformance a default option
becuase a customer wants it.

I have actually seen two seperate companies want LRM non conformance, but
implemented differently. Niether wanted to use a command line switch to
activate it. Both were holding up big money deals until they got thier
enhancement. Nasty.

"KJ" <kkjennings@sbcglobal.net> wrote in message
news:D9Vej.2718$6%.2006@nlpi061.nbdc.sbc.com...
"Dwayne Dilbeck" <ddilbeck@yahoo.com> wrote in message
news:13no3pnikq54b6@corp.supernews.com...
The way the sensitivity list is synthesized is going to dependon the tool
being used.
The only 'tool dependency' would be because the tool does not conform to
the VHDL LRM.

Aside from an extra bit in the sensitivity list the two would function
the same.
Well, they would likely synthesize to the exact same thing....but the
synthesized result would differ from that of simulation because of the
different signals in the sensitivity list. The 'correct' one would be the
simulation result, the synthesized result would be wrong.

But synthesis could be completely different. In our synthesis tool the
"sensitivity list" is completely ignored in some situations.
Bragging about LRM non-compliance??

We actually have a coding guide for our tool that states how the
sensitivity list will be synthesized based on the code inside the block.

I prefer the approved standards myself as opposed to a vendor's shortcuts.

Check to see if your synthesis tool has a coding guide for using
sensitivity lists.

Check the LRM instead.

I admit that I do prefer the usual synthesizer's ignoring of the
sensitivity list and putting up a warning to indicate when I have an
incomplete list or a signal that does not belong but that not being the
standard, but I MUCH MORE strongly prefer simulation results to match
synthesized results.

But by not using processes other than clocked ones where 'clock' (or
'clock' and 'reset') is the extent of the sensitivity list means I
normally don't even have to bother with this issue at all.

Kevin Jennings
 
On Dec 24 2007, 4:45 pm, kennheinr...@sympatico.ca wrote:
On Dec 24, 3:10 am, Steven Kauffmann <steven.kauffm...@gmail.com
wrote:

So this means that the process below is not working when it's
implemented in hardware this because the sensitivity list is ignored
and so the process will never be updated?

process(port_a)
begin
-- do something
end process;

Not quite. VHDL is fundamentally a simulation language, which, when
written using certain common styles, allow it to be used as a source
language for hardware synthesis. This code really could have two ways
to interpret it: one in a simulation environment, which is exactly
what the official language definition explains, and one interpretation
as a hardware description, which is fuzzier. The idea behind using
certain common coding styles is to make sure the behaviour of your
code in simulation and synthesis are the same. That's what's meant by
"synthesis/simulation mismatch".

For simulation purposes, a process with a sensitivity list will run
exactly once at initialization (although in no particular order w.r.t.
other processes' initialization steps), and when the signal changes.
If you specify the wrong sensitivity list by accident, your process
won't respond as you expect (either ignoring events on the signal you
wanted to use, or firing at apparently random other times).

Generally, if you just want a process that responds asynchronously,
immediately, to a set of signals, (like if you're writing a simple
logic gate or an asynchronous memory read), you can skip the
sensitivity list altogether and the compiler will figure out the right
sensitivity list automatically, by looking at every signal that gets
read in the process. You want to either specify every signal correctly
or specify no signals at all in the sensitivity list. Otherwise
there's a good chance that you messed up.

Your question about "comparator in hardware" doesn't quite catch the
idea. If you wanted to follow this analogy, think of a process as
specifying some kind of piece of logic that might be a mixture of
clocked and combinatorial. The sensitivity list defines those inputs
which, if they have an event on them, may cause the output to change.
This means that those signals are either directly connected to the
circuit output through gates, or are used as clock input edges. (This
is admittedly a sloppy analogy.)

When you want to write something behind a clocked register (like a
counter, state machine, etc), you typically _only_ specify the clock
signal in the sensitivity list. Then you put the entire body of the
process inside an "if rising_edge(clk)..." statement. The combination
of these two things tells the synthesizer to generate the
combinatorial logic specified inside the "if" statement, with a flop
on each output signal you assign to. This again, is admittedly a
sloppy description of the synthesis process :)

If you write processes that don't follow one of these three styles
(clocked, combinatorial with no sensitivity, or combinatorial with
complete sensitivity), you're either doing the wrong thing (if you're
a beginner) or are trying to do something fancy (if you're a more
advanced user). If you're trying to be fancy as an advanced user,
there's still a good chance you're wrong, at least the first few
times :)

And so as to make sure to answer your last question:

process(port_a)
blah blah...

will run in simulation at initialization and when any subelement on
port_a (or port_a in its entirety) changes. In hardware, as long as
port_a is the only signal you look at inside your process, you should
be generating a simple combinatorial function of port_a. If
"blah_blah_bah" reads signals _other_ than port_a, or doesn't have the
complete sensitivity list (as in the 4 vs 5 signal discrepancy Mike
pointed out), you're most likely generating something which you didn't
want, regardless of whether you're simulating or synthesizing.

Hope this helps,

- Kenn
Yes I want to do something fancy, but it is not working and I think I
know the problem after that I read your post. But I don't know a
solution for it.

As I already mentioned in my first post, I have to do something in a
process when there is an event on a output port of an other component
described in VHDL. That component is a complex algorithm and because I
don't know how many clock pulses it need before its calculation is
ready, I want to use an other process to check if there is an event on
the output port. When there is an event, I know that the calculation
of the algorithm is done.

Because I thought that a sensitivity list wakes up a process when
there's an event on the signals in its list. I write the following
process.

process(output_complex_algorithm)
begin
result_ready <= not(result_ready);
end process;

I thought that when the output of the complex algorithm changed, the
result_ready signal would also change because of the sensitivity list.
This is not working in hardware. The reason for that, I think, is that
the signal output_complex_algorithm is not used in the process, only
in the sensitivity list. The sensitivity list is not a comparator but
these signals are directly connected with some logic as you said. But
because I don't use the signals in the sensitivity list, it's not
working. Is this correct what I'm saying?

Regards

Steven
 
On Jan 4, 3:32 am, Steven Kauffmann <steven.kauffm...@gmail.com>
wrote:
On Dec 24 2007, 4:45 pm, kennheinr...@sympatico.ca wrote:





On Dec 24, 3:10 am, Steven Kauffmann <steven.kauffm...@gmail.com
wrote:

So this means that the process below is not working when it's
implemented in hardware this because the sensitivity list is ignored
and so the process will never be updated?

process(port_a)
begin
 -- do something
end process;

Not quite. VHDL is fundamentally a simulation language, which, when
written using certain common styles, allow it to be used as a source
language for hardware synthesis. This code really could have two ways
to interpret it: one in a simulation environment, which is exactly
what the official language definition explains, and one interpretation
as a hardware description, which is fuzzier. The idea behind using
certain common coding styles is to make sure the behaviour of your
code in simulation and synthesis are the same. That's what's meant by
"synthesis/simulation mismatch".

For simulation purposes, a process with a sensitivity list will run
exactly once at initialization (although in no particular order w.r.t.
other processes' initialization steps), and when the signal changes.
If you specify the wrong sensitivity list by accident, your process
won't respond as you expect (either ignoring events on the signal you
wanted to use, or firing at apparently random other times).

Generally, if you just want a process that responds asynchronously,
immediately, to a set of signals, (like if you're writing a simple
logic gate or an asynchronous memory read), you can skip the
sensitivity list altogether and the compiler will figure out the right
sensitivity list automatically, by looking at every signal that gets
read in the process. You want to either specify every signal correctly
or specify no signals at all in the sensitivity list. Otherwise
there's a good chance that you messed up.

Your question about "comparator in hardware" doesn't quite catch the
idea.  If you wanted to follow this analogy, think of a process as
specifying some kind of piece of logic that might be a mixture of
clocked and combinatorial.  The sensitivity list defines those inputs
which, if they have an event on them, may cause the output to change.
This means that those signals are either directly connected to the
circuit output through gates, or are used as clock input edges. (This
is admittedly a sloppy analogy.)

When you want to write something behind a clocked register (like a
counter, state machine, etc), you typically _only_ specify the clock
signal in the sensitivity list. Then you put the entire body of the
process inside an "if rising_edge(clk)..." statement. The combination
of these two things tells the synthesizer to generate the
combinatorial logic specified inside the "if" statement, with a flop
on each output signal you assign to. This again, is admittedly a
sloppy description of the synthesis process :)

If you write processes that don't follow one of these three styles
(clocked, combinatorial with no sensitivity, or combinatorial with
complete sensitivity), you're either doing the wrong thing (if you're
a beginner) or are trying to do something fancy (if you're a more
advanced user). If you're trying to be fancy as an advanced user,
there's still a good chance you're wrong, at least the first few
times :)

And so as to make sure to answer your last question:

process(port_a)
blah blah...

will run in simulation at initialization and when any subelement on
port_a (or port_a in its entirety) changes. In hardware, as long as
port_a is the only signal you look at inside your process, you should
be generating a simple combinatorial function of port_a. If
"blah_blah_bah" reads signals _other_ than port_a, or doesn't have the
complete sensitivity list (as in the 4 vs 5 signal discrepancy Mike
pointed out), you're most likely generating something which you didn't
want, regardless of whether you're simulating or synthesizing.

Hope this helps,

 - Kenn

As I already mentioned in my first post, I have to do something in a
process when there is an event on a output port of an other component
described in VHDL. That component is a complex algorithm and because I
don't know how many clock pulses it need before its calculation is
ready, I want to use an other process to check if there is an event on
the output port.
Then the other component should be generating an 'output_valid' signal
to flag when the calculation is ready. This signal would be true on
each and every clock cycle when there is some new output ready.

When there is an event, I know that the calculation
of the algorithm is done.
'Events' don't synthesize well, because synthesis tools choose to
ignore sensitivity lists. This makes the synthesized result different
than from what you'll see in simulation. Other than to use a
sensitivity list for looking for rising or falling edges of clock
signals you shouldn't bother with them....but do pay attention to and
fix any synthesis warnings that pop out about them (more on that
later).

Because I thought that a sensitivity list wakes up a process when
there's an event on the signals in its list. I write the following
process.

process(output_complex_algorithm)
begin
 result_ready <= not(result_ready);
end process;

Per the VHDL standard, what you've written is correct, the problem is
that synthesis tools do not follow the standard when it comes to
sensitivity lists. They basically ignore the sensitivity list and
simply look at the rest of the code in the process. Given your code
above, your synthesis tool should have generated a warning that signal
'output_complex_algorithm' is not used in the process and will be
ignored. That's the tools way of saying, I'm violating the language
standard but at least I'm telling you about it. The reason it is
ignoring it is because it does not get used anywhere in the process
(other than in the sensitivity list...which the synthesis tool
ignores).

Now take a look at your process from the perspective of something that
has blatantly chosen to ignore the sensitivity list and looks what's
left

result_ready <= not(result_ready);

This will generate a free running, uncontrollable oscillator if
synthesized. Since it is also a combinatorial loop (i.e. feedback
with no intervening flip flop) the synthesis tool should flag this as
a 'warning' as well.

The other type of warning you can get from synthesis tools in regards
to sensitivity lists is an incomplete sensitivity list. In your
process, the signal 'result_ready' was used within the process but was
not in the sensitivity list. Again, the synthesis tool should
generate a warning to that effect. It is doing this because it went
off and determined what IT thinks your process SHOULD be sensitive to
and found that you did not include a signal.

Although the problem is technically with the synthesis tool for
violating the language standard, you have to live with it and design
around it lest you end up with hardware that doesn't work. Peruse the
list of warnings from synthesis and make sure you really understand
their implications. As you should be able to verify, the two types of
warnings that I believe you'll find right now regarding the
sensitivity list must be cleaned up because they represent ways that
the synthesized result is completely different from simulation.
Blaming the synthesis tool will get you nowhere, this behavior has
been there for a looooong time (although don't interpret that to mean
that if you run across other ways that synthesis differs from the
language standard that you shouldn't open a service request, synthesis
tools have lots of bugs).

Synthesis tool 'warnings' can many times be design errors. The only
thing that the synthesis tool considers as an 'error' is something
that prevents it from generating an output file, anything else is a
'warning'. Some examples:
Violating specified timing requirements? 'Warning'.
Completely change the logic by ignoring sensitivity list? 'Warning'

I thought that when the output of the complex algorithm changed, the
result_ready signal would also change because of the sensitivity list.
This is not working in hardware. The reason for that, I think, is that
the signal output_complex_algorithm is not used in the process, only
in the sensitivity list. The sensitivity list is not a comparator but
these signals are directly connected with some logic as you said. But
because I don't use the signals in the sensitivity list, it's not
working. Is this correct what I'm saying?
I think so...get out the fine tooth comb and peruse the warnings that
are no doubt present in the output of the synthesis tool and clean
them all up and you'll be much closer to a working system.

Kevin Jennings
 
On Jan 4, 6:18 am, KJ <kkjenni...@sbcglobal.net> wrote:
On Jan 4, 3:32 am, Steven Kauffmann <steven.kauffm...@gmail.com
wrote:

On Dec 24 2007, 4:45 pm, kennheinr...@sympatico.ca wrote:

On Dec 24, 3:10 am, Steven Kauffmann <steven.kauffm...@gmail.com
wrote:

So this means that the process below is not working when it's
implemented in hardware this because the sensitivity list is ignored
and so the process will never be updated?

process(port_a)
begin
-- do something
end process;

Not quite. VHDL is fundamentally a simulation language, which, when
written using certain common styles, allow it to be used as a source
language for hardware synthesis. This code really could have two ways
to interpret it: one in a simulation environment, which is exactly
what the official language definition explains, and one interpretation
as a hardware description, which is fuzzier. The idea behind using
certain common coding styles is to make sure the behaviour of your
code in simulation and synthesis are the same. That's what's meant by
"synthesis/simulation mismatch".

For simulation purposes, a process with a sensitivity list will run
exactly once at initialization (although in no particular order w.r.t.
other processes' initialization steps), and when the signal changes.
If you specify the wrong sensitivity list by accident, your process
won't respond as you expect (either ignoring events on the signal you
wanted to use, or firing at apparently random other times).

Generally, if you just want a process that responds asynchronously,
immediately, to a set of signals, (like if you're writing a simple
logic gate or an asynchronous memory read), you can skip the
sensitivity list altogether and the compiler will figure out the right
sensitivity list automatically, by looking at every signal that gets
read in the process. You want to either specify every signal correctly
or specify no signals at all in the sensitivity list. Otherwise
there's a good chance that you messed up.

Your question about "comparator in hardware" doesn't quite catch the
idea. If you wanted to follow this analogy, think of a process as
specifying some kind of piece of logic that might be a mixture of
clocked and combinatorial. The sensitivity list defines those inputs
which, if they have an event on them, may cause the output to change.
This means that those signals are either directly connected to the
circuit output through gates, or are used as clock input edges. (This
is admittedly a sloppy analogy.)

When you want to write something behind a clocked register (like a
counter, state machine, etc), you typically _only_ specify the clock
signal in the sensitivity list. Then you put the entire body of the
process inside an "if rising_edge(clk)..." statement. The combination
of these two things tells the synthesizer to generate the
combinatorial logic specified inside the "if" statement, with a flop
on each output signal you assign to. This again, is admittedly a
sloppy description of the synthesis process :)

If you write processes that don't follow one of these three styles
(clocked, combinatorial with no sensitivity, or combinatorial with
complete sensitivity), you're either doing the wrong thing (if you're
a beginner) or are trying to do something fancy (if you're a more
advanced user). If you're trying to be fancy as an advanced user,
there's still a good chance you're wrong, at least the first few
times :)

And so as to make sure to answer your last question:

process(port_a)
blah blah...

will run in simulation at initialization and when any subelement on
port_a (or port_a in its entirety) changes. In hardware, as long as
port_a is the only signal you look at inside your process, you should
be generating a simple combinatorial function of port_a. If
"blah_blah_bah" reads signals _other_ than port_a, or doesn't have the
complete sensitivity list (as in the 4 vs 5 signal discrepancy Mike
pointed out), you're most likely generating something which you didn't
want, regardless of whether you're simulating or synthesizing.

Hope this helps,

- Kenn

As I already mentioned in my first post, I have to do something in a
process when there is an event on a output port of an other component
described in VHDL. That component is a complex algorithm and because I
don't know how many clock pulses it need before its calculation is
ready, I want to use an other process to check if there is an event on
the output port.

Then the other component should be generating an 'output_valid' signal
to flag when the calculation is ready. This signal would be true on
each and every clock cycle when there is some new output ready.

When there is an event, I know that the calculation
of the algorithm is done.

'Events' don't synthesize well, because synthesis tools choose to
ignore sensitivity lists. This makes the synthesized result different
than from what you'll see in simulation. Other than to use a
sensitivity list for looking for rising or falling edges of clock
signals you shouldn't bother with them....but do pay attention to and
fix any synthesis warnings that pop out about them (more on that
later).



Because I thought that a sensitivity list wakes up a process when
there's an event on the signals in its list. I write the following
process.

process(output_complex_algorithm)
begin
result_ready <= not(result_ready);
end process;

Per the VHDL standard, what you've written is correct, the problem is
that synthesis tools do not follow the standard when it comes to
sensitivity lists. They basically ignore the sensitivity list and
simply look at the rest of the code in the process. Given your code
above, your synthesis tool should have generated a warning that signal
'output_complex_algorithm' is not used in the process and will be
ignored. That's the tools way of saying, I'm violating the language
standard but at least I'm telling you about it. The reason it is
ignoring it is because it does not get used anywhere in the process
(other than in the sensitivity list...which the synthesis tool
ignores).

Now take a look at your process from the perspective of something that
has blatantly chosen to ignore the sensitivity list and looks what's
left

result_ready <= not(result_ready);

This will generate a free running, uncontrollable oscillator if
synthesized. Since it is also a combinatorial loop (i.e. feedback
with no intervening flip flop) the synthesis tool should flag this as
a 'warning' as well.

The other type of warning you can get from synthesis tools in regards
to sensitivity lists is an incomplete sensitivity list. In your
process, the signal 'result_ready' was used within the process but was
not in the sensitivity list. Again, the synthesis tool should
generate a warning to that effect. It is doing this because it went
off and determined what IT thinks your process SHOULD be sensitive to
and found that you did not include a signal.

Although the problem is technically with the synthesis tool for
violating the language standard, you have to live with it and design
around it lest you end up with hardware that doesn't work. Peruse the
list of warnings from synthesis and make sure you really understand
their implications. As you should be able to verify, the two types of
warnings that I believe you'll find right now regarding the
sensitivity list must be cleaned up because they represent ways that
the synthesized result is completely different from simulation.
Blaming the synthesis tool will get you nowhere, this behavior has
been there for a looooong time (although don't interpret that to mean
that if you run across other ways that synthesis differs from the
language standard that you shouldn't open a service request, synthesis
tools have lots of bugs).

Synthesis tool 'warnings' can many times be design errors. The only
thing that the synthesis tool considers as an 'error' is something
that prevents it from generating an output file, anything else is a
'warning'. Some examples:
Violating specified timing requirements? 'Warning'.
Completely change the logic by ignoring sensitivity list? 'Warning'

I thought that when the output of the complex algorithm changed, the
result_ready signal would also change because of the sensitivity list.
This is not working in hardware. The reason for that, I think, is that
the signal output_complex_algorithm is not used in the process, only
in the sensitivity list. The sensitivity list is not a comparator but
these signals are directly connected with some logic as you said. But
because I don't use the signals in the sensitivity list, it's not
working. Is this correct what I'm saying?

I think so...get out the fine tooth comb and peruse the warnings that
are no doubt present in the output of the synthesis tool and clean
them all up and you'll be much closer to a working system.

Kevin Jennings
Kevin has given excellent advice. While I abhor the synthesis tools'
ignorance of sensitivity lists, at least they do give you warnings
that they cannot completely implement the list's effects. It is also
interesting that they are perfectly willing to generate a latch, which
is an artifact of the behavior due at least partially to the
sensitivity list.

If you try to think about what kind of hardware would be needed to
implement an "event detector", such a thing would be very risky to
design in an FPGA or ASIC without very explicit timing control, which
is something that is generally best left to controlling clocks and
paths between clocked registers.

Besides, in the real implementation, how do you know that the
circuit's output does not change until it magically has the right
answer? Maybe it changes multiple times before settling on the right
answer. What happens if the valid output is the same data twice in a
row (there would be no change to the data, but it represents two valid
pieces of data)? This is the reason you need to have that circuit
either guarantee that output will be valid on specific clock cycles
(usually a fixed cycle delay from the input, etc.), or it must give
you a signal that says the data is or will be valid. Both are valid
design techniques, and are universally used.

Andy
 
On Fri, 4 Jan 2008 00:32:21 -0800 (PST), Steven Kauffmann
<steven.kauffmann@gmail.com> wrote:

On Dec 24 2007, 4:45 pm, kennheinr...@sympatico.ca wrote:
On Dec 24, 3:10 am, Steven Kauffmann <steven.kauffm...@gmail.com
wrote:

Because I thought that a sensitivity list wakes up a process when
there's an event on the signals in its list. I write the following
process.

process(output_complex_algorithm)
begin
result_ready <= not(result_ready);
end process;

I thought that when the output of the complex algorithm changed, the
result_ready signal would also change because of the sensitivity list.
This is not working in hardware. The reason for that, I think, is that
the signal output_complex_algorithm is not used in the process, only
in the sensitivity list. The sensitivity list is not a comparator but
these signals are directly connected with some logic as you said. But
because I don't use the signals in the sensitivity list, it's not
working. Is this correct what I'm saying?
As KJ says, this is certainly valid VHDL and should do what you expect in
simulation.

But the trouble is that synthesis tools cannot generally translate VHDL into
hardware (this is equally true for all the hardware-C efforts out there; any C
or C++ construct capable of translation into hardware already has a VHDL
equivalent.) Now some of these limitations are due to the current state of the
synthesis tools (whether VHDL or other) but some are fundamental to what is
achievable in hardware.

The upshot is that, for synthesis, you need to "think hardware" first and
foremost, and create something that WILL synthesise. Then and only then, worry
about the sensitivity list to provide the simulator with information to make the
simulation behaviour match the real hardware.

Again as KJ says, the "clean" way in this case is for "complex_algorithm" to
provide a data_valid signal.

But assuming it cannot, (e.g. it's someone else's code) we have to find a way
around the problem.

Which is to detect and announce changes in the output from "complex_algorithm".

Thinking hardware; you are right that a comparator is part of the solution. But
we are detecting changes in the output; therefore comparing the output with an
old copy of the output will work.

You also said that "complex_algorithm" took an unknown number of clock pulses;
implying it is a clocked component, so assume it produces at most one result per
clock. (Two per clock is possible; let's not discuss that here!) Therefore we
can use the same clock to clock a storage element for our "old copy".

So:

process(clk)
begin
if rising_edge(clk) then
old_output <= output_complex_algorithm;
-- new_data_clocked <= new_data; -- ignore, but see below
end if;
end process;

will store the current output until the next cycle, and present the previous
output during this cycle. It only does anything when there is an event on "clk"
therefore that is the only signal required in the sensitivity list.

process (old_output, output_complex_algorithm)
begin
if old_output = output_complex_algorithm then
new_data <= 0;
else
new_data <= '1';
end if;
-- assuming new_data is of type std_logic, or simply
-- new_data <= old_output /= output_complex_algorithm;
-- if new_data is boolean;
end process;

The second process is unclocked; it will simply produce gates. It needs BOTH
signals shown in its sensitivity list.

It will synthesise correctly without them; however if you omit old_output, you
will get incorrect SIMULATION results, because new_data will go '1' when new
data comes in; however in the following cycle, when "old_output" updates, the
simulator will not wake up the process to retract new_data. This is what the
"missing signals in sensitivity list" synthesis warning is about.

It can also be expressed as a single statement; this is simply shorthand for
the above; the tools will work out the sensitivity list from the statement
because what can be expressed in such a statement is strictly limited in scope.

new_data <= old_output /= output_complex_algorithm; -- boolean
-- or for std_logic
new_data <= '0' when old_output = output_complex_algorithm else '1';

Note that "new_data" would normally be stored in a register of its own, as
commented out in the first process; in the current form it is present for less
than a cycle; but guaranteed to be correct at the clock rising_edge, in the SAME
CYCLE as the new input (which may or may not be important to you).

If you want a stored "new_data" output (a clean signal, but one cycle late) you
can combine both processes into one:

process(clk)
begin
if rising_edge(clk) then
old_output <= output_complex_algorithm;
new_data_clocked <= old_output /= output_complex_algorithm;
end if;
end process;

and because you are only interested in the comparator output at the time of the
clock edge, NO other signal is required in the sensitivity list. (Which is good
synchronous design).

The fact that it is one cycle late may not be of any importance to you; simply
use "old_output" downstream instead of "output_complex_algorithm" and it is in
the correct cycle; you have just added one cycle to your pipeline depth.

Sorry if this is a bit pedantic, but I hope that the step by step approach makes
it clear.

- Brian
 
On Jan 4, 12:17 pm, Brian Drummond <brian_drumm...@btconnect.com>
wrote:
On Fri, 4 Jan 2008 00:32:21 -0800 (PST), Steven Kauffmann



steven.kauffm...@gmail.com> wrote:
On Dec 24 2007, 4:45 pm, kennheinr...@sympatico.ca wrote:
On Dec 24, 3:10 am, Steven Kauffmann <steven.kauffm...@gmail.com
wrote:
Because I thought that a sensitivity list wakes up a process when
there's an event on the signals in its list. I write the following
process.

process(output_complex_algorithm)
begin
result_ready <= not(result_ready);
end process;

I thought that when the output of the complex algorithm changed, the
result_ready signal would also change because of the sensitivity list.
This is not working in hardware. The reason for that, I think, is that
the signal output_complex_algorithm is not used in the process, only
in the sensitivity list. The sensitivity list is not a comparator but
these signals are directly connected with some logic as you said. But
because I don't use the signals in the sensitivity list, it's not
working. Is this correct what I'm saying?

As KJ says, this is certainly valid VHDL and should do what you expect in
simulation.

But the trouble is that synthesis tools cannot generally translate VHDL into
hardware (this is equally true for all the hardware-C efforts out there; any C
or C++ construct capable of translation into hardware already has a VHDL
equivalent.) Now some of these limitations are due to the current state of the
synthesis tools (whether VHDL or other) but some are fundamental to what is
achievable in hardware.

The upshot is that, for synthesis, you need to "think hardware" first and
foremost, and create something that WILL synthesise. Then and only then, worry
about the sensitivity list to provide the simulator with information to make the
simulation behaviour match the real hardware.

Again as KJ says, the "clean" way in this case is for "complex_algorithm" to
provide a data_valid signal.

But assuming it cannot, (e.g. it's someone else's code) we have to find a way
around the problem.

Which is to detect and announce changes in the output from "complex_algorithm".

Thinking hardware; you are right that a comparator is part of the solution. But
we are detecting changes in the output; therefore comparing the output with an
old copy of the output will work.

You also said that "complex_algorithm" took an unknown number of clock pulses;
implying it is a clocked component, so assume it produces at most one result per
clock. (Two per clock is possible; let's not discuss that here!) Therefore we
can use the same clock to clock a storage element for our "old copy".

So:

process(clk)
begin
if rising_edge(clk) then
old_output <= output_complex_algorithm;
-- new_data_clocked <= new_data; -- ignore, but see below
end if;
end process;

will store the current output until the next cycle, and present the previous
output during this cycle. It only does anything when there is an event on "clk"
therefore that is the only signal required in the sensitivity list.

process (old_output, output_complex_algorithm)
begin
if old_output = output_complex_algorithm then
new_data <= 0;
else
new_data <= '1';
end if;
-- assuming new_data is of type std_logic, or simply
-- new_data <= old_output /= output_complex_algorithm;
-- if new_data is boolean;
end process;

The second process is unclocked; it will simply produce gates. It needs BOTH
signals shown in its sensitivity list.

It will synthesise correctly without them; however if you omit old_output, you
will get incorrect SIMULATION results, because new_data will go '1' when new
data comes in; however in the following cycle, when "old_output" updates, the
simulator will not wake up the process to retract new_data. This is what the
"missing signals in sensitivity list" synthesis warning is about.

It can also be expressed as a single statement; this is simply shorthand for
the above; the tools will work out the sensitivity list from the statement
because what can be expressed in such a statement is strictly limited in scope.

new_data <= old_output /= output_complex_algorithm; -- boolean
-- or for std_logic
new_data <= '0' when old_output = output_complex_algorithm else '1';

Note that "new_data" would normally be stored in a register of its own, as
commented out in the first process; in the current form it is present for less
than a cycle; but guaranteed to be correct at the clock rising_edge, in the SAME
CYCLE as the new input (which may or may not be important to you).

If you want a stored "new_data" output (a clean signal, but one cycle late) you
can combine both processes into one:

process(clk)
begin
if rising_edge(clk) then
old_output <= output_complex_algorithm;
new_data_clocked <= old_output /= output_complex_algorithm;
end if;
end process;

and because you are only interested in the comparator output at the time of the
clock edge, NO other signal is required in the sensitivity list. (Which is good
synchronous design).

The fact that it is one cycle late may not be of any importance to you; simply
use "old_output" downstream instead of "output_complex_algorithm" and it is in
the correct cycle; you have just added one cycle to your pipeline depth.

Sorry if this is a bit pedantic, but I hope that the step by step approach makes
it clear.

- Brian
Watch out for one fine point though: a simple check of "output not
equal to input" is not always equivalent to a "computation done" flag.
For matching the behaviour of your simulation/sensitivity example
given, it should work. But if you were, say pipelining some
calculation, and *waiting* for the new result before going into some
other stage of the pipeline, it could fail. If the earlier stage
happened to produce the same result on different inputs, your data
might be correct, the first computation would be complete, but your
change-detect logic wouldn't fire and your next stage would be waiting
forever. In some designs this might be OK; in others it's not.

The unclocked process example that detects a change is also a very
dangerous thing; it has the potential to produce glitches and timing
problems.

I would strongly encourage you to add a "computation done" flag to
your complex calculation block. And it goes without saying that this
should be a synchronous (clocked) flag, just like the output of your
complex block ought to be :)

Brian's advice above to "think hardware" first is right on the money;
a "done flag" is probably the first thought of most hardware guys.

- Kenn
 
On Fri, 4 Jan 2008 11:38:00 -0800 (PST), kennheinrich@sympatico.ca wrote:

On Jan 4, 12:17 pm, Brian Drummond <brian_drumm...@btconnect.com
wrote:
On Fri, 4 Jan 2008 00:32:21 -0800 (PST), Steven Kauffmann

I thought that when the output of the complex algorithm changed, the
result_ready signal would also change because of the sensitivity list.
Thinking hardware; you are right that a comparator is part of the solution. But
we are detecting changes in the output; therefore comparing the output with an
old copy of the output will work.

new_data <= old_output /= output_complex_algorithm; -- boolean
-- or for std_logic
new_data <= '0' when old_output = output_complex_algorithm else '1';

Note that "new_data" would normally be stored in a register of its own, as
commented out in the first process; in the current form it is present for less
than a cycle; but guaranteed to be correct at the clock rising_edge, in the SAME
CYCLE as the new input (which may or may not be important to you).

Watch out for one fine point though: a simple check of "output not
equal to input" is not always equivalent to a "computation done" flag.
Now this is true! Either for multiple computations producing the same result,
or the computation outputting an intermediate result. I was taking the stated
problem as the brief, but it's certainly worth asking if it's valid.

The unclocked process example that detects a change is also a very
dangerous thing; it has the potential to produce glitches and timing
problems.
Not "very dangerous" if it is used as I suggested - sampled on the clock edge.
The design tools will either guarantee it is valid then, or report a timing
error, as long as they are used correctly. (If you lie to them about the clock
rate, for example, all bets are off!)

But you are of course correct that other ways of using it - especially, using it
as a clock signal itself - have their attendant dangers.

- Brian
 
On Jan 4, 7:52 pm, Brian Drummond <brian_drumm...@btconnect.com>
wrote:
The unclocked process example that detects a change is also a very
dangerous thing; it has the potential to produce glitches and timing
problems.

Not "very dangerous" if it is used as I suggested - sampled on the clock edge.
The design tools will either guarantee it is valid then, or report a timing
error, as long as they are used correctly. (If you lie to them about the clock
rate, for example, all bets are off!)
You're right; I mis-read your process.

I'm sure this is all old hat to many. But for the benefit of the OP, I
still think you want to add a done flag to the computation unit for
real hardware. More specifically...

There are still more ways the comparator/not equal approach can fail
in the general case. Consider, for example, if the complex logic unit
outputs a large result (say a record type) and not all of the outputs
subelements change synchronously. Maybe one of the portions of the
result is available a clock or two before the others. Then the
comparator may falsely detect "done" when it's not really done, just
in the middle of a partial result. Similarly if the output has don't
care fields in some cases: say a hypothetical controller outputs a
record which can indicate either a "reset" command with an ignored
address, or a "read" command from a specified address. If the address
(which was a don't care) changed spuriously (which conceivably is
legal when the controller is outputting a "reset") it could trigger
downstream action.

Again, these would all be in keeping with the simulation semantics of
the original code, but is not in general a robust way of achieving
system synchronization.

And I can almost guarantee simulation/synthesis mismatch if there are
'X's in the complex output; in simulation, an 'X' will never equal a
'0' but in hardware your gates only know '1' and '0'. So if your sim
initializes the calculation output to 'X', then produces a '1', your
comparator in simulation will detect a change. But if your *hardware*
initializes to '0' and then you calculate a '0', your comparator won't
fire. Mismatch!

Cheers,

- Kenn
 

Welcome to EDABoard.com

Sponsor

Back
Top