Mixed clocked/combinatorial coding styles

No, I don't think so.  Of course you're right that
your code is the same.  But it exposes the internal
state of the process ("count") as a signal that is
global to the architecture; and it splits out the
functionality into many processes.  For the counter
example, none of that matters; for bigger examples,
it can have an important impact on encapsulation
and readability.  I was simply seeking out viable
alternatives - and trying to find what *really*
works and doesn't work, rather than relying on
myth or (in my case) obsolete information.
Does this go further into the variable vs signal argument? The same
colleague at work also says your Form 1 was a bad practice form of
code, because variables should never be used to store values between
clock cycles, and should only be used as logic, with the argument that
its just a danger synthesisers may not pick it up as such. He cited an
example of an old collegue (at another company) used to use variables
for starage often with less use of signals. This ran him into bother
after synthesis. Is this just old worrys? or was it more likely that
this person was probably just writing bad code?
 
On Aug 20, 9:45 am, KJ <kkjenni...@sbcglobal.net> wrote:
On Aug 18, 5:23 pm, rickman <gnu...@gmail.com> wrote:

On Aug 18, 4:38 pm, Jonathan Bromley <jonathan.brom...@MYCOMPANY.com
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 rarely use async resets at all and wouldn't really use any of these
forms sticking instead with the simple synchronous process form
(putting the "if (reset = '1') then..." at the top for readability).
The one exception for async resets being the shift register(s) that
take as input the external reset pin and from that generate a reset
signal that is synchronous to any clock(s). Using a reset signal that
is not synchronized to the clock is a design failure waiting to
happen.
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
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.

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.


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.

I'd turn it around and say that if there is no functional requirement
to reset a register than don't bother spending the time and adding the
extra code to do so.

Most registers (by quantity) in a design do not have such a
requirement since they hold data and do not control anything. Signals
that control other things (like an 'enable' bit that turns on/off some
function, a state machine) do need resets.
But you are ignoring that the register *has* an async reset whether
you choose to control it or not.

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!

You're right when you say "the async reset does not belong in a
synchronous design"...but I would say that the only exceptions to that
being
- The reset synchronizer
- Any output pins of the top level design that require a specific
power up state prior to having a good clock.
You seem to ignore my point which is about the GSR signal.

Rick
 
On Aug 20, 3:58 pm, rickman <gnu...@gmail.com> 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
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 exactly. Yes, the GSR is there, but you do not have to use the
async reset template to get controlled initialization at power up.
Constraints can be used, and some synthesis tools are using initial
value specifications to drive it.

I generally have to use an async reset since I usually have
requirements to safe the outputs in response to a external reset
input, even in the absence of a clock, well-behaved or not.

Additionally, GSR is only used for the most common clock domain in the
design. The other clock domains must have a reset synchronized
(deasserting edge only!) to their clock, and must use other means of
distribution.

Andy
 
On Aug 20, 7:53 am, KJ <kkjenni...@sbcglobal.net> wrote:
On Aug 20, 6:00 am, Jonathan Bromley <jonathan.brom...@MYCOMPANY.com
wrote:

On Tue, 19 Aug 2008 14:29:55 -0700 (PDT), rickman wrote:
"it exposes the internal state of the process ("count") as a signal
that is global to the architecture"

What is that a problem?

Encapsulation, and separation of concerns - all the
usual stuff that anyone needs to think about as their
designs (be they hardware, software or mechanical)
get larger.

Hierarchy in VHDL is best expressed at the entity level, not process
or procedure. As the design gets larger and it becomes apparent that
a different (or simply finer grained) breakdown is needed, that should
be accomplished by creating new entities. That's where the
encapsulation and separation of concerns should occur.

Entity/architectures can also generally be reused in some new
application without modification, processes and procedures generally
can not since they usually need the context that is provided by the
entity/architecture.

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.

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.

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

Dynamically-created variables - locals of a function or procedure,
or automatics in Verilog - may require the use of breakpoints.

