SV---句柄的使用

1.句柄的传递

1)句柄可以作为形式参数通过方法来完成对象句柄的传递,从外部传入方法内部。

2)句柄也可以在方法内部首先完成修改,而后再由外部完成使用

例题:下述代码最后显示的t.addr的数值是多少?

function void create (Transaction tr);
	tr = new();
	tr.addr = 100;
	...
endfunction

Transaction t;

initial begin
	create(t);
	t.addr = 10;
	$display (t.addr);
end 

解析:tr默认是输入方向,导致句柄t悬空,从而t的值是null,所以执行creat(t)之后t不会发生变化还是null,因为这里t没有返回值,所以执行到t.addr = 10这步会报错。

总结:句柄悬空,无法查找变量。

解决方法:在第一行代码中Transaction前面添加inout/ref。

3)在程序执行时,可以在任何时刻为句柄创建新的对象,并将新的指针赋值给句柄。

例题:t.addr的数值是多少?

task generate trans();
	Transaction t;
	Transaction fifo [$];
	t = new();
	for(int i = 0;i<3;i++) begin
		t.addr = i << 2;
		fifo.push_back(t);
	end
	t = fifo.pop_front();
endtask

解析:问题的关键是只t = new();只出现一次,即只创建了一个对象,i = 0时,t.addr =  0 ,把第一个句柄放入fifo。i = 1时,t.addr =  2 ,把第二个句柄放入fifo。i = 2时,t.addr =  8 ,把第三个句柄放入fifo。当三个句柄都放好之后,因为只声明一个对象,所以三个句柄都会指向最后的t.addr =  8,即便时从后放,从前面拿,拿到的是第一个句柄指向的对象,仍然是t.addr =  8。

如果把t = new()放入for循环里面,就会声明三个对象,那么第一个句柄指向的就是t.addr = 0。

SystemVerilog中,为了进行随机测试,我们可以利用类(Class)和句柄(Handle)的概念。首先,你需要定义一个测试类(Test Class)来管理测试实例和随机数据。下面是一个简单的示例,展示了如何使用类和句柄进行随机测试: ```systemverilog // 测试类 TestResponder class test_responder; private ArbResponder#(NUM_REQUESTS) responder; // 使用参数化类型声明应答器实例 public method void init(responder_handle rh); public method void send_request(int index); public event response_received(response_type resp); protected rand bit request[index_max]; // 定义随机变量 endclass // 测试类初始化方法 function void test_responder::init(responder_handle rh); responder = new(rh, $time); // 创建并初始化应答器实例 endfunction // 发送随机请求方法 function void test_responder::send_request(int index); `ifndef _SIMULINK_ request[index] = $urandom(); responder.send(request[index]); // 通过句柄调用应答器的send方法 `else // 如果在仿真环境中,可以使用特定的方法发送请求 `endif endfunction // 应答事件处理 event test_responder::response_received(response_type resp); $notify(resp_received, resp); // 触发响应事件 endevent ``` 在这个例子中,`test_responder`类负责管理`ArbResponder`实例的创建、发送请求以及接收和处理应答。`rand`关键字用于声明随机变量,`response_received`事件用于表示接收到的应答。 在实际测试脚本中,你可以创建多个`test_responder`对象,并使用它们进行随机测试: ```systemverilog initial begin TestResponder tr[TEST_INSTANCES]; // 创建一组测试实例 foreach(tr[i]) begin tr[i].init(responder_h); // 初始化每个实例 for (int i = 0; i < TEST_CASES; i++) do_test_case(i); // 执行一系列测试用例 end end function void do_test_case(int case_idx); tr[case_idx].send_request($urandom()); // 发送随机请求 // 等待响应并检查结果 endfunction ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值