Verilog HDL入门基础之行为级建模.docx

上传人:PIYPING 文档编号:11505616 上传时间:2021-08-10 格式:DOCX 页数:17 大小:79.92KB
返回 下载 相关 举报
Verilog HDL入门基础之行为级建模.docx_第1页
第1页 / 共17页
Verilog HDL入门基础之行为级建模.docx_第2页
第2页 / 共17页
Verilog HDL入门基础之行为级建模.docx_第3页
第3页 / 共17页
Verilog HDL入门基础之行为级建模.docx_第4页
第4页 / 共17页
Verilog HDL入门基础之行为级建模.docx_第5页
第5页 / 共17页
点击查看更多>>
资源描述

《Verilog HDL入门基础之行为级建模.docx》由会员分享,可在线阅读,更多相关《Verilog HDL入门基础之行为级建模.docx(17页珍藏版)》请在三一文库上搜索。

1、行为级建模建模的基本结构module ()模块端口说明参数定义数据类型说明过程块(initial 过程块或always 过程块,可以有一个或多个)连续赋值语句任务定义(task)函数定义(function)endmodule针对上述语法格式进行如下说明: 方括号“”内为可选项。 中可以有单个或多个输入、输出、或双向端口;这些端口类型要在端口说明部分进行类型定义。 参数定义用关键词“parameter”实现,如果模块定义了参数,那么该模块的每个实例(调用)都可以对该参数进行重新定义,使得该参数对每一个具体的模块实例是唯一的。 数据类型说明用来对模块中用到的各种数据类型进行说明。如果某个数据没有进

2、行类型说明,则它的默认数据类型为线网类型“wire”。 过程块是由过程语句initial或always开头的语句块,根据这两个不同的关键词,过程块可以分为“initial”过程块和“always”过程块两种类型。每个过程块包含一条或多条行为语句。过程块可以有一个或多个,它们是行为建模的主要组成部分。 连续赋值语句是由关键词“assign”开头的一种赋值语句。它只能对线网(net)型数据进行驱动。它和语句块一样,也是一种行为建模语句。 任务定义和函数定义都是可选项,引入它们的目的是为了描述模块中被多次执行的部分以及为了增强代码的可读性。上述各个模块组成项可以以任意次序出现,但是端口说明和数据类型

3、说明必须出现在这些端口和数据被引用之前。还有一点,在行为级建模方式中没有出现模块实例语句或基本元件实例语句,而只有过程块、连续赋值语句、任务和函数定义这几种结构成分。任务和函数的使用也要在过程块和连续赋值语句中进行调用。一个行为建模方式的模块中可以同时包含多个过程块和多个连续赋值语句,它们将可以并行方式各自独立执行。例子module behave;reg 1:0 a,b;initialbegina = b1;b = b0;endalwaysbegin#50 a = a; /变量的值将保持到指定的延迟时间(由符号“#”引导的延迟控制)结束时才会发生变化endalwaysbegin#100 b =

4、 b;endendmodule过程块结构Verilog HDL中每个过程块都是由过程语句always或initial和语句块组成。而语句块主要是由过程性赋值语句(包括过程赋值语句和过程连续赋值语句)和高级程序语句(包括条件分支语句和循环控制语句)这两种行为语句构成。具有如下特点: 在行为描述模块中出现的每一个过程块(always过程块或initial过程块)都代表独立的进程。 在进行仿真时,所有initial过程块和always过程块的执行都是从0时刻开始并行进行。 每一个过程块内部的多条语句的执行方式可以是顺序执行的(当块定义语句为begin-end时的情况),也可以是并行执行的(块定义语句

5、为fork-join时的情况)。 Always过程块和initial过程块都是不能潜嵌套使用的。Initial过程块Initial过程块由initial语句和语句块组成,主要用于仿真,不具有可综合性,常常用来对只执行一次的进程进行描述,不能有敏感列表,它的语法格式如下:Initial语句块而语句块的语法格式为:时间控制1 行为语句1;时间控制n 行为语句n;针对上述格式,做如下说明。 过程语句关键词initial表明过程块是一个initial过程块。 和构成了一组块定义语句,它们可以是begin-end语句组或fork-join语句组。这两条块定义语句将它们之间的多条行为语句组合在一起,使之构

