I'd rather switch than fight!

You seem to put a lot of stock in the effortlessness of boilerplate,
yet you prefer a language that is said to reduce the need for
boilerplate.

OK, so you mention that you could write a script to automate all of
that, but to work, it would depend on a specific non-standard, non-
enforceable naming convention. Not to mention this script has yet to
be written and offered to the public, for free or fee. Which means
each of those who would follow your advice must write, test, run and
maintain their own scripts (or maybe even sell it to the rest of us,
if they felt there was a market).

Alas, we have no such scripts. So that would put most users back at
typing out all that boilerplate. Once it is typed, there is no
compiler to check it for you (unlike much of the boilerplate often
attributed to vhdl).

You recommend all of this extra work, rather than writing just one
process, with none of your boilerplate (no additional process, no
additional declarations, no additional assignments, no chances for
latches, no simulation-slowing effects).

What's really silly is how the two-process code model even got
started. The original synthesis tools could not infer registers, so
you had to instantiate them separately from your combinatorial code.
Once the tools progressed, and could infer registers, the least impact
to the existing coding style (and tools) was simply to replace the
code that instantiated registers with code that inferred them, still
separating that code from the logic code.

Finally, someone (God bless them!) figured out how to do both logic
and registers from one process with less code, boilerplate or not.

For all your staunch support of this archaic coding style, we still
have not seen any examples of why a single process style did not work
for you. Instead of telling me why the boilerplate's not as bad as I
think it is, tell me why it is better than no boilerplate in the first
place.

Andy
 
(With apologies to Jan, I accidently emailed this first time to him instead of
posting... )


On Apr 22, 10:08 am, Jan Decaluwe <j...@jandecaluwe.com> wrote:
I suggest you try your coding style with my examples. You have the
spec and test vectors. If you find your code much clearer, I don't
have
a case (with you) to argue further. Otherwise, you'll remember me
when you start applying this technique in your designs :)

Jan
Ok, coming in late. I'm a two always block designer. And I use
"variables". For me, it's an issue of how far away from the hardware
do you want to be.

I've done the block entirely in my coding style including
parameterizing the counter width, and naming conventions
(not simulated):

module jc2
#(
parameter WIDTH = 4;
)
(
input wire clk_i,
input wire goleft_i,
input wire goright_i,
input wire stop_i,
output reg [ WIDTH - 1 : 0 ] q_o
);

reg [ WIDTH - 1 : 0 ] next_q;
reg dir, next_dir;
reg run, next_run;
always @( posedge clk )
begin
q_o <= next_q;
dir <= next_dir;
run <= next_run;
end

always @*
begin
next_q = q_o;
next_dir = dir;
next_run = run;

if( goright_i )
begin
next_dir = 1'b0;
next_run = 1'b1;
end
else if( goleft_i )
begin
next_dir = 1'b1;
next_run = 1'b1;
end
if( stop_i )
next_run = 1'b0;

if( next_run )
begin
if( ~next_dir )
next_q = { ~q_o[ 0 ], q_o } >> 1;
else
next_q = { q_o, ~q_o[ WIDTH - 1 ] };
end
end
endmodule

Not much bigger than what's on your website for the myhdl code. Yes,
the top always block for the registers is overhead (above myhdl), but
I've got text editor macros to do that. Same for the default assign
of the next_* register to set my initial decode (and coincidentally
always prevent latches). The initial decode in this case is a
simple "stay in current state" but it doesn't have to be.

The benefit, to me, it's clearer. I know what's registers, what's
combinational. I also know that by using the "next_run", and
"next_dir" variables near the end of that combinational block
- instead of the state registers "run" and "dir" - I'm adding more
decode - I may have a critical path issue (Not likely in this trivial
example, but with large decodes...)

It comes down to what designers prefer. I like to "see in my head"
the logic I'm generating. The style above works for me quite well.
I get all the benefits that you tout about using "variables".
Others obviously wish to be more concise and use one always block.
They're allowed to. It's all a designers style.

Regards,

Mark
 
On Apr 23, 2:09 pm, Jonathan Bromley <s...@oxfordbromley.plus.com>
wrote:
If you have had even half an eye on comp.lang.verilog
these past few years you will have seen a number of
posts clearly pointing out the very serious flaws in
Cliff's otherwise rather useful paper.  In particular,
the "guideline" (=myth) about not using blocking
assignments in a clocked always block was long
ago exposed for the nonsense it is.
Well, I just did a search, and found some mild disagreements, but
nothing that I would consider a "debunking." Perhaps you could point
me to such?

FWIW, I independently learned several of the lessons in Cliff's paper,
so I find it handy to explain these lessons to others. So I really
would be interested in a valid counterpoint, but I honestly didn't see
it.

