Clock Edge notation

radarman wrote:
After reading the arguments here, <snip> There are just too many times
when I don't want to wait until the next clock for an output to take affect.
Stop being so impatient ;)

Another hard requirement
(that I agree with) is that there should only be one clocked process
per clock. The guy that came up with the requirement predates HDL's in
general - and I'm sure there was a good reason for it at one time.

This struck me as kind of odd. I understand that if there is a hard
requirement to do it this way then you either will do it that way or
seek other employment. I also don't find it hard to believe either
that the reason for the requirement for may predate HDLs and there was
a good reason for it at one time.

What I find odd though is that you agree with it. Based on your other
posts to this group I could see that you could 'accept' that this is
how you have to do it but I guess I'm surprised that you would 'agree
with' something that you don't know what the reasoning is...doesn't
seem like 'radarman' talking.

By the way, if you do find the 'good' reason for having physically only
one clocked process I'd be curious to hear what it is. Although I put
myself in the 'one process' camp my 'one process' tends to be several
physical processes all clocked by the same clock. From a logic
synthesis/simulation perspective those multiple processes are all
logically 'one' process but breaking them up into physically separate
processes I find makes it easier to understand and debug.

KJ
 
Hi Andy et al.,

I am relatively new to VHDL coding and have used the two-process
approach for state machines for all that time. Where can I find a good
reference on the one-process approach or a good example of it? I'm
interested to learn more about it.

Thanks.
 
With variables, you don't have to wait an extra clock in single process
descriptions.

Andy


radarman wrote:
KJ wrote:
"Tommy Thorn" <tommy.thorn@gmail.com> wrote in message
news:1153510009.206861.78040@p79g2000cwp.googlegroups.com...
Andy wrote:
Too bad the author is a proponent of the ancient style of separate
clocked and combinatorial processes in VHDL. He even uses a third
process for registered outputs.

I think he needs to discover what variables can do for you in a clocked
process.

Really? Which of his arguments do you disagree with?

I always thought of the two-process style as being redundant, but after
reading Dr. Chu's argument, I'm revising my thinking. For one thing,
this style makes it much less disruptive to change a Moore output to a
Mealy and vise versa.

My thanks to S.C. for the reference. Good one.


But in practice one doesn't much care if any outputs are 'Mealy' or 'Moore'.
What one has is a function that needs to be implemented within specific area
(or logic resource) constraints and performance (i.e. clock cycle, Tpd, Tsu,
Tco) constraints.

Breaking what can be accomplished in one process into two (or more)
logically equivalent processes should be considered for code clarity which
can aid in support and maintenance of the code during it's lifetime as well
as for potential design reuse (although realistically re-use of any single
process is probably pretty low). Re-use happens more often at the
entity/architecture level, but the 'copy/paste/modify' type of re-use
probably happens more at the process level when it does happen.

Breaking a process into two just to have a combinatorial process to describe
the 'next' state and a separate process to clock that 'next' state into the
'current' state has no particular value when using design support and
maintenance cost as a metric of 'value'. Since the different methods
produce the final end logic there is no function or performance advantage to
either approach. On the other hand, there are definite drawbacks to
implementing combinatorial logic in a VHDL process. Two of these are
- Introduction of 'unintended' latches
- Missing signals in the sensitivity list that result in different
simulation versus synthesis results

Both of these drawbacks have manual methods that can be used to try to
minimize them from happening but the bottom line is that extra effort
(a.k.a.. cost or negative value) must be incurred to do this....all of which
is avoided by simply not using the VHDL process to implement combinatorial
logic (i.e. the 'next' state computation).

So as far as the VHDL language is concerned, there are real costs that will
be incurred every time the two process method is used but no real value
add....or at least that's my 2 cents.....

KJ

After reading the arguments here, I have started using a mixed
approach, but I still use the two process model for state machines and
other complex logic. There are just too many times when I don't want to
wait until the next clock for an output to take affect.

At work, we have a hard requirement (as in, it won't pass a peer
review) to write in the two process model. Another hard requirement
(that I agree with) is that there should only be one clocked process
per clock. The guy that came up with the requirement predates HDL's in
general - and I'm sure there was a good reason for it at one time.

However, for my home projects, I tend to mix the one and two-process
models based on what is most convenient.

Having done so, I don't see that the two-process model is that terribly
inconvenient. I simply place a default condition at the beginning of
the process, and override the default as needed. For most processes,
this adds maybe 1-10 "extra" lines.

