1

So I am pretty new to Verilog and I am trying to write a simple FSM.

Input a is a push button and by pushing it starts the machine. But every other next state, after initially pressing a, causes to go back to the start/initial state.

input clk, reset;
input a,b,c;

reg [1:0] state;
reg [1:0] nextstate;

parameter = START=2b'0,
            STATE1=2b'1,
            STATE2=2b'11;

always @(posedge clk)
 if(reset) state <= START;
 else state<=nextstate;

always @(state, a)
 case (state)
   START: begin if(a) nextstate<=STATE1; else nextstate<=START; end
   STATE1: begin if(a) nextstate<=START; else if(b) nextstate<=STATE2; else nextstate<=STATE1; end
   STATE2: begin if(a) nextstate<=START; else if(c) nextstate<=STATE1; else nextstate<=STATE2; end
 endcase

Keeping your finger on a now means my state is alternating between STATE1 and START every positive edge of clk. How do I fix this?

e19293001
  • 2,783
  • 9
  • 42
  • 54
Bude
  • 13
  • 5

1 Answers1

0

A simple solution is to track the "edge" of the button, rather than the current state. For example:

reg aPressed, aPrev;
always @(posedge clk)
    aPrev<=a;

always@(*)
    if (a&&!aPrev) // a is high now, but was low last cycle
        aPressed = 1;
    else
        aPressed = 0;

In this code, aPressed is asserted only when a was low last cycle, and is high now (i.e. it was just pressed). If you replace a with aPressed in your next state logic, the user will be required to release a for a least one cycle before aPressed will trigger again.

always @(*)
    case (state)
        START: begin 
            if(aPressed) nextstate=STATE1; 
            else nextstate=START;
         end
        STATE1: begin 
            if(aPressed) nextstate=START; 
            else if(b) nextstate=STATE2;
            else nextstate=STATE1; 
        end
        STATE2: begin 
            if(aPressed) nextstate=START; 
            else if(c) nextstate=STATE1; 
            else nextstate=STATE2; 
        end
     endcase

Side note: it's good practice to use always@(*) for combinational logic, rather than specifying the sensitivity list (always@(state,a))

wilcroft
  • 1,580
  • 2
  • 14
  • 20
  • Here is a similar topic on your answer: [Proper way for signal edge detection in Verilog](http://stackoverflow.com/questions/8413661/proper-way-for-signal-edge-detection-in-verilog) – e19293001 Jan 01 '16 at 13:05