寄存器模型reg_model的建立
寄存器模型的建立reg_model
1.1 把uvm_reg_field加入到uvm_reg中,
例1
class my_reg extends uvm_reg;
rand uvm_reg_field data;
virtual function void build();
data = uvm_reg_field::type_id::create("data");
// parameter: parent, size, lsb_pos, access, volatile, reset value, has_reset, is_rand, individually accessible
data.configure(this, 16, 0, "RW", 1, 0, 1, 1, 0);
endfunction
`uvm_object_utils(my_reg)
function new(input string name="unnamed_my_reg");
//parameter: name, size, has_coverage
super.new(name, 16, UVM_NO_COVERAGE);
endfunction
endclass
uvm_reg_field加入到uvm_reg中是通过在uvm_reg的build中调用uvm_reg_field的configure函数来实现的。在上面的build中,先对data进行实例化,之后调用configure函数,对uvm_reg_field型的data进行配置.
1.2 把uvm_reg加入到uvm_reg_block中
把uvm_reg加入到uvm_reg_block中,
1.最关键的就调用uvm_reg的configure函数,如下面的例子就是调用configure函数,后面还调用了build函数;
2.还需要把uvm_reg加入到uvm_reg_map中
//创建寄存器1:reg_slave_ID
class reg_slave_ID extends uvm_reg;
uvm_reg_field REVISION_ID;
uvm_reg_field CHIP_ID;
uvm_reg_field PRODUCT_ID;
function new(string name = "slave_ID");
super.new(name,32,UVM_NO_COVERAGE);
endfunction
virtual function void build();
this.REVISION_ID = uvm_reg_field::type_id::create("REVISION_ID");
this.CHIP_ID = uvm_reg_field::type_id::create("CHIP_ID");
this.PRODUCT_ID = uvm_reg_field::type_id::create("PRODUCT_ID");
this.REVISION_ID.configure(this, 8, 0, "RO", 0, 8'h03, 1, 0, 1);
this.CHIP_ID.configure(this, 8, 8, "RO", 0, 8'h5A, 1, 0, 1);
this.PRODUCT_ID.configure(this, 10, 16,"RO", 0, 10'h176, 1, 0, 1);
endfunction
`uvm_object_utils(reg_slave_ID)
endclass
//创建寄存器2:reg_slave_INDEX
class reg_slave_INDEX extends uvm_reg;
uvm_reg_field value;
function new(string name = "slave_INDEX");
super.new(name,8,UVM_NO_COVERAGE);
endfunction
virtual function void build();
this.value = uvm_reg_field::type_id::create("value");
this.value.configure(this, 8, 0, "RW", 0, 32'h0, 1, 0, 1);
endfunction
`uvm_object_utils(reg_slave_INDEX)
endclass
//创建寄存器3:reg_slave_SOCKET
class reg_slave_SOCKET extends uvm_reg;
rand uvm_reg_field IP;
rand uvm_reg_field PORT;
function new(string name = "slave_ADDR");
super.new(name,64,UVM_NO_COVERAGE);
endfunction: new
virtual function void build();
this.IP = uvm_reg_field::type_id::create("IP");
this.PORT = uvm_reg_field::type_id::create("PORT");
this.IP.configure(this, 48, 0, "RW", 0, 48'h0, 1, 0, 1);
this.PORT.configure(this, 16, 48, "RW", 0, 16'h0, 1, 0, 1);
endfunction
`uvm_object_utils(reg_slave_SOCKET)
endclass
//创建一个包含其他寄存器的regfile
class reg_slave_SESSION extends uvm_reg_file;
rand reg_slave_SOCKET SRC;//uvm_reg类型
rand reg_slave_SOCKET DST;//uvm_reg类型
function new(string name = "slave_SESSION");
super.new(name);
endfunction: new
virtual function void build();
this.SRC = reg_slave_SOCKET::type_id::create("SRC");
this.DST = reg_slave_SOCKET::type_id::create("DST");
this.SRC.configure(get_block(), this, "SRC");
this.DST.configure(get_block(), this, "DST");
this.SRC.build();
this.DST.build();
endfunction
virtual function void map(uvm_reg_map mp,
uvm_reg_addr_t offset);
mp.add_reg(SRC, offset+'h00);
mp.add_reg(DST, offset+'h08);
endfunction
virtual function void set_offset(uvm_reg_map mp,
uvm_reg_addr_t offset);
SRC.set_offset(mp, offset+'h00);
DST.set_offset(mp, offset+'h08);
endfunction
`uvm_object_utils(reg_slave_SESSION)
endclass
//创建寄存器4:reg_slave_TABLES
class reg_slave_TABLES extends uvm_reg;
rand uvm_reg_field value;
function new(string name = "slave_TABLES");
super.new(name,32,UVM_NO_COVERAGE);
endfunction
virtual function void build();
this.value = uvm_reg_field::type_id::create("value");
this.value.configure(this, 32, 0, "RW", 0, 32'h0, 1, 0, 1);
endfunction
`uvm_object_utils(reg_slave_TABLES)
endclass
//创建RAM:mem_slave_DMA_RAM
class mem_slave_DMA_RAM extends uvm_mem;
function new(string name = "slave_DMA_RAM");
super.new(name,'h400,32,"RW",UVM_NO_COVERAGE);//h400=longint unsigned size,mem大小,32=int unsigned n_bits,mem的位宽
endfunction
`uvm_object_utils(mem_slave_DMA_RAM)
endclass
//创建间接访问寄存器类reg_slave_DATA
class reg_slave_DATA extends uvm_reg_indirect_data;
function new(string name = "slave_DATA");
super.new(name,32,UVM_NO_COVERAGE);
endfunction
`uvm_object_utils(reg_slave_DATA)
endclass
//创建包含所有reg、regfile、间接访问类型寄存器、mem的reg_block_slave
class reg_block_slave extends uvm_reg_block;
//class register_model extends uvm_reg_block;
reg_slave_ID ID;//uvm_reg
reg_slave_INDEX INDEX;//uvm_reg
reg_slave_DATA DATA;//uvm_reg_indirect_data
rand reg_slave_SESSION SESSION[256]; //uvm_reg_file
rand reg_slave_TABLES TABLES[256];//uvm_reg_file
mem_slave_DMA_RAM DMA_RAM; //uvm_mem,把一块memory加入到uvm_reg_block
uvm_reg_field REVISION_ID;
uvm_reg_field CHIP_ID;
uvm_reg_field PRODUCT_ID;
function new(string name = "slave");
super.new(name,UVM_NO_COVERAGE);
endfunction
virtual function void build();
// create
ID = reg_slave_ID::type_id::create("ID");
INDEX = reg_slave_INDEX::type_id::create("INDEX");
DATA = reg_slave_DATA::type_id::create("DATA");
foreach (SESSION[i])
SESSION[i] = reg_slave_SESSION::type_id::create($sformatf("SESSION[%0d]",i));
foreach (TABLES[i])
TABLES[i] = reg_slave_TABLES::type_id::create($sformatf("TABLES[%0d]",i));
DMA_RAM = mem_slave_DMA_RAM::type_id::create("DMA_RAM");
// configure
ID.configure(this,null,"ID");
ID.build();
INDEX.configure(this,null,"INDEX");
INDEX.build();
foreach (SESSION[i]) begin
SESSION[i].configure(this,null,$sformatf("SESSION[%0d]",i));
SESSION[i].build();
end
foreach (TABLES[i]) begin
TABLES[i].configure(this,null,$sformatf("TABLES[%0d]",i));
TABLES[i].build();
end
// the SV LRM IEEE2009 is not clear if an array of class handles can be assigned to another array if the element types are assignment compatible OR
//if the LRM states the element types have to be 'equal' (the LRM states equal types) IUS requires per LRM 'equivalent' element types and
//does not accept assignment compatible types
`ifdef INCA
begin
uvm_reg r[256];
foreach(TABLES[i])
r[i]=TABLES[i];
DATA.configure(INDEX, r, this, null);
end
`else
DATA.configure(INDEX, TABLES, this, null);
`endif
DATA.build();
DMA_RAM.configure(this,"");
// define default map
default_map = create_map("default_map", 'h0, 4, UVM_LITTLE_ENDIAN);
default_map.add_reg(ID, 'h0, "RW");
default_map.add_reg(INDEX, 'h20, "RW");
default_map.add_reg(DATA, 'h24, "RW");
foreach (SESSION[i])
SESSION[i].map(default_map, 'h1000 + 16 * i);
default_map.add_mem(DMA_RAM, 'h2000, "RW");
// field handle aliases
REVISION_ID = ID.REVISION_ID;
CHIP_ID = ID.CHIP_ID;
PRODUCT_ID = ID.PRODUCT_ID;
endfunction
`uvm_object_utils(reg_block_slave)
endclass : reg_block_slave
在uvm_reg_block的build中,首先需要把default_map实例化:
default_map = create_map("default_map",//string name,
'h0, //uvm_reg_addr_t base_addr,
4,//int unsigned n_bytes,
UVM_LITTLE_ENDIAN);//uvm_endianness_e endian

浙公网安备 33010602011771号