对任务和函数的改进

对任务和函数的改进

1、任务和函数的隐式语句组
SystemVerilog会推断出begin…end
SystemVerilog简化了任务和函数的定义,有多条语句时不在需要begin …end对多条语句进行打包。打包省略之后,任务或函数中的语句将会顺序执行,就像仍然在begin…end中一样。

function states_t NextState(State_t State);NextState = State;//默认次态case(State)WAITE:if(start) NextState = LOAD;LOAD:if(done) NextState  = STORE;STORE:          NextState  = WAITE;endcase
endfunction

2、返回函数值
函数会创建一个与其名称和类型一样的隐含变量
SystemVerilog增加一条return语句,和C语言一样,函数可以像C语言中一样,使用return语句返回数值。

function int add_and_inc(input int a,b)return a+b+1;
endfunction

return语句的优先级高于返回函数名的值
如果执行return语句就会返回一个值。如果函数执行到最后也没有遇到return语句,那么与Verilog一样,最后赋给函数名变量的值就是函数的返回值。即使使用了return语句,函数名仍然是一个变量,可以执行return语句之前当作临时内存使用。

funciton int add_and_inc(input int a,b);add_and_inc = a + b;return ++ add_and_inc;
endfunction

3、在任务和函数结束前返回
return语句可以用来在到达结尾前退出
在SystemVerilog中,使用return语句可以在执行流的任何时刻退出任务或函数,而不需要到达任务或函数的结尾。

function automatic int log2(input int n);if(n <= 1) return 1; //异常中止函数log2 = 0;while(n>1)beginn = n/2;log2++;end
endfunction

4、空函数
SystemVerilog增加了一个类似C语言的类型–void。函数可以显式地声明为void数据类型,表示函数没有返回值。空函数的调用方式和任务一样。但同样有函数在语法和语义上的限制。例如,函数不能包含任何类型的延迟或事件控制,也不能使用非阻塞赋值语句。空函数的另一个优点是克服了函数不能调用任务,这改善了难以在复杂函数添加编码结构的缺陷。不管怎样,函数总可以调用其他函数,调用空函数就可以得到和使用任务相同的结构化编码风格。
SystemVerilog的另一个改进之处是函数可以有output和inout的形式参数。这样一来,虽然空函数没有返回值,仍然可以传送调用函数所产生的变化。

typedef struct{logic valid;logic [7:0] check;logic [63:0] data;
}packet_t;function void fill_packet(input logic [63:0] data_in;output packe_t data_out
);data_out.data = data_in;for(int i = 0; i <= 7; i++)data_out.check[i] =^data_in[8*i +:8];data_out.valid = 1;endfunction

在可综合的模块中,使用空函数来代替任务
空函数的优势在于它可以像任务一样被调用,但必须遵循函数编码规则,例如函数不能包含事件控制,这样的限制有助于确保能综合处正确的结果。
5、使用名称传递任务/函数的参数
SystemVerilog可以通过名称传递变量值
在SystemVerilog中,增加了使用形式参数的名称而不是顺序来传递参数值的功能。通过参数名称传递可以用任何顺序,而且显式的传递给指定的形式参数。

always@(posedge clock)result <= divide(.denominator(b),.numerator(a));function int divide(input int numerator,denominator);if(denominator == 0)beginif(denominator == 0)begin$display("Error!divide by zero");return 0;endendelsereturn = numerator / demoinator;endfunction

参数名称传递可以减少错误
使用参数名称传递的方式消除了原先那个数组应该传给那个参数的不确定性。任务或函数的调用代码明确地指明了设计的意图,而且减少了那些由于疏忽造成的不易察觉和调试的设计错误。
6、增强型函数形式参数
SystemVerilog的函数有输入和输出端口
SystemVerilog允许函数的形式参数像任务一样,可以声明为input、output和inout。函数可以有任意个输出以及函数返回值,这极大地扩展了函数的建模范围。

//SystemVerilog风格的函数形式参数
function [63:0] add(input [63:0] a,boutput overflow);
{overflow,add} = a +b;
endfunction

对有输出的函数的调用限制
为了防止出现不合要求的以及不可综合的边缘效应,SystemVerilog对何处能调用有output或inout参数的函数进行了一定的限制。有输出或输入输出参数的函数不能在一下几种情况中调用:

  • 事件表达式
  • 使用过程持续赋值的表达式
  • 不在过程语句内的表达式

7、无形式参数的函数
SystemVerilog的函数可以没有参数
8、形式参数的缺省方向和类型
缺省的形式参数方向是输入
SystemVerilog简化了任务和函数声明的语法,形式参数的缺省方向为input。也就说,如果没有声明形式参数方向,所有参数假定是输入的。一旦声明了一个方向,后面的参数为声明的方向。

