Coding Practices for Combinational and Sequential circuits

K

kb33

Guest
Hi,

I have been always been taught so and try to strictly follow the
practice of splitting my design into combinational and sequential
blocks (see example below). However, I have been asked to look at
somebody's design at my workplace that does not do so, and I do not
know whether I should ignore his style or bring it to the notice of
the manager. I am looking for the most convincing explanation as to
why the second style is not good.

----------My style----------------------

Sequential
---------------

always @(posedge clock)
data_out <= data_out_comb;

Combinational
---------------------

always @(reset_n or data_a or data_b)
if (~reset_n)
data_out_comb = 0;
else
data_out_comb = data_a + data_b;




-------Mixed sequential and combinational design----------------

always @ (posedge clock or negedge reset_n)
begin
if(~reset_n)
data_out <= 0;
else
data_out <= data_a + data_b;
end



P.S The second coding style doesn't even have the signals data_a and
data_b in the sensitivity list.


Thanks
kb33
 
On Aug 27, 11:32 am, kb33 <kanchan.devarako...@gmail.com> wrote:
Hi,

I have been always been taught so and try to strictly follow the
practice of splitting my design into combinational and sequential
blocks (see example below). However, I have been asked to look at
somebody's design at my workplace that does not do so, and I do not
know whether I should ignore his style or bring it to the notice of
the manager. I am looking for the most convincing explanation as to
why the second style is not good.

----------My style----------------------

Sequential
---------------

always @(posedge clock)
   data_out <= data_out_comb;

Combinational
---------------------

always @(reset_n or data_a or data_b)
   if (~reset_n)
      data_out_comb = 0;
   else
      data_out_comb = data_a + data_b;

-------Mixed sequential and combinational design----------------

always @ (posedge clock or negedge reset_n)
   begin
      if(~reset_n)
         data_out <= 0;
      else
         data_out <= data_a + data_b;
   end

P.S The second coding style doesn't even have the signals data_a and
data_b in the sensitivity list.

Thanks
kb33
There is nothing wrong with the second example. In fact, it is my
preferred
style. More concise, less prone to typos.


John Providenza
 
kb33 <kanchan.devarakonda@gmail.com> writes:

-------Mixed sequential and combinational design----------------

always @ (posedge clock or negedge reset_n)
begin
if(~reset_n)
data_out <= 0;
else
data_out <= data_a + data_b;
end



P.S The second coding style doesn't even have the signals data_a and
data_b in the sensitivity list.
And, it *should not*. The logic is not sensitive to changes in those
signals. It merely samples those signals when the appropriate edges
occur. If you add the data_a or data_b signals to the sensitivity
list, you will get something that doesn't behave properly. It will
change at non edges of the clock and reset signals.

Hope this helps,
Chris
 
On Aug 27, 11:26 pm, Chris F Clark <c...@shell01.TheWorld.com> wrote:
kb33 <kanchan.devarako...@gmail.com> writes:
-------Mixed sequential and combinational design----------------

always @ (posedge clock or negedge reset_n)
   begin
      if(~reset_n)
         data_out <= 0;
      else
         data_out <= data_a + data_b;
   end

P.S The second coding style doesn't even have the signals data_a and
data_b in the sensitivity list.

And, it *should not*.  The logic is not sensitive to changes in those
signals.  It merely samples those signals when the appropriate edges
occur.  If you add the data_a or data_b signals to the sensitivity
list, you will get something that doesn't behave properly.  It will
change at non edges of the clock and reset signals.

Hope this helps,
Chris
The second style requires half the always blocks, half the signal
declarations, and does not require all of the inputs to be listed in
the sensitivity list.

What's not to like?

Many simulators also merge multiple always blocks with the same
sensitivity lists into one for execution, reducing scheduling
overhead. The second style is more amenable to this optimization,
since only the clock and reset are ever used in the sensitivity lists.
Having a lot of processes in the first style with more or less random
sensitivity lists defeats the optimization.

Andy
 
On Thu, 28 Aug 2008 07:43:54 -0700 (PDT), gabor <gabor@alacron.com>
wrote:

On Aug 27, 2:32 pm, kb33 <kanchan.devarako...@gmail.com> wrote:
Hi,

