Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > VHDL > clocked process and sensitivity list

Reply
Thread Tools

clocked process and sensitivity list

 
 
alb
Guest
Posts: n/a
 
      05-03-2013
Hi everyone (geez has been a long time since my last post...),

I'm looking at a piece of code that I would feel embarrassed to post
here and when I synthesize it I get a warning about 'Feedback mux
created for signal...'. Any insight on the type of warning?

I am also puzzled about the style used in the code which goes along
these lines:

process (clr, rst, foo, bar, foobar)
begin
if rst = '1' then
-- a bunch of assignments
elsif foo = '1' then
-- another bunch of assignments
elsif bar = '1' then
-- another bloody bunch of assignments
elsif (bar = '0') and (foo = '1') and (foobar = '1') then
-- another insane bunch of assignments

elsif rising_edge(clk) then
case mysterious_signal is
when '1' =>
foobar <= '0';
mysterious_signal <= '0';
-- gibberish

when '0' =>
-- some more gibberish
end case;
end if;
end process; -- thanks GOD!!!

Except for the readability issues, there's something deeper I'd like to
understand; when there's an asynchronous set and reset I would
definitely need to have both signals in the sensitivity list otherwise
the pre-synthesis simulation would never trigger the process
assignments. But why synthesis does not need them?

Moreover the 'foobar' signal in the above snippet is truly not needed in
the sensitivity list since an event should be scheduled for it to change
at next delta cycle. Am I wrong?

There's a possibility that my questions are badly formulated!! But I'm
trying to figure out what the heck stroke the designer's mind when he
wrote this...

Al

--
A: Because it fouls the order in which people normally read text.
Q: Why is top-posting such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
 
Reply With Quote
 
 
 
 
Thomas Stanka
Guest
Posts: n/a
 
      05-03-2013
On 3 Mai, 11:51, alb <(E-Mail Removed)> wrote:
> here and when I synthesize it I get a warning about 'Feedback mux
> created for signal...'. Any insight on the type of warning?

[..]
> process (clr, rst, foo, bar, foobar)
> begin
> * if rst = '1' then
> * * -- a bunch of assignments
> * elsif foo = '1' then
> * * -- another bunch of assignments
> * elsif bar = '1' then
> * * -- another bloody bunch of assignments
> * elsif (bar = '0') and (foo = '1') and (foobar = '1') then
> * * -- another insane bunch of assignments
>
> * elsif rising_edge(clk) then

[..]

First I assume the clr in sensitivity list should be clk.
In fact the designer wrote a bunch of logic in the asynchronous
(re)set path of the FF. I see no wrong on a formal point(depending on
conntent of the "bunch of assignments" there could still be trouble),
but I guess that usual synthesis tools accept only

if resetcondition = true then
reset/set
elsif rising_edge(Clk) then
modify
end if

Depending on content of the commented lines, you could have logic that
is hard to implement in a technology that contains no FF with both set
and reset. This would lead to creation of latch with a lot surrounding
stuff to emulate FF with async set and reset. The warning is for me
first hint that some latch or even worse is instantiated. I think you
need to analyse for all signals in (re)set whats happing.
A good example of what is sometimes desired on first glance, but not
synthesiseable by any tool:

if reset = '1' than
FF <= Inputsignal;
elsif ....


best regards

Thomas
 
Reply With Quote
 
 
 
 
Andy
Guest
Posts: n/a
 
      05-03-2013
First things first. A "feedback mux generated" message almost always indicates an issue with asynchronous resets.

