uvm_reg_indirect_data

uvm_reg_indirect_data是一个间接数据访问抽象类。对用于间接访问寄存器数组的寄存器的行为进行建模,由第二个 ~address~ 寄存器索引。不应直接实例化此类。应使用特定于类型的类扩展来提供 工厂启用的构造函数并指定 ~n_bits~ 和覆盖模型。

class uvm_reg_indirect_data extends uvm_reg;

   protected uvm_reg m_idx;
   protected uvm_reg m_tbl[];

// 函数: new,创建该类的一个实例 ,不应直接调用,而是通过 super.new() 调用, ~n_bits~ 的值必须与间接寄存器数组中的位数匹配。
   function new(string name = "uvm_reg_indirect", int unsigned n_bits, int has_cover);
      super.new(name,n_bits,has_cover);
   endfunction: new

   virtual function void build();
   endfunction: build

    // Function: configure
  // 配置indirect data寄存器。 ~idx~ 寄存器指定要访问的寄存器在~reg_a~ 寄存器数组中的索引。~idx~ 必须首先写入。
  //对该寄存器的读取或写入操作随后将读取或写入寄存器数组中的索引寄存器。寄存器数组中每个寄存器的位数必须等于该寄存器的~n_bits~。
//其余参数见 <uvm_reg::configure()>。 function void configure (uvm_reg idx, uvm_reg reg_a[], uvm_reg_block blk_parent, uvm_reg_file regfile_parent = null); super.configure(blk_parent, regfile_parent, ""); m_idx = idx; m_tbl = reg_a; // Not testable using pre-defined sequences uvm_resource_db#(bit)::set({"REG::", get_full_name()}, "NO_REG_TESTS", 1); // Add a frontdoor to each indirectly-accessed register for every address map this register is in.
foreach (m_maps[map]) begin add_frontdoors(map); end endfunction /*local*/ virtual function void add_map(uvm_reg_map map); super.add_map(map); add_frontdoors(map); endfunction local function void add_frontdoors(uvm_reg_map map); foreach (m_tbl[i]) begin uvm_reg_indirect_ftdr_seq fd; if (m_tbl[i] == null) begin `uvm_error(get_full_name(),   $sformatf("Indirect register #%0d is NULL", i)); continue; end fd = new(m_idx, i, this); if (m_tbl[i].is_in_map(map)) m_tbl[i].set_frontdoor(fd, map); else map.add_reg(m_tbl[i], -1, "RW", 1, fd); end endfunction virtual function void do_predict (uvm_reg_item rw, uvm_predict_e kind = UVM_PREDICT_DIRECT, uvm_reg_byte_en_t be = -1); if (m_idx.get() >= m_tbl.size()) begin `uvm_error(get_full_name(), $sformatf("Address register %s has a value (%0d) greater than the maximum indirect register array size (%0d)", m_idx.get_full_name(), m_idx.get(), m_tbl.size())); rw.status = UVM_NOT_OK; return; end //NOTE limit to 2**32 registers begin int unsigned idx = m_idx.get(); m_tbl[idx].do_predict(rw, kind, be); end endfunction virtual function uvm_reg_map get_local_map(uvm_reg_map map, string caller=""); return m_idx.get_local_map(map,caller); endfunction // Just for good measure, to catch and short-circuit non-sensical uses virtual function void add_field (uvm_reg_field field); `uvm_error(get_full_name(), "Cannot add field to an indirect data access register"); endfunction virtual function void set (uvm_reg_data_t value, string fname = "", int lineno = 0); `uvm_error(get_full_name(), "Cannot set() an indirect data access register"); endfunction virtual function uvm_reg_data_t get(string fname = "", int lineno = 0); `uvm_error(get_full_name(), "Cannot get() an indirect data access register"); return 0; endfunction virtual function uvm_reg get_indirect_reg(string fname = "", int lineno = 0); int unsigned idx = m_idx.get_mirrored_value(); return(m_tbl[idx]); endfunction virtual function bit needs_update(); return 0; endfunction virtual task write(output uvm_status_e status, input uvm_reg_data_t value, input uvm_path_e path = UVM_DEFAULT_PATH, input uvm_reg_map map = null, input uvm_sequence_base parent = null, input int prior = -1, input uvm_object extension = null, input string fname = "", input int lineno = 0); if (path == UVM_DEFAULT_PATH) begin uvm_reg_block blk = get_parent(); path = blk.get_default_path(); end if (path == UVM_BACKDOOR) begin `uvm_warning(get_full_name(), "Cannot backdoor-write an indirect data access register. Switching to frontdoor."); path = UVM_FRONTDOOR; end // Can't simply call super.write() because it'll call set() begin uvm_reg_item rw; XatomicX(1); rw = uvm_reg_item::type_id::create("write_item",,get_full_name()); rw.element = this; rw.element_kind = UVM_REG; rw.kind = UVM_WRITE; rw.value[0] = value; rw.path = path; rw.map = map; rw.parent = parent; rw.prior = prior; rw.extension = extension; rw.fname = fname; rw.lineno = lineno; do_write(rw); status = rw.status; XatomicX(0); end endtask virtual task read(output uvm_status_e status, output uvm_reg_data_t value, input uvm_path_e path = UVM_DEFAULT_PATH, input uvm_reg_map map = null, input uvm_sequence_base parent = null, input int prior = -1, input uvm_object extension = null, input string fname = "", input int lineno = 0); if (path == UVM_DEFAULT_PATH) begin uvm_reg_block blk = get_parent(); path = blk.get_default_path(); end if (path == UVM_BACKDOOR) begin `uvm_warning(get_full_name(), "Cannot backdoor-read an indirect data access register. Switching to frontdoor."); path = UVM_FRONTDOOR; end super.read(status, value, path, map, parent, prior, extension, fname, lineno); endtask virtual task poke(output uvm_status_e status, input uvm_reg_data_t value, input string kind = "", input uvm_sequence_base parent = null, input uvm_object extension = null, input string fname = "", input int lineno = 0); `uvm_error(get_full_name(), "Cannot poke() an indirect data access register"); status = UVM_NOT_OK; endtask virtual task peek(output uvm_status_e status, output uvm_reg_data_t value, input string kind = "", input uvm_sequence_base parent = null, input uvm_object extension = null, input string fname = "", input int lineno = 0); `uvm_error(get_full_name(), "Cannot peek() an indirect data access register"); status = UVM_NOT_OK; endtask
virtual task update(output uvm_status_e status, input uvm_path_e path = UVM_DEFAULT_PATH, input uvm_reg_map map = null, input uvm_sequence_base parent = null, input int prior = -1, input uvm_object extension = null, input string fname = "", input int lineno = 0); status = UVM_IS_OK; endtask virtual task mirror(output uvm_status_e status, input uvm_check_e check = UVM_NO_CHECK, input uvm_path_e path = UVM_DEFAULT_PATH, input uvm_reg_map map = null, input uvm_sequence_base parent = null, input int prior = -1, input uvm_object extension = null, input string fname = "", input int lineno = 0); status = UVM_IS_OK; endtask endclass : uvm_reg_indirect_data

 

posted @ 2023-02-10 20:21  luckylan  阅读(155)  评论(0)    收藏  举报