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

This site is temporarily in read only mode and not accepting new answers.

Not the answer you're looking for? Browse other questions tagged .