FSM single process...BIG question

C

carlob

Guest
Hi all,
I've a problem to efficiently unregister output from FSM written in
single process style...

in FSM synch process (don't pay attention to syntax..):

case IDLE:
if (pippo = '1') then
next_state <= START;
if (pluto = '1') then
outp <= '0';
else
outp <= '1';
end if;
end if;

outp is registered...if I want to avoid that register I should (in anothe
process) duplicate a lot of logic:

if (state = IDLE) then
if (pippo = '1' and pluto = '1') then
outp <= '0'
elsif (pippo = '1' and pluto = '0') then
outp <= '1';
else outp <= 'Z' -- for example
end if;
end if;

Is it possible to unregister output without duplicating that logic (I
seems to me very poor coding...)...

I've read something about using variables...but I don't understand exactl
how...please show me an example...

Thanx for any help
Carlo



---------------------------------------
Posted through http://www.FPGARelated.com
 
On 12/2/2010 6:43 AM, carlob wrote:

I've a problem to efficiently unregister output from FSM written in a
single process style...

I've read something about using variables...but I don't understand exactly
how...please show me an example...
For such a simple case, you could more quickly rewrite the code.

If you are interested in using vhdl variables, and have some spare time,
here is how I do it:

begin -- process template
if reset = '1' then -- Assumes synched trailing edge reset
init_regs; -- reg_v := init_c; No port init required
elsif rising_edge(clock) then
update_regs; -- reg_v := f(in, var)
-- no port update need here
end if; --
update_ports; -- out_port <= reg_v; -- sync outputs
-- out_port <= f(in, var) -- asych out
end process sync_template; -- will infer port wires ok rst or clk
end architecture synth;

Details here:
http://mysite.ncnetwork.net/reszotzl/sync_template.vhd
http://mysite.ncnetwork.net/reszotzl

Good luck
-- Mike Treseler
 
On Dec 2, 9:43 am, "carlob" <carlo.beccia@n_o_s_p_a_m.libero.it>
wrote:
Hi all,
I've a problem to efficiently unregister output from FSM written in a
single process style...

in FSM synch process (don't pay attention to syntax..):

case IDLE:
if (pippo = '1') then
next_state <= START;
if (pluto = '1') then
outp <= '0';
else
outp <= '1';
end if;
end if;

outp is registered...if I want to avoid that register I should (in another
process) duplicate a lot of logic:

if (state = IDLE) then
if (pippo = '1' and pluto = '1') then
outp <= '0'
elsif (pippo = '1' and pluto = '0') then
outp <= '1';
else outp <= 'Z' -- for example
end if;
end if;

Is it possible to unregister output without duplicating that logic (It
seems to me very poor coding...)...

I've read something about using variables...but I don't understand exactly
how...please show me an example...
You might find it easier to separate the state machine from the state
register. Then you define all your state transitions and outputs in a
single process just as you have above, but not a clocked process.
Instead you need two signals, CurState and NxtState. The
combinatorial process updates NxtState in terms of CurState with
CurState and all the other input signals in the sensitivity list, just
as you have it written now with the outputs registered. The clocked
process just defines the CurState register in terms of the NxtState
signal. The clocked process is idiot simple and so does not duplicate
the code that you are worried about.

StateLogicPrc: process (CurState, pippo, pluto,...) begin
-- if (rising_edge(clk)) then -- remove this sequential stuff from
the process
-- so you are just left with the logic...
case CurState is
when IDLE:
if (pippo = '1') then
next_state <= START;
if (pluto = '1') then
outp <= '0';
else
outp <= '1';
end if;
end if;
....
end process StateLogicPrc;

StateRegPrc: process (rst, clk) begin
if (rst = '1') then
CurState <= StartingState;
elsif (rising_edge(clk)) then
CurState <= next_state;
end if;
end process StateRegPrc;

This style was taught in many text books some 10 years ago because
some felt the tools did a better job with the two processes
separated. Now the tools are pretty good no matter what and I think
this is only used when the output signals are not to be registered as
in your case.

Rick
 
Carlo,

You may already know this, but...

Your combinatorial process is not equivalent to the clocked process.
An unassigned signal is not driven to 'Z'; it creates a latch. Read
below for more information.

If this was just an unfortunate choice of "for example" please
disregard.

Andy

Hi,
first of all...thanx for your help....

The question is...basically in a case like that is better to use 2 proces
method...is it right??

I'm studing vhdl by myself and on every textbook I've found around the bes
way to code FSM is 2 process...
I started writing my code (in 2 process style)...but, taking a look at cod
written by others I see very often only 1 process...crazy...
I tried to implement some part in 1 process style because it seems to m
more "simple"..cleaner...but the output is registered and doesn't fit wel
with rest of the code (other FSM)...

I've started to ask me if there is a method to implement in a 1 proces
unregistered output FSM...

I've tried something like this:

variable v_tx_data : std_logic_vector(7 downto 0);
begin
if (reset='1') then
act_txd_state <= TXD_IDLE;
v_tx_data := (others => '0');
elsif (clk'event and clk ='1') then

case act_txd_state is

when TXD_IDLE =>
if (txValid = '1') then
if (dataIn = "00000000") then
v_tx_data := "01000000";
else v_tx_data := "11000000";
end if;
act_txd_state <= TXD_ACTIVE;
end if;

when TXD_ACTIVE =>
if (txReady = '1') then
act_txd_state <= TXD_END;
end if;

when TXD_END =>
v_tx_data := dataIn;
if (txValid = '0') then
act_txd_state <= TXD_IDLE;
end if;
end case;

end if;

tx_data <= v_tx_data;

Obviously v_tx_data is a FF...and the output is registered....I don't fin
any way to unregister output in a process like that...

Any hint??

Mike in you example output is registered or not?? eventually...how can
apply your 1 process example to the
above code???

Yes code is very simple...I've already coded a version with 2 process an
unregistered output...but, to better
understand, I would like to discover if it is possible in one process...

In general..better 1 process and registered outout or 2 process and choos
if un/register output???

Thanx
Carlo


---------------------------------------
Posted through http://www.FPGARelated.com
 
On Dec 2, 1:46 pm, Mike Treseler <mtrese...@gmail.com> wrote:
On 12/2/2010 6:43 AM, carlob wrote:

I've a problem to efficiently unregister output from FSM written in a
single process style...
I've read something about using variables...but I don't understand exactly
how...please show me an example...

For such a simple case, you could more quickly rewrite the code.

If you are interested in using vhdl variables, and have some spare time,
here is how I do it:

    begin  -- process template
       if reset = '1' then     -- Assumes synched trailing edge reset
          init_regs;           -- reg_v := init_c; No port init required
       elsif rising_edge(clock) then
          update_regs;         -- reg_v := f(in, var)
                               -- no port update need here
       end if;                 --
       update_ports;           -- out_port <= reg_v;     -- sync outputs
                               -- out_port <= f(in, var) -- asych out
    end process sync_template; -- will infer port wires ok rst or clk
end architecture synth;

Details here:http://mysite.ncnetwork.net/reszotzl/sync_template.vhdhttp://mysite.ncnetwork.net/reszotzl

Good luck
     -- Mike Treseler
Note that while out_port <= f(in, var), located after the clk/rst end
if statement, will produce combinatorial logic from in to out_port (or
out_sig), the simulation and synthesis will mismatch slightly. Outport
will only be updated on any event of clk or rst (i.e. both edges of
both) in simulation, but continously in hardware (i.e. any edge of
in). Whether this makes a difference is dependent upon what is reading
the out_port. This can be avoided by adding any "in" signals used as
such to the process sensitivity list.

If pluto is an input to the process, then the only way to do it and
retain the sim/hw matching behavior for all cases is to use a separate
combinatorial process. I generally do not like combinatorial paths
from in to out within a state machine, and will seek to implement it
in a register if at all possible.

Combinatorial processes, especially ones as complex as state machines
with nested case & if statements, are prone to create latches. Avoid
the combinatorial process, and avoid the possibility of a latch. If
you cannot avoid the combinatorial process, then at least add default
assignments for all output signals in the very beginning of the
process, before any conditional statements are executed. This is much
easier to write, and to review/audit, than the old addage to include
an else for every if, etc.

Andy
 
On Dec 2, 2:16 pm, rickman <gnu...@gmail.com> wrote:
On Dec 2, 9:43 am, "carlob" <carlo.beccia@n_o_s_p_a_m.libero.it
wrote:





Hi all,
I've a problem to efficiently unregister output from FSM written in a
single process style...

in FSM synch process (don't pay attention to syntax..):

case IDLE:
if (pippo = '1') then
next_state <= START;
if (pluto = '1') then
outp <= '0';
else
outp <= '1';
end if;
end if;

outp is registered...if I want to avoid that register I should (in another
process) duplicate a lot of logic:

if (state = IDLE) then
if (pippo = '1' and pluto = '1') then
outp <= '0'
elsif (pippo = '1' and pluto = '0') then
outp <= '1';
else outp <= 'Z' -- for example
end if;
end if;

Is it possible to unregister output without duplicating that logic (It
seems to me very poor coding...)...

I've read something about using variables...but I don't understand exactly
how...please show me an example...

You might find it easier to separate the state machine from the state
register.  Then you define all your state transitions and outputs in a
single process just as you have above, but not a clocked process.
Instead you need two signals, CurState and NxtState.  The
combinatorial process updates NxtState in terms of CurState with
CurState and all the other input signals in the sensitivity list, just
as you have it written now with the outputs registered.  The clocked
process just defines the CurState register in terms of the NxtState
signal.  The clocked process is idiot simple and so does not duplicate
the code that you are worried about.

StateLogicPrc: process (CurState, pippo, pluto,...) begin
  -- if (rising_edge(clk)) then  -- remove this sequential stuff from
the process
  -- so you are just left with the logic...
  case CurState is
    when IDLE:
      if (pippo = '1') then
        next_state <= START;
        if (pluto = '1') then
          outp <= '0';
        else
          outp <= '1';
        end if;
      end if;
...
end process StateLogicPrc;

StateRegPrc: process (rst, clk) begin
  if (rst = '1') then
    CurState <= StartingState;
  elsif (rising_edge(clk)) then
    CurState <= next_state;
  end if;
end process StateRegPrc;

This style was taught in many text books some 10 years ago because
some felt the tools did a better job with the two processes
separated.  Now the tools are pretty good no matter what and I think
this is only used when the output signals are not to be registered as
in your case.

Rick- Hide quoted text -

- Show quoted text -
Rick,

Your example illustrates exactly why combinatorial processes should be
avoided if possible. You have created a latch (or two)...

I've read your posts long enough to know that you are an experienced,
talented designer, and in any real design, you would have taken care
of it. But not everyone knows that they need to take care of it, or
knows how.

The best way to avoid a latch is to avoid a combinatorial process.
The 2nd best way is to include in every combinatorial process, a
default assignment for every output, right up front, before any
conditional logic. This is much easier and more fool-proof than simply
adding an else for every if.

Andy
 
Carlo,

You may already know this, but...

Your combinatorial process is not equivalent to the clocked process.
An unassigned signal is not driven to 'Z'; it creates a latch. Read
below for more information.

If this was just an unfortunate choice of "for example" please
disregard.

Andy
 
Yes code is very simple...I've already coded a version with 2 process and
unregistered output...but, to better
understand, I would like to discover if it is possible in one process...

In general..better 1 process and registered outout or 2 process and choose
if un/register output???
Why do you want to avoid the output register? Is it for latency or
resource usage? Is there really no other sollution?
I strongly suggest to register outputs whenever possible. For all
other cases I tend to use concurrent signal assignments. Of course I
use also combinatorical process in cases it would simplify concurrent
statements (which is seldom the case)

process (clk,rst)
if reset = active then
sig_a <= '0';
elsif rising_edge(clk)
sig_a <= input_a;
end if;
end process;

comb_out <= (sig_a xor input_a) when fsm_state=idle else '0';
 
On Dec 3, 4:05 am, Thomas Stanka <usenet_nospam_va...@stanka-web.de>
wrote:
Yes code is very simple...I've already coded a version with 2 process and
unregistered output...but, to better
understand, I would like to discover if it is possible in one process....

In general..better 1 process and registered outout or 2 process and choose
if un/register output???

Why do you want to avoid the output register? Is it for latency or
resource usage? Is there really no other sollution?
I strongly suggest to register outputs whenever possible. For all
other cases I tend to use concurrent signal assignments. Of course I
use also combinatorical process in cases it would simplify concurrent
statements (which is seldom the case)

process (clk,rst)
if reset = active then
  sig_a <= '0';
elsif rising_edge(clk)
 sig_a <= input_a;
end if;
end process;

comb_out <= (sig_a xor input_a) when fsm_state=idle else '0';
I agree with Thomas; in register-rich environment, use those regs.
Great for portability, modularity, and performance.

I find the choices of fsm coding styles fascinating. Myself, I use the
dual method (make sure all inputs in sensitivity list of comb.
process!), but I always keep my "control" signals separate from either
of these processes, and try to register those as well. (e.g. in
clocked process, if ((pstate = s3) OR (pstate = s4) mux_select <DATA_A; else mux_select <= DATA_B;)

But what's the desire to combine all processes into one? It certainly
is efficient coding; only one clk/reset structure. But I find that
method somewhat confusing to read and understand. In fact, when I have
to understand someone else's consolidated code, I'll rewrite it
stripping out everything but the fsm states. I'd rather read my FSM
flow in one process and my control variables somewhere else, but I
realize some designers feel the opposite way...
John
 
Yes code is very simple...I've already coded a version with 2 proces
and
unregistered output...but, to better
understand, I would like to discover if it is possible in on
process...

In general..better 1 process and registered outout or 2 process an
choose
if un/register output???

Why do you want to avoid the output register? Is it for latency or
resource usage? Is there really no other sollution?
I strongly suggest to register outputs whenever possible. For all
other cases I tend to use concurrent signal assignments. Of course I
use also combinatorical process in cases it would simplify concurrent
statements (which is seldom the case)

process (clk,rst)
if reset = active then
sig_a <= '0';
elsif rising_edge(clk)
sig_a <= input_a;
end if;
end process;

comb_out <= (sig_a xor input_a) when fsm_state=idle else '0';


Hi,
that's only because that is a simple fsm inside a project...and 1 cloc
latency on that signal doesn't fit with other modules....
Yes...I agree with you...I tend to use registers when possible...using
process style (till now) you have to take care of registering outpu
therefore is up to you to decide...

Thanx
Carlo


---------------------------------------
Posted through http://www.FPGARelated.com
 
On Dec 3, 4:05=A0am, Thomas Stanka <usenet_nospam_va...@stanka-web.de
wrote:
Yes code is very simple...I've already coded a version with 2 proces
a=
nd
unregistered output...but, to better
understand, I would like to discover if it is possible in on
process..=
.

In general..better 1 process and registered outout or 2 process an
cho=
ose
if un/register output???

Why do you want to avoid the output register? Is it for latency or
resource usage? Is there really no other sollution?
I strongly suggest to register outputs whenever possible. For all
other cases I tend to use concurrent signal assignments. Of course I
use also combinatorical process in cases it would simplify concurrent
statements (which is seldom the case)

process (clk,rst)
if reset =3D active then
=A0 sig_a <=3D '0';
elsif rising_edge(clk)
=A0sig_a <=3D input_a;
end if;
end process;

comb_out <=3D (sig_a xor input_a) when fsm_state=3Didle else '0';

I agree with Thomas; in register-rich environment, use those regs.
Great for portability, modularity, and performance.

I find the choices of fsm coding styles fascinating. Myself, I use the
dual method (make sure all inputs in sensitivity list of comb.
process!), but I always keep my "control" signals separate from either
of these processes, and try to register those as well. (e.g. in
clocked process, if ((pstate =3D s3) OR (pstate =3D s4) mux_select <=3D
DATA_A; else mux_select <=3D DATA_B;)

But what's the desire to combine all processes into one? It certainly
is efficient coding; only one clk/reset structure. But I find that
method somewhat confusing to read and understand. In fact, when I have
to understand someone else's consolidated code, I'll rewrite it
stripping out everything but the fsm states. I'd rather read my FSM
flow in one process and my control variables somewhere else, but I
realize some designers feel the opposite way...
John
Hi,
I would like to go deep in both methods...I already manage 2 process....no
I would like to improve the 1 process knowledge to better fit my style t
every situation...

My conclusion is...when your output is regstered (probably very goo
choise) better to use 1 process style...when some/all outputs ar
unregistered better dive in 2 process style...that give more flexibilit
even if is more prone to errors (sensitivity list, inferred latc
etc..)...

Do you agree???

Thanx
Carlo

---------------------------------------
Posted through http://www.FPGARelated.com
 
Textbooks are seldom about state of the art in anything. Just because
they seem to be in unanimous agreement about one coding method does
not mean that the state of the art agrees. Two-process FSMs require
twice the declarations, require complex sensitivity lists, require
additional code to avoid latches, prohibit using variables to keep
local data local, thwart simulation optimizations that take advantage
of common sensitivity lists, and a host of other problems.

There are two different practical issues at play here. One is whether
an output is a combinatorial function of just the state, and one is
whether the output is a also a combinatorial function of some
combinatorial inputs.

The former can be mitigated by assigning registered outputs
"early" (i.e. when the FSM transitions to the state, not just when the
FSM is already in the state), or by assigning outputs from the state
variable after the clocked if statement ends.

You appear to want the output to be the latter: a combinatorial
function of the registered state and of the unregistered inputs.

While you can combine both into one process (with the combinatorial
input in the sensitivity list) as Mike has suggested, that is asking
for trouble, and if you don't correct the sensitivity list, then the
simulation and synthesis results will differ slightly, depending on
how/when the output is read by other processes/hardware. It is also
potentially prone to creating latches, to which a simple clocked
process is immune.

You really should create this output in a separate process (or
concurrent assignment), but there is no need to separate the FSM into
two processes.

The best way to avoid latches is to avoid combinatorial processes.
If you cannot avoid a combinatorial process, keep it as simple as
possible (doing only what has to be done combinatorially) and use up
front default assignments.

I would suggest you look at your design requirements, and decide what
must be combinatorial, and what can tolerate a clock delay.

Do you need to avoid a clock delay between tx_valid and tx_data?
Do you need to avoid a clock delay between data_in and tx_data?
Do you need to avoid a clock delay between tx_ready and tx_data?

Make sure you really need to avoid that clock delay. "It would be
better if..." does not count. A working design that is simple to
write, understand and maintain is much better than a design that is
none of those but happens to be a clock cycle faster.

Find a way to accomplish combinatorially only what needs to be
combinatorial. It appears that tx_data is merely a function of
tx_valid, tx_ready, and data_in. What exactly do you need an FSM for?
You could use an FSM for error handling (what happens if tx_valid goes
high, then low, and tx_ready never fired?). But you don't appear to be
using it for that (maybe just to simplify the example?).

Andy
 
On Dec 2, 5:46 pm, Andy <jonesa...@comcast.net> wrote:
On Dec 2, 2:16 pm, rickman <gnu...@gmail.com> wrote:



On Dec 2, 9:43 am, "carlob" <carlo.beccia@n_o_s_p_a_m.libero.it
wrote:

Hi all,
I've a problem to efficiently unregister output from FSM written in a
single process style...

in FSM synch process (don't pay attention to syntax..):

case IDLE:
if (pippo = '1') then
next_state <= START;
if (pluto = '1') then
outp <= '0';
else
outp <= '1';
end if;
end if;

outp is registered...if I want to avoid that register I should (in another
process) duplicate a lot of logic:

if (state = IDLE) then
if (pippo = '1' and pluto = '1') then
outp <= '0'
elsif (pippo = '1' and pluto = '0') then
outp <= '1';
else outp <= 'Z' -- for example
end if;
end if;

Is it possible to unregister output without duplicating that logic (It
seems to me very poor coding...)...

I've read something about using variables...but I don't understand exactly
how...please show me an example...

You might find it easier to separate the state machine from the state
register. Then you define all your state transitions and outputs in a
single process just as you have above, but not a clocked process.
Instead you need two signals, CurState and NxtState. The
combinatorial process updates NxtState in terms of CurState with
CurState and all the other input signals in the sensitivity list, just
as you have it written now with the outputs registered. The clocked
process just defines the CurState register in terms of the NxtState
signal. The clocked process is idiot simple and so does not duplicate
the code that you are worried about.

StateLogicPrc: process (CurState, pippo, pluto,...) begin
-- if (rising_edge(clk)) then -- remove this sequential stuff from
the process
-- so you are just left with the logic...
case CurState is
when IDLE:
if (pippo = '1') then
next_state <= START;
if (pluto = '1') then
outp <= '0';
else
outp <= '1';
end if;
end if;
...
end process StateLogicPrc;

StateRegPrc: process (rst, clk) begin
if (rst = '1') then
CurState <= StartingState;
elsif (rising_edge(clk)) then
CurState <= next_state;
end if;
end process StateRegPrc;

This style was taught in many text books some 10 years ago because
some felt the tools did a better job with the two processes
separated. Now the tools are pretty good no matter what and I think
this is only used when the output signals are not to be registered as
in your case.

Rick- Hide quoted text -

- Show quoted text -

Rick,

Your example illustrates exactly why combinatorial processes should be
avoided if possible. You have created a latch (or two)...

I've read your posts long enough to know that you are an experienced,
talented designer, and in any real design, you would have taken care
of it. But not everyone knows that they need to take care of it, or
knows how.

The best way to avoid a latch is to avoid a combinatorial process.
The 2nd best way is to include in every combinatorial process, a
default assignment for every output, right up front, before any
conditional logic. This is much easier and more fool-proof than simply
adding an else for every if.

Andy
I wasn't going to provide any code to the OP mainly because I didn't
have time to worry with it. But I saw that a verbal explanation
wasn't very good and I thought I could get away with a quick edit of
his code. Obviously I made a mistake, but that doesn't make
combinatorial processes bad. You can also create latches in
concurrent statements too. Should you avoid using them as well?

I remember when I was just learning VHDL there were things about using
integers and variables that I just didn't get. I posted that someone
should avoid using them. I was chided for that and I have remembered
it since.

Just because you don't know how to use a feature effectively doesn't
mean no one else should.

Rick
 
On Dec 3, 7:58 am, "carlob"
<carlo.beccia@n_o_s_p_a_m.n_o_s_p_a_m.libero.it> wrote:
On Dec 3, 4:05=A0am, Thomas Stanka <usenet_nospam_va...@stanka-web.de
wrote:
Yes code is very simple...I've already coded a version with 2 process
a> >nd
unregistered output...but, to better
understand, I would like to discover if it is possible in one
process..> >.

In general..better 1 process and registered outout or 2 process and
cho> >ose
if un/register output???

Why do you want to avoid the output register? Is it for latency or
resource usage? Is there really no other sollution?
I strongly suggest to register outputs whenever possible. For all
other cases I tend to use concurrent signal assignments. Of course I
use also combinatorical process in cases it would simplify concurrent
statements (which is seldom the case)

process (clk,rst)
if reset =3D active then
=A0 sig_a <=3D '0';
elsif rising_edge(clk)
=A0sig_a <=3D input_a;
end if;
end process;

comb_out <=3D (sig_a xor input_a) when fsm_state=3Didle else '0';

I agree with Thomas; in register-rich environment, use those regs.
Great for portability, modularity, and performance.

I find the choices of fsm coding styles fascinating. Myself, I use the
dual method (make sure all inputs in sensitivity list of comb.
process!), but I always keep my "control" signals separate from either
of these processes, and try to register those as well. (e.g. in
clocked process, if ((pstate =3D s3) OR (pstate =3D s4) mux_select <=3D
DATA_A; else mux_select <=3D DATA_B;)

But what's the desire to combine all processes into one? It certainly
is efficient coding; only one clk/reset structure. But I find that
method somewhat confusing to read and understand. In fact, when I have
to understand someone else's consolidated code, I'll rewrite it
stripping out everything but the fsm states. I'd rather read my FSM
flow in one process and my control variables somewhere else, but I
realize some designers feel the opposite way...
John

Hi,
I would like to go deep in both methods...I already manage 2 process....now
I would like to improve the 1 process knowledge to better fit my style to
every situation...

My conclusion is...when your output is regstered (probably very good
choise) better to use 1 process style...when some/all outputs are
unregistered better dive in 2 process style...that give more flexibility
even if is more prone to errors (sensitivity list, inferred latch
etc..)...

Do you agree???
I agree that I evaluate every case on its own merits. The other thing
you could do is to use one process for the state machine and then use
concurrent statements for the outputs. I don't use combinatorial
processes very often. There are also times when I use concurrent
statements for intermediate logic in the state machine. It all
depends on what is more clear and that would be up to you to decide.

Rick
 
Hi Andy,
as you can understand I'm not an expert.....

The former can be mitigated by assigning registered outputs
"early" (i.e. when the FSM transitions to the state, not just when the
FSM is already in the state), or by assigning outputs from the state
variable after the clocked if statement ends.

pYou appear to want the output to be the latter: a combinatorial
function of the registered state and of the unregistered inputs.
Could you elaborate better on this with an example on my FSM???

Find a way to accomplish combinatorially only what needs to be
combinatorial. It appears that tx_data is merely a function of
tx_valid, tx_ready, and data_in. What exactly do you need an FSM for?
You could use an FSM for error handling (what happens if tx_valid goes
high, then low, and tx_ready never fired?). But you don't appear to be
using it for that (maybe just to simplify the example?).

Andy
Uhmm...I've written a fsm manly to describe the interface...the outpu
becomes "01000000"/"11000000" when tx_valid goes high depending on dat
input...then stay on that value till tx_ready becomes high....at that poin
(on the next clock cycle) tx_data will be equal to datain till tx_vali
goes to '0'...yes..I miss probably some error handling...the code is no
completely written...

Every signal on output should change when clock raise...and every signal i
input should change/be checked according to the same cloc
front....input/output interfaces are synchronous to the clock...
How do you describe all this combinatorially???
More simple ways are welcome....if you/somebody wanna help me... :))

Thanx
Carlo

---------------------------------------
Posted through http://www.FPGARelated.com
 
Andy
I've tried one of your suggestion...tell me if I'm wrong (this is a quic
written code...probably there are mistakes...pay attention t
principle..)...

if (reset='1') then
act_txd_state := TXD_IDLE;
v_delay := '0';
elsif (clk'event and clk ='1') then

v_delay := '0';
case act_txd_state is

when TXD_IDLE =>
if (txValid = '1') then
act_txd_state := TXD_ACTIVE;
end if;

when TXD_ACTIVE =>
if (txReady = '1') then
v_delay := '1';
act_txd_state := TXD_END;
end if;

when TXD_END =>
if (txValid = '0') then
act_txd_state := TXD_IDLE;
end if;
end case;

end if;

if (act_txd_state = TXD_ACTIVE) OR (v_delay = '1')then
if (dataIn = "00000000") then
tx_data <= "01000000";
else
tx_data <= "11000000";
end if;
elsif (act_txd_state = TXD_END) then
tx_data <= dataIn;
else
tx_data <= "00000000";
end if;

This "should" be equivalent (not tested yet)...I've used v_delay FF t
delay 1 clock the output change between ACTIVE and END...I've no mor
registered output...but I've been forced to add dataIn in the sensitivit
list (to avoid latches)...

That is change you were talking about??

Thanx
Carlo



---------------------------------------
Posted through http://www.FPGARelated.com
 
On Dec 3, 12:42 pm, Andy <jonesa...@comcast.net> wrote:
Textbooks are seldom about state of the art in anything. Just because
they seem to be in unanimous agreement about one coding method does
not mean that the state of the art agrees. Two-process FSMs require
twice the declarations, require complex sensitivity lists, require
additional code to avoid latches, prohibit using variables to keep
local data local, thwart simulation optimizations that take advantage
of common sensitivity lists, and a host of other problems.

There are two different practical issues at play here. One is whether
an output is a combinatorial function of just the state, and one is
whether the output is a also a combinatorial function of some
combinatorial inputs.

The former can be mitigated by assigning registered outputs
"early" (i.e. when the FSM transitions to the state, not just when the
FSM is already in the state), or by assigning outputs from the state
variable after the clocked if statement ends.

You appear to want the output to be the latter: a combinatorial
function of the registered state and of the unregistered inputs.

While you can combine both into one process (with the combinatorial
input in the sensitivity list) as Mike has suggested, that is asking
for trouble, and if you don't correct the sensitivity list, then the
simulation and synthesis results will differ slightly, depending on
how/when the output is read by other processes/hardware. It is also
potentially prone to creating latches, to which a simple clocked
process is immune.

You really should create this output in a separate process (or
concurrent assignment), but there is no need to separate the FSM into
two processes.

The best way to avoid latches is to avoid combinatorial processes.
If you cannot avoid a combinatorial process, keep it as simple as
possible (doing only what has to be done combinatorially) and use up
front default assignments.

I would suggest you look at your design requirements, and decide what
must be combinatorial, and what can tolerate a clock delay.

Do you need to avoid  a clock delay between tx_valid and tx_data?
Do you need to avoid a clock delay between data_in and tx_data?
Do you need to avoid a clock delay between tx_ready and tx_data?

Make sure you really need to avoid that clock delay. "It would be
better if..." does not count. A working design that is simple to
write, understand and maintain is much better than a design that is
none of those but happens to be a clock cycle faster.

Find a way to accomplish combinatorially only what needs to be
combinatorial. It appears that tx_data is merely a function of
tx_valid, tx_ready, and data_in. What exactly do you need an FSM for?
You could use an FSM for error handling (what happens if tx_valid goes
high, then low, and tx_ready never fired?). But you don't appear to be
using it for that (maybe just to simplify the example?).

Andy
General rule of thumb is that for the very best performance, limit
combinatorial block of logic to fanin that can be contained in one LUT
of target FPGA fabric. The idea is that you can't go much faster than
into one LUT-REG combination. For larger fanins, either use pipelining
(for instance, one might have to pipeline large N-bit comparators into
multiple clocked stages) or designer will have to rely on tool's
efforts in keeping source/destination flops close to combinatorial
implementation--at which time floorplanning (i.e. grouping)
necessities may rear its ugly head.

On FSMs, I don't think either one or two processes is "right" or
"wrong." Each has its drawbacks. It is up to the hardware designer to
adopt a style and routine of coding it right to meet project
requirements. Over time, the designer will be able to draw up and
debug that style very efficiently because of familiarity.
John
 
On Dec 3, 4:05 am, Thomas Stanka <usenet_nospam_va...@stanka-web.de>
wrote:
Yes code is very simple...I've already coded a version with 2 process and
unregistered output...but, to better
understand, I would like to discover if it is possible in one process....

In general..better 1 process and registered outout or 2 process and choose
if un/register output???

Why do you want to avoid the output register? Is it for latency or
resource usage? Is there really no other sollution?
I strongly suggest to register outputs whenever possible. For all
other cases I tend to use concurrent signal assignments. Of course I
use also combinatorical process in cases it would simplify concurrent
statements (which is seldom the case)

process (clk,rst)
if reset = active then
  sig_a <= '0';
elsif rising_edge(clk)
 sig_a <= input_a;
end if;
end process;

comb_out <= (sig_a xor input_a) when fsm_state=idle else '0';
Just to elaborate on Thomas Stanka's post...

Say that you've inherited a design that has a large FSM that had a
clocked process and the BRAM were from an old technology and
interfaced to the FSM with combinatorial inputs. The new device has
registered BRAM inputs so you want to get rid of a pipeline delay in
the FSM but want to keep the changes to a minimum.

I went through the exercise with the example to see how messy it would
be.

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity state_test is

port (
clk : in std_logic;
reset : in std_logic;
txValid : in std_logic;
txReady : in std_logic;
dataIn : in std_logic_vector(7 downto 0);

tx_data_out : out std_logic_vector(7 downto 0)
);

end state_test;

architecture behav of state_test is
type state_typ is (TXD_IDLE, TXD_ACTIVE, TXD_END);

signal act_txd_state : state_typ := TXD_IDLE;
signal tx_data_next, tx_data : std_logic_vector(7 downto 0);

begin
tx_data_out <= tx_data_next;

tx_data_next < "00000000" when reset '1'
else
"01000000" when ((act_txd_state = TXD_IDLE) and (txValid = '1')
and (dataIn = "00000000")) else
"11000000" when ((act_txd_state = TXD_IDLE) and (txValid = '1')
and (dataIn /= "00000000")) else
dataIn when ((act_txd_state TXD_END))
else
tx_data;

sync_proc : process (clk, reset) is
begin
if (reset = '1') then
act_txd_state <= TXD_IDLE;
tx_data <= (others => '0');
elsif (clk'event and clk = '1') then
tx_data <= tx_data_next;

case act_txd_state is

when TXD_IDLE =>
if (txValid = '1') then
act_txd_state <= TXD_ACTIVE;
end if;


when TXD_ACTIVE =>
if (txReady = '1') then
act_txd_state <= TXD_END;
end if;


when TXD_END =>
if (txValid = '0') then
act_txd_state <= TXD_IDLE;
end if;
end case;

end if;
end process sync_proc;
end behav;
 
I went through the exercise with the example to see how messy it would
be.

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity state_test is

port (
clk : in std_logic;
reset : in std_logic;
txValid : in std_logic;
txReady : in std_logic;
dataIn : in std_logic_vector(7 downto 0);

tx_data_out : out std_logic_vector(7 downto 0)
);

end state_test;

architecture behav of state_test is
type state_typ is (TXD_IDLE, TXD_ACTIVE, TXD_END);

signal act_txd_state : state_typ :=3D TXD_IDLE;
signal tx_data_next, tx_data : std_logic_vector(7 downto 0);

begin
tx_data_out <=3D tx_data_next;

tx_data_next <=3D
"00000000" when reset =3D
'1'
else
"01000000" when ((act_txd_state =3D TXD_IDLE) and (txValid =3D '1')
and (dataIn =3D "00000000")) else
"11000000" when ((act_txd_state =3D TXD_IDLE) and (txValid =3D '1')
and (dataIn /=3D "00000000")) else
dataIn when ((act_txd_state =3D
TXD_END))
else
tx_data;

sync_proc : process (clk, reset) is
begin
if (reset =3D '1') then
act_txd_state <=3D TXD_IDLE;
tx_data <=3D (others =3D> '0');
elsif (clk'event and clk =3D '1') then
tx_data <=3D tx_data_next;

case act_txd_state is

when TXD_IDLE =3D
if (txValid =3D '1') then
act_txd_state <=3D TXD_ACTIVE;
end if;


when TXD_ACTIVE =3D
if (txReady =3D '1') then
act_txd_state <=3D TXD_END;
end if;


when TXD_END =3D
if (txValid =3D '0') then
act_txd_state <=3D TXD_IDLE;
end if;
end case;

end if;
end process sync_proc;
end behav;
Yes...indeed that is the only way (or one of few ways) to eliminate th
output FF...
In some way it is "similar" to what I've written with variables but usin
concurrent signal assignment....effectively it is not a complete mess...

Anyway...probably I was wrong...I don't need to avoid registered outpu
(and a lot of you were right)...in fact I'm always assigning the "output
of a FF...therefore I'm sure that when fsm reach a state the output wil
change to the value that is required on that state on the same clock fron
and I don't have to wait for another clock front to have that value o
output...am I correct???

I saw it in simulation...looking at the RTL synthesys diagram wasn't clea
for me....I have, further, the advantage of registered output....

Probably I will rewrite everything (or the most part) in 1 proces
style...it seems more clear....I'm evaluating...

Thanx
Carlo

---------------------------------------
Posted through http://www.FPGARelated.com
 
Anyway...probably I was wrong...I don't need to avoid registered output
(and a lot of you were right)...in fact I'm always assigning the "output"
of a FF...therefore I'm sure that when fsm reach a state the output will
change to the value that is required on that state on the same cloc
front
and I don't have to wait for another clock front to have that value on
output...
This is not completely true...state change immediately if change conditio
is met...output is still at values on previous state...on the next cloc
front the output goes to the new state value...this is the effect of th
output FF...I'm sorry a misunderstanding....

...the difference is now clear....I've just simulated the tw
situations...(1 process, 2 process-no register)...and checked th
differences....

Anyway...since all input signals "should be sinchronous" to the raise fron
of the clock and the produced output MUST be synch I think that the bes
way to achieve that is registering output and evaluating input on cloc
raise...my previous implementation was wrong because output is allowed t
change asynchronously...I have to correct...and I think that 1 proces
style fit better the requirements...

If in some cases I will need to unreg output I will use concurren
statements outside of the process as pointed out in the discussion...

Thanx to everyone who helped me...
Carlo


---------------------------------------
Posted through http://www.FPGARelated.com
 

Welcome to EDABoard.com

Sponsor

Back
Top