Variable vs. Signal on indexing

M

Mike Treseler

Andy said:
When I first started flirting with variables in VHDL synthesis,
understanding how they mapped to hardware took some time. OTOH, when I
first started coding VHDL at all, understanding the non-sequential
nature of signal assignment statements in sequential code took a while
too.

Yes, it is a big hill to climb in either case.
But once on top of the "variable" hill,
I can write a sequential description
that is easy for me to understand a year from now.

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
 
M

Mike Treseler

Jim said:
Sure. You and Mike ready to take it up? These things
take volunteers.

Send me an email.

I could free up an hour a week, but I can't
tinker with my production tools setup.

Everything I do is already covered by
VHDL-93 and I am not interested in
trying to convince a vendor how to run
his business.

I would be interested in documenting
synthesis techniques that already work
on my tools, but I am not sure this would
have any effect on the 2004 revision.

-- Mike Treseler
 
A

Andy

Jim said:
Sure. You and Mike ready to take it up? These things
take volunteers. The 2004 revision needs to be re-anlayzed
with this in mind to see if it is missing or if it is there
and I missed seeing it. There is also some need for adding
more attributes and perhaps renaming fsm_complete (particularly
if no-one has implemented it) to fsm_safe (as that is what it
does).

OK, I see your point, but did you see mine? If the majority of
synthesis vendors are already coming to a common ground, is there a
need for a published standard, or to restrict oneself to it? If the
value in synthesis development is in supporting new features and coding
styles, should we wait for standards to be written embracing them
before we ask tool vendors to implement them? The synthesis market for
FPGA's is very competitive, and one vendor is not about to let another
have a valuable feature all to themselves for very long, which keeps
the fire stoked for continuous innovation to provide, however fleeting,
some kind of market advantage. Standardization would do nothing for
this type of innovation except provide a common framework to document
what is already being done.

As for this particular issue (signal assignments from expressions of
variables after the clocked clause), synthesis vendors have just
realized that this is another simulation behavior that is relatively
easy to implement in hardware, so they've done it. The movement away
from "templates" has fostered this innovation by looking at synthesis
in a whole new light: implementing behavior instead of structure.
Obvious to the quick and the sharp. Subtle to new users
who are overwhelmed by other pieces of the design and
design flow.

I say it is overwhelming because we are still trying to teach new users
"this is how you code a register; this is how you code a gate". It's
like starting out teaching a new C coder how to create a piece of
assembler code by writing C.

Except for specialized cases of synchronization and driving causal
inputs, does it really matter where the flops are and where the gates
are, as long as they are spread out enough to meet timing (automated by
many tools already), and the functional and latency (in terms of clock
cycles) requirements are met? Specifically, if re-timing is used, why
worry about register placement in the circuit, since it will all get
rearranged any way? And if you don't have to worry about it, why not
code in a style that frees you from having to worry about it?
Exciting :). Sometimes registered, sometimes combo logic.

A brave new world :) And much more difficult to do without variables.
Just don't think of it in terms of registers or combo, think of it in
terms of delayed or not (by a clock cycle).

Andy
 
M

mikegurche

Mike said:
Yes, it is a big hill to climb in either case.
But once on top of the "variable" hill,
I can write a sequential description
that is easy for me to understand a year from now.

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.

It is very clear to me and I can visualize the underlying circuit.
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 ...

It is fine if this is a C segment. For RTL hardware description, I
can't relate the code to the circuit and must rely on the black magic
of synthesis software.
To me, there is no comparison.
It's like calculus vs Laplace transforms.


-- Mike Treseler

To me, there is also no comparison. "Black magic" is never my
preference.

Mike G.
 
M

Mike Treseler

It is fine if this is a C segment.

Fine as in understandable?
For RTL hardware description, I
can't relate the code to the circuit

One way to do this is to click up the RTL viewer.
and must rely on the black magic
of synthesis software.

It's all LUTs and flops.
We rely on synthesis to get it right in either case.
My point is that synthesis *does* get it right.



-- Mike Treseler
 
M

mikegurche

Mike said:
Fine as in understandable?