6、成一个语句块,并使其在格式上更像一条语句。当语句块中只包含一条行为语句并且不需要定义块名和块内局部变量时,这两条块定义语句可以省略。 为可选项,块名可以为语句块创建一个局部作用域。定义了块名的过程块称为有名块,在有名块内可以定义局部变量,有名块内部语句的执行可以被disable中断。 块内局部变量说明也是可选项,只有在有名块内才可以定义局部变量,并且块内局部变量只能是寄存器数据类型。 时间控制用来对过程块语句的执行时间进行控制。它可以是任何一种控制方式。 行为语句可以是下列语句的一种:过程赋值语句(阻塞型和非阻塞型过程赋值语句); 过程连续赋值语句(assign/deassign或者force

7、/release语句组); If条件分支语句; Case条件分支语句; 循环控制语句(forever, repeat, while, for循环控制语句); Wait等待语句; Disable中断语句; 事件触发语句(event_trigger); 任务调度语句(用户自定义任务或系统任务)。上述行为语句中的赋值语句(除force/release过程连续赋值语句外)只能对寄存器型变量进行赋值例子:initial过程块用于为电路仿真生成激励信号波形。module zzy( outputs);output 5:0 outputs; reg 5:0 outputs; initial begin out

8、puts= b000000; /初始时刻为0 #10 outputs=b011001; /10个时间单位后值改变 #20 outputs=b011011; #5 outputs=b011000; #10 outputs=b001000; endendmodule用ISE自带的Isim仿真后的结果如下(仿真以1ns为仿真的时间单位):always过程块always过程块是由always过程块语句和语句块组成的,其语法格式如下:always(敏感事件列表)语句块其中语句块的格式为:时间控制1 行为语句1;时间控制n 行为语句n; 过程语句关键词always表明该过程块是一个always过程块 (时

9、间敏感列表)是可选项,带有敏感事件列表的语句块被称为“由事件控制的语句块”,它的执行要受到敏感事件的控制。敏感事件的列表的格式为:(event-expression or event-expression)敏感事件列表是由一个或多个事件表达式(event-expression)构成的,当存在多个表达式时用or将它们连接起来。 Always过程块中关于块定义语句的规定和initial一样 Always与initial不同之处,在仿真时虽然都是从0时刻开始,但是always会在仿真过程中不断重复执行,并且其内部的语句的执行由敏感列表的事件触发,如果敏感事件列表默认则always过程块会无条件重复执

10、行下去直到遇到$finish或$stop为止。语句块语句块由块定义语句所界定的一组行为语句。块定义语句只有两种,前面在过程块中已将有讲解。但过程块不可以嵌套而语句块可以,而且过程块之间也是并行关系。注意!如果语句块需要给出块名,则一定要在块定义语句后用引号(:)引出块名;反之,一定不要使用引号。时间控制延时控制延时控制的语法格式为:# 行为语句;或#;其中:符号(#)是延时控制的标识符;是直接指定的延迟时间量,它表示仿真时间单位的个数,可以是一个立即数、变量或表达式。如果代表的变量或表达式的值未知或高阻,则该延迟控制等效于0延迟;如果代表的变量或表达式的值为负值,则以该负值二进制补码所代表的无

11、符号整数作为实际的时间延迟量。边沿事件控制语法格式如下: ()行为语句; (); (oror.or)行为语句; (oror.or);上述表达式中()是边沿触发事件控制的标识符,“事件表达式”代表触发语句执行的触发事件;而“行为语句”则指出了触发事件所要触发执行的具体操作。事件表达式: ; posedge; negedge;其中,第一种事件表达式代表只要信号发生了某种逻辑变化(无论正跳变还是负跳变),即逻辑值从0、1、x、z四个值中的一个变化到另一个,都算事件触发;第二种事件表达式代表所指定的信号发生了正跳变( 中的一种),就算事件触发;第三种事件表达式代表所指定的信号发生了负跳变( 中的一种)

12、,就算事件触发;敏感事件列表在always过程块中的应用(1) 用always过程块实现组合逻辑 事件表达式内不能包含posedge和negedge关键词 组合逻辑的所有输入都要作为出现在敏感列表中(2) 用always过程块实现时序逻辑 事件表达式可以是上述表达式三种中的任意一种 不要求所有输入都要作为出现在敏感列表中电平敏感事件控制(wait语句)电平敏感事件控制用关键词wait来表示,它有如下三种形式: wait(条件表达式)语句块; Wait(条件表达式)行为语句; Wait(条件表达式)上面的结构中,只有当条件表达式的逻辑值为真时才执行后面的语句;下面用上述三种格式实现当enable