I have been always been taught so and try to strictly follow the
practice of splitting my design into combinational and sequential
blocks (see example below). However, I have been asked to look at
somebody's design at my workplace that does not do so, and I do not
know whether I should ignore his style or bring it to the notice of
the manager. I am looking for the most convincing explanation as to
why the second style is not good.

----------My style----------------------

Sequential
---------------

always @(posedge clock)
data_out <= data_out_comb;

Combinational
---------------------

always @(reset_n or data_a or data_b)
if (~reset_n)
data_out_comb = 0;
else
data_out_comb = data_a + data_b;

-------Mixed sequential and combinational design----------------

always @ (posedge clock or negedge reset_n)
begin
if(~reset_n)
data_out <= 0;
else
data_out <= data_a + data_b;
end

P.S The second coding style doesn't even have the signals data_a and
data_b in the sensitivity list.

Thanks
kb33

If you want to synthesize this code, you may find that your
version doesn't work (at least XST won't take it) BECAUSE
it has assignments to the same register in more than one
always block.
The OP was just showing two examples of the same design. The first two
always blocks is one implementation and the third always is the second
implementation. They are not meant to be used together.
 
On Aug 28, 6:37 am, Andy <jonesa...@comcast.net> wrote:
On Aug 27, 11:26 pm, Chris F Clark <c...@shell01.TheWorld.com> wrote:



kb33 <kanchan.devarako...@gmail.com> writes:
-------Mixed sequential and combinational design----------------

always @ (posedge clock or negedge reset_n)
   begin
      if(~reset_n)
         data_out <= 0;
      else
         data_out <= data_a + data_b;
   end

P.S The second coding style doesn't even have the signals data_a and
data_b in the sensitivity list.

And, it *should not*.  The logic is not sensitive to changes in those
signals.  It merely samples those signals when the appropriate edges
occur.  If you add the data_a or data_b signals to the sensitivity
list, you will get something that doesn't behave properly.  It will
change at non edges of the clock and reset signals.

Hope this helps,
Chris

The second style requires half the always blocks, half the signal
declarations, and does not require all of the inputs to be listed in
the sensitivity list.

What's not to like?

Many simulators also merge multiple always blocks with the same
sensitivity lists into one for execution, reducing scheduling
overhead. The second style is more amenable to this optimization,
since only the clock and reset are ever used in the sensitivity lists.
Having a lot of processes in the first style with more or less random
sensitivity lists defeats the optimization.

Andy
I have seen people that like to separate the next state logic from
the
clocked logic in state machines. This potentially makes decoding
outputs
for a Mealy state machine more concise to code. Thus you end up with
a
structure similar to the "officially sanctioned" organizations desired
by
the OP.

John Providenza
 
On Aug 27, 2:32 pm, kb33 <kanchan.devarako...@gmail.com> wrote:
Hi,

I have been always been taught so and try to strictly follow the
practice of splitting my design into combinational and sequential
blocks (see example below). However, I have been asked to look at
somebody's design at my workplace that does not do so, and I do not
know whether I should ignore his style or bring it to the notice of
the manager. I am looking for the most convincing explanation as to
why the second style is not good.

----------My style----------------------

Sequential
---------------

always @(posedge clock)
data_out <= data_out_comb;

Combinational
---------------------

always @(reset_n or data_a or data_b)
if (~reset_n)
data_out_comb = 0;
else
data_out_comb = data_a + data_b;

-------Mixed sequential and combinational design----------------

always @ (posedge clock or negedge reset_n)
begin
if(~reset_n)
data_out <= 0;
else
data_out <= data_a + data_b;
end

P.S The second coding style doesn't even have the signals data_a and
data_b in the sensitivity list.

Thanks
kb33
If you want to synthesize this code, you may find that your
version doesn't work (at least XST won't take it) BECAUSE
it has assignments to the same register in more than one
always block.
 
jprovidenza@yahoo.com wrote:

I have seen people that like to separate the next state logic from
the
clocked logic in state machines. This potentially makes decoding
outputs
for a Mealy state machine more concise to code. Thus you end up with
a
structure similar to the "officially sanctioned" organizations desired
by
the OP.
The OP said nothing about Mealy machines or
"officially sanctioned" organizations.

He asked if he should "bring it to the notice of the manager"
I have found that this is almost always a bad idea.

