1. Testbech总是用reg去驱动DUT的input端口,因为需要在仿真期间设置和保持输入端的值(例如在initial中设置初值,在always中设置激励值);

2. 避免对局部reg在定义时赋值,尽管这在计算机语言中很常见。例如:

always @(...) begin : XXX
reg c = ;
c = ...;
end

上面的代码中,定义时赋值会使得c仅在初次进入always时被赋值为0,其后的值因reg特性而得以保留,从而综合工具(至少quartus)会综合出组合环路。改成如下形式即可:

reg c;

c = 0;

c = ...

modelsim甚至拒绝编译局部reg定义时赋值的代码。

3. 可以在always语句中给reg赋默认值

always @(...) begin
c = ; // c is a reg
if(condition)
c = ;
end

这样即使没有else也不会综合出环路。(VHDL的process语句也可采用这种写法)

4. in/out/reg等等可直接写在端口列表中,例如:

module(input clk, input[:] preset, output reg[:] cnt);

5. always begin/end中,“=”是阻塞式赋值,"<="是并发式赋值。所以:

always @(posedge clk) begin
d1 = d0;
d2 = d1; // 阻塞赋值,两条语句依次执行完毕后(d2=d1)等待下一个clk,对应综合结果一级锁存
end always @(posedge clk) begin
d1 <= d0;
d2 <= d1; // 并发赋值,两条语句(在同一个时钟边沿)并发执行,对应综合结果二级并行锁存
end

注意:设计程序时应避免在同一always块内同时出现阻塞赋值和非阻塞赋值。

综合工具(至少quartus)拒绝综合always fork/join。

6. in/inout*不*能是reg;in端口从模块外部取值因此不可能保持某个值;inout具有in能力因此同前述(从综合角度看inout必须具有tri能力以便在必要时关闭out用作in)。

7. 惯性延迟和传播延迟

7.1 惯性延迟

惯性延迟使得小于延迟时间的信号变化被忽略。

例如:

assign #5 b = a;

或者:

always @(a) #5 b = a;

以上语句执行如下:

1> a发生变化;

2> 5个时间单位后,将a的当前值赋给b。

于是,若a上产生的是小于5个时间单位的脉冲,那么当赋值语句执行时,a的值已恢复,b上将不会产生脉冲。

测试代码和仿真结果如下:

`timescale 1ns/100ps
module sim; reg a;
reg b; initial begin
a = ;
b = ;
# a = ;
# a = ;
# a = ;
# a = ;
end always @(a) begin
if($time > ) begin
$display($time, " a=%b, b=%b", a, b);
# b = a;
$display($time, " a=%b, b=%b", a, b);
end
end endmodule

代码跳过$time=0时刻在a上x->0的变化。

$display语句打印如下消息:

# 1 a=1, b=0
# 6 a=0, b=0

仿真波形:

7.2 传播延迟

传播延迟传递信号的任何变化。测试程序如下:

(注意赋值语句为非阻塞赋值,注意延时值在语句中的位置)

`timescale 1ns/100ps

module sim;

  reg a;
reg b; initial begin
a = ;
b = ;
# a = ;
# a = ;
# a = ;
# a = ;
end always @(a) begin
if($time > ) begin
$display($time, " +++ a=%b, b=%b", a, b);
b <=# a;
$display($time, " --- a=%b, b=%b", a, b);
end
end endmodule

上面always块执行时,a发生变化后立即取a的值,在5个时间单位后赋值给b。并且,因为采用了非阻塞式赋值,always语句块在取得a的值后就退出,以便能够捕捉到a上的下一次变化(此时延时时间还没到,b还没有得到新值)。

仿真结果如下:

# 1 +++ a=1, b=0
# 1 --- a=1, b=0
# 2 +++ a=0, b=0
# 2 --- a=0, b=0
# 3 +++ a=1, b=0
# 3 --- a=1, b=0
# 4 +++ a=0, b=0
# 4 --- a=0, b=0

从仿真结果可以看出,非阻塞赋值语句的执行和生效是分开的。当使用上述赋值形式时,语句的执行是立即的,而生效时间由延时时间设定。

7.3 使用语句内延迟和阻塞式赋值

always @(a) b =# a;

执行如下:

取得a的值;延时5时间单位;赋值给b。此写法捕获a的第一次变化,但忽略其后a上5个时间单位内的任何变化。

例如对于以下激励,b在时间单位6从0变为1,且不再回到0。

  initial begin
a = ;
b = ;
# a = ;
# a = ;
# a = ;
# a = ;
end

7.4 使用语句间延迟和非阻塞赋值

always @(a) # b <= a;

由于只有一条赋值语句,其结果与惯性延迟等价。

7.4 在fork/join内使用延时语句

[略]

8 event

event是广播且无记忆的,因此,当event发生时,只有且所有正在其上等待的进程会接收到这个ev。

9 纯延时

always begin
#;
end

10 语句块和disable

总是使用独立的begin/end来标识语句块(?):

always begin
begin : my_block
for(int i = ; i < ; i++) begin // i++是system verilog语法
if(i == ) begin
disable my_block;
end
end
end
end

这样看起来比较清晰且不会引发误解。如果将my_block标记在for循环的begin后面,disable的将是该begin和对应end之间的语句块,也就是if语句,而for循环本身不会被禁用。
disable对语句块的禁用是“临时”的,下次满足进入语句块条件时仍会执行。上例中禁用for循环后,再次进入always块仍然会执行for循环。

