Electronic – Finite State Machine

state-machinesverilog

I tried to write a Verilog code for the finite state machine whose diagram shown below. I see nothing as an output. What is the wrong part of my code? or Is my code completely absurd?

My code:

module FSM(D1,D2, NextState);
input D1,D2;
output [1:0] NextState;
reg [1:0] CurrentState=2'b00;
reg [1:0] NextStateOut;
parameter S0=2'b00, S1=2'b10, S2=2'b11, S3=2'b01;

always @(D1 or D2)
 begin
 case(CurrentState)
 S0:
 begin
    if(D1==1'b0 && D2==1'b0)
        NextStateOut <=S0;
    if(D1==1'b1 && D2==1'b0)
    begin
        NextStateOut <=S1;              
    end
end
S1:
begin
    if(D1==1'b0 && D2==1'b0)
    begin
        NextStateOut <=S0;          
    end
    if(D1==1'b1 && D2==1'b0)
        NextStateOut <=S1;
    if(D1==1'b1 && D2==1'b1)
    begin
        NextStateOut <=S2;                  
    end
end
S2:
begin
    if(D1==1'b1 && D2==1'b0)
    begin
        NextStateOut <=S1;      
    end
    if(D1==1'b1 && D2==1'b1)
        NextStateOut <=S2;
    if(D1==1'b0 && D2==1'b1)
    begin
        NextStateOut <=S3;                  
    end
end
S3:
begin
    if(D1==1'b1 && D2==1'b1)
    begin
        NextStateOut <=S2;
                end
    if(D1==1'b0 && D2==1'b1)
        NextStateOut <=S2;
    if(D1==1'b0 && D2==1'b0)
    begin
        NextStateOut <=2'b00;           
    end
end
endcase
CurrentState<= NextStateOut;
end
assign  NextState= NextStateOut;
endmodule

State diagram:

enter image description here

Best Answer

An FSM typically has 2 always blocks: 1 sequential (with a clock), 1 combinational (no clock). Assuming you have a clock and an asynchronous reset (untested):

module FSM(D1,D2, NextState, clk, rst);
input D1,D2,clk,rst;
output [1:0] NextState;
reg [1:0] CurrentState;
reg [1:0] NextStateOut;
parameter S0=2'b00, S1=2'b10, S2=2'b11, S3=2'b01;

always @(posedge clk or posedge rst) begin
    if (rst) begin
        CurrentState <= S0;
    end else begin
        CurrentState <= NextStateOut;
    end
end

always @*
 begin
 case(CurrentState)
 S0:
 begin
    if(D1==1'b0 && D2==1'b0)
        NextStateOut =S0;
    if(D1==1'b1 && D2==1'b0)
    begin
        NextStateOut =S1;              
    end
end
S1:
begin
    if(D1==1'b0 && D2==1'b0)
    begin
        NextStateOut =S0;          
    end
    if(D1==1'b1 && D2==1'b0)
        NextStateOut =S1;
    if(D1==1'b1 && D2==1'b1)
    begin
        NextStateOut =S2;                  
    end
end
S2:
begin
    if(D1==1'b1 && D2==1'b0)
    begin
        NextStateOut =S1;      
    end
    if(D1==1'b1 && D2==1'b1)
        NextStateOut =S2;
    if(D1==1'b0 && D2==1'b1)
    begin
        NextStateOut =S3;                  
    end
end
S3:
begin
    if(D1==1'b1 && D2==1'b1)
    begin
        NextStateOut =S2;
                end
    if(D1==1'b0 && D2==1'b1)
        NextStateOut =S2;
    if(D1==1'b0 && D2==1'b0)
    begin
        NextStateOut =S0;           
    end
end
endcase
end

assign  NextState= NextStateOut;

endmodule

Some modifications:

  1. Combo always block uses @*
  2. Use blocking assignments (=) in combo block
  3. Use S0 parameter instead of 2'b00 in last assignment.
Related Topic