I have Systemverilog macros for endianess-aware parsing of unpacked data:
The purpose of this macro is to take any BYTE_WIDTH Bytes from an BYTE_OFFSET offset at a Byte array, and pack them into a vector.
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?
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
$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.
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