首先引入一个例子:

`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. Linux 帐户管理

    一 用户相关操作 1. 添加帐户 useradd 选项 用户名 -c comment 指定一段注释性描述. -d 目录 指定用户主目录,如果此目录不存在,则同时使用-m选项,可以创建主目录. -g 用 ...

  2. VC 测试一段程序的运行时间 精确到ms

    分三个步骤 1:声明变量 LARGE_INTEGER litmp; _int64 QPart1,QPart2; double dfMinus,dfFreq, dfTim; QueryPerforman ...

  3. 【POJ2888】Magic Bracelet Burnside引理+欧拉函数+矩阵乘法

    [POJ2888]Magic Bracelet 题意:一个长度为n的项链,有m种颜色的珠子,有k个限制(a,b)表示颜色为a的珠子和颜色为b的珠子不能相邻,求用m种珠子能串成的项链有多少种.如果一个项 ...

  4. Android KITKAT 以上实现沉浸式状态栏

    extends:http://www.jianshu.com/p/f8374d6267ef 代码未行,效果先上 Flyme4.2 Android4.4.4上运行效果 如何实现 在 KITKAT 之后, ...

  5. spring c3po 连接mysql,sqlserver

    1  连接mysql (1) http://wenku.it168.com/d_000096351.shtml 2  连接sqlserver (1)http://blog.csdn.net/vinep ...

  6. python开发环境搭建(python3.3.2+wing IDE4.1)

    1.下载python http://www.wingide.com/downloads下载最新版python 2.下载Wing IDE http://wingware.com/downloads/wi ...

  7. ELK之使用filebeat的多行过滤插件把多行合并成一行

    java运行日志一般有多行,格式类似如下 格式为:日期 + 日志级别 + 日志信息 有些日志是多行的,需要使用filebeat多行插件把多行合并成一行 未使用多行插件的日志格式 修改filebeat配 ...

  8. Solr学习笔记之问题汇总

    一. 问题描述:Solr在建立索引时候出现如下错误:org.apache.solr.common.SolrException: Document [null] missing required fie ...

  9. 152 - - G Traffic Light 搜索(The 18th Zhejiang University Programming Contest Sponsored by TuSimple )

    http://acm.zju.edu.cn/onlinejudge/showContestProblem.do?problemId=5738 题意 给你一个map 每个格子里有一个红绿灯,用0,1表示 ...

  10. 【Pyton】【小甲鱼】正则表达式(一)

    正则表达式学习: >>> import re >>> re.search(r'FishC','I love FishC.com!') <_sre.SRE_Ma ...