Regards,
Pat
 
On Apr 23, 1:26 pm, Andy <jonesa...@comcast.net> wrote:
You seem to put a lot of stock in the effortlessness of boilerplate,
yet you prefer a language that is said to reduce the need for
boilerplate.
Not all boilerplate is created equal. In particular, some boilerplate
is, not only easy to glance at and understand, but also, and more
important, easy to code from first principles without knowing arcane
corners of the language your are coding in.

OK, so you mention that you could write a script to automate all of
that, but to work, it would depend on a specific non-standard, non-
enforceable naming convention. Not to mention this script has yet to
be written and offered to the public, for free or fee. Which means
each of those who would follow your advice must write, test, run and
maintain their own scripts (or maybe even sell it to the rest of us,
if they felt there was a market).
That's a good point. I have some languishing tools for this (because
the boilerplate is never quite bad enough to work on the tools some
more) that I should clean up and publish.

Alas, we have no such scripts. So that would put most users back at
typing out all that boilerplate. Once it is typed, there is no
compiler to check it for you (unlike much of the boilerplate often
attributed to vhdl).
Well, actually, the stock verilog tools do a pretty darn good job
these days.

What's really silly is how the two-process code model even got
started. The original synthesis tools could not infer registers, so
you had to instantiate them separately from your combinatorial code.
Once the tools progressed, and could infer registers, the least impact
to the existing coding style (and tools) was simply to replace the
code that instantiated registers with code that inferred them, still
separating that code from the logic code.
That may well be. Nonetheless, many people found the two process
method better, even before 'always @*' or the new systemverilog
'always_comb', to the point where they maintained ungodly long
sensitivity lists. Are you suggesting that none of those people were
reflective enough to try to figure out if that was the best way (for
them) to code?

Finally, someone (God bless them!) figured out how to do both logic
and registers from one process with less code, boilerplate or not.
Yes, and the most significant downside to this is that the access to
the 'before clock' and 'after clock' versions of the same signal is
implicit, and in fact, in some cases (e.g. if you use blocking
assignments) you have access to more than two different signals within
a process, all with the same name. There is no question that in many
cases this is not an issue and the one process model will work fine.
But I think most who do serious coding with the 'one process' model
will, at least occasionally, wind up having two processes (either a
separate combinatorial process, or two interrelated sequential
processes) to cope with not having an explicit delineation of 'before
clock' and 'after clock'.

At the end of the day, it is certainly desirable to have something
that looks more like the 'one process' model, but that gives explicit
access to 'previous state' and 'next state', so that complicated
combinatorial logic with interrelated variables can always be
expressed inside the same process without resorting to weird code
ordering that is done just to make sure that the synthesizer and
simulator will create the structures you want.

For all your staunch support of this archaic coding style, we still
have not seen any examples of why a single process style did not work
for you. Instead of telling me why the boilerplate's not as bad as I
think it is, tell me why it is better than no boilerplate in the first
place.
A paper I have mentioned in other posts,
http://www.sunburst-design.com/papers/CummingsSNUG2000SJ_NBA.pdf gives
some good examples why the general rule of never having blocking
assignments in sequential blocks is a good practice. I have seen some
dismiss this paper here, but haven't seen a technical analysis about
why it's wrong. The paper itself speaks to my own prior experience,
and I also feel that related variables should be processed in the same
block. When I put this preference together with the guidelines from
the paper, it turns out that a reliable, general way to achieve good
results without thinking about it too hard is to use the two process
model.

But, if you can tell me that you *always* manage to put *all* related
variables in the same sequential block, and *never* get confused about
it (and never confuse any co-workers), then, as with KJ and Bromley
and some others, you have no reason to consider the two process
model. OTOH, if you sometimes get confused, or have easily confused
co-workers, and/or find yourself using multiple sequential processes
to model variables where multiple processes have references to
variables in other processes, then you might want to consider whether
slicing related functionality into processes in this fashion is really
better than slicing the processes in a manner where you keep all the
related functional variables together in a single combinatorial
process, and simply extract out the registers into a very-well
understood model.

At the end of the day, I am willing to concede that the two process
model is, at least partly, a mental crutch. Am I a mental cripple?
In some respects, almost certainly. But on the off-chance that I am
not the only one, I tolerate a certain amount of abuse here in order
to explain to others who may also be easily confused that there are
other coding styles than the single process model.

I will also concede that the single process model can be beefed up
with things like tasks or functions (similar to what Mike Treseler has
done) to overcome some of the shortcomings. However, personally, I
don't really find that to be any better than putting combinatorial
stuff in a separate process.

Regards,
Pat
 
