如何使用流运算符投射宏

问题描述 投票:0回答:1
  • 我有 Systemverilog 宏,用于对解压数据进行字节顺序感知解析:

  • 此宏的目的是从字节数组中的 BYTE_OFFSET 偏移量中获取任何 BYTE_WIDTH 字节,并将它们打包到向量中。

我一直在运行较旧的 Modelsim 版本,没有出现任何问题。 最近,我将模拟器更新为 Questa Base 的更新版本,并开始收到此警告(对于调用该宏的文件),尽管功能是正确的。

是否有正确的方法将其编写为宏?

独立使用示例(文件
example.sv
):
`define PARSE_LITTLE_ENDIAN(TARGET, SOURCE, BYTE_OFFSET, BYTE_WIDTH) \
TARGET = $size(TARGET)'({<<8{SOURCE[BYTE_OFFSET +: BYTE_WIDTH]}})

`define PARSE_BIG_ENDIAN(TARGET, SOURCE, BYTE_OFFSET, BYTE_WIDTH) \
TARGET = $size(TARGET)'({>>8{SOURCE[BYTE_OFFSET +: BYTE_WIDTH]}})

class my_parser;

    bit  [64-1:0] body_len;
    logic[8-1:0]  frame_buffer[];

    function void call_macro();

        this.frame_buffer = new[10];

        for (int byte_idx = 0; byte_idx < this.frame_buffer.size(); byte_idx++)
        begin
          this.frame_buffer[byte_idx] = $urandom();
        end

        `PARSE_LITTLE_ENDIAN(this.body_len, this.frame_buffer, 2, 8);
        `PARSE_BIG_ENDIAN(this.body_len, this.frame_buffer, 2, 8);

    endfunction

endclass
编译结果:
vlog -sv example.sv 
Questa Base Edition-64 vlog 2024.1 Compiler 2024.02 Feb  1 2024
Start time: 11:26:42 on Apr 10,2024
vlog -sv example.sv 
-- Compiling package example_sv_unit
** Warning: example.sv(21): (vlog-2960) Streaming concatenation shall not be used as an operand in an expression without first casting it to a bit-stream type.
** Warning: example.sv(22): (vlog-2960) Streaming concatenation shall not be used as an operand in an expression without first casting it to a bit-stream type.

Top level modules:
        --none--
End time: 11:26:42 on Apr 10,2024, Elapsed time: 0:00:00
Errors: 0, Warnings: 2
注意:该代码可以很好地模拟,并且也可以使用 Vivado 很好地构建到 Xilinx FPGA 中。
以下方法不起作用:

$cast(TARGET,{<<BYTE{SOURCE[BYTE_OFFSET +: BYTE_WIDTH]}})
给出相同的警告。

还有

TARGET = $size(TARGET)'($type(TARGET)'({<<BYTE{SOURCE[BYTE_OFFSET +: BYTE_WIDTH]}}))

TARGET = $type(TARGET)'($size(TARGET)'({<<BYTE{SOURCE[BYTE_OFFSET +: BYTE_WIDTH]}}))

出错。

casting system-verilog modelsim questasim
1个回答
0
投票

我不确定您为什么会收到错误消息,但是您显示的代码不需要强制转换为大小,并且删除它可以消除警告消息。

这就是我所说的完整可运行示例的含义:

`define PARSE_LITTLE_ENDIAN(TARGET, SOURCE, BYTE_OFFSET, BYTE_WIDTH) \
TARGET    = {<<8{SOURCE[BYTE_OFFSET +: BYTE_WIDTH]}}
`define PARSE_BIG_ENDIAN(TARGET, SOURCE, BYTE_OFFSET, BYTE_WIDTH) \
  TARGET  = {>>8{SOURCE[BYTE_OFFSET +: BYTE_WIDTH]}}

class my_parser;
    bit  [64-1:0] body_len;
    logic[8-1:0]  frame_buffer[];
    function void call_macro();
       this.frame_buffer = new[10];
       void'(randomize(frame_buffer));
       $displayh("%p",frame_buffer);
        `PARSE_LITTLE_ENDIAN(this.body_len, this.frame_buffer, 2, 8);
       $displayh(body_len);
        `PARSE_BIG_ENDIAN(this.body_len, this.frame_buffer, 2, 8);
       $displayh(body_len);
    endfunction
endclass

module top;
   my_parser p  = new;

   initial p.call_macro();
endmodule
© www.soinside.com 2019 - 2024. All rights reserved.