在使用Verilog编写有限状态机等逻辑的时候,状态机的各个状态通常以参数表示(如IDLE等)。当使用ModelSim仿真的时候,状态机变量在wave窗口中以二进制编码的形式显示,如下面所示,这种显示形式不是很直观,但我们可以使用ModelSim提供的命令将状态机变量以“文本”形式的参数名显示,从而有利于调试。
下面以一个实例来说明。
代码来源:http://www.cnblogs.com/oomusou/archive/2011/06/05/fsm_coding_style.html
源文件:
1 /*
2 (C) OOMusou 2011 http://oomusou.cnblogs.com
3
4 Filename : simple_fsm_moore_3_always_best.v
5 Synthesizer : Quartus II 8.1
6 Description : 3 always block for moore fsm (BEST)
7 Release : Jun.05,2011 1.0
8 */
9
10 module simple_fsm (
11 clk,
12 rst_n,
13 w_i,
14 z_o
15 );
16
17 input clk;
18 input rst_n;
19 input w_i;
20 output z_o;
21
22 parameter IDLE = 2'b00;
23 parameter S0 = 2'b01;
24 parameter S1 = 2'b10;
25
26 reg [1:0] curr_state;
27 reg [1:0] next_state;
28 reg z_o;
29
30 // state reg
31 always@(posedge clk or negedge rst_n)
32 if (~rst_n) curr_state <= IDLE;
33 else curr_state <= next_state;
34
35 // next state logic
36 always@(*)
37 case (curr_state)
38 IDLE : if (w_i) next_state = S0;
39 else next_state = IDLE;
40 S0 : if (w_i) next_state = S1;
41 else next_state = IDLE;
42 S1 : if (w_i) next_state = S1;
43 else next_state = IDLE;
44 default : next_state = IDLE;
45 endcase
46
47 // output logic
48 always@(*)
49 case (curr_state)
50 IDLE : z_o = 1'b0;
51 S0 : z_o = 1'b0;
52 S1 : z_o = 1'b1;
53 default : z_o = 1'b0;
54 endcase
55
56 endmodule
simple_fsm
1 /*
2 (C) OOMusou 2011 http://oomusou.cnblogs.com
3
4 Filename : simple_fsm_tb.v
5 Simulator : ModelSim SE 6.3e + Debussy 5.4 v9
6 Description : testbench for FSM
7 Release : Jun.05,2011 1.0
8 */
9
10 module simple_fsm_tb;
11
12 reg clk = 1'b1;
13 reg rst_n = 1'b1;
14 reg w_i = 1'b0;
15 wire z_o;
16
17 // clk
18 always #10 clk = ~clk;
19
20 event after_rst;
21
22 // rst_n
23 initial begin
24 #6; // 6ns
25 rst_n = 1'b0;
26 #30; // 36ns
27 rst_n = 1'b1;
28 ->after_rst;
29 end
30
31 // w_i
32 initial begin
33 @(after_rst);
34 repeat(2)@(posedge clk); // 60ns
35 w_i <= 1'b1;
36 @(posedge clk); // 80 ns
37 w_i <= 1'b0;
38 @(posedge clk); // 100 ns
39 w_i <= 1'b1;
40 repeat(2)@(posedge clk); // 140 ns
41 w_i <= 1'b0;
42 @(posedge clk); // 160 ns
43 w_i <= 1'b1;
44 repeat(3)@(posedge clk); // 220 ns
45 w_i <= 1'b0;
46 end
47
48 initial begin
49 $fsdbDumpfile("simple_fsm.fsdb");
50 $fsdbDumpvars(0, simple_fsm_tb);
51 end
52
53 simple_fsm u_simple_fsm (
54 .clk (clk),
55 .rst_n (rst_n),
56 .w_i (w_i),
57 .z_o (z_o)
58 );
59
60 endmodule
simple_fsm_tb.v
vlib work
vlog -novopt simple_fsm.v simple_fsm_tb.v
vsim -voptargs=+acc work.simple_fsm_tb
add wave *
virtual type { {0x00 IDLE} {0x01 S0} {0x02 S1} } FSM_TYPE
virtual function {(FSM_TYPE)/simple_fsm_tb/u_simple_fsm/curr_state} state1
add wave u_simple_fsm/curr_state
add wave -color pink /simple_fsm_tb/u_simple_fsm/state1
virtual function {(FSM_TYPE)/simple_fsm_tb/u_simple_fsm/next_state} state2
add wave u_simple_fsm/next_state
add wave -color pink /simple_fsm_tb/u_simple_fsm/state2
run 1000ns