Variables Synthesysable ?

A

Al

David said:

I think you better handle them with care, it happened to me that they
turned out in a "removed instance" or something like this because not
carefully handled.
Variables schedule the value not at the end of the process as signals
do, but immediately, that is why you can have funny behaviour out of that.
The following processes have very different behaviour:

case1:

process (clk, nrst)
begin
if nrst = '0' then
A <= '0';
B <= '0';
elsif rising_edge (clk) then
A <= not A;
B <= A;
end if;
end process

case2:

process (clk, nrst)
variable B : std_logic;
begin
if nrst = '0' then
A <= '0';
B := '0';
elsif rising_edge (clk) then
A <= not A;
B := A;
end if;
end process

In case1 both A and B will be instantiated as FFs and B will be always
one clock cycle delayed in respect of A.
In the case2 B will be scheduled immediately and will be removed by the
compiler because is equivalent to A.
So watch what you are writing.

Cheers

Al
 
K

Kai Harrekilde-Petersen

Al said:
I think you better handle them with care, it happened to me that they
turned out in a "removed instance" or something like this because not
carefully handled.

[snippage]

It's all a question of care and getting used to. At my previous job,
we used variables almost exclusively and it worked very well. We did
17 tapeouts (all multi-million gate Ethernet switch designs) in around
4 years with only 2 designs that weren't right-first-time (neither of
the two errors were due to the coding style).

A typical pipelined design shows some of the differences you need to
adapt to:

signal pipe: std_logic_vector(3 downto 0);
process(Clk, Reset)
begin
if Reset = RESET then
pipe <= (others => '0');
elsif rising_edge(Clk) then
-- do your assignments to pipe(x) in arbitrary order:
outputs <= output_stage(p(4));
pipe(0) <= input_stage(inputs);
pipe(3) <= stage_3(p(2));
pipe(1) <= stage_1(p(0));
pipe(2) <= stage_2(p(1));
end if;
end process;

Alternate version using variables:
process(Clk, Reset)
variable pipe: std_logic_vector(3 downto 0);
begin
if Reset = RESET then
pipe := (others => '0');
elsif rising_edge(Clk) then
-- Assign output FFs (defined elsewhere)
outputs <= output_stage(p(3));
-- Assign each stage in REVERSE order:
p(3) := stage_3(p(2));
p(2) := stage_3(p(1));
p(1) := stage_3(p(0));
p(0) := input_stage(inputs);
endif;
end process;

That being said, we did see some significant improvements in
simulation speed and memory size by using variables rather than
signals. And no, I don't recall the numbers.


Kai
 
P

Paul Uiterlinden

Kai Harrekilde-Petersen wrote:

That being said, we did see some significant improvements in
simulation speed and memory size by using variables rather than
signals. And no, I don't recall the numbers.

That's a pitty. Not even an order of magnitide? Was it more than 2X?

I'm just curious. The designs I'm dealing with almost exclusively use
signals. I do verifciation, using my own bus functional models. They
are written in a behavioral style with variables exclusively
(almost).

When profiling a simulation, some 90% of the time is spend in the DUT
and 10% in my verification models (both VHDL).

Clearly, the DUT is the part to be optimized to improve simulation
speed. That's why I would like to know if you could put a rough
estimate on the factor that may be gained by using variables.
 
K

KJ

Paul Uiterlinden said:
Kai Harrekilde-Petersen wrote:



That's a pitty. Not even an order of magnitide? Was it more than 2X?

I'm just curious. The designs I'm dealing with almost exclusively use
signals. I do verifciation, using my own bus functional models. They
are written in a behavioral style with variables exclusively
(almost).

I made a test case which was an array of large counters and I recall
something on the order of about 10% improvement when using variables over
signals, definitely not orders of magnitude or even 2x. Although 10% is
'something' it wasn't enough (in my book) to get over the lack of visibility
of variables while you're debugging. By that I mean that you can't add a
variable to the Modelsim wave window to see the history of that variable
after the fact....which is something that I can do with signals with the
simple 'log -r /*' command at the start of sim.

