uvm_mem_mam的用法:
1. 几个相关的class:
uvm_mem_mam
uvm_mem_mam_cfg : 用来配置uvm_mem_mam,在uvm_mem_man.new()的时候引入;
uvm_mem_mam_policy: 在分配memory空间的时候用;
一般情况下需要重新定义一下;
class pcie_mem_man_policy extends uvm_mem_mam_policy;
bit [63:0] addr_align_mask; // 0 means no align requirement
// 'b0011 means DW align
bit [63:0] low_base = 64'h00000000_00000000; // region cannnot exeed this limit
bit [63:0] high_limit = 64'hFFFFFFFF_FFFFFFFF; // region cannnot exeed this limit
constraint addr_align_cst {
(start_offset & addr_align_mask) == 0;
}
constraint region_limit_cst {
start_offset >= low_base;
{1'b0, start_offset} + len - 1 <= high_limit;
}
endclass : pcie_mem_man_policy
2. 用法:
uvm_mem_mam mem_mam_h;
uvm_mem_mam_cfg mem_cfg_h;
pcie_mem_mam_policy mem_policy_h;
...
mem_cfg_h = new();
mem_cfg_h.start_offset = 64'h0;
mem_cfg_h.end_offset = 64'hffff_ffff_ffff_ffff;
mem_cfg_h.n_bytes = 1;
mem_mam_h = new("mem_mam_h",mem_cfg_h);
mem_policy_h = new();
mem_policy_h.low_base = 64'h0;
mem_policy_h.high_limit = 64'hffff_ffff_ffff_ffff;
2.1 随机设置地址空间
uvm_mem_region cur_region; //存储所分配的空间
int region_size=32'h1000_0000;
mem_mam_h.release_all_regions(); //释放所有分配的地址
mem_policy_h.addr_align_mask = {28{1'b1}}; //设置分配的地址低28位对齐
cur_region = mem_mam_h.request_region(region_size, mem_policy_h); //分配的地址空间大小为32'h1000_0000;
if(cur_region == null) `uvm_fatal("",""); //检查是否分配成功;
// 利用cur_region.get_start_offset()/cur_region.get_end_offset()可以获取cur_region的起始地址和结束地址;
2.2 手动分配地址
bit[63:0] cur_mem_base = 64'h8000_0000;
bit[63:0] cur_mem_limit = 64'h8fff_ffff;
mem_mam_h.reserve_region(.start_offset(cur_mem_base), .n_bytes(cur_mem_limit - cur_mem_base + 1)); //在mem_mam_h锁定这个地址,不会被随机分配给别的空间;