Perhaps it's because I was taught in the two-process model, but I find
it easier to understand what is going on when I use it, so anything
that requires me to think, I use a separate combinatorial process for.
Simple logic, like counters, pipeline registers, etc. goes into the
appropriate clocked process.

For me, this mixed approach works pretty well.
 
My impression is that hardware people don't like to write much, and
even if they do, they don't have time to sit down and document all of
the important "big issues" that new people need to learn in order to be
effective.

But if anyone writes a book like this it will fly off the shelves!
Care to estimate the size of the market?

I.e. how much would the author expect to make, given typical publishing contracts?

(I've long wanted to write such a book, but have trouble with the
business case - i.e. persuading my wife. And, of course, I cannot
write it as an employee of Intel.)
 
mcgrigor wrote:

I am relatively new to VHDL coding and have used the two-process
approach for state machines for all that time. Where can I find a good
reference on the one-process approach or a good example of it? I'm
interested to learn more about it.
See the procedure tx_state in the reference design source here:

http://home.comcast.net/~mike_treseler/

-- Mike Treseler
 
Another hard requirement
(that I agree with) is that there should only be one clocked process
per clock. The guy that came up with the requirement predates HDL's in
general - and I'm sure there was a good reason for it at one time.

This struck me as kind of odd. I understand that if there is a hard
requirement to do it this way then you either will do it that way or
seek other employment. I also don't find it hard to believe either
that the reason for the requirement for may predate HDLs and there was
a good reason for it at one time.

