IEEE 1076.6-2004 support, understanding the examples

Discussion in 'VHDL' started by Guenter.Bartsch@googlemail.com, Jan 18, 2011.

  1. Guest

    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
     
    , Jan 18, 2011
    #1
    1. Advertising

  2. backhus Guest

    On 18 Jan., 18:49, ""
    <> wrote:
    > 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
     
    backhus, Jan 19, 2011
    #2
    1. Advertising

  3. Guest

    Eilert,

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

    On Jan 19, 3:31 am, backhus <> wrote:
    > 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
     
    , Jan 19, 2011
    #3
  4. rickman Guest

    On Jan 18, 12:49 pm, ""
    <> wrote:
    > 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
     
    rickman, Jan 19, 2011
    #4
  5. Guest

    Rick,

    On Jan 19, 9:06 pm, rickman <> wrote:
    >
    > > 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;

    >
    > 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
     
    , Jan 19, 2011
    #5
  6. backhus Guest

    On 19 Jan., 21:49, ""
    <> wrote:
    > Rick,
    >
    > On Jan 19, 9:06 pm, rickman <> wrote:
    >
    >
    >
    > > > 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;

    >
    > > 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


    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
     
    backhus, Jan 20, 2011
    #6
  7. rickman Guest

    On Jan 19, 3:49 pm, ""
    <> wrote:
    > Rick,
    >
    > On Jan 19, 9:06 pm, rickman <> wrote:
    >
    > > > 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;

    >
    > > 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:)


    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.


    > > 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


    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.


    > >  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,



    I hope you understand this now.

    Rick
     
    rickman, Jan 20, 2011
    #7
  8. rickman Guest

    On Jan 20, 6:42 am, backhus <> wrote:
    > On 19 Jan., 21:49, ""
    >
    > <> wrote:
    > > Rick,

    >
    > > On Jan 19, 9:06 pm, rickman <> wrote:

    >
    > > > > 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;

    >
    > > > 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

    >
    > 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
     
    rickman, Jan 20, 2011
    #8
  9. Guest

    Rick,

    On Jan 20, 11:36 am, rickman <> wrote:

    > > > > 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;

    >
    > > > 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:)

    >
    > 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
     
    , Jan 20, 2011
    #9
  10. Andy Guest

    >
    > 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
     
    Andy, Jan 20, 2011
    #10
  11. rickman Guest

    On Jan 20, 2:37 pm, Andy <> wrote:
    > > 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


    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
     
    rickman, Jan 21, 2011
    #11
  12. rickman Guest

    On Jan 20, 1:13 pm, ""
    <> wrote:
    > Rick,
    >
    > On Jan 20, 11:36 am, rickman <> wrote:
    >
    >
    >
    > > > > > 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;

    >
    > > > > 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:)

    >
    > > 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


    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
     
    rickman, Jan 21, 2011
    #12
  13. JimLewis Guest

    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.
     
    JimLewis, Feb 15, 2011
    #13
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Richard Auletta
    Replies:
    0
    Views:
    506
    Richard Auletta
    Dec 18, 2003
  2. Just an Illusion

    About 1076.6-2004

    Just an Illusion, Jun 8, 2004, in forum: VHDL
    Replies:
    0
    Views:
    552
    Just an Illusion
    Jun 8, 2004
  3. cp

    IEEE 1076.6 compliance

    cp, Aug 16, 2004, in forum: VHDL
    Replies:
    4
    Views:
    1,269
    Eric Delage
    Aug 20, 2004
  4. Kholdoun TORKI

    IEEE ICM'2004 Extended Call For Papers

    Kholdoun TORKI, Aug 17, 2004, in forum: VHDL
    Replies:
    0
    Views:
    459
    Kholdoun TORKI
    Aug 17, 2004
  5. Replies:
    0
    Views:
    691
Loading...

Share This Page