On Apr 23, 2:09 pm, Jonathan Bromley
You have the freedom to choose your coding
style, as we all do.  You do yourself no favours
by citing flawed "authority" as discrediting
a style that you dislike.
BTW, I wasn't trying to cite "authority." I was trying to cite a
paper which I've actually read and have no current reason to disagree
with. You claim it's been debunked -- care to present a technical
citation for such a claim?

Regards,
Pat
 
On Apr 23, 2:09 pm, Jonathan Bromley <s...@oxfordbromley.plus.com>
wrote:

If you have had even half an eye on comp.lang.verilog
these past few years you will have seen a number of
posts clearly pointing out the very serious flaws in
Cliff's otherwise rather useful paper.  In particular,
the "guideline" (=myth) about not using blocking
assignments in a clocked always block was long
ago exposed for the nonsense it is.
One last note: In researching this, I found a posting by you with
rules and recommendations that I cannot disagree with:
http://groups.google.com/group/comp.lang.verilog/msg/a87ba28b6d68ecc8

I will note that, if faithfully followed, the two process model can
make it very easy to insure that none of these rules or guidelines are
broken. Finally, as I have posted elsewhere, these rules combined
with my personal preference to always update related variables inside
the same always block, sometimes make it difficult to *not* use the
two process model.

Regards,
Pat
 
On Apr 23, 11:27 pm, gtw...@sonic.net (Mark Curry) wrote:


Ok, coming in late.  I'm a two always block designer.  And I use
"variables".  For me, it's an issue of how far away from the hardware
do you want to be.

I've done the block entirely in my coding style including
parameterizing the counter width, and naming conventions


It comes down to what designers prefer.  I like to "see in my head"
the logic I'm generating.  The style above works for me quite well.  
I get all the benefits that you tout about using "variables".
Others obviously wish to be more concise and use one always block.
They're allowed to.   It's all a designers style.
Thanks for going through the effort of coding this up. As I said, if
you really think this is clearer, I don't have a case to argue,
although as you will expect I disagree.

My original concern about raising the abstraction level still stands
however. I agree that your style is closer to hardware; you will
probably agree mine is at a slightly higher level of abstraction. So
how are we supposed to raise the abstraction level significantly
(something many clever people claim is urgently required) if we cannot
even take a small step that is available today?

Best regards,

Jan
 
On Apr 23, 5:04 pm, Jan Decaluwe <j...@jandecaluwe.com> wrote:
My original concern about raising the abstraction level still stands
however. I agree that your style is closer to hardware; you will
probably agree mine is at a slightly higher level of abstraction. So
how are we supposed to raise the abstraction level significantly
(something many clever people claim is urgently required) if we cannot
even take a small step that is available today?
Well, it's hard for me to know what you are looking for in "raising
the abstraction level" when you showed the code this way. In my
opinion, coding run/stop and direction separately unnecessarily lowers
the abstraction level. I haven't given the actual design too much
thought, but I dashed out how I think I would approach this. I
haven't simulated or synthesized it, but I am confident that any bugs
in it would be quite easy to wring out. Also, all except the last few
lines are, again, what I personally consider "boilerplate" which
requires near-enough zero thought, so I don't see that they affect the
abstraction level too much. (But I would like to be able to get rid of
them, make no mistake!)

Note that this violates my preference not to use 'next_xxx' on the rhs
in one instance (but doesn't violate any of the underlying rules laid
out by Cliff Cummings), but given the choice between an extra variable
and this minor infraction (where it can be easily seen that next_state
is never used until all potential assignments to it have occurred), I
would probably code it as I have shown.

module johnson (
clk,
reset_n,
goLeft_n,
goRight_n,
stop_n,
q
);

parameter COUNTER_WIDTH = 4;
localparam COUNTER_TOP = COUNTER_WIDTH - 1;

localparam
STOP[1:0] = 2'b00,
RUNRIGHT[1:0] = 2'b01,
RUNLEFT[1:0] = 2'b10;

input clk;
input reset_n;
input goLeft_n;
input goRight_n;
input stop_n;
output [COUNTER_TOP:0] q;

reg [COUNTER_TOP:0] q, next_q;
reg [1:0] state, next_state;

always @(posedge clk or negedge reset_n)
if (!reset_n) begin
q <= 0;
state <= STOP;
end else begin
q <= next_q;
state <= next_state;
end

always @* begin
next_state = state;
next_q = q;

casez ({stop_n, goRight_n, goLeft_n})
3'b0??: next_state = STOP;
3'b10?: next_state = RUNRIGHT;
3'b110: next_state = RUNLEFT;
endcase

case (next_state)
RUNLEFT: next_q = {q, !q[COUNTER_TOP]};
RUNRIGHT: next_q = {!q[0], q[COUNTER_TOP:1]};
endcase
end

endmodule