function int compare(int a,b);
...
endfunciton
//a,b是输入,y1,y2是输出
task mytask(a,b,output y1,y2);
...
endtask

缺省的形式参数类型是logic
9、缺省的形式参数值
SystemVerilog允许任务与函数为每个形式参数定义一个可选的缺省值。设定缺省值的语法与设置变量的初始值的语法类似。

形式参数count的缺省值是0,形式参数step的缺省值是1function int incrementer(int count = 0,step = 1);incrementer = count + step;
endfunction

调用任务或函数时可以对一些参数不指定
当调用任务或函数时,不一定非得给有缺省值的参数传递参数值。如果没有给这种参数传递任何值,则在任务或函数调用时使用缺省值。

函数incrementer在调用时只给了一个值,
这个值会传递给函数的第一个形式参数。
而第二个形式参数step,会使用缺省值1always@(posedge clock)result = incrementer(data_bus);

缺省的形式参数值允许任务或函数调用时只传递与该次调用相关的参数
SystemVerilog允许任务或函数的参数表达式数目小于形式的参数数目。
如果在调用中,没有给任务或函数的参数传递数值,则该参数的形式定义中必须有一个缺省值。如果存在一个没有缺省值,也没有传递值的形式参数,系统就会报告一个错误。
10、数组、结构体和联合体作为形式参数
形式参数可以是结构体联合体或数组
SystemVerilog允许非压缩数组、压缩或非压缩结构体和压缩、非压缩或标签联合体传递出/出任务和函数。对于结构体和联合体,形式参数必须定义为结构体或联合体类型(用typedef来定义这种类型)。压缩数组在传递给任务或函数时被看做向量。如果调用的压缩数组参数的宽度与形式参数不匹配,该向量就会按照Verilog向量赋值规则进行截断或扩展。对于非压缩数组,传递给任务或函数的调用数组参数必须与数组形式参数定义的结构和元素类型精确匹配。为了匹配,调用参数和形式参数必须具有相同的数组维数和维度宽度,并且每个元素有效相同的压缩宽度。

typedef struct packed{logic valid;logic [7:0] check;logic [63:0] data;
}packet_t;
function void fill_packed(input logic [7:0] data_in [0:7];//数组参数output packed_t data_out //结构体参数
);
for(int i = 0;i <= 7; i++)
begindata_out.data[(8*i) + :8] = data_in[i];data_out.check[i] = ^data_in[i];
enddata_out.valid = 1;
endtask

11、用引用取代复制来传递参数值
数值通过复制传递给任务和函数
当调用任务或函数时,系统会将输入值复制到任务或函数中于是这些值变为任务或函数的局部数值。当任务或函数执行到末尾返回时,系统再将所有的输出复制到任务或函数调用程序。
SystemVerilog可以通过引进任务/函数参数进行显式传递
SystemVerilog对自动任务和函数进行扩展,可以使用引用而不是复制的方法传递数值。为了通过引用传递数值,形式参数用关键字ref取代方向关键字input,output,或inout进行声明。ref参数名就成了对传递任务或函数的值的实际储存区进行层次化引进的别名。任务或函数内使用的是局部参数名而非外部信号名。这种引用提供了类似Verilog外部信号引用的能力,但没有外部信号名必须硬编码到任务或函数一样。
ref形式参数是实际值的别名
通过引进传递,变量只需要在调用部分声明,而不需要在任务或函数描述时再次声明。这样,任务或函数只在它调用的范围内引用这个变量。引用不传递到任务或函数内的信号就像对外部信号的引用已经隐含传递给任务或函数一样。

注意:只有自动任务和函数可以具有ref参数

为了具有ref参数,任务或函数必需是自动的。任务或函数可以显式声明为自动的,也可以通过为定义为自动的模块、接口或程序中声明来推断为自动的。

