在模擬時為狀態機狀態加上名稱,跑模擬時就可以清楚瞭解目前狀態,因為ASCII一個字元需要8 bit 來表示,所以在定義儲存空間時需要把可能會顯示出最大的字元數乘8,此例是假設最大字元數為10 (reg [8*10-1:0] StateName),再為每個狀態取個名稱,模擬時就能清楚知道狀態機的狀態。
頂層 RTL 如下 :
////// … . .. –.. . – …. . — — — . -. – //////
// Author : TienYao
// Source Code Name : StateMachineName.v
// Function Description: For displaying state name in simulation
// ===========================================================
module StateMachineName (
input clk,
input rstN,
output [7:0] ovState
);
reg [3:0] cState, nState;
reg [7:0] rvCnt_d, rvCnt_q;
reg [7:0] rvData_d, rvData_q;
reg [8*10 - 1 : 0] StateName;
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;
//state machine
always @(posedge clk or negedge rstN)
begin
if(!rstN)
cState <= S0_IDLE;
else
cState <= nState;
end
always @(*)
begin
case(cState)
S0_IDLE:
begin
if(rvCnt_q == 8'd99)
nState = S1_STATE0;
else
nState = cState;
end
S1_STATE0:
begin
if(rvCnt_q == 8'd99)
nState = S2_STATE1;
else
nState = cState;
end
S2_STATE1:
begin
if(rvCnt_q == 8'd99)
nState = S3_STATE2;
else
nState = cState;
end
S3_STATE2:
begin
if(rvCnt_q == 8'd99)
nState = S4_STATE3;
else
nState = cState;
end
S4_STATE3:
begin
if(rvCnt_q == 8'd99)
nState = S5_FINISH;
else
nState = cState;
end
S5_FINISH:
begin
if(rvCnt_q == 8'd99)
nState = S0_IDLE;
else
nState = cState;
end
default:
begin
nState = S0_IDLE;
end
endcase
end
//output
always @(posedge clk or negedge rstN)
begin
if(!rstN)
rvData_q <= 8'b0000_0000;
else
rvData_q <= rvData_d;
end
always @(*)
begin
case(cState)
S0_IDLE : rvData_d = 8'b0000_0000;
S1_STATE0: rvData_d = 8'b0000_0011;
S2_STATE1: rvData_d = 8'b0000_1100;
S3_STATE2: rvData_d = 8'b0011_0000;
S4_STATE3: rvData_d = 8'b1100_0000;
S5_FINISH: rvData_d = 8'b1111_1111;
default: rvData_d = 8'b0000_0000;
endcase
end
assign ovState = rvData_q;
always @(posedge clk or negedge rstN)
begin
if(!rstN)
rvCnt_q <= 8'h0;
else
rvCnt_q <= rvCnt_d;
end
always @(*)
begin
if(cState != nState)
rvCnt_d = 8'h0;
else if(rvCnt_q < 8'd99)
rvCnt_d = rvCnt_q + 8'd1;
else
rvCnt_d = 8'h0;
end
//dispaly state name
always @(*)
begin
case(cState)
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
Test bench 如下 :
`timescale 1ns/100ps
////// … . .. –.. . – …. . — — — . -. – //////
// Author : TienYao
// Source Code Name : StateMachineName_tb.v
// Function Description: Test bench for State machine function
// ===========================================================
module StateMachineName_tb;
reg clk;
reg rstN;
wire [7:0] wvState;
StateMachineName DUT (
.clk (clk),
.rstN (rstN),
.ovState (wvState)
);
initial
begin
clk = 0;
rstN = 0;
end
always #10 clk = ~clk;
task SYS_RST;
begin
repeat(100) @(posedge clk);
rstN = 1;
end
endtask
initial
begin
SYS_RST;
#10000;
$stop;
end
endmodule
模擬如下圖 :