In your code, if any of those reset conditions trigger, the elsif rising_edge(clk) section does not execute (nor do the other reset sections execute).Therefore the synthesis tool has to add a feedback mux for those registersnot reset by all reset conditions. The feedback mux is controlled by the reset conditions (oops, they're asynchronous!) so that the register does notupdate on rising clock edges while any of the reset conditions is true.

If you really want to have non-reset and reset registers in the same process, then you should use an "if rising_edge(clk)" section first, with a matching end if, and then a separate if statement (NOT elsif!) afterwards for EACH reset input condition.

Note that using multiple, partial asynchronous resets can cause strange problems, if circuitry that is not reset is using outputs from other asynchronously reset circuitry, since those outputs can be reset at any time relative to the clock. For this reason, asynchronous resets should generally only be used for general initialization, and not for functional logic purposes. Consider other ways to accomplish what the multiple asynchronous resets aretrying to do.

As for the sensitivity list issues, generating an event is not the same as triggering a process. A process has to be sensitive to the signal in order for an event on that signal to cause the process to re-execute.

Synthesis tools started out ignoring sensitivity lists, and have continued to do so to this day, much to my chagrin. At least they warn you when they find a sensitivity list problem that would cause a mismatch between the code's simulated behavior and that of the resulting hardware.

Andy
 
Reply With Quote
 
Ralf Hildebrandt
Guest
Posts: n/a
 
      05-06-2013
Hi alb!


> process (clr, rst, foo, bar, foobar)

....
> elsif (bar = '0') and (foo = '1') and (foobar = '1') then
> -- another insane bunch of assignments
>
> elsif rising_edge(clk) then
> case mysterious_signal is
> when '1' =>
> foobar <= '0';

....
> end process; -- thanks GOD!!!


> Moreover the 'foobar' signal in the above snippet is truly not needed in
> the sensitivity list since an event should be scheduled for it to change
> at next delta cycle. Am I wrong?


foobar is needed in the sensitivity list: it is a Flipflop written in
the rising_edge(clk) part and furthermore it is used as async. reset/set
for the "another insane bunch of assignments"-branch.

Therefore it may be that foobar is a signal, that triggers it's own
reset. But I guess the designer of this code was aware of this and did
pay attention to it.

But let's come back to the "feedback mux"-problem: foobar is used as
input for the reset/set conditions. Therefore if the "another insane
bunch of assignments"-branch gets active, then the
"rising_edge(clk)"-part should not be reached. For this purpose
synthesis tools may infer a data multiplexer. Let's have a look at some
synthesizable code:

process(reset_n,set_n,clk)
begin
if (reset_n='0') then
dout(1) <= '0';
dout(0) <= '0';
elsif (set_n='0') then
dout(1) <= '1';
--dout(0) <= '1';
elsif rising_edge(clk) then
dout(1) <= din(1);
dout(0) <= din(0);
end if;
end process;

As can be seen, dout(0) does not have a set-Input, but if set_n gets
active, then dout(0) must not change. Therefore synthesis builds the
following logic for the "rising_edge(clk)"-part :
"if set_n='0' then dout(0)<=dout(0); else dout(0)<=din(0);"


Please note that all this depends on your synthesis tool and the target
library.

Ralf
 
Reply With Quote
 
Ralf Hildebrandt
Guest
Posts: n/a
 
      05-06-2013
Hi Thomas!


> A good example of what is sometimes desired on first glance, but not
> synthesiseable by any tool:
>
> if reset = '1' than
> FF <= Inputsignal;
> elsif ....


This synthesizes "well" to a Flipflop with reset and set input and some
logic in front of that.

set_input gets active, if reset='1' and Inputsignal='1'
reset_input gets active, if reset='1' and Inputsignal='0'

This works fine as long as Inputsignal does not change around the time
when reset gets inactive.

This is not code that is accepted as good code, may cause trouble with
synthesis and ATPG tools and so on, but it is synthesizable and works.

Ralf

 
Reply With Quote
 
alb
Guest
Posts: n/a
 
      05-07-2013
Hi Andy,

On 03/05/2013 17:13, Andy wrote:
> First things first. A "feedback mux generated" message almost always
> indicates an issue with asynchronous resets.


I believe that 'almost' in your statement is referred to the variability
of the various synthesis tools' implementation.

>
> In your code, if any of those reset conditions trigger, the elsif
> rising_edge(clk) section does not execute (nor do the other reset
> sections execute). Therefore the synthesis tool has to add a feedback
> mux for those registers not reset by all reset conditions. The
> feedback mux is controlled by the reset conditions (oops, they're
> asynchronous!) so that the register does not update on rising clock
> edges while any of the reset conditions is true.


meaning that if a signal is not set for *all* sets and resets, the
synthesis needs to 'remember' the state of the not-assigned signal to
maintain its state. Sorry if I needed to reformulate it, but I guess is
part of my 'learning process'!

>
> If you really want to have non-reset and reset registers in the same
> process, then you should use an "if rising_edge(clk)" section first,
> with a matching end if, and then a separate if statement (NOT elsif!)
> afterwards for EACH reset input condition.
>


got your point.

> Note that using multiple, partial asynchronous resets can cause
> strange problems, if circuitry that is not reset is using outputs
> from other asynchronously reset circuitry, since those outputs can be
> reset at any time relative to the clock. For this reason,
> asynchronous resets should generally only be used for general
> initialization, and not for functional logic purposes. Consider other
> ways to accomplish what the multiple asynchronous resets are trying
> to do.


This is the direction towards which I'm willing to go. The code (as I
sarcastically described) has been put together with patches after
patches up to a point where 'it works', but I've been asked to review
the code and pin point any suspicious part which might cause problems.

