【问题标题】:Unpack custom data fields in SystemVerilog在 SystemVerilog 中解压自定义数据字段
【发布时间】:2021-06-23 06:27:24
【问题描述】:

我正在尝试为 SystemVerilog symulation(不可综合)编写一个通用寄存器解析器。 目标是返回一个字段数组,给定:

  • 字段位置
  • 字段宽度
  • 寄存器值

这是我的看法:

  task automatic reg_parser( ref    int apb_word,
                             ref    int lsb_array[],
                             ref    int width_array[],
                             output int fields_array[] );

    // Extract right bits
    // field  = word[FIELD_LSB+FIELD_WIDTH-1 : FIELD_LSB];
    for (int i = 0; i < $size(fields_array); i++) begin
      fields_array[i] = apb_word[lsb_array[i]+width_array[i]-1:lsb_array[i]];
    end
  endtask : reg_parser

问题是vlog 在抱怨:range must be bounded by constant expressions。 我发现examples 带有流式运算符 (&gt;&gt;,&lt;&lt;),但它们暗示着恒定的规则结构,而寄存器字段通常不那么规则。

关于如何正确实现此功能的任何建议?

【问题讨论】:

    标签: verilog system-verilog uvm


    【解决方案1】:

    由于“字段”的大小不固定,部分选择将不起作用。我会旋转并屏蔽该值。

    for (int i = 0; i < $size(fields_array); i++) begin
      int mask;
      //Create mask which is of width of your field, by rotation
      mask = 32'hFFFF_FFFF >> (32 - width_array[i]);
      //Rotate the APB_WORD so that the lsb postion as at 0 postion 
      //and mask the value.
      fields_array[i] = mask&(apb_word >> lsb_array[i]);
      // fields_array[i] = apb_word[lsb_array[i]+width_array[i]-1:lsb_array[i]];
    end
    

    您也可以通过将宽度旋转 1 倍然后减去 1 来创建蒙版。如果我没记错的话,UVM 会以类似的方式处理uvm_reg

    mask = (1 << width_array[i]) - 1;
    

    通过不使用 `mask` 的 decalration 并在作业中创建掩码,您可以使其成为单行。

    fields_array[i] = ((1 << width_array[i]) - 1) & (apb_word >> lsb_array[i]);
    

    【讨论】:

    • 感谢您的回复。我传递给int 的任务数组。 W/您的解决方案我仍然收到错误:问题在于 width_array[i] 必须是常量,但我需要将其作为参数传递,因为 width 在每个字段之间有所不同。
    • @a_bet 是的,您实际上是正确的。我忽略了它。将更新答案。我有一个解决方案,但可能有人有更好、更有说服力的解决方案:-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多