Conditional signal assignment or process statement

Discussion in 'VHDL' started by devas, Apr 12, 2011.

  1. devas

    devas Guest

    Hi Gurus,

    What is your opinion for coding combinational logic (multiplexer) in
    VHDL. Using a conditional signal assignment or using a process? What are
    the pro's and con's for both?

    I can imagine that for simulation performance a process is efficienter
    as it will only be reached when one of the signals on the sens. list
    changes. A con could be the danger of an incomplete sens. list.

    I would like to know your opinion and what your are using.


    devas, Apr 12, 2011
    1. Advertisements

  2. devas

    backhus Guest

    Hi Devas,
    with the upcoming of VHDL-2008 and the
    feature, the differences in performance and danger of simulation
    faults should be rendered to almost neglectable.
    Also with VHDL-2008 the
    constructs can be used inside processes.
    So, even the coding style difference is mostly evened out.

    What's left is merely a question of personally prefered coding style.

    One might argue, that not all synthesis tools support this yet, but
    time flies and before long this won't be a problem anymore.
    My personal choice is to have as few concurrent code lines in my
    architecture as possible, and put every functional part in processes.
    Sometimes specific assignments to output ports are necessary, but
    that's just one-liners.

    Have a nice synthesis
    backhus, Apr 12, 2011
    1. Advertisements

  3. devas

    Tricky Guest

    Theres not really a lot of difference. A signal assignment outside of
    a formal process is really just another process, with the sensitivity
    list set by the signals on the right hand side.

    so this code:

    output <= a when sel = '0' else b;

    is the same as:

    process(a, b, sel)
    if sel = '0' then
    output <= a;
    output <= b;
    end if;
    end process;
    Tricky, Apr 12, 2011
  4. devas

    rickman Guest

    I see one major difference. The process is eight lines of code and
    the concurrent statement is only one. Which do you think is easier to
    read and provides fewer opportunities for errors?

    rickman, Apr 12, 2011
  5. In the interests of civil discussion I'll
    temporarily pretend that this stance doesn't
    make my blood boil.

    Instead I'll politely point out that, on the
    very rare occasions when I really want something
    that simple as a standalone thing, then the
    concurrent statement is indeed probably better.
    Three-state I/O buffers are the best and
    commonest example.

    And I'll also politely point out that
    decomposing designs into pieces small enough
    to represent as concurrent statements makes
    each piece trivially easy to understand, but
    makes the whole design as comprehensible as
    a broken-up jigsaw puzzle.

    Taking a complicated thing and breaking it
    into lots of simple pieces doesn't make it
    simpler. It simply turns the complicated
    thing into a pile of pieces.
    Jonathan Bromley, Apr 12, 2011
  6. devas

    KJ Guest

    Based on what devas posted, the 'standalone thing' is all that one can
    guess that devas is interested in for the reasons that were listed.
    I agree in principle...but in this case, the only context given by
    devas in his posting was in the pros and cons of coding a mux as
    either a conditional signal assignment or using a process. In this
    case, there is no 'complicated thing' being broken into simpler

    Your comment though is valid, but should be directed to devas within
    the context of 'hey, why are you spending time thinking about the
    coding of a mux'? The opportunities to code a mux by itself are
    relatively few and far between. The opportunities to describe logic
    that also includes mux-like behavior are far more numerous and rarely
    are enhanced by the ability to describe this behavior explicitly as a
    standalone thing (whether as a process or concurrent statement).

    But then again maybe devas is just getting started in design and/or
    VHDL or perhaps his interest is not in designing something in VHDL but
    is actually in simulator performance, or some theoretical language
    aspect, something more abstract, who knows?

    In any case, devas was already aware of the major drawback from the
    standpoint of creating reliable/maintainable designs of the process
    which is that of an incomplete sensitivity list (prior to VHDL-2008).
    On the other hand, devas seems misinformed (or maybe needs to
    experimentally try) about why he thinks the process approach would be
    more efficient in simulation than the concurrent assignment.

    Kevin Jennings
    KJ, Apr 12, 2011
  7. I apologize if I confused or misled the OP. My post
    was responding to yet another clear description of the
    position that states "bugs increase monotonically with
    lines of code, therefore anything that locally reduces
    the number of lines of code is good". This I regard as
    such pernicious nonsense that I will unapologetically
    seize on any opportunity to challenge it, especially
    if expressed in a way that encourages the decomposition
    of designs into absurdly small and meaningless pieces.
    True. I carefully pointed out that this can happen, in some
    very specific situations, and there the shorter description
    is entirely appropriate.
    It could have been, but wasn't; that was not my target.
    The OP's question was reasonable, and evinced reasonable
    answers; it was the added spin on those answers that
    riled me.
    Jonathan Bromley, Apr 12, 2011
  8. devas

    Andy Guest

    For one simple, combinatorial function with one output, I prefer the
    concurrent assignment.

    Features that make me lean toward using a process include:

    more than one output controlled similarly by the same inputs,
    logic that feeds a register within the same architecture,
    nested if-then logic,
    existence of related logic that is already in a process

    Since one or more of these features is often present in my projects, I
    usually use processes with sequential statements, synchronous when

    Extensive use of concurrent statements starts to look like coding a
    netlist (and reads like one too), instead of coding a synthesizeable
    behavior with sequential statements, which is usually easier to

    Andy, Apr 12, 2011
  9. Synthesis requires an entity.
    Since each entity has code overhead,
    I describe logic at a higher level for less overall code.

    I describe the entity output ports only
    in terms of input ports and local variables,
    rather than muxes and flops.

    For example in this stack design:
    no muxes are described directly,
    yet synthesis inferred several:

    -- Mike Treseler
    Mike Treseler, Apr 12, 2011
  10. devas

    daniel.kho Guest

    Yes, for me as well. If a block (or sub-block) seems simple enough to
    describe as a one-liner (or a few lines) of concurrent statements, go
    for it. If my block/sub-block starts getting a bit more complex, I'll
    start putting those concurrent statements within a process instead.

    When it gets difficult to behaviourally describe your functionality
    with just a few concurrent statements, and when you start breaking up
    a concurrent statement to multiple smaller concurrent statements,
    that's when you're beginning to change your behavioural design to a
    structural one, i.e. one that doesn't describe the behaviour and
    therefore is difficult to understand. When I could foresee that I'm
    heading this (wrong) direction, I'll steer myself back to enclose
    those statements in a process, and add whatever other functionality I

    Daniel Kho
    daniel.kho, Apr 13, 2011
  11. devas

    rickman Guest

    Ok Jonathan, take a deep breath. Now, tell me what you *really*

    I think if you read my post again, you will see that all I am saying
    is that the above code is much simpler written as one line of
    concurrent code than eight lines of process. I'm not espousing a
    philosophy or promoting anything about a standard practice. I'm just
    saying that the two code examples do exactly the same thing and one is
    *much* simpler than the other.

    What exactly did you think was in my post that I am not aware of?

    rickman, Apr 13, 2011
  12. devas

    rickman Guest

    I should have read all the posts before I replied to your earlier
    one. This tells me a bit more, but you are making claims without
    supporting them. Can you tell me why you believe your position? So
    far you have simply stated it.


    M: An argument isn't just contradiction.
    A: It can be.
    M: No it can't. An argument is a connected series of statements
    intended to establish a proposition.
    A: No it isn't.
    M: Yes it is! It's not just contradiction.
    A: Look, if I argue with you, I must take up a contrary position.
    M: Yes, but that's not just saying 'No it isn't.'
    A: Yes it is!
    M: No it isn't!
    rickman, Apr 13, 2011
  13. devas

    rickman Guest

    I don't have any grand rules for when I describe combinatorial logic
    with a process, but it is seldom, mainly because I don't like
    maintaining the sensitivity list. Mostly the logic I code is
    included in sequential processes, but there are times when it doesn't
    make sense from a decomposition point of view to include some of the
    logic in the sequential process. Then I put it is concurrent
    statements. A data path mux is a perfect example of that.

    If the concurrent statements get too complex, I will use a process. I
    did that for some code controlling a couple of status LEDs. The
    concurrent logic was getting complex because of multiple modes
    displaying different status. The muxing was rather complex and hard
    to understand. In a process the IF statement structure was more

    But for signal path logic it is often a series arrangement of
    processing steps. Putting that in a process requires that some of the
    outputs which feed into the logic for the next step be included in the
    sensitivity list. I find this rather messy. Otherwise these
    intermediate values need to be expressed with variables. But
    variables don't show up in the waveform display, at least in
    ActiveHDL. So I find variables harder to use in debug and only use
    them when there is a clear advantage, like in test benches. I've
    never had any real issues expressing a linear flow in four concurrent
    statements rather than four sequential statements inside the several
    lines of code to setup a process.

    rickman, Apr 13, 2011
  14. devas

    Andy Guest

    I think there are two arguments in play here: how to describe
    combinatorial logic, and whether it needs to be described
    combinatorially at all.

    I very rarely need to describe combinatorial logic outside the context
    of a synchronous process, so that sensitivity lists and latches are
    rarely a problem.

    I usually debug source code, not waveforms, so variables not showing
    up in waveforms would not be a big issue for me, especially compared
    to the advantages of using variables.

    Andy, Apr 13, 2011
  15. devas

    rickman Guest

    Wow, we work so differently. The big difference between HDL and
    software that I love is the fact that I can access any point in the
    design with a simulation scope probe to see just what is happening.
    The few times I have used the code debugging tools I find them to be
    fairly painful to get to the point of the issue. Maybe I'm just not
    experienced enough with them.

    rickman, Apr 13, 2011
  16. devas

    KJ Guest

    I agree. Debugging the source code implies that you have identified
    an incorrect behavior (presumably via an assertion or observation of
    some other 'incorrect' output) AND you have restarted the simulation
    to get it up near the suspected time of the failure so you can step
    through or otherwise 'debug the source code'. Not only is restarting
    the sim wasted time (although maybe it's not a 'lot' of time depending
    on the particular design) but if you guess incorrectly about the time
    that the root cause of the failure occurred you may have to restart
    the sim again...all because there is no equivalent to 'log -r /*' that
    captures the history of all variables in a design.

    Debugging with the waveform allows one to easily plop down the entire
    history of any signal anywhere in the entire design and testbench.
    The cost is a single command ('log -r /*') and some extra wall clock
    time and disk space to store the data to disk. Whether or not that
    extra bit of wall clock time was 'well spent' or not can be user
    dependent, I've found it to be 'worth it'.

    Which is 'best', is most likely a very user dependent question.
    Either way can work. To be efficient at using one method or the other
    may take time, but in the end I would guess that one can be equally
    productive either way. If there is a compelling reason for one way
    versus the other, I haven't heard about it.

    As a side note, to work around the issue of wanting to use sequential
    statements (because it more readily conveys the design intent) but
    need an unclocked signal but don't want to bother with sensitivity
    lists, there is always the ability to define a function or a procedure
    and instantiate call that function/procedure out just like a
    concurrent assignment. You get all of the benefits of sequential
    statement syntax along with proper checking of inputs (no missing
    signals in the sensitivity list) and a combinatorial output.

    Kevin Jennings
    KJ, Apr 13, 2011
  17. devas

    Andy Guest

    I use waveforms occasionally to get a look at an interface (external
    or internal) but those are always signals anyway (ports). I use
    assertions in both the RTL and the testbench which stop the simulation
    when something goes wrong, then I can observe the variables and
    signals I need, and insert a few breakpoints and monitors if
    necessary. Given the cyclical nature of most hardware designs, it is
    often not necessary to "back up" to see what happened, just catch it
    again on the next time around. Backing up can be a pain though if I
    have to. Most of the RTL assertions get put in during design or unit
    testing, so they are already there by the time I have a larger system
    simulation that would be time consuming to restart (and that would be
    severely slowed down by dumping every signal to a file "just in
    case".) I'm a big proponent of self-checking testbenches, and they
    don't use waveforms either.

    Most of us use methods we are most comfortable with, and using
    waveforms is very similar to the typical test equipment in the lab
    that we learned on. I started using the source code debugger after
    working with the SW driver guys to debug HW/SW issues in the lab. I
    had also taken a couple of Ada courses to sharpen my VHDL, and was
    exposed to the techniques there. Then I started trying some of those
    techniques in my VHDL simulations, and it worked well for me.

    But what works well for me may not work for others. Having multiple
    examples to accomplish the same thing allows users to find what works
    best for them individually.

    Andy, Apr 13, 2011
  18. OK, let's keep separate things separate.

    The bit that got my dander up was your implied, but
    clear, statement that fewer lines of code makes for
    fewer bugs. Others have stated this much more
    starkly than you did. I rather strongly disagree
    with it. Whilst it is evidently true that adding
    more code to any project will of course increase
    the number of bugs, since code is rarely bug-free,
    that in itself provides not a shred of evidence
    that the implementation of a given set of
    functionality will have fewer bugs if implemented
    using coding techniques that result in fewer
    lines of code. My own experience suggests that
    very compact, dense coding styles increase the
    risk of subtle hidden bugs and oversights that
    are very hard to track down. A more literate
    coding style generally leads to more easily
    debugged code. Clearly you can go too far
    the other way - verbosity for its own
    sake is unlikely to help, and in particular
    it is never a good idea to have redundancy
    in code. But the basic argument that leads
    to the mantra "code it in fewer characters
    and you'll get fewer bugs" is groundless, and
    I'm convinced it has led to misguided choices
    in the design and application of HDLs.

    More directly related to what you posted
    is the question of the most desirable
    granularity to which you should decompose
    a problem. I think I was clear enough in
    my discomfort there. You can always make
    each piece of a design trivially easy to
    understand, simply by decomposing it into
    pieces that are small enough. Is a shift
    register small enough for you? A flop?
    A mux? A transistor? The snag is, this
    simplification comes at an unacceptable
    price: it hides the real functionality
    of the design or design fragment. As
    others have indicated, it's probably
    unhelpful to lay down rigid guidelines
    here. I can suggest some touchstones:
    is the piece of code amenable to testing
    that will show whether it does what you
    need it to do, without wasting effort by
    testing some function such as a mux that's
    already well-known to work? Can I write
    a few lines of comment in the code that
    describe succinctly what it does, and
    why it's there? Can I relate this fragment
    to any kind of specification or requirement?
    The reality, though, is that the optimum
    choices depend on the people doing the
    work, the nature of the problem, the
    customer's demands and a whole pile of
    other things.

    Despite all this fence-sitting, there is
    something that seems obvious to me.
    Breaking a design into excessively small
    pieces (transistors!!) clearly obscures
    its functionality. Leaving a design in
    huge monolithic chunks (an entire FPGA
    in one VHDL process!!) is clearly hopeless
    too; no-one could possibly understand it.
    Somewhere in the middle there is an
    optimum - not ideal, but certainly better
    than either end of that spectrum. Merely
    saying "simpler is better" is inadequate.

    For me, pieces of design small enough to
    write as a single concurrent statement are
    almost never big enough to give me useful
    clues about how they contribute to the
    overall functionality (unless you put a
    function call in the expression).

    Sorry about the lengthy ramblings. You
    did ask for a justification :)
    Jonathan Bromley, Apr 14, 2011
  19. devas

    Tricky Guest

    I can see where you're coming from andy. Ideally, your final test
    should be a black box test, with a self checking testbench. It worries
    me when I see designers stare at waveforms all day and using this for
    their verification. They should be using output data as the test - no
    waveforms needed. Working in video I use bitmaps for input and output
    data. Its so much easier looking at a whole picture than looking at a
    stream of pixels. Often this output picture gives you a clue as to
    whats wrong - its normally very obviously when something has gone
    wrong doing this. Then I can get in amongst the waveform for more
    specific debugging, using the clues from the output.
    Tricky, Apr 14, 2011
  20. That's much the same as the methods I use (and even the odd printf^H^H^H^H^H
    report statement :)

    I'm sure Aldec can put variables in the wave window - it may be that (as with
    Modelsim) you have to do it before the sim for it to log them. At the subblock
    level, adding a few variables and restarting is not usually a killer - especially
    when you have asserts already in to stop the simulation as soon as things go

    (The variables I want to see are usually state variables - it'd be great
    to be able to do "log -r *state" on variables :)
    And there are times when I'm writing embedded software that I'd really like a
    waveform trace of my C variables :)

    Martin Thompson, Apr 14, 2011
    1. Advertisements

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 (here). After that, you can post your question and our members will help you out.