The fun part of it is the total absence of specs and a very primitive
verification plan in place... but that's another issue.

>
> As for the sensitivity list issues, generating an event is not the
> same as triggering a process. A process has to be sensitive to the
> signal in order for an event on that signal to cause the process to
> re-execute.


Meaning that every signal the process depends on (i.e. resets/sets and
clock) should be in the sensitivity list. Correct?

>
> Synthesis tools started out ignoring sensitivity lists, and have
> continued to do so to this day, much to my chagrin. At least they
> warn you when they find a sensitivity list problem that would cause a
> mismatch between the code's simulated behavior and that of the
> resulting hardware.
>


That is unfortunate and allows proliferating bad habits as well. I often
see designers rushing to the synthesis phase (or even the FPGA
programming) without paying too much of attention to pre-synth simulations.
 
Reply With Quote
 
alb
Guest
Posts: n/a
 
      05-07-2013
Hi Ralf,

On 06/05/2013 09:43, Ralf Hildebrandt wrote:
> ....
>> elsif (bar = '0') and (foo = '1') and (foobar = '1') then
>> -- another insane bunch of assignments
>>
>> elsif rising_edge(clk) then
>> case mysterious_signal is
>> when '1' =>
>> foobar <= '0';

> ....
>> end process; -- thanks GOD!!!

>
>> Moreover the 'foobar' signal in the above snippet is truly not needed in
>> the sensitivity list since an event should be scheduled for it to change
>> at next delta cycle. Am I wrong?

>
> foobar is needed in the sensitivity list: it is a Flipflop written in
> the rising_edge(clk) part and furthermore it is used as async. reset/set
> for the "another insane bunch of assignments"-branch.


Uhm, I guess you are right. Indeed I guess I was also right that
'foobar' is scheduled for a change in the next delta cycle, but if the
process is not sensitive to it (with the sensitivity list) than it will
not trigger. Is this a correct statement?

>
> Therefore it may be that foobar is a signal, that triggers it's own
> reset. But I guess the designer of this code was aware of this and did
> pay attention to it.


Well, I've raised this question also. Indeed I did not even receive a
strong opinion on why the resets/sets should really be asynchronous...

>
> But let's come back to the "feedback mux"-problem: foobar is used as
> input for the reset/set conditions. Therefore if the "another insane
> bunch of assignments"-branch gets active, then the
> "rising_edge(clk)"-part should not be reached. For this purpose
> synthesis tools may infer a data multiplexer. Let's have a look at some
> synthesizable code:
>
> process(reset_n,set_n,clk)
> begin
> if (reset_n='0') then
> dout(1) <= '0';
> dout(0) <= '0';
> elsif (set_n='0') then
> dout(1) <= '1';
> --dout(0) <= '1';
> elsif rising_edge(clk) then
> dout(1) <= din(1);
> dout(0) <= din(0);
> end if;
> end process;
>
> As can be seen, dout(0) does not have a set-Input, but if set_n gets
> active, then dout(0) must not change. Therefore synthesis builds the
> following logic for the "rising_edge(clk)"-part :
> "if set_n='0' then dout(0)<=dout(0); else dout(0)<=din(0);"


that is crystal clear. In the even of a reset_n/set_n and clk happening
at the same time both will have an event schedule for the same
delta-cycle and to prevent the clk branch to trigger there should be
some logic 'around' it, hence the feedback mux.

>
>
> Please note that all this depends on your synthesis tool and the target
> library.


