verilog 2001中的一些新语法

比较有用的:1,generate语句,但需注意,generate-for中变量范围是已知的确定值, generate-case,generate-if语句中变量都必须是固定的,

generate必须跟endgenerate 中间begin加块名。

2,算术左移右移

3,有符号数,其实就是两个变量位宽不一致做运算的时候,低位宽的补齐位宽的方式与以前发生了变化,原来是用零补齐,现在看最高位如果是1就以1补齐,如果是0,就以0补齐。

4,多维向量,并且可以取向量的任意一位。

1.Verilog-2001的由来
      Verilog HDL 虽然得到了广泛应用,但是人们在应用过程中也发现了Verilog的不少缺陷。在2001年,OVI(Open Verilog Initiative)向IEEE提交了一个改善了用户觉得原始的Verilog-95标准缺陷的新的标准。这一扩展版本成为了IEEE1364-2001标准,也就是Verilog 2001。Verilog 2001是1995的增补,现在几乎所有的工具都支持Verilog 2001。Verilog 2001也被称作Verilog 2.0。应该说,作为一个Verilog的使用者,懂Verilog的语法是必须的。对于大多数人来讲,在使用Verilog的过程中,总是不知觉的将Verilog 2001和1995混用。

2.Verilog-2001的模块定义
     相比于Verilog-1995,Verilog-2001允许更加灵活的模块定义方式,语法如下:
     module module_name
     #(parameter_declaration, parameter_declaration,... )
     (port_declaration port_name, port_name,..., port_declaration port_name, port_name,...);
     module items
     endmodule
           而Verilog-1995的语法如下
     module module_name (port_name, port_name, ... );
     port_declaration port_name, port_name,...;
     port_declaration port_name, port_name,...;
     module items
     endmodule
     
     (port_declaration port_name, port_name)的一个实例如下:
     parameter SIZE = 4096;
     input [log2(SIZE)-1:0] addr;
     
     Verilog-2001风格的模块示例如下:
     module reg4 (output wire [3:0] q,input wire [3:0] d,clk);
     input clk;
     …
     endmodule
     用户可以继续使用Verilog-1995的风格,也可以采用Verilog-2001的风格。

3.Verilog-2001端口定义
     Verilog-2001允许更加灵活的端口定义方式,允许数据类型和端口方向同时定义,语法如下:
     port_direction data_type signed range port_name, port_name, ... ;
     其中,signed是Verilog-2001的一个新增关键字,表示有符号数据类型,以2的补码方式表示。
     端口定义的实例如下:
       output signed [31:0] result;
       input signed [15:0] a, b;
       input [15:12] addr;
       inout [0:15] data_bus;

4. Reg的定义
   在Verilog-1995中定义和初始化reg需要两条语句,而在Verilog-2001中可以合成一条语句。

实例如下:
   Verilog-1995:
   reg clock;
   initial
   clk = 0;
   
   Verilog-2001:
   reg clock = 0;

5.Verilog-2001的缺省位扩展
     在Verilog-1995中,在不指定基数的情况下为大于32位的变量赋高阻值,只能使其低32位为高阻值,其他高位会被设置为0,此时需要指定基数值才能将高位赋值为高阻。

6. Verilog-2001使用逗号隔开敏感信号
Verilog-2001中可以用逗号来代替or隔开敏感信号。
     Verilog-1995:
     always @(a or b or c or d or sel)
     Verilog-2001:
     always @(a, b, c, d, sel)

7.Verilog-2001组合逻辑敏感信号通配符
在组合逻辑设计中,需要在敏感信号列表中包含所有组合逻辑输入信号,以免产生锁存器。在大型的组合逻辑中比较容易遗忘一些敏感信号,因此在Verilog-2001中可以使用@*包含所有的输入信号作为敏感信号。
     
     always @* //combinational logic sensitivity
     if (sel)
     y = a;
     else
     y = b;
    
    这样做的好处是避免敏感表芯合不完整导致的latch。

8.Verilog-2001指数运算
Verilog-2001中增加了指数运算操作,操作符为**。
     
     always @(posedge clock)
     result = base ** exponent

9.Verilog-2001递归函数和任务
在Verilog-2001中增加了一个新的关键字:automatic。该关键字可以让任务或函数在运行中从新调用该任务和函数。
      
      function automatic [63:0] factorial;
      input [31:0] n;
      if (n == 1)
      factorial = 1;
      else
      factorial = n * factorial(n-1);
      endfunction

10.Verilog-2001有符号运算
在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

11. Verilog-2001算术移位操作
Verilog-2001增加了算术移位操作,在Verilog-1995中只有逻辑移位操作。比如D的初始值为8’b10100011,则:
     
     D >> 3 //logical shift yields 8‘b00010100
     D >>> 3 //arithmetic shift yields 8‘b11110100

12.Verilog-2001多维数组
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];

13.Verilog-2001向量部分选择
在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。

14.Verilog-2001常量函数
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

15.Verilog-2001 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)
      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

时间: 2024-08-01 12:56:23

verilog 2001中的一些新语法的相关文章

.NET中那些所谓的新语法之三:系统预定义委托与Lambda表达式

