当前位置:首页 > 新闻资讯 > FPGA之家动态 >

FPGA设计心得(10)关于行为仿真的一点观点

时间:2024-08-08      来源:网络搜集 关于我们 0

👉前言

👉实践分析

👉推荐的仿真设计

👉总结

前言

提前给出一些观点:

仿真是为了仿真,所以不要设置极限情况,例如在时钟上升沿通过阻塞赋值给数据,应该避免这种情况;各种不同的仿真软件对时钟上升沿通过阻塞赋值给数据的理解不一致,例如modelsim和isim;可以使用非阻塞赋值设置数据值,避免在时钟上升沿时刻使用阻塞赋值给数据。

本文最后会给出推荐的仿真观点。

实践分析

事实上,上面三点说的是针对一种情况,我们举一个简单的例子说明。我们的设计文件,很简单,就是一个检测上升沿的程序:

`timescale 1ns / 1ps//////////////////////////////////////////////////////////////////////////////////// Engineer: Reborn Lee// website : https://blog.csdn.net/Reborn_Lee//////////////////////////////////////////////////////////////////////////////////module

 delay(

    input wire

 in,

    input wire

 clk,

    input wire

 rst,

    output reg

 out_r3

    );

    reg

 in_reg;

    always@(posedge clk) begin        if(rst) begin            in_reg <= 0

;

        end        else begin

            in_reg <= in;

        end    end    wire

 mid_pos;

    assign

 mid_pos = ~in_reg & in;

    reg

 reg_pos;

    reg

 reg1_pos;

    reg

 reg2_pos;

    always@(posedge clk) begin        if(rst) begin            reg_pos <= 0

;

            reg1_pos <= 0

;

            reg2_pos <= 0

;

            out_r3 <= 0

;

        end        else begin

            reg_pos <= mid_pos;

            reg1_pos <= reg_pos;

            reg2_pos <= reg1_pos;

            out_r3 <= reg2_pos;

        end    endendmodule

如下,我们的testbench为:

`timescale 1ns / 1ps// Engineer: Reborn Lee// website : https://blog.csdn.net/Reborn_Leemodule

 sim_delay;

    reg

     clk;

    reg

     rst;

    reg

     in;

    wire

    out_r3;

    initial begin        clk =   0

;

        forever begin            #5

 clk =   ~clk;

        end    end    initial begin    rst =    1

;

    in =    0

;

    #20    rst = 0

;

    #100    @(posedge clk) begin        in =    1

;

    end    #300    in =   0

;

    end

    delay delay_inst(

        .in

(in),

        .clk

(clk),

        .rst

(rst),

        .out_r3

(out_r3)

    );

endmodule

我们对输入进行赋值:

 @(posedge clk) begin        in =    1

;

    end

可见,使用的是阻塞赋值,且在时钟上升沿赋值;

在这种情况下,我们使用vivado自带的仿真工具仿真,得到结果如下:

isim仿真工具

可见,得不到上升沿,这我们其实也能理解;由于是行为仿真,所以,一切都是理想的,不考虑延迟;我们使用阻塞赋值在时钟上升沿时刻给输入赋值,立即生效;固然,我们的时钟在上升沿采样的时候,得到in_reg和in是同边沿的,这样自然就得不到边沿了,后面延迟多拍也自然无用。

这是vivado的仿真工具isim对这种情况的理解。

现在问题来了,当我们使用modelsim进行仿真的时候,情况是这样的:

modelsim仿真工具

它会对in延迟一整拍,也就是要给时钟,最终也就能得到上升沿了。同样的设计,同样的仿真文件,为何会出现这样的差异呢?这里给出的解释是仿真工具对这种情况的理解问题:在实际情况中(考虑真实环境,存在延迟),这种输入的边沿出现在时钟的有效沿,本身就是不合法的,因为这会导致时序通过不了,例如建立时间。对于这种情况,modelsim或者questasim的处理就比较直接,我不准出现这种情况,如果你出现了,我们认为此刻无效。其效果类似于非阻塞赋值:

 @(posedge clk) begin        in <=    1

;

    end

这里使用了非阻塞赋值,那么在时钟上升沿时刻,in的值就没那么快生效,如此,无论在那个平台仿真,仿真情况都一致了。

下面是这种情况下在任意平台的仿真图:

任意平台

推荐的仿真设计

开门见山,在时钟有效沿时刻给数据是不符合实际的,是极端的做法,这在实际情况中不会出现,即使出现,综合布线工具也会重新布线避免这种情况,否则就是时许违规。因此为了有意义的仿真且统一仿真平台,我们应该在距离有效沿一定延迟给数据,例如:

    #100    @(posedge clk) begin        #1 in =    1

;

    end

或者:

    #100    @(negedge clk) begin       in =    1

;

    end

总之,别在有效沿给数据,以这种情况为例,给出仿真图:

    #100    @(posedge clk) begin        #1 in =    1

;

    end推荐的仿真方式

总结

从上面的分析可以看出,为了适应不同的仿真平台(并不是说哪个仿真平台错了) ,且本着仿真意义的实际情况,我们不应该在极端的情况下进行仿真,不仅没有意义,而且让人疑惑。推荐的做法是在下降沿或者距离时钟的上升沿有一定的延迟给数据,这才能避开不同平台的差异且有实际意义。


注明:本内容来源网络,不用于商业使用,禁止转载,如有侵权,请来信到邮箱:429562386ⓐqq.com 或联系本站客服处理,感谢配合!

用户登陆

    未注册用户登录后会自动为您创建账号

提交留言