• systemverilog学习 ---- 任务和函数


    task

    一个任务可以包括参数定义、输出参数、输出参数、输入输出参数、寄存器、事件和若干条行为语句。任务可以分类为自动任务(automatic task)和静态任务(static task)。两者的区别在于存储的不同,静态任务调用时共享存储空间,自动任务则为每次任务调用分配单独的栈存储。
    systemverilog允许:

    1. 在静态任务中声明一个动态的变量
    2. 在动态任务中声明一个静态的变量
    3. 多种方法声明任务端口
    4. 在task中的多条语句不需要begin … end or fork … join语句块
    5. 可以任务中间进行返回
    6. 可以通过reference,values,names,position进行数值传递
    7. 支持默认参数
    8. 如果不指定参数的输入方向,则默认为输入
    9. 默认的变量类型是Logic

    task 例子

    module sv_task;
    
    int     x   ;
    
    //task to add two integer numbers
    task sum(input int a, b, output int c);
        c = a + b;
    endtask
    
    initial begin
        sum(10, 5, x);
        $display("\t Value of x = %0d", x);
    end
    
    endmodule
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    其输出结果为:
    在这里插入图片描述

    function

    函数可以包括范围声明,返回值类型,参数,输入参数,寄存器和事件。函数若没有位宽和返回值类型,返回1bit值。任何表达式都可以作为函数的参数,函数不可以拥有任何的事件控制语句。函数不能调用task,并且函数只可以返回一个值。
    函数也分为两类,静态函数和动态函数。前者所有的调用共享相同的存储空间,后者对于每次函数调用,都会分配相应的堆栈空间。

    function 例子

    module sv_function;
    
    int     x   ;
    //function to add two integer numbers
    function int sum(input int a, b);
    
        sum = a + b;
    
    endfunction
    
    initial begin
        x = sum(10, 5);
        $display("\t Value of x = %0d", x);
    end
    
    endmodule
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    其输出结果是:
    在这里插入图片描述
    下面举一个没有返回值的例子:

    module sv_function;
    
    int     x       ;
    //void function to display current simulation time
    function void current_time;
        $display("\t Current simulation time is %0d", $time);
    endfunction
    
    initial begin
        #10;
        current_time();
        #20;
        current_time();
    end
    
    endmodule
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    其输出结果是:
    在这里插入图片描述

    task 和 function的参数传递

    对于任务和函数,有四种传递参数的方式:

    1. 通过值传递
    2. 通过引用传递
    3. 通过名字传递
    4. 通过位置传递
      通过值传递,通过拷贝每个参数到子函数领域,如果在子函数领域这些参数有变化的化,并不会影响子函数领域外面的参数的值。
      下面举一个例子:
    module  argument_passing;
    
    int     x       ;
    int     y       ;
    int     z       ;
    
    //function to add two integers numbers
    function int sum(int x, y);
        x = x + y;
        return x+y;
    endfunction
    
    initial begin
        x = 20 ;
        y = 30 ;
        z = sum(x,y);
        $display("-------------------------------------------------");
        $display("\t Value of x = %0d", x);
        $display("\t Value of y = %0d", y);
        $display("\t Value of z = %0d", z);
        $display("-------------------------------------------------");
    end
    
    endmodule
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    其输出结果是:
    在这里插入图片描述
    由此可见在函数内部修改参数的值并不会影响外面。

    通过引用传递,可以修改传入函数内部的变量,需要在参数声明上添加reg。但是如果不希望修改,则可以在前面添加const。

    module  argument_passing;
    
    int     x       ;
    int     y       ;
    int     z       ;
    
    //function to add two integers numbers
    function automatic int sum(ref int x, y);
        x = x + y;
        return x+y;
    endfunction
    
    initial begin
        x = 20 ;
        y = 30 ;
        z = sum(x,y);
        $display("-------------------------------------------------");
        $display("\t Value of x = %0d", x);
        $display("\t Value of y = %0d", y);
        $display("\t Value of z = %0d", z);
        $display("-------------------------------------------------");
    end
    
    endmodule
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    其输出结果是:
    在这里插入图片描述
    可以看出x的值被更改,如果不想修改,可以在ref前面添加修饰const,如果尝试修改,则编译器会给出如下的报错:

    在这里插入图片描述
    按照名字传递,和verilogd的模板例化一样。
    在这里插入图片描述
    其输出结果就是:

    Value of x = 2016, y = Hello World
    
    • 1
  • 相关阅读:
    python操作excel中xlrd模块的一些简单方法
    SUSE Linux文件系统在线扩容
    职场人,该看重机遇,还是该注重自己的能力?
    联合概率和条件概率的区别和联系
    SOA:整车架构下一代的升级方向
    Gut代谢组学文献分享:小小肠道菌群决定肾的“生死”
    python基础-3(文件操作)
    springcloud05——Zookeeper实现支付微服务
    java中对象的比较
    gpt批量工具,gpt批量生成文章工具
  • 原文地址:https://blog.csdn.net/weixin_45614076/article/details/126249658