Looks to me like the reviewee has
more language savvy than the reviewer,
and bringing the boss into the loop won't help.

-- Mike Treseler
 
----------My style----------------------

Sequential
---------------

always @(posedge clock)
data_out <= data_out_comb;

Combinational
---------------------

always @(reset_n or data_a or data_b)
if (~reset_n)
data_out_comb = 0;
else
data_out_comb = data_a + data_b;




-------Mixed sequential and combinational design----------------

always @ (posedge clock or negedge reset_n)
begin
if(~reset_n)
data_out <= 0;
else
data_out <= data_a + data_b;
end
First of all, I have to point out that these examples are not
equivalent. In the first example the reset will be synchronous, and in
the second example the reset will be asynchronous. To make the second
example equivalent to the first, remove "or negedge reset_n" from the
sensitivity list.

Second, if you bring it to the attention of your manager, you should do
so only to commend your colleague's code for having better clarity,
conciseness, faster simulation speed, and for being less bug-prone.
-Kevin
 
On Thu, 28 Aug 2008 11:16:15 -0700 (PDT), kb33
<kanchan.devarakonda@gmail.com> wrote:

So my next questions are as follows:

1. Assuming that having everything in one always block with just the
reset and clock in the sensitivity list is better, why doesn't the
synthesis tool complain about any missing "else" statements or missing
bit assignments? And why does it not generate latches?
Latches are needed when you have a "reg" which needs to keep its
current value when it's not assigned in a branch. In single always
solutions, the reg already provides for that purpose and infers
storage so there is no need for another storage ie latch. In separate
always block designs, you put all your storage in the clocked block
and the other one is supposed to be fully combinational ie no storage,
no latch.

2. I am totally confused as to which style should be adopted. Is it
that one is better for ASICs and the other better for FPGAs?

This is completely arbitrary. Pick one which you like more or the one
forced on you.

3. My company RTL coding guidelines still state that I should have
different combinational and sequential blocks (which I already
follow), but at the same time my current project requires that I use
as less resources on my FPGA as possible. So maybe if I were to use
just one always block, I might save Logic cells on the FPGA.
This is a little puzzling. One should be able to code the designs so
that they have identical behavior and identical synthesis results.
Review your changes to the original code and see if you have added
more logic (do a formal comparison between two rtl blocks if you have
a tool). Try a different synthesis tool and see if the results are the
same.

Muzaffer Kal
DSPIA INC.
http://www.dspia.com
 
On Aug 28, 1:28 pm, Mike Treseler <mtrese...@gmail.com> wrote:
jprovide...@yahoo.com wrote:
I have seen people that like to separate the next state logic from
the
clocked logic in state machines. This potentially makes decoding
outputs
for a Mealy state machine more concise to code. Thus you end up with
a
structure similar to the "officially sanctioned" organizations desired
by
the OP.

The OP said nothing about Mealy machines or
"officially sanctioned" organizations.

He asked if he should "bring it to the notice of the manager"
I have found that this is almost always a bad idea.

Looks to me like the reviewee has
more language savvy than the reviewer,
and bringing the boss into the loop won't help.

-- Mike Treseler
Thanks for all the help, everybody! I must say this discussion has
forced me to think whether all that I learnt the text book way is
actually the best thing. In fact, I did a small experiment - I
synthesized a piece of Verilog code (from the same guy whose code I
am looking at). First I synthesized it as is, and then I split the
code into sequential and combinational blocks and re-synthesized. The
synthesis results were better for the original. Splitting the design
into two always blocks used up more Logic cells (I was targetting an
Altera FPGA)

ANother strange observation that I made - when the sensitivity list
has only the clock and reset, it doesn't complain about or generate
latches for missing assignments (let's say a missing "else" part to an
"if" and so on). However, the moment the design was spilt into
sequential and combinational, every bit of every signal had to be
assigned a default value, and all "if" statements had to be matched
with "else", otherwise (obviously), latches were generated.


So my next questions are as follows:

1. Assuming that having everything in one always block with just the
reset and clock in the sensitivity list is better, why doesn't the
synthesis tool complain about any missing "else" statements or missing
bit assignments? And why does it not generate latches?

2. I am totally confused as to which style should be adopted. Is it
that one is better for ASICs and the other better for FPGAs?

