Signals and variables, concurrent and sequential assignments

T

Taras_96

Hi everyone,

I've heard a number of theories about when to use signal assignments or
variable assignments for RTL code, and when to use concurrent or
sequential VHDL. Does anyone have an opinion on the following 'rules
of thumb'?

1) Model combinational logic within a process with a full sensitivity
list using variable assignments

Coming from a Verilog background, I was told to model combinational
logic, using an always@(/*AUTOSENSE*/) procedural block with blocking
assignments. The VHDL equivalent of this is using a process with a
full sensitivty list, and using variable assignments. However, the
variables are only visible from within the process, and thus it is
difficult to get the results out to a sequential block (clocked
process) bit of code.

process(...)
variable sum;
begin
sum := a + b; //how to get this to a process that is clocked?!
end process;

Once way of getting around this is by assigning the variable to a
signal once all combinational logic has finished, however, this breaks
the general rule of not mixing blocking and non-blocking (in Verilog),
or signal and variable (in VHDL) assignments, and also seems
cumbersome. One alternative is to combine the combinational and logic
parts - discussed further below.
"In general:

sequential blocks use non-blocking <=
combinational blocks use blocking =" http://groups-beta.google.com/group..._frm/thread/6c57aee8293cd934/32fd131568d5e217

"Use non blocking assignments within sequential (clocked) blocks:" http://groups-beta.google.com/group/comp.lang.verilog/browse_frm/thread/d4db6011c11acbf7/

"If it's a reg (i.e. it's being assigned in an always block or an
initial block) and you are trying to design synchronous sequential
logic (flip-flops), then use the non-blocking procedural assignment
(<=).
4. If it's a reg (i.e. it's being assigned in an always block or an
initial block) and you are trying to design combinatorial logic, then
use the blocking signal assignment."
http://groups-beta.google.com/group..._frm/thread/d4db6011c11acbf7/e750bbf691c67e5e

Another solution is to migrate all combinational code into the
concurrent section of VHDL - but why then, in Verilog, would you write
combinational code in procedural blocks rather than using assign
statements? I came across the following post discussing the benefits
in Verilog:
"If you wanted the latch or combinational logic. I would decide which
construct to use based on the other features available in continuous
assignments vs. procedural assignments. These are delays and
strengths. You can give strengths to wires and not regs (so you would
use the continuous assignment if you wanted this feature)."
http://groups-beta.google.com/group..._frm/thread/dca48606454e48b5/5c87510daa47030d

Is there any other disadvantages in writing combinational code in
concurrent VHDL - perhaps code clarity? The disadvantage mentioned
above is not really relevant in RTL.

2) Don't mix signal and variable assignments (blocking and
non-blocking)

As mentioned above, one solution is to introduce all the combinational
logic into a clocked process using variable assignments, and then clock
them using signal assignments. This is also suggested in another
thread:
"This is the conventional wisdom. I disagree. I prefer to use signal
(non-blocking) assignments _only_ for the purpose of transferring a
variable (register) value to a port or to another process." http://groups-beta.google.com/group/comp.lang.vhdl/msg/7a377484e81b23e9


"Try looking at a complex always block which uses a mixture of
blocking and non-blocking and it can be a real challange to decipher
what is intended even with a good understanding of the language." http://groups-beta.google.com/group/comp.lang.verilog/msg/c7a6c4f0df5676eb

"In summary then, one should use non-blocking assignments to
synchronous>signals and blocking assignments in combinational
constructs. Don't mix them together."
http://groups-beta.google.com/group/comp.lang.verilog/msg/bc07296b9fb0cfe1

So in summary:

If you are to write combinational logic in a process using variable
assignments, thus following rule 1, how do you get the new values to
the clocked process? One solution is to write all combinational code
in concurrent VHDL - are there any disadvantages in this? Another
solution is to combine the combinational and sequential sections of
code, but this seems to go against conventional wisdom.

I'm sure there are many opinions out there, and I'm interested to see
what people think.

Thanks

Taras
 
M

Mike Treseler

"This is the conventional wisdom. I disagree. I prefer to use signal
This works fine.
I have provided you an example design and testbench
that is very easy to read
if you want to test the technique on your tools.
On the contrary:

As long as signal assignments are used only
as wiring, no confusion will result.
I'm sure there are many opinions out there, and I'm interested to see
what people think.

Consider trying some examples on your simulator
and judge for yourself.

-- Mike Treseler
 
T

Taras_96

Hi Mike

Your 'rule of thumb' works fine - I've implemented a few simple designs
already using different assignment conventions, and yours seems to give
the clearest code. Just wondering if any of the experts out there have
any comments/experiences on any conventions they might have used. As I
said, using my judgement your convention seems to give the clearest
code, but I'm not an expert (as you can tell by my posts) and thus I
don't trust my own judgements :).

Taras
 
J

Jonathan Bromley

I've heard a number of theories about when to use signal assignments or
variable assignments for RTL code, and when to use concurrent or
sequential VHDL. Does anyone have an opinion on the following 'rules
of thumb'?

I have a useful opinion on rules of thumb in general: If you use
only your thumb to design things, they are quite helpful. Once you
graduate to using all ten fingers, the rules of thumb tend to get
consigned to the scrapheap of "things I learned along the way".
1) Model combinational logic within a process with a full sensitivity
list ...

In VHDL you have no choice - despite what you say about "concurrent
logic" (see below).
... using variable assignments

Assign to variables whenever it aids the noble cause of readability
and clarity of expression.
Coming from a Verilog background, I was told to model combinational
logic, using an always@(/*AUTOSENSE*/) ...

