為狀態機各個狀態加上有意義的名稱吧

在模擬時為狀態機狀態加上名稱,跑模擬時就可以清楚瞭解目前狀態,因為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

模擬如下圖 :

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *