IEEE 1076.6-2004 support, understanding the examples

G

Guenter.Bartsch

Hi everyone,

I am currently working on VHDL RTL synthesis support for zamiacad
(http://zamia.org) and stumbled upon the 2004 revision of the 1076.6
std. Until recently I wasn't aware this revision existed and now I am
slowly making my way through the examples given in the standard. So
far, I came across two questions (more to come, I guess ;)):

(1) what is the general experience, do the proprietary tools in the
market support the 2004 revision? parts of it, the whole thing? I just
tried a few of the examples in Altera's Quartus II and none of them
worked so I was beginning to wonder whether this might be a failed
standard so far (although I must say I do like some of the ideas they
outline in there). Can anybody recommend a tool that is known to have
good 2004 support?

(2) I do have trouble understanding some of the examples in there -
Example 6 on page 11 in particular. I have come up with my own
algorithm how to implement some of the synthesis rules so far and it
seems to work on most examples _including_ example 6 which is supposed
to be illegal. Basically what i am doing is compute logic expressions
that act as conditions under which certain assignments happen. In
example 6 we have:

if rising_edge(clock) or reset = '1' then
if reset = '1' then
Q <= '0' ; -- assignment 1
else
Q <= D; -- assignment 2
end if;
end if;

so assignment 1 happens when

(clock' || reset) & reset

is true which can be simplified to just

reset

so this is an async assignment of '0' to Q if reset='1'.

for assignment 2 i get

(clk' || reset) & ^reset = clk' & ^reset

which is a sync assignment under the condition that reset='0' (which
could actually be optimized out later since when reset='1' the async
assignment kicks in). so this could be synthesized as a flipflop that
has an asynchroneous reset, I guess? anyone see where I go wrong and
why this example should be illegal?

thanks and best regards,

guenter
 
B

backhus

Hi everyone,

I am currently working on VHDL RTL synthesis support for zamiacad
(http://zamia.org) and stumbled upon the 2004 revision of the 1076.6
std. Until recently I wasn't aware this revision existed and now I am
slowly making my way through the examples given in the standard. So
far, I came across two questions (more to come, I guess ;)):

(1) what is the general experience, do the proprietary tools in the
market support the 2004 revision? parts of it, the whole thing? I just
tried a few of the examples in Altera's Quartus II and none of them
worked so I was beginning to wonder whether this might be a failed
standard so far (although I must say I do like some of the ideas they
outline in there). Can anybody recommend a tool that is known to have
good 2004 support?

(2) I do have trouble understanding some of the examples in there -
Example 6 on page 11 in particular. I have come up with my own
algorithm how to implement some of the synthesis rules so far and it
seems to work on most examples _including_ example 6 which is supposed
to be illegal. Basically what i am doing is compute logic expressions
that act as conditions under which certain assignments happen. In
example 6 we have:

if rising_edge(clock) or reset = '1' then
  if reset = '1' then
    Q <= '0' ; -- assignment 1
  else
    Q <= D; -- assignment 2
  end if;
end if;

so assignment 1 happens when

(clock' || reset) & reset

is true which can be simplified to just

reset

so this is an async assignment of '0' to Q if reset='1'.

for assignment 2 i get

(clk' || reset) & ^reset = clk' & ^reset

which is a sync assignment under the condition that reset='0' (which
could actually be optimized out later since when reset='1' the async
assignment kicks in). so this could be synthesized as a flipflop that
has an asynchroneous reset, I guess? anyone see where I go wrong and
why this example should be illegal?

thanks and best regards,

   guenter

Hi Guenter,
this is the synthesis part of the original standard.
It refers to the 2002 release of the full VHDL standard (see top of
page iii, which is page 4 in the pdf)
That also explains, why it is two years "late" compared to the full
standard.
Tool vendors normally only refer to the original standard, not the
derived substandards.
So you probably won't find a tool that explicitly supports some 2004
release.

I found the paper here:
http://www.ece.gatech.edu/academic/courses/spring2007/ece4170/DesignDocumentation/IEEE_1076 6.pdf


About the example:
the violated rule (a) is mentioned.
To become a valid synthesizable description I think the "else" should
be replaced by
"elsif rising_edge(clk) then".

Anyway, the examples in the standard are kind of weird, in order to
reflect the synthesis rules.
They are not intended to bee good practice examples.

Your musing about the code incorporates human understanding, but is
not based on the rules given on page nine.

See:
<sync_assignment>. An assignment to a signal or variable that is
controlled explicitly by <clock_edge> in
all execution paths.
....
Edge-sensitive storage shall be modeled for a signal or variable
assigned inside a process with sensitivity list
when all of the following apply:
a) The signal or variable has a <sync_assignment>.
b) There is no execution path in which the value update from a
<sync_assignment> overrides the value
update from an <async_assignment> unless the <async_assignment> is an
assignment to itself.
c) It is possible to statically enumerate all execution paths to the
signal or variable assignments.
d) The process sensitivity list includes the clock and any signal
controlling an <async_assignment>.
e) The <clock_edge> is present in the conditions only, and the
<clock_edge> always expresses the
same edge of the same clock signal.
f) For a variable, the value written by a given clock edge is read
during a subsequent clock edge.

