On Nov 20, 2:12 pm, Dave <dhsch...@gmail.com> wrote:
> On Nov 20, 2:51 pm, Andy <jonesa...@comcast.net> wrote:
>
>
>
> > On Nov 19, 2:07 pm, Dave <dhsch...@gmail.com> wrote:
>
> > > On Nov 15, 10:50 pm, "KJ" <kkjenni...@sbcglobal.net> wrote:
>
> > > > "Andy" <jonesa...@comcast.net> wrote in message
>
> > > >news:68c74a06-bdd3-49c8-934a-...
>
> > > > > On Nov 14, 12:31 pm, Mike Treseler <mike_trese...@comcast.net> wrote:
>
> > > > > I use variables for one main reason: they behave like the code reads:
> > > > > they update immediately. Signals turn sequential code into "pseudo-
> > > > > sequential" code, and I don't like that. There, I said it.
>
> > > > OK. Generally I don't like that variables change their meaning (because
> > > > they've been assigned to and update immediately) when they are assigned to
> > > > in several places in a long hunk-o-code with all kinds of paths through it.
> > > > Of course nobody writes such code
My bigger gripe is the lack of history
> > > > though.
>
> > > > >I tend
> > > > > to use source level debuggers and self checking features (assertions)
> > > > > more than waveforms, but that's just the way I do it. I can certainly
> > > > > see that if you rely on waveforms, and want to see past history,
> > > > > variables can be a liability.
>
> > > > Assertions don't tell you the root cause of what is wrong, just that a
> > > > particular bad something has occurred. Many times one can tell simply by
> > > > looking at what assertion failed and quickly deduce the root cause of the
> > > > problem, but many times it's not so simple to see what incorrect logic led
> > > > to the assertion having failed. In any case, the information that one needs
> > > > to debug the failed condition lies in the past (i.e. the simulation history
> > > > up to that point) not in the future so stepping through code or really
> > > > anything other than analysis of the prior state of (possibly) everything in
> > > > the design and testbench is required. Signals, variables and log/trace
> > > > output files are the evidence that you use for that forensic analysis.
> > > > Things that hinder that analysis typically slows down debug. Wave windows
> > > > assist in the forensics as a good analytical tool, for investigating the
> > > > scene of the crime (i.e. the failed assert). The two are complementary in
> > > > that regard.....having said that though, I realize that the beginner will be
> > > > debugging using waves alone (until they recognize the value of asserting
> > > > darn near everything that they can instead).
>
> > > > > The downside of using entities for "information hiding" is that they
> > > > > are an all or nothing solution: once you drop down into another
> > > > > entity, there is NO shared visibility, unless you go completely global
> > > > > which widens the scope too much (and many synthesis tools still don't
> > > > > use anyway).
>
> > > > I didn't mean to imply that if, after initial design creation, the
> > > > realization sets in that some lower level entity has a 'need to know' about
> > > > something and that the interface to that entity couldn't simply be changed
> > > > to include that new signal and now the previously hidden info is known. No
> > > > need to go global.
>
> > > > > As far as "proper design", a state variable should only be accessed
> > > > > and/or updated within a single process (actually, within the case
> > > > > statement that defines the state transitions). To do otherwise makes
> > > > > maintenance more difficult because the effects of changes to the state
> > > > > assignments and transitions are not limited to the state machine.
>
> > > > The downside to that is that the state machine code itself gets bloated and
> > > > hard to maintain because you end up with lots of signal assignments
> > > > intertwined with the various 'case' and 'if' branches typical of a state
> > > > machine. In any case, a state variable is just another signal and is
> > > > deserving of no more or less respect than any other signal or variable in
> > > > the design. Changes to the code on any signal will have repercussions
> > > > downstream, not just changes to state variables.
>
> > > > Maintenance has more to do with readability then it does with dogma about
> > > > scoping rules that apply to 'special' signals like state variables that
> > > > inexplicitly do not apply to other signals.
>
> > > > > So let me clarify: The use of signals for state variables is not poor
> > > > > design per se. The use of a signal for a state variable that is
> > > > > accessible outside the state machine is poor design.
>
> > > > A multiple screen long state machine filled with signal assignments in the
> > > > various branches of the state machine code is a much poorer design (in my
> > > > opinion), since it requires paging back and forth to understand the various
> > > > reasons why something can be set or reset. I'd much rather have a 1000 line
> > > > file where the logic defining any given signal can be viewed and understood
> > > > within a single screen than having to wade through that same file searching
> > > > for all the possible places that the signal might get assigned.
>
> > > > > Like it or not, there is a lot of benefit in the years of software
> > > > > development standards that we can take advantage of to improve our
> > > > > hardware designs. Just remember, somebody (maybe you) will have to
> > > > > maintain that code some day...
>
> > > > Words of wisdom
>
> > > > KJ
>
> > > Does anyone know if there is a reason that declaring signals local to
> > > a process is not allowed? I've always used signals for registers and
> > > variables only for temporary values or to make code more readable, so
> > > I'm used to thinking that way. However, I do like the data-hiding of
> > > variables, and the fact that I don't have to scroll to the top of the
> > > architecture to see their definitions. I realize blocks could give the
> > > same effect, but why not just allow signals local to a process?
>
> > I've often wondered that myself... I don't think there is a good
> > reason for it, and it would probably simplify some optimizations on
> > signals that aren't read outside the same process where they are
> > written during simulation (avoiding a lot of the signal overhead). But
> > I'm pretty sure a lot of simulators already take advantage of that
> > when they find it; this would just make it easier to identify such
> > situations (in addition to the human readability & information hiding
> > benefits)
>
> > Do you prefer using signals for registers because it is easier to
> > recognize a register from a combinatorial value? I quit trying to
> > focus on that, and instead focus on the cycle-cycle behavior, and let
> > the registers fall where they may. If I need to add/subtract a
> > register in a signal path, I add/subtract a behavioral delay (i.e.
> > a[nother] loop through the process). Often that can be accomplished by
> > simply re-ordering statements, without adding anything to the code.
> > With synthesis retiming, the exact placement of registers in source
> > code is becoming less important anyway (not totally unimportant yet!)
>
> > Andy
>
> I guess it's mostly habit. Once you learn to write a certain way for a
> while, it gets hard to change. Since I've started reading these
> forums, I've seen people use variables a lot more than I expected, so
> I'm thinking about using variables more - it's quite a different way
> to think, at least to me. Do you guys know of any good books that
> really show what variables can do in synthesizable code?
No books, but a couple of basic principles:
Look at how synthesis really infers storage (registers or latches):
whenever the execution of the code requires remembering a previous
value in time, storage is implied. In signals, that's easy since
because of postponed updates, every reference to a signal in a clocked
process is from a previous time (one or more clock cycles in the
past). With variables, the same inference principles apply, and boil
down to the fact that a reference to a variable in a clocked process
after it has been updated in that cycle requires no "memory" and thus
no storage or register. Conversely, a reference to a variable that has
NOT already been written in that clock cycle does require memory and
therefore implies storage with a register.
Since a variable can be referenced before and/or after it has been
updated in a given clock cycle, a variable REFERENCE can represent a
registered and/or a combinatorial value. It is important to note that
the variable itself does not represent either register or
combinatorial data, EACH REFERENCE to it does. Also, if the prior
update is conditional (within an if statement, etc.) then any
subsequent reference to the variable is also referring to the
multiplexer structure implied by the conditional if statement. So, it
is possible to have a variable reference that in some clock cycles is
a register (i.e. it was not updated earlier in that clock cycle), and
in other clock cycles is combinatorial: a multiplexer is implied to
select, during each clock cycle, the combinatorial or registered
value.
The bottom line is: the synthesis tool will create a circuit that
behaves the way the circuit simulates. If it needs a register to make
that happen, it will use a register.
Andy