如何为跨越两个寄存器的字段定义后门访问?

时间:2014-06-13 18:49:41

标签: system-verilog uvm

我有一个寄存器映射,它有16位宽的寄存器。我有一个大于16位宽的字段,所以它必须跨越两个地址。如何定义此字段的后门访问权限?

这是我为我的字段test_pattern[23:0]尝试的内容:

register_a.add_hdl_path_slice("path.to.regmap.test_pattern[15:0]", 0, 16);
register_b.add_hdl_path_slice("path.to.regmap.test_pattern[23:16]", 0, 8);

此失败并出现此错误:

  

错误:VPI TYPERR            vpi_handle_by_name()无法获取部件选择的句柄。

目前尚不清楚这是否是我的工具的约束,或UVM代码如何使用VPI。在内部浏览UVM代码后,我看到应该处理部分选择的代码,但是它在#ifdef QUESTA指令内,所以我认为这是一个工具约束。

对此有好的解决方法吗?

3 个答案:

答案 0 :(得分:0)

根据UVM Class Reference

function void add_hdl_path_slice(string name,
    int offset,
    int size,
    bit first = 0,
    string kind = "RTL")

我猜测解决方案应使用offset来选择起始索引。

register_a.add_hdl_path_slice("path.to.regmap.test_pattern", 0, 16);
register_b.add_hdl_path_slice("path.to.regmap.test_pattern", 16, 8);

可能的替代方案,在for循环中进行位选择:

for (int i=0; i<16; i++) begin
  string tmp_path_s;
  tmp_path_s = $sformatf("path.to.regmap.test_pattern[%0d]", i);
  register_a.add_hdl_path_slice(tmp_path_s, i, 1);
end
for (int i=0; i<8; i++) begin
  string tmp_path_s;
  tmp_path_s = $sformatf("path.to.regmap.test_pattern[%0d]", i+16);
  register_a.add_hdl_path_slice(tmp_path_s, i, 1);
end

答案 1 :(得分:0)

很遗憾,提供此代码的人(可能是Mentor?)认为有必要为ifdefs中包含的 Universal 库添加一个有用的功能。事实上,在整个DPI / PLI接口文件被拆分为模拟器特定实现的UVM_1_2分支上更糟糕!

在git://git.code.sf.net/p/uvm/code的master分支上查看distrib/src/dpi/uvm_hdl.c,看起来唯一的QUESTA特定代码就是这个函数:

static int uvm_hdl_set_vlog_partsel(char *path, p_vpi_vecval value, PLI_INT32 flag);
static int uvm_hdl_get_vlog_partsel(char *path, p_vpi_vecval value, PLI_INT32 flag);

使用以下DPI定义的值:

svLogic logic_bit;
svGetBitselLogic(&bit_value,0);
svLogicVecVal bit_value;
svGetPartselLogic(&bit_value,value,i,1);
svPutPartselLogic(value,bit_value,i,1);

理论上,如果您的模拟器和Mentor代码都符合标准,则可以删除ifdefs,而 仍然有效。

您也可以通过检测路径中的部分选择并使用vpi_handle_by_index来读取各个位来执行此操作,这也应该在任何模拟器中都受支持。

注意我的原始答案是错误的,因为代码是针对Mentor的 - 感谢@ dave_59让我直截了当并向Mentor道歉。

答案 2 :(得分:0)

有什么理由说明你没有把它分成2个寄存器。由于寄存器大小为16位,因此声明一个大于此的寄存器是没有意义的。

我看到像这样定义的大字段的方式是声明2个寄存器,每个寄存器中都有一个单独的字段。例如,如果您需要32位指针,则需要:

addr_high,带有16位字段 addr_low,带有16位字段

为方便起见,您可以添加一个可以按顺序访问这两个任务的任务。