How to truncate an expression bit width in Verilog?
You can use another variable, though this is not particularly elegant.
wire[31:0] y;
assign y = func(A) ^ func(B);
assign x = y[15:0];
A better approach would be to use a function.
function [15:0] trunc_32_to_16(input [31:0] val32);
trunc_32_to_16 = val32[15:0];
endfunction
assign x = trunc_32_to_16(func(A) ^ func(B));
In your example, you are implicitly truncating bits.
Making the truncation explicit can often remove the warnings in simulation/lint/synthesis.
One way to do this in-line is to use a cast operator, e.g.:
typedef logic [15:0] HALF_WORD;
assign x = HALF_WORD'((func(A) ^ func(B));
This approach may make sense if it is obvious from the context that all the bits being dropped are 0's.
If some of the bits may be nonzero then I would suggest still using an intermediate net like @dwikle suggested in a previous answer, since it makes it more clear that you are actually throwing away bits. Here it is again for reference.
wire[31:0] y;
assign y = func(A) ^ func(B);
assign x = y[15:0];
I think that this might help keep the line count down.
wire [15:0] not_used ;
assign {not_used, x} = (func(A) ^ func(B));
Not sure if that is valid with assigns though.