Again, the use of breakpoints implies that the simulation was
restarted so that one can get visibility into what led up to the bad
thing. This starts to happen when the use of variables and procedures
has clouded things to the point that one can not easily discern what
is going wrong given the available information (which is the entire
'signal' history). Don't get me wrong, I do like variables and
procedures, but whenever possible I'll use a signal instead of a
variable simply for the debug value.

"it splits out the functionality into many processes"

Is that really an issue?

It's not a big deal,

Whew, I was wondering if someone was charging you a fee per process or
something.

except that a process is (to my mind)
a block of stuff that has a life of its own; it's nice for
such blocks to be coherent and decoupled,

Coherent yes, decoupled no. Anything that is decoupled from the rest
of the world is not needed (and a synthesis tool will see to that by
optimizing it away). I realize that this extreme of 'decoupled' is
more decoupled than what you likely had in mind, but my point is that
every process interacts with some input stimulus and provides some
output. It interacts with and is therefore coupled to other things.
What one really wants to have is good interfaces between these hunks
of code (be they multiple processes or multiple entities) rather than
some unachievable decoupling. Personally I prefer Altera's Avalon
specification as a model interface to use, it provides for
handshaking, latency, etc. at a zero (or minimal) logic resource
overhead.

i.e. to be as
far as possible related to one set of concerns and to
be a complete implementation of that set of concerns.
Inevitably in hardware that ideal is unrealizable, but
it's still worth fighting for.

But the reason it's unrealizable is because of what I just mentioned
above regarding interfaces. Given that every useful process will have
some interface to other surrounding code I don't see what the cause is
that you would be 'fighting for'.

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.

Speaking of "blocks", of course the (very under-utilised)
VHDL "block" construct allows you to group a bunch of
processes, and the signals that link them, without
requiring a module (entity) to encapsulate them.

I agree, and would add that the same can also be said for the generate
statement...both quite handy ways to create 'local' signals.



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.

Kevin Jennings
Hierarchy is best expressed wherever you can express it. Decoupling /
information hiding is not an all or nothing affair. Of course, a
completely decoupled/hidden process is an absurdly useless
extrapolation, but there is tremendous value in restricting the scope
of access to information to those areas where it is really needed.
Using variables inside processes allows you to do that, while still
using signals to communicate between processes. Relying solely on the
entity for hierarchy leads to too many files (since most organizations
restrict designs to one entity/architecture per file) to reach the
same level of decoupling that variables in processes give you. A side
benefit of variables is that their definition is located within the
process where they are used, preventing needless scrolling up to the
architecture declarative region and back to the process of interest
while reviewing the code.

Block statements can be used to provide a similar level of hierarchy
(and locality of definition in the file), while preserving the comfort
of signal behavior for those that want it. I think they would be a
good idea for designers to "get their feet wet" in decoupling/hiding
without also having to deal with variables.

Those that wish for less freedom in an HDL are free to limit
themselves to whatever subset of the language they choose, but for
many of us, descriptive styles that allow abstraction above the level
of gates and registers are very useful. Given available optimizations
such as register retiming, etc., carefully crafted circuit
descriptions that attempt to define precise sequences of gates and
registers become useless in the face of the final implementation.
Sure, their clock cycle behavior is retained, but what exactly is that
behavior? I'd rather use a style that describes the behavior in the
first place, since that is the only thing that is sure to be preserved
in the implementation.

Andy
 
KJ wrote:
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.