Rule a is violated by the example because the first if may be
triggered by a rising edge of the clock signal only,
but the assignment Q<=D is just depending on the state of reset.

On first reading I stepped into the same trap as you did.
The problem is that event triggereing (rising_edge) and state logic
can not be mixed up the way you did.
let me reanalyse the code:
first if: entered on rising clock edge or active reset. (This allows
the tool to proceed reading the code, nothing more, nothing less)
second if: Deciding which of two asynchronous assignments has to be
mate relating to the state of reset. (Tool doesn't know why it is
reading this.)
---
If the tool would remember why it has entered the second if, there may
be the chance that on active reset you also have a rising clock edge.
This would cause a flipflop to be synthesized.
But at anoter time when Reset is active but there's no rising clock
edge, for the same if, just some asynchronous assignment has to be
done, and no Flip Flop will be synthesized.
This is a contradiction the synthesis tool can't resolve.

The mistake you made is that you can not overrule the rising clock
edge with logical optimization of the clock signal. It has to be
treated different.
For this one example your method may work, but when things become more
complicated (e.g. with clockenables and/or mixing of asynchronous and
synchronous reset/presets) it will fail.

Have a nice synthesis
Eilert
 
G

Guenter.Bartsch

Eilert,

first of all thank you for your quick and very detailed answer, you
helped me a lot!

this is the synthesis part of the original standard.
It refers to the 2002 release of the full VHDL standard (see top of
page iii, which is page 4 in the pdf)
That also explains, why it is two years "late" compared to the full
standard.
Tool vendors normally only refer to the original standard, not the
derived substandards.
So you probably won't find a tool that explicitly supports some 2004
release.

I guess you're right :) - at least the big vendors hardly ever mention
the 1076.6 standard (no matter which revision). for simulation, that
is completely fine, but I do wonder why they do not claim at least
1076.6-1999 conformance for their synthesis tools.

Anyway, my question was more about what is working in practice - so
what user's experiences are in the real world when they try to model
hardware the way the 2004 revision describes it - e.g. does design
compiler handle multiple wait statements in one process? sync
assignments controlled by "complicated boolean expressions"?

About the example:
the violated rule (a) is mentioned.
To become a valid synthesizable description I think the "else" should
be replaced by
"elsif rising_edge(clk) then".

I was kinda wondering why they keep repeating parts of the conditional
expressions in the other examples ;) that explains a lot - however, I
have no clue why they're specifying this the way they do - maybe I'm
viewing this from a completely wrong perspective, but it seems very
complicated and unelegant to me...
See:
<sync_assignment>. An assignment to a signal or variable that is
controlled explicitly by <clock_edge> in
all execution paths.
...
Edge-sensitive storage shall be modeled for a signal or variable
assigned inside a process with sensitivity list
when all of the following apply:
a) The signal or variable has a <sync_assignment>.
b) There is no execution path in which the value update from a
<sync_assignment> overrides the value
update from an <async_assignment> unless the <async_assignment> is an
assignment to itself.
c) It is possible to statically enumerate all execution paths to the
signal or variable assignments.
d) The process sensitivity list includes the clock and any signal
controlling an <async_assignment>.
e) The <clock_edge> is present in the conditions only, and the
<clock_edge> always expresses the
same edge of the same clock signal.
f) For a variable, the value written by a given clock edge is read
during a subsequent clock edge.

