【问题标题】:Formatting Dynamic Array of Bits as String in SystemVerilog在 SystemVerilog 中将动态位数组格式化为字符串
【发布时间】:2016-07-20 17:49:08
【问题描述】:

如何将动态位数组(或更准确地说是逻辑)格式化为字符串,例如,对于 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}});

但它至少在 Questa 10.3d 中返回 # x#(我怀疑这是一个错误 - 如果它适用于其他模拟器,我会很感兴趣)。

我尝试先将其转换为打包数组,但这会遇到其他问题。如果对结果没有大小限制,源值总是在目标变量中左对齐,例如:

logic [63:0] v64;
...
v64 = {>> {vdyn}}; // 64'h0097000000000000

如果不使用可变大小的切片,就无法只打印出我想要的部分。以下工作,但它要求我在编译时知道数组的大小:

v64 = 16'({>> {vdyn}});  // 64'h0000000000000097

我发现的最好的东西是以下“双反”(注意我在这里使用<<,而不是>>):

     v64 = {<< {vdyn}};    // 64'he900000000000000 
     v64 = {<< {v64}};     // 64'h0000000000000097
     vstr = $sformatf(fmt, v64); // #0097#

不过,不得不这样做似乎有点做作。顺便说一句,将前两个语句合二为一是行不通的:

     v64 = {<< {{<< {vdyn}}}};     // 64'hZ900000000000000

(出于某种原因,v64[63] 是 z)。同样,我怀疑这是 Questa 10.3d 中的一个错误。

【问题讨论】:

    标签: arrays system-verilog dynamic-arrays


    【解决方案1】:

    尝试投射数组的一部分并循环遍历。例如,转换为 4 位值的 4 条目切片。可以使用-: 或+: 运算符来完成调整(参见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
    

    代码中的4s 可以更改为其他值,具体取决于需要多少前导 0 或非二次方格式,但它必须是数字常量


    我在其他一些模拟器上尝试了您的代码。 vstr = $sformatf(fmt, { &gt;&gt; {vdyn}}); 有时会给我编译错误。将数组转换为大于其预期最大大小的东西似乎有效

    fmt = $sformatf("#%%%0dh#", (vdyn.size-1)/4 + 1); // "#%4h#"
    vstr = $sformatf(fmt, 128'({ >> {vdyn}})); // works iff 128>=vdyn.size
    

    【讨论】:

    • 谢谢。我曾想过用循环来做(我通常写VHDL,所以我习惯于用蛮力的方式做事)。我认为它需要一些增强来支持不是 4 的倍数的大小,但除此之外它应该适用于几乎任何大小的数组。流式传输到打包数组(就像我所做的那样)仍然对大小设置了上限。感谢您在另一个模拟器上尝试代码。在 Questa 10.3d 上将其转换为固定大小“有效”,但它具有我提到的相同的左对齐问题。
    • 我玩过它不是 4 的倍数,在将 i&gt;0 更改为 i&gt;=0 后,它仍然可以在 edaplayground 上使用模拟器正确投射。示例:vdyn = new [17]
    【解决方案2】:

    我认为问题可能在于使用动态类型的流式运算符的宽度未在自行确定的上下文中定义(例如,系统任务的参数)。我认为 LRM 应该将此视为错误。

    一种解决方法是将左对齐的结果向右移动

    v64 = {>> {vdyn}}; 
    v64 >>= 64-vdyn.size;
    

    【讨论】:

    • (a) 宽度应该是明确的,尽管显然不是静态的(如果这就是您所说的“自行决定”的话)。 (b) 这是改变对齐方式的一种更明智的方法,但是真的没有办法直接将动态位数组转换为等效的(右对齐)压缩数组吗?在我看来,这将是一个明显的语言特征。 (c) 有没有办法在此处的评论中添加换行符?我刚刚注意到所有内容都放在一个段落中。
    • 是的。我应该说不是静态定义的。 Verilog 要求静态确定所有整数类型的宽度。
    猜你喜欢
    • 2021-07-09
    • 2012-05-31
    • 2021-05-10
    • 2016-01-28
    • 2010-10-16
    • 2021-05-05
    • 2014-11-02
    • 2011-02-09
    相关资源
    最近更新 更多