systemverilog中的参数传递——ref、input、output

news/2024/5/19 18:14:13 标签: systemverilog

systemverilog中的参数传递——ref、input、output

  • 1 静态数组作为参数
    • 1.1 input
    • 1.2 output
    • 1.3 ref
  • 2 动态数组或队列作为参数
  • 3 类作为参数
  • 4 原文链接

1 静态数组作为参数

sv中的静态数组、动态数组、队列都是用一块内存存放,而他们的名字作为该内存的地址,这点和c一致,但sv中没有指针的概念。

传递这种大片内存的值一般只有两种规则:
1.地址传递,函数内部修改可以改变函数调用的值。
2.值传递,将整片空间复制一份,函数内部修改不会改变函数调用的值。

但是,sv中里面关键字有三个:input、output、ref。具体哪个对应哪个,下面来看一下,以静态数组作为模板来试。

function void run();
  int r[2];
  r[0]=1;
  r[1]=2;
  f(r);
  $display("%0x %0x",r[0],r[1]);
 endfunction

1.1 input

当函数类型为input时。

function void f(input int a[2]);
  a[0]=3;
 endfunction

输出结果:1 2

具体过程如下:
1.函数调用之前,内存里只有r数组的空间
2.函数调用之后,会将r拷贝一份到a, 函数里面用的都是a这份空间
3.函数调用之后,复制后,修改的是a这份空间
4.函数返回之后,a空间会被释放掉,所以r的值并没有被修改

因此,input是标准的值传递。

1.2 output

当函数类型为output时。

function void f(output int a[2]);
  a[0]=3;
 endfunction

输出结果是:3 0

具体过程如下:
1.函数调用之前,内存里只有r数组的空间
2.函数调用 之后,会新建一份a数组,注意这里并不会把r的值传进来,函数里面用的是a这份空间
3.函数调用之后,赋值后,修改的是a这份空间
4.函数返回之后,会将r指向a空间,而原来的r指向的空间会被释放掉,所以r的值都被修改了

因此,output 采用的是地址传递,确切的说是反向地址传递,数组共有两份,函数内部看到的是新建的一份,并传递给函数调用的处。所以函数调用前是第一份,函数调用后看到的是新建的那份。

1.3 ref

当函数是ref时。

function void f(ref int a[2]);
  a[0]=3;
 endfunction

输出结果是: 3 2

具体过程如下:
1.函数调用前,内存里只有r数组的空间
2.函数调用之后,会将a指向r所在的空间,函数里面用的都是这份空间
3.函数调用之后,赋值后,修改的是这份空间的值,所以a和r的值都被修改啦
4.函数返回后,所以r的值只有部分被修改
因此,ref采用的是标准的地址传递,只有一份数组,函数内部和调用出都是访问该空间。

对比来看,input是将函数外面的值传递到函数里面,调用之后,函数里面的值就被丢弃了;output是将函数里面的值传递到函数外面来,调用之后,函数外面的值就被丢弃了;ref是函数内部和外部看到的是同一份值,哪里都会被修改。另外,可以看出,采用ref关键字,占用 的空间内存是最小的,因为只有一份数组,这样能提高效率。

2 动态数组或队列作为参数

如果传递的是动态数组或队列,其结果是一模一样的,不另外作说明。

3 类作为参数

下面展示一些 内联代码片

class c;
 int v0;
 int v1;
 endclass
function void run();
 c c0;
 c0 = new();
 c0.v0 = 1;
 c0.v1 = 2;
 f(c0)
 $display(" %0x %0x ", c0.v0 ,c0.v1);
 endfunction
 
 function voidf(input /output ref c c0);
  c0.v0 =3;
 endfunction

输出结果是:
1.input : 3 2
2.output :报null point 错误
3.ref: 3 2

可以看出,如果是传递类的话,使用input 和ref 的结果是一样 的,而output和数组 的结果是一样 的。

4 原文链接

systemverilog中的参数传递.


http://www.niftyadmin.cn/n/1458770.html

相关文章

verilog中函数用法

verilog中函数用法读写文件常用1.1打开文件1.2读写文件2执行系统命令读写文件常用 1.1打开文件 $fopen打开文件&#xff0c;用法如下&#xff1a; 1. $fopen("<文件名>")&#xff1b; 2. <句柄>$fopen(“<文件名>”)&#xff1b;用法1自然无须多…

tf.linalg.band_part函数的参数意思

tf.linalg.band_part&#xff08;.) 函数功能&#xff1a;保留非主对角线的元素&#xff0c;其余位置的元素替换为0 参数描述 input: 输入的张量num_lower &#xff1a;指定保留的主对角线下方的副对角线的数量&#xff0c;输入数值为负数时&#xff0c;表示下方的对角矩阵元…

在模型训练中,如何初始化及冻结Embedding层

Embedding layer 继承自 keras.layers.Layer&#xff0c;而 Layer 层的属性中包含 trainable&#xff0c;该值默认为 True&#xff0c; 设置其为 False&#xff0c;则可在模型训练中冻结 Embedding 层&#xff1b;Layer 层的方法中包含 set_weigths&#xff0c;利用该方法就可以…

OS module:使用主机操作系统服务

os 库包含很多功能&#xff0c;本部分主要记录os库中的文件与路径操作命令。 os.sep 返回操作系统路径分隔符&#xff0c;linux系统返回符号/&#xff0c; windows系统返回符号\。 os.environ 返回一个mapping对象&#xff0c;该对象的操作类似字典&#xff0c;包含一些常用的…

sys sysconfig module

sys标准库包含的参数或者函数较多&#xff0c;以下部分介绍比较常用的部分&#xff1a; sys.argv 返回在命令行环境下&#xff0c;运行python脚本时提供的命令行参数列表&#xff0c;其中sys.argv[0]存储python脚本的名称。 sys.path 返回一个列表&#xff0c; 列表中的元素是…

from_tensor_slices, from_tensors, from_generator的区别

from_tensor_slices(tensors) tensors: 输入可以是一个或者多个 tensor&#xff0c;若是多个 tensor&#xff0c;需要以元组的形式组装起来&#xff1b;另外所有的输入对象&#xff0c;在 “axis 0” 即第一个维度上&#xff0c;必须有相同的 “shape”。Dataset 内部元素的状…

SQL语法摘要

Select 语句 SELECT&#xff1a;选择原生字段或者定义新字段 字段名以逗号隔开&#xff0c;最后一个字段后不需要加逗号Distinct 关键字作用于全部列空格|AS 别名称通过操作符、数据处理函数、聚集函数、窗口函数自定义表达式生成新字段当不FROM子句时&#xff0c;就是直接计…

bash shell 命令

bash shell可以指定shell的启动方式&#xff0c;常见参数包括&#xff1a; -c string语法格式&#xff0c;参数c表示从“string”字符串中读取命令并执行-i 启动一个能接受用户输入的交互shell 常见linux目录名称&#xff1a; 基础命令 ps命令输出运行在系统上所有进程的相…