Rule a is violated by the example because the first if may be
triggered by a rising edge of the clock signal only,
but the assignment Q<=D is just depending on the state of reset.

obviously I am reading the rules wrong in here - I thought rule a) is
met since there is a sync assignment (Q <= D since the two if-
statements around it result in if rising_edge(clk)) - there is, of
course, also an async assignment (Q<='0') but rule a) doesn't specify
that there have to be _only_ sync assignments.

On first reading I stepped into the same trap as you did.
The problem is that event triggereing (rising_edge) and state logic
can not be mixed up the way you did.
let me reanalyse the code:
first if: entered on rising clock edge or active reset. (This allows
the tool to proceed reading the code, nothing more, nothing less)
second if: Deciding which of two asynchronous assignments has to be
mate relating to the state of reset. (Tool doesn't know why it is
reading this.)

I really do not understand when and why the tool is supposed to forget
about outer if-conditions - is that specified anywhere in the
standard?

But you're right, the algorithm I am thinking about does collect if-
conditions, ands them together (or and-nots them together in case of
else-branches) and then analyses them when it reaches an assignment.
so in this case i'd end up with

(rising_edge(clk) or reset='1') and not (reset='1')

which I could then simplify into rising_edge(clk)

---
If the tool would remember why it has entered the second if, there may
be the chance that on active reset you also have a rising clock edge.
This would cause a flipflop to be synthesized.
But at anoter time when Reset is active but there's no rising clock
edge, for the same if, just some asynchronous assignment has to be
done, and no Flip Flop will be synthesized.
This is a contradiction the synthesis tool can't resolve.

ok - the part I obviously do not understand is the one where
conditions from outer if-statements get dropped. With the approach I
have in mind this would cleanly synthesize as a flipflop that has an
asynchroneous reset-input, I think.

The mistake you made is that you can not overrule the rising clock
edge with logical optimization of the clock signal. It has to be
treated different.
For this one example your method may work, but when things become more
complicated (e.g. with clockenables and/or mixing of asynchronous and
synchronous reset/presets) it will fail.

can you five an example where my approach would fail? I must confess,
I have only sketched it so far and will need to write it down in a
formal way (I am writing a paper right now ;) ) - my idea was
basically to collect conditions, basically I have an expression engine
which can handle logic equations, arithmetic expressions and you can
also have clock edge specifications in there, all mixed together and
it will apply standard optimizations to those expressions. whenever I
reach an assignment, I look at the current condition I have collected,
optimize it down and check, whether it still contains a clock edge or
not. if it does contain a clock edge, i will use that clock for a
flipflop (which can have additional async inputs, if needed to
synthesize other assignments) clk input, will tell the expression
engine to tread that part of the expression as don't care and optimize
it further down, which i will then use to synthesize synced enable and
data inputs for the flipflop.

I do wonder how much of the standard I cover, where I am not compliant
- I am definitely not "bug-compatible" with my approach since
obviously I can handle designs which I shouldn't be able to handle.
Actually, I could easily live with that - but I am worried about
examples that I should be able according to the standard which my
approach fails to handle.

BTW: in the meantime I have read on. I was very surprised about
6.1.3.3 where they allow multiple clock signals for assignments to the
same signal - I wonder what that would result in when synthesized -
would I need flip flops that have several separate clock inputs in my
target library to support that?

in chapter 6.1.3.4 they model implicit FSMs using multiple wait-
statements in a single process - which I could imagine is pretty
useful (I was always wondering why VHDL doesn't have a syntax for
FSMs) but then again I have trouble really understanding their rules.
What gives me most headaches is the way they use loops and next
statements: from the examples I gather that they

