Takes in a vector of a given input width, a flag denoting if it is a signed/unsigned value, and an output width. Outputs the same vector extended or truncated to the output width, with signed/unsigned extension. There is no guard against truncating so much you lose significant bits.
You would use this to normalize binary integers to the same constant width before doing arithmetic or Boolean operations upon them. The max function is handy for this when you don't know the widths ahead of time (e.g.: when they depend on another module parameter).
`default_nettype none module Width_Adjuster #( parameter WORD_WIDTH_IN = 0, parameter SIGNED = 0, parameter WORD_WIDTH_OUT = 0 ) ( // It's possible some input bits are truncated away // verilator lint_off UNUSED input wire [WORD_WIDTH_IN-1:0] original_input, // verilator lint_on UNUSED output reg [WORD_WIDTH_OUT-1:0] adjusted_output );
Calculate the width difference and handle each possible case:
localparam PAD_WIDTH = WORD_WIDTH_OUT - WORD_WIDTH_IN; generate if (PAD_WIDTH == 0) begin: zero always @(*) begin adjusted_output = original_input; end end if (PAD_WIDTH > 0) begin: sign_extend localparam PAD_ZERO = {PAD_WIDTH{1'b0}}; localparam PAD_ONES = {PAD_WIDTH{1'b1}}; always @(*) begin adjusted_output = ((SIGNED != 0) && (original_input[WORD_WIDTH_IN-1] == 1'b1)) ? {PAD_ONES, original_input} : {PAD_ZERO, original_input}; end end if (PAD_WIDTH < 0) begin: truncate always @(*) begin adjusted_output = original_input [WORD_WIDTH_OUT-1:0]; end end endgenerate endmodule