[OT] This is indeed very unfortunate. When we will have a common
agreement by synthesis tool vendors on 'how a synthesis tool should
behave'. Is there any standard they need to obey? I apologize but I got
a bit 'infected' by the *nix world where platforms aim to comply to
POSIX standards and code can be - to a large extent - portable.

 
Reply With Quote
 
Andy
Guest
Posts: n/a
 
      05-07-2013
Alb,

My use of "almost always" instead of "always" is just being cautious. I have never had a case where it was not caused by a missing assignment in a process with a preceding asynchronous reset clause. But I have not written every possible combination of code yet, nor have I used every synthesis tool.

Anytime a description has to remember a previously (in simulation time) stored value, there is some type of storage or storage modification involved in the implementation. This fundamental behavioral aspect of synthesis is atthe root of how/why latches, registers and clock enables are inferred, andholds true whether you use signals or variables for your data. But that's another subject...

I feel your pain. The absence of specifications for what the code is actually required to do (NOT how it has to or does do it) creates problems whenever the code must be changed. An effective testbench is not possible withouta good specification. Otherwise, the testbench can only test what you think the code is supposed to do, which must be extracted from what the code actually does.

All causal signals must be in the sensitivity list. Non-causal signals should not be in the sensitivity list. In a combinatorial process, every signalread is causal. In a clocked process, only the clock and if present, asynchronous reset(s) are causal.

Andy
 
Reply With Quote
 
rickman
Guest
Posts: n/a
 
      05-07-2013
On 5/7/2013 9:27 AM, Andy wrote:
> Alb,
>
> My use of "almost always" instead of "always" is just being cautious. I have never had a case where it was not caused by a missing assignment in a process with a preceding asynchronous reset clause. But I have not written every possible combination of code yet, nor have I used every synthesis tool.
>
> Anytime a description has to remember a previously (in simulation time) stored value, there is some type of storage or storage modification involved in the implementation. This fundamental behavioral aspect of synthesis is at the root of how/why latches, registers and clock enables are inferred, and holds true whether you use signals or variables for your data. But that's another subject...
>
> I feel your pain. The absence of specifications for what the code is actually required to do (NOT how it has to or does do it) creates problems whenever the code must be changed. An effective testbench is not possible without a good specification. Otherwise, the testbench can only test what you think the code is supposed to do, which must be extracted from what the code actually does.
>
> All causal signals must be in the sensitivity list. Non-causal signals should not be in the sensitivity list. In a combinatorial process, every signal read is causal. In a clocked process, only the clock and if present, asynchronous reset(s) are causal.


I'm not following the issue here. I can't see why any extra logic would
need to be asserted. The clocked process infers a register for each bit
assigned in the edge triggered section. Are the async assigned bits
*not* assigned in the edge triggered section?

What am I missing?

--

Rick
 
Reply With Quote
 
Ralf Hildebrandt
Guest
Posts: n/a
 
      05-08-2013
Hi alb!


> Uhm, I guess you are right. Indeed I guess I was also right that
> 'foobar' is scheduled for a change in the next delta cycle, but if the
> process is not sensitive to it (with the sensitivity list) than it will
> not trigger. Is this a correct statement?


This is correct for simulation. Most synthesis tools don't care for the
sensitivity list and "generate their depending on the code".


>> Please note that all this depends on your synthesis tool and the target
>> library.

>
> [OT] This is indeed very unfortunate. When we will have a common
> agreement by synthesis tool vendors on 'how a synthesis tool should
> behave'.


It depends on the target library, because it has to include flipflops
with async. set and reset. An for these flipflops in the synthesis model
there must be a specification what to do is set and reset are activated
together. (This will in most cases not happen, but the synthesis tool
has to be aware of it.)

And then it depends on the synthesis tool, how it solves the given
problem. It is not some kind of "incompatibility" but more a problem of
choosing one solution.

Ralf
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
latch inferrence in clocked process vu VHDL 3 08-14-2006 12:38 PM
The following signals are missing in the process sensitivity list antonio bergnoli VHDL 5 12-18-2005 08:16 PM
Generating combination signal from within clocked clocked block Valentin Tihomirov VHDL 3 10-28-2003 08:56 AM
custom types in process sensitivity list Roger Dahl VHDL 10 10-03-2003 09:03 PM
Are all the signals read in the process should appear in the sensitivity list of the process? walala VHDL 3 09-09-2003 07:47 AM



Advertisments