- have at most one outer infinite loop and next-statements immediately
following the wait statements to model the async reset state. the
rules they state are pretty elaborate about the conditions used in the
wait statements having to be the same throughout the process - not
pretty, but makes sense. but i don't see them specify anywhere that
the next statement has to follow the wait statement immediately, nor,
that one can have at most one such infinite loop - so I wonder what
would happen if the user breaks these rules? has next statements in
arbitrary locations or nests infinite loops, possibly mixed with if-
and for-loops, has multiple labels in there, uses next-statements to
jump to any of them? is all that forbidden or is the tool supposed to
handle all that in some way?

- maybe a simpler question: is there a rules which dictates that if
one wants to have wait statements in for-loops, it has to be the first
statement in the loop body? that assumption certainly holds for the
examples they give, yet i cannot find a rule about that

what I am aiming for maybe has become clear already: I'd like to
extend my approach to handle FSM specifications as well - I would
basically treat the examples before 6.1.3.4 as mealy automata that
have at most one state (plus additional async logic) and would like to
extend my approach smoothly to FSM descriptions which then generate
automata with multiple states (basically one per wait-statement).

thanks again for your help, sorry for my far too long post and best
regards,

guenter
 
R

rickman

Hi everyone,

I am currently working on VHDL RTL synthesis support for zamiacad
(http://zamia.org) and stumbled upon the 2004 revision of the 1076.6
std. Until recently I wasn't aware this revision existed and now I am
slowly making my way through the examples given in the standard. So
far, I came across two questions (more to come, I guess ;)):

(1) what is the general experience, do the proprietary tools in the
market support the 2004 revision? parts of it, the whole thing? I just
tried a few of the examples in Altera's Quartus II and none of them
worked so I was beginning to wonder whether this might be a failed
standard so far (although I must say I do like some of the ideas they
outline in there). Can anybody recommend a tool that is known to have
good 2004 support?

(2) I do have trouble understanding some of the examples in there -
Example 6 on page 11 in particular. I have come up with my own
algorithm how to implement some of the synthesis rules so far and it
seems to work on most examples _including_ example 6 which is supposed
to be illegal. Basically what i am doing is compute logic expressions
that act as conditions under which certain assignments happen. In
example 6 we have:

if rising_edge(clock) or reset = '1' then
  if reset = '1' then
    Q <= '0' ; -- assignment 1
  else
    Q <= D; -- assignment 2
  end if;
end if;

so assignment 1 happens when

(clock' || reset) & reset

is true which can be simplified to just

reset

so this is an async assignment of '0' to Q if reset='1'.

for assignment 2 i get

(clk' || reset) & ^reset = clk' & ^reset

which is a sync assignment under the condition that reset='0' (which
could actually be optimized out later since when reset='1' the async
assignment kicks in). so this could be synthesized as a flipflop that
has an asynchroneous reset, I guess? anyone see where I go wrong and
why this example should be illegal?

As Eilert says, you need the risingedge test in the IF statement for
this to be valid. Why? Because the sensitivity list is not the same
as a condition test. The values in the sensitivity list do not need
to be true for the process to run, there only needs to be a change in
the items in the list for the process to run. So your logical
analysis above is flawed.

For example, when the reset is asserted, the process runs and the
reset clause of the IF is executed. When the reset is deasserted the
process runs again and the else clause of the IF is executed, which a
FF will only perform on the rising edge of the clock.

It seems like an inefficiency for a sensitivity clause to allow a
process to run when nothing is supposed to happen, but I assume the
simulation vendors know how to optimize this so it has little impact.
Otherwise I would want to tailor my sensitivity list to only run on
the leading edge of the reset and not all transitions. BTW, if you
assign anything other than a constant value in the reset clause of the
IF, it is no longer a standard DFF with async reset and you must add
those signals to the sensitivity list for it to simulate properly.

Rick
 
G

Guenter.Bartsch

Rick,

As Eilert says, you need the risingedge test in the IF statement for
this to be valid.  Why?  Because the sensitivity list is not the same
as a condition test.  The values in the sensitivity list do not need
to be true for the process to run, there only needs to be a change in
the items in the list for the process to run.  So your logical
analysis above is flawed.

actually the outer if-statement does have the risingedge test, so that
is not the point :eek:)

what puzzles me is that apparently the else-branch of the inner if-
statement needs the risingedge-test again. of course, if one wanted
this example to be completely synchroneous then yes, there needs to be
a risingedge-test in the else-branch (or one could just drop the "or
reset='1'" part from the outer if in the first place... ). all that of
course requires the synthesis tool to remember all nested if-
conditions - if the synthesis tool is to forget the outer if-condition
then yes, it would need to be repeated.
For example, when the reset is asserted, the process runs and the
reset clause of the IF is executed.  When the reset is deasserted the
process runs again and the else clause of the IF is executed, which a
FF will only perform on the rising edge of the clock.

if reset switches to '0' and there is no clk event, the inner if never
gets executed since neither "risingedge(clk)" nor "reset='1'" is true

if reset switches to '0' and clk has a rising edge, the else branch of
the inner if does indeed execute, but that would be a synchroneous
assignment.
 BTW, if you
assign anything other than a constant value in the reset clause of the
IF, it is no longer a standard DFF with async reset

my tool would use a DFF with async reset and set signals in that case
and you must add
those signals to the sensitivity list for it to simulate properly.

agreed :)

thanks for your reply and best regards,

guenter
 
B

backhus

Rick,




actually the outer if-statement does have the risingedge test, so that
is not the point :eek:)

