signals in sensitiv list... and reset

R

Rick North

Hi all,

I have been away from the vhdl design for a while and when I got back
and read through some code I found some things that was new for me.

1.) In a process sensitive list I usually have a clock and a reset
making it synchronous or signals to do some combinatorial stuff. But
now I see that the two versions are being mixed.

process (clk, reset, switch)
begin
if rising_edge(clk) then
a_delay <= b or c;

if switch = "00" then
output <= "010" & a_delay;
elsif switch = "01" then
output <= "011" & a_delay;
elsif switch = "10" then
output <= "111" & a_delay or d;
elsif switch = "11" then
output <= "101" & a_delay;
end if;
end if;
end process;

As I see it this would place a combinatorial cloud on the output flip-
flop a_delay with an or gate at its input. Is there any advantage to
write this in a single process?

2.) is there any benefit of writing a synchronous reset as follows?
....
if rising_edge(clk) then
....
a <= b;
c <= d;
etc....

if reset = '1' then
a <= '0';
c <= '1';
end if;
end if;
.....

instead of

if rising_edge(clk) then
if reset = '1' then
a <= '0';
c <= '1';
else
....
a <= b;
c <= d;
etc....
end if;
end if;


What do you think?

Best regards,
Rick
 
K

KJ

Hi all,

I have been away from the vhdl design for a while and when I got back
and read through some code I found some things that was new for me.

1.) In a process sensitive list I usually have a clock and a reset
making it synchronous or signals to do some combinatorial stuff. But
now I see that the two versions are being mixed.

process (clk, reset, switch)
begin
   if rising_edge(clk) then
     a_delay <= b or c;

      if switch = "00" then
         output <= "010" & a_delay;
     elsif switch = "01" then
         output <= "011" & a_delay;
     elsif switch = "10" then
         output <= "111" & a_delay or d;
     elsif switch = "11" then
         output <= "101" & a_delay;
     end if;
 end if;
end process;

As I see it this would place a combinatorial cloud on the output flip-
flop a_delay with an or gate at its input.

I'm not sure what 'cloud' you're seeing but what I see is a strictly
synchronous process that will take some slight teeny bit longer to
simulate because of the extraneous signals in the sensitivity list.
In this case, the process 'wakes up' when clk, switch or reset
changes, BUT the outermost 'if rising_edge(clk) then...' will inhibit
any of the code from executing unless the rising edge of clk has
occurred, thus it is a strictly synchronous process and will
synthesize as such (no async reset, no 'combinatorial cloud').

Is there any advantage to
write this in a single process?

It is one process.
2.) is there any benefit of writing a synchronous reset as follows?
...
if rising_edge(clk) then
    ....
    a <= b;
    c  <= d;
    etc....

    if reset = '1' then
       a <= '0';
       c <= '1';
    end if;
end if;
....

instead of

if rising_edge(clk) then
    if reset = '1' then
       a <= '0';
       c <= '1';
    else
       ....
       a <= b;
       c  <= d;
       etc....
    end if;
end if;

They are both functionally equivalent, they will both synthesize to
the same thing so it's simply a matter of appearances then as to which
you think is 'better' and whether you think there is any benefit.
What do you think?
Personally, I prefer the following form
if reset = '1' then
....
else
....
end if;
simply because I hate wading through a long process trying to decipher
the logic only to find that it is all moot because there is an 'if
The_Sky_Is_Falling = '1' statement at the end. Reset logic tends to
usually be short and sweet, one line per signal whereas the 'else'
portion can get long and windy. But again, it's not a functional
anything, strictly a beauty contest as to the form.

KJ
 
A

Andy

They are both functionally equivalent, they will both synthesize to
the same thing so it's simply a matter of appearances then as to which
you think is 'better' and whether you think there is any benefit.

The two forms are not necessarily equivalent. In the first form, if a
register is not reset, its value is preserved with a feedback mux
while reset is active. In the second form, if a register is not reset,
it functions normally. Synplify will warn you if it uses a feedback
mux with an async reset, but I don't know if it does so for
synchronous resets.

