This question is related to article on rounding found here.
The "Convergent rounding: Round half to even" code is written as follows:
assign w_convergent = i_data[(IWID-1):0]
+ { {(OWID){1'b0}},
i_data[(IWID-OWID)],
{(IWID-OWID-1){!i_data[(IWID-OWID)]}}};
always @(posedge i_clk)
o_convergent <= w_convergent[(IWID-1):(IWID-OWID)];
I am not able to understand what exactly the following lines are doing and why they are required:
+ { {(OWID){1'b0}},
i_data[(IWID-OWID)],
{(IWID-OWID-1){!i_data[(IWID-OWID)]}}};
EDIT:
There are three things that are confusing me about this,
(1) Why is there no IF statement to accomodate the case where the input is exactly half-way e.g 1.5, 2.5 e.t.c.
(2) Why do we need the third part {(IWID-OWID-1){!i_data[(IWID-OWID)]}}, aren't these bits always supposed to be 0?
(3) Since SystemVerilog can easily add two logic vectors together when they have different size, why do we need the {(OWID){1'b0}}?