what puzzles me is that apparently the else-branch of the inner if-
statement needs the risingedge-test again. of course, if one wanted
this example to be completely synchroneous then yes, there needs to be
a risingedge-test in the else-branch (or one could just drop the "or
reset='1'" part from the outer if in the first place... ). all that of
course requires the synthesis tool to remember all nested if-
conditions - if the synthesis tool is to forget the outer if-condition
then yes, it would need to be repeated.


if reset switches to '0' and there is no clk event, the inner if never
gets executed since neither "risingedge(clk)" nor "reset='1'" is true

if reset switches to '0' and clk has a rising edge, the else branch of
the inner if does indeed execute, but that would be a synchroneous
assignment.


my tool would use a DFF with async reset and set signals in that case


agreed :)

thanks for your reply and best regards,

   guenter

Hi,
you probably know, but just to clarify for other readers:
Synthesis tools don't care about the sensitivity list of a process.

Guenther asked for an example, so I give it a try:

if rising_edge(clock) or areset = '1' or sreset = '1'then
if reset = '1' then
Q <= '0' ; -- assignment 1
elsif sreset = '1' then
Q <= '0' ; -- assignment 1
else
Q <= D; -- assignment 2
end if;
end if;

So, how do you decide by logic reduction which of these is the
synchronous reset? ;-)

Following rule a) this should work:

if rising_edge(clock) or areset = '1' or sreset = '1'then
if reset = '1' then
Q <= '0' ; -- assignment 1
elsif rising_edge(clock) and sreset = '1' then
Q <= '0' ; -- assignment 1
elsif rising_edge(clock) then
Q <= D; -- assignment 2
end if;
end if;

You also asked why synthesis tool vendors don't mention to comply to
the synthesis standard.
Maybe because they just don't support everything of it.
Sometimes just because the target architecture can't handle all of the
allowed constructs anyway.
Like multiple clocked processes or dual edge Flipflops.

Also, the tool vendors are more concerned about supporting approved
coding styles
and useful extra features (like file I/O for ROM contents) that are
not covered by the syntehsis standard.

I remember the good old WARP compiler for Cypress CPLDs (way back when
in the las millenium).
There you had to follow a strict template for synchronous
descriptions.
All other styles, that work well for other synthesis tools, were
simply rejected.

Tools become better now, but still they are focussed on a special
target architecture, while the VHDL standard has to cover everything.
So, if a synthesis tool understands many or all of the good examples
this is a real progress.

As I said before, the known-bad example looked weird to me.
Even when corrected according to the rules.

The point is, that neither for simulation nor for synthesis the pseudo-
sensitivity-list made with the first if-condition makes sense.
It's just code redundancy, and that can cause errors.

Lets take a look at the everyday synchronous process:

