Search code examples
system-verilogbit-shiftsigned

Arithmetic right shift on logic (2 dimensional) signal


I am trying to do a Shift Right, Arithmetic (keep sign) on the signal in.

When I set the value in[0] to 16'hbb00, I expect in_sign_extend[0] to be 16'hf760 after it is signed right shifted. But, I notice that the actual result I see on in_sign_extend[0] is 16'h0680.

localparam CHANNELS = 8;
localparam AXI_M_DATA_WIDTH = 32;

logic signed [0:CHANNELS-1]    [AXI_M_DATA_WIDTH/2-1:0] in;
logic signed [0:CHANNELS-1]    [AXI_M_DATA_WIDTH/2-1:0] in_sign_extend;

assign in_sign_extend[0] = (in[0] >>> 3);

I am trying to understand if the in is actually correctly signed. Or am I missing something here.


Solution

  • The part select of a packed array is always unsigned, even when selecting the entire array. Only the variable as a whole reference (in) is signed. You can change your code to

    assign in_sign_extend[0] = (signed'(in[0]) >>> 3);
    

    Or you might prefer to use an unpacked array

    logic signed [AXI_M_DATA_WIDTH/2-1:0] in[CHANNELS];
    logic signed [AXI_M_DATA_WIDTH/2-1:0] in_sign_extend[CHANNELS];
    
    assign in_sign_extend[0] = (in[0] >>> 3);