13、置于高电平时对输入实现与或操作:Wait(enable=1)begind=a&b;d=d|c;endwait (enable=1) d=a&b|c;beginwait (enable=1);d=a&b;d=d|c;end注意此处要想实现wait语句对后面语句的控制只能在顺序执行的语句中。例子:(参照实现时序逻辑的仿真)module zzy(flag1,flag2); output flag1,flag2; reg enable,flag1,flag2; initial begin flag1=1; flag2=1; enable=1; #20 enable=0; #10 enable=1; e

14、nd always begin #10; wait(enable=1) flag1=flag1; end initial begin #10 (posedge enable) flag2=flag2; endendmodule赋值语句过程赋值语句过程赋值语句的语法格式为:;其中,可以是“=”(阻塞型)或“=”(非阻塞型),有关控制语句前面已将介绍。过程赋值语句的具体目标可以是: Reg、integer、real、time型变量(标量或矢量) 上述变量矢量的的某一位或某几位 存储器数据类型,只能对某个地址单元的整个字进行操作,不能对该字的某一位或某几位进行赋值操作。 上述几个变量用连接操作符“,

15、”拼接起来构成的整体。赋值语句中可以出现延时控制和事件控制的时间控制,根据控制语句出现的位置可以分为外部事件控制方式(如#10 a=b)和内部时间控制方式(如b=#10 b)。前者是等待一段时间后才计算等号右边的表达式的值,后者是立即计算等号右边的表达式的值,等待一段时间后才赋值。阻塞型和非阻塞型赋值语句阻塞型过程赋值语句:其特点如下: 顺序语句块中的阻塞型赋值语句将按照他们的位置的顺序先后执行;并行语句块中的阻塞型赋值语句是同时得到执行的。 其执行过程是:首先计算右端复制表达式的值,然后立即将计算结果赋值给“=”左端的被赋值变量。非阻塞型过程赋值语句: 在顺序语句块中,一条非阻塞型语句的执行

16、不会影响下一条语句的执行,也就是说当前语句在执行时,下一条语句可以开始执行。 仿真进程在遇到非阻塞型语句时,首先计算右端赋值表达式的值,然后等到当前仿真结束时才将计算结果赋值给被赋值变量,即非阻塞型赋值操作是在其他普通操作完成后才执行。如下例子:initialbegina=b;b=a;end上述例子中首先计算b的值,此时由于是非阻塞语句,因而同时计算a的值,在这个时刻结束时进行赋值,相当于a、b的值互换。在多条非阻塞赋值语句(时间延迟相同)对同一变量赋值,那么变量的最终值是由过程块中的最后一句决定。连续赋值语句和过程连续赋值语句连续赋值语句连续赋值语句主要用来对组合逻辑电路的行为进行描述,而不

17、需要指定组合逻辑电路元件之间具体的硬件连接关系。连续赋值语句只能用来对线网数据类型(标量或矢量)进行驱动(赋值),而不能对变量型数据类型进行赋值,它有以下两种格式 显式连续赋值线网型数据类型(赋值驱动强度)线网型数据位宽 线网型数据名;Assign #(延迟量)线网型数据名=赋值表达式; 隐式连续赋值语句线网型数据类型(赋值驱动强度)线网型数据位宽#(延迟量)线网型数据名=赋值表达式;在显式连续赋值语句中包含了两条语句:第一条语句是对线网型数据进行类型声明的语句;第二句是对这个已经得到申明的线网型数据类型进行连续赋值的赋值语句。在隐式连续赋值语句中将线网型数据的声明语句及对该线网型数据进行连续

18、赋值的赋值语句组合到同一语句中。利用隐式连续赋值语句可以对线网型数据进行类型声明的同时实现连续赋值。 关键词“assign”是连续赋值语句的标志。 “(赋值驱动强度)”为可选项,它用来对线网型数据受到的驱动强度进行指定。该选项由“对1驱动强度”和“对0驱动强度”两项组成。比如语句“wire(weak1,strong0)a=b&c”内的“(weak1,strong0)”就表示该语句指定的连续赋值对线网型数据a的驱动强度是:赋1值时的驱动强度为“weak(弱)”,而赋0值时的驱动强度为“strong(强)”。如果在连续赋值语句中默认了驱动强度这一选项,则驱动强度默认为(strong1,strong

19、0)。 “#(延迟量)”也为可选项。它指定了由赋值表达式内信号发生变化时刻到线网型数据取值被更新时刻之间的延迟时间量。它类似于基本元件声明时指定的延迟量。“延迟量”的基本格式如下:#(delay1,delay2,delay3)其中delay1,delay2,delay3都是一个数值。Delay1指定了线网型数据转移到“1”状态时的延迟量(称为上升延时);delay2指定了线网型数据转移到“0”状态时的延迟量(称为下降延时);delay3指定了线网型数据转移到“z(高阻)”状态时的延迟量(称为关断延时)。实际使用中可以有所省略: 若只给出一个延迟值,则这个延时值将同时代表“上升延时值”、“下降延

20、时值”、“关断延时值”。 若只给出两个延时量,则这两个延时值将分别代表“上升延时值”、“下降延时值”,而“关断延时值”将由给出的两个延时值中较小的那一个指定。 若“延时值“这一项默认,则默认所有的延时值都为”0“ “赋值表达式“内可以包含线网型、变量型或函数调用等任何数据类型的操作数,同时也可以包含任何操作数。连续赋值语句的赋值目标可以是如下几种: 标量线网型数据类型。如:wire a,b;assign a=b; 矢量线网型数据类型。如:wire 7:0 a,b;assign a=b; 矢量线网型数据的某一位。如:wire 7:0 a,b;assign a4=b4; 矢量线网型数据的某几位。如

21、:wire 7:0 a,b;assign a4:1=b4:1; 上述几种类型的任意拼接结果。如:wire a,c;wire2:1bassign a,c=b;在需要对多个线网型数据进行连续赋值时,还可以采用如下形式的连续赋值语句,它可以实现对多个线网型数据进行连续赋值:assign out_and=a&b; out_or=a|b; out_xor=ab; out_not_a=a; out_not_b=b;与寄存器变量不同,线网型数据(除了trireg类型外)没有数据保存能力,只有在被连续赋值驱动后才能取得确定值;若一个线网型数据没有得到任何连续驱动,则它的取值将为不定态”x“,(还有一种进行连续

22、驱动的方法是由某个模块输出端来对线网型数据进行驱动)连续性赋值语句与过程赋值语句的区别: 从语法上来看,连续赋值语句由”assign“关键词来标识,而过程赋值语句中则不包含这个关键词。 连续赋值语句中左侧的被赋值数据必须是线网型数据,而过程赋值语句中的被赋值数据类型必须是寄存器型的变量。 连续赋值语句不能出现在过程块中,而过程赋值语句只能出现在过程块内 连续赋值语句主要用来对组合逻辑电路进行建模以及对线网型数据间的链接进行描述,而过程赋值语句主要用来对时序逻辑电路进行行为描述 连续赋值语句对被赋值线网型数据的赋值是”连续“的(即连续赋值语句产生作用后,赋值表达式中信号的变化都将立即反映到被赋值

23、线网型数据的取值上),只有在过程赋值语句被执行时才执行赋值操作,语句执行完后被赋值变量的取值不再受到赋值表达式的影响。过程连续赋值语句过程连续赋值语句也是一种过程赋值语句,它用来实现过程连续赋值(用于过程块内对变量或线网型数据进行连续赋值)。其与连续性赋值语句的不同之处: 过程连续赋值语句只能用于过程块内,而连续性赋值语句不能在过程块内。 过程性赋值语句可以对寄存器型变量进行连续赋值(force-release语句组还可以对线网型数据进行赋值),它的赋值目标不能是变量或线网型数据的某一位或几位,而连续性赋值语句只能对线网型数据进行赋值,它的赋值目标可以是线网型数据的几位或一位。过程连续性赋值语

24、句执行的是一种“连续赋值”:一旦对某个变量或线网型数据进行了过程连续性赋值,则它将一直受到过程连续赋值语句内“赋值表达式”的连续驱动,“赋值表达式”内任何操作数的变化都会引起被赋值变量或线网型数据取值的更新,直到对其执行了“撤销过程连续性赋值”操作为止。在Verilog HDL中有两个语组可以实现过程连续赋值:(1) assign-deassignassign和deassign只能用来给寄存器变量连续赋值,而不能用于对线网型数据进行操作。其中“assign”用来实现对寄存器类型的变量连续赋值操作,而“deassign”语句则是一条撤销连续赋值的语句,它用来解除由“assign语句”对寄存器类型

25、变量进行的连续赋值状态 assign语句的用法assign =其中指明了连续赋值操作的目标变量,而则指明了连续赋值的驱动源。一旦assign语句得到执行,寄存器类型变量将由复制表达式进行连续驱动,它将进入被连续赋值的状态。如果此时有普通的过程赋值语句对该寄存器变量进行过程赋值操作,由于过程连续赋值语句assign的优先级高于普通过程赋值语句,所以处于连续赋值状态下的寄存器变量将忽略普通过程赋值语句对它的过程赋值操作,它的逻辑状态任然由过程连续赋值语句内的赋值表达式所决定。如果前后有两条assign语句对同一寄存器变量进行了过程连续赋值,那么第二句的assign语句将覆盖第一条assign语句的

26、执行效果,即寄存器变量最终将进入由第二条assign语句实现的连续赋值状态。“deassign语句”的使用语法为:Deassign ;“deassign语句”是一条撤销连续赋值语句。当它得到执行后,原先由assign语句对该变量进行的连续赋值操作符失效,寄存器变量被连续赋值的状态将得到解除,该变量又可以由普通过程赋值语句进行赋值操作了。当用deassign语句撤销了对某个寄存器变量的连续赋值后,该寄存器变量任将保持deassign语句执行前的原有取值。由于过程连续赋值语句比一般的赋值语句优先级更高,因而常用于实现优先级高于正常时序逻辑功能的异步置位或异步清零。下面举例说明assign和deas

27、sign语句的使用(具有一部清零输入的下降沿D触发器):module dff_asyn_clear(q,d,clr,clk)output q;input d,clr,clk;reg q;always (clr)beginif(!clr)assign q=0;elsedeassign q;endalways (negedge clk)beginq=d;endendmodule(2) force-releasse“force语句”和“release语句”也构成了一组过程连续赋值语句。它不仅能对寄存器型变量赋值也能对线网型数据赋值。“force语句”优先级高于“assign语句”。“force语句”

28、的使用语法:Force = ;其他与assign语句类似。分支语句If-else条件分支语句If-else条件分支语句的作用是根据指定的判断条件是否满足来确定下一步要执行的操作。它在使用时采用如下三种形式:1、 使用形式1If () 语句或语句块;这种使用形式中没有出现else项,其执行过程是: 如果指定的成立(即该表达式的逻辑值为“1”),则执行条件分支语句中给出的“语句或语句块”,然后退出条件分支语句的执行 如果指定的不成立,则不执行条件分支语句中给出的“语句或语句块”,而是直接退出条件分支语句的执行2、 使用形式2If() 语句或语句块1;Else 语句或语句块2;这种使用形式的条件分支

29、语句将以如下方式得到执行: 如果指定的成立,则执行“语句或语句块1”,然后结束条件分支语句的执行; 如果指定的不成立。则执行“语句或语句块2”,然后结束条件支语句的执行;3、 使用形式3If () 语句或语句块1;Else if() 语句或语句块2;Else if() 语句或语句块n-1;Else 语句或语句块n;这种形式的执行方式是当某一个条件表达式成立时便执行对应的语句或语句块,如果没有一个条件表达式成立,则执行语句或语句块n。对于以上三种形式的if-else条件分支语句还需要作以下几点说明: 一般是一个逻辑表达式或关系表达式。如果这个逻辑表达式或关系表达式的逻辑值“1”,则认为该条件表达

30、式成立,否则不成立。 第二种和第三种形式的if-else条件分支语句在形式上是由多行或多条语句构成,但Verilog HDL将它们视为一条if-else条件分支语句来进行处理。 处于分支项内的用于指定该分支项对应操作的语句可以是一条行为语句或多条行为语句。在多条行为语句情况下要用begin和end这两个关键词将这多条语句组合成语句块。 没一个else总是与离它最近的上一个if进行配对。为了明确程序设计者的意图,我们可以用begin-end块语句来明确if与else的配对关系。例如:If (out_enable=1) /外层if语句BeginIf (with_not=1)output=input

31、; /内层if语句EndElse output=input; /外层else语句case分支控制语句case语句的语法格式如下:case():语句或语句块1;:语句或语句块2;:语句或语句块n;default: 语句或语句块n+1;endcase 上述格式中,代表者对程序流向进行控制的控制信号;各则代表的某些具体状态值,在实际使用时,这些分支项表达式通常是一些常量表达式;各个“语句或语句块”则指定了在各个分支下所要执行的操作;处于最后的以关键词”default”开头那个分支项称为默认分支项,它可以默认。case语句的执行过程如下: 当取值等于的值时,执行“语句或语句块1”; 当取值等于的值时,

32、执行“语句或语句块2”; 如果取值与所有都不相等,则执行default分支项的“语句或语句块n+1”; 在执行完任一分支项“语句或语句块”后,跳出case语句结构,终止case语句的执行。case语句中各的取值不能相等,否则出现语法错误。如果的多个不同取值对应同一操作,则可以这样简写:用逗号(,)将这多个隔开,再将在这些情况下需要执行的“语句或语句块”放在这几个分支项表达式的后面。case语句中控制表达式和分支项表达式之间进行的比较是一种按位进行的全等比较,即只有在分支项表达式和控制表达式对应的每一位都彼此相等的情况下才认为这两者是相等的。在进行对应位的比较时,“x”和”z”这两种逻辑状态与“

33、0”、“1”逻辑状态一样作为合法的状态参与比较。casez和casex分支控制语句verilog hdl还提供了另外两种形式的case分支语句,它们是casez语句和casex语句。其基本用法与case一样,只是casez语句执行时的比较过程将不考虑控制表达式及分支项表达式中处于高阻态的那些位的比较,而casex语句则将高阻态“z”和不定态“x”都视为不必关心的情况。循环控制语句forever循环语句forever循环语句实现的是一种无限的循环,其语法格式如下:forever 语句或语句块在上述格式中,关键词forever后面的“语句或语句块”就是被重复执行的循环体。Forever循环语句常用

34、于产生周期性的波形来作为仿真测试信号。如果需要在某个时刻跳出forever循环语句所指定的无限循环,则可以通过在循环体语句块中使用终止语句(disable语句)来实现这一目的。例子(Isim)module clk_generator(clk);output clk;reg clk;integer counter;initialbegincounter=0;clk=0;#20;begin: forever_partforeverbegincounter=counter+1;if(counter10) disable forever_part;#5 clk=clk;endendendendmodu

35、lerepeat循环语句repeat循环语句实现的是一种循环次数预先指定的循环。其语法格式如下:repeat () 语句或语句块;在上述格式中:用于指定循环次数,它可以是一个整型常量、寄存器变量或者一个数值表达式。如果为变量或者数值表达式,其数值只在第一次进入循环时得到计算(从而得以事先确定循环次数)“语句或者语句块”是要被重复执行的循环体部分。Repeat还有一种特别的用法:Repeat(num)(posedge clk)此处循环语句的作用是:等待时钟信号的num次正跳变,该语句之后的语句将在时钟信号的第num次跳变后得到执行。while循环语句while循环语句实现的循环是一种条件循环,即

36、只有在指定的条件表达式取值为”真“时才会重复执行循环体,否则就不执行循环体。其语法格式如下:while () 语句或语句块;for循环语句与while循环语句一样,for循环语句实现的循环也是一种条件循环,只有在指定的条件表达式成立时才进行循环。其语法格式如下:for(;)循环体语句或语句块;在上述格式中:和是两条过程赋值语句,它们分别用来对循环计数变量执行赋初值操作和增值操作。代表循环重复进行时必须满足的条件,它通常是一个逻辑表达式。在每一次执行循环体之前都要对这个条件表达式是否成立进行判断。“循环体语句或语句块“是要被重复执行的部分。for语句的执行过程如下。(1) 执行(2) 判断是否成

37、立:若成立,则执行循环体,然后继续执行下面的第3步;反之,则不再执行循环体,跳出for循环;(3) 执行,然后转到(2)执行任务(task)和函数(function)任务(task)1、 任务的定义任务的语法格式如下:task 端口类型与说明; 局部变量说明; begin ; ; . ; endendtask针对上述格式做以下说明: 关键词task和endtask将它们之间的内容标志成是一个任务定义。在新的标准中允许将输入输出端口列表放在之后。 ”端口类型与说明“用于对任务各个端口的宽度和类型进行说明,其中端口类型由关键词input、output、inout(分别表示输入、输出和双向端口)指定

38、,该说明语句的语法与模块定义时相应说明语句的语法是一致的。 ”局部变量说明“用来对任务内用到的局部变量进行宽度和类型说明,该说明语句的语法与模块定义时相应说明语句语法一致 由begin-end关键词界定的一组行为语句指明了任务被调用时需要进行的操作。在任务被调度时,这些行为语句将按顺序方式得到执行。 任务定义与过程块、连续赋值语句及函数定义这四种成分以并列方式存在于行为描述模块中,它们在层次级别上是相同的。任务定义结构不能出现在任何一个过程块的内部,但可以调用。例:task read_meminput15:0 address; /输入端口说明output31:0 data; /输出端口说明 r

39、eg3:0 counter; /局部变量说明reg7:0 temp1:4; /局部变量说明beginfor(counter=1;counter=4;counter=counter+1)tempcounter=memaddress+counter-1; data=temp1,temp2,temp3,temp4;endendtask 当上例所定义的任务被调用时,begin-end语句块将得到执行,用来完成对存储器”mem“的四次读操作,将其结果合并后输出到端口”data”。在任务定义时必须注意以下四点: 在任务定义结构中的”行为语句“部分可以有延时语句、敏感事件控制语句等时间控制语句出现。 一个任

40、务可以没有输入、输出、双向端口,也可以有一个或多个输入、输出或双向端口。 一个任务可以没有返回值,也可以通过输出端口或双向端口返回一个或多个返回值。 在一个任务中可以调用其他的任务和函数,也可以调用该任务本身 在任务定义结构内不允许出现过程块 在任务定义结构体中可以出现”disable“终止语句,中断正在执行的任务2、 任务的调用调用格式如下: (端口1,端口2,端口n);其中,(端口1,端口2,端口n)组成了一个端口名列表。任务调用时要注意以下几点: 任务调用语句只能出现在过程块中 任务调用语句就像一条普通的行为语句那样得到处理。 当被调用的任务具有输入或输出端口时,任务调用语句必须包含端口

41、列表,该列表内各个端口名出现的顺序必须与任务定义结构中端口说明部分的端口顺序和类型相一致,注意,只有寄存器类型的变量才能与任务的输出端口相对应。任务的调用具有以下特点: 在任务内定义的局部变量都具有局部和静态的特点。即如果同时对同一任务进行两次调用,则两个调用进程使用的将是相同物理地址处的同一局部变量。在此情况下要防止内存使用冲突。 在一个任务中可以直接访问上一级调用模块的任何寄存器。 由于任务内部可以包含时间控制语句,所以调用一个任务所需要的时间可以是非零时间单位,即任务的启动时刻可以是不同于任务结束时刻的。 可以通过一个disable语句来中断任务的执行。任务被中断后,程序流程将返回到调用

42、任务的地方继续往下执行。函数(function)1、 函数的定义函数定义的语法格式如下:function begin . endendfunction针对上述格式做如下说明: 关键词“function”和“endfunction”表示这部分语句是一个函数定义结构。“function”标志着这个函数定义结构的开始,“endfunction”标志着函数定义结构的结束。 是为被定义函数所取的名字,对被定义函数的调用是通过该函数名进行的。该函数名在函数定义结构内部还代表着一个内部变量,函数调用后的返回值是通过该函数名传递给调用语句的。新的规定中允许在函数名后出现端口列表。 是可选项,它用来对函数调用返回数据的类型或宽度进行说明(这个数据是通过函数名返回的),它可以有如下三种形式: msb:lsb:这种形式说明函数名所代表的返回数据变量时一个多位的寄存器变量,它的位数由msb:lsb指定, Integer这种形式说明函数名所代表的数据变量是一个整型变量 Real:这种形式说明函数名所代表的返回数据变量是一个浮点型变量 如果默认返回值或返回值

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 科普知识


经营许可证编号:宁ICP备18001539号-1