goodsync: process (reset, clock) is
variable Data : std_logic_vector 8 downto 0); -- just an example
begin
if Reset = '1' then -- the asynchronous part starts here
Data <= (others => '0');
elsif rising_edge(clock) then -- the synchronous part starts here
Data <= Input
end if;
Output <= Data; -- Just some renaming, in case Data
has a feedback path (Yes, asynchronous, but theres nothing really
happening here)
end process goodsync;

So, here we have clean separated areas for asynchronous and
synchronous coded stuff, and no repetition.
Its just useles to mention in the code that reset shall be '0' during
the synchronous part. If it's '1' the other branch isn't reached
anyway.

Have a nice synthesis
Eilert
 
R

rickman

Rick,




actually the outer if-statement does have the risingedge test, so that
is not the point :eek:)

You misunderstand. No changes in clock will trigger the process other
than the rising edge, but any transition of the reset=1 expression
will trigger execution of the process. Any transition that does not
result in reset='1' being true will be handled by the else clause and
treated as if it were a rising edge of the clock signal. Try it
yourself in simulation. If you have the D input high at the time the
reset signal goes low, the Q output will be set high as if it had been
clocked!

That behavior is not synthesizable as a DFF.

what puzzles me is that apparently the else-branch of the inner if-
statement needs the risingedge-test again. of course, if one wanted
this example to be completely synchroneous then yes, there needs to be
a risingedge-test in the else-branch (or one could just drop the "or
reset='1'" part from the outer if in the first place... ). all that of
course requires the synthesis tool to remember all nested if-
conditions - if the synthesis tool is to forget the outer if-condition
then yes, it would need to be repeated.

You need to realize that rising_edge(clock) and changes in reset='1'
are not mutually exclusive. So you can enter the process under other
conditions such as the falling edge of reset!

Oddly enough, in Verilog you don't need the rising edge condition on
clock in the IF, but then they require a rising edge condition of
reset in the sensitivity list... I think. I've seen some code that
doesn't use it, but that was in a second rate tutorial.

if reset switches to '0' and there is no clk event, the inner if never
gets executed since neither "risingedge(clk)" nor "reset='1'" is true

This is what you don't get. The sensitivity list is not an IF
statement. It lists the conditions of which ANY CHANGE will cause the
process to be run. Rising_edge is defined so that it only triggers on
the rising edge. But reset=1 changes any time reset changes to or
FROM a 1. So it triggers the process to run on both the leading and
falling edge of reset. That is why they use rising_edge and
falling_edge functions.

if reset switches to '0' and clk has a rising edge, the else branch of
the inner if does indeed execute, but that would be a synchroneous
assignment.

If reset=1 triggered when it was true and not on a change, it would
run the process continually while reset was asserted. Not good for
performance. Also, if there is no change in an expression, it can
have no impact on the value of the assignments. So instead they
trigger on changes.

my tool would use a DFF with async reset and set signals in that case


agreed :)

thanks for your reply and best regards,


I hope you understand this now.

Rick
 
R

rickman

Hi,
you probably know, but just to clarify for other readers:
Synthesis tools don't care about the sensitivity list of a process.

Guenther asked for an example, so I give it a try:

if rising_edge(clock) or areset = '1' or sreset = '1'then
if reset = '1' then
Q <= '0' ; -- assignment 1
elsif sreset = '1' then
Q <= '0' ; -- assignment 1
else
Q <= D; -- assignment 2
end if;
end if;

This is NOT the same as a sensitivity list.... I think. First, an IF
can only be used inside a process and that process will have a
sensitivity list. But assuming you instead implemented this in an
equivalent conditional assignment statement, the assignment would be
triggered to run on ANY change in areset='1' or sreset='1'. So like
Guenter's example, the deassertion of areset or sreset will trigger
the assignment and cause Q to be set to the value of D like a clock
edge.


Rick
 
G

Guenter.Bartsch

Rick,

You misunderstand.  No changes in clock will trigger the process other
than the rising edge, but any transition of the reset=1 expression
will trigger execution of the process.  Any transition that does not
result in reset='1' being true will be handled by the else clause and
treated as if it were a rising edge of the clock signal.  Try it
yourself in simulation.  If you have the D input high at the time the
reset signal goes low, the Q output will be set high as if it had been
clocked!

