【Modelsim仿真让状态机波形显示状态名字】

  我们再用modelsim进行状态机仿真时,状态机state显示通常是以进制数字表示,我们更喜欢的是需要用当前状态表示(例如S0、S1等),这样以文本形式表示更利于调试。
  下面用一个实例来说明
源文件:

module fsm_sale
(
input                   clk                 ,
input                   rst_n               ,
input      [1:0]        in                  ,
output reg [1:0]        out                 ,
output reg              out_vld
);

reg  [3:0]              state             ;
reg  [3:0]              n_state             ;

localparam S0           = 4'b0001           ;
localparam S1           = 4'b0010           ;
localparam S2           = 4'b0100           ;
localparam S3           = 4'b1000           ;


always @(posedge clk or negedge rst_n)begin
    if(!rst_n)
        state <= S0;
    else
        state <= n_state;
end


always @(*)begin
    case(state)
        S0: begin
            if(in==1)
                n_state = S1;
            else if(in==2)
                n_state = S2;
            else
                n_state = state;
        end
        S1: begin
            if(in==1)
                n_state = S2;
            else if(in==2)
                n_state = S3;
            else
                n_state = state;
        end
        S2: begin
            if(in==1)
                n_state = S3;
            else if(in==2)
                n_state = S0;
            else
                n_state = state;
        end
        S3: begin
            if(in==1 || in==2)      // in != 0也行
                n_state = S0;
            else
                n_state = state;
        end
        default:n_state = S0;
    endcase
end


always @(posedge clk or negedge rst_n)begin
    if(!rst_n)
        out <= 0;
    else if(state ==S3 && in==2)
        out <= 1;
    else
        out <= 0;
end


always @(posedge clk or negedge rst_n)begin
    if(rst_n==1'b0)
        out_vld <= 0;
    else if((state ==S2 && in==2) || (state ==S3 && in!=0))
        out_vld <= 1;
    else
        out_vld <= 0;
end


endmodule

测试文件

`timescale 1ns/1ps  //时间精度
`define    Clock 20 //时钟周期

module FSM_tb;

reg                     clk                 ;
reg                     rst_n               ;
reg  [1:0]              in                  ;
wire [1:0]              out                 ;
wire                    out_vld             ;


fsm_sale u_fsm_sale
(
    .clk                (clk                ),
    .rst_n              (rst_n              ),
    .in                 (in                 ),
    .out                (out                ),
    .out_vld            (out_vld            )
);


localparam S0           = 4'b0001           ;
localparam S1           = 4'b0010           ;
localparam S2           = 4'b0100           ;
localparam S3           = 4'b1000           ;
//2字符16位
reg [15:0]              state_name          ;

always@(*)begin
    case(u_fsm_sale.state)
        S0:     state_name = "S0";
        S1:     state_name = "S1";
        S2:     state_name = "S2";
        S3:     state_name = "S3";
        default:state_name = "S0";
    endcase
end


initial begin
    clk = 1;
    forever
    #(`Clock/2) clk = ~clk;
end

initial begin
    rst_n = 0; #(`Clock*20+1);
    rst_n = 1;
end


initial begin
    #1;
    in = 0;
    #(`Clock*20+1); //初始化完成
//情况1--------------------------
    in = 1;         //1块钱
    #(`Clock*1);
    in = 0;
    #(`Clock*1);
    in = 1;         //1块钱
    #(`Clock*1);
    in = 0;
    #(`Clock*1);
    in = 1;         //1块钱
    #(`Clock*1);
    in = 0;
    #(`Clock*1);
    in = 1;         //1块钱
    #(`Clock*1);
    in = 0;
    #(`Clock*10);
//情况2--------------------------
    in = 1;         //1块钱
    #(`Clock*1);
    in = 0;
    #(`Clock*1);
    in = 1;         //1块钱
    #(`Clock*1);
    in = 0;
    #(`Clock*1);
    in = 1;         //1块钱
    #(`Clock*1);
    in = 0;
    #(`Clock*1);
    in = 2;         //2块钱
    #(`Clock*1);
    in = 0;
    #(`Clock*10);
//情况3--------------------------
    in = 1;         //1块钱
    #(`Clock*1);
    in = 0;
    #(`Clock*1);
    in = 1;         //1块钱
    #(`Clock*1);
    in = 0;
    #(`Clock*1);
    in = 2;         //2块钱
    #(`Clock*1);
    in = 0;
    #(`Clock*10);
//情况4--------------------------
    in = 1;         //1块钱
    #(`Clock*1);
    in = 0;
    #(`Clock*1);
    in = 2;         //2块钱
    #(`Clock*1);
    in = 0;
    #(`Clock*1);
    in = 2;         //2块钱
    #(`Clock*1);
    in = 0;
    #(`Clock*10);
//情况5--------------------------
    in = 2;         //2块钱
    #(`Clock*1);
    in = 0;
    #(`Clock*1);
    in = 2;         //2块钱
    #(`Clock*1);
    in = 0;
    #(`Clock*10);


    $stop;
end


endmodule

这里我用的quartus对上述代码进行编译,然后用modelsim进行状态测试。
第一步:在modelsim的transcript命令窗口中定义一个新的枚举(FSM_TYPE)
在这里插入图片描述

virtual type {

{4’b0001 S0}

{4’b0010 S1}

{4’b0100 S2}

{4’b1000 S3}

} FSM_TYPE;

第二步:将需要的信号(state)进行转换成新的信号(state_new),此时需要把信号地址写清楚;
virtual function {(FSM_TYPE)/FSM_tb/u_fsm_sale/state} state_new

第三步:将新的信号添加到wave窗口中,重置信号,再运行run -all
add wave -color green /FSM_tb/u_fsm_sale/state_new

最后部分运行结果如下:
在这里插入图片描述
参考文献:在ModelSim波形图中以参数名显示变量

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值