Endliche Zustandsmaschine

Ich habe versucht, einen Verilog-Code für die endliche Zustandsmaschine zu schreiben, deren Diagramm unten gezeigt wird. Ich sehe nichts als Ausgabe. Was ist der falsche Teil meines Codes? oder Ist mein Code völlig absurd?

Mein 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

Zustandsdiagramm:

Geben Sie hier die Bildbeschreibung ein

Antworten (1)

Ein FSM hat typischerweise 2 Always-Blöcke: 1 sequentiell (mit einer Uhr), 1 kombinatorisch (ohne Uhr). Angenommen, Sie haben eine Uhr und einen asynchronen Reset (ungetestet):

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

Einige Modifikationen:

  1. Combo blockiert immer Verwendungen@*
  2. Verwenden Sie blockierende Zuweisungen ( =) im Kombinationsblock
  3. Verwenden Sie in der letzten Zuweisung den S0-Parameter anstelle von 2'b00.

Hinweis: @*ist dasselbe wie @(potentially long list), aber weniger fehleranfällig. Eine Pflege der Liste ist nicht erforderlich. Ihre Liste sollte beispielsweise enthalten CurrentState, ist es aber nicht. @*tut. Siehe IEEE Std 1800-2012, Abschnitt 9.4.2.2 Implicit event_expression list .

Sie könnten auch NextStateeine machen output regund die Notwendigkeit für ein separates Signal beseitigen ( NestStateOut)