One way to do this is to click up the RTL viewer.


It's all LUTs and flops.
We rely on synthesis to get it right in either case.
My point is that synthesis *does* get it right.



-- Mike Treseler

You have more faith on synthesis software than I do :)

Mike G.
 
M

mikegurche

Jonathan said:
Yes; but then, many things about simulation and synthesis
are odd.

For example: it's odd that, in a discrete-event simulator,
all the simulator's time is spent processing activity that
occurs in zero simulated time; the passage of simulated
time costs the simulator essentially nothing (merely
replacing the current value of NOW with the value
at which the next event occurs).

Given the usual RTL paradigm, the relationship between
VHDL signals and the hardware they represent can be
explained rather easily. The relationship between VHDL
variables and the hardware they represent (or don't!)
is much subtler.

It's difficult to get hardware folk to think in terms of
functionality, when they (quite properly) need to
spend much of their working lives worrying about
structure and timing.

I have huge sympathy for the position held by Mike
Treseler and others - that you should use variables
in fairly complicated synchronous processes to describe
the functionality you want, and let the synthesis tool
fuss about the structure - but that position works
only for people who have enough insight to be able
to envisage what hardware structures they're describing,
without actually laying-out the gates and flops. For
beginners, and traditional paper-and-pencil designers,
it's tough.
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
(e-mail address removed)
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.


I write codes in both VHDL and Verilog. The variable and signal in a
VHDL process roughly translate to the non-blocking and blocking
statements in Verilog. Almost all Verilog coding guidelines recommend
not to mix the non-blocking and blocking statements. It will be much
easier to convert codes between the two languages if VHDL code follows
the same guideline.

Anyone wish to comment from this perspective?

Mike G.
 
M

Mike Treseler

I write codes in both VHDL and Verilog. The variable and signal in a
VHDL process roughly translate to the non-blocking and blocking
statements in Verilog. Almost all Verilog coding guidelines recommend
not to mix the non-blocking and blocking statements. It will be much
easier to convert codes between the two languages if VHDL code follows
the same guideline.

I have translated single process vhdl designs into verilog
using register variables. It works fine if you follow
the template, but it is possible to create races
in verilog that are not possible in vhdl.

Here's an example:

http://home.comcast.net/~mike_treseler/div10.v
http://home.comcast.net/~mike_treseler/div10.pdf
 
J

Jonathan Bromley

I write codes in both VHDL and Verilog. The variable and signal in a
VHDL process roughly translate to the non-blocking and blocking
statements in Verilog. Almost all Verilog coding guidelines recommend
not to mix the non-blocking and blocking statements.

Not mine.

There *is* such a coding guideline, and it is vital for synthesis -
so much so that just about every synthesis tool will choke if you
violate it:
** Never mix blocking and nonblocking
** assignments to the same variable.
The guidelines (and I agree, they are many) that deprecate any mixture
of blocking and nonblocking assignments in the same process
are simply wrong and should be treated with disdain - unless they
are applied to enforce a painfully low lowest-common-denominator
style on engineers you are unable or unwilling to trust.
It will be much
easier to convert codes between the two languages if VHDL code follows
the same guideline.

Wrong. It will be much easier to convert synthesisable code if
your Verilog code follows the VHDL model. In clocked processes,

** make nonblocking assignments to variables declared at the
** module level, imitating the semantics of VHDL signals;
**
** make blocking assignments to variables declared locally
** in the named begin...end block that forms the body of your
** clocked process, imitating the semantics of VHDL variables.

Not only does this make the code VHDL-friendly, it makes it
more stylish. Local variables are a good thing for isolating
and hiding local design decisions.
Anyone wish to comment from this perspective?

Yes. I wish to say, very loudly, that the extremely conservative
coding guidelines that you mentioned are absurdly restrictive.
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
(e-mail address removed)
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
J

Jim Lewis

Andy,
OK, I see your point, but did you see mine? If the majority of
synthesis vendors are already coming to a common ground, is there a
need for a published standard, or to restrict oneself to it?

Its value is more obvious when you buy IP. If they certify it
to a standard and your tool supports that standard, then it will
work.
A brave new world :) And much more difficult to do without variables.
Just don't think of it in terms of registers or combo, think of it in
terms of delayed or not (by a clock cycle).