Verilog杂谈的更多相关文章

  1. Verilog学习笔记简单功能实现(二)...............全加器

    先以一位全加器为例:Xi.Yi代表两个加数,Cin是地位进位信号,Cout是向高位的进位信号.列表有:   Xi     Yi    Cin Sum Cout 0 0 0 0 0 0 0 1 1 0 ...

  2. Verilog HDL模型的不同抽象级别

    所谓不同的抽象类别,实际上是指同一个物理电路,可以在不同层次上用Verilog语言来描述.如果只从行为功能的角度来描述某一电路模块,就称作行为模块.如果从电路结构的角度来描述该电路模块,就称作结构模块 ...

  3. Verilog学习笔记基本语法篇(十二)········ 编译预处理

    h Verilog HDL语言和C语言一样也提供编译预处理的功能.在Verilog中为了和一般的语句相区别,这些预处理语句以符号"`"开头,注意,这个字符位于主键盘的左上角,其对应 ...

  4. Verilog学习笔记基本语法篇(十一)········ 常用系统函数

    1)系统任务:$monitor   格式: $monitor(p1,p2,p3...pn); $monitor; $monitoron; $monitoroff; 任务$monitor提供了监控输出列 ...

  5. 【转】PHP 杂谈《重构-改善既有代码的设计》之一 重新组织你的函数

    原文地址: PHP 杂谈<重构-改善既有代码的设计>之一 重新组织你的函数 思维导图   点击下图,可以看大图.    介绍   我把我比较喜欢的和比较关注的地方写下来和大家分享.上次我写 ...

  6. FPGA作为从机与STM32进行SPI协议通信---Verilog实现 [转]

    一.SPI协议简要介绍 SPI,是英语Serial Peripheral Interface的缩写,顾名思义就是串行外围设备接口.SPI,是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用 ...

  7. 基于Verilog HDL整数乘法器设计与仿真验证

    基于Verilog HDL整数乘法器设计与仿真验证 1.预备知识 整数分为短整数,中整数,长整数,本文只涉及到短整数.短整数:占用一个字节空间,8位,其中最高位为符号位(最高位为1表示为负数,最高位为 ...

  8. system verilog中的跳转操作

    在verilog中,使用disable声明来从执行流程中的某一点跳转到另一点.特别地,disable声明使执行流程跳转到标注名字的声明组末尾,或者一个任务的末尾. verilog中的disable命令 ...

  9. system verilog中的类型转换(type casting)、位宽转换(size casting)和符号转换(sign casting)

    类型转换 verilog中,任何类型的任何数值都用来给任何类型赋值.verilog使用赋值语句自动将一种类型的数值转换为另一种类型. 例如,当一个wire类型赋值给一个reg类型的变量时,wire类型 ...

随机推荐

  1. ubuntu基本配置

    新系统装好后的操作: 1.resource updata:服务器镜像地址选择 2.删除不必要软件: 2.1:libreoffice sudo apt-get remove libreoffice-co ...

  2. Mysql Too Many Connections问题解决

    MySQL的max_connections参数用来设置最大连接(用户)数.每个连接MySQL的用户均算作一个连接,max_connections的默认值为100.本文将讲解此参数的详细作用与性能影响. ...

  3. win10新增快捷键

    按此键   出现位置 重要程度 联想记忆 替代 用途 +A                    打开“操作中心” 右侧,   ★★★★★  Action    控制面板 ‌ +S           ...

  4. tyvj1014 - 乘法游戏 ——记忆化搜索DP

    题目链接:https://www.tyvj.cn/Problem_Show.aspx?id=1014 f[i][j]表示区间[i,j]所得到的最小值. 不断地划分区间,把结果保存起来. #includ ...

  5. python--迭代--7

    原创博文,转载请标明出处--周学伟http://www.cnblogs.com/zxouxuewei/ 一.什么是迭代 在Python中,如果给定一个list或tuple,我们可以通过for循环来遍历 ...

  6. Xcode7.0.1(ios9)的部分适配问题

    今天更新了Xcode 7 正式版,App编译出现很多警告,在App运行的时候出现如下的提示......... the resource could not be loaded because the ...

  7. Android-Universal-Image-Loader开源项目的简要说明及使用实例

    本文转载于:http://www.cnblogs.com/hsx514/p/3460179.html 一.核心类的说明及相关参数的说明 ImageLoaderConfiguration 1.作用:为I ...

  8. java的nio之:java的bio流下实现的socket服务器同步阻塞模型和socket的伪异步的socket服务器的通信模型

    同步I/O模型的弊端===>每一个线程的创建都会消耗服务端内存,当大量请求进来,会耗尽内存,导致服务宕机 伪异步I/O的弊端分析===>当对Socket的输入流进行读取操作的时候,它会一直 ...

  9. php 代码大全

    1.子类访问父类静态方法 <?php class A{ static function loadById(){ $class_name = get_called_class(); $model ...

  10. Unity3D 几个基本动画(控制物体移动、旋转、缩放)

    Transform基本移动函数: 1.指定方向移动: //移动速度 float TranslateSpeed = 10f; //Vector3.forward 表示"向前" tra ...