Working on an FSM


L

laserbeak43

Hello,
I'm learning about FSMs and I'm having a hard time getting my code to
run correctly.
I'm getting errors that say the registers for my states won't hold
outside of the clock edge, and another set of errors saying that i
have multiple constant drivers that can't be resolved.

Does anyone think that they could help me out with this code? I've
truncated the switch, the full
source can be found here http://paste.org/pastebin/view/26824

Thanks
Malik

****************************************************************************************************************

LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;

entity part1take2 is
port(
CLOCK_50 : in std_logic;
SW : in unsigned(1 downto 0);
LEDR : out unsigned(8 downto 0)
);
end part1take2;

architecture behavioral of part1take2 is

type statet is ( A, B, C, D, E, F, G, H, I );
constant FMil: integer := 50000000;

signal count : unsigned(25 downto 0);
signal CLK : std_logic;
signal cstate, nstate : statet;
signal lstate : unsigned(8 downto 0);

begin

LEDR <= lstate;

process(CLK, SW, cstate)
begin

nstate <= cstate;
LEDR <= to_unsigned(0, 9);

if(SW(0) = '1') then
nstate <= A;
else
if(rising_edge(CLK)) then
case cstate is
when A =>
lstate <= to_unsigned(000000001, 9);
if(SW(1) = '1') then
nstate <= F;
else
nstate <= B;
end if;
when B =>
lstate <= to_unsigned(000000010, 9);
if(SW(1) = '1') then
nstate <= F;
else
nstate <= C;
end if;
t--truncated
end case;
end if;
end if;
end process;

process(CLOCK_50) begin

if rising_edge(CLOCK_50) then
if(count = FMil) then
CLK <= (not CLK);
if(CLK = '1') then
cstate <= nstate;
end if;
else
count <= count + 1;
end if;
end if;

end process;

end behavioral;
 
Ad

Advertisements

Joined
Mar 10, 2008
Messages
348
Reaction score
0
Hi

Try this instead - your next-state logic should be pure combinatorial

Code:
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;

entity part1take2 is
 port( 
  CLOCK_50 : in std_logic;
  SW   : in unsigned(1 downto 0);
  LEDR  : out unsigned(8 downto 0)
 );
end part1take2;

architecture behavioral of part1take2 is 
 
 type statet is ( A, B, C, D, E, F, G, H, I );
 constant FMil: integer := 50000000;
 
 signal count : unsigned(25 downto 0);
 signal CLK  : std_logic;
 signal cstate, nstate : statet;
 signal lstate : unsigned(8 downto 0);
 
begin
 
 LEDR <= lstate;
 
 process(CLK, SW, cstate) 
 begin
  
  nstate <= cstate;
  LEDR <= to_unsigned(0, 9);
  
  if(SW(0) = '1') then
   nstate <= A;
  else 
   -- not needed for combinatorial logic  => if(rising_edge(CLK)) then
    case cstate is
     when A =>
      lstate <= to_unsigned(000000001, 9);
      if(SW(1) = '1') then
       nstate <= F;
      else
       nstate <= B;
      end if;
     when B =>
      lstate <= to_unsigned(000000010, 9);
      if(SW(1) = '1') then
       nstate <= F;
      else
       nstate <= C;
      end if;
     when C =>
      lstate <= to_unsigned(000000100, 9);
      if(SW(1) = '1') then
       nstate <= F;
      else
       nstate <= D;
      end if;
     when D =>
      lstate <= to_unsigned(000001000, 9);
      if(SW(1) = '1') then
       nstate <= F;
      else
       nstate <= E;
      end if;
     when E =>
      lstate <= to_unsigned(000010000, 9);
      if(SW(1) = '1') then
       nstate <= F;
      else
       nstate <= E;
      end if;
     when F =>
      lstate <= to_unsigned(000100000, 9);
      if(SW(1) = '1') then
       nstate <= G;
      else
       nstate <= B;
      end if;
     when G =>
      lstate <= to_unsigned(001000000, 9);
      if(SW(1) = '1') then
       nstate <= H;
      else
       nstate <= B;
      end if;
     when H =>
      lstate <= to_unsigned(010000000, 9);
      if(SW(1) = '1') then
       nstate <= I;
      else
       nstate <= B;
      end if;
     when I =>
      lstate <= to_unsigned(100000000, 9);
      if(SW(1) = '1') then
       nstate <= I;
      else
       nstate <= B;
      end if;
    end case;
   ------------------- to be deleted  => end if;
  end if;
 end process;
 
 process(CLOCK_50) begin

  if rising_edge(CLOCK_50) then
   if(count = FMil) then
    CLK <= (not CLK);
    cstate <= nstate;
    count <= (others=>'0'); 
   else 
    count <= count + 1;
   end if;
  end if;
 
 end process;
 
end behavioral;
 
M

Mike Treseler

Hello,
I'm learning about FSMs and I'm having a hard time getting my code to
run correctly.
I'm getting errors that say the registers for my states won't hold
outside of the clock edge, and another set of errors saying that i
have multiple constant drivers that can't be resolved.

I use a single process (reset, clock)
This would fix most of your problems.

-- Mike Treseler
 
Joined
Jan 30, 2009
Messages
42
Reaction score
0
FSM Problem

It would help if you described what you are trying to do with the FSM and the counter.
 
J

JimLewis

Hi Malik,
1)
You have multiple drivers on LEDR.
One outside the process and one in the process.
For every signal assigned in a separate process
(and think of a concurrent assignment as a separate
process), a separate piece of hardware is created.
If you have more than one piece of hardware, you are
connecting outputs directly together in a bad way.

