
寄存器模型的自动化生成
编写excel文件,后缀为csv;编写python脚本
才cmd中输入这两个文件的路径和命名就可以自动生成寄存器模型rgm


寄存器模型的更新
最开始的寄存器模型是这样的

在reg_pkg中,这些接口信号作为uvm_sequence_item定义为reg_trans类。约束,注册,域的自动化,new函数,一个不要落。
class reg_trans extends uvm_sequence_item;
rand bit[7:0] addr;
rand bit[1:0] cmd;
rand bit[31:0] data;
bit rsp;
constraint cstr {
soft cmd inside {`WRITE, `READ, `IDLE};
soft addr inside {`SLV0_RW_ADDR, `SLV1_RW_ADDR, `SLV2_RW_ADDR, `SLV0_R_ADDR, `SLV1_R_ADDR, `SLV2_R_ADDR};
addr[7:4]==0 && cmd==`WRITE -> soft data[31:6]==0;
soft addr[7:5]==0;
addr[4]==1 -> soft cmd == `READ;
};
`uvm_object_utils_begin(reg_trans)
`uvm_field_int(addr, UVM_ALL_ON)
`uvm_field_int(cmd, UVM_ALL_ON)
`uvm_field_int(data, UVM_ALL_ON)
`uvm_field_int(rsp, UVM_ALL_ON)
`uvm_object_utils_end
function new (string name = "reg_trans");
super.new(name);
endfunction
endclass 
item由driver驱动
class reg_driver extends uvm_driver #(reg_trans);
local virtual reg_intf intf;
`uvm_component_utils(reg_driver)
function new (string name = "reg_driver", uvm_component parent);
super.new(name, parent);
endfunction
function void set_interface(virtual reg_intf intf);
if(intf == null)
$error("interface handle is NULL, please check if target interface has been intantiated");
else
this.intf = intf;
endfunction
task run_phase(uvm_phase phase);
fork
this.do_drive();
this.do_reset();
join
endtask
task do_reset();
forever begin
@(negedge intf.rstn);
intf.cmd_addr <= 0;
intf.cmd <= `IDLE;
intf.cmd_data_m2s <= 0;
end
endtask
task do_drive();
reg_trans req, rsp;
@(posedge intf.rstn);
forever begin
seq_item_port.get_next_item(req);
this.reg_write(req);
void'($cast(rsp, req.clone()));
rsp.rsp = 1;
rsp.set_sequence_id(req.get_sequence_id());
seq_item_port.item_done(rsp);
end
endtask
task reg_write(reg_trans t);
@(posedge intf.clk iff intf.rstn);
case(t.cmd)
`WRITE: begin
intf.drv_ck.cmd_addr <= t.addr;
intf.drv_ck.cmd <= t.cmd;
intf.drv_ck.cmd_data_m2s <= t.data;
end
`READ: begin
intf.drv_ck.cmd_addr <= t.addr;
intf.drv_ck.cmd <= t.cmd;
repeat(2) @(negedge intf.clk);
t.data = intf.cmd_data_s2m;
end
`IDLE: begin
this.reg_idle();
end
default: $error("command %b is illegal", t.cmd);
endcase
`uvm_info(get_type_name(), $sformatf("sent addr %2x, cmd %2b, data %8x", t.addr, t.cmd, t.data), UVM_HIGH)
endtask
task reg_idle();
@(posedge intf.clk);
intf.drv_ck.cmd_addr <= 0;
intf.drv_ck.cmd <= `IDLE;
intf.drv_ck.cmd_data_m2s <= 0;
endtask
endclass 

一共6个寄存器对应的csv文档如下

更新后的结构图如下,寄存器被换成了APB总线?

寄存器接口如下


根据v1.csv和寄存器图,以及寄存器接口中的信号,更新寄存器为v2

这是自己的傻逼更新,需要更改的地方是:预留区域reserved为RO只读,id的重置值不是全部为0;域不是信号名;free slot的重置值时'd32

用相同的操作获得rgm.pkg。寄存器模型每个reg为一个类,最后多一个类mcdf_reg

每个寄存器类的结构都是相似的:注册,声明域,域的覆盖组;new函数中有条件例化覆盖组;build_phase完成域的例化和配置;与覆盖组相对应的采样函数。
在最后的mcdf_rgm中,所有寄存器class被作为随机变量,声明寄存器map,build_phase中对每个寄存器进行例化、配置、调用build、例化map+每个寄存器偏移地址,预留了后门访问的添加路径。最后是lock_model,这部分要再复习一下uvm的寄存器模型。
class mcdf_rgm extends uvm_reg_block;
`uvm_object_utils(mcdf_rgm)
rand slv_en_reg slv_en;
rand parity_err_clr_reg parity_err_clr;
rand slv_id_reg slv_id;
rand slv_len_reg slv_len;
rand slv0_free_slot_reg slv0_free_slot;
rand slv1_free_slot_reg slv1_free_slot;
rand slv2_free_slot_reg slv2_free_slot;
rand slv3_free_slot_reg slv3_free_slot;
rand slv0_parity_err_reg slv0_parity_err;
rand slv1_parity_err_reg slv1_parity_err;
rand slv2_parity_err_reg slv2_parity_err;
rand slv3_parity_err_reg slv3_parity_err;
uvm_reg_map map;
function new(string name = "mcdf_rgm");
super.new(name, UVM_NO_COVERAGE);
endfunction
virtual function void build();
slv_en = slv_en_reg::type_id::create("slv_en");
slv_en.configure(this);
slv_en.build();
parity_err_clr = parity_err_clr_reg::type_id::create("parity_err_clr");
parity_err_clr.configure(this);
parity_err_clr.build();
slv_id = slv_id_reg::type_id::create("slv_id");
slv_id.configure(this);
slv_id.build();
slv_len = slv_len_reg::type_id::create("slv_len");
slv_len.configure(this);
slv_len.build();
slv0_free_slot = slv0_free_slot_reg::type_id::create("slv0_free_slot");
slv0_free_slot.configure(this);
slv0_free_slot.build();
slv1_free_slot = slv1_free_slot_reg::type_id::create("slv1_free_slot");
slv1_free_slot.configure(this);
slv1_free_slot.build();
slv2_free_slot = slv2_free_slot_reg::type_id::create("slv2_free_slot");
slv2_free_slot.configure(this);
slv2_free_slot.build();
slv3_free_slot = slv3_free_slot_reg::type_id::create("slv3_free_slot");
slv3_free_slot.configure(this);
slv3_free_slot.build();
slv0_parity_err = slv0_parity_err_reg::type_id::create("slv0_parity_err");
slv0_parity_err.configure(this);
slv0_parity_err.build();
slv1_parity_err = slv1_parity_err_reg::type_id::create("slv1_parity_err");
slv1_parity_err.configure(this);
slv1_parity_err.build();
slv2_parity_err = slv2_parity_err_reg::type_id::create("slv2_parity_err");
slv2_parity_err.configure(this);
slv2_parity_err.build();
slv3_parity_err = slv3_parity_err_reg::type_id::create("slv3_parity_err");
slv3_parity_err.configure(this);
slv3_parity_err.build();
map = create_map("map", 'h0, 4, UVM_LITTLE_ENDIAN);
map.add_reg(slv_en, 32'h00, "RW");
map.add_reg(parity_err_clr, 32'h04, "RW");
map.add_reg(slv_id, 32'h08, "RW");
map.add_reg(slv_len, 32'h0C, "RW");
map.add_reg(slv0_free_slot, 32'h80, "RO");
map.add_reg(slv1_free_slot, 32'h84, "RO");
map.add_reg(slv2_free_slot, 32'h88, "RO");
map.add_reg(slv3_free_slot, 32'h8C, "RO");
map.add_reg(slv0_parity_err, 32'h90, "RO");
map.add_reg(slv1_parity_err, 32'h94, "RO");
map.add_reg(slv2_parity_err, 32'h98, "RO");
map.add_reg(slv3_parity_err, 32'h9C, "RO");
//slv_en.add_hdl_path_slice("???", 0, 32);
//parity_err_clr.add_hdl_path_slice("???", 0, 32);
//slv_id.add_hdl_path_slice("???", 0, 32);
//slv_len.add_hdl_path_slice("???", 0, 32);
//slv0_free_slot.add_hdl_path_slice("???", 0, 32);
//slv1_free_slot.add_hdl_path_slice("???", 0, 32);
//slv2_free_slot.add_hdl_path_slice("???", 0, 32);
//slv3_free_slot.add_hdl_path_slice("???", 0, 32);
//slv0_parity_err.add_hdl_path_slice("???", 0, 32);
//slv1_parity_err.add_hdl_path_slice("???", 0, 32);
//slv2_parity_err.add_hdl_path_slice("???", 0, 32);
//slv3_parity_err.add_hdl_path_slice("???", 0, 32);
//add_hdl_path("???");
lock_model();
endfunction
endclass版权声明:本文为weixin_39668316原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。