欢迎来到EDA中国!
当前位置:网站首页 >资源共享 > FPGA

verilog HDL语言教程第十章--其他论题

  • 415k
  • pdf
  •  
  •  
  • 下载
  • 2013-04-26
  • 软件简介
10.1 任务
一个任务就像一个过程,它可以从描述的不同位置执行共同的代码段。共同的代码段用
任务定义编写成任务,这样它就能够从设计描述的不同位置通过任务调用被调用。任务可以
包含时序控制,即时延控制,并且任务也能调用其它任务和函数。
10.1.1 任务定义
任务定义的形式如下:
t a s k t a s k i d;
[d e c l a r a t i o n s]
p r o c e d u r a l s t a t e m e n t
e n d t a s k
任务可以没有或有一个或多个参数。值通过参数传入和传出任务。除输入参数外(参数
从任务中接收值),任务还能带有输出参数(从任务中返回值)和输入输出参数。任务的定义
在模块说明部分中编写。例如:
m o d u l e H a s T a s k;
p a r a m e t e r MAXBITS = 8;
t a s k R e v e r s e B i t s;
i n p u t [MAXBITS -1:0] D i n;
o u t p u t [MAXBITS -1:0] D o u t;
i n t e g e r K;
b e g i n
f o r (K = 0; K < M A X B I T S; K = K + 1)
D o u t [M A X B I T S-K] = D i n[K] ;
e n d
e n d t a s k
. . .
e n d m o d u l e
任务的输入和输出在任务开始处声明。这些输入和输出的顺序决定了它们在任务调用中
的顺序。下面是另一个例子:
t a s k R o t a t e L e f t;
i n o u t [1:16] I n A r r;
i n p u t [0:3] S t a r t B i t,S t o p B i t,R o t a t e B y;
r e g F i l l V a l u e;
i n t e g e r M a c 1,M a c 3;
b e g i n
f o r (M a c 3 = 1; Mac3 <= R o t a t e B y; M a c 3 = M a c 3 + 1)
b e g i n
F i l l V a l u e = I n A r r[S t o p B i t] ;
f o r (M a c 1 = S t o p B i t; M a c 1 >= S t a r t B i t + 1;
M a c 1 = M a c 1 - 1 )
I n A r r[M a c 1] = I n A r r [M a c 1 - 1];
I n A r r[S t a r t B i t] = F i l l V a l u e;
e n d
e n d
e n d t a s k
F i l l Va l u e是任务的局部寄存器,只能在任务中直接可见。任务的第1个参数是输入输出数
组I n A rr,随后是3个输入,S t a rt B i t、S t o p B i t和R o t a t e B y。
除任务参数外,任务还能够引用说明任务的模块中定义的任何变量。在下一节将举例说
明这种情况。
10.1.2 任务调用
一个任务由任务调用语句调用。任务调用语句给出传入任务的参数值和接收结果的变量
值。任务调用语句是过程性语句,可以在always 语句或initial 语句中使用。形式如下:
t a s k i d [ (e x p r 1 , e x p r 2 , . . . , e x p r N) ] ;
任务调用语句中参数列表必须与任务定义中的输入、输出和输入输出参数说明的顺序匹
配。此外,参数要按值传递,不能按地址传递。在其它高级编程语言中,例如P a s c a l,任务与
过程的一个重要区别是任务能够被并发地调用多次,并且每次调用能带有自己的控制,最重
要的一点是在任务中声明的变量是静态的,即它决不会消失或重新被初始化。因此一个任务
调用能够修改被其他任务调用读取的局部变量的值。
下面是调用任务R e v e r s e B i t s的实例,该任务定义已在前面章节中给出,
/ /寄存器说明部分:
r e g [M A X B I T S-1:0] R e g X , N e w R e g;
R e v e r s e B i t s(R e g X , N e w R e g); //任务调用。
R e g X的值作为输入值传递,即传递给D i n。任务的输出D o u t返回到N e w R e g。注意因为
任务能够包含定时控制,任务可在被调用后再经过一定时延才返回值。
因为任务调用语句是过程性语句,所以任务调用中的输出和输入输出参数必须是寄存器
类型的。在上面的例子中, N e w R e g必须被声明为寄存器类型。
下面的例子不通过参数表向任务调用传入变量。尽管引用全局变量被认为是不良的编程
风格,它有时却非常有用。
m o d u l e G l o b a l V a r;
reg [0:7] R a m Q [ 0 : 6 3 ] ;
i n t e g e r I n d e x;
r e g C h e c k B i t;
t a s k G e t P a r i t y;
i n p u t A d d r e s s;
o u t p u t P a r i t y B i t;
92 Verilog HDL 硬件描述语言
下载
P a r i t y B i t = ^R a m Q[A d d r e s s] ;
e n d t a s k
i n i t i a l
f o r (I n d e x = 0; I n d e x <= 63; I n d e x = I n d e x+ 1 )b e g i n
G e t P a r i t y(I n d e x , C h e c k B i t) ;
$d i s p l a y("Parity bit of memory word %d is %b.",
Index, CheckBit) ;
e n d
e n d m o d u l e
存储器R a m Q的地址被作为参数传递,而存储器本身在任务内直接引用。
任务可以带有时序控制,或等待特定事件的发生。但是,输出参数的值直到任务退出时
才传递给调用参数。例如:
m o d u l e T a s k W a i t;
r e g N o C l o c k;
t a s k G e n e r a t e W a v e f o r m;
o u t p u t C l o c k Q;
b e g i n
C l o c k Q = 1;
#2 C l o c k Q = 0;
#2 C l o c k Q = 1;
#2 C l o c k Q = 0;
e n d
e n d t a s k
i n i t i a l
G e n a r a t e W a v e f o r m (N o C l o c k) ;
e n d m o d u l e
任务G e n e r a t e Wa v e f o r m对C l o c k Q的赋值不出现在N o C l o c k上,即没有波形出现在N o C l o c k
上;只有对C l o c k Q的最终赋值0在任务返回后出现在N o C l o c k上。为避免这一情形出现,最好
将C l o c k Q声明为全局寄存器类型,即在任务之外声明它。
10.2 函数
函数,如同任务一样,也可以在模块不同位置执行共同代码。函数与任务的不同之处是
函数只能返回一个值,它不能包含任何时延或时序控制(必须立即执行),并且它不能调用其
它的任务。此外,函数必须带有至少一个输入,在函数中允许没有输出或输入输出说明。函
数可以调用其它的函数。
10.2.1 函数说明部分
函数说明部分可以在模块说明中的任何位置出现,函数的输入是由输入说明指定,形式
如下:
f u n c t i o n [r a n g e] f u n c t i o n i d;
i n p u t d e c l a r a t i o n
o t h e r d e c l a r a t i o n s
p r o c e d u r a l s t a t e m e n t
e n d f u n c t i o n
第10章其他论题93
下载
如果函数说明部分中没有指定函数取值范围,则其缺省的函数值为1位二进制数。函数实
例如下:
m o d u l e F u n c t i o n E x a m p l e
p a r a m e t e r MAXBITS = 8;
f u n c t i o n [M A X B I T S-1:0] R e v e r s e B i t s;
i n p u t [M A X B I T S-1:0] D i n;
i n t e g e r K;
b e g i n
f o r (K=0; K < M A X B I T S; K = K + 1)
R e v e r s e B i t s [M A X B I T S-K] = D i n [K] ;
e n d
e n d f u n c t i o n
. . .
e n d m o d u l e
函数名为R e v e r s e _ B i t s。函数返回一个长度为M A X B I T S的向量。函数有一个输入D i n.K,
是局部整型变量。
函数定义在函数内部隐式地声明一个寄存器变量,该寄存器变量与函数同名并且取值范
围相同。函数通过在函数定义中显式地对该寄存器赋值来返回函数值。对这一寄存器的赋值
必须出现在函数定义中。下面是另一个函数的实例。
f u n c t i o n P a r i t y;
i n p u t [0:31] S e t;
r e g [0:3] R e t;
integer J;
b e g i n
R e t = 0;
f o r (J = 0;J <= 31; J = J + 1)
if (S e t[J] = = 1 )
R e t = R e t + 1;
P a r i t y = R e t % 2;
e n d
e n d f u n c t i o n
在该函数中, P a r i t y是函数的名称。因为没有指定长度,函数返回1位二进制数。R e t和J
是局部寄存器变量。注意最后一个过程性赋值语句赋值给寄存器,该寄存器从函数返回值
(与函数同名的寄存器在函数中被隐式地声明)。
10.2.2 函数调用
函数调用是表达式的一部分。形式如下:
f u n c i d(e x p r 1 , e x p r 2 , . . . , e x p r N)
以下是函数调用的例子:
r e g [M A X B I T S-1:0] N e w R e g , R e g X; //寄存器说明。
N e w R e g = R e v e r s e B i t s(R e g X); //函数调用在右侧表达式内。
与任务相似,函数定义中声明的所有局部寄存器都是静态的,即函数中的局部寄存器在
94 Verilog HDL 硬件描述语言
下载
函数的多个调用之间保持它们的值。
10.3 系统任务和系统函数
Verilog HDL提供了内置的系统任务和系统函数,即在语言中预定义的任务和函数。它们
分为以下几类:
1) 显示任务( display task)
2) 文件输入/输出任务(File I/O task)
3) 时间标度任务(timescale task)
4) 模拟控制任务(simulation control task)
5) 时序验证任务(timing check task)
6) PLA建模任务(PLA modeling task)
7) 随机建模任务(stochastic modeling task)
8) 实数变换函数(conversion functions for real)
9) 概率分布函数(probabilistic distribution function)
P L A建模任务和随机建模任务不在本书的讨论范围内。
10.3.1 显示任务
显示系统任务用于信息显示和输出。这些系统任务进一步分为:
• 显示和写入任务
• 探测监控任务
• 连续监控任务
1. 显示和写入任务
语法如下:
t a s k n a m e (f o r m a t s p e c i f i c a t i o n 1 , a r g u m e n t l i s t 1 ,
f o r m a t s p e c i f i c a t i o n 2 , a r g u m e n t l i s t 2 ,
. . . ,
f o r m a t s p e c i f i c a t i o n N , a r g u m e n t l i s t N) ;
t a s k n a m e是如下编译指令的一种:
$display $displayb $displayh $d i s p l a y o
$write $writeb $writeh $w r i t e o
显示任务将特定信息输出到标准输出设备,并且带有行结束字符;而写入任务输出特定
信息时不带有行结束符。下列代码序列能够用于格式定义:
%h 或%H : 十六进制
%d 或%D : 十进制
%o 或%O : 八进制
%b 或%B : 二进制
%c 或%C : ASCII字符
%v 或%V : 线网信号长度
%m 或%M : 层次名
%s 或%S : 字符串
%t 或%T : 当前时间格式
如果没有特定的参数格式说明,缺省值如下:
第10章其他论题95
下载
关键字 : HDL Verilog 语言 
获取帮助