Verilog 语法知识3

Verilog 语法知识3

11.结构体说明语句,Verilog语言中的任何过程模块都从属于以下四种结构的说明语句。

  1. initial说明语句
  2. always说明语句
  3. task说明语句
  4. function说明语句

注意:initial和always说明语句在仿真的一开始即开始执行。initial语句只执行一次。相反,always语句则是不断地重复执行,直到仿真过程结束。在一个模块中,使用initial和always语句的次数是不受限制的。task和function语句可以在程序模块中的一处或多处调用。

  • initial语句

如:

initial
	begin
		inputs = 'b000000; //初始时刻为0
		#10 inputs = 'b011001;
		#10 inputs = 'b011011;
		#10 inputs = 'b011000;
		#10 inputs = 'b001000;
end

从这个例子中,我们可以看到initial语句的另一用途,即用initial语句来生成激励波形作为电路的测试仿真信号。一个模块中可以有多个initial块,它们都是并行运行的。initial块常用于测试文件和虚拟模块的编写,用来产生仿真测试信号和设置信号记录等仿真环境。

  • always语句;格式 always <时序控制> <语句>
    always语句由于其不断重复执行的特性,只有和一定的时序控制结合在一起才有用。如果一个always语句没有时序控制,则这个always语句将会发成一个仿真死锁。

如:

reg[7:0] counter;
reg tick;
always @(posedge areg)
	begin
		tick = ~tick;
		counter = counter + 1;
	end

每当areg信号的上升沿出现时把tick信号反相,并且把counter增加1。这种时间控制是always语句最常用的,always 的时间控制可以是沿触发也可以是电平触发的,可以单个信号也可以多个信号,中间需要用关键字 or 连接
沿触发的always块常常描述时序逻辑,一个模块中可以有多个always块,它们都是并行运行的。

  • task和function说明语句,task和function说明语句分别用来定义任务和函数。利用任务和函数可以把一个很大的程序模块分解成许多较小的任务和函数便于理解和调试。输入、输出和总线信号的值可以传入、传出任务和函数。任务和函数往往还是大的程序模块中在不同地点多次用到的相同的程序段。学会使用task和function语句可以简化程序的结构,使程序明白易懂,是编写较大型模块的基本功。

注意:任务和函数有些不同,主要的不同有以下四点:

  1. 函数只能与主模块共用同一个仿真时间单位,而任务可以定义自己的仿真时间单位。
  2. 函数不能启动任务,而任务能启动其它任务和函数。
  3. 函数至少要有一个输入变量,而任务可以没有或有多个任何类型的变量。
  4. 函数返回一个值,而任务则不返回值。

函数的目的是通过返回一个值来响应输入信号的值。任务却能支持多种目的,能计算多个结果值,这些结果值只能通过被调用的任务的输出或总线端口送出。Verilog HDL模块使用函数时是把它当作表达式中的操作符,这个操作的结果值就是这个函数的返回值。

如:

task my_task;//任务名
input a, b;
inout c;
output d, e;<语句> //执行任务工作相应的语句
…
c = foo1; //赋初始值
d = foo2; //对任务的输出变量赋值t
e = foo3;
endtask

任务调用:my_task(v,w,x,y,z);任务调用变量(v,w,x,y,z)和任务定义的I/O变量(a,b,c,d,e)之间是一一对应的。

module traffic_lights;
reg clock, red, amber, green;
parameter on=1, off=0, red_tics=350,
amber_tics=30,green_tics=200;
//交通灯初始化
	initial red=off;
	initial amber=off;
	initial green=off;
//交通灯控制时序
 always
	begin
		red=on; //开红灯
		light(red,red_tics); //调用等待任务
		green=on; //开绿灯
		light(green,green_tics); //等待
		amber=on; //开黄灯
		light(amber,amber_tics); //等待
	end
//定义交通灯开启时间的任务
 task light(color,tics);
	output color;
	input[31:0] tics;
 begin
	repeat(tics) @(posedge clock);//等待tics个时钟的上升沿
	color=off;//关灯
 end
endtask
//产生时钟脉冲的always块
always
 begin
	#100 clock=0;
	#100 clock=1;
 end
