如何将动态数组位(或更正确的逻辑)格式化为字符串,例如,对于UVM的convert2string?例如,我想转换
logic vdyn[];
...
vdyn = new [16] ('{0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1});
到字符串0097
。
我认为以下内容可行(#
仅用于分隔字符串以便于阅读):
fmt = $sformatf("#%%%0dh#", (vdyn.size-1)/4 + 1); // "#%4h#"
vstr = $sformatf(fmt, { >> {vdyn}});
但它返回# x#
,至少在Questa 10.3d中(我怀疑这是一个错误 - 如果它适用于其他模拟器,我会感兴趣)。
我首先尝试将其转换为打包数组,但这会遇到其他问题。如果结果没有大小限制,则源值始终在目标变量中左对齐,例如:
logic [63:0] v64;
...
v64 = {>> {vdyn}}; // 64'h0097000000000000
如果不使用可变尺寸切片,就无法打印出我想要的部分。以下工作,但它需要我在编译时知道数组的大小:
v64 = 16'({>> {vdyn}}); // 64'h0000000000000097
我发现的最好的事情是:&#34; double-reverse&#34; (请注意,我在这里使用<<
,而不是>>
):
v64 = {<< {vdyn}}; // 64'he900000000000000
v64 = {<< {v64}}; // 64'h0000000000000097
vstr = $sformatf(fmt, v64); // #0097#
但是,这似乎有点不可思议。顺便说一句,将前两个陈述合并为一个不起作用:
v64 = {<< {{<< {vdyn}}}}; // 64'hZ900000000000000
(v64[63]
由于某种原因是z
。同样,我怀疑这是Questa 10.3d中的一个错误。
答案 0 :(得分:1)
尝试投射一个数组切片并循环遍历。例如,4个条目切片被强制转换为4位值。 slize可以使用-:
或+:
运算符完成(请参阅IEEE Std 1800-2012§7.4.3阵列操作和§7.4.6索引和切片数组)
vstr = "";
for(int i=vdyn.size()-1; i>=0; i-=4) begin
vstr = $sformatf("%h%s", 4'({>>{vdyn[i -: 4]}}), vstr);
end
vstr = $sformatf("#%s#", vstr); // user formatting
代码中的4
可以更改为其他内容,具体取决于需要多少前导0或非二次幂格式,但它必须是数字常量
我在其他一些模拟器上尝试过你的代码。 vstr = $sformatf(fmt, { >> {vdyn}});
有时会给我编译错误。将数组转换为大于预期最大大小的数组似乎可以正常工作
fmt = $sformatf("#%%%0dh#", (vdyn.size-1)/4 + 1); // "#%4h#"
vstr = $sformatf(fmt, 128'({ >> {vdyn}})); // works iff 128>=vdyn.size
答案 1 :(得分:1)
我认为问题可能是使用动态类型的流操作符的宽度未在自定义上下文中定义(例如,系统任务的参数)。我认为LRM应该对此进行处理。
解决方法是通过
将左对齐结果向右移动v64 = {>> {vdyn}};
v64 >>= 64-vdyn.size;