systemverilog中ref的用法

input端口是输入端口;output是输出端口;还有inout端口。
inout端口用于双向连接。如果使用多个inout端口驱动一个信号,sv将会根据所有驱动器的值,驱动强度来计算最终的值。

ref是对变量(不能是net)的应用,它的值是该变量最后一次赋的值。如果将一个变量连接到多个ref端口,就有可能产生竞争,因为多个模块的端口都有可能更新同一个变量。

在sysytemverilog中,参数的传递方式可以指定为引用而不是复制,这种ref函数类型比input,output和inout更好用,首先你可以把数组传递给子程序;
使用ref和const传递数组,如下

function void print_checksum (const ref bit [31:0] a[]);
	bit [31:0] checksum = 0;
	for(int i=0; i<a.size(); i++)
		checksum ^= a[i];
		$display("the array checksum is %0d", checksum);
endfunction

以上实例中,用到了const修饰符,虽然数组变量a指向了调用程序中的数组,但是子程序不能修改数组的值,如果你试图改变数组的值,编译器将报错。
systemverilog允许不带ref进行数组的传递,这时数组会被复制到堆栈区中,这种操作的代价很高,除非是对特别小的数组。
**systemverilog的语言参考手册规定了ref参数只能用于带自动存储的子程序中(automatic funtion/automatic task/void function)。**如果你对程序或模块指定了automatic属性,则整个程序内部都是自动存储的。

ref参数的第二个好处是在任务里可以修改变量而且修改结果对调用他的函数是可见的。

task bus_read(input logic [31:0] addr, ref logic [31:0] data);
	bus.request = 1'b1;
	@(posedge bus.grant) bus.addr = addr;
	@(posedge bus.enable) data = bus.data;
	bus.request = 1'b0;
	@(negedge bus.grant);
endtask
logic [31:0] addr, data;
initial fork
	bus_read(addr, data);
	thread2: begin
		@data;	//数据变化时触发
		$display("read %h from bus", data);
	end
join
  • 1
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值