FSM Verilog - 1个按钮,用于启动和停止

时间:2015-12-31 15:36:03

标签: verilog fsm

所以我对Verilog很陌生,我正在尝试编写一个简单的FSM。

输入a是一个按钮,按启动机器。但是,在最初按a之后,每个其他下一个状态都会导致返回到开始/初始状态。

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

现在让您的手指a开始,意味着我的状态在STATE1的每个正边缘STARTclk之间交替显示。 我该如何解决这个问题?

1 个答案:

答案 0 :(得分:0)

一个简单的解决方案是跟踪边缘&#34;按钮,而不是当前状态。例如:

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;

在此代码中,aPressed仅在a最后一个周期为低时置位,并且现在为高(即仅按下它)。如果您在下一个状态逻辑中将a替换为aPressed,则系统会要求用户在a再次触发之前至少释放一个aPressed

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

附注:将 always@(*) 用于组合逻辑,而非指定敏感度列表always@(state,a),这是一种很好的做法)