BTW, if I read your code right, the casez above should match its
behavior. Personally, based on the description I read of the problem
(and if my probing of the customer indicated he didn't really care
about some of the edge conditions, because, for example, they
shouldn't occur), my preferred coding of this would probably be more
like:

next_state = STOP;

...

case ({stop_n, goRight_n, goLeft_n})
3'b111: next_state = state;
3'b101: next_state = RUNRIGHT;
3'b110: next_state = RUNLEFT;
endcase

Note also that, if all the variables are assigned a default next state
(which could be their previous state, or a constant, or an equation)
before any case statements or if/else statements, it is extremely easy
to verify, either manually or mechanically, that no latches have been
introduced.

It would be nice to get away from the boilerplate, and one of these
days I would like to get around to making something that would
reliably create and re-create the entire verilog file from
(essentially) the last few lines, maybe coded in a slightly different
style. I think it is doable.

Regards,
Pat
 
On Fri, 23 Apr 2010 20:09:45 +0100, Jonathan Bromley
<spam@oxfordbromley.plus.com> wrote:

On Fri, 23 Apr 2010 09:25:50 -0700 (PDT), Patrick Maupin wrote:

In any case, I posted elsewhere in this thread a
pointer to Cliff Cumming's paper on blocking vs non-blocking
assignments. I assume you've been studiously avoiding that for
plausible deniability

Very droll.

If you have had even half an eye on comp.lang.verilog
these past few years you will have seen a number of
posts clearly pointing out the very serious flaws in
Cliff's otherwise rather useful paper. In particular,
the "guideline" (=myth) about not using blocking
assignments in a clocked always block was long
ago exposed for the nonsense it is.

I think you're being overly harsh about this issue. The paper in
question is almost 10 years old and synthesis tools came along way
since then. Also one has to take the guideline within the context it
has been defined.
Here is the main justification stated in the paper: "A problem with
blocking assignments occurs when the RHS variable of one assignment in
one procedural block is also the LHS variable of another assignment in
another procedural block and both equations are scheduled to execute
in the same simulation time step, such as on the same clock edge. If
blocking assignments are not properly ordered, a race condition can
occur. When blocking assignments are scheduled to execute in the same
time step, the order execution is unknown."

If one considers that the guidelines are usually there for novices I
don't think it's too much to say blocking assignments should not be
used for sequential logic. You have to keep in mind that the use
you're advocating is only applicable for regs which are local to the
always block where no other always block can get at them. So the
appropriate use of blocking statements in a clocked always block comes
with a pretty strict constraint. As the guideline, as stated, has no
constraints it should be considered more than half valuable.
--
Muzaffer Kal

DSPIA INC.
ASIC/FPGA Design Services

http://www.dspia.com
 
On Apr 23, 12:25 pm, Patrick Maupin <pmau...@gmail.com> wrote:
On Apr 23, 8:12 am, KJ <kkjenni...@sbcglobal.net> wrote:

The two process people generally do fall back on excuses about being
misunderstood.

Well, I'm not going to generalize about "one process people" but at
least some of them are supercilious bastards who think that anybody
who doesn't do things their way is an idiot.
Name calling now...sigh...

Hmmm...so you prefer to take what you admit as unnecessary
chances....fair enough, that implies though that you expect some
actual benefit from that decision...but are probably unable to come up
with an actual example demonstrating that benefit.

Well, I haven't used the single process style in many years, so no, I
can't point you directly to the issues I had that led me to switch.
The implication in your earlier post was that you could...perhaps in
the future you should consider not stating things that you can't
actually back up in some fashion since at least in this sub-thread
that inability has just led you to poor word choices.

But I have helped others to switch over they years, and they have all
been grateful.
OK

In any case, I posted elsewhere in this thread a
pointer to Cliff Cumming's paper on blocking vs non-blocking
assignments. I assume you've been studiously avoiding that for
plausible deniability, so here it is: http://www.sunburst-design.com/papers/CummingsSNUG2000SJ_NBA.pdf
Assuming something about other people is almost always a mistake.
I've read Cummings' post before, but not being a Verilog guy and the
issues he covers being very language specific it wasn't relevant to me
in VHDL.

<snip some Verilog commentary>
You can concentrate all your hard thinking on
the problem at hand, in the non-boilerplate code in the combinatorial
process.
VHDL using clocked processes and concurrent assignments avoids all
boilerplate that is not checked by the compiler. There is no
boilerplate executable design specific code at all.

but I could have some other hard to find logic problems, which
I *have* had in the past).

