Variable vs. Signal on indexing

J

Jim Lewis

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

Same as I code any other hardware - sketch the picture,
code the picture. Much time spent understanding hardware
and picture. Little time spent coding and synthesis.

Only use variables when the situation demands it.

Cheers,
Jim
 
J

Jim Lewis

KJ said:
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?
This much I can agree with. Like Mike G, I aways start from
the picture. I spend lots of time understanding the picture
I want to code, and then I code.

I think everyone's design process is personal and tuned to
what makes them successful. I think up front, because I
enjoy the challenge and I hate incremental debug and tuning.
Once I start coding it goes fast and so does debug.
To the absolute newbie, variables are easier to grasp since
> you can step ... Snip

The rest I think we will just have to agree to disagree.

Cheers,
Jim
 
J

Jan Decaluwe

Jim said:
Jan,



Same as I code any other hardware - sketch the picture,
code the picture. Much time spent understanding hardware
and picture. Little time spent coding and synthesis.

What I do is to put a for-loop over the bits around
the bit-serial equation (which is trivially related to
the polynomial), and leave the optimization of the
xor-network to a tool. Little time spent overall.

Remarks:

* variable semantics are mandatory for this, because
each loop iteration is influenced by the previous one.
* this can be done both in a combinatorial block or
a clocked one. In the latter case, the CRC variable
will result both in hardware registers and combo
logic.
Only use variables when the situation demands it.

That is so vague that everybody has to agree with it.
For example, to those who are happy with using HDL design
as a textual form of schematic entry, the situation will
never demand it. Good for them.

To me, the meaningful way to discuss the desirability
of variables is in terms of their influence on design
productivity.

Regards,

Jan
 
J

Jim Lewis

Jan
What I do is to put a for-loop over the bits around
the bit-serial equation (which is trivially related to
the polynomial), and leave the optimization of the
xor-network to a tool. Little time spent overall.

Remarks:

* variable semantics are mandatory for this, because
each loop iteration is influenced by the previous one.
* this can be done both in a combinatorial block or
a clocked one. In the latter case, the CRC variable
will result both in hardware registers and combo
logic.


That is so vague that everybody has to agree with it.
For example, to those who are happy with using HDL design
as a textual form of schematic entry, the situation will
never demand it. Good for them.

To me, the meaningful way to discuss the desirability
of variables is in terms of their influence on design
productivity.

Add to that a meaningful example with at least a sketch
of the solution, as you have provided, and then we can
have a meaningful discussion.

While I recommend not using variables in RTL for the first
couple of designs, in class I also show compelling places to
use variables - such as forming a select for a case expression
or XOR reduction.

Getting back to what Andy said:
-- the background
> Also, not the variables themselves, but _references_ to them imply
> storage or not (and thus register or not); the same variable name may
> represent a combinatorial value in one reference, and a register value
> in another.

-- the statement that worries me:
> And the difference can even be dynamically controlled (e.g.
> a prior write may be conditional). The point is the synthesis tool will
> use a register or not (or a mux between the two) to implement the coded
> behavior.

My read of this says:
process (clk)
begin
if rising_edge(Clk) then
if (le = '1') then
MyVar := ...
end if ;
MySig <= MyVar ;
end if ;
end process ;

In the past, I have seen synthesis tools create a register for
MyVar even when it was redundant with the one for MySig.

For those of you just tuning in, I realize that some, but not
all, synthesis tools support the following:
process (clk)
begin
if rising_edge(Clk) then
if (le = '1') then
MyVar := ...
end if ;
end if ;
MySig <= MyVar ;
end process ;

So personally I would not use either of the above.
 
J

Jim Lewis

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.

Just to be fair, ...
while I recommend not using variables in RTL for the first
couple of designs, in class I also show compelling places to
use variables - such as forming a select for a case expression
or XOR reduction. XOR reduction is just plain ugly without
variables - thank goodness it is being added to the language.

This is simply telling those who already feel burdened with
enough information that they do not need to worry about
learning this yet. However, by showing them the other examples
it gives them the idea that some day they do need to learn it.
For verification classes we fully utilize the whole language.

One always needs to be careful about making guidelines.
Something that seems trivial, such as always reset state registers
can have exceptions - such as when all registers are reset by
BIST and BIST always runs before the system becomes active and
leaves the system in the reset state.

Cheers,
Jim
 
J

Jonathan Bromley

Just to be fair, ...
while I recommend not using variables in RTL for the first
couple of designs, in class I also show compelling places to
use variables[...]

Sincere apologies if I misrepresented you. I was trying
only to exemplify a reasonable difference of opinion
that might exist.
For verification classes we fully utilize the whole language.

Absolutely. It's kinda tough to use TEXTIO without
variables! Any differences of opinion are surely only
related to coding styles for synthesis.

The "variables, yes or no" question arose again today in a
training class I'm delivering. As usual, shades of opinion
ranged all the way from
"hey, that's cool, I'm going to start using that" to
"no, I'll keep the combinational and clocked logic in
separate processes where I can see what they look like".
Ultimately, what matters is maintainability and robustness of
code, and - as others have said - that has much more to
do with quality of thinking than quality of coding gudelines.
One always needs to be careful about making guidelines.

