我有一个寄存器映射,它有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
指令内,所以我认为这是一个工具约束。
对此有好的解决方法吗?
答案 0 :(得分:0)
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位字段
为方便起见,您可以添加一个可以按顺序访问这两个任务的任务。