在模擬時為狀態機加上名稱,可以清楚瞭解目前狀態就不用看著單調的數字了,因為ASCII一個字元需要8 bit,所以在定義儲存空間時需要把可能最大的字元數乘8,此例是假設最大字元數為10 (reg [8*10-1:0] StateName),再為每個狀態取名子,模擬時就能清楚知道目前狀態機的狀態。
////// … . .. –.. . – …. . — — — . -. – //////
// Author : TienYao
// Source Code Name : StateMachineName.v
// Function Description: For displaying state name in simulation
// ===========================================================
module StateMachineName
(
input CLK,
input nRST,
output [7:0] STATE_OUT
);
reg [3:0] current_state;
reg [3:0] next_state;
reg [7:0] rvCNT_q;
reg [7:0] rvCNT_d;
reg [7:0] rvData_TMP_q;
reg [7:0] rvData_TMP_d;
localparam S0_IDLE = 4'd0,
S1_STATE0 = 4'd1,
S2_STATE1 = 4'd2,
S3_STATE2 = 4'd3,
S4_STATE3 = 4'd4,
S5_FINISH = 4'd5;
always @(posedge CLK or negedge nRST)
begin
if(!nRST)
current_state <= S0_IDLE;
else
current_state <= next_state;
end
always @(*)
begin
case(current_state)
S0_IDLE:
begin
if(rvCNT_q == 8'd99)
next_state = S1_STATE0;
else
next_state = current_state;
end
S1_STATE0:
begin
if(rvCNT_q == 8'd99)
next_state = S2_STATE1;
else
next_state = current_state;
end
S2_STATE1:
begin
if(rvCNT_q == 8'd99)
next_state = S3_STATE2;
else
next_state = current_state;
end
S3_STATE2:
begin
if(rvCNT_q == 8'd99)
next_state = S4_STATE3;
else
next_state = current_state;
end
S4_STATE3:
begin
if(rvCNT_q == 8'd99)
next_state = S5_FINISH;
else
next_state = current_state;
end
S5_FINISH:
begin
if(rvCNT_q == 8'd99)
next_state = S0_IDLE;
else
next_state = current_state;
end
default:
begin
next_state = S0_IDLE;
end
endcase
end
always @(posedge CLK or negedge nRST)
begin
if(!nRST)
rvData_TMP_q <= 8'b0000_0000;
else
rvData_TMP_q <= rvData_TMP_d;
end
always @(*)
begin
case(current_state)
S0_IDLE : rvData_TMP_d = 8'b0000_0000;
S1_STATE0: rvData_TMP_d = 8'b0000_0011;
S2_STATE1: rvData_TMP_d = 8'b0000_1100;
S3_STATE2: rvData_TMP_d = 8'b0011_0000;
S4_STATE3: rvData_TMP_d = 8'b1100_0000;
S5_FINISH: rvData_TMP_d = 8'b1111_1111;
default: rvData_TMP_d = 8'b0000_0000;
endcase
end
assign STATE_OUT = rvData_TMP_q;
always @(posedge CLK or negedge nRST)
begin
if(!nRST)
rvCNT_q <= 8'h0;
else
rvCNT_q <= rvCNT_d;
end
always @(*)
begin
if(current_state != next_state)
rvCNT_d = 8'h0;
else if(rvCNT_q < 8'd99)
rvCNT_d = rvCNT_q + 8'd1;
else
rvCNT_d = 8'h0;
end
reg [8*10–1:0] StateName;
always @(*)
begin
case(current_state)
S0_IDLE : StateName = "IDLE";
S1_STATE0: StateName = "STATE0";
S2_STATE1: StateName = "STATE1";
S3_STATE2: StateName = "STATE2";
S4_STATE3: StateName = "STATE3";
S5_FINISH: StateName = "FINISH";
default : StateName = "ERROR";
endcase
end
endmodule