首先引入一个例子:

`timescale  1ns/100ps

module   TB;                                                                                       module  INV_DFF(Clock, Reset_n, DataIn, DataOut);

reg Ck, Rst_n, Din;                                                                                  input Clock;

wire Dout;                                                                                               input Reset_n;

//Clock  generation                                                                                  input DataIn;

initial   begin                                                                                           output reg Data_Out

Ck = 0;                                                                                   wire DataInv;

forever   #10 Ck = ~Ck;                                                           always @(posedge Clock or negedge Reset_n)

end                                                                                                           begin if(~Reset_n)

//Reset  generation                                                                                                            Data_Out <= 1'b0;

initial   begin                                                                                                                  else Data_Out <= Data_Inv;

Rst_n = 1;                                                                                             end

#5 Rst_n = 0;                                                                          assign #3 DataInv = ~ DataIn;

#55 Rst = 1;                                                                        endmodule

end

//Data input generation

initial   begin

Din = 0;

#80 Din = 1;

#40 Din = 0;

end

INV_DFF     u_INV_DFF(                 //DUV

.Clock(Ck),

.Reset_n(Rst_n),

.DataIn(Din),

.DataOut(Dout),

);

0仿真时刻:3个initial进程和1个DUV同时执行。同时执行的进程其顺序不是固定的,和所用的仿真器有关,假设此处的同时执行,按代码中的顺序来执行。

执行Clock Generation 中的语句Ck = 0; ~Ck。 执行forever #10 进程挂起。

执行Reset Generation 中的语句Rst_n = 1; #5 进程挂起。

执行Data Input Generation中的语句Din = 0; #80 进程挂起。

执行DUV中的语句~DataIn; #3进程挂起。always @进程挂起。 至此0仿真时刻的语句全部执行完毕,仿真时间轴向前推进。

3仿真时刻:只有一个计算事件 DataInv = #3 ~DataIn;更新DataInv的值。无触发更多计算事件,所以仿真时间轴向前推进。

5仿真时刻:执行Reset Generation 中的语句 Rst_n = 0; #55 进程挂起。

由于Rst_n的更新时间,DUV中的always @进程执行,DataOut值更新。无触发更多计算事件,仿真时间轴向前推进。

10仿真时刻: 执行Clock Gneration 中的计算事件CK。更新事件触发。#10进程挂起。

执行DUV中的always进程,计算事件Data_Out = 0。无触发更多事件,仿真时间轴向前推进。

60仿真时刻: 执行Clock Gneration 中的计算事件CK。更新事件触发。#10进程挂起。

执行Reset Generation 中的语句 Rst_n = 1; 进程结束。

执行DUV中的always进程,计算事件Data_Out = 1(Rst_n的值已经为1)。无触发更多事件,仿真时间轴向前推进。

80仿真时刻: 执行Clock Gneration 中的计算事件CK。更新事件触发。#10进程挂起。

执行Data Input Generation中的语句Din = 1; #40 进程挂起。

执行DUV中的always进程,计算事件Data_Out = Data_Inv。

执行DUV中的语句~DataIn; #3进程挂起。always @进程挂起。 至此0仿真时刻的语句全部执行完毕,仿真时间轴向前推进。

仿真时间:是仿真时间维护的时间值,用来对仿真电路的真实时间进行建模(仿真时间和软件的执行时间没有任何联系),当仿真时间推进到某一个时间点时,该时间点就被称为当前仿真时间,而以后的任何时间都被称为将来仿真时间。

事件:模型中数值的变化,功能仿真是一种事件驱动的仿真,整个仿真过程都是围绕事件来组织的。

更新事件:在被仿真的电路中,线网或寄存器的值在任何进程中的任何改变都被认为是一个更新事件。

计算事件:由于更新事件产生的,进程的计算,计算事件。

计算事件和更新事件之间循环往复的互相触发,推动仿真时间的前进。

进程是Verilog中的独立执行单元,包括:原语(Primitives), 模块(Moules), initial过程块, always过程块, 连续赋值语句(assign), 异步任务(task)。在仿真时,所有的进程都是仿真器按Verilog的语义来顺序执行的,效果是各个进程并行执行的效果,在未执行完当前所有的进程时,仿真时间不会向前推进。

initial   begin

Ck = 0;  forever Ck = ~Ck;

end

例子会hang在仿真时刻0,因为更新时间一直触发计算事件,计算事件一直触发更新时间。

Verilog中的时序控制:事件语句(@),延时语句(#),等待语句(wait)。

Verilog仿真时的不确定性:在同一个仿真时间内,几个同一调度模块中事件执行顺序的任意性,进程之间语句的任意交织。

verilog或者systemverilog相对于C,能用于硬件建模的最大区别:

1)connectivity  一个大的design可以由很多block,组成,通过例化或者interface来进行连接

2)time   time的变化可以使得design的state变化,与执行时间(execution time)完全不同,通过@/wait/#来实现

3)concurrency    event之间的同步发生关系, 通过initial/always/fork join来实现

对于验证还缺少:1)randomization;  2)constrainability;  3)functional coverage;

在simulator中的concurrency是基于time_share的来跑的,CPU轮询执行。

always模块,initial模块,连续赋值模块,fork/join,都是完全并行执行的,并没有先后顺序。

在基于time-sharing的处理中,simulator对于各个并行thread,保证访问机会时一样的,但是各个模块的先后顺序不能保证,

和代码块中的位置有关。simulator也不会自己关掉一个thread,除非自己执行结束。

Verilog的事件调度:

在systemverilog中有两种thread,module thread和program thread,module thread主要用来建模design,

program thread主要用来建模testbench。

program中的task的执行,主要看task的定义位置,如果是在module内定义的task,则尽管在program中调用,也算是一个

module thread。

对于program和module内的class的执行顺序,systemverilog标准中,并没有准确给出,根据simulator的实现而不同。

program中在SV2012中,才开始支持非阻塞赋值。

其中的执行顺序:

1)sample阶段,进行clock,property这样的采样。

2)excute阶段,执行阻塞赋值等。

3)reactive阶段,执行非阻塞赋值等。以及阻塞赋值的迭代。

4)evaluate阶段,执行assertion的判断。

5)program thread阶段,执行program中的阻塞赋值,非阻塞赋值

simulation的前进,依靠两条线,一条simulation time,另一个是module thread中的非阻塞赋值和阻塞赋值之间的迭代。

其中第二种也称为delta cycle,一个设计中可能会有很多delta cycle,因为信号的依赖关系可以一直迭代。

几种存在race condition的情况:

1)concurrent中的冲突:

2)delta cycle对clock的影响:

如果两个时钟有信号之间的采样关系,而且一个clock比另一个clock多一个非阻塞赋值。

此时,两个clock之间会差一个delta cycle,在RTL仿真时,两个clock之间的信号采样会出错。

快一点的clock的值,可以再被慢一点的采到,但是在波形中不会体现出来。

这时的解决方法:

1)手工增加delay

2)将另一个clock 也经过一个非阻塞赋值。

Verilog篇(三)仿真原理的更多相关文章

  1. VCS使用学习笔记(1)——Verilog相关的仿真知识

    本文主要学习Verilog的仿真特性,以及仿真器对Verilog的处理,算是对Verilog知识的增量学习.本文内容与我的另一篇博文(http://www.cnblogs.com/IClearner/ ...

  2. 敌情篇 ——DDoS攻击原理

    敌情篇 ——DDoS攻击原理 DDoS攻击基础 DDoS(Distributed Denial of Service,分布式拒绝服务)攻击的主要目的是让指定目标无法提供正常服务,甚至从互联网上消失,是 ...

  3. 阻塞赋值与非阻塞赋值(verilog篇)

    阻塞赋值与非阻塞赋值(verilog篇) 2017-09-30 竹海 相约电子ee 相信刚刚接触verilog的读者,多少对阻塞赋值和非阻塞赋值仍有一些困惑.笔者在这篇文章,带领大家深入的理解这两者的 ...

  4. 【基于WinForm+Access局域网共享数据库的项目总结】之篇三:Access远程连接数据库和窗体打包部署

    篇一:WinForm开发总体概述与技术实现 篇二:WinForm开发扇形图统计和Excel数据导出 篇三:Access远程连接数据库和窗体打包部署 [小记]:最近基于WinForm+Access数据库 ...

  5. 【基于WPF+OneNote+Oracle的中文图片识别系统阶段总结】之篇三:批量处理后的txt文件入库处理

    篇一:WPF常用知识以及本项目设计总结:http://www.cnblogs.com/baiboy/p/wpf.html 篇二:基于OneNote难点突破和批量识别:http://www.cnblog ...

  6. 【SSRS】入门篇(三) -- 为报表定义数据集

    原文:[SSRS]入门篇(三) -- 为报表定义数据集 通过前两篇文件 [SSRS]入门篇(一) -- 创建SSRS项目 和 [SSRS]入门篇(二) -- 建立数据源 后, 我们建立了一个SSRS项 ...

  7. 机器学习之决策树三-CART原理与代码实现

    决策树系列三—CART原理与代码实现 本文系作者原创,转载请注明出处:https://www.cnblogs.com/further-further-further/p/9482885.html ID ...

  8. 爬虫前篇 /https协议原理剖析

    爬虫前篇 /https协议原理剖析 目录 爬虫前篇 /https协议原理剖析 1. http协议是不安全的 2. 使用对称秘钥进行数据加密 3. 动态对称秘钥和非对称秘钥 4. CA证书的应用 5. ...

  9. Verilog学习笔记设计和验证篇(三)...............同步有限状态机的指导原则

    因为大多数的FPGA内部的触发器数目相当多,又加上独热码状态机(one hot code machine)的译码逻辑最为简单,所以在FPGA实现状态机时,往往采用独热码状态机(即每个状态只有一个寄存器 ...

随机推荐

  1. 完全卸载Oracle数据库软件

    软件环境: 1.Windows xp+ORACLE 8.1.7 2.ORACLE安装路径为:C:\ORACLE 实现方法: 1. 开始->设置->控制面板->管理工具->服务 ...

  2. Android Usb Camera HAL框架

  3. 关于数据库DB负载均衡的初步研究(二)

    负载均衡: 是什么:有一组服务器由路由器联系在一起,各个节点相互协作,共同负载,均衡压力. 实现原理:应用程序与DB之间有个中央控制台服务器,根据负载均衡策略决定访问哪一台DB服务器. DB服务器:读 ...

  4. Rails secret token bug

    ArgumentError (A secret is required to generate an integrity hash for cookie session data. Use confi ...

  5. 更新jenkins插件,报错 Perhaps you need to run your container with "-Djava.awt.headless=true"?

    Configuring the Java environment variables vi ~/.bash_profile 在最后一行加入: export JAVA_OPTS=-Djava.awt.h ...

  6. .net C#中页面之间传值传参的六种方法

    1.QueryString是一种非常简单的传值方式,他可以将传送的值显示在浏览器的地址栏中.如果是传递一个或多个安全性要求不高或是结构简单的数值时,可以使用这个方法.但是对于传递数组或对象的话,就不能 ...

  7. 【LOJ6254】最优卡组 堆(模拟搜索)

    [LOJ6254]最优卡组 题面 题解:常用的用堆模拟搜索套路(当然也可以二分).先将每个卡包里的卡从大到小排序,然后将所有卡包按(最大值-次大值)从小到大排序,并提前处理掉只有一张卡的卡包. 我们将 ...

  8. C++ Error: no appropriate default constructor available

    我定义了一个结构体,然后初始化它,结果编译报错 no appropriate default constructor available 代码如下: struct matrixXvect_func { ...

  9. iOS - 视频开发

    视频实质: 纯粹的视频(不包括音频)实质上就是一组帧图片,经过视频编码成为视频(video)文件再把音频(audio)文件有些还有字幕文件组装在一起成为我们看到的视频(movie)文件.1秒内出现的图 ...

  10. python3+socket搭建简易服务器

    踩了一上午的坑之后,终于对网络编程有了一点大致的.基本的了解.真的是0基础,之前对socket网络编程一点都不知道.(感觉自己与时代脱轨....) 首先我想对这些美妙的专业术语进行一番搜索: 服务器: ...