I was being facetious. In general I like keeping a tight
eye on the hardware I am creating. I have not come across
a hardware structure for which I really desired to do this.

Going further, reading your first statement, I am guessing
that you mean something like the following.

LoadEnProc : process
variable AVar : std_logic ;
begin
wait until Clk = '1' ;
if (LoadEn = '1') then
AVar := A ;
end if ;
AReg2 <= AVar ;
end process ; -- LoadEnProc

Note, the above code also exhibits some odd quirks in
register implementation that may (like the previous problem
I posted in this thread) be fixed during place and route.

Cheers,
Jim
 
M

mikegurche

Jonathan said:
Not mine.

There *is* such a coding guideline, and it is vital for synthesis -
so much so that just about every synthesis tool will choke if you
violate it:
** Never mix blocking and nonblocking
** assignments to the same variable.
The guidelines (and I agree, they are many) that deprecate any mixture
of blocking and nonblocking assignments in the same process
are simply wrong and should be treated with disdain - unless they
are applied to enforce a painfully low lowest-common-denominator
style on engineers you are unable or unwilling to trust.


Wrong. It will be much easier to convert synthesisable code if
your Verilog code follows the VHDL model. In clocked processes,

** make nonblocking assignments to variables declared at the
** module level, imitating the semantics of VHDL signals;
**
** make blocking assignments to variables declared locally
** in the named begin...end block that forms the body of your
** clocked process, imitating the semantics of VHDL variables.

Not only does this make the code VHDL-friendly, it makes it
more stylish. Local variables are a good thing for isolating
and hiding local design decisions.


Yes. I wish to say, very loudly, that the extremely conservative
coding guidelines that you mentioned are absurdly restrictive.
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
(e-mail address removed)
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.

Jonathan,

The guidelines I metioned is from

"Nonblocking Assignments in Verilog Synthesis, Coding Styles That Kill"

http://www.sunburst-design.com/papers/CummingsSNUG2000SJ_NBA.pdf

which is voted best paper in SNUG2000.

It will be nice if you can provide some links for other guidelines.

Mike G.
 
J

Jonathan Bromley

Jonathan Bromley wrote:
[a rant about why Verilog RTL code ought to look
more like VHDL RTL code]
Jonathan,

The guidelines I metioned is from
"Nonblocking Assignments in Verilog Synthesis, Coding Styles That Kill"
http://www.sunburst-design.com/papers/CummingsSNUG2000SJ_NBA.pdf
which is voted best paper in SNUG2000.

You'll find the same guidelines elsewhere too; for example, in the
OpenMORE coding standard. That doesn't automatically make
the advice correct, though.

Cliff's discussion of the behaviour of NBA and races is spot-on
(and, indeed, I often point my own trainees to that paper), but
please read his section 13.0 rather carefully. He correctly
dismisses his example 25 (mixed blocking and nonblocking assignment
to the same variable) as being non-synthesisable. But he also
dismisses his example 24 without justification, despite correctly
saying that the example synthesises and simulates in exactly the
desired way! On this point (and, note, on only this point)
I disagree strongly with his paper's conclusions. His example
24 is a perfectly sensible use of blocking assignment to local
variables, and represents a coding style that I would strongly
encourage.

I imagine that Cliff's reasoning here is that of a trainer who
wishes to be conservative - note that Jim Lewis uses exactly
the same reasoning when avoiding discussion of variables in
his VHDL training classes. We, similarly, avoid the use of
variables (and locals in Verilog) in our introductory training,
but we slip in the possibility as soon as we are able.
We believe it gives users a powerful additional tool for
expressing their design intent.
It will be nice if you can provide some links for other guidelines.

There is plenty of guidance in this thread. However, I'm not aware
of the idea being published as "guidelines".
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
(e-mail address removed)
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
K

KJ

Jim Lewis said:
Andy,

