赞
踩
在C语言中,有经验的软件工程师一定会为经常使用的一段代码写一个子程序,然后通过不同的参数对其进行调用。这样做可以达到代码复用的效果,减少了不必要的重复劳动,也使得代码相对简捷一些。在Testbench中也可以使用task进行代码的封装,它能够和C语言的子函数一样被灵活调用。
下面的例子给出一段很实用的封装子程序,也许在每个工程的测试脚本中都可以排上用场。
// 封装一些做测试时有用的报告显示 //包括任务error, warning, fatal, terminate module print_task(); //显示warning报告,同时包含显示当前时间和警告内容(由用户输入) task warning; input [80*8:1] msg; begin $write("WARNING at %t: %s", $time,msg); end endtask //显示error 报告,同时包含显示当前时间和错误内容(由用户输入) task error; input [80*8:1] msg; begin $write("-ERROR- at %t: %s", $time, msg); end endtask //显示fatal报告,同时包含显示当前时间和致命内容(由用户输入) task fatal; input [80*8:1] msg; begin $write(" *FATAL* at %t: %s", $time, msg); terminate; end endtask //显示warning 报告,同时包含显示当前时间和结束信息(该任务生成) task terminate; begin $write("Simulation completed\n"); $ finish; end endtask endmodule
在使用封装子程序时,如下代码所示:
//使用print_task.v,后面就可以调用其封装好的task了
print_task print();
...
initial begin
if (...) print.error("Unexpected response\n"); //调用error任务
...
print.terminate; //调用terminate任务
end
...
endmodule
在编写Testbench时,关于变量的定义常犯的错误就是将一个定义好的全局变量应用到了两个不同的always块中(如EX1C),那么由于这两个always块独立并行的工作机制,很可能会导致意想不到的后果。
EX1C:
interger i;
always begin
for(i=0; i<32; i=i+1) begin
end
end
always begin
for(i=0; i<32;i=i+1) begin
...
end
end
实际上,在Verilog中(编写Testbench时),如果在begin…end 之间定义了always的块名,那么可以如EX1C一样申明变量。这样两个always块里的变量i就互不相关,也就不会产生不可预料的结果了。
EX2C:
always begin
integer i;
for(i=0; i<32; i=i+1) begin
...
end
end
always
begin: block_2
integer i;
for(i=0; i<32;i=i+1) begin
...
end
end
除此以外,在Verilog中的function和task也支持类似上面的局部变量定义。
为什么C不能取代Verilog和VHDL作为硬件描述语言?因为C缺少了硬件描述最基本的3个思想:连通性(connectivity)、时间性(Time)和并行性(Concurrency)。
连通性是使用一个简单并相互连接的模块来描述设计的能力,原理图设计工具就是连通性完美的支持工具。
时间性是表现设计状态演进的时间变化的能力,这个能力不同于衡量一个代码执行所用的时间。
并行性是描述同时发生相互独立的行为的能力。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。