tried it in ghdl and q stays '0', just as i expected. here is the test
program i tried:

use std.textio.all;

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned."+";
use IEEE.std_logic_unsigned."-";

entity dir_test is

end dir_test;

architecture behaviour of dir_test is

signal clock, reset, d, q : std_logic;

begin

process (clock, reset, d)

begin

if rising_edge(clock) or reset = '1' then
if reset = '1' then
Q <= '0' ; -- assignment 1
else
Q <= D; -- assignment 2
end if;
end if;

end process;

tb: process

function to_string (value : STD_LOGIC) return STRING is
begin
if value = '1' then
return "1";
else
return "0";
end if;
end function to_string;

variable l : line;

begin

clock <= '0'; reset <= '0'; d <= '1';

wait for 10 ns;

write (l, "clock: " & to_string(clock) & ", reset: " &
to_string(reset) & ", q: " & to_string(q));
writeline (output, l);

clock <= '0'; reset <= '1'; d <= '1';

wait for 10 ns;

write (l, "clock: " & to_string(clock) & ", reset: " &
to_string(reset) & ", q: " & to_string(q));
writeline (output, l);

clock <= '0'; reset <= '0'; d <= '1';

wait for 10 ns;

write (l, "clock: " & to_string(clock) & ", reset: " &
to_string(reset) & ", q: " & to_string(q));
writeline (output, l);

wait;

end process;

end behaviour;

output I get:

clock: 0, reset: 0, q: 0
clock: 0, reset: 1, q: 0
clock: 0, reset: 0, q: 0

best regards,

guenter
 
A

Andy

You misunderstand.  No changes in clock will trigger the process other
than the rising edge, but any transition of the reset=1 expression
will trigger execution of the process.  Any transition that does not
result in reset='1' being true will be handled by the else clause and
treated as if it were a rising edge of the clock signal.  Try it
yourself in simulation.  If you have the D input high at the time the
reset signal goes low, the Q output will be set high as if it had been
clocked!

No it won't! The outer "if rising_edge(clock) or reset = '1' then"
statement will prevent any assignment if rising_edge() is false and
reset is '0'.

Don't confuse "triggering a process," and "executing code within that
process" Any event on any signal in the sensitivity list will "trigger
the process," and start execution of the first executable statement.
Whether other code within that process gets executed is dependent upon
BOTH the process being triggered, AND any surrounding conditional
statements.

Andy
 
R

rickman

No it won't! The outer "if rising_edge(clock) or reset = '1' then"
statement will prevent any assignment if rising_edge() is false and
reset is '0'.

Don't confuse "triggering a process," and "executing code within that
process" Any event on any signal in the sensitivity list will "trigger
the process," and start execution of the first executable statement.
Whether other code within that process gets executed is dependent upon
BOTH the process being triggered, AND any surrounding conditional
statements.

Andy

You are absolutely right. Somehow as many times as I read this, I saw
the first IF statement as a process statement.

But I have no idea why anyone would write code that way. The fact
that code is logically correct (meaning it should simulate ok) does
not mean it will synthesize. I think that is the purpose of IEEE
1076.6-2004, to explain the subset of VHDL that will give you what you
want in synthesis. The tool vendors can't create reasonable hardware
from every combination of code that will simulate in the same manner.
They have to pick code templates that they can recognize and match to
hardware.

Rick
 
R

rickman

Rick,




tried it in ghdl and q stays '0', just as i expected. here is the test
program i tried:

use std.textio.all;

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned."+";
use IEEE.std_logic_unsigned."-";

entity dir_test is

end dir_test;

architecture behaviour of dir_test is

signal clock, reset, d, q : std_logic;