When I hit an assert in my simulation I like to see what led up to that
event without having to restart the sim and having to guess at which
variables I'll need so I can add them to the wave window up front. You can
of course wave the signals that are on the entity to debug and that may be
enough to figure out what's wrong.

Others who use variables extensively cope with this handicap, so it's
something that you can get used to but if someone else has to pick up your
code and debug something they might not appreciate that handicap....It's
also hard to nail down how much less productive one is by having to mentally
keep track of what a variable is instead of being able to just display it.

So while on the one hand you can say that you can run 10% more test cases
with that 10% speedup it's hard to guesstimate at how much time you spend on
the mental gymnastics of keeping track of the variable(s). The difficulty
is also a function of how big and/or complicated the code is at the point
you're debugging. Whatever that time is, it would need to be subtracted
from the 10% (or whatever speedup you measure).

Bottom line though is benchmark it for yourself and see if it's worth it to
you. There are good reasons for using and good reasons for not using
variables.

KJ
 
A

Amontec, Larry

ec said:
Hi
Are VARIABLES in VHDL synthesisable ?
Thanks
EC

Yes, VARIABLES are synthesisable ...
.... but what is a variable in hardware description ?
We know what is a Signal ! ;-)

When possible, we use SIGNAL for RTL description (synthesisable code)!
When possible, We use VARIABLE for Test Bench description
(non-synthesisable code) -> the simulator will run much faster!

Laurent
www.amontec.com
 
K

KJ

Yes, VARIABLES are synthesisable ...
... but what is a variable in hardware description ?
We know what is a Signal ! ;-)

I'm guessing that you really don't know what a signal is or you
wouldn't be asking "what is a variable in hardware description ?" and
implying that a variable is anything different than a signal in some
unspecifyed physical manner.

Variables and signals in the VHDL language have different behaviours in
the same way that 'and' and 'or' and 'xor' are VHDL operators that have
different behaviours. Just because they do different things doesn't
make one better or worse than the other....it simply means they do
different things.
When possible, we use SIGNAL for RTL description (synthesisable code)!
When possible, We use VARIABLE for Test Bench description
(non-synthesisable code) -> the simulator will run much faster!
If you've measured faster sim times with variables then two questions
come to mind from your two statements....
1. Why do you use signals in your RTL (since it would be faster with
variables)
2. How much faster does it run? (I'm guessing that it probably wasn't
enough to warrant an exclamation point, I measured around 10% on a test
case, what have you seen?)

KJ
 
M

Mike Treseler

Paul said:
That's a pity. Not even an order of magnitide? Was it more than 2X?

What if it were 2X?
I wouldn't rewrite working code for that.

The reason I use variables is that they
enable a procedural coding style that
produces working synthesis code faster for me.

I declare variable data structures where I used to generate processes.
I declare functions where I once used asynch processes.
All sim values are current.
The the timing portion of my synthesis description ...

begin -- process template
if reset = '1' then
init_regs;
elsif rising_edge(clock) then
update_regs;
end if;
update_ports;
end process;

.... is separate from my logic description,
and is *always* the same.

These are the advantages for me of using variables.
But this is a different way of looking at logic description,
not just a simple substitution of variables for signals.
Clearly, the DUT is the part to be optimized to improve simulation
speed. That's why I would like to know if you could put a rough
estimate on the factor that may be gained by using variables.

My gut estimate is 2x for my signal-less design entities.
To prove it, I would have to rewrite a design in
a style that I have not used for years. This
doesn't sound like much fun and even if I held
this proof, it alone is not a good enough reason
to change design styles.

-- Mike Treseler
 
M

Mike Treseler

KJ said:
By that I mean that you can't add a
variable to the Modelsim wave window to see the history of that variable
after the fact....which is something that I can do with signals with the
simple 'log -r /*' command at the start of sim.

Note that

