天天看點

在Modelsim仿真中顯示狀态機名稱

經過網上的搜尋及自己的實驗,總結在Modelsim仿真中顯示狀态機名稱的三種方法。下面以一個具體的執行個體進行講解。

執行個體功能:引入狀态機實作2分頻,這裡使用狀态機完全隻是為了說明如何在仿真中顯示狀态機名稱。

狀态轉移圖:

在Modelsim仿真中顯示狀态機名稱

設計檔案代碼:

1 	module fsm(
2 		input clk,
3 		input reset_n,
4 		output reg clkout
5 	);
6 
7 	parameter ONE  = 2'b01,
8 			  ZERO = 2'b10;
9 				 
10	reg [1:0]state;
11
12	always@(posedge clk or negedge reset_n)
13	if(!reset_n)begin
14		state <= ONE;
15		clkout <= 1'b1;
16	end
17	else begin
18		case(state)
19			ONE:begin
20				state <= ZERO;
21				clkout <= 1'b0;
22			end
23			ZERO:begin
24				state <= ONE;
25				clkout <= 1'b1;
26			end
27		endcase
28	end
29
30	endmodule
           

testbench檔案代碼:

1 	`timescale 1ns/1ns
2 	`define CLK_PRIOD 20
3 
4 	module tb_fsm();
5 
6 		reg clk;
7 		reg reset_n;
8 		wire clkout;
9 
10		fsm inst_fsm(
11			.clk(clk),
12			.reset_n(reset_n),
13			.clkout(clkout)
14		);
15		
16		initial clk = 1;
17		always #(`CLK_PRIOD/2) clk = ~clk;
18		
19		initial begin
20			reset_n = 0;
21			#201
22			reset_n = 1;
23			#500;
24			$stop;
25		end
26
27	endmodule
           

仿真波形:

在Modelsim仿真中顯示狀态機名稱

在波形圖中,看到狀态機狀态隻能以各種進制的數進行顯示,當狀态比較多的時候不太便于檢視波形查找一些問題,下面将用3種不同的方式對狀态機狀态以名稱的形式顯示在波形圖中。

方法一:在testbench檔案中對設計檔案中的各種狀态進行映射

實作過程:

在tb檔案加入一個reg變量monitor_state,将設計檔案中的狀态state映射到monitor_state,通過映射将不同的狀态state在tb檔案中通過monitor_state用字元串表示,具體實作代碼如下。與開始相比,tb檔案增加了9~16行的代碼,在modelsim波形顯示視窗将信号monitor_state添加進行,将資料顯示格式設定為ASCII碼,這樣就能看到monitor_state信号名稱就顯示為狀态機名了,并且與state是一一對應的。

注:這裡的monitor_state的位寬設定是根據狀态名稱最長字元的個數确定的,一個ASCII碼字元要用8bit表示,這裡最長的是4個字元,是以這裡設定的位寬是32位。

1 	`timescale 1ns/1ns
2 	`define CLK_PRIOD 20
3 	module tb_fsm();
4 		reg clk;
5 		reg reset_n;
6 		wire clkout;
7 		reg [31:0]monitor_state;
8 		
9 	parameter ONE  = 2'b01,
10	          ZERO = 2'b10;
11
12		always@(inst_fsm.state)
13		case(inst_fsm.state)
14			ONE:  monitor_state = "ONE ";
15			ZERO: monitor_state = "ZERO";
16		endcase
17
18		fsm inst_fsm(
19			.clk(clk),
20			.reset_n(reset_n),
21			.clkout(clkout)
22		);
23		
24		initial clk = 1;
25		always #(`CLK_PRIOD/2) clk = ~clk;
26		
27		initial begin
28			reset_n = 0;
29			#201
30			reset_n = 1;
31			#500;
32			$stop;
33		end
34	endmodule 
           

仿真波形:

在Modelsim仿真中顯示狀态機名稱

方法二:在testbench檔案中對設計檔案中的狀态機編碼進行重定義

實作過程:

在tb檔案中将設計檔案中的狀态機編碼用 defpara 進行重定義,具體可見下面代碼8、9行,這裡就涉及到重定義前後狀态機狀态寄存器的位寬發生了變化,重定義後的位寬變成了32位,這樣就需要在設計檔案中将狀态寄存器state的位寬也設定成32bit。即将設計檔案代碼的第10行代碼更改為 “reg [31:0]state;” 。這種情況不需要在波形檔案額外添加信号,直接讓狀态機狀态寄存器顯示狀态名。仿真波形見下面。

1 	`timescale 1ns/1ns
2 	`define CLK_PRIOD 20
3 	module tb_fsm();
4 		reg clk;
5 		reg reset_n;
6 		wire clkout;
7 
8 	defparam	inst_fsm.ONE  = "ONE ";
9 	defparam	inst_fsm.ZERO = "ZERO";
10
11		fsm inst_fsm(
12			.clk(clk),
13			.reset_n(reset_n),
14			.clkout(clkout)
15		);
16		
17		initial clk = 1;
18		always #(`CLK_PRIOD/2) clk = ~clk;
19		
20		initial begin
21			reset_n = 0;
22			#201
23			reset_n = 1;
24			#500;
25			$stop;
26		end
27	endmodule
           

仿真波形:

在Modelsim仿真中顯示狀态機名稱

方法三:使用虛拟對象顯示狀态機名稱

實作過程:

該種方法不需要對設計代碼和tb代碼進行更改,這個隻需要在modelsim軟體上進行一些Tcl指令的操作,首先使用ModelSim的virtual type指令定義一個新的枚舉類型(FSM_TYPE),該枚舉類型可以在随後的仿真中使用,其指令格式為:virtual type { {val1 s1} { val2 s2} … { valn sn} } newVirtualType,其中val表示枚舉值,s表示枚舉名。而newVirtualType表示新的枚舉類型名稱。

注:virtual type與 { 之間,裡面的 {} 與 {} 之間,} 與newVirtualType 一定要有空格。

具體在本執行個體中在使用最開始的tb檔案進行仿真後,然後再modelsim軟體的tcl console視窗依次輸入如下指令:

virtual type { {2‘b01 ONE} { 2'b10 ZERO} } state_type

virtual function {(state_type)/inst_fsm/state} fsm_state

add wave -color pink /inst_fsm/fsm_state 
           

3條指令的作用分别為:

1、使用ModelSim的virtual type指令定義一個新的枚舉類型state_type

2、将需要顯示的信号(/inst_fsm/state,設計檔案中狀态寄存器)進行類型轉換,轉換成一個新的信号fsm_state

3、将新的信号fsm_state加入到wave視窗中

最終在波形圖形中金可以看到新的信号fsm_state是與設計檔案中狀态寄存器state同步變化,并且以字元名稱顯示。

仿真波形:

在Modelsim仿真中顯示狀态機名稱

該種方法的實作可參考:https://www.cnblogs.com/ZcsTech/p/3504416.html

總結:

以上三種方法均能實作在Modelsim仿真中顯示狀态機名稱,各有特點,讀者可以根據自己的習慣選擇其中一種方法即可,這個就是能讓在仿真波形時更加直覺的看到狀态轉移的跳轉情況。