// round and truncate unit (detecting overflow)

module roundtrunc  ( din, overflow, dout );

	parameter DATAWIDTH = 47;
	parameter FRACT_BIT = 16; // fratcional bits to be rounded (>0) (pos. index of new LSB)
	parameter TRUNC_BIT = 3; // truncate bits at MSB side
	
	localparam POS_MSB = DATAWIDTH-1; // MSB position index
	localparam POS_RUP = FRACT_BIT-1; // round up(/down) deciding position index
	localparam POS_NSN = POS_MSB - TRUNC_BIT; // new sign (MSB) bit position index after trunc
	//	localparam OUTBITSIZE = DATAWIDTH - FRACT_BIT - TRUNC_BIT; // output bit size
	
input  [DATAWIDTH-1:0] din;
output overflow;
output [POS_NSN:FRACT_BIT] dout; // output [OUTBITSIZE-1:0] dout;

// module items

wire roundbit, pos_din;
wire ovf_din, ovf_round;

assign ovf_din = 
		( din[DATAWIDTH-1:POS_NSN] == {(TRUNC_BIT+1){1'b0} } ) ? 1'b0 : // posi. valid
		( din[DATAWIDTH-1:POS_NSN] == {(TRUNC_BIT+1){1'b1} } ) ? 1'b0 : // nega. valid
																1'b1 ; // invalid (overflow)

assign pos_din = ~din[DATAWIDTH-1];
assign roundbit	= din[POS_RUP];

assign dout = din[POS_NSN:FRACT_BIT] + roundbit; // LSB/2 is added
assign ovf_round = ( dout[POS_NSN] & pos_din ) ? 1'b1 : 1'b0 ; // pos. input chagned to neg.

assign overflow = ovf_din | ovf_round ; 

endmodule