Yuck. What is (/*AUTOSENSE*/)? (I can guess.) Today,
Verilog-2001 always@* is fully supported by all serious tools.
... procedural block with blocking assignments.

Yes, that's entirely appropriate.
The VHDL equivalent of this is using a process with a
full sensitivty list, and using variable assignments.

No it isn't. VHDL variables are invisible outside the process
that defines them, but this is not true for Verilog regs.
However, the
variables are only visible from within the process, and thus it is
difficult to get the results out to a sequential block (clocked
process) bit of code.

So, you need a signal. You have no choice. It is appropriate.
Once way of getting around this is by assigning the variable to a
signal once all combinational logic has finished

An excellent idea.
however, this breaks
the general rule of not mixing blocking and non-blocking (in Verilog),
or signal and variable (in VHDL) assignments

Please cite a reference to this "general rule". It is neither a
rule, nor general. It is a misunderstanding of the rule imposed
by almost every Verilog synthesis tool: "never mix blocking and
nonblocking assignment TO THE SAME VARIABLE". In VHDL such a "rule"
would be meaningless, because you can make variable assignment only
to variables, and signal assignment only to signals. Variable
assignment to a variable, and signal assignment to a signal, may
be freely mixed in a single process, of course.

[ mixing var:= and sig<= ]

In Verilog, that's a reasonable starting point.
In VHDL it makes no sense.

In several messages on comp.lang.verilog I have explained at some
length why this is pernicious nonsense. Others have responded with
entirely valid reasons why they personally choose to follow that
guideline even though they know it is not mandatory.

Please try to limit the quantity of Verilog baggage you bring
to VHDL. VHDL has enough baggage of its own, without adding
spurious stuff.
Another solution is to migrate all combinational code into the
concurrent section of VHDL

AARGH - As I said in an earlier response to you, there is NO
SUCH THING as "the concurrent section of VHDL" in the sense
you are using here. The body of an architecture contains
a collection of processes. These processes execute independently
and concurrently. However, sometimes processes appear in
disguise...

* a concurrent assignment is in fact a process, sensitive to
all signals that appear in the expression that it calculates,
containing an assignment to the target signal and nothing else
* a component instance is a rather complicated process made up
of the collection of processes in the architecture body of the
instantiated component
.... and so on.
- but why then, in Verilog, would you write
combinational code in procedural blocks rather than using assign
statements?

So that you can say more complicated things clearly.
Is there any other disadvantages in writing combinational code in
concurrent VHDL - perhaps code clarity? The disadvantage mentioned
above is not really relevant in RTL.

As pointed out above, "concurrent" VHDL is simply a shorthand
way of writing a particularly simple kind of process.

[...]
So in summary:
If you are to write combinational logic [...]
but this seems to go against conventional wisdom.

Conventional wisdom is often deluded, but far worse, it often is
transformed (by time and the passage of newsgroup postings) into
half-truth and urban myth. Trust it at your peril.
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL, Verilog, SystemC, Perl, Tcl/Tk, Verification, Project Services

Doulos Ltd. Church Hatch, 22 Market Place, Ringwood, BH24 1AW, UK
Tel: +44 (0)1425 471223 mail:[email protected]
Fax: +44 (0)1425 471573 Web: http://www.doulos.com

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

Ralf Hildebrandt

Taras_96 wrote:

1) Model combinational logic within a process with a full sensitivity
list using variable assignments

This is because, you would get different simulation results before and
after synthesis. A process needs to know, when it should be triggered.

The VHDL equivalent of this is using a process with a
full sensitivty list, and using variable assignments. However, the
variables are only visible from within the process, and thus it is
difficult to get the results out to a sequential block (clocked
process) bit of code.

Variables cannot be in sensitivity lists, as they reside /inside/ the
process. The sensitivity list lists stuff from outside. This is, where
Verilog blocking signal assignments differ from VHDL variables. They are
similar (at first sight), but not equal.

process(...)
variable sum;
begin
sum := a + b; //how to get this to a process that is clocked?!
end process;

process(clock)
variable sum;
begin
if rising_edge(clock) then
sum := a + b;
end if;
-- do something with sum - assign it to a signal
end process;

In Verilog you have the edge-condition in the sensitivity list. In VHDL
you have a normal sensitivitiy list and the edge-condition inside the
process.

Note: For the example it would be useful to copy sum to a signal, as sum
is a variable and only readable inside this process.

Once way of getting around this is by assigning the variable to a
signal once all combinational logic has finished, however, this breaks
the general rule of not mixing blocking and non-blocking (in Verilog),
or signal and variable (in VHDL) assignments, and also seems
cumbersome.

First: Mixing blocking and non-blocking assignments holds only for one
variable in a always-satement.
Second: Don't think about this rule in VHDL. This is Verilog stuff.

Let me give you an example:

always @(a,b,sum,flag)
begin
sum = a+b;
if (sum[0] == 1'b1) begin
flag_out <= flag;
end else begin
flag_out <= 1'b0;
end //if
end //always

I mixed blocking and non-blocking assignments in general, but this was
nessecary to code it this way. For every signal I used only one
assignment type.

In VHDL the code could look like:

process(a,b,flag)
variable sum_var : unsigned(15 downto 0);
begin
sum_var := a+b;
if (sum_var[0] = '1') then
flag_out <= flag;
else
flag_out <= '0';
end if;
sum <= sum_var;
end process;


Ralf
 

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,731
Messages
2,569,432
Members
44,832
Latest member
GlennSmall

Latest Threads

Top