verilogiverilog

How to select bits in expression?


This my excersize is make a 6-to-64 decoder using 3-to-8 decoder. I've implemented it as below:

module dec_3_8 (
    input wire [2:0] in,
    output wire [7:0] out,
    input en
);

genvar i;
generate
    for (i = 0; i < 8; i = i + 1) 
    begin :gen
        assign out[i] = in == i & en ? 1'b1 : 1'b0;
    end
endgenerate
endmodule

module dec_mul (
    input wire [5:0] in,
    input wire en,
    output wire [63:0] out
);

genvar i;
generate
    for (i = 0; i < 8; i = i + 1) begin : gen
        dec_3_8 dec (.in((in % 8)), .out(out[8*i +: 8]), .en((in >> 3) == i && en));
    end
endgenerate
endmodule

It works as expected, but there is a warning: Port 1 (in) of dec_3_8 expects 3 bits, got 32. So, I tried to select 3 bytes from the expression in % 8 like this:

dec_3_8 dec (.in((in % 8)[2:0]), .out(out[8*i +: 8]), .en((in >> 3) == i && en));

but there is an error: error: invalid port connection expression.

Of cource, I can to do something like this:

wire [32:0] a = in % 8;
dec_3_8 dec (.in(a[2:0]), .out(out[8*i +: 8]), .en((in >> 3) == i && en));

but is it possible to truncate vector in-place?


Solution

  • There is a bit of nuance with the modulus operator because when you apply it on a variable, there is a division operations in the background. Verilog tries to manipulate the widths of both dividend and divisor to make them compatible. This results in this warning.

    If you want to truncate/branch out a vector, you can use an assign operator.

    wire [7:0] original_vector = 8'b11010110; // 8-bit vector
    wire [2:0] truncated_vector;
    
    // Truncate to lower 3 bits
    assign truncated_vector = original_vector[2:0];