Ahhh....one of those examples...now what sort of 'hard to find' logic
problem would you like to offer up to to the group to actually
demonstrate that two processes are better than one? I'm willing to
listen, but I'll warn that you that every time in the past that this
debate pops up, the two process people are unable to coherently
describe anything other than vague generalities as you've done
here...so here is your opportunity to present a clear example
describing a 'hard to find' logic problem that is easier to find when
coded with two processes. The clocked process folks (i.e. the one
process camp) have in the past presented actual examples to back their
claims, Googling for 'two process' in the groups should provide some
good cases.

That's because you're *not* really willing to listen.
Because you didn't say anything relevant to the point of presenting an
example.

If you were,
you would have heard, from me, anyway, loud and clear, that it's not
really about the *language constructs*, it's about how much people can
hold in their heads at a single time.
I agree and will add to that it's also about how much can fit on a
screen so that it can be digested and kept in one's head...but I'll
also add again that your response here in no way is directed to what I
had asked which was "now what sort of 'hard to find' logic problem
would you like to offer up...". Perhaps you should consider trying to
make your repliess a bit more on topic rather than going on a tangent.

The two process method reduces
the need for that, so even if I presented an example where it helped
me in my thinking, you would just superciliously explain how any idiot
should have seen the error in the one process method, so it doesn't
prove anything.
Again you wrongly assume a particular reaction from me and then use
that incorrect assumption to provide yourself some personal
justification for why you do not present anything to back up your
claims...I'll leave it at that.

Since you're the smartest asshole in the world, the
two process method couldn't possibly offer any benefits you would be
interested in, so just forget about it.
More name calling and explicitly at me this time...you're
distinguishing yourself in a rather unflattering manner

- Producing less maintainable code (two process will always physically
separate related things based only on whether the logic signal is a
'register' or not)

See, this is another place where you haven't listened. What don't you
understand about 'boilerplate'?
Apparently you've got your responses mixed up because nowhere in our
little back and forth did we get into 'boilerplate' until you brought
it up here, you and Andy were bantering boilerplate, not you and
I...so, now who's not listening??

It's a tiny bit of overhead, not
really part of what you need to worry about in maintenance. It is
easily checked and even automated.
Also completely avoidable (at least in VHDL).

BTW, this is the last
post I'm going to reply to you on
OK, probably for the best. I won't wait for the apology for the name
calling then.

so feel free to have fun with more
piling on.
Asking for an example, is not demand for proof and certainly can't be
considered to be 'piling on'.

Kevin Jennings
 
On Apr 23, 10:03 pm, KJ <kkjenni...@sbcglobal.net> wrote:

Assuming something about other people is almost always a mistake.
I've read Cummings' post before, but not being a Verilog guy and the
issues he covers being very language specific it wasn't relevant to me
in VHDL.
Well, I will apologize about one thing. In some of my earlier posts,
I restricted my replies to not include comp.lang.vhdl, but I didn't on
this sub-thread, so this "leaked" into that newsgroup without me
paying adequate attention. So I apologize for assuming that you knew
verilog and that you had seen my other posts that did not make it into
comp.lang.vhdl.

Verilog was the framing point for the one process/two process
discussions I was having. The Cummings paper adequately describes
several of the bad things that can happen in Verilog if you aren't
paying close attention (that the two process model can help
alleviate), so that is why I did not feel compelled to provide a
similar example.

As far as the rest of it goes, you had the chance in multiple posts to
step back and say to yourself that you must be misunderstanding me,
but in all cases you chose to assume I was a complete idiot. This is
certainly a distinct possibility (perhaps even a probability), but the
assumption of it starting out did not lead to a fruitful discussion,
and, in fact, it was only in your reply to my name-calling that you
have given me the chance to see how we are talking past each other.

Regards,
Pat
 
On Apr 23, 10:43 pm, Muzaffer Kal <k...@dspia.com> wrote:

I think you're being overly harsh about this issue. The paper in
question is almost 10 years old and synthesis tools came along way
since then. Also one has to take the guideline within the context it
has been defined.
FWIW, the latest rev of the paper (1.3) was September of last year.

Regards,
Pat
 
On Apr 24, 3:26 am, Patrick Maupin <pmau...@gmail.com> wrote:

Well, it's hard for me to know what you are looking for in "raising
the abstraction level" when you showed the code this way.  In my
opinion, coding run/stop and direction separately unnecessarily lowers
the abstraction level.
'run' and 'dir' come from the original Xilinx examples, and play the
crucial role in the story. In particular, the mismatch between the
Xilinx VHDL and verilog versions is due to different assignment types
to these variables. You will understand that I treat them as a given
in my article that tries to shed a light on the issues.

Note that this violates my preference not to use 'next_xxx' on the rhs
in one instance (but doesn't violate any of the underlying rules laid
out by Cliff Cummings), but given the choice between an extra variable
and this minor infraction (where it can be easily seen that next_state
is never used until all potential assignments to it have occurred), I
would probably code it as I have shown.
Thanks for your coding efforts.