2)
You probably do not want derived clocks. Instead
use enables - you are kind of doing this with CLK in
the process that includes CLOCK_50. I suspect you do
not need the "rising_edge(CLK)" in the other process.

3)
You need to work on your logic revolving around count.
Does count ever go back to 0? Otherwise the condition,
count = FMil will only be true once.

You could probably evolve it to something that captures
the nstate when count = 2*FMil and resets count to 0,
and otherwise increments count.

4)
You need to simulate before you synthesize.


5)
Although Mike hates using more than one process to code
a statemachine, I prefer using two.

6)
The assignment "nstate <= cstate;" is called a default
assignment and can help you take short-cuts in some
statemachines, but looking at the rest of your statemachine,
you are neither using it nor would you benefit from it
(except in state E - and I am not going to use a default
assignment to help only in one state).

Good luck. Try the simulator.

Best,
Jim Lewis
 
R

rickman

Hello,
I'm learning about FSMs and I'm having a hard time getting my code to
run correctly.
I'm getting errors that say the registers for my states won't hold
outside of the clock edge, and another set of errors saying that i
have multiple constant drivers that can't be resolved.

Does anyone think that they could help me out with this code? I've
truncated the switch, the full
source can be found herehttp://paste.org/pastebin/view/26824

Thanks
Malik

****************************************************************************************************************

LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;

entity part1take2 is
        port(
                CLOCK_50        : in std_logic;
                SW                      : in unsigned(1 downto 0);
                LEDR            : out unsigned(8 downto 0)
        );
end part1take2;

architecture behavioral of part1take2 is

        type statet is ( A, B, C, D, E, F, G, H, I );
        constant FMil: integer := 50000000;

        signal count    : unsigned(25 downto 0);
        signal CLK              : std_logic;
        signal cstate, nstate : statet;
        signal lstate   : unsigned(8 downto 0);

begin

        LEDR <= lstate;

        process(CLK, SW, cstate)

In a clocked process only the clock and any async inputs should be in
the sensitivity list. This can make your simulation differ from the
synthesized logic. Remove cstate.
        begin

                nstate <= cstate;
                LEDR <= to_unsigned(0, 9);

These two lines are outside of the conditional clauses. That means
they are executed anytime any of the signals in the sensitivity list
change. There is no reasonable synthesizable logic that will match
this description. What are you trying to do with these two lines?
They are the ones giving the error.

                if(SW(0) = '1') then
                        nstate <= A;
                else
                        if(rising_edge(CLK)) then
                                case cstate is
                                        when A =>
                                                lstate <= to_unsigned(000000001, 9);
                                                if(SW(1) = '1') then
                                                        nstate <= F;
                                                else
                                                        nstate <= B;
                                                end if;
                                        when B =>
                                                lstate <= to_unsigned(000000010, 9);
                                                if(SW(1) = '1') then
                                                        nstate <= F;
                                                else
                                                        nstate <= C;
                                                end if;
                                        t--truncated
                                end case;
                        end if;
                end if;
        end process;

        process(CLOCK_50) begin

                if rising_edge(CLOCK_50) then
                        if(count = FMil) then
                                CLK <= (not CLK);
                                if(CLK = '1') then
                                        cstate <= nstate;
                                end if;
                        else
                                count <= count + 1;
                        end if;
                end if;

        end process;

end behavioral;

I also don't understand what you are trying to acheive with the two
processes. The second process synthesizes a clock for the first. The
values of cstate and nstate run through BOTH clocks, two registers!
One is clocked by the rising edge of CLK while the other is clocked by
the rising edget of CLOCK_50, but enabled when CLK is high which
roughly corresponds to the falling edge of CLK. Is that what you
intend?

BTW, to get the CLK <= not CLK; line to simulate you need to
initialize CLK in a reset statement or in the signal declaration. The
former will be synthesized while the latter may or may not be.

Rick
 
Ad

Advertisements

D

d_s_klein

In a clocked process only the clock and any async inputs should be in
the sensitivity list.  This can make your simulation differ from the
synthesized logic.  Remove cstate.

Rick

I suggest that only 'clock' and 'reset' be on the sensitivity list of
a clocked process.

RK
 
M

Martin Thompson

d_s_klein said:
I suggest that only 'clock' and 'reset' be on the sensitivity list of
a clocked process.

Good suggestion iff reset is an async input.

When using synchronous resets, then *only* clock should be in the
sensitivity list.

Cheers,
Martin
 
D

d_s_klein

Good suggestion iff reset is an async input.  

You are correct; all of the synthesis tools I have used behave exactly
as you describe.

I wonder how many understand that 'iff' is not a typo.

RK
 
Ad

Advertisements

M

Martin Thompson

d_s_klein said:
You are correct; all of the synthesis tools I have used behave exactly
as you describe.

And the simulators I hope - it's the way the language is specified!

[aside]
Of course, if you omit reset from the sensitivity list and then use it
in an "asynchronous" way in the process (outside of the "clocked" part),
all bets are off synthesis-behaviour-wise:

process (clk)
begin
if asyncreset = '1' then
-- do stuff on both clock edges when asyncreset is high!
elsif rising_edge(clk) then
-- do stuff on rising edges when syncreset is low...
end if;
end;

Some (all?) synthesisers will assume you meant to include reset in the
sensitivity list and synth an async reset. Whereas the simulator will
execute the reset clause on *every* clock edge, but the "normal"
clocked part on the rising edges.

I'm sure no-one would ever write code like that though :)
I wonder how many understand that 'iff' is not a typo.

I have to admit I wondered that as I wrote it...

Cheers,
Martin
 

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

Top