3. My company RTL coding guidelines still state that I should have
different combinational and sequential blocks (which I already
follow), but at the same time my current project requires that I use
as less resources on my FPGA as possible. So maybe if I were to use
just one always block, I might save Logic cells on the FPGA.


Please advise!

Thanks
kb33
 
On Aug 28, 1:16 pm, kb33 <kanchan.devarako...@gmail.com> wrote:
1. Assuming that having everything in one always block with just the
reset and clock in the sensitivity list is better, why doesn't the
synthesis tool complain about any missing "else" statements or missing
bit assignments? And why does it not generate latches?
In a clocked process, assignments to a signal represent clocked
registers. Missing assignments result in clock enables (disabled) on
those registers. It is impossible to infer a latch from a clocked
process (another advantage).

2. I am totally confused as to which style should be adopted. Is it
that one is better for ASICs and the other better for FPGAs?
I believe the single block style is superior for both. YMMV

3. My company RTL coding guidelines still state that I should have
different combinational and sequential blocks (which I already
follow), but at the same time my current project requires that I use
as less resources on my FPGA as possible. So maybe if I were to use
just one always block, I might save Logic cells on the FPGA.
Sometimes code that results in feedback muxes with two block
representations can result in clock enables with single block
representations. Otherwise, I am not aware of any inherent resource
utilization differences between results for functionally equivalent
single and dual block representations.

Andy
 
Your style is good. General speaking, "posedge or negedge" in always
activity list , the circuit is sequential circuit. and other wire or
reg type in always activity list, the circuit is combinational
circuit. the same function using the different verilog description
always produces synthesis result.
 
googler wrote:

Why is a single block style superior?
Read this thread for several advantages.

Isn't it almost always
recommended that for designing state machines the logic for next state
should go into a combinational 'always' block and that for updating
the current state should go into a clocked 'always' block?
If it were, would counters have to be constructed that way as well?


-- Mike Treseler
 
On Aug 28, 1:36 pm, Andy <jonesa...@comcast.net> wrote:
On Aug 28, 1:16 pm, kb33 <kanchan.devarako...@gmail.com> wrote:
<snip>

2. I am totally confused as to which style should be adopted. Is it
that one is better for ASICs and the other better for FPGAs?

I believe the single block style is superior for both. YMMV
Why is a single block style superior? Isn't it almost always
recommended that for designing state machines the logic for next state
should go into a combinational 'always' block and that for updating
the current state should go into a clocked 'always' block? I think
this is what the OP had in mind when he asked the original question
and that is what he is confused about. However, in the example
provided by the OP, the design is not that of a state machine and the
combo 'always' block seems completely unnecessary.
 
On Aug 29, 12:52 am, Mike Treseler <mtrese...@gmail.com> wrote:
googler wrote:
Why is a single block style superior?

Read this thread for several advantages.

Isn't it almost always
recommended that for designing state machines the logic for next state
should go into a combinational 'always' block and that for updating
the current state should go into a clocked 'always' block?

If it were, would counters have to be constructed that way as well?

   -- Mike Treseler
The case of counters is too simple (very much like the OP's original
example). I was talking about a state machine in general. The OP
seemed confused, so I thought some general guideline would help him.
 
On Aug 28, 11:35 pm, googler <pinaki_...@yahoo.com> wrote:
Why is a single block style superior? Isn't it almost always
recommended that for designing state machines the logic for next state
should go into a combinational 'always' block and that for updating
the current state should go into a clocked 'always' block?
Many (most?) textbooks still recommend separate combinatorial and
registered blocks. Textbooks are notoriously not up to date with the
latest developments.

The earliest synthesis tools were not able to infer registers from
block code, so they had to be instantiated, but the combinatorial
logic could be inferred (and optimized) from combinatorial blocks.
When synthesis tools gained the ability to infer registers from
clocked blocks, the simplest change to the existing coding style (and
tools) was to simply replace the register instantiations with clocked
blocks, and leave the combinatorial blocks alone. Later (>10 years
ago), tools got better and more users started combining the two.

Many (most?) users prefer registered outputs from state machines,
where there is no benefit to separate state/next_state
representations.

Andy
 

Welcome to EDABoard.com

Sponsor

Back
Top