castingsystem-verilogmodelsimquestasim

How to cast a macro using the streaming operator


I've been running an older Modelsim version with it without issue. Recently I updated the simulator to an updated version of Questa Base, and started receiving this warning, for files calling that macro, although the functionality is correct.

Is there a proper way to write this as a macro?

Self Contained Example of use (file 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
Compilation result:
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
Note: The code simulates well and also builds well into a Xilinx FPGA using Vivado.
The following doesn't work:

$cast(TARGET,{<<BYTE{SOURCE[BYTE_OFFSET +: BYTE_WIDTH]}}) gives the same warning.

And

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

or

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

error out.


Solution

  • I'm not sure why you are getting the error message, but the cast to size is unnecessary with the code you show and removing it gets rid of the warning message.

    Here is what I mean by complete runnable example:

    `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