module chip(...);typedef struct{logic valid;logic [7:0] check;logic [63:0] data}packet_t;packet_t data_packet;bit[7:0] raw_data [0:7];always@(posedge clock)if(data_ready) fill_packet(.data_in(raw_data),.data_out(data_packet));function automatic void fill_packet(ref logic[7:0] data_in [0:7];//ref参数ref packed_t data_out    //ref参数);for(int i = 0;i <= 7;i++)begindata_out.data[(8*i)+:8]=data_in[i];data_out.check[i] = ^data_in[i];end
endfunction
...
endmodule

只读引用参数
通过引用传递的参数为只读
通过将形式参数声明为const ref类型,可以将引用形式参数声明为只允许对引用的对象进行读操作。这样可以使任务或函数只能引用调用部分的信息,而禁止任务或函数改动信息的内容。

  	function automatic void fill_packet(const ref logic[7:0] data_in [0:7];//ref参数ref packed_t data_out    //ref参数);...endfunction

任务ref参数对变化敏感
通过引用传递的参数允许对变化敏感
ref参数的一个重要特点是任务中的逻辑会对信号在调用程序内发生的变化敏感。对变化的这种敏感对函数ref参数不适用。由于函数必需零延时执行,函数不能包含对参数变化敏感的时间控制。

typedef struct packed{logic valid;logic [7:0] check;logic [63:0] data;
}packet_t;
packet_t send_packet,receive_packed;task automatic check_results(input packet_t sent,ref packet_t received,ref logic done
);static int error_count;wait(done)if(sent !== receive)beginerror_count++;$display("ERROR! receive bad packet");end
endtask

ref参数可以读取当前值
ref参数可以立即传播变化
如果任务的输出通过复制来传递,需等到任务退出时才会将输出值复制回调用模块,假如在任务的输出参数值发生变化时间和任务退出的时间之间存在时序控制或者事件控制,调用程序只能在任务退出时才能看到变量的这个变化,而不能在其发生变化时立即察觉。
如果任务的输出通过引用来传递,任务将对调用模块中变量直接赋值。因此调用模块中对这个变量敏感的事件控制都会第一时间检测到变化,而不是要等到任务执行完将输出参数复制回调用模块时。
对使用ref参数进行函数调用的限制
带有ref形式参数的函数可以修改函数外部变量的值,因此与带有输出参数的函数有相同的使用限制。有output、inout或ref参数的函数不能被以下几种情况调用:

  • 事件表达式
  • 持续赋值中的表达式
  • 过程持续赋值内的表达式
  • 不在过程语句内的表达式

命名的任务和函数结尾
SystemVerilog允许用关键字endtask和endfunction指定名称。

endtask:<task_name>
endfunciton:<funciton_name>

冒号前后的空格可以省略。结尾处指定的名称必须与对应的任务或函数的名称一致。

function int add_and_inc (int a,b);return a+b+1;
endfunciton:add_and_incrask autormatic check_result(input packet_t sent,ref packet_t received,ref logic done
);
static int error_count;
...
endtask:check_results

13、空任务和函数
任务或函数可以为空
SystemVerilog允许任务和函数完全为空,即不包含任何语句或语句组。空函数将返回表示函数名的隐含变量的当前值。
空任务和空函数在非完整的代码中预留出了空间。对于自顶向下的设计流程而言,可以在模块的描述中创建空任务和函数作为模型文件,而在后面的设计步骤中逐步将其内容添加完整。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/243272.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

RAPI简单说明及Sample Code

RAPI简单说明及Sample Code 一&#xff0e;什么是RAPI RAPI用来通过ActiveSync来建立PC与Device的通信。通过RAPI可以实现PC 对Device的控制和同步。 二&#xff0e;使用说明 常用的RAPI包括File I/O的一些操作&#xff0c;以及获取系统信息的一些API。 在使用RAPI来建立PC与…

在C/C++代码中使用SSE等指令集的指令(1)介绍

http://blog.csdn.net/gengshenghong/article/details/7007100我们知道&#xff0c;在C/C代码中&#xff0c;可以插入汇编代码提高性能。现在的指令集有了很多的高级指令&#xff0c;如果我们希望使用这些高级指令来实现一些高效的算法&#xff0c;就可以在代码中嵌入汇编&…

递增和递减操作符

递增和递减操作符 和- -操作符 for(i 0;i < 31; i) begin... end先加与后加 通常原则是&#xff0c;对组合逻辑使用阻塞赋值&#xff0c;而对时序逻辑赋值使用非阻塞赋值。 注意&#xff1a;和--操作符是阻塞赋值i;//使用阻塞赋值对i进行递增 ii1;//使用阻塞赋值对i进行…

User Mode Driver Management介绍(一)

User Mode Driver介绍 Windows CE 6.0中引入了User Mode Driver的概念&#xff0c;可是无论是网上&#xff0c;还是各个芯片厂商提供的方案中&#xff0c;都很少提及这方面的内容。 本文以小郭对存储管理和User Mode Driver Host的理解为基础&#xff0c;结合具体的代码实现&am…

CString内存泄露

经常见到 unicode 设置不一致造成内存泄露。。。

赋值操作符

赋值操作符 和其他赋值操作符 out in;//将out和in相加并将结果赋值给out //out out in;注意&#xff1a;这些操作符都是阻塞赋值packdage definitions;typedef enum logic[2:0] {ADD,SUB,MULT,DIV,SL.SR} opcode_t;typedef enum logic{UNSIGNED,SIGNED}operand_type_t;typ…

SolidGraph CAD System

http://www.codeproject.com/Articles/15554/SolidGraph-CAD-System

User Mode Driver Management 介绍(二)

&#xff08;接上一篇&#xff09; 3> 调用User Mode Driver Host API来将Driver Load到内存 CeFsIoControl()实际上是一个对文件系统驱动FSD进行操作的函数&#xff0c;需要传入文件夹名字和IoControlCode。 帮助文档中对该函数的解释如下&#xff1a; This function send…

有无关通配符的相等操作符

有无关通配符的相等操作符 逻辑相等操作符 条件相等操作 SystemVerilog通配符相等操作符允许屏蔽某些位 SystemVerilog还增加了两个新的比较操作符&#xff1a; &#xff1f; 和&#xff01;&#xff1f;。这两个操作符允许在比较中屏蔽无关位。 操作符 &#xff1f;&#x…

cab文件介绍及制作方法

转自&#xff1a;http://bbs.pcpop.com/091030/5945399.html 1. 什么是cab文件 CAB在电脑上是一种压缩文件&#xff0c;微软出品的东西&#xff0c;用WinRAR可以解压缩&#xff0c;在DOS启动盘里面可以看见一些CAB压缩文件。其实Windows里面已经带了CAB压缩程序&#xff0c;但…

设置成员操作符--inside

设置成员操作符–inside SystemVerilog增加了一个检测是否集合中–员的操作符&#xff0c;这个操作符的关键字是inside。 logic [2:0] a; if(a inside{3b001,3b010,3b100}) //等价if((a3b001)||(a3b010)||(a3b100)) ...使用inside操作符可以方便的比较一个数值和多个可能值之…

CVE-2015-0235: GHOST – A Critical Vulnerability in the Glibc Library

GHOST is a ‘buffer overflow’ bug affecting the gethostbyname() and gethostbyname2() function calls in the glibc library. If a remote attacker can make an application call to gethostbyname() or gethostbyname2(), this vulnerability allows the remote attack…

开发库 C++

C/C 开发库 | C/C Development Library 这里收集一些著名的 C/C 开发库、SDK、类库、可复用类与结构代码 等信息&#xff0c;列举它们的介绍、参考和网站链接&#xff0c;为各位 C/C 程序员和爱好者提供检索和查阅类库的方便 下面收集的 C/C 类库介绍整理来源于文章&#xff1a…

VS2005与Device通过ActiveSync连接异常的常见原因

VS2005与Device通过ActiveSync连接异常的常见原因 很多人都碰到过VS2005与Device之间不能够通过ActiveSync进行连接的问题&#xff0c;中间报出来的错误也是形形色色。 根据自己碰到过的原因&#xff0c;我总结了一下&#xff1a; 一&#xff0e;VS2005与Device的连接方式错误…

操作数改进

操作数改进 1、两态和四态类型数据的运算 全两态类型的运算使用Verilog运算法则 Verilog对大多数操作数类型的混合运算都制定了相应规则。 SystemVerilog包含了Verilog没有涉及的两态类型数据的运算&#xff0c;从而对这些规则进行了扩展。对SystemVerilog新类型的运算按照相同…

通过ap运行cab安装程序的方法及Sample Code

1. 第一部分&#xff1a;Sample Code 这部分转自&#xff1a;http://blog.csdn.net/hhygcy/archive/2009/05/04/4147870.aspx 最近这个东西很多被问及&#xff0c;软件动态升级的时候可能可以用到&#xff0c;在这里做一下记录。 就知道的方法有2个&#xff0c; 一个是通过Sh…

MFC透明桌面flash金鱼

代码&#xff1a; http://download.csdn.net/detail/hemmingway/6823935 使用方法&#xff1a; //0,添加left.png&#xff0c;right.png资源文件 //1, 头文件定义变量 GoldFish pet; //2, 在CPP文件创建 // Create a goldfishif (!pet.Create(NULL, NULL, WS_CHILD | WS_VISIB…

改进的for循环

改进的for循环 声明局部循环变量 SystemVerilog简化了声明用于for循环的局部变量的方法。SystemVerilog可以在for循环内部声明循环变量。这样就不需要在模块级定义多个变量&#xff0c;也不用在命名的begin…end块中定义局部变量了。 module chip(...);//SystemVerilog风格的…

程序员们请别做下一个小贝

据网友提供的《蜗居》第24集3:30秒截图&#xff0c;有理由相信小贝是搞 C 的 那本书是《大规模C程序设计》 -- 历史上一定有那么一些人&#xff0c;没有名&#xff0c;没有钱&#xff0c;只是和爱人一起过完了一生。他们不用思念&#xff0c;不用写情话。他们的情话&#xff0c…

底部检测的do...while循环

底部检测的do…while循环 1、while循环可能从未执行 while循环有可能根本没有执行过。当执行流首次执行到循环的开头&#xff0c;控制值就为假的时候就会发生这种情况。 为了保证循环的每个输出都与循环的输入变量保持一致&#xff0c;使用这种在开头检测的while循环需要在循环…