开篇:在上一篇中,我们了解了匿名类.匿名方法与扩展方法等所谓的新语法,这一篇我们继续征程,看看系统预定义委托(Action/Func/Predicate)和超爱的Lambda表达式.为了方便码农们,.Net基类库针对实际开发中最常用的情形提供了几个预定义好的委托,这些委托可以直接使用,无需再重头定义一个自己的委托类型.预定义委托在.Net基类库中使用的比较广泛,比如在Lambda表达式和并行计算中都大量地使用,需要我们予以关注起来! /* 新语法索引 */ 1.自动属性 Auto-Impleme

.NET中那些所谓的新语法之一:自动属性、隐式类型、命名参数与自动初始化器

开篇:在日常的.NET开发学习中,我们往往会接触到一些较新的语法,它们相对以前的老语法相比,做了很多的改进,简化了很多繁杂的代码格式,也大大减少了我们这些菜鸟码农的代码量.但是,在开心欢乐之余,我们也不禁地对编译器内部到底为我们做了哪些事儿而感到好奇?于是,我们就借助反编译神器,去看看编译器到底做了啥事!其实本篇中很多都不算新语法,对于很多人来说可能都是接触了很久了,这里主要是针对.NET的老版本来说,是一个“相对”的新语法. /* 新语法索引 */ 1.自动属性 Auto-Implemente

.NET中那些所谓的新语法之四:标准查询运算符与LINQ

开篇:在上一篇中,我们了解了预定义委托与Lambda表达式等所谓的新语法,这一篇我们继续征程,看看标准查询运算符和LINQ.标准查询运算符是定义在System.Linq.Enumerable类中的50多个为IEnumerable<T>准备的扩展方法,而LINQ则是一种类似于SQL风格的查询表达式,它们可以大大方便我们的日常开发工作.因此,需要我们予以关注起来! /* 新语法索引 */ 1.自动属性 Auto-Implemented Properties 2.隐式类型 var 3.参数默认值 和

一起学习c++11——c++11中的新语法

c++11新语法1: auto关键字 c++11 添加的最有用的一个特性应该就是auto关键字. 不知道大家有没有写过这样的代码: std::map<std::string, std::vector<std::shared_ptr<std::list<T> > > > map; std::map<std::string, std::vector<std::shared_ptr<std::list<T> > > >

.NET中那些所谓的新语法

.NET中那些所谓的新语法之四:标准查询运算符与LINQ 摘要: 开篇:在上一篇中,我们了解了预定义委托与Lambda表达式等所谓的新语法,这一篇我们继续征程,看看标准查询运算符和LINQ.标准查询运算符是定义在System.Linq.Enumerable类中的50多个为IEnumerable准备的扩展方法,而LINQ则是一种类似于SQL风格的查询表达式,它们可以...阅读全文 posted @ 2014-11-20 21:29 Edison Chou 阅读(1230) | 评论 (10) 编辑

.NET中那些所谓的新语法之二:匿名类、匿名方法与扩展方法

开篇:在上一篇中,我们了解了自动属性.隐式类型.自动初始化器等所谓的新语法,这一篇我们继续征程,看看匿名类.匿名方法以及常用的扩展方法.虽然,都是很常见的东西,但是未必我们都明白其中蕴含的奥妙.所以,跟着本篇的步伐,继续来围观. /* 新语法索引 */ 1.自动属性 Auto-Implemented Properties 2.隐式类型 var 3.参数默认值 和 命名参数 4.对象初始化器 与 集合初始化器 { } 5.匿名类 & 匿名方法 6.扩展方法 7.系统内置委托 Func / Acti

什么?接口中方法可以不是抽象的「JDK8接口新语法的深度思考」

先赞后看,养成习惯 文本已收录至GitHub开源仓库 Lu_JavaNodes 码云仓库地址Lu_JavaNodes,包含教程涉及所有思维导图,案例代码和后续讲解视频,欢迎Star增砖添瓦. 前言 在传统的接口语法中,接口中只可以有抽象方法.在是在实际的使用中,我们往往会需要用到很多和接口相关的功能(方法),这些功能会单独的拿出开放在工具类中. 工具类:类中所有的方法都是静态的 例如:Collection 和 Collocations,Collection 是一个集合接口,而我们需要很多集合相关

总结常见的ES6新语法特性。

前言 ES6是即将到来的新版本JavaScript语言的标准,他给我们带来了更"甜"的语法糖(一种语法,使得语言更容易理解和更具有可读性,也让我们编写代码更加简单快捷),如箭头函数(=>).class等等.用一句话来说就是: ES6给我们提供了许多的新语法和代码特性来提高javascript的体验 不过遗憾的是,现在还没有浏览器能够很好的支持es6语法,点这里查看浏览器支持情况,所以我们在开发中还需要用babel进行转换为CommonJS这种模块化标准的语法. 因为下面我会讲到一

objective-c 新语法特性

2007年的时候,Objective-C在TIOBE编程语言排名里还排在可怜的第45位,而随着移动互联网的迅速发展和iPhone,iPad等iOS设备的广阔市场前景,Objective-C也迅速崛起,走进了开发者的视野.在最近的TIOBE排名中,Objective-C达到了惊人的第4名,可以说已经成为当今世界上一门非常重要的编程语言. 而Objective-C现在主要是由Apple在负责维护了.一直以来Apple为了适应开发的发展需要,不断在完善OC以及相应的cocoa库,2.0中引入的prop