verilogsystem-verilog

Extend a value with ones in SystemVerilog


When assigning a narrow bit vector to a wider one in SystemVerilog like this:

logic [3:0] narrow;
logic [7:0] wide;
assign wide = narrow;

it will zero-extend narrow. Is there a nice way to one-extend it instead? I do not mean sign-extend, and I don't want to explicitly have to put the size in. I'm thinking something like this:

assign wide = { '1, narrow };

But it doesn't work because you aren't allowed unsized values in a concatenation. Is there a nice solution to this?


Solution

  • Ok I found a convenient way:

    assign wide = ~{~narrow};
    

    If you just do this:

    assign wide = ~narrow;
    

    then rather counter-intuitively SV will zero extend narrow to the width of wide before inverting it. My god do we need a sane SV replacement. Anyway in this case we can use that fact. The {...} concatenation protects the ~narrow inside it from being similarly extended. So this is equivalent to (in a saner language):

    wide = ~(zero_extend(~(narrow)));
    

    which is of course equivalent to one-extending it. It does add back-to-back inverters but if your optimiser can't eliminate those then you have bigger problems.

    Also the "WTF SV?" level is quite high on this so if you do use it, definitely add a comment explaining it!