These are the kind of considerations that I'm trying to put on the
agenda, translated to your closer-to-hardware coding style. I note
that you conclude, quite appropriately, that the best option here is
to depart from your preferred style. In effect, what you are doing is
making more effective use of variable semantics as offered by the HDL.

Jan
 
Chris Higgs <chiggs.99@googlemail.com> writes:

You can only use sequential processes and make it impossible to infer
a latch but lose the ability to use a combinatorially derived signal.
Alternatively you can use a two-process technique which allows
intermediate/derived signals to be used but accept the risk that bad
code will introduce latches.
Or you can use a single sequential process with variables to infer
both combinatorial logic and flip-flops, which both avoids latches and
allows the ability to use a combinatorially derived "signal" (in the
non-VHDL sense of the word).

Cheers,
Martin

--
martin.j.thompson@trw.com
TRW Conekt - Consultancy in Engineering, Knowledge and Technology
http://www.conekt.net/electronics.html
 
Cliff's paper is about avoiding race conditions. However, in vhdl
"blocking assignements" (to unshared variables) are limited to local
process/subprogram scope anyway, so you never have problems with race
conditions with them. That is why it is safe and even beneficial to
use blocking assignments (to unshared variables) in VHDL clocked
processes. Combine that with the flexibility afforded in describing
both combinatorial and sequential logic in the same process, and it
makes for an extremely powerful, yet safe concept. While some may
struggle with identifying where the registers are located in relation
to the combinatorial logic, understanding the cycle-based behavior is
more intuitive, since the code "reads and executes like SW". Given the
increasing use of retiming optimizations, knowing where registers are
located in your RTL is rapidly becoming useless anyway.

For the remaining < 1% of the time when I need an in-to-out
combinatorial logic path through a module/entity, I'll go ahead and
use a combinatorial process (implied by a concurrent assignment or
otherwise). That doesn't mean I'm going to throw away the benefits of
using only clocked processes for the other > 99%, just for purity's
sake.

Andy
 
On Apr 26, 7:15 pm, Andy <jonesa...@comcast.net> wrote:
Cliff's paper is about avoiding race conditions. However, in vhdl
"blocking assignements" (to unshared variables) are limited to local
process/subprogram scope anyway, so you never have problems with race
conditions with them. That is why it is safe and even beneficial to
use blocking assignments (to unshared variables) in VHDL clocked
processes. Combine that with the flexibility afforded in describing
both combinatorial and sequential logic in the same process, and it
makes for an extremely powerful, yet safe concept. While some may
struggle with identifying where the registers are located in relation
to the combinatorial logic, understanding the cycle-based behavior is
more intuitive, since the code "reads and executes like SW". Given the
increasing use of retiming optimizations, knowing where registers are
located in your RTL is rapidly becoming useless anyway.

For the remaining < 1% of the time when I need an in-to-out
combinatorial logic path through a module/entity, I'll go ahead and
use a combinatorial process (implied by a concurrent assignment or
otherwise). That doesn't mean I'm going to throw away the benefits of
using only clocked processes for the other > 99%, just for purity's
sake.
Yes, the two process model probably isn't nearly as useful in VHDL.

As others have been quick to point out, you don't need a combinatorial
process in verilog either, but then you have to be careful about
blocking vs. non-blocking, not using variables which have blocking
assignments to them from other processes, etc. The two process model
is simply an organizing principle that provides a separation of
concerns and simplifies the rules a bit, making it easier to reason
about the code. Extremely simple code doesn't gain anything from
using this model, but a lot of real-world code does.

Regards,
Pat
 
On Mon, 26 Apr 2010 18:26:25 -0700 (PDT), Patrick Maupin
<pmaupin@gmail.com> wrote:

On Apr 26, 7:15 pm, Andy <jonesa...@comcast.net> wrote:
Cliff's paper is about avoiding race conditions. However, in vhdl
"blocking assignements" (to unshared variables) are limited to local
process/subprogram scope anyway, so you never have problems with race
conditions with them. That is why it is safe and even beneficial to
use blocking assignments (to unshared variables) in VHDL clocked
processes.

Yes, the two process model probably isn't nearly as useful in VHDL.

As others have been quick to point out, you don't need a combinatorial
process in verilog either, but then you have to be careful about
blocking vs. non-blocking, not using variables which have blocking
assignments to them from other processes, etc. The two process model
is simply an organizing principle that provides a separation of
concerns and simplifies the rules a bit, making it easier to reason
about the code. Extremely simple code doesn't gain anything from
using this model, but a lot of real-world code does.
I have to wonder if *that* is the reason the two-process model refuses
to die in VHDL textbooks, tutorials, and example designs worldwide.