What I find odd though is that you agree with it. Based on your other
posts to this group I could see that you could 'accept' that this is
how you have to do it but I guess I'm surprised that you would 'agree
with' something that you don't know what the reasoning is...doesn't
seem like 'radarman' talking.
I've been bitten in the hindquarters with cross-clock domain problems
too many times. I now have one clocked process per clock. While I try
to avoid cross-clock asynchronous resets, occasionally (especially in
CPLD's) there is no other choice.

I find that by doing this, I catch clock domain crossing errors more
easily. For example. On one design, I had a bus interface running on a
fixed clock (32MHz), internal logic on another fixed clock (40MHz), a
state machine that controlled a digital synthesizer (DDS 9858) that ran
on the DDS utility clock (40MHz, but asynchronous to the previous
clock), and a whole other section of code that ran on the clock
generated by the synthesizer (approximately 40MHz, but variable within
a band).

To summarize:
Local bus clock -> 32MHz.
Local bus I/F and control -> 40MHz (fixed)
DDS controller -> 40MHz (frequency locked, but not phase locked to the
previous)
"special logic" -> 38MHz < f < 42MHz from DDS.

Now, in most cases I was able to limit the crossings. There were a few
F40 <-> V40 crossings due to the nature of the design, but I tried to
restrict those to a handful of sentinel signals with strict timing, and
used rate-change FIFO's where timing wasn't critical. To simplify
things a bit, I created two copies of the bus interface - one for the
40MHz fixed, and another for the 40MHz variable.

However, in the actual DDS controller, I had all three clocks in play
at once. My design had to be able to frequency and phase lock the DDS
output frequency to the fixed 40 (which is quite doable, even if the
design to do so "looks" terrible). To make things more fun, it had to
issue the controls to the DDS aligned with the DDS utility clock - so
the state machine ran on that clock domain. Thankfully, the DDS utility
clock was reliably 90 degrees out of phase with the F40 domain, so I
could design a proper clock boundary crossing circuit.

The one time I fooled around with multiple clocked processes and
multiple clock domains, I ended up spending days (weeks?) debugging a
pernicious little problem that took hours of operation to fail. I
accidentally clocked something that was in the fixed 40MHz domain with
the variable 40MHz. It took a long time to debug that problem because
the per-operation error was so small. Unfortunately, even though the
error was only +/- a few nanoseconds worst case, it was cumulative, and
would cause the system to fail eventually.

While I would have been given leave to violate the design guidelines
with that module, given the complexity of the clock domain crossings, I
found it was better to follow them. Eventually, it dawned on me that a
certain register was in the wrong process. By putting all of the
registers for each domain in a single process, I was able to wrap my
head around the problem more easily.

As a result of that experience, I also started adding the clock domain
as a suffix to the signal name in complex designs. It leads to long
names, but it is worth the effort.
 
KJ wrote:


By the way, if you do find the 'good' reason for having physically only
one clocked process I'd be curious to hear what it is.
No signal declarations or direction
conflicts to worry about.
Output register variable values
are assigned directly to out ports.

-- Mike Treseler
 
Mike Treseler wrote:
snip
See the procedure tx_state in the reference design source here:

http://home.comcast.net/~mike_treseler/

-- Mike Treseler
Thanks Mike.

Very interesting.
 
Andy Glew wrote:

Care to estimate the size of the market?
2000-4000 copies over 2 years.
I.e. how much would the author expect to make, given typical publishing contracts?
Maybe $4 per book.

(I've long wanted to write such a book, but have trouble with the
business case
There isn't one.
You would have to do it for love, not money.

And, of course, I cannot
write it as an employee of Intel.
I expect that would be negotiable.
RTL design is hardly proprietary.

-- Mike Treseler
 
Mike Treseler wrote:
KJ wrote:


By the way, if you do find the 'good' reason for having physically only
one clocked process I'd be curious to hear what it is.

No signal declarations or direction
conflicts to worry about.
You have variable declarations instead....not sure what 'direction
conflicts' you're talking about but if it's multiple processes both
'outputting' some signal than not using 'resolved' logic types allows
the compiler to catch that straight out also.

Output register variable values
are assigned directly to out ports.

And this is better (or just different) than output register signals
values being assigned to out ports?

KJ
 
radarman wrote:
Eventually, it dawned on me that a
certain register was in the wrong process. By putting all of the
registers for each domain in a single process, I was able to wrap my
head around the problem more easily.

As a result of that experience, I also started adding the clock domain
as a suffix to the signal name in complex designs. It leads to long
names, but it is worth the effort.
OK, good explanation, I wasn't immediately considering the entities
with several clocks in them. I'd submit though that most of the real
value was in the naming convention of adding the clock domain suffix to
the signal name (which is something that I do as well by the way) and
not so much that they were all physically in one process.

If you agree that the naming convention was probably the more important
of the two then from your description it appears that 'the company'
didn't have signal naming rules in place....and that would've been a
bigger help if it did. In other words, the clock domain suffix
certainly would qualify as one of those 'good' patterns for all to
follow and your problem description is a case for why.

The jury is still out in my mind on the physically one clocked process
requirement, to me it can lead to a lot of scrolling back and forth to
make sure one understands all of the places where signals get assigned.
But I'll also accept that in the multi-clock entities that one needs
to be even more rigid than usual since the tools are of almost no help
in helping to make sure you're crossing domains properly.....and dang,
why is that anyway it's not like it brain surgery.

KJ
 
KJ wrote:

You have variable declarations instead....not sure what 'direction
conflicts' you're talking about but if it's multiple processes both
'outputting' some signal than not using 'resolved' logic types allows
the compiler to catch that straight out also.
True. My point is that keeping track of signal
direction relative to each process is manual
bookkeeping that I don't have to with a single process.

Output register variable values
are assigned directly to out ports.

And this is better (or just different) than output register signals
values being assigned to out ports?
Simpler because *all* of my registers are variables.
There is no need to interpose a signal. Just

my_out_port <= my_out_reg_v;


-- Mike Treseler
 
Andy wrote:
With variables, you don't have to wait an extra clock in single process
descriptions.

With concurrent signal assignments that are outside of the process you
don't have to wait an extra clock either.

KJ
 
Mike Treseler wrote:
KJ wrote:

You have variable declarations instead....not sure what 'direction
conflicts' you're talking about but if it's multiple processes both
'outputting' some signal than not using 'resolved' logic types allows
the compiler to catch that straight out also.

True. My point is that keeping track of signal
direction relative to each process is manual
bookkeeping that I don't have to with a single process.

But if you use an unresolved type you're not doing the bookkeeping
either, the compiler is when it complains about multiple drivers on an
unresolved signal. If you assume that the designer can have a brain
fart and try to drive signal 'XYZ' from two processes then you also
have to accept that the same designer could have two equations for
'XYZ' in the 'one' process. Assume for the moment that one of those
two is correct. If those two equations are in separate processes the
compiler immediately flags it as an error, if they are all in one
process then you've basically priority encoded those two equations.
Since we assumed that the designer had a momentary brain fart
forgetting about the other assignment that already existed, which
method allows you to fix the bug quicker?

Output register variable values
are assigned directly to out ports.

And this is better (or just different) than output register signals
values being assigned to out ports?

Simpler because *all* of my registers are variables.
There is no need to interpose a signal. Just

my_out_port <= my_out_reg_v;


I'll go with just 'different' on this one, it doesn't seem better,
worse or simpler to me since the only reason for that line of code is
because the probably more logically complicated assignment that occurs
to the variable could just as easily have assigned it to the output
signal in the first place. But there are times when even I use
variables inside a clocked process too so I don't really disagree.

KJ
 
Yes, but...

Assuming the signals that those concurrent assignments depend on are
driven from clocked processes, they do not update until after the
clock, which means they are the registered (delayed) values.

Also, see below:

process (clk) is
begin
if rising_edge(clk) then
var := (var - 1) mod var_limit;
out1 <= var = 0; -- registered comparison of combinatorial var
(i.e. var - 1) with 0
end if;
out2 <= var = 0; -- combinatorial comparison of registered var with 0
end process;

Note that both out1 and out2 have the same cycle-accurate behavior.
Note also that if both out1 and out2 exist, Synplify will combine them
and use out1 for both.

Andy

KJ wrote:
Andy wrote:
With variables, you don't have to wait an extra clock in single process
descriptions.

With concurrent signal assignments that are outside of the process you
don't have to wait an extra clock either.

KJ
 
Using variables for the register itself also means that the register
can be read back internally, which you can't do with the output port
signal.

Variable assignment/update overhead during simulation is less than that
of signals.

Using variables for the registers, then a final output signal
assignment from the variable (within the process) removes the need for
a separate combo process or concurrent assignment, and the simulation
overhead involved with that too.

Andy

KJ wrote:
Mike Treseler wrote:
Simpler because *all* of my registers are variables.
There is no need to interpose a signal. Just

my_out_port <= my_out_reg_v;


I'll go with just 'different' on this one, it doesn't seem better,
worse or simpler to me since the only reason for that line of code is
because the probably more logically complicated assignment that occurs
to the variable could just as easily have assigned it to the output
signal in the first place. But there are times when even I use
variables inside a clocked process too so I don't really disagree.

KJ
 
Andy wrote:
Using variables for the register itself also means that the register
can be read back internally, which you can't do with the output port
signal.

We were discussing true outputs signals (i.e. not needed internally).
If the signal is needed internally than the coding effort is identical,
in one case you declare a signal, the other you declare a variable.

Variable assignment/update overhead during simulation is less than that
of signals.

Agreed, I measured something around 10% hit for using signals with some
sample code a while back. Assuming that the actual simulation time
itself is ~10-25% of the total sim/analyze/debug/fix cycle time (the
other 75-90% being analyzing, debugging, fixing) than this speed up
saves you about 1-2.5% of the total amount of time you spend getting a
design working.

Whether or not those numbers are representative of what you see or not,
the point is that the additional amount of test coverage that one gets
is not inversely proportional to actual simulation time.

Using variables for the registers, then a final output signal
assignment from the variable (within the process) removes the need for
a separate combo process or concurrent assignment,
But the coding effort is the same, it's just a question of whether you
put that code inside a process or out in a concurrent assignment.
There's nothing inherently 'pure' or 'better' or anything about whether
everything fits into one process or not. In this particular case
you're comparing code that is darn near equivalent no matter what
metric you choose to grade it against.

and the simulation overhead involved with that too.
Agreed previously.

KJ
 
Andy wrote:
Yes, but...

Assuming the signals that those concurrent assignments depend on are
driven from clocked processes, they do not update until after the
clock, which means they are the registered (delayed) values.
So what? I typically don't care about waiting a delta cycle delay,
when you put them up on a wave window to debug they all happen at the
same time.

<snip>
Note that both out1 and out2 have the same cycle-accurate behavior.
Note also that if both out1 and out2 exist, Synplify will combine them
and use out1 for both.
And this can be written in a functionally equivalent manner using a
process and concurrent assignments and it will synthesize to the exact
same thing....equivalent.

KJ
 
KJ wrote:
Andy wrote:
Using variables for the register itself also means that the register
can be read back internally, which you can't do with the output port
signal.

We were discussing true outputs signals (i.e. not needed internally).
That's not what I was talking about.
I use output registers as working registers as well.

search for serial_out_v in http://home.comcast.net/~mike_treseler/uart.vhd
for an example.

-- Mike Treseler
 
Mike Treseler wrote:
That's not what I was talking about.
I use output registers as working registers as well.
Actually at the time, we were just talking about output registers
specifically.

<Pasting from 4 up in this thread>

** Mike said **
Output register variable values
are assigned directly to out ports.
** KJ said ***
And this is better (or just different) than output register signals
values being assigned to out ports?

<Pasting from 3 up in this thread>

** Mike said **
Simpler because *all* of my registers are variables.
There is no need to interpose a signal. Just

my_out_port <= my_out_reg_v;
** KJ said **

I'll go with just 'different' on this one, it doesn't seem...

----
I think we've beaten this one over the head enough, back to woyk.

KJ
 

Welcome to EDABoard.com

Sponsor

Back
Top