如何在父uvm_transaction中随机及例化子的uvm_transaction

Use Case: AXI DMA控制器有128个独立的通道,可以并行进行读写操作。首先我们对AXI DMA控制器的top level的事务进行建模,如下:

class axi_dmac_transaction extends uvm_transaction;
	rand axi_chan_transaction axi_chan[axi_dmac_dec::CHAN_NUM];
    function new(string name = "axi_dmac_transaction ");
        super.new(name);
        `uvm_info("TRACE", $sformatf("%m"), UVM_DEBUG)
    endfunction
endclass

那么如何进行多通道事务的例化及随机呢?这里利用到了uvm object的pre_randomize函数:

function void pre_randomize();
    foreach(axi_chan[i]) begin
        axi_chan[i] = axi_chan_transaction ::type_id::create($sformatf("axi_chan[%0d]",i));
    end
endfunction

这样就可以在接下来调用axi_dmac_transaction的随机化,从而实现axi_chan_transaction的各个实例的随机化。

如果开启的DMA的通道数量不确定,我们可以利用队列来进行实现:

class axi_dmac_transaction extends uvm_transaction;
	rand int chan_num;
	rand axi_chan_transaction axi_chan[$];
	
	constraint c_chan_num {
		chan_num inside {[1:128]};
		axi_chan.size == chan_num;
    }
    
    function new(string name = "axi_dmac_transaction ");
        super.new(name);
        `uvm_info("TRACE", $sformatf("%m"), UVM_DEBUG)
    endfunction

	function void pre_randomize();
	endfunction

endclass

这时候,调用axi_dmac_transaction的随机化,队列axi_chanchan_numaxi_chan_transaction 句柄,但是句柄的值是空的,因此我们需要进行实例化,该操作可在post_randomize函数中完成:

function void post_randomize();
    `uvm_info("TRACE", $sformatf("%m"), UVM_DEBUG)
    
    foreach(axi_chan[i]) begin
        axi_chan[i] = axi_chan_transaction ::type_id::create($sformatf("axi_chan[%0d]",i));
        assert(axi_chan[i].randomize());
    end
endfunction

你可能感兴趣的:(数字验证,uvm,object,instantiation,randomization)