log /top/dut/myproc/*

Saves all variable history for a single process uut.
I agree that speed is an insufficient reason to
take on variables, but an unfamiliar command
to log waves is not an insurmountable roadblock either.
Bottom line though is benchmark it for yourself and see if it's worth it to
you. There are good reasons for using and good reasons for not using
variables.

The most significant value for me is clarity of design intent.
This a personal preference, and there is no point
in my trying to prove or disprove it.

-- Mike Treseler
 
K

KJ

Mike said:
Note that

log /top/dut/myproc/*

Saves all variable history for a single process uut.
"Single process uut" is the key restriction.
I agree that speed is an insufficient reason to
take on variables, but an unfamiliar command
to log waves is not an insurmountable roadblock either.

It's not an unfamiliar command that needs to be mastered, it's the fact
that you can't use that command (or any other) to log all variables in
a design unless you go through and list all of the processes. There is
no equivalent to "log -r /*" to log all variables in a design unit that
is being simulated. The only way around that is to get the full
hierarchical list of all processes and make up a .do file (and then
maintain that as the design hierarchy evolves) to log that activity.

For any design verfication testing simulation other than the lowest
unit levels you most likely don't know ahead of time which process to
log the variables on for the assert that is going to fail once you
finally do a 'run'. Once the assert hits is when the debug starts and
the lack of variable history is at least some bit of a hinderance.

I don't doubt that you can (and do) debug using the signals that you
have available from the entity but I would hazard to guess that if the
variable history was there you'd make use of that too and probably
debug a bit faster (i.e. more productive during the particular task of
debugging).
The most significant value for me is clarity of design intent.
I agree, and I find that 'clarity of design intent' is much more a
function of the person writing the code than whether that person uses
signals or variables or both depending on the particular design.
This a personal preference, and there is no point
in my trying to prove or disprove it.
Never said that 'you' should. I was simply suggesting to the previous
poster that if they thought it might be a useful technique because of
sim speed (or whatever metric they thought it was an improvement on) to
simply benchmark and test it on a small scale and try it out for
themselves.....and pointed out my recollection of what I seem to recall
for sim speed improvement when I did that benchmarking myself and one
of the drawbacks that exists when using variables. They can take that
tiny tidbit of information and consider or discard that as they wish.

KJ
 
P

Paul Uiterlinden

Bottom line though is benchmark it for yourself and see if it's
worth it to
you. There are good reasons for using and good reasons for not
using variables.

KJ,

Thanks for your answer. I agree 10% is not worth the hassle. 2X
perhaps would, but the only way to find out is doing a design twice.
And that's definitely not do-able.

Although, proving that it can be done and gaining simulation speed
would give me a nice stick to beat the designer and let him think
about his coding style... ;-)
 
P

Paul Uiterlinden

Mike said:
What if it were 2X?
I wouldn't rewrite working code for that.

No, but it would give a reason to talk with the designers about coding
styles.

Having said that, there is also Equivalence Checking that allows you
to chance existing code and prove that the functionality has not
changed. I have done that in the past. Still you have to be careful
to not forget the synthesis part and make a mess of the synthesis
result speed-wise.
My gut estimate is 2x for my signal-less design entities.
To prove it, I would have to rewrite a design in
a style that I have not used for years. This
doesn't sound like much fun and even if I held
this proof, it alone is not a good enough reason
to change design styles.

It is risky to change coding style, I agree. A factor of 2X however
would justify at least some thought about it, in my opinion.
 
K

Kai Harrekilde-Petersen

Paul Uiterlinden said:
Kai Harrekilde-Petersen wrote:



That's a pitty. Not even an order of magnitide? Was it more than 2X?

Alas, I did not do those timed tests at the time, but only used the
results from it. It was generally combined with the procedural coding
style that Mike wrote about.
When profiling a simulation, some 90% of the time is spend in the DUT
and 10% in my verification models (both VHDL).

Clearly, the DUT is the part to be optimized to improve simulation
speed. That's why I would like to know if you could put a rough
estimate on the factor that may be gained by using variables.

In my experience, you need to profile your DUT code and look at it to
determine where the bottleneck is.

In many of the Ethernet switch designs, the major part (>50%!) of the
simulation time was spent in the CRC32 calculations, which used some
very neat recursively defined XOR_tree() functions which yielded
perfectly balanced binary XOR-gate trees directly during the synthesis
elaboration, but were simulation time hogs.

As I recall, this was in particular a problem with designs with 10GbE
ports which used a 64-bit wide CRC32, while the 8-bit parallel
computations for the 1GbE ports wasn't a real issue even when there
were 24+ ports.

Kai
 
P

Paul Uiterlinden

Kai said:
In my experience, you need to profile your DUT code and look at it
to determine where the bottleneck is.

Agreed, but not always you will find a bottle neck. There are those
designs that show an evenly spread cpu time consumption. An
indication of an optimal design, or showing that the design is
generally slow. Who is to say?
In many of the Ethernet switch designs, the major part (>50%!) of
the simulation time was spent in the CRC32 calculations, which used
some very neat recursively defined XOR_tree() functions which
yielded perfectly balanced binary XOR-gate trees directly during the
synthesis elaboration, but were simulation time hogs.

I've even seen the same with a simple parity generator. That too was a
recursive function, consuming a disproportional part of cpu time
during simulation. And to make it worse: switching on code coverage
broke the function. Clearly a simulator bug, but the fastest way to
get around it was to flatten the function. The simulation ran faster,
code coverage worked and synthesis result was not affected after all.
 
A

Amontec, Larry

KJ said:
I'm guessing that you really don't know what a signal is or you
wouldn't be asking "what is a variable in hardware description ?"
KJ, are you a C programmer talking about VHDL !
and
implying that a variable is anything different than a signal in some
unspecifyed physical manner.
The SIGNAL and VARIABLE are really VERY different !
VARIABLEs can only be used in the process itself!
SIGNALs are used to interact between process!
Variables and signals in the VHDL language have different behaviours in
the same way that 'and' and 'or' and 'xor' are VHDL operators that have
different behaviours. Just because they do different things doesn't
make one better or worse than the other....it simply means they do
different things.



If you've measured faster sim times with variables then two questions
come to mind from your two statements....
1. Why do you use signals in your RTL (since it would be faster with
variables)
RTL description concept is much more different than Test Bench concept.
VHDL RTL description has the advantage to provide TRUE multi-processing
description. Multiple concurrent PROCESS with multiple SIGNALs for
interacting between the PROCESS ! The only objective is to write many
smallest process (This is the better way to write re-usable VHDL code).
In this way, all VARIABLEs will be gone. If you still have VARIABLEs,
you have to re-think about your methodology and design concept!
For a test bench description, it is more more easy to think ONE process,
as one processor with multiple VARIABLEs and FUNCTIONs !
2. How much faster does it run? (I'm guessing that it probably wasn't
enough to warrant an exclamation point, I measured around 10% on a test
case, what have you seen?)
50% to 70%
Yes, but this is for a complex PCI core testbench + high level
application as FFT accelerator ... no simple as a Shift register test
bench !
Laurent Gauch
www.amontec.com
 
K

KJ

KJ, are you a C programmer talking about VHDL !
Absolutely not. I'm a professional engineer who has been designing
boards and writing logic for all sorts of programmable devices even
before there was a VHDL or Verilog language standard. As a college
intern I was even doing some PLD programming before JEDEC had
standardized on a fusemap file and Data I/O had yet to come out with
Abel, Minc's PLDesigner did not yet exist. But I also know C and a bit
of C++ and a few other languages also.
and
The SIGNAL and VARIABLE are really VERY different !
VARIABLEs can only be used in the process itself!
SIGNALs are used to interact between process!
What started this was your statement "... but what is a variable in
hardware description ?" with the implicit (to me) assumption that
variables were somehow not as good as signals or something since you
didn't know what the 'hardware description' of a variable is. My point
is that variables and signals result in the same 'hardware
description'. Inside an FPGA signals and variables would both be
physical metal interconnect and pass transistor programming (for those
that don't get optomized away). Just because they are used differently
doesn't affect that definition, it simply affects how you actually
write your code.

You can write code, making extensive use of variables, and never use
any signals other than the inputs and outputs of the entities
themselves OR you could write code that never uses a single variable
but uses signals everywhere (or anything between those extremes). Both
approaches can result in the exact same synthesized result....so now
tell me how is the 'hardware description' of a variable any different
than that of a signal?
RTL description concept is much more different than Test Bench concept.
Not always. Generally I surround my FPGA design with a model of the
PCBA that it is going to be a part of and the models for some of those
parts on the board are very much RTL like. In fact, by gross count of
parts on the board, most of those parts would probably be considered
RTL. The more complicated ones (like processors and more 'difficult'
functions) are not and could not be synthesized by any present or
future tool in this decade. All of those parts are elements of the
'testbench concept'. In any case, it's a mix.
VHDL RTL description has the advantage to provide TRUE multi-processing
description.
Strike the word 'RTL' from the previous sentence and I agree.
Multiple concurrent PROCESS with multiple SIGNALs for
interacting between the PROCESS ! The only objective is to write many
smallest process (This is the better way to write re-usable VHDL code).
That's your opinion and you're entitled to it. The 'smallest process'
would be to put one signal within each process....most likely not a way
to write maintainable re-usable code.

My opinion is that processes are somewhat analogous to paragraphs in a
chapter. They should encapsulate a specific thought and if that means
one signal or a dozen that's OK. My fuzzy metric is that a process
should fit on a screen. That way the entire process can be studied,
debugged and understood at a glance without having to flip back and
forth. I tend to group signals within a process by how much those
signals depend on the same set of inputs. Again, that minimizes the
amount of flipping back and forth. I'll use variables within processes
where it enhances readability to do so. That's the general idea, for
how I come out with code that is readable and understandable.

I don't have hard fast rules such as 'only one process per entity',
'minimum sized process' or 'minimum lines of code', 'no variables'
since I haven't found any of these to be the most productive way to get
to a functioning design. There are elements of each that are useful
and I'll use them in the way I find to be most productive for myself
while also not trying to come up with something that may be a chore for
someone else unfamiliar with the design to pick up later.
In this way, all VARIABLEs will be gone
So what? Do you get charged by how many variables you use?
If you still have VARIABLEs,
you have to re-think about your methodology and design concept!
I don't agree....and I think you'd get a bigger disagree from Mike
Tressler and many others that follow his lead and use variables more
extensively than I do.
For a test bench description, it is more more easy to think ONE process,
as one processor with multiple VARIABLEs and FUNCTIONs !
You really like excamation points don't you? In any case, whether it
is 'easier to think of a function as one process' or not depends on
what that function is whether it is part of a testbench or not. In
fact, even in simple testbench cases I tend to have multiple processes;
the simplest being I'll typically have a process to generate stimulus
input to the thing that I'm testing and another process to validate
that the outputs are correct. At times I've been able to combine them
into a single process but I find that to be more the exception than the
general case.
50% to 70%
Yes, but this is for a complex PCI core testbench + high level
application as FFT accelerator ... no simple as a Shift register test
bench !
So are you saying that you have two equivalent descriptions of the same
thing, one written with variables and the other with the same coding
style but using signals and measured a 50-70% speed improvement with
variables? If so, then besides seeing more of a speedup than I saw, it
would seem that you would have a stronger motivation to use variables
because of the larger speedup....so why aren't you?

Also, I didn't say my benchmark test was a simple shift register. The
benchmark was an entity that used a generate statement to generate a
large block of processes (to emulate the large number of processes
within a typical design) where each process implemented a counter using
either a signal or a variable. Instead of a counter I could have
chosen any other logical function as well and benchmarked that. I
suspect that my results would be the same (i.e. that variables were
about 10% faster than signals)...but perhaps not.

KJ
 
M

Mike Treseler

KJ, are you a C programmer talking about VHDL !

I'm also a C programmer talking about VHDL.
These things happen.
and
implying that a variable is anything different than a signal in some
unspecifyed physical manner.

The significant difference is assignment delay.
Hardware is inferred from assignments.
Variables and signals alone have no physical significance.

In a synchronous process either

n_v := n_v + 1;
or
n_s <= n_s + 1;

will infer a counter as long
as n affects the right side of
a port assignment.

I can synthesize an entity without signals.
The only thing that variable can't do
is participate in a port map.

-- 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

Similar Threads


Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top