2、transaction和事务级仿真
...大约 3 分钟
本文简述了事务级仿真以及transaction的部分编写规则,并使用一个简单的数据转发模块作为本文的DUT,内容与代码都仅供参考。
2、transaction和事务级仿真
2.1 何为事务级仿真
在验证平台中,数据并不以pin级信号传输,而是以一种特殊的数据形式transaction存在。这里提到的transaction指的就是事务,它区别于pin级仿真。以定义transaction类来决定DUT的需要传入的信号,能有效解决数据随机生成问题的。诚然,Verilog中也有random系统函数可用,但用起来不太顺手,复用性也不是很好。
因此,在DUT固定下来后,首先需要搞清楚DUT的作用,以及它和上位机的通信方式,还有它需要接收的pin级信号有哪些,接着就可以编写transaction类了。
这里作为例子,用一个非常简单的模块作为DUT:
// 数据转发模块
module dut(
input clk,
input rst_n,
input [3:0] rxd,
input rxv,
output reg [3:0]txd,
output reg txv
);
always@(posedge clk or negedge rst_n) begin
if(!rst_n) begin
txd <= 0;
txv <= 0;
end
else begin
txd <= rxd;
txv <= rxv;
end
end
endmodule
这个模块承担一个非常简单的任务:把从上位机接收到的4位数据rxd、他们的有效信号rxv,原封不动地通过txd和txv传给下位机。所以,要这样写transaction:
class my_transaction extends uvm_sequence_item;
// 定义transaction类需要向DUT传递的信息,其中rand表示需要随机化的信息:
rand bit [3:0] rxd;
rand bit rxv;
// 利用factory机制,到时可以自动生成transaction和自动进行随机化
// 这里还涉及另一个叫field的机制,现在也先不解释
`uvm_object_utils_begin(my_transaction)
`uvm_field_int(rxd, UVM_ALL_ON)
`uvm_field_int(rxv, UVM_ALL_ON)
`uvm_object_utils_end
// 约束条件。尽管本文的DUT选取得相当简单,但在更复杂的DUT中,不是所有输入都是符合规范的,
// 所以需要添加一些约束条件,以限制随机的范围。并且,如果到了验证后期,随机化的部分做得差不多了,
// 需要定向测试几个边缘条件时,也可以通过这个约束来直接进行定向测试。
// 直接在transaction中定义的约束称为内部约束,它是可以被从外部改变的,这个后面再考虑。
constraint Limit{
// 先把rxd的值限制在一个范围内,rxv不做限制
// 这样写,rxd会被限制在0到15之间。而这样做其实就相当于没限制,只是这边作为一个示例。
rxd inside {[0:15]};
}
// 现在写一下构造函数。构造函数是每个类都需要写的。当这个类的对象被创建时,就需要调用这个构造函数。
function new(string name = "");
super.new(name);
endfunction
endclass
事实上,transaction虽然在验证平台中承担转运数据的功能,但它并不属于平台组件的一部分,它属于UVM验证平台中的object,而非component。这点在使用UVM的field机制时就能看出来,它使用的宏是`uvm_object_utils_xxx而不是component。
这样,就完成了简易的transaction编写。
Powered by Waline v2.15.5