【Synopsys】AXI Slave Agent Memory模型的使用

memory模型的前门操作

memory模型的前门访问包括passive模式和active 模式,在passive模式,根据monitor监控到的接口上的读写事务进行更新内存;在active模式下则由slave sequence更新内存。

// axi_slave_mem_response_sequence
if(req_resp.xact_type == svt_axi_slave_transaction::WRITE) begin
    put_write_transaction_data_to_mem(req_resp);
end
else begin
    get_read_data_from_mem_to_transaction(req_resp);
end

在base_test中需要使用config_db机制将该slave_resp_seq设置为对应slave_agent中sequencer的default sequene

uvm_config_db#(uvm_object_wrapper)::set(this,"*sub_env.axi_sys_env.slave[0].sequencer.run_phase","default_sequence",axi_slave_mem_response_sequence::type_id::get());

memory模型的后门操作

鉴于uvm_root.find可以用来查找UVM树形结构中的例化的component句柄,可以用此方法获取验证环境中例化的svt_mem,然后调用svt_mem自带的write()和read()方式进行后门操作。

获取memory类型

function automatic svt_mem find_svt_mem(string name)

	static svt_axi_slave_agent  axi_salve_agent0;
	static svt_axi_slave_agent  axi_salve_agent1;

	svt_mem memory;

	case(name)
		"axi_salve0":begin
			if(axi_salve_agent0 == null) begin
				uvm_pkg::uvm_root  root = uvm_pkg::uvm_root::get();
				uvm_pkg::uvm_component  comp = root.find("*sub_env.axi_sys_env.slave[0]");
				assert($cast(axi_salve_agent0,comp));
			end
			memory = axi_salve_agent0.axi_slave_mem;
		end
		... ...
	endcase
	
	return memory;
endfunction

获取到axi slave中的memory后,便可以调用其自带的read()和write()方法通过后门的方式访问该内存。需要注意的是,对该内存的访问需要保证地址对齐(地址需要与配置的该slave agent的data_width对齐)。

自定义函数的封装

假设axi_slave agent的配置参数 addr_width 为 48-bit,data_width 为256-bit,可以按照以下方式进行封装。

function logic [7:0] axi_write_mem8(string name, bit [47:0] address, logic [7:0] data)
	
	bit [47:0] mem_address;
	logic [255:0] mem_data;	
	logic [31:0] mem_strb;
	svt_mem axi_mem;
	
	axi_mem = find_svt_mem(name);

	mem_address = address;
	mem_data = 'h0;
	mem_data[mem_address[4:0]*8 +: 8] = data;
	mem_strb = 'h0;
	mem_strb[mem_address[4:0]] = 1'b1;	

	void'(axi_mem.write({mem_address[47:5],5'b00000},mem_data,mem_strb));

endfunction

其他方法介绍

另外,axi slave vip还提供write_byte()和read_byte(),可以按字节对memory进行后门访问,其原型如下:

task svt_axi_slave_agent::write_byte(input bit[`SVT_AXI_MAX_ADDR_WIDTH-1:0] addr, bit[7:0] data);
task svt_axi_slave_agent::read_byte(input bit[`SVT_AXI_MAX_ADDR_WIDTH-1:0] addr, output bit[7:0] data);

set_meminit() 方法 可以配置mem模型对未写过的地址返回一些特定值,以此实现mem的随机初始化,原型如下:

task svt_mem::set_meminit (svt_mem::meminit_enum meminit = UNKNOWNS,
				 	bit [SVT_MEM_MAX_DATA_WIDTH-1:0] meminit_value = 0, 
				 	bit [SVT_MEM_MAX_ADDR_WIDTH-1:0] meminit_address_offset = 0)

meminit_enum 中定义的类型如下:

UNKNOWNS
ZEROES
ONES
ADDRESS
VALUE
INCR
DECR
USER_PATTERN
RANDOM

可以通过如下方式为svt_mem赋值:

axi_mem = find_svt_mem("axi_slave"); 
axi_mem.set_meminit(svt_mem::VALUE,'h123456789,'h0);

补充知识

uvm_root中的find()find_all()方法

详见UVM_Class_Reference_Manual的uvm_root章节.

- function uvm_component find (string comp_match) 

该方法调用了uvm_root::find_all

- function void find_all (string comp_match, ref uvm_component comps[S], input uvm_component comp=null)

find/find_all可以根据传入的字符串(string comp_match)来查找uvm树形结构中例化的 component句柄(find)或者component句柄列表(find all)。
例如,sequence中使用 uvm_top.find(“uvm_test_top”)就可以获得testcase的句柄。

同时,find/find_all调用了DPI,对字符串支持使用通配符*和?

uvm_root.find源码如下
在这里插入图片描述

  • 3
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值