Perhaps too many educators focus on comparing the languages, showing how
the same thing is done *the same way* in both languages.

I would prefer to see each language shown off at its best.

Then VHDL could be illustrated with the (much less verbose) single
process model, functions and procedures to raise the abstraction level
and simplify the main process, and proper use of the type system to help
rather than frustrate the user.

(e.g. recently here, there was an example where someone frustrated
himself by using a type with integer semantics when he really wanted a
type with modular semantics, so he had to code all the wrap-arounds by
hand. Easy pitfall for someone used to C which doesn't have any types
with integer semantics.)

Likewise best practice in Verilog could be illustrated.
(I have no idea what that is; hearsay suggests it would include avoiding
races, avoiding problems with signed arithmetic, implicit declarations
and so on. But Verilog must have real strengths too)

- Brian
 
On Apr 27, 6:05 am, Brian Drummond <brian_drumm...@btconnect.com>
wrote:
On Mon, 26 Apr 2010 18:26:25 -0700 (PDT), Patrick Maupin



pmau...@gmail.com> wrote:
On Apr 26, 7:15 pm, Andy <jonesa...@comcast.net> wrote:
Cliff's paper is about avoiding race conditions. However, in vhdl
"blocking assignements" (to unshared variables) are limited to local
process/subprogram scope anyway, so you never have problems with race
conditions with them. That is why it is safe and even beneficial to
use blocking assignments (to unshared variables) in VHDL clocked
processes.

Yes, the two process model probably isn't nearly as useful in VHDL.

As others have been quick to point out, you don't need a combinatorial
process in verilog either, but then you have to be careful about
blocking vs. non-blocking, not using variables which have blocking
assignments to them from other processes, etc.  The two process model
is simply an organizing principle that provides a separation of
concerns and simplifies the rules a bit, making it easier to reason
about the code.  Extremely simple code doesn't gain anything from
using this model, but a lot of real-world code does.

I have to wonder if *that* is the reason the two-process model refuses
to die in VHDL textbooks, tutorials, and example designs worldwide.

Perhaps too many educators focus on comparing the languages, showing how
the same thing is done *the same way* in both languages.

I would prefer to see each language shown off at its best.

Then VHDL could be illustrated with the (much less verbose) single
process model, functions and procedures to raise the abstraction level
and simplify the main process, and proper use of the type system to help
rather than frustrate the user.

(e.g. recently here, there was an example where someone frustrated
himself by using a type with integer semantics when he really wanted a
type with modular semantics, so he had to code all the wrap-arounds by
hand. Easy pitfall for someone used to C which doesn't have any types
with integer semantics.)

Likewise best practice in Verilog could be illustrated.
(I have no idea what that is; hearsay suggests it would include avoiding
races, avoiding problems with signed arithmetic, implicit declarations
and so on. But Verilog must have real strengths too)

- Brian
I don't agree that the two process model is inherently less
desirable. Or maybe I should say that I don't think describing
combinatorial logic outside of clocked processes is inherently less
desirable. I seldom put a lot of combinatorial logic in processes,
clocked or unclocked, mainly because the structures in processes and
combinatorial logic are rather weighty (a synonym for verbose I
guess). But it always depends on the logic. Lacking the conditional
expression, VHDL concurrent logic can be a PITB to write complex
expressions in a clear manner. This means sometimes I put
combinatorial in unclocked processes because it is more clear. Simple
logic goes in with the clocked process, but when possible, I put
combinatorial logic in concurrent statements.

A foolish consistency is the hobgoblin of little minds, but there are
times when consistency is a good thing in engineering, other times
not. I guess I'm consistently inconsistent.

Rick
 
On Tue, 27 Apr 2010 15:56:57 -0700 (PDT), rickman <gnuarm@gmail.com> wrote:

On Apr 27, 6:05 am, Brian Drummond <brian_drumm...@btconnect.com
wrote:

I don't agree that the two process model is inherently less
desirable. Or maybe I should say that I don't think describing
combinatorial logic outside of clocked processes is inherently less
desirable.
Where there are combinatorial outputs to be described, I agree, I'll describe
them outside the main process.

But I can't remember the last time I had one so complex it needed a process of
its own.

I seldom put a lot of combinatorial logic in processes,
clocked or unclocked, mainly because the structures in processes and
combinatorial logic are rather weighty (a synonym for verbose I
guess). But it always depends on the logic. Lacking the conditional
expression, VHDL concurrent logic can be a PITB to write complex
expressions in a clear manner. This means sometimes I put
combinatorial in unclocked processes because it is more clear. Simple
logic goes in with the clocked process, but when possible, I put
combinatorial logic in concurrent statements.
I think you are referring to the ?: conditional operator inherited from C?

