📜  Verilog Simulation基础知识

📅  最后修改于: 2021-01-11 15:00:32             🧑  作者: Mango

Verilog仿真基础

Verilog是一种硬件描述语言,不需要设计人员模拟其RTL设计以将其转换为逻辑门。

仿真是一种在不同时间将不同的输入刺激应用于设计以检查RTL代码是否以预期方式运行的技术。

仿真是一种验证设计稳健性的熟知技术。这类似于在现实世界中将如何使用预制芯片以及其如何对不同的输入做出反应。

例如,以上设计代表了一个具有输入时钟信号的上升沿检测器,它们会定期进行评估以确定输出。仿真使我们可以查看相关信号的时序图,以了解设计说明在Verilog中的行为。

许多EDA公司开发了仿真器,这些仿真器能够确定设计各种输入的输出。 Verilog是根据离散事件执行模型定义的。并且不同的模拟器可以自由使用不同的算法来为用户提供一致的结果集。

Verilog代码分为多个进程和线程,可以在仿真中的不同时间进行评估。

在此示例中, tb (测试台)是用于保存设计模块的容器。在特定时间可以为两个信号变量分配单独的值。 clk表示在测试平台内生成的时钟。

这是使用always语句通过在每5ns之后交替改变时钟值来完成的。初始块包含一组为两个信号分配不同值的语句。

module tb;
  reg clk;
  reg sig;

  // Clock generation
  // Process starts at time 0ns and loops after every 5ns
  always #5 clk = ~clk;

  // Process starts at time 0ns
  initial begin
    // This system task will print out the signal values everytime they change
    $monitor("Time = %0t clk = %0d sig = %0d", $time, clk, sig);

    // Also called stimulus, we simply assign different values to the variables
    // after some simulation "delay"
    sig = 0;
    #5 clk = 0;         // Assign clk to 0 at time 5ns
    #15  sig = 1;      // Assign sig to 1 at time 20ns (#5 + #15)
    #20  sig = 0;      // Assign sig to 0 at time 40ns (#5 + #15 + #20)
    #15  sig = 1;      // Assign sig to 1 at time 55ns (#5 + #15 + #20 + #15)
    #10  sig = 0;      // Assign sig to 0 at time 65ns (#5 + #15 + #20 + #15 + #10)
    #20 $finish;       // Finish simulation at time 85ns
  end
endmodule

执行上述测试平台后,模拟器将提供以下输出。

ncsim> run
Time = 0 clk = x sig = 0
Time = 5 clk = 0 sig = 0
Time = 10 clk = 1 sig = 0
Time = 15 clk = 0 sig = 0
Time = 20 clk = 1 sig = 1
Time = 25 clk = 0 sig = 1
Time = 30 clk = 1 sig = 1
Time = 35 clk = 0 sig = 1
Time = 40 clk = 1 sig = 0
Time = 45 clk = 0 sig = 0
Time = 50 clk = 1 sig = 0
Time = 55 clk = 0 sig = 1
Time = 60 clk = 1 sig = 1
Time = 65 clk = 0 sig = 0
Time = 70 clk = 1 sig = 0
Time = 75 clk = 0 sig = 0
Time = 80 clk = 1 sig = 0
Simulation complete via $finish(1) at time 85 NS + 0

仿真波形

通过仿真,可以将设计和测试台信号转储为可通过图形表示的波形,以分析和调试RTL设计功能。

下面显示的波形是从EDA工具获得的,显示了每个信号的时间变化,并且与时序图相同。

网络或变量值的每次更改都称为更新事件。并且流程对更新事件很敏感,因此每当更新事件发生时就对这些流程进行评估,这称为评估事件。由于可能会任意评估多个流程,因此必须在称为事件队列的事件中跟踪更改的顺序。

它们按仿真时间排序。在队列中放置新事件称为调度

仿真时间是指仿真器维护的时间值,该时间值用于对仿真电路实际花费的时间进行建模。

module des;
    wire abc;
    wire a, b, c;

    assign abc = a & b | c;           // abc is updated via the assign statement (process)                          
                                                            //whenever a, b or c change -> update event

endmodule

事件队列中的区域

Verilog事件队列分为五个区域,事件可以添加到其中的任何一个。但是,只能将其从活动区域中删除。

Events Description
Active It occurs at the current simulation time and can be processed in any order
Inactive It occurs at the current simulation time but is processed after all active events are done
Non-blocking It evaluated at some previous time, but the assignment is done in the current simulation time after active and inactive events are done
Monitor It processed after all the active, inactive and non-blocking events are done
Future It occurs at some future simulation time

仿真周期是处理所有活动事件的地方。该标准保证了除少数情况外的特定调度顺序。

例如,begin-end块中的语句将仅按照它们出现的顺序执行。

module tb;
    reg [3:0] a;
    reg [3:0] b;
    initial begin        // Statements are executed one after the other at appropriate simulation times
        a = 5;            // At time 0ns, a is assigned 5
        b = 2;    // In the same simulation step (time 0ns), b is assigned 2
        #10 a = 7;    // When simulation advances to 10ns, a is assigned 7    end

endmodule

事件队列定义了对b的赋值应该在对a赋值之后进行。