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. JAVA学习之Ecplise IDE 使用技巧(2)第二章:键盘小快手,代码辅助

    上一篇:JAVA学习之Ecplise IDE 使用技巧(1)第一章:我的地盘我做主,工作空间 第二章:键盘小快手,代码辅助 内容包括: 第一:显示行号 如何设置行号:Ecplice菜单Windows& ...

  2. JSONP解决ajax跨域问题

    在A域名下,用ajax请求B域名下的请求,会报类似这样的错误:No 'Access-Control-Allow-Origin' header is present on the requested r ...

  3. Single Number-C++中的异或

    Single Number Given an array of integers, every element appears twice except for one. Find that sing ...

  4. Linux系统下查看硬件信息命令大全

    导读 有许多命令可以用来查看 Linux 系统上的硬件信息.有些命令只能够打印出像 CPU 和内存这一特定的硬件组件信息,另外一些命令可以查看多种硬件组件的信息. 这个教程可以带大家快速了解一下查看各 ...

  5. 203. Remove Linked List Elements

    Remove all elements from a linked list of integers that have value val. ExampleGiven: 1 --> 2 --& ...

  6. Codeforces Round #151 (Div. 2)

    A. Buggy Sorting \(n \ge 3\)时,序列\(n.n-1.\cdots.1\)即可. B. Increase and Decrease 考虑和是否能被\(n\)整除. C. Be ...

  7. 关于kafka连接不上别的机器问题Connection refused

    1.确认config里面的server.properties 正确(包括IP+端口2181记得看清,用hostname的话记得etc/hostnames下面查看全部配置上没,建议用hostname方便 ...

  8. 数据库必会必知 之 SQL四种语言:DDL DML DCL TCL(转)

    今天群里面讨论,DDL 还是 DML,我这种小白还是总结下他们的区别吧. 1. DDL – Data Definition Language 数据库定义语言:定义数据库的结构. 其主要命令有CREAT ...

  9. List of devices attached ???????????? no permissions

    如果显示如下:List of devices attached???????????? no permissions就要设置usb $ lsusbBus 005 Device 001: ID 1d6b ...

  10. javaweb在线预览

    需要工具: 1.openoffice 将word.excel.ppt.txt等文件转换为pdf文件 2.SWFTool 将pdf转换为swf文件 3.flexPaper是一个开源轻量级的在浏览器上显示 ...