Its value is more obvious when you buy IP. If they certify it
to a standard and your tool supports that standard, then it will
work.
Besides IP, the synthesis tools vendors themselves all claim to meet a
standard and generally they don't. As a user of those tools, I'm
technically in a much stronger position to complain about the lack of
adherance when I can refer back to the standard that they claim support for
that their tool doesn't actually support. However, having said that I can
also say that when they hear me say "Modelsim and Quartus have no problem
with this code" it seems to get their attention faster than if I try to
refer to a paragraph in a standard.....but in the final analysis, it is the
existence of a standard that provides that fundamental underpinning of
support for why the competition correctly implements something that they can
not.

Kevin Jennings
 
K

KJ

You have more faith on synthesis software than I do :)

Mike G.
Unless the source code you write is only in terms of hooking up 4-6 input
LUTs, flip flops, small memory elements (and the various new hard features
that keep popping up with each new generation of devices), then you have a
lot more faith in synthesis software than you may realize.

You may not feel comfortable with the coding style, but if it succintly
describes the function and is maintainable (both are rather nebulous metrics
though) than, if nothing else, this is raising your awareness of other ways
of describing functionality and that is a 'good thing' even if you have no
immediate plans to adopt it.

Kevin Jennings
 
J

Jan Decaluwe

I write codes in both VHDL and Verilog. The variable and signal in a
VHDL process roughly translate to the non-blocking and blocking
statements in Verilog. Almost all Verilog coding guidelines recommend
not to mix the non-blocking and blocking statements. It will be much
easier to convert codes between the two languages if VHDL code follows
the same guideline.

Anyone wish to comment from this perspective?

Sure :)

That is a bad guideline and bad guidelines should be ignored. Here are
my reasons.

First, Cummings created this guideline without any proper
justification. He
simply labels the coding style *a priori* as poor and adds: "Although
this
will work, the author does not recommend it." See the paper. In other
words,
don't do this because I tell you so. I find that unacceptable.

More importantly, there *are* important technical arguments for giving
variable semantics (blocking assignments) a prominent position in RTL
design. It's not just a neutral choice of style. Many relevant design
problems
that are cumbersome and hard to solve without variables, have elegant
solutions with them.

I have treated this subject in some more detail using a practical
example here:
http://myhdl.jandecaluwe.com/doku.php/cookbook:jc2
(Although this page is about MyHDL, it contains (converted) equivalent
Verilog for your review.)

Jan
 
K

KJ

Jim Lewis said:
Note I state my guideline as a "recommendation" and not a rule.

Recommendation:
Avoid using variables for RTL design on your first couple of projects.

This way those who already have FPGA design skills or are
sharp would feel free to violate it.


To some degree, I agree. Especially for verification.
Here are my notes for RTL creation:

RTL behavior in a clocked process:
Signal assignment: Always implies* a register
Variable assignment:
Implies a register if variable read before written.
Alternately implies a register if variable has a life time.
Implies combinational logic when always written before read.

*Registers are created for all implied registers unless there
is a redundancy that can be merged with another register.


RTL behavior in a combinational process:
Signal assignment:
Must get a value for every hardware execution of the
process or it will create a latch.
Recommendation: do not read a value that is written in the same
process, otherwise, signal must be on sensitivity list and process
must iterate.

Variable assignment:
Implies combinational logic when always written before read.
If read before written then error
Must get a value for every hardware execution of the
process or it will create a latch.

For design creation there are alot of details that must
be managed. As you pare this down to RTL creation,
you must master signals, but for most applications you
don't need to use variables - hence you
don't need to learn the additional hardware implications.

Actually, if you focus on correct function first and foremost I suspect
you'll be up and running faster. The 'implications' of whether you use
signals or variables are rather transparent....i.e. who cares if the
function being implemented is correct? To the absolute newbie, variables
are easier to grasp since you can step through the code and see your
variable getting updated. with signals you don't get that feedback, so in
many cases the learning curve there can be steeper.

