Process to combinational circuits?

C

Christiano

Guest
I see many codes that use VHDL process in the combinational. Why is this
so common? Why not use constructs suitable for combinational circuits
instead of using process as often?

Everything that can be done with the process can be done without the
process when it comes to combinational, is not it? So what is the
justification?
 
Am Mittwoch, 4. September 2013 02:01:37 UTC+2 schrieb Christiano:
Everything that can be done with the process can be done without the
process when it comes to combinational, is not it? So what is the
justification?

I use seldom combinatorical process for RTL, but sometimes the code is easier written, maintained or read when using combinatorial process instead of concurrent statements. Especially, if you use intermediate variables for type conversions that are used on several lines within a process you can ease code with process instead of inlining these type conversions at each occurency in a concurrent statement. And often I like to increase readablitiy by using nested if, which is impossible in concurrent statements.
 
To expand on Al's point, I thought I would just give 3 examples of a mux. Which one is "best" is really up to the designer, but it is consistancy and readability that are important:

op <= ip0 when sel = "00" else
ip1 when sel = "01" else
ip2 when sel = "10" else
ip3 when sel = "11" else
'X';

-------

mux : with sel select
op <= ip0 when "00",
ip1 when "01",
ip2 when "10",
ip3 when "11",
'X' when others;

-------

mux_proc : process(sel, ip0, ip1, ip2, ip3)
begin
case sel is
when "00" => op <= ip0;
when "01" => op <= ip1;
when "10" =>
op <= ip2;
report "Case 2 selected for output" severity NOTE;
when "11" => op <= ip3;
when others => op <= 'X';
end case;
end process;



Notice how the process version also allows for extra debug informaton, or any other code that fits in with that logic (maybe you want to combine 3 muxes into 1 process)
 
On 04/09/2013 02:01, Christiano wrote:
I see many codes that use VHDL process in the combinational. Why is this
so common? Why not use constructs suitable for combinational circuits
instead of using process as often?

You may use one single process for the entire entity or have multiple
processes sharing signals with a sparse collection of concurrent
statements or processes to infer combinatorial logic. There's no one
single way to describe your hardware, even though some of them will
reduce the amount of time spent in debugging.

Everything that can be done with the process can be done without the
process when it comes to combinational, is not it? So what is the
justification?

When it comes to hardware *description* you are not only describing it
to an analysis tool but also to a human being, meaning that the more
readable and accurate is your description the easier would be for people
within your team (or for yourself within few weeks from the coding) to
understand your code and possibly fix it!

Synthesis tools are not so picky as human beings and they have no
particular reluctance to accept an insane combination of styles, but a
human being can potentially get lost in your code if the style is not
consistent.

Depending on your working environment it is possible that there are
guidelines with naming conventions, structure, preferred syntax forms...
AFAIK there's no one particular style which is superior to others, but a
consistent style may help you (and your teammates) to spot problems sooner.

Of course you might have equally been unlucky and confronted only with
people who did not know about the possibility to infer combinatorial
logic with concurrent signal assignment statements.

IMHO every effort spent in making the code more readable is good, every
effort spent in reducing the amount of code is good, nearly every effort
spent in optimizing your code is wasted unless proven necessary with
clear metrics and benchmarks.

Al
 
Everything that can be done with the process can be done without the
process when it comes to combinational, is not it? So what is the
justification?
Yes. For small logic, I use concurrent assignments. For larger more complex code, I use a process.

Furthermore, the following is a flip-flop. We just need to make sure to file bug reports against synthesis vendors who do not support it:
AReg <= A when rising_edge(Clk) ;

There are lots of coding preferences out there. Some say use only a single clocked process per architecture. My preference is piecewise using smaller pieces of code. However, the only thing that really matters is readable code that gives us insight into the hardware being created.
 
On 04/09/2013 20:08, Jim Lewis wrote:
Everything that can be done with the process can be done without the
process when it comes to combinational, is not it? So what is the
justification?
Yes. For small logic, I use concurrent assignments. For larger more complex code, I use a process.

Furthermore, the following is a flip-flop. We just need to make sure to file bug reports against synthesis vendors who do not support it:
AReg <= A when rising_edge(Clk) ;

Just checked Mentor's Precision, seems to work fine,

Hans
www.ht-lab.com


There are lots of coding preferences out there. Some say use only a single clocked process per architecture. My preference is piecewise using smaller pieces of code. However, the only thing that really matters is readable code that gives us insight into the hardware being created.
 
On 04/09/2013 21:08, HT-Lab wrote:
On 04/09/2013 20:08, Jim Lewis wrote:
Everything that can be done with the process can be done without the
process when it comes to combinational, is not it? So what is the
justification?
Yes. For small logic, I use concurrent assignments. For larger more
complex code, I use a process.

Furthermore, the following is a flip-flop. We just need to make sure
to file bug reports against synthesis vendors who do not support it:
AReg <= A when rising_edge(Clk) ;

Just checked Mentor's Precision, seems to work fine,

Hans
www.ht-lab.com

I just checked ISE14.4 which is happy as well, I like this constructs as
it is short and sweet ;-)

Thanks,

Hans
www.ht-lab.com

There are lots of coding preferences out there. Some say use only a
single clocked process per architecture. My preference is piecewise
using smaller pieces of code. However, the only thing that really
matters is readable code that gives us insight into the hardware being
created.
 
Here are my thoughts on concurrent vs sequential descriptions...

Humans are sequential thinkers. We understand sequential instructions best. Imagine trying to bake a cake, following a recipe written in concurrent statements that are written in an arbitrary order.

Furthermore, the synthesis tool is perfectly capable of inferring concurrency from a sequential description where applicable.

That being said, complexity often dictates breaking down the description of a complex behavior into multiple concurrent islands of sequential behavior.. This is sometimes useful to clearly indicate independence of behavior (no matter what that process over there is doing, this process here is doing this...)

So, here are some loose rules I try to follow:

Avoid concurrent assignments that depend on each other, or if necessary, state the assignments in order of their dependency (in to out, top to bottom)..

If two or more signals are controlled by the same set of inputs, use a process to make that joint relationship (e.g. the same case statement) more clear. Concurrent assignments can only affect one signal unless you use aggregate data types and functions or a concurrent procedure call, which, if you are not going to reuse it, is a waste of time and code bulk.

Anytime combinatorial logic is described in the same architecture as the register it drives, it should be described in the process that assigns the register. Since my preference is to have all outputs from an entity registered, I do not often have combinatorial logic that does not drive a register in the same architecture.

Cominatorial logic in a clocked process can be described as:

1) an expression which is assigned to the register,
2) as a variable written before being assigned to the register,
3) as a function in an expression being assinged to the register
4) as a procedure with an output variable

#3 & #4 are useful when the same combinatorial function feeds register signals or variables in separate clocked processes (since the subprogram can be re-used.)

If you are relying on code coverage to help define your verification scope/effort, beware that combinatorial processes and concurrent assignments often execute more than once before their value is actually used on the next clock cycle. This can cause lots of false-positive code coverage hits.

Andy
 
Everything that can be done with the process can be done without the
process when it comes to combinational, is not it? So what is the
justification?

Tradition.

I prefer to write a function.
That can be tested out of time using assertions.

-- Mike Treseler
 

Welcome to EDABoard.com

Sponsor

Back
Top