begin

  process (clock, reset, d)

  begin

    if rising_edge(clock) or reset = '1' then
      if reset = '1' then
        Q <= '0' ; -- assignment 1
      else
        Q <= D; -- assignment 2
      end if;
    end if;

  end process;

  tb: process

    function to_string (value : STD_LOGIC) return STRING is
    begin
      if value = '1' then
        return "1";
      else
        return "0";
      end if;
    end function to_string;

    variable l  : line;

  begin

    clock <= '0'; reset <= '0'; d <= '1';

    wait for 10 ns;

    write (l, "clock: " & to_string(clock) & ", reset: " &
to_string(reset) & ", q: " & to_string(q));
    writeline (output, l);

    clock <= '0'; reset <= '1'; d <= '1';

    wait for 10 ns;

    write (l, "clock: " & to_string(clock) & ", reset: " &
to_string(reset) & ", q: " & to_string(q));
    writeline (output, l);

    clock <= '0'; reset <= '0'; d <= '1';

    wait for 10 ns;

    write (l, "clock: " & to_string(clock) & ", reset: " &
to_string(reset) & ", q: " & to_string(q));
    writeline (output, l);

    wait;

  end process;

end behaviour;

output I get:

clock: 0, reset: 0, q: 0
clock: 0, reset: 1, q: 0
clock: 0, reset: 0, q: 0

best regards,

   guenter

I was misreading the code in your original post. I thought the first
IF was a process statement... I've been using the same template too
long I guess, I'm starting to see it whether it's there or not.

So this code should simulate the same as a D FF with async reset. But
what does that have to do with synthesis? See my reply to Andy.

Rick
 
J

JimLewis

Hi Guenter,
A little history. 1076.6-1999 was a template based standard.
For flip-flops there was a limited number of templates that
a tool was required to support.

When 1076.6-2004 was started we had to decide whether to add
a limited number of additional templates - which would be
tedious and require additional updates from time to time,
or change to an algorithmic based description of the code.
1076.6-2004 chose to develop an algorithmic based description
of the code.

Note, I think it is ok if you support a superset of the
standard as I think the language of the standard is,
a tool shall support at least .... So a superset of the
standard is still be compliant with the standard.

I think the rules that were capture were thought of to be
a line by line analysis. So looking at example 6 on page 11,
the second assignment fails to be understood as a
synchronous assignment from the perspective of the line
by line analysis.

OTOH, if you are building a graph based data structure of the
code (as your webpage suggests), then your analysis will have
a deeper understanding of the code. I would say this is a
good thing. I suspect the rules still apply, however, you
have a deeper understanding of what a synchronous and
asynchronous assignment are - and as a result, in your
world, example 6 on page 11 becomes legal.

In my limited re-read of the standard text, it looks like
your analysis is also a correct interpretation of the
standard - as opposed to a superset.

As I said, I am fairly certain the language committee
(I was on the committee - it is just a long time ago)
considered the analysis to be a line by line analysis
and concluded, from that perspective, that example 6
is illegal. However, in the definitions, I do not see
anything that makes a graph based analysis illegal and
as a result my guess is that your conclusion is also valid
and that from that perspective the example is legal.

Can anybody recommend a tool that is known to have good
2004 support?
When 1076.6-2004 was published, we did the normal rounds
of papers to publicize it. However, it has gained little
traction in the tool market. Vendors mostly have seemed to
ignore its existence. Part of this is because of how
vendors work - if there are no user requests for support,
they don't implement it. Part of this is because how
users work - hey it is a standard, the vendors will support
it eventually right?

If I had to guess, I expect Synplify to have some 2004 support.

TO ALL: if you see value in 1076.6-2004, then let your
vendors know that you want it supported.

If you want something different or something additional, the
committee needs to be reformed and the standard needs
to be worked on. I can help you with this by giving
guidance (I know the process well), however, I cannot do
the work as I am already a over committed doing 1076 standard
work. If you want my help, contact me directly via email as
I don't read the news groups frequently enough.

At this point 1076.6-2004 is a withdrawn standard - which
means that anything is possible. One thing the standard
touches on that we really need is a standard set of
statemachine attributes/pragmas and memory modeling (RTL)
attributes/pragmas.

Best,
Jim

BTW, compliance claims to an IEEE standard are an interesting
thing as there is no one who is in the role of confirming
compliance.
 

Ask a Question

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

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

Ask a Question

Members online

Forum statistics

Threads
473,772
Messages
2,569,593
Members
45,111
Latest member
KetoBurn
Top