Verilog-2001标准在2001年就发布了
,不过翻了一些Verilog书籍,对Verilog-2001的新增特性很少有提及,即使提到了,也只是寥寥数语带过,其实在Verilog-2001中做了很多有用的改进,给编程带来很大的帮助,有必要详细了解。
在Quartus II软件中现在支持的Verilog标准有三类,即Verilog-1995,Verilog-2001,以及SystemVerilog-2005.具体用那种标准进行编译综合,需要在设置对话框中进行设置,如下图所示:
下面对Verilog-2001新增特性进行详细说明,部分说明用实例进行解析。
l generate语句
Verilog-2001添加了generate循环,允许产生module和primitive的多个实例化,同时也可以产生多个variable,net,task,function,continous assignment,initial和always。在generate语句中可以引入if-else和case语句,根据条件不同产生不同的实例化。
为此,Verilog-2001还增加了以下关键字:generate,endgenerate,genvar,localparam。genvar为新增数据类型,存储正的integer。在generate语句中使用的index必须定义成genvar类型。localparam与parameter有些类似,不过其不能通过redefinition改变值。除了可以在generate语句中使用if-else,case外,还能使用for语句进行循环。
下面是一个使用generate的例子,根据a_width和b_width的不同,实例化不同的multiplier。
module multiplier (a, b, product);
parameter a_width = 8, b_width = 8;
localparam product_width = a_width+b_width;
input [a_width-1:0] a;
input [b_width-1:0] b;
output[product_width-1:0]product;
generate
if((a_width < 8) || (b_width < 8))
CLA_multiplier #(a_width, b_width)
u1 (a, b, product);
else
WALLACE_multiplier #(a_width, b_width)
u1 (a, b, product);
endgenerate
endmodule
在下面的例子中,在generate语句中使用了for语句。
module Nbit_adder (co, sum, a, b, ci);
parameter SIZE = 4;
output [SIZE-1:0] sum;
output co;
input [SIZE-1:0] a, b;
input ci;
wire [SIZE:0] c;
genvar i;
assign c[0] = ci;
assign co = c[SIZE];
generate
for(i=0; i<size; i="i" +1)<="" font="">
begin:addbit
wire n1,n2,n3; //internal nets
xor g1 ( n1, a[i], b[i]);
xor g2 (sum[i],n1, c[i]);
and g3 ( n2, a[i], b[i]);
and g4 ( n3, n1, c[i]);
or g5 (c[i+1],n2, n3);
end
endgenerate
endmodule
generate执行过程中,每一个generated net在每次循环中有唯一的名字,比如n1在4次循环中会产生如下名字:
addbit[0].n1
addbit[1].n1
addbit[2].n1
addbit[3].n1
这也是为什么在begin-end块语句需要名字的一个原因。同样,实例化的module,gate等在每次循环中也有不同的名字。
addbit[0].g1
addbit[1].g1
addbit[2].g1
addbit[3].g1
l constant functions
Verilog的语法要求定义向量的宽度或数组大小时其值必须是一个确定的数字或一个常量表达式。比如:
parameter WIDTH = 8;
wire [WIDTH-1:0] data;
在Verilog-1995标准中,常量表达式只能是基于一些常量的算术操作。而在Verilog-2001中增加了constant function,其定义与普通的function一样,不过constant function只允许操作常量。下面是一个使用constant function的例子,clogb2函数返回输入值2次方的次数。
module ram (address_bus, write, select, data);
parameter SIZE = 1024;
input [clogb2(SIZE)-1:0] address_bus;
...
function integer clogb2 (input integer depth);
begin
for(clogb2=0; depth>0; clogb2=clogb2+1)
depth = depth >> 1;
end
endfunction
...
endmodule
l Indexed vector part selects
在Verilog-1995中,可以选择向量的任一位输出,也可以选择向量的连续几位输出,不过此时连续几位的始末数值的index需要是常量。而在Verilog-2001中,可以用变量作为index,进行part select。
[base_expr +: width_expr] //positive offset
[base_expr -: width_expr] //negative offset
其中base_expr可以是变量,而width_expr必须是常量。+:表示由base_expr向上增长width_expr位,-:表示由base_expr向上递减width_expr位。例如:
reg [63:0] word;
reg [3:0] byte_num; //a value from 0 to 7
wire [7:0] byteN = word[byte_num*8 +: 8];
如果byte_num的值为4,则word[39:32]赋值给byteN。
l 多维数组
Verilog-1995只允许一维数组,而Verilog-2001允许多维数组。
//1-dimensional array of 8-bit reg variables
//(allowed in Verilog-1995 and Verilog-2001)
reg [7:0] array1 [0:255];
wire [7:0] out1 = array1[address];
//3-dimensional array of 8-bit wire nets
//(new for Verilog-2001)
wire [7:0] array3 [0:255][0:255][0:15];
wire [7:0] out3 = array3[addr1][addr2][addr3];
而且在Verilog-1995中不能对一维数组中取出其中的一位,比如要取出上面array1[7][5],需要将array1[7]赋给一个reg变量比如arrayreg <= array1[7],再从arrayreg中取出bit5,即arrayreg[5]。而在Verilog-2001中,可以任意取出多维数组中的一位或连续几位,比如:
//select the high-order byte of one word in a
//2-dimensional array of 32-bit reg variables
reg [31:0] array2 [0:255][0:15];
wire [7:0] out2 = array2[100][7][31:24];
l 符号运算
在Verilog-1995中,integer数据类型为有符号类型,而reg和wire类型为无符号类型。而且integer大小固定,即为32位数据。在Verilog-2001中对符号运算进行了如下扩展。
Reg和wire变量可以定义为有符号类型:
reg signed [63:0] data;
wire signed [7:0] vector;
input signed [31:0] a;
function signed [128:0] alu;
函数返回类型可以定义为有符号类型。
带有基数的整数也可以定义为有符号数,在基数符号前加入s符号。
16'hC501 //an unsigned 16-bit hex value
16'shC501 //a signed 16-bit hex value
操作数可以在无符号和有符号之间转变。通过系统函数$signed和$unsigned实现。
reg [63:0] a; //unsigned data type
always @(a) begin
result1 = a / 2; //unsigned arithmetic
result2 = $signed(a) / 2;//signed arithmetic
end
增加了算术移位操作,在Verilog-1995中只有逻辑移位操作。比如D的初始值为8’b10100011,则:
D >> 3 //logical shift yields 8'b00010100
D >>> 3 //arithmetic shift yields 8'b11110100
l 指数运算
Verilog-2001中增加了指数运算操作,操作符为**。
always @(posedge clock)
result = base ** exponent;
l 递归函数和任务
在Verilog-2001中增加了一个新的关键字:automatic。该关键字可以让任务或函数在运行中从新调用该任务和函数。
function automatic [63:0] factorial;
input [31:0] n;
if (n == 1)
factorial = 1;
else
factorial = n * factorial(n-1);
endfunction
l 组合逻辑敏感信号通配符
在组合逻辑设计中,需要在敏感信号列表中包含所有组合逻辑输入信号,以免产生锁存器。在大型的组合逻辑中比较容易遗忘一些敏感信号,因此在Verilog-2001中可以使用@*包含所有的输入信号作为敏感信号。
always @* //combinational logic sensitivity
if (sel)
y = a;
else
y = b;
l 使用逗号隔开敏感信号
Verilog-2001中可以用逗号来代替or隔开敏感信号。
always @(a or b or c or d or sel)
always @(a, b, c, d, sel)
l Automatic width extension beyond 32 bits
在Verilog-1995中,在不指定基数的情况下为大于32位的变量赋高阻值,只能使其低32位为高阻值,其他高位会被设置为0,此时需要指定基数值才能将高位赋值为高阻。
Verilog-1995:
parameter WIDTH = 64;
reg [WIDTH-1:0] data;
data = 'bz; //fills with 'h00000000zzzzzzzz
data = 64'bz; //fills with 'hzzzzzzzzzzzzzzzz
而在Verilog-2001中并没有这一限制。
Verilog-2001:
parameter WIDTH = 64;
reg [WIDTH-1:0] data;
data = 'bz; //fills with 'hzzzzzzzzzzzzzzzz
l 组合端口及数据类型定义
在Verilog-1995中,端口定义和数据类型定义需要在两条语句中执行,而Verilog-2001中可以将其组合在一起。
module mux8 (y, a, b, en);
output reg [7:0] y;
input wire [7:0] a, b;
input wire en;
l ANSI格式的端口定义
在定义端口的同时并定义其数据类型,比上一个改进更简洁。
module mux8 (output reg [7:0] y,
input wire [7:0] a,
input wire [7:0] b,
input wire en );
function [63:0] alu (
input [63:0] a, b,
input [7:0] opcode );
l 定义reg并初始化
在Verilog-1995中定义和初始化reg需要两条语句,而在Verilog中可以合成一条语句。
Verilog-1995:
reg clock;
initial
clk = 0;
Verilog-2001:
reg clock = 0;
需要更加详细的说明,请下载下列附件。
Verilog-2001标准在2001年就发布了的更多相关文章
- verilog语法标准
initial 中语句超过一需要添加begin和end: 1995 2001 介绍了当用逗号分隔敏感列表更方便构成事件控制表达式的选择条件: 2005 2001/2005语法标准,没有类型定义的任何标 ...
- 使用yum安装应用程序时候,报错:[Errno 14] PYCURL ERROR 7 - "Failed to connect to 2001:da8:8000:6023::230: 网络不可达"
使用yum安装应用程序时候,报错:[Errno 14] PYCURL ERROR 7 - "Failed to connect to 2001:da8:8000:6023::230: 网络不 ...
- PKCS 发布的15 个标准与X509
PKCS 发布的15 个标准,转自:http://falchion.iteye.com/blog/1472453 PKCS 全称是 Public-Key Cryptography Standards ...
- dicom通讯的工作方式及dicom标准简介
本文主要讲述dicom标准及dicom通讯的工作方式.dicom全称医学数字图像与通讯 其实嘛就两个方面 那就是“存储”跟“通讯”. 文件数据组织方式 网络数据组织方式.文件数据组织方式就是解析静态 ...
- DICOM标准相关资料
由于需要阅读影像,对DICOM需要先熟悉起来.关于DICOM,找了一些资料,可以学习.如下: DICOM标准:http://dicom.nema.org/standard.html 中文 DICOM ...
- Verilog语言:还真的是人格分裂的语言
人气腹语术师天愿在现场披露了被人偶搭档夺取灵魂的腹语术师将妻子杀害的表演节目.天愿真的陷入了多重人格,命令自己杀害妻子和子的人偶的人格出现了.为了不(让自己)杀害和弟子登川有外遇的妻子,天愿提出委托想 ...
- PKCS 标准
PKCS 标准 The Public-Key Cryptography Standards (PKCS)是由美国RSA数据安全公司及其合作伙伴制定的一组公钥密码学标准,其中包括证书申请.证书更新.证书 ...
- IEEE二进制浮点数算术标准(IEEE 754)
整理自IEEE 754 IEEE二进制浮点数算术标准(IEEE 754)是20世纪80年代以来最广泛使用的浮点数运算标准,为许多CPU与浮点运算器所采用.这个标准定义了表示浮点数的格式(包括负零-0) ...
- verilog 介绍
Verilog HDL Verilog HDL是在C语言的基础上发展起来的一种硬件描述语言,语法较自由.VHDL和Verilog HDL两者相比,VHDL的书写规则比Verilog HDL烦琐一些,但 ...
随机推荐
- Run nginx from Docker in Windows
1.首先, 使用 docker run hello-world 命令 确认 docker 在本地安装成功,若成功应如下所示(此处使用的是 Docker Toolbox 在Windows上安装Docke ...
- 问:在指定的JSON数据中(最外层是数组)根据指定条件拿到匹配到的结果
let carr = [{ "code": "000", "agyTypeCode": "1", "name& ...
- vue 自己写的一个日历
样式: //quanbu全部代码 <template> <div class="priceListContent clearfix"> <!-- 顶部 ...
- linux命令--truncate 学习
truncate命令可以将一个文件缩小或者扩展到某个给定的大小 可以利用该命令和-s选项来特别指定文件的大小 1.清空一个文件内容,尤其是log 2. truncate -s 0 test
- 用Vue来实现音乐播放器(三十八):歌词滚动列表的问题
1.频繁切换歌曲时,歌词会跳来跳去 原因: // 歌词跳跃是因为内部有一个currentLyric对像内部有一些功能来完成歌词的跳跃 //每个currentLyric能实现歌曲的播放跳到相应的位置 是 ...
- kafka 通信报文格式
1. 序列化一条消息 消息有 key 和 value kafka 提供了基础数据类型的序列化工具,对于业务的自定义类需要自行实现序列化 ProducerRecord 是对象,含 KV 和 header ...
- Python 2 和 3 的区别及兼容技巧
目录 目录 前言 Python 2 or 3 ? 不同与兼容 统一不等于语法 统一整数类型 统一整数除法 统一缩进语法 统一类定义 统一字符编码类型 统一导入模块的路径搜索方式 修正列表推导式的变量作 ...
- C# 无焦点获取扫码枪扫码信息
代码网上有的是,多是需要窗体焦点直接show出扫码信息(usb,模拟键盘,hook) 怎样才能真的无焦点获取? 用串口方式 usb转串口 以接收串口通讯消息的方式获取扫码信息
- vim加脚本注释和文本加密
vim /etc/vimrc 一.李导版本 autocmd BufNewFile *.py,*.cc,*.sh,*.java exec ":call SetTitle()" fun ...
- 社工 - By浏览器 - Google搜索技巧 - 汇总
google基本语法 Index of: 使用它可以直接进入网站首页下的所有文件和文件夹中 intext: 将返回所有在网页正文部分包含关键词的网页 intitle: 将返回所有网页标题中包含关键词的 ...