Re: Mixed clocked/combinatorial coding styles

Discussion in 'VHDL' started by rickman, Aug 18, 2008.

  1. rickman

    rickman Guest

    On Aug 18, 11:53 am, Jonathan Bromley <>
    wrote:
    > OK, so I tried the following synthesis example -
    > various declarations omitted to save space.
    > I have been able to try this on five different
    > synthesis tools, spanning the whole range of
    > cost and FPGA-vs-ASIC. The results surprised
    > me a little - it's a long time since I did such
    > a complete survey.
    >
    > ~~~~~~~
    > Form 1: Clocked process, with combinational output logic
    > outside the usual clocked if..else...endif block.
    > ~~~~~~~
    >
    > process(clock, reset)
    > variable count: unsigned(7 downto 0);
    > begin
    > -- 8-bit counter, clocked with async reset
    > if reset = '1' then
    > count := (others => '0');
    > elsif rising_edge(clock) then
    > count := count + 1;
    > end if;
    > -- Combinational logic
    > q <= std_logic_vector(count);
    > msb <= count(7);
    > if count = (count'range => '1') then
    > tc <= '1';
    > else
    > tc <= '0';
    > end if;
    > end process;
    >
    > This is the form I was objecting to in an earlier post,
    > on the grounds that the signal assignments don't match
    > standard synthesis templates. EVERY ONE of the five
    > synthesis tools I tried gave exactly the results you
    > might hope for: "msb" is directly connected to count[7],
    > "q" is directly connected to count[7:0], "tc" is the
    > output of an AND gate looking at all eight bits of count.
    >
    > ~~~~~~~
    > Form 2: Clocked process, with outputs assigned based on
    > next-state value of counter variable.
    > ~~~~~~~
    >
    > process(clock, reset)
    > variable count: unsigned(7 downto 0);
    > begin
    > if reset = '1' then
    > count := (others => '0');
    > q <= std_logic_vector(count);
    > msb <= count(7);
    > if count = (count'range => '1') then
    > tc <= '1';
    > else
    > tc <= '0';
    > end if;
    > elsif rising_edge(clock) then
    > count := count + 1;
    > q <= std_logic_vector(count);
    > msb <= count(7);
    > if count = (count'range => '1') then
    > tc <= '1';
    > else
    > tc <= '0';
    > end if;
    > end if;
    > end process;
    >
    > You'll note that this is quite a bit nastier because
    > it's necessary to assign to the outputs both in the
    > reset and in the clocked branch, otherwise the
    > "q" and "count" registers will have subtly different
    > behaviour and could not be merged.


    I can't say I follow you on this. A reset input by definition defines
    the state of all registers, state and output. Why would you want to
    assign the outputs to be dependant on the previous state when the
    reset is asserted??? I have never done this since it was not the
    desired behavior. Oh, I guess it is because you are trying to force
    the use of the carry chain. Do you have any reason to believe that
    this is needed? Considering that the if (count = 1's) in the reset
    code is redundant (at this point count is always the value 0), this
    just seems so verbose.


    > All five tools gave correct results, but two tools
    > failed to merge the duplicate registers they had
    > created for count and q. Of course, it is entirely
    > possible that those duplicate registers might be
    > merged later, during place-and-route, as they were
    > indeed exact duplicates.
    >
    > I'm not quite sure what to think now. Form 1 still
    > does not really appeal. In particular, it cannot be
    > reproduced in Verilog. Form 2 gives registered outputs
    > for everything - not even the very simplest combinational
    > logic between flops and outputs - and maps well to Verilog,
    > but it's disappointing that some tools didn't merge the
    > duplicate registers and there is no doubt that it's
    > clumsier to code, especially if there's an asynchronous
    > reset in the process.


    What about form B, not using a variable since it adds nothing to the
    situation and is clearly making things more difficult.

    > One final data point: The style of asynch reset
    > that has been suggested here on several occasions,
    > allowing you to reset some but not all of a process's
    > registers without implying unwanted enable logic,
    > worked as expected in all five tools I tried:
    >
    > process (clock, reset)
    > variable count: unsigned(7 downto 0);
    > begin
    > if rising_edge(clock) then
    > count_pipe <= count; -- count_pipe isn't reset
    > count := count + 1;
    > end if;
    > if reset = '1' then
    > count := (others => '0');
    > end if;
    > end process;


    I personally don't care for this since it is 1) complex and 2) not the
    same as your other code that sets the values of the outputs.

    Rick
     
    rickman, Aug 18, 2008
    #1
    1. Advertising

  2. rickman

    rickman Guest

    On Aug 18, 4:38 pm, Jonathan Bromley <>
    wrote:
    > On Mon, 18 Aug 2008 11:39:42 -0700 (PDT), rickman wrote:
    > >> it's necessary to assign to the outputs both in the
    > >> reset and in the clocked branch, otherwise the
    > >> "q" and "count" registers will have subtly different
    > >> behaviour and could not be merged.

    >
    > >I can't say I follow you on this. A reset input by definition defines
    > >the state of all registers, state and output.

    >
    > Not if I write a description in which some of the registers
    > are reset and some aren't, surely?


    Of course you can define any world you wish to work in. I was
    referring to the world of FPGA design. There a global async reset is
    nearly always provided and needs to be specified. The standard
    template is mapped to the global reset quite well by the tools. In
    that context, there is no reason to leave any register uncontrolled on
    reset (unless you have some very odd requirements) and failure to do
    so can result in unpredictable power up behavior.

    I don't have to consider the entire universe of possibilities. I just
    have to consider the universe that I choose to work in and I don't
    want to make my life difficult by not controlling the power up state
    of registers in my design. It also helps with simulation a great
    deal!


    > > Why would you want to
    > >assign the outputs to be dependant on the previous state when the
    > >reset is asserted??? I have never done this since it was not the
    > >desired behavior. Oh, I guess it is because you are trying to force
    > >the use of the carry chain.

    >
    > No, nothing as smart as that. It's just a simple thing
    > about the usual synthesisable clocked process:
    >
    > process(clk)
    > begin
    > if reset = '1' then
    > Q0 <= '0'; -- reset, but never clocked
    > Q1 <= '0'; -- reset and clocked, OK
    > elsif rising_edge(clk) then
    > Q1 <= D1; -- reset and clocked, OK
    > Q2 <= D2; -- clocked but never reset
    > end if;
    > end process;
    >
    > The usage of Q0 and Q2 is unsatisfactory because...
    > - Q0 is a latch, enabled by reset, with constant input
    > - Q2 is a regular flop with (reset = '0') as its clock enable
    >
    > So, what happens when I wish to describe some kind of pipeline
    > in which the first stage has an asynch reset but the later
    > stages do not? That's a sensible design; if you know that
    > the clock will tick several times during reset, then you
    > don't need to reset anything but the first stage of the
    > pipeline because all later stages will flush through
    > by clocked action during the reset interval. But how
    > to describe that? You need TWO PROCESSES, one for the
    > register that HAS a reset and one for the registers
    > that LACK a reset. Of course, synch reset doesn't suffer
    > this problem - you can freely apply it to individual
    > registers, and not to others, in a single process.


    Again, you don't explain the context of your async reset. If it is
    the global reset I see no reason to leave it off of any registers in
    your design. A sync reset is one that is typically used at any time
    during operation. The async reset is typically mapped to the global
    reset. If it does not, IMHO, the async reset does not belong in a
    synchronous design. I avoid the problem by avoiding it!


    > All of that was the motivation for my final example,
    > which you didn't like...
    >
    > >> begin
    > >> if rising_edge(clock) then
    > >> count_pipe <= count; -- count_pipe isn't reset
    > >> count := count + 1;
    > >> end if;
    > >> if reset = '1' then
    > >> count := (others => '0');
    > >> end if;
    > >> end process;

    > > I personally don't care for this since it is 1) complex and 2) not the
    > > same as your other code that sets the values of the outputs.

    >
    > I abbreviated the example; it could easily set outputs just as
    > the "Form 2" variant does. But I take the point that it is
    > unfamiliar (surely not really "complex"?) and, as someone else
    > has pointed out, it's not too nice to have a piece of code that
    > says Do-Lots-Of-Complicated-Stuff only to have the rug pulled out
    > from under you by an If-The-World-Is-About-To-End condition
    > right at the end of the process. It's better to know about
    > those global things right up front.


    I will point out that the above example can fail to initialize
    count_pipe. The above should produce two registers and only the
    first, count, will be reset. Why would you want to do that???

    So I still fail to see your motivation, or at least I don't share
    it.

    Rick
     
    rickman, Aug 18, 2008
    #2
    1. Advertising

  3. rickman wrote:

    > I can't say I follow you on this. A reset input by definition defines
    > the state of all registers, state and output. Why would you want to
    > assign the outputs to be dependant on the previous state when the
    > reset is asserted???


    Maybe I want to describe a block ram and
    a lut shifter in the same process as some registers.
    The registers need a reset, but the ram and
    shifter can't have one.

    -- Mike Treseler
     
    Mike Treseler, Aug 19, 2008
    #3
  4. KJ <> writes:

    > On Aug 20, 6:00 am, Jonathan Bromley <>
    > wrote:
    >> On Tue, 19 Aug 2008 14:29:55 -0700 (PDT), rickman wrote:
    >> >One of the issues I have with variables is
    >> >that they are hard to debug since they can only be viewed when in
    >> >context, so I prefer a signal that is always viewable.  It was a long
    >> >ago that I worked with signals and maybe the tools I used were not
    >> >very good.  Has that changed?

    >>
    >> There's no difficulty viewing variables (at least, the static
    >> variables that you declare in processes) in any tools I use.

    >
    > You can't view variables in a wave or list windows after the fact
    > using Modelsim.
    >


    In defence of variables, you can view them when you've added them to
    the wave before you start. When I start debugging an entity, I
    usually just add all its various variables to a wave window at the
    start.

    > When something fails in any simulation, the reason for the failure
    > many time is in the past, although sometimes the reason is in the
    > present. The wave and list windows are the available tools for
    > investigating what happened prior to the failure in order to discern
    > what was the root cause. When you use variables extensively you lose
    > at least some of the ability to use those tools to debug. Given that
    > handicap you must turn to other methods such as re-running the
    > simulation to either step through code, or add the variables that
    > you'd like to see to the wave/list windows at sim start (hoping you've
    > guessed correctly at all of the ones you need). At best you're only
    > slightly less productive because of this handicap.


    For the vast majority of my simulations, re-running the sim takes a
    matter of seconds if I forget to add the signals to the wave window.
    Problems that a "whole-FPGA" problems usually come down to signals anyway.

    >
    > Modelsim's log -r /* command is a very powerful debug aid...it get
    > signals, it doesn't pick up variables.
    >


    It would be nice if it did :) Maybe some TCL could help here... hmm...

    <snip>

    > Within an entity, I tend to have multiple clocked processes and
    > concurrent statements. The physical grouping of what signals go in
    > this clocked process versus that clocked process has to do with how
    > closely related the logic is that is required to implement that
    > signal. Things that are unrelated go in separate processes. I'll
    > also tend to try to limit the physical size of a process so that it
    > fits on a screen. The end result is a file where you don't have to
    > scroll back and forth and all around in order to see what is going
    > on. During the design process where you're still working on what the
    > actual logic is, things can freely move (by cut/paste) from one
    > process to another as the realization sets in that the logic for
    > signal 'abc' is very similar after all to that which I have for
    > 'xyz'. This type of situation is also where the limited use of
    > variables is a good thing since I can freely move and modify the code
    > from one process to the other to textually group together the related
    > stuff because, when the code being moved only uses signals, that cut/
    > paste can always be safely done without mucking up something else in
    > the process that it was cut from.


    Except when you forget to move the reset clause for a signal - then
    you have two processes driving it. But that's what std_ulogic is for :)

    <snip>
    >>
    >> >I would almost prefer a language that did not offer so much freedom.
    >> >I can't help but think this offers limited value to the coders and
    >> >makes life a lot harder for the tool writers.

    >>
    >> Again, perhaps we should agree to differ.
    >>

    >
    > I agree with you (Jonathon). The more skilled you get with VHDL, the
    > more you appreciate all the things that they thought to include (but
    > you still gripe about the odd constraints).
    >
    > Abel is a simple language to learn and use but I wouldn't use it today
    > because VHDL provides much more power for creating not only a design
    > but a self checking testbench of the design within a single language
    > environment. That design and testbench can also be as fully
    > parameterized as I would like it so that they can be reused for some
    > other project down the road.


    That get's my agreement too!

    Cheers,
    Martin

    --

    TRW Conekt - Consultancy in Engineering, Knowledge and Technology
    http://www.conekt.net/electronics.html
     
    Martin Thompson, Aug 21, 2008
    #4
  5. rickman

    rickman Guest

    On Aug 21, 2:52 am, Mike Treseler <> wrote:
    > Kim Enkovaara wrote:
    > > Yes, I agree that variables are sometimes painful and make debugging
    > > much harder, but on the other hand they help to make cleaner code
    > > usually that is easier to read.

    >
    > ...and less likely to have a logical error in the first place.
    >
    > -- Mike Treseler


    People keep saying this, but I have not seen one example. Can anyone
    come up with a compelling example of why we should suffer the use of
    variables in our code?

    Rick
     
    rickman, Aug 21, 2008
    #5
  6. rickman

    rickman Guest

    On Aug 21, 2:01 am, Kim Enkovaara <> wrote:
    > rickman wrote:
    > > On Aug 20, 9:45 am, KJ <> wrote:
    > >> On Aug 18, 5:23 pm, rickman <> wrote:

    >
    > > If you don't use async resets, then you don't use FPGAs, at least none
    > > that I am aware of. FPGAs have a global set/reset signal that
    > > initializes the FFs on power up. You don't have to drive it with your

    >
    > Of course with FPGAs also initial values can be used and then no reset
    > is connected to the FF. The initial value comes from the configuration
    > file in that case.


    But this requires the global set reset signal. That is how the FFs
    get their initial state.

    > > own signal, but it is active regardless of your code. But if you want
    > > to control the state of the FF on power up, then you need to use a
    > > register template with an async reset.

    >
    > Not always. You can also use the FFs without any reset and give initial
    > values for the signals. Most synthesizers can transfer those values
    > to configuration image.


    I don't think this is the rule. If you want to write portable code,
    you need to use a reset as part of the clocked process.


    > > The shift register you describe driving a synchronous reset is what I
    > > use, except I use it to drive the async reset. Since the output of
    > > the shift register is sync'd to the clock, it will not cause
    > > problems. It also does not use any extra resources since it will be
    > > mapped to the dedicated GSR signal in the FPGA.

    >
    > It might cause problems, because the internal global reset lines inside
    > FPGA are quite slow. And the signal might not propagate trough the FPGA
    > during one clock cycle. I have seen problems with this kind of reset
    > style, the design locked once every 100 startups. The cause was that on
    > some one-hot statemachines the FFs got reset deasserted on different
    > clock cycles, and there was no guard logic in the state machines to get
    > out from that situation.


    Maybe if you are running at 200 MHz. There are always speed issues in
    any design. That is why you use timing constraints. You do use
    timing constraints, right?

    Rick
     
    rickman, Aug 21, 2008
    #6
  7. rickman

    KJ Guest

    On Aug 21, 8:32 am, rickman <> wrote:
    > On Aug 21, 2:01 am, Kim Enkovaara <> wrote:
    >
    > > Of course with FPGAs also initial values can be used and then no reset
    > > is connected to the FF. The initial value comes from the configuration
    > > file in that case.

    >
    > But this requires the global set reset signal.  That is how the FFs
    > get their initial state.
    >


    No, implementing an initial value does not require *any* signal in the
    design source files. Maybe we're delving into an area where the tools
    that you're using don't (or you think they don't) support initial
    values in the source code or something and in order to get those
    intial values that tools requires you to code it as if it was an async
    reset.

    If xyz is a flip flop output and one can say...
    signal xyz: std_ulogic := '1';
    and signal xyz gets initialized at configuration time then the tools
    support the VHDL language standard as it applies to defining initial
    values.

    If instead you have to say...
    if (Reset = '1') then
    xyz <= '1';
    ...

    in order to get xyz initialized at configuration time then the tools
    do not support the VHDL language standard as it applies to defining
    initial values and the above code is the work around that might
    help...but still it's a work around to a tool limitation, not some
    fundamental principle.

    > > > own signal, but it is active regardless of your code.  But if you want
    > > > to control the state of the FF on power up, then you need to use a
    > > > register template with an async reset.

    >
    > > Not always. You can also use the FFs without any reset and give initial
    > > values for the signals. Most synthesizers can transfer those values
    > > to configuration image.

    >
    > I don't think this is the rule.  If you want to write portable code,
    > you need to use a reset as part of the clocked process.
    >


    Not really. If you're talking about portability to tools that don't
    support initial value specification then you could still find yourself
    at the mercy of having to supply an external I/O pin to ultimately
    give you the reset at the end of configuration. Now this tool
    limitation work around is requiring additional PCBA support that would
    not otherwise be required.

    Obviously all this only applies to devices that have a defined powerup/
    end configuration state available but which *tools* don't support
    initial value specification now-a-daze?

    KJ
     
    KJ, Aug 21, 2008
    #7
  8. rickman

    Andy Guest

    On Aug 21, 7:27 am, rickman <> wrote:
    > On Aug 21, 2:52 am, Mike Treseler <> wrote:
    >
    > > Kim Enkovaara wrote:
    > > > Yes, I agree that variables are sometimes painful and make debugging
    > > > much harder, but on the other hand they help to make cleaner code
    > > > usually that is easier to read.

    >
    > > ...and less likely to have a logical error in the first place.

    >
    > > -- Mike Treseler

    >
    > People keep saying this, but I have not seen one example. Can anyone
    > come up with a compelling example of why we should suffer the use of
    > variables in our code?
    >
    > Rick


    "We" have already given several examples that are compelling to many
    of us:

    Ease of discerning cycle based behavior from the code
    Decoupling, etc. without resorting to separate files/entities/
    architectures
    Proximity of the variable definition to where it is used
    Simulation efficiency

    Apparently these are not compelling reasons to you, and you are free
    to limit your use of the VHDL language and tool capabilities
    accordingly.

    Andy
     
    Andy, Aug 21, 2008
    #8
  9. rickman

    KJ Guest

    On Aug 21, 9:35 am, Andy <> wrote:
    > On Aug 21, 7:27 am, rickman <> wrote:
    >
    > > On Aug 21, 2:52 am, Mike Treseler <> wrote:

    >
    > > > Kim Enkovaara wrote:
    > > > > Yes, I agree that variables are sometimes painful and make debugging
    > > > > much harder, but on the other hand they help to make cleaner code
    > > > > usually that is easier to read.

    >
    > > > ...and less likely to have a logical error in the first place.

    >
    > > >        -- Mike Treseler

    >
    > > People keep saying this, but I have not seen one example.  Can anyone
    > > come up with a compelling example of why we should suffer the use of
    > > variables in our code?

    >
    > > Rick

    >
    > "We" have already given several examples that are compelling to many
    > of us:
    >


    > Ease of discerning cycle based behavior from the code

    The 'ease of discerning' depends much on the skill of the person
    writing the code, not whether or not variables were used.

    > Decoupling, etc. without resorting to separate files/entities/
    > architectures

    Decoupling and hierarchy has nothing to do with the use of variables.
    If you don't like the typing overhead of separate entities to express
    hierarchy (a valid complaint for some) you're free to express
    hierarchy within a block or generate statement and keep it all in one
    file...the amount of typing would be the same (slightly less I guess
    since 'block' is a shorter word than 'process').

    If your point here though was that keeping things (in this case
    variables) invisible outside of the scope of the process then this is
    exactly analogous to keeping other things (in this case signals) local
    to a block or generate...and inside that block you can still plop down
    a process with its variables if you so choose. Processes are
    handicapped in that they can not define a local signal if needed so
    you're forced to use variables to keep it local.

    > Proximity of the variable definition to where it is used

    The proximity of a variable definition to it's use is identical to
    that of a signal definition within a block to it's point of use.

    > Simulation efficiency

    I measured ~10-15% a while back...so that's one advantage.

    > Apparently these are not compelling reasons to you, and you are free
    > to limit your use of the VHDL language and tool capabilities
    > accordingly.

    You listed four reasons, only one of which is a valid advantage (which
    in turn must be balanced against the disadvantages previously
    mentioned).

    @Rick
    Where I tend to use variables in synthesis is where the logic to
    express the function is best handled with sequential statements (i.e.
    'if', 'case', etc.) and I don't want to bother writing it as a
    function for whatever reason so that I could use the function output
    in a concurrent signal assignment.

    The other case I would use variables in synthesis is to compute some
    intermediate thing which, if I didn't do it that way, would result in
    basically copy/pasting code, or otherwise cluttering up the source
    code...in other words, use of the variable becomes much like a
    shorthand notation.

    The biggest place I find for variables though has to be in the
    testbench code where I model the various widgets on the board and
    where synthesizability (if that's a word) is not a concern.

    The 'compelling example' is only something that you find compelling.
    Variables are just a tool in the toolkit for getting the job done.
    Like any tool they can be used well or misused. The quality/
    readability/*-ity of the resulting code that pops out depends solely
    on the skill and knowledge of the designer. Being limited in either
    area reduces the *-ity measure.

    KJ
     
    KJ, Aug 21, 2008
    #9
  10. rickman wrote:

    > Can anyone
    > come up with a compelling example of why we should suffer the use of
    > variables in our code?


    Let say I want to describe a phase accumulator
    in the traditional manner.
    With a mult-process design, I might
    say something like:

    accum_s <= '0' & accum_s(accum_s'length - 2 downto 0)
    + ('0' & addend_c);

    in one process and pick up the
    output msb in another process:

    msb <= accum_s(accum_s'length - 1);

    Thats not too bad, but it's pretty easy
    to get a count or length off by one.

    I prefer a single process description
    like this that does exactly the same thing.
    ...
    accum_v := accum_v + addend_c; -- add magic number
    msb_v := accum_v(accum_v'length-1); -- save the carry bit
    accum_v(accum_v'length-1) := '0'; -- clear carry for next time
    ...
    -- Now use msb_v however I like down here ...

    To me, there is no comparison.
    It's like calculus vs Laplace transforms.

    --Mike Treseler
     
    Mike Treseler, Aug 21, 2008
    #10
  11. rickman

    rickman Guest

    On Aug 21, 12:27 pm, Mike Treseler <> wrote:
    > rickman wrote:
    > > Can anyone
    > > come up with a compelling example of why we should suffer the use of
    > > variables in our code?

    >
    > Let say I want to describe a phase accumulator
    > in the traditional manner.
    > With a mult-process design, I might
    > say something like:
    >
    > accum_s <= '0' & accum_s(accum_s'length - 2 downto 0)
    > + ('0' & addend_c);
    >
    > in one process and pick up the
    > output msb in another process:
    >
    > msb <= accum_s(accum_s'length - 1);
    >
    > Thats not too bad, but it's pretty easy
    > to get a count or length off by one.


    I have no idea why you would use two processes for the above??? At
    first I thought that maybe you were assigning msb in a concurrent
    assignment so that it would not be registered. But in the example
    below you are assigning it in a clocked process.

    So what is the basis for using two processes above and one below???


    > I prefer a single process description
    > like this that does exactly the same thing.
    > ...
    > accum_v := accum_v + addend_c; -- add magic number
    > msb_v := accum_v(accum_v'length-1); -- save the carry bit
    > accum_v(accum_v'length-1) := '0'; -- clear carry for next time
    > ...
    > -- Now use msb_v however I like down here ...
    >
    > To me, there is no comparison.
    > It's like calculus vs Laplace transforms.


    Yes, it would appear that, to you, there are a lot of things that I
    can't see. For example, I can't see how you would make use of a
    variable outside of the process it is defined in. Or is "down here"
    still inside the process?

    Andy seems to think I am being silly or argumentative or whatever.
    But I maintain that no one in this discussion has actually explained
    how the use of variables provides any advantage. Andy just keeps
    waving his arms around saying "Decoupling" and "Proximity" without
    actually explaining how any of this is worth the extra trouble using
    variables. You have given an incomplete example that does not clearly
    show your point.

    Why is your point so hard to explain?

    Rick
     
    rickman, Aug 21, 2008
    #11
  12. rickman

    rickman Guest

    On Aug 21, 9:19 am, KJ <> wrote:
    > On Aug 21, 8:32 am, rickman <> wrote:
    >
    > > On Aug 21, 2:01 am, Kim Enkovaara <> wrote:

    >
    > > > Of course with FPGAs also initial values can be used and then no reset
    > > > is connected to the FF. The initial value comes from the configuration
    > > > file in that case.

    >
    > > But this requires the global set reset signal. That is how the FFs
    > > get their initial state.

    >
    > No, implementing an initial value does not require *any* signal in the
    > design source files. Maybe we're delving into an area where the tools
    > that you're using don't (or you think they don't) support initial
    > values in the source code or something and in order to get those
    > intial values that tools requires you to code it as if it was an async
    > reset.
    >
    > If xyz is a flip flop output and one can say...
    > signal xyz: std_ulogic := '1';
    > and signal xyz gets initialized at configuration time then the tools
    > support the VHDL language standard as it applies to defining initial
    > values.
    >
    > If instead you have to say...
    > if (Reset = '1') then
    > xyz <= '1';
    > ...
    >
    > in order to get xyz initialized at configuration time then the tools
    > do not support the VHDL language standard as it applies to defining
    > initial values and the above code is the work around that might
    > help...but still it's a work around to a tool limitation, not some
    > fundamental principle.


    I am not aware that initial values of signals is part of a VHDL
    standard for synthesis. In fact, I was under the impression that
    there is no "standard" for what parts of the language were supported
    for synthesis. Am I wrong about this? Are initial value assignments
    a required construct for synthesis support? I know they have not been
    historically.


    > > > > own signal, but it is active regardless of your code. But if you want
    > > > > to control the state of the FF on power up, then you need to use a
    > > > > register template with an async reset.

    >
    > > > Not always. You can also use the FFs without any reset and give initial
    > > > values for the signals. Most synthesizers can transfer those values
    > > > to configuration image.

    >
    > > I don't think this is the rule. If you want to write portable code,
    > > you need to use a reset as part of the clocked process.

    >
    > Not really. If you're talking about portability to tools that don't
    > support initial value specification then you could still find yourself
    > at the mercy of having to supply an external I/O pin to ultimately
    > give you the reset at the end of configuration. Now this tool
    > limitation work around is requiring additional PCBA support that would
    > not otherwise be required.


    If you want your part to come out of configuration cleanly, then you
    have to provide a way to synchronizing the end of the internal reset
    to the system clock. I have yet to find a way to do this without
    proving that external reset pin, even if it is just tied high (or
    low).

    Maybe the perceived problem of synchronizing the end of reset is a red
    herring. I have never seen a problem with it. But if you consider
    how FSM and counters work, it is entirely possible that they will not
    start up properly when reset in the default async manner.

    > Obviously all this only applies to devices that have a defined powerup/
    > end configuration state available but which *tools* don't support
    > initial value specification now-a-daze?


    That has been a large number of tools and FPGA devices by my
    experience. Can you state that there are no tools that don't support
    this feature?

    Rick
     
    rickman, Aug 21, 2008
    #12
  13. rickman

    rickman Guest

    On Aug 21, 9:07 am, Brian Drummond <>
    wrote:
    > On Mon, 18 Aug 2008 11:39:42 -0700 (PDT), rickman <>
    > wrote:
    >
    >
    >
    > >> You'll note that this is quite a bit nastier because
    > >> it's necessary to assign to the outputs both in the
    > >> reset and in the clocked branch, otherwise the
    > >> "q" and "count" registers will have subtly different
    > >> behaviour and could not be merged.

    >
    > >I can't say I follow you on this. A reset input by definition defines
    > >the state of all registers, state and output. Why would you want to
    > >assign the outputs to be dependant on the previous state when the
    > >reset is asserted??? I have never done this since it was not the
    > >desired behavior.

    >
    > One reason (not the case in this example): a very long delay line,
    > containing delayed state (to be used when a slow operation started by
    > the main state machine has completed). You can either reset this along
    > with the main state, or simply let its inputs ripple through. The latter
    > can be implemented at 16 bits per LUT in SRL16s for Xilinx, saving
    > several hundred FFs. The former can't, because the SRL16s don't have the
    > necessary reset connections.


    Ok, so how does that relate to the issue of using variables?

    Rick
     
    rickman, Aug 21, 2008
    #13
  14. rickman wrote:

    > I have no idea why you would use two processes for the above???


    I wouldn't.
    I assumed that others would.
    How would you do it?

    > Yes, it would appear that, to you, there are a lot of things that I
    > can't see. For example, I can't see how you would make use of a
    > variable outside of the process it is defined in. Or is "down here"
    > still inside the process?


    Yes. Sorry but I can't publish this entire entity.
    See my published examples for simpler cases.

    > Why is your point so hard to explain?


    I don't know.
    My preference is based on writing shell scripts, C and python.

    -- Mike Treseler
     
    Mike Treseler, Aug 21, 2008
    #14
  15. rickman

    Jan Decaluwe Guest

    Andy wrote:

    > "We" have already given several examples that are compelling to many
    > of us:
    >
    > Ease of discerning cycle based behavior from the code
    > Decoupling, etc. without resorting to separate files/entities/
    > architectures
    > Proximity of the variable definition to where it is used
    > Simulation efficiency


    All true, but I'm missing the most important point: the difference
    in semantics between signals and variables.

    There are things you can do with variables that you cannot easily
    accomplish with signals. So they add another dimension to the game.

    In particular, in a clocked process the same variable can be used
    both "combinatorially" and "as a register". Once you get that,
    the opportunities for elegant HDL solutions for real problems
    pop up everywhere.

    I consider register inference from variables the most powerful
    tool in the RTL toolbox - however it is poorly understood and
    probably banned in a majority of design teams.

    http://myhdl.jandecaluwe.com/doku.php/cookbook:jc2

    Jan

    --
    Jan Decaluwe - Resources bvba - http://www.jandecaluwe.com
    Kaboutermansstraat 97, B-3000 Leuven, Belgium
    From Python to silicon:
    http://myhdl.jandecaluwe.com
     
    Jan Decaluwe, Aug 22, 2008
    #15
  16. rickman

    rickman Guest

    On Aug 22, 6:19 am, Jan Decaluwe <> wrote:
    >
    > I consider register inference from variables the most powerful
    > tool in the RTL toolbox - however it is poorly understood and
    > probably banned in a majority of design teams.


    Not to mention poorly supported compared to signals, both in
    simulation and synthesis. If you use variables, you will see more
    bugs and limitations of the tools. Why? I guess because it is just
    not as mainstream. Kinda like driving a Maserati for the daily
    commute.

    Rick
     
    rickman, Aug 22, 2008
    #16
  17. rickman

    rickman Guest

    On Aug 21, 1:11 pm, Mike Treseler <> wrote:
    > rickman wrote:
    > > I have no idea why you would use two processes for the above???

    >
    > I wouldn't.
    > I assumed that others would.
    > How would you do it?
    >
    > > Yes, it would appear that, to you, there are a lot of things that I
    > > can't see. For example, I can't see how you would make use of a
    > > variable outside of the process it is defined in. Or is "down here"
    > > still inside the process?

    >
    > Yes. Sorry but I can't publish this entire entity.
    > See my published examples for simpler cases.
    >
    > > Why is your point so hard to explain?

    >
    > I don't know.
    > My preference is based on writing shell scripts, C and python.


    Well, that makes sense. If you are used to writing software, then you
    will be more comfortable with variables. I have a much stronger
    hardware background. I design my hardware in block diagrams, tables
    and state charts before I write any code (if needed). I then write
    the code that describes the registers and logic. I take the D in HDL
    literally (hardware Description language) and use the language to
    describe the hardware I want. I actually did not get a job offer
    once because I said that I code RTL. One of the lead engineers felt
    very strongly that this was too inefficient to be effective and
    blackballed an offer. Funny, I seem to be doing just fine on the
    engineering side of things. I wish I had a business manager though.

    This is in the clocked process
    accum_v <= accum_v + addend_c;

    This is a concurrent statement
    msb_v <= accum_v(accum_v'high);

    I don't recall needing this in a phase accumulator. Isn't the top bit
    just your output signal? The NCOs I have written were producing a
    digital output of 1 bit for use as a clock. Otherwise, why would you
    need the carry? Actually, I didn't use the carry out. I used the
    msb. Maybe I don't understand what you are doing with this.
    accum_v(accum_v'length-1) := '0'; -- clear carry for next time

    I guess my way uses an extra bit in the accumulator, one more than you
    have in the phase increment register. You look at this as saving the
    "carry" bit. But I don't get why you don't retain the carry bit into
    the sum. But then it has been a while since I have done an NCO.
    Maybe I am forgetting some things. BTW, "clearing" the carry can be
    done in the sum if you really need to.

    accum_v <= '0' & accum_v(accum_v'high-1 downto 0) + addend_c;

    But where did the extra bit in the addend_c come from? Do you have a
    bit in the addend that is never set?

    Rick
     
    rickman, Aug 22, 2008
    #17
  18. rickman <> writes:

    > On Aug 22, 6:19 am, Jan Decaluwe <> wrote:
    >>
    >> I consider register inference from variables the most powerful
    >> tool in the RTL toolbox - however it is poorly understood and
    >> probably banned in a majority of design teams.

    >
    > Not to mention poorly supported compared to signals, both in
    > simulation and synthesis.


    I really can't imagine a modern simulator not supporting variables to
    spec, surely! That would be just plain broken!

    > If you use variables, you will see more bugs and limitations of the
    > tools. Why? I guess because it is just not as mainstream. Kinda
    > like driving a Maserati for the daily commute.
    >


    I've never seen a variable-related bug in my time. In the old days
    there we *limitations*, but I haven't come across any of those
    recently either in the tools I use. And I use a *lot* of variables
    (and records, and procedures within processes, and all sorts of other
    things that didn't used to work, but make my life easier *now*).

    YMMV however :)

    Cheers,
    Martin

    --

    TRW Conekt - Consultancy in Engineering, Knowledge and Technology
    http://www.conekt.net/electronics.html
     
    Martin Thompson, Aug 22, 2008
    #18
  19. rickman wrote:
    > I don't recall needing this in a phase accumulator. Isn't the top bit
    > just your output signal?


    That would be a counter Q type output.
    I need to enable a prescaler with a carry-out.

    By saving the bit before clearing it
    I have exactly what I need and synthesis
    does a fine job with the carry chain details.
    I guess the advantage I see with variables
    is this ability to build up the values
    I need in sequential steps and to make
    the computer do more of the detail work.

    -- Mike Treseler
     
    Mike Treseler, Aug 22, 2008
    #19
  20. rickman

    KJ Guest

    On Aug 21, 9:35 am, Andy <> wrote:



    > On Aug 21, 7:27 am, rickman <> wrote:


    > > On Aug 21, 2:52 am, Mike Treseler <> wrote:



    > > > Kim Enkovaara wrote:
    > > > > Yes, I agree that variables are sometimes painful and make debugging
    > > > > much harder, but on the other hand they help to make cleaner code
    > > > > usually that is easier to read.



    > > > ...and less likely to have a logical error in the first place.



    > > > -- Mike Treseler



    > > People keep saying this, but I have not seen one example. Can anyone
    > > come up with a compelling example of why we should suffer the use of
    > > variables in our code?



    > > Rick



    > "We" have already given several examples that are compelling to many
    > of us:



    > Ease of discerning cycle based behavior from the code




    The 'ease of discerning' depends much on the skill of the person
    writing the code, not whether or not variables were used.


    > Decoupling, etc. without resorting to separate files/entities/
    > architectures



    Decoupling and hierarchy has nothing to do with the use of variables.
    If you don't like the typing overhead of separate entities to express
    hierarchy (a valid complaint for some) you're free to express
    hierarchy within a block or generate statement and keep it all in one
    file...the amount of typing would be the same (slightly less I guess
    since 'block' is a shorter word than 'process').

    If your point here though was that keeping things (in this case
    variables) invisible outside of the scope of the process then this is
    exactly analogous to keeping other things (in this case signals) local
    to a block or generate...and inside that block you can still plop down
    a process with its variables if you so choose. Processes are
    handicapped in that they can not define a local signal if needed so
    you're forced to use variables to keep it local.



    > Proximity of the variable definition to where it is used



    The proximity of a variable definition to it's use is identical to
    that of a signal definition within a block to it's point of use.


    > Simulation efficiency



    I measured ~10-15% a while back...so that's one advantage.


    > Apparently these are not compelling reasons to you, and you are free
    > to limit your use of the VHDL language and tool capabilities
    > accordingly.



    You listed four reasons, only one of which is a valid advantage (which
    in turn must be balanced against the disadvantages previously
    mentioned).

    @Rick
    Where I tend to use variables in synthesis is where the logic to
    express the function is best handled with sequential statements (i.e.
    'if', 'case', etc.) and I don't want to bother writing it as a
    function for whatever reason so that I could use the function output
    in a concurrent signal assignment.


    The other case I would use variables in synthesis is to compute some
    intermediate thing which, if I didn't do it that way, would result in
    basically copy/pasting code, or otherwise cluttering up the source
    code...in other words, use of the variable becomes much like a
    shorthand notation.


    The biggest place I find for variables though has to be in the
    testbench code where I model the various widgets on the board and
    where synthesizability (if that's a word) is not a concern.


    The 'compelling example' is only something that you find compelling.
    Variables are just a tool in the toolkit for getting the job done.
    Like any tool they can be used well or misused. The quality/
    readability/*-ity of the resulting code that pops out depends solely
    on the skill and knowledge of the designer. Being limited in either
    area reduces the *-ity measure.


    KJ
     
    KJ, Aug 23, 2008
    #20
    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. Ajeetha Kumari

    Re: clocked file-reading

    Ajeetha Kumari, Jul 4, 2003, in forum: VHDL
    Replies:
    0
    Views:
    1,051
    Ajeetha Kumari
    Jul 4, 2003
  2. Valentin Tihomirov
    Replies:
    3
    Views:
    537
    Jonathan Bromley
    Oct 28, 2003
  3. Replies:
    0
    Views:
    433
  4. Mike Treseler
    Replies:
    0
    Views:
    440
    Mike Treseler
    Aug 19, 2008
  5. whygee
    Replies:
    23
    Views:
    1,569
    Mike Treseler
    Aug 26, 2008
Loading...

Share This Page