endmodule

这个例子描述了一个简单的交通灯的时序控制,并且该交通灯有它自己的时钟产生器。

而 function说明语句,即函数的目的是返回一个用于表达式的值。

  1. 函数的定义不能包含有任何的时间控制语句,即任何用#、@、或wait来标识的语句。
  2. 函数不能启动任务。
  3. 定义函数时至少要有一个输入参量。
  4. 在函数的定义中必须有一条赋值语句给函数中的一个内部变量赋以函数的结果值,该内部变量具有和函数名相同的名字。

如:

module tryfact;
//函数的定义-------------------------------
	function[31:0]factorial;//前面可以说明位数
		input[3:0]operand;
		reg[3:0]index;
		begin
			factorial = operand? 1 : 0;
			for(index=2;index<=operand;index=index+1)
			factorial = index * factorial;
		end
	endfunction
//函数的测试-------------------------------------
reg[31:0]result;
reg[3:0]n;
initial
begin
	result=1;
	for(n=2;n<=9;n=n+1)
	begin
		$display("Partial result n= %d result= %d", n, result);
		result = n * factorial(n)/((n*2)+1);
	end
	$display("Finalresult=%d",result);
end
endmodule//模块结束

该例子中定义了一个可进行阶乘运算的名为factorial的函数,该函数返回一个32位的寄存器类型的值,该函数可后向调用自身,并且打印出部分结果值。

12.系统函数和任务,Verilog HDL语言中自带的,和C语言里面好多函数也是一样的。像$bitstoreal, $rtoi, $display, $setup, $finish, $skew, $hold,
$setuphold, $itor, $strobe, $period, $time, $printtimescale, $timefoemat, $realtime, $width, $real tobits, $write, $recovery,在Verilog HDL语言中每个系统函数和任务前面都用一个标识符 $ 来加以确认。这些系统函数和任务提供了非常强大的功能。有兴趣的同学可以参阅附录:Verilog语言参考手册。

13.编译预处理,Verilog HDL语言和C语言一样也提供了编译预处理的功能。“编译预处理”是Verilog HDL编译系统的一个组成部分。Verilog HDL语言允许在程序中使用几种特殊的命令(它们不是一般的语句)。Verilog HDL编译系统通常先对这些特殊的命令进行“预处理”,然后将预处理的结果和源程序一起在进行通常的编译处理,请查阅参考书。在Verilog HDL语言中,为了和一般的语句相区别,这些预处理命令以符号“ `”开头(注意这个符号是不同于单引号“ '”的)。

如:define signal string(前面的“ `”不好打出来)

它的作用是指定用标识符signal来代替string这个字符串,在编译预处理时,把程序中在该命令以后所有的signal都替换成string。这种方法使用户能以一个简单的名字代替一个长的字符串,也可以用一个有含义的名字来代替没有含义的数字和符号,因此把这个标识符(名字)称为“宏名”,在编译预处理时将宏名替换成字符串的过程称为“宏展开”。`define是宏定义命令。

14.条件编译命令 :一般情况下,Verilog HDL源程序中所有的行都将参加编译。但是有时希望对其中的一部分内容只有在满足条件才进行编译,也就是对一部分内容指定编译的条件,这就是“条件编译”。有时,希望当满足条件时对一组语句进行编译,而当条件不满足是则编译另一部分。和C语言里面if _endif是一样的。

小结:
Verilog HDL的语法与C语言的语法有许多类似的地方,但也有许多不同的地方。我们学习Verilog HDL
语法要善于找到不同点,着重理解如:阻塞〔Blocking〕和非阻塞〔Non-Blocking〕赋值的不同;
顺序块和并行块的不同;块与块之间的并行执行的概念;task和function的概念。Verilog HDL还有
许多系统函数和任务也是C语言中没有的如: $ monitor、$ readmemb、$stop等等,而这些系统任务在
调试模块的设计中是非常有用的,我们只有通过阅读大量的Verilog调试模块实例,经过长期的实践,
经常查阅附录中的Verilog语言参考手册才能逐步掌握。

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值