3
\$\begingroup\$

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

\$\endgroup\$
0
2
\$\begingroup\$

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.

Note: @* is the same as @(potentially long list), but it is less error-prone. There is no need to maintain the list. For example, your list should include CurrentState, but it does not. @* does. Refer to IEEE Std 1800-2012, section 9.4.2.2 Implicit event_expression list.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ You could also make NextState an output reg and eliminate the need for a separate signal (NestStateOut) \$\endgroup\$
    – Greg
    Apr 26 '15 at 0:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.