Description
(Feel free to reassign this, not sure which tag is suitable)
I was trying to invoke verilator manually on a calyx-generated verilog file and got some warnings of the format
%Warning-WIDTHTRUNC: test/decode.v:218:14: Operator ASSIGNW expects 5 bits on the Assign RHS, but Assign RHS's SEL generates 6 bits.
: ... note: In instance 'decode_stage_tb.dut.compute_imm.slice_11_7'
218 | assign out = in[END_IDX:START_IDX];
| ^
referring to
module std_bit_slice #(
parameter IN_WIDTH = 32,
parameter START_IDX = 0,
parameter END_IDX = 31,
parameter OUT_WIDTH = 32
)(
input wire logic [IN_WIDTH-1:0] in,
output logic [OUT_WIDTH-1:0] out
);
assign out = in[END_IDX:START_IDX];
`ifdef VERILATOR
always_comb begin
if (START_IDX < 0 || END_IDX > IN_WIDTH-1)
$error(
"std_bit_slice: Slice range out of bounds\n",
"IN_WIDTH: %0d", IN_WIDTH,
"START_IDX: %0d", START_IDX,
"END_IDX: %0d", END_IDX,
);
end
`endif
endmodule
This seems to imply that slicing arr[A:B]
includes values from arr[A]
up to arr[B]
, instead of up to arr[B-1]
like the docs say.
See pg 144 of this sv spec, which assigns u1.bit_slice[415:408];
to a byte, implying both slice bounds are inclusive.
I may be missing something, but this seems like a discrepancy? It's not an urgent correctness issue because that extra bit gets lopped off due to the out
signal's width obeying the Calyx docs behavior. Easy fix would be either update the docs to say the bounds are inclusive or make the primitive behavior assign out = in[END_IDX-1:START_IDX]
.