I just use VHDL's conditional signal assignments for that purpose. As it's
purely combinational, I have never found the need for an equivalent that I can
use inside a process.

I eventually figured out what I heartily detest about that (?:) - it's the ONE
construct across all the languages I've encountered that expects the list of
choices in descending order.

(And does so implicitly as opposed to explicitly, with a "downto" or "step -1"
or "when true else..." or some visible indication that it's doing something
quaint)

If VHDL is to adopt a conditional operator I hope it can do better than that!
Something less surprising, and generalisable to other discrete types or at least
other enums.

If you are going to allow
---------------------------------
Signal Flag : Boolean := True;
Signal Int_val : Integer;

Int_val <= Flag?1:0;
---------------------------------
then you must surely allow similar expressions with other enumerations,
for instance:
---------------------------------
Type NTSC_Color is (red, green, blue);
Signal Channel_Color : NTSC_Color;
Signal Channel_Gain : real;

Channel_Gain <= Channel_Color ? 0.11 : 0.55 : 0.34;
-- nice and compact, but descending order to remain compatible with Boolean
---------------------------------

Now I believe that ascending order, like every other positional list in the
language (port lists, argument lists, etc), would be less surprising:

Channel_Gain <= Channel_Color ? 0.34 : 0.55 : 0.11;

There would of course be an associative form of the expression
Channel_Gain <= Channel_Color ? red =>0.34 : green =>0.55 : blue=>0.11;
to make the bugs harder to bury.

In this context, is anyone still happy with the C-compatible version?

However...

in today's VHDL, if I ever needed ?: I would resort to a trivial function, and
replace

Int_val <= Flag?1:0;
with
Int_val <= cond(Flag,1,0);
or even
Int_val <= cond( test=>Flag, T=>1, F=>0 );

YMMV but for the sake of keeping the language relatively free of warts, I don't
mind typing six extra characters.

It's precisely that wart-free-ness that lets you extend it (e.g. by adding
functions) in simple ways that actually work, instead of frustrating you.

And it's precisely the remaining warts that limit the ability to extend it
further. For example, the closed set of operators (a wart shared with most
not-quite-object-oriented languages like C++) stops you naming the
above function "?:" and writing
Int_val <= "?:"( Flag,1, 0 );
to look that little bit more like Verilog or C.

Or a better example: if you allowed types as generics, as Ada does, you could
write the "?:" function once and use it to return different types. (Newer
versions of C++ have this, as the template).

A foolish consistency is the hobgoblin of little minds, but there are
times when consistency is a good thing in engineering, other times
not. I guess I'm consistently inconsistent.
Oh I'm inconsistent too, just not consistently so.

I like "consistently inconsistent" - I suspect it would make the best
description of the underlying design principles of C.
(I don't know Verilog at all well, so won't extend the same courtesy to it!)

- Brian
 
On 28/04/2010 11:56, Brian Drummond wrote:
On Tue, 27 Apr 2010 15:56:57 -0700 (PDT), rickman<gnuarm@gmail.com> wrote:

On Apr 27, 6:05 am, Brian Drummond<brian_drumm...@btconnect.com
wrote:

snip

I think you are referring to the ?: conditional operator inherited from C?

I just use VHDL's conditional signal assignments for that purpose. As it's
purely combinational, I have never found the need for an equivalent that I can
use inside a process.
Hi Brian,
just a little note - conditional signal assignment is allowed as a
sequential statement in VHDL 2008

<snip>
If VHDL is to adopt a conditional operator I hope it can do better than that!
Something less surprising, and generalisable to other discrete types or at least
other enums.
And VHDL 2008 provides various matching operators that allow std_logic,
bit and so on to be interpreted as Boolean - see
http://www.doulos.com/knowhow/vhdl_designers_guide/vhdl_2008/vhdl_200x_ease/

If you're interested in VHDL 2008, I recommend the book "VHDL 2008 -
Just the New Stuff" by Peter Ashenden and Jim Lewis.

Now if only the tools supported ...


regards
Alan

<snip>

--
Alan Fitch
Senior Consultant

Doulos – Developing Design Know-how
VHDL * Verilog * SystemVerilog * SystemC * PSL * Perl * Tcl/Tk * Project
Services

Doulos Ltd. Church Hatch, 22 Marketing Place, Ringwood, Hampshire, BH24
1AW, UK
Tel: + 44 (0)1425 471223 Email: alan.fitch@doulos.com
Fax: +44 (0)1425 471573 http://www.doulos.com

------------------------------------------------------------------------

This message may contain personal views which are not the views of
Doulos, unless specifically stated.
 

Welcome to EDABoard.com

Sponsor

Back
Top