SV学习笔记(七)-任务和函数

任务和函数

概述

  • 类似于C语言,函数(function)和任务(task)可以提高代码的复用性和整洁度

  • 目的都是在于将大型的过程块切分成更小的片段,而便于阅读和代码维护

  • 函数和任务的区别

    • function不会消耗仿真时间,task可能会消耗仿真时间
    • function无法(不建议)调用task,task可以调用function
    • 一个可以返回数据的function只能返回一个单一数值,而task或者void function不会返回数值
    • 一个可以返回数据的function可以作为一个表达式中的操作数,而该操作数的值即function的返回值

function

  • 函数的主要目的在于为表达式提供返回值,这样既便于简化原有的代码,也便于大型代码的维护

  • void函数不会返回数值

  • 函数的参数列表方向可以声明为:input、output、inout、ref

    • input:输入
    • output:输出
    • inout:输入输出双向
    • ref:是对变量的应用,它的值是该变量最后一次赋的值
  • 函数声明格式:

    // 方式一:logic[15:0]是返回值,logic可以不写,默认logic类型
    //        int x,int y,没有说是input还是output,默认input
    function logic[15:0] mydunc1(int x, int y);
        ...
    endfunction
    
    // 方式二:
    function logic[15:0] myfunc2;
        input int x;
        input int y;
        ...
    endfunction
    
  • 函数调用

    • 顺序传参

      // 函数
      function myfunc(input [15:0] x, input [15:0] y, input [15:0]);
          $display("x=%0d,y=%0d,z=%0d", x, y, z);
      endfunction
      // 顺序传参调用函数,按照参数顺序传入
      myfunc(10, 11, 12);
      
    • 关键字传参

      // 函数
      function myfunc(input [15:0] x, input [15:0] y, input [15:0]);
          $display("x=%0d,y=%0d,z=%0d", x, y, z);
      endfunction
      // 关键字传参调用函数
      myfunc(.z(10), .y(11), .x(12));
      
    • 参数默认值

      // 函数
      function myfunc(input [15:0] x = 10, input [15:0] y, input [15:0] z = 20);
          $display("x=%0d,y=%0d,z=%0d", x, y, z);
      endfunction
      
      // 函数调用
      myfunc(, 5, );  // 方式一,按顺序传入,使用参数默认值的,保持为空
      myfunc(, 5);	// 方式二,按顺序传入,使用参数默认值的,保持为空,后面全为默认值时,可以省略
      myfunc(.y(5));	// 方式三,关键字传参,可以只传没有默认值的参数
      
  • 返回值

    • 使用return返回

      function [15:0] myfunc1(input[7:0] x, y);
      	return = x * y -1;
      endfunction
      
    • 将值赋给和函数同名的变量

      function [15:0] myfunc2(input[7:0] x,y);
          myfunc2 = x * y - 1;
      endfunction
      
    • 两种返回值区别:

      • return会直接返回,并终止后续代码的执行
      • 赋值给函数名同名变量后将继续执行后续代码
      • 如果函数有返回值,但是又不适用该返回值时,建议使用void'(some_function())进行转换,虽然直接使用不加void'()也没关系,但是编译的时候会报有数值没处理

task

  • 任务的定义可以指定参数,input,output,inout,ref

  • 任务可以消耗仿真时间

  • 任务可以调用其它任务或者函数

  • task没有返回值,也不需要void(函数中void表明函数没有返回值)

  • 任务的定义:

    task mytask1(input [7:0] x,
                 input [7:0] y,
                 output [15:0] z);
        #5ns;  // task中可以进行延时,
        z = x * y - 1;
        #5ns;
    endtask
    
  • 示例1:

    `timescale 1ns/1ps
    module testbench_top();
    	task mytask(input [7:0] x,
    				input [7:0] y,
    				output [15:0] z);
    		#5ns;
    		z = x * y;
    		#5ns;
    	endtask
    	
    	int a = 3;
    	int b = 4;
    	int c;
    	
    	initial begin
    
    		mytask(a, b, c);
    	end
    	
    	initial begin
    		repeat(12) begin
    			#1ns;
    			$display("time = %0t,c = %0d", $time, c);
    		end
    	end
    
    endmodule
    

    执行结果:

    # time = 1000,c = 0
    # time = 2000,c = 0
    # time = 3000,c = 0
    # time = 4000,c = 0
    # time = 5000,c = 0
    # time = 6000,c = 0
    # time = 7000,c = 0
    # time = 8000,c = 0
    # time = 9000,c = 0
    # time = 10000,c = 12
    # time = 11000,c = 12
    # time = 12000,c = 12
    

    虽然任务中5ns后计算z=x*y,z得到值15,但是因为task还没有执行完,z的值变化还在task的内部,所以后面再过5ns后,c的值才变为12

  • 示例2:

    `timescale 1ns/1ps
    module testbench_top();
    	task automatic mytask(input [7:0] x,
    				input [7:0] y,
    				ref [15:0] z);
    		#5ns;
    		z = x * y;
    		#5ns;
    	endtask
    	
    	logic[7:0] a = 8'd3;
    	logic[7:0] b = 8'd4;
    	logic[15:0] c;
    	
    	initial begin
    
    		mytask(a, b, c);
    	end
    	
    	initial begin
    		repeat(12) begin
    			#1ns;
    			$display("time = %0t,c = %0d", $time, c);
    		end
    	end
    
    endmodule
    

    执行结果:

    # time = 1000,c = x
    # time = 2000,c = x
    # time = 3000,c = x
    # time = 4000,c = x
    # time = 5000,c = 12
    # time = 6000,c = 12
    # time = 7000,c = 12
    # time = 8000,c = 12
    # time = 9000,c = 12
    # time = 10000,c = 12
    # time = 11000,c = 12
    # time = 12000,c = 12
    

    ref是会即时返回的,所以5ns后,c的值就拿到了是12

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值