The more important design considerations inside a process are things like
understanding what hardware can be generated by seemingly simple looking
constructs....like if (a=b) then....else .... end if, where a and b are, say
16 bit signals...oh and that if statement is buried down 5 levels of if
statements all encapsulated inside a case statement. Or even c <= a /
b;....gee this won't run at 200 MHz? Clocking on multiple edges or even on
multiple signals. What is this 'combinatorial loop' warning thingy? What's
a latch? Stuff like that are the kinds of things that 'simulate just fine'
but either don't synthesize or can only operate in the KHz range.

Whether one uses variables or signals to accomplish the task of implementing
a given function generally just doesn't matter much in getting the function
working properly at the intended speed but it can make a difference in how
maintainable that code ends up being. So after designing for function and
performance, having code that is clean, maintainable and supportable is the
next major item even though none of those things are directly measurable
metrics.

Kevin Jennings
 
J

Jan Decaluwe

Jim said:
I was being facetious. In general I like keeping a tight
eye on the hardware I am creating. I have not come across
a hardware structure for which I really desired to do this.

Never needed to code a CRC which treated multiple bits
in a single clock cycle? How did you/would you solve that?

Jan
 
M

mikegurche

KJ said:
Unless the source code you write is only in terms of hooking up 4-6 input
LUTs, flip flops, small memory elements (and the various new hard features
that keep popping up with each new generation of devices), then you have a
lot more faith in synthesis software than you may realize.

You may not feel comfortable with the coding style, but if it succintly
describes the function and is maintainable (both are rather nebulous metrics
though) than, if nothing else, this is raising your awareness of other ways
of describing functionality and that is a 'good thing' even if you have no
immediate plans to adopt it.

Kevin Jennings

By "visualizing hardware", I mean to think in terms of block
diagram and then describe each block in a VHDL segment. I consider
synthesis software as a tool that performs transformation and local
optimization and converts HDL constructs to LUTs. It just follows your
instruction.

It is like a C compiler that transforms C code to machine instructions.
The compiler can do some optimization but can never change the
algorithm. Regardless how good it is, no compiler can convert bubble
sort (O(n^2)) to quick sort (O(n log n)).

I use variables when the hardware counterpart (an abstract part, not
LUTs) can be clearly identified. The main issue is to relate hardware
to code rather than the usage of variables or sequential statements.
By doing this, I never worry about "simulation/synthesis mismatch"
and seldom check the synthesized RTL schematic (unless for critical
path) because I know it is correct.

Mike G.
 
K

KJ

By "visualizing hardware", I mean to think in terms of block
diagram and then describe each block in a VHDL segment. I consider
synthesis software as a tool that performs transformation and local
optimization and converts HDL constructs to LUTs. It just follows your
instruction.
It is like a C compiler that transforms C code to machine instructions.
Yep.....and if the usage of a variable or signal translates into a flip flop
or a LUT then so be it.
The compiler can do some optimization but can never change the
algorithm. Regardless how good it is, no compiler can convert bubble
sort (O(n^2)) to quick sort (O(n log n)).
Nobody was implying that it could or should....and certainly not as a result
of choosing between variables or signals in an implementation.
I use variables when the hardware counterpart (an abstract part, not
LUTs) can be clearly identified.
What is the relevance of clearly identifying an abstract part that is not
actually part of the actual implementation? (Since you stated 'not LUTs'
which are the basic logic building block in an FPGA). The code describes
function, which needs to be absolutely correct.
The main issue is to relate hardware
to code rather than the usage of variables or sequential statements.
So how does what you say be related to this thread then?
By doing this, I never worry about "simulation/synthesis mismatch"
and seldom check the synthesized RTL schematic (unless for critical
path) because I know it is correct.
You can only know it is correct via verification by simulation and actual
implementation, not visualization of hardware.

I think your basic point is that having a feel for what is going to be
implemented by the code you write is important so knowing that you will have
difficulty synthesizing dual clock edged flip flops (as an example) is
problematic so you don't do it...and that's a correct view. But use of
variables versus signals does not fall under that category, they will result
in a function that is implemented by a LUT which may be followed by a flip
flop (depending on the usage inside the process).

Kevin Jennings
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,535
Members
45,007
Latest member
obedient dusk

Latest Threads

Top