Modelsim's log -r /* command is a very powerful debug aid...it get
signals, it doesn't pick up variables.
On the other hand log -r /* can slow down the simulations so much,
that it is more reasonable to rerun the simulation with the same
seed values for the testbench, and recreate the situation that was
visible in the regressions. The impact for productivity is even
bigger if the regressions can not be run during the night. Also I
once calculated that dumping all signals for one regression run would
have created about terabyte of data, that puts quite hard load to
fileservers and network.

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.

Dynamically-created variables - locals of a function or procedure,
or automatics in Verilog - may require the use of breakpoints.

Again, the use of breakpoints implies that the simulation was
restarted so that one can get visibility into what led up to the bad
thing. This starts to happen when the use of variables and procedures
Also it might imply that the problem is in testbench, where more
abstract way of programming is usually a good thing. In SW side use
of debugger is normal way of finding problems. I use regulary
breakpoints in testbench side, because complex algorithms are not
always easy to follow without stepping trough them.

Speaking of "blocks", of course the (very under-utilised)
VHDL "block" construct allows you to group a bunch of
processes, and the signals that link them, without
requiring a module (entity) to encapsulate them.

I agree, and would add that the same can also be said for the generate
statement...both quite handy ways to create 'local' signals.
Sometimes complex generates and configurations can generate code
that is almost impossible to read and understand. It is not
always the original coder that has to debug the problems and fix them.
Too clever code usually becomes a problem later on, either it
is hard to fix, or it breaks tools. Many hot and new tools have
quite weak VHDL parser.

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.
It's interesting to see what happens when now SystemVerilog has more
fancy features than VHDL. How much of the market and mindshare will
it capture. Will we see more and more for example designs where the
design is VHDL and the testbench is SV.


--Kim
 
Tricky wrote:
its just a danger synthesisers may not pick it up as such. He cited an
example of an old collegue (at another company) used to use variables
for starage often with less use of signals. This ran him into bother
after synthesis. Is this just old worrys? or was it more likely that
this person was probably just writing bad code?
There have been problems like that in the past. But I have seen designs
that use heavily variables for storage and they have worked just fine
with modern tools. If you are not using retiming current tools are
quite safe with different structures. But with retiming I have seen
some synthesis bugs, and they have been more in the codes that use
heavily variables. But those codes were also relying heavily on
retiming to balance their pipelines, so the code was also much more
heavily modified by the tool.

--Kim
 
rickman wrote:
On Aug 20, 9:45 am, KJ <kkjenni...@sbcglobal.net> wrote:
On Aug 18, 5:23 pm, rickman <gnu...@gmail.com> 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.

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.

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.

--Kim
 
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
 
KJ <kkjennings@sbcglobal.net> writes:

On Aug 20, 6:00 am, Jonathan Bromley <jonathan.brom...@MYCOMPANY.com
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

--
martin.j.thompson@trw.com
TRW Conekt - Consultancy in Engineering, Knowledge and Technology
http://www.conekt.net/electronics.html
 
On Mon, 18 Aug 2008 11:39:42 -0700 (PDT), rickman <gnuarm@gmail.com>
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.

- Brian
 
On Aug 21, 2:52 am, Mike Treseler <miket_trese...@comcast.net> 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
 
On Aug 21, 2:01 am, Kim Enkovaara <kim.enkova...@iki.fi> wrote:
rickman wrote:
On Aug 20, 9:45 am, KJ <kkjenni...@sbcglobal.net> wrote:
On Aug 18, 5:23 pm, rickman <gnu...@gmail.com> 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
 
On Aug 21, 8:32 am, rickman <gnu...@gmail.com> wrote:
On Aug 21, 2:01 am, Kim Enkovaara <kim.enkova...@iki.fi> 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
 
On Aug 21, 7:27 am, rickman <gnu...@gmail.com> wrote:
On Aug 21, 2:52 am, Mike Treseler <miket_trese...@comcast.net> 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
 
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
 
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
 
On Aug 21, 9:35 am, Andy <jonesa...@comcast.net> wrote:
On Aug 21, 7:27 am, rickman <gnu...@gmail.com> wrote:

On Aug 21, 2:52 am, Mike Treseler <miket_trese...@comcast.net> 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
 
On Aug 21, 12:27 pm, Mike Treseler <miket_trese...@comcast.net> 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
 
On Aug 21, 9:19 am, KJ <kkjenni...@sbcglobal.net> wrote:
On Aug 21, 8:32 am, rickman <gnu...@gmail.com> wrote:

On Aug 21, 2:01 am, Kim Enkovaara <kim.enkova...@iki.fi> 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
 
On Aug 21, 9:07 am, Brian Drummond <brian_drumm...@btconnect.com>
wrote:
On Mon, 18 Aug 2008 11:39:42 -0700 (PDT), rickman <gnu...@gmail.com
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
 

Welcome to EDABoard.com

Sponsor

Back
Top