I use asynchronous resets for initialization, so I use the first form
most of the time, to get the warnings indicating unreset registers. If
I intentionally need to not reset some things in a process (like
distributed ram array), then I use the second form, which also reminds
me to double check the completeness of the reset assignments.

Andy
 
J

jacko

Hi all,

I have been away from the vhdl design for a while and when I got back
and read through some code I found some things that was new for me.

1.) In a process sensitive list I usually have a clock and a reset
making it synchronous or signals to do some combinatorial stuff. But
now I see that the two versions are being mixed.

process (clk, reset, switch)
begin
   if rising_edge(clk) then
     a_delay <= b or c;

      if switch = "00" then
         output <= "010" & a_delay;
     elsif switch = "01" then
         output <= "011" & a_delay;
     elsif switch = "10" then
         output <= "111" & a_delay or d;
     elsif switch = "11" then
         output <= "101" & a_delay;
     end if;
 end if;
end process;

As I see it this would place a combinatorial cloud on the output flip-
flop a_delay with an or gate at its input. Is there any advantage to
write this in a single process?

2.) is there any benefit of writing a synchronous reset as follows?
...
if rising_edge(clk) then
    ....
    a <= b;
    c  <= d;
    etc....

    if reset = '1' then
       a <= '0';
       c <= '1';
    end if;
end if;
....

instead of

if rising_edge(clk) then
    if reset = '1' then
       a <= '0';
       c <= '1';
    else
       ....
       a <= b;
       c  <= d;
       etc....
    end if;
end if;

What do you think?

Best regards,
Rick

if reset = '1' in the first example causes parrallel assignment. It
may have synthesys problem.
 
J

jacko

k




You're mistaken, there will be no parallel assignment or synthesis
problem.

KJ

if rising_edge(clk) then
....
a <= b; --assignment 1
c <= d;
etc....


if reset = '1' then
a <= '0'; --assignment 2
c <= '1';
end if;
end if;


a <= b and/or ('0' and reset)_extended;
c <= d and/or ('1' and reset)_extended;

the assignments are multiple when reset = '1' on risign_edge(clk) am I
to infer that the assignment 1 is not performed on rising_edge(clk)?
That's not what the code says. The systhesis of the or logic would be
dependant on implementation technology and so be ambiguous.

cheers
jacko
 
K

KJ

if rising_edge(clk) then
    ....
    a <= b;  --assignment 1
    c  <= d;
    etc....

    if reset = '1' then
       a <= '0'; --assignment 2
       c <= '1';
    end if;
end if;

a <= b and/or ('0' and reset)_extended;
c <= d and/or ('1' and reset)_extended;

the assignments are multiple when reset = '1' on risign_edge(clk) am I
to infer that the assignment 1 is not performed on rising_edge(clk)?

If you'd look at your own code, the "if reset = '1' then" is inside
the "if rising_edge(clk) then", this is one form for a synchronous
reset. If there is not clock, then reset is ignored...just as you
wrote it.

Then take a look at how VHDL does things and realize that if there are
multiple assignments to a signal *inside a process* that the last
assignment takes precedence. This is not creating multiples of
anything...any synthesis tool can handle this.
That's not what the code says. The systhesis of the or logic would be
dependant on implementation technology and so be ambiguous.
Perhaps you should step back and actually try to synthesize this
before you post.

I'm assuming that these statements that you listed...
a <= b and/or ('0' and reset)_extended;
c <= d and/or ('1' and reset)_extended;

are just nonsense, and the only 'code' we're talking about is the
process.

There is nothing technology dependent or ambiguous in the code for the
process.

KJ
 
J

jacko

If you'd look at your own code, the "if reset = '1' then" is inside
the "if rising_edge(clk) then", this is one form for a synchronous
reset.  If there is not clock, then reset is ignored...just as you
wrote it.

cut and paste it with edits.
Then take a look at how VHDL does things and realize that if there are
multiple assignments to a signal *inside a process* that the last
assignment takes precedence.  This is not creating multiples of
anything...any synthesis tool can handle this.

Synthesis is sequential emulation of parallel.
Perhaps you should step back and actually try to synthesize this
before you post.

Yes and organized by cut and paste to get nice read shame about the
error introduced by just moving some parallel assignment statements
about.
I'm assuming that these statements that you listed...
a <= b and/or ('0' and reset)_extended;
c <= d and/or ('1' and reset)_extended;

are just nonsense, and the only 'code' we're talking about is the
process.

No I was wondering how a dual parallel assignment was performed.
There is nothing technology dependent or ambiguous in the code for the
process.

Until the VHDL for <= is called serial overidden parallel assignment
statement, I will not use the two assignment infered form.

cheers
jacko
 
R

rickman

The two forms are not necessarily equivalent. In the first form, if a
register is not reset, its value is preserved with a feedback mux
while reset is active. In the second form, if a register is not reset,
it functions normally. Synplify will warn you if it uses a feedback
mux with an async reset, but I don't know if it does so for
synchronous resets.

I disagree. Both forms are identical. Neither generates an async
reset, both create a sync reset and the rest of the time cause the
output of the register to be defined by the non-reset logic.

I use asynchronous resets for initialization, so I use the first form
most of the time, to get the warnings indicating unreset registers. If
I intentionally need to not reset some things in a process (like
distributed ram array), then I use the second form, which also reminds
me to double check the completeness of the reset assignments.

I also use async resets for FPGA logic since they need to be
initialized at power up. I use neither of the above forms, I use one
that actually creates an async reset.

if reset = '1' then
a <= '0';
c <= '1';
elsif rising_edge(clk) then
....
a <= b;
c <= d;
etc....
end if;

By putting the reset test inside the rising_edge if, it is a sync
reset, not async.

Rick
 
R

rickman

if rising_edge(clk) then
....
a <= b; --assignment 1
c <= d;
etc....

if reset = '1' then
a <= '0'; --assignment 2
c <= '1';
end if;
end if;

a <= b and/or ('0' and reset)_extended;
c <= d and/or ('1' and reset)_extended;

the assignments are multiple when reset = '1' on risign_edge(clk) am I
to infer that the assignment 1 is not performed on rising_edge(clk)?
That's not what the code says. The systhesis of the or logic would be
dependant on implementation technology and so be ambiguous.

This is not a multiple assignment. You need to refresh yourself on
how processes work. The <= is an assignment, but it is pending the
suspension of the process. Or another way to look at it is to say the
assignment is made at the present time plus one delta delay.

Otherwise, the statements inside a process are executed sequentially.
So if you first execute a <= b; a pending assignment is made to happen
at "now" plus delta. When a <= '0'; is executed the first assignment
is replaced with the second. When the process exits at the end
process; statement and all other operations pending the current time
the assignment to a can be run and it assumes the appropriate value.

This is done all the time... well by some of us. It is not uncommon
for a complex piece of logic to not be fully specified. Rather than
to type a <= '0'; into a dozen branches of if statement to complement
the one where a is updated, you can put the assignment of a <= '0';
ahead of the first if and it will be the default when no other
assignment to a is made inside the conditionals. This mostly happens
when multiple signals are assigned values in a complex if or case
statements where the other assignments are sparse.

Rick
 
J

jacko

I can see the potential advantages in smaller code, but it increases
size and reduces speed. I tried it. Tis must be due to insertion of a
mux baed of conditions, some of which does reduce, but not all of it.
Seperating the conlicting state so there is no conflict, never has to
introduce a mux, just an or gate.

cheers
jacko
 
K

KJ

I can see the potential advantages in smaller code, but it increases
size and reduces speed.

No it doesn't increase size or reduce speed. Both forms produce the
exact same thing.
I tried it. Tis must be due to insertion of a
mux baed of conditions, some of which does reduce, but not all of it.
Seperating the conlicting state so there is no conflict, never has to
introduce a mux, just an or gate.

Or more likely you made a mistake and implemented different
functionality. Take the code shown below (which implements both
flavors of synchronous reset, run it through whatever synthesis tool
you'd like and report back on any differences you find in the logic
implementation. Here's a hint: there won't be any. The pre-route and
post-route view of the logic will be identical.

Run the source code through a simulator if you'd like and display the
waveforms and once again you'll see that the two forms produce the
exact same output even all the way down to the simulation delta.

The two different forms are functionally identical and will produce
exactly the same timing. Function and performance are the same...end
of story.

KJ

---- Start of code
library ieee;
use ieee.std_logic_1164.all;

entity Foo is port(
clk, reset: in std_ulogic;
b1, d1, b2, d2: in std_ulogic;
a1, c1, a2, c2: out std_ulogic);
end Foo;

architecture RTL of foo is
begin
------------
-- Method #1
------------
process(clk)
begin
if rising_edge(clk) then
a1 <= b1;
c1 <= d1;
if reset = '1' then
a1 <= '0';
c1 <= '1';
end if;
end if;
end process;

------------
-- Method #2
------------
process(clk)
begin
if rising_edge(clk) then
if reset = '1' then
a2 <= '0';
c2 <= '1';
else
a2 <= b2;
c2 <= d2;
end if;
end if;
end process;
end RTL;
---- End of code
 
J

jacko

Take nibz12.vhd from http://nibz.googlecode.com and eliminate the
enumeration state indqq. This is to prevent post increment on register
assign. According to you the fact that post-increment code occurs
before register assignment code, register assignment should overide,
and the state indqq would not be required.

I have tried it, it makes it larger and slower! A real example of
using or avoiding 'double' assignment.

cheers
jacko

p.s. wouldn't consider doing a pointless simple test as reduction of
logic form just too obvoius to any silicon compilier.
 
J

jacko

This does not change the fact that I think it should have reduced it
to a 34 state hot one state machine. Writing it as such would
seriously limit maintainability upon instruction set expansion. And
such a design would not meet size requirements, due to having to place
instruction decode in sequential not combinational and the extra
pipeline register introduced.

cheers
jacko
 
R

rickman

Take nibz12.vhd fromhttp://nibz.googlecode.comand eliminate the
enumeration state indqq. This is to prevent post increment on register
assign. According to you the fact that post-increment code occurs
before register assignment code, register assignment should overide,
and the state indqq would not be required.

I have tried it, it makes it larger and slower! A real example of
using or avoiding 'double' assignment.

cheers
jacko

p.s. wouldn't consider doing a pointless simple test as reduction of
logic form just too obvoius to any silicon compilier.


From your response, I can only surmise that you are relatively new to
HDL coding. I can assure you that the two forms, if coded correctly,
are identical in meaning and unless there is a bug in the synthesis
tool, will produce identical results.

To understand that the two forms are identical, you do need to
understand how processes operate.

Rick
 
A

Andy

I disagree. Both forms are identical. Neither generates an async
reset, both create a sync reset and the rest of the time cause the
output of the register to be defined by the non-reset logic.


I also use async resets for FPGA logic since they need to be
initialized at power up. I use neither of the above forms, I use one
that actually creates an async reset.

if reset = '1' then
a <= '0';
c <= '1';
elsif rising_edge(clk) then
....
a <= b;
c <= d;
etc....
end if;

By putting the reset test inside the rising_edge if, it is a sync
reset, not async.

Rick

I did not state my case clearly. If in the first style (syncrhonous
reset with 'else'), "etc..." is expanded to include assignments to
other signals/variables, then those assignments don't happen when
reset is active (the 'else' won't let them). To mimic this behavior,
the synthesis tool will insert a feedback mux or use a clock enabled
register with (not reset) as the enable.

Such is not the case with the reset clause at the bottom of the
clocked section. Regardless of whether reset is active or not, the non-
reset clocked assignments happen. No feedback mux or clock enable is
needed to mimic this behavior.

Similarly, for asynchronous resets there are two analogous styles:

if reset = '1' then
do_resets;
elsif rising_edge(clk) then
do_clocked_assignments;
end if;

and...

if rising_edge(clk) then
do_clocked_assignments;
end if;
if reset = '1' then
do_resets;
end if;

In the first example, if do_clocked_assignments assigns registers that
are not reset in do_resets, then the synthesis tool will add a
feedback mux or clock enable, but now it is driven by an asynchronous
reset signal (very bad!).

In the second example, if do_clocked_assignments assigns additional
registers they still get assigned even while reset is active, so there
is no need for a feedback mux or clock enable.

Andy
 
J

jacko

From your response, I can only surmise that you are relatively new to
HDL coding.  I can assure you that the two forms, if coded correctly,
are identical in meaning and unless there is a bug in the synthesis
tool, will produce identical results.

To understand that the two forms are identical, you do need to
understand how processes operate.

Rick

May be the increase in one hot from 4 to 5 states does the extra gain.
Yes it is a 'mild bug' for the full infered state machine NOT to be
rendered. It would be obvious that all enummerations were assigned
from the instruction decode process, and direct decode of the
instruction register was possible implying 17 states producted by
(fetch, execute). Then there should be no difference.

There is a difference.

cheers
jacko
 
R

rickman

May be the increase in one hot from 4 to 5 states does the extra gain.
Yes it is a 'mild bug' for the full infered state machine NOT to be
rendered. It would be obvious that all enummerations were assigned
from the instruction decode process, and direct decode of the
instruction register was possible implying 17 states producted by
(fetch, execute). Then there should be no difference.

There is a difference.

That's fine. But just be sure to understand that the "difference" is
not due to the coding styles in the context of the language. The
"difference" is due to some combination of your overall code, the tool
vendor and the particular version of your tools. It is very likely if
you change any of these even a small amount and your results will
change too. This reduction of resource usage is not a portable
result.

Rick
 
J

jacko

That's fine.  But just be sure to understand that the "difference" is
not due to the coding styles in the context of the language.  The
"difference" is due to some combination of your overall code, the tool
vendor and the particular version of your tools.  It is very likely if
you change any of these even a small amount and your results will
change too.  This reduction of resource usage is not a portable
result.

Rick- Hide quoted text -

- Show quoted text -

Not portable, but the code should render in generic vhdl. I think the
optimization is possibly due to a one hot register enable effect. I
leave it in for prosperity and the editability. Enumeration is the
king of don't cares.

cheers
jacko
 
R

rickman

Not portable, but the code should render in generic vhdl. I think the
optimization is possibly due to a one hot register enable effect. I
leave it in for prosperity and the editability. Enumeration is the
king of don't cares.

I'm not talking about your application. I am talking about your
understanding of the HDL. When I started out with VHDL I learned a
lot by doing and finding out what worked. Turns out that was a very
bad way to learn. The tools I was using were pretty much crap
(especially compared to the tools in use now) and they often would
allow things that were not actually valid code or that was certainly
not portable, and without warning!

Then there were things that did not work that should have.

There were also things I "learned" to do that were about quirks in the
tools that should have been unnecessary. These were the most trouble
to unlearn as not only were they not required by other tools, but
could actually produce poor results.

There is nothing wrong with coding either of the two ways you
describe. The issue is "learning" that one way is better than the
other for synthesis. This is what I call a "superstition". It may
seem to be valid today, but next week with another tool or another
version of the same tool or with a small change in the code, that
difference will vanish like a ghost on the morning after Halloween.

Just don't fool yourself that tools are constant. They ebb and flow
like the tide. It is best to learn what the language is about, not
the tools.

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

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,535
Members
45,008
Latest member
obedient dusk

Latest Threads

Top