diff options
| -rw-r--r-- | usrp2/sdr_lib/round.v | 22 | ||||
| -rw-r--r-- | usrp2/sdr_lib/round_tb.v | 61 | 
2 files changed, 80 insertions, 3 deletions
| diff --git a/usrp2/sdr_lib/round.v b/usrp2/sdr_lib/round.v index 7a137d702..5b83981c6 100644 --- a/usrp2/sdr_lib/round.v +++ b/usrp2/sdr_lib/round.v @@ -2,7 +2,7 @@  //  //  USRP - Universal Software Radio Peripheral  // -//  Copyright (C) 2007 Matt Ettus +//  Copyright (C) 2011 Matt Ettus  //  //  This program is free software; you can redistribute it and/or modify  //  it under the terms of the GNU General Public License as published by @@ -24,12 +24,28 @@  module round    #(parameter bits_in=0, -    parameter bits_out=0) +    parameter bits_out=0, +    parameter round_to_zero=0,       // original behavior +    parameter round_to_nearest=1,    // lowest noise +    parameter trunc=0)               // round to negative infinity      (input [bits_in-1:0] in,       output [bits_out-1:0] out,       output [bits_in-bits_out:0] err); -   assign out = in[bits_in-1:bits_in-bits_out] + (in[bits_in-1] & |in[bits_in-bits_out-1:0]); +   wire 			 round_corr; +   wire 			 round_corr_trunc = 0; +   wire 			 round_corr_rtz = (in[bits_in-1] & |in[bits_in-bits_out-1:0]); +   wire 			 round_corr_nearest = in[bits_in-bits_out-1]; +   wire 			 round_corr_nearest_safe = (~in[bits_in-1] & (&in[bits_in-2:bits_out])) ? 0 : +				 round_corr_nearest; +       +   assign round_corr = round_to_nearest ? round_corr_nearest_safe : +		       trunc ? round_corr_trunc :  +		       round_to_zero ? round_corr_rtz : +		       0;  // default to trunc +       +   assign out = in[bits_in-1:bits_in-bits_out] + round_corr; +        assign err = in - {out,{(bits_in-bits_out){1'b0}}};  endmodule // round diff --git a/usrp2/sdr_lib/round_tb.v b/usrp2/sdr_lib/round_tb.v new file mode 100644 index 000000000..ddc464f4a --- /dev/null +++ b/usrp2/sdr_lib/round_tb.v @@ -0,0 +1,61 @@ +// -*- verilog -*- +// +//  USRP - Universal Software Radio Peripheral +// +//  Copyright (C) 2011 Matt Ettus +// +//  This program is free software; you can redistribute it and/or modify +//  it under the terms of the GNU General Public License as published by +//  the Free Software Foundation; either version 2 of the License, or +//  (at your option) any later version. +// +//  This program is distributed in the hope that it will be useful, +//  but WITHOUT ANY WARRANTY; without even the implied warranty of +//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +//  GNU General Public License for more details. +// +//  You should have received a copy of the GNU General Public License +//  along with this program; if not, write to the Free Software +//  Foundation, Inc., 51 Franklin Street, Boston, MA  02110-1301  USA +// + +// Rounding "macro" +// Keeps the topmost bits, does proper 2s comp round to zero (unbiased truncation) + +module round_tb(); + +   localparam IW=8; +   localparam OW=4; +   localparam EW=IW-OW+1; +    +   reg signed [IW-1:0] in; +   wire signed [OW-1:0] out; +   wire signed [EW-1:0] err; + +   round #(.bits_in(IW), +	   .bits_out(OW), +	   .round_to_zero(0),       // original behavior +	   .round_to_nearest(1),    // lowest noise +	   .trunc(0))               // round to negative infinity +   round (.in(in),.out(out),.err(err)); + +   initial $dumpfile("round_tb.vcd"); +   initial $dumpvars(0,round_tb); + +   wire signed [IW-1:0] out_round = {out,{IW-OW{1'b0}}}; +    +   initial +     begin +	in <= -129; +	#1; +	repeat (260) +	  begin +	     in <= in + 1; +	     #1; +	     $display("In %d, out %d, out_rnd %d, err %d, real err %d",in,out,out_round,-err,out_round-in); +	     #1; +	  end +	$finish; +     end +      +endmodule // round | 