Wisely said :)
--
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.
 
A

Andy

Jim said:
Getting back to what Andy said:
-- the background

-- the statement that worries me:

My read of this says:
process (clk)
begin
if rising_edge(Clk) then
if (le = '1') then
MyVar := ...
end if ;
MySig <= MyVar ;
end if ;
end process ;

In the past, I have seen synthesis tools create a register for
MyVar even when it was redundant with the one for MySig.

The reference to MyVar in the assignment to MySig is a combinatorial
reference to MyVar if le='1', and a registered reference if le ='0'.
So, the synthesis will put a mux on the input to the MySig register to
make that choice. The interesting optimization is that the mux before
MySig looks amazingly like the clock enable mux on the MyVar register.
And if the same mux feeds two registers, then the registers are
redundant, and one can be optimized out. I suspect this optimization
has to do with at which point the synthesis tool selects a clock
enabled register, with the mux built in, for MyVar. If it does it too
soon, the optimization is not available when needed.

A larger point is, do you always code to get exactly the hardware
structure you want? If I always, only coded in a manner to which any
synthesis tool would give me the exact same implementation, I'd have to
write out a structural VHDL netlist. The same issue is present when and
if you use automatic register replication, or register retiming. In
either of these cases, the hardware you envisioned to write the
description will no longer exist when those optimizations are done. My
point is the link between code and hardware is getting looser and
looser as tools advance. The only thing that remains the same is that
the synthesis tool will give you hardware which will behave the same as
the code, on a cycle by cycle basis.

Now, suppose you had written:

....
MySig <= MyVar + 1;
....

Now the two registers are not redundant, but the mux is shareable in
both places. However, for performance reasons, most synthesizers will
not share them (i.e. they'll use a clock enabled register for MyVar,
and blend the mux in with the incrementor for MySig)

I suppose if I was in the business of writing code for all kinds of
customers to use, on all kinds of tools, I'd get a lot more
conservative in my coding practices. As it is, I've had pretty good
luck getting results by telling vendor A that vendor B already does
this.
For those of you just tuning in, I realize that some, but not
all, synthesis tools support the following:
process (clk)
begin
if rising_edge(Clk) then
if (le = '1') then
MyVar := ...
end if ;
end if ;
MySig <= MyVar ;
end process ;

So personally I would not use either of the above.

Say you added the same incrementor to this one. The incrementor would
be after the MyVar register, and the assignment to MySig is
combinatorial. So MySig is now a combinatorial output from a clocked
process!

This one is handled by the tools I use, so I use it. Maybe instead of
arguing over whether it is a good idea to use it, we should be opening
up support cases with those vendors who don't support it. Again,
"...but Vendor B (Synplicity) handles this correctly" works amazingly
well! (A really sad story about "thousands of lines of code, riddled
with this stuff, works with Vendor B, but we'd like to use Vendor A's
tool, if it just worked on this code" can't hurt either.)

Andy
 
J

Jan Decaluwe

Mike said:
If I put the port assignment
outside of the clocked clause,
no pipeline register is inferred.

clked : process(clk)
variable cnt_v : count_t;
begin
if rising_edge(clk) then
cnt_v := cnt_v + 1; -- increment on rising edge
end if;
cnt <= cnt_v; -- wire assignment outside of clocked clause
end process clked;

I never used this template, but started to think about it because
of my work on MyHDL.

The question I have is: is there an equivalent (also synthesizable)
version for Verilog? At first sight, I don't think so, but perhaps
I'm wrong.

Background: there is a MyHDL to Verilog converter, and a MyHDL to
VHDL converter is well under way. When finished, IP developers will
have a way to generate equivalent Verilog and VHDL code from a single
source. Of course, this requires that equivalent templates exist
in both languages. See also:

http://myhdl.jandecaluwe.com/doku.php/dev:whatsnew:0.6#template_transformation

Thanks,

Jan
 
M

Mike Treseler

Jan said:
I never used this template, but started to think about it because
of my work on MyHDL.

The question I have is: is there an equivalent (also synthesizable)
version for Verilog? At first sight, I don't think so, but perhaps
I'm wrong.

Don't know.
I will play with it a bit.

Background: there is a MyHDL to Verilog converter, and a MyHDL to
VHDL converter is well under way. When finished, IP developers will
have a way to generate equivalent Verilog and VHDL code from a single
source. Of course, this requires that equivalent templates exist
in both languages.

Good work.

-- Mike Treseler
 
M

Mike Treseler

Mike Treseler wrote:

I can get the same register init, update, output
in one always block by doing something like this:

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

The Quartus synthesis report and tech viewer get
the correct number of registers (5)

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

But I couldn't use my vhdl-style port assignment
trick to eliminate duplication in the verific RTL front end.

The verilog block uses no IF statement for the rising edge of the clock.
The rtl schematic shows 4 duplicated regs that do not
appear in the utilization report or tech schematic.

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

This is really just a cosmetic problem since everything
after synthesis gets it right. The RTL schematic is generated
after analysis and rtl elaboration, but before fitting.
See http://www.verific.com/ for more information.

-- Mike Treseler
 

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

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,564
Members
45,039
Latest member
CasimiraVa

Latest Threads

Top