summaryrefslogtreecommitdiffstats
path: root/fpga/usrp2/sdr_lib
diff options
context:
space:
mode:
authorJosh Blum <josh@joshknows.com>2011-11-07 17:09:07 -0800
committerJosh Blum <josh@joshknows.com>2011-11-07 17:09:07 -0800
commit11f1390bbde65c60f45962acb128cac1ce21e474 (patch)
tree372f2e426781de9885889bec6aa98697006268ec /fpga/usrp2/sdr_lib
parent902818f50bbd486138a7d4cd2ce9ba3661f4a732 (diff)
parentbcb80c5cf9a2117f9d6d22b8e793ea2ecb68ed1f (diff)
downloaduhd-11f1390bbde65c60f45962acb128cac1ce21e474.tar.gz
uhd-11f1390bbde65c60f45962acb128cac1ce21e474.tar.bz2
uhd-11f1390bbde65c60f45962acb128cac1ce21e474.zip
Merge branch 'fpga_master' into uhd_next
Diffstat (limited to 'fpga/usrp2/sdr_lib')
-rw-r--r--fpga/usrp2/sdr_lib/Makefile.srcs3
-rw-r--r--fpga/usrp2/sdr_lib/clip_reg.v14
-rw-r--r--fpga/usrp2/sdr_lib/dsp_core_rx.v6
-rw-r--r--fpga/usrp2/sdr_lib/dspengine_16to8.v221
-rw-r--r--fpga/usrp2/sdr_lib/pipectrl.v66
-rw-r--r--fpga/usrp2/sdr_lib/pipestage.v45
-rw-r--r--fpga/usrp2/sdr_lib/round.v30
-rw-r--r--fpga/usrp2/sdr_lib/round_sd.v5
-rw-r--r--fpga/usrp2/sdr_lib/round_tb.v61
-rw-r--r--fpga/usrp2/sdr_lib/rx_dcoffset.v3
-rw-r--r--fpga/usrp2/sdr_lib/small_hb_int.v4
11 files changed, 445 insertions, 13 deletions
diff --git a/fpga/usrp2/sdr_lib/Makefile.srcs b/fpga/usrp2/sdr_lib/Makefile.srcs
index defbced17..629b92cc8 100644
--- a/fpga/usrp2/sdr_lib/Makefile.srcs
+++ b/fpga/usrp2/sdr_lib/Makefile.srcs
@@ -25,8 +25,11 @@ cordic_z24.v \
cordic_stage.v \
dsp_core_rx.v \
dsp_core_tx.v \
+dspengine_16to8.v \
hb_dec.v \
hb_interp.v \
+pipectrl.v \
+pipestage.v \
round.v \
round_reg.v \
round_sd.v \
diff --git a/fpga/usrp2/sdr_lib/clip_reg.v b/fpga/usrp2/sdr_lib/clip_reg.v
index d5e98d982..9098fd5b8 100644
--- a/fpga/usrp2/sdr_lib/clip_reg.v
+++ b/fpga/usrp2/sdr_lib/clip_reg.v
@@ -23,16 +23,24 @@
module clip_reg
#(parameter bits_in=0,
- parameter bits_out=0)
+ parameter bits_out=0,
+ parameter STROBED=1'b0)
(input clk,
input [bits_in-1:0] in,
- output reg [bits_out-1:0] out);
+ output reg [bits_out-1:0] out,
+ input strobe_in,
+ output reg strobe_out);
wire [bits_out-1:0] temp;
clip #(.bits_in(bits_in),.bits_out(bits_out)) clip (.in(in),.out(temp));
+
+ always @(posedge clk)
+ strobe_out <= strobe_in;
+
always @(posedge clk)
- out <= temp;
+ if(strobe_in | ~STROBED)
+ out <= temp;
endmodule // clip_reg
diff --git a/fpga/usrp2/sdr_lib/dsp_core_rx.v b/fpga/usrp2/sdr_lib/dsp_core_rx.v
index 639744de7..d1c7e238a 100644
--- a/fpga/usrp2/sdr_lib/dsp_core_rx.v
+++ b/fpga/usrp2/sdr_lib/dsp_core_rx.v
@@ -94,8 +94,10 @@ module dsp_core_rx
.xi({adc_i_mux[23],adc_i_mux}),. yi({adc_q_mux[23],adc_q_mux}), .zi(phase[31:8]),
.xo(i_cordic),.yo(q_cordic),.zo() );
- clip_reg #(.bits_in(25), .bits_out(24)) clip_i (.clk(clk), .in(i_cordic), .out(i_cordic_clip));
- clip_reg #(.bits_in(25), .bits_out(24)) clip_q (.clk(clk), .in(q_cordic), .out(q_cordic_clip));
+ clip_reg #(.bits_in(25), .bits_out(24)) clip_i
+ (.clk(clk), .in(i_cordic), .strobe_in(1'b1), .out(i_cordic_clip));
+ clip_reg #(.bits_in(25), .bits_out(24)) clip_q
+ (.clk(clk), .in(q_cordic), .strobe_in(1'b1), .out(q_cordic_clip));
// CIC decimator 24 bit I/O
cic_strober cic_strober(.clock(clk),.reset(rst),.enable(run),.rate(cic_decim_rate),
diff --git a/fpga/usrp2/sdr_lib/dspengine_16to8.v b/fpga/usrp2/sdr_lib/dspengine_16to8.v
new file mode 100644
index 000000000..53c5d29da
--- /dev/null
+++ b/fpga/usrp2/sdr_lib/dspengine_16to8.v
@@ -0,0 +1,221 @@
+
+// Copyright 2011 Ettus Research LLC
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+//
+
+module dspengine_16to8
+ #(parameter BASE = 0,
+ parameter BUF_SIZE = 9)
+ (input clk, input reset, input clear,
+ input set_stb, input [7:0] set_addr, input [31:0] set_data,
+
+ output access_we,
+ output access_stb,
+ input access_ok,
+ output access_done,
+ output access_skip_read,
+ output [BUF_SIZE-1:0] access_adr,
+ input [BUF_SIZE-1:0] access_len,
+ output [35:0] access_dat_o,
+ input [35:0] access_dat_i
+ );
+
+ wire convert;
+ wire [17:0] scale_factor;
+
+ setting_reg #(.my_addr(BASE),.width(19)) sr_16to8
+ (.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr),
+ .in(set_data),.out({convert,scale_factor}),.changed());
+
+ reg [2:0] dsp_state;
+ localparam DSP_IDLE = 0;
+ localparam DSP_PARSE_HEADER = 1;
+ localparam DSP_CONVERT = 2;
+ localparam DSP_CONVERT_DRAIN_PIPE = 3;
+ localparam DSP_READ_TRAILER = 4;
+ localparam DSP_WRITE_TRAILER = 5;
+ localparam DSP_WRITE_HEADER = 6;
+ localparam DSP_DONE = 7;
+
+ // Parse VITA header
+ wire is_if_data = (access_dat_i[31:29] == 3'b000);
+ wire has_streamid = access_dat_i[28];
+ wire has_classid = access_dat_i[27];
+ wire has_trailer = access_dat_i[26];
+ // 25:24 reserved, aka SOB/EOB
+ wire has_secs = |access_dat_i[23:22];
+ wire has_tics = |access_dat_i[21:20];
+ wire [3:0] hdr_length = 1 + has_streamid + has_classid + has_classid + has_secs + has_tics + has_tics;
+
+ wire [35:0] prod_i, prod_q;
+ wire [15:0] scaled_i, scaled_q;
+ wire [7:0] i8, q8;
+ reg [7:0] i8_reg, q8_reg;
+ wire stb_read, stb_mult, stb_clip, stb_round, val_read, val_mult, val_clip, val_round;
+ wire stb_out, stb_reg;
+ reg even;
+
+ reg [BUF_SIZE-1:0] read_adr, write_adr;
+ reg has_trailer_reg;
+
+ wire last = (read_adr + 1) == (access_len - has_trailer_reg);
+ wire last_o, even_o;
+
+ wire stb_write = stb_out & (even_o | last_o);
+ wire send_to_pipe = ~stb_write & (dsp_state == DSP_CONVERT);
+ reg [31:0] new_header, new_trailer, trailer_mask;
+ reg [15:0] length;
+ reg wait_for_trailer;
+
+ always @(posedge clk)
+ if(reset | clear)
+ dsp_state <= DSP_IDLE;
+ else
+ case(dsp_state)
+ DSP_IDLE :
+ begin
+ read_adr <= 0;
+ write_adr <= 0;
+ even <= 0;
+ if(access_ok)
+ dsp_state <= DSP_PARSE_HEADER;
+ end
+
+ DSP_PARSE_HEADER :
+ begin
+ has_trailer_reg <= has_trailer;
+ new_header[31:16] <= access_dat_i[31:16];
+ new_header[15:0] <= access_len;
+ length <= access_len;
+ if(is_if_data & convert)
+ begin
+ read_adr <= hdr_length;
+ write_adr <= hdr_length;
+ dsp_state <= DSP_CONVERT;
+ end
+ else
+ dsp_state <= DSP_WRITE_HEADER;
+ end
+
+ DSP_CONVERT:
+ begin
+ new_header[26] <= 1'b1; // all converted packets have a trailer
+ if(stb_write)
+ write_adr <= write_adr + 1;
+ else if(stb_read) // should always be 1 if we are here
+ begin
+ read_adr <= read_adr + 1;
+ even <= ~even;
+ if(last)
+ begin
+ dsp_state <= DSP_CONVERT_DRAIN_PIPE;
+ if(~even)
+ trailer_mask <= 32'h00400400;
+ else
+ trailer_mask <= 32'h00400000;
+ end
+ end
+ end
+
+ DSP_CONVERT_DRAIN_PIPE :
+ if(stb_write)
+ begin
+ write_adr <= write_adr + 1;
+ if(last_o)
+ if(has_trailer_reg)
+ begin
+ dsp_state <= DSP_READ_TRAILER;
+ wait_for_trailer <= 0;
+ end
+ else
+ begin
+ dsp_state <= DSP_WRITE_TRAILER;
+ new_trailer <= trailer_mask;
+ end
+ end
+
+ DSP_READ_TRAILER :
+ begin
+ wait_for_trailer <= 1;
+ if(wait_for_trailer)
+ dsp_state <= DSP_WRITE_TRAILER;
+ new_trailer <= access_dat_i[31:0] | trailer_mask;
+ end
+
+ DSP_WRITE_TRAILER :
+ begin
+ dsp_state <= DSP_WRITE_HEADER;
+ write_adr <= 0;
+ new_header[15:0] <= write_adr + 1;
+ end
+
+ DSP_WRITE_HEADER :
+ dsp_state <= DSP_DONE;
+
+ DSP_DONE :
+ begin
+ read_adr <= 0;
+ write_adr <= 0;
+ dsp_state <= DSP_IDLE;
+ end
+ endcase // case (dsp_state)
+
+ assign access_skip_read = 0;
+ assign access_done = (dsp_state == DSP_DONE);
+
+ assign access_stb = 1;
+
+ assign access_we = (dsp_state == DSP_WRITE_HEADER) |
+ (dsp_state == DSP_WRITE_TRAILER) |
+ stb_write;
+
+ assign access_dat_o = (dsp_state == DSP_WRITE_HEADER) ? { 4'h1, new_header } :
+ (dsp_state == DSP_WRITE_TRAILER) ? { 4'h2, new_trailer } :
+ (last_o&~even_o) ? {4'h0, 16'd0, i8, q8 } :
+ {4'h0, i8, q8, i8_reg, q8_reg };
+
+ assign access_adr = (stb_write|(dsp_state == DSP_WRITE_HEADER)|(dsp_state == DSP_WRITE_TRAILER)) ? write_adr : read_adr;
+
+ // DSP Pipeline
+
+ wire [15:0] i16 = access_dat_i[31:16];
+ wire [15:0] q16 = access_dat_i[15:0];
+
+ pipectrl #(.STAGES(4), .TAGWIDTH(2)) pipectrl
+ (.clk(clk), .reset(reset),
+ .src_rdy_i(send_to_pipe), .dst_rdy_o(), // dst_rdy_o will always be 1 since dst_rdy_i is 1, below
+ .src_rdy_o(stb_out), .dst_rdy_i(1), // always accept output of chain
+ .strobes({stb_round,stb_clip,stb_mult,stb_read}), .valids({val_round,val_clip,val_mult,val_read}),
+ .tag_i({last,even}), .tag_o({last_o,even_o}));
+
+ always @(posedge clk)
+ if(stb_out & ~even_o)
+ {i8_reg,q8_reg} <= {i8,q8};
+
+ MULT18X18S mult_i
+ (.P(prod_i), .A(scale_factor), .B({i16,2'b00}), .C(clk), .CE(stb_mult), .R(reset) );
+ clip_reg #(.bits_in(24),.bits_out(16),.STROBED(1)) clip_i
+ (.clk(clk), .in(prod_i[35:12]), .out(scaled_i), .strobe_in(stb_clip), .strobe_out());
+ round_sd #(.WIDTH_IN(16),.WIDTH_OUT(8),.DISABLE_SD(1)) round_i
+ (.clk(clk), .reset(reset), .in(scaled_i), .strobe_in(stb_round), .out(i8), .strobe_out());
+
+ MULT18X18S mult_q
+ (.P(prod_q), .A(scale_factor), .B({q16,2'b00}), .C(clk), .CE(stb_mult), .R(reset) );
+ clip_reg #(.bits_in(24),.bits_out(16),.STROBED(1)) clip_q
+ (.clk(clk), .in(prod_q[35:12]), .out(scaled_q), .strobe_in(stb_clip), .strobe_out());
+ round_sd #(.WIDTH_IN(16),.WIDTH_OUT(8),.DISABLE_SD(1)) round_q
+ (.clk(clk), .reset(reset), .in(scaled_q), .strobe_in(stb_round), .out(q8), .strobe_out());
+
+endmodule // dspengine_16to8
diff --git a/fpga/usrp2/sdr_lib/pipectrl.v b/fpga/usrp2/sdr_lib/pipectrl.v
new file mode 100644
index 000000000..85d0ce04f
--- /dev/null
+++ b/fpga/usrp2/sdr_lib/pipectrl.v
@@ -0,0 +1,66 @@
+//
+// Copyright 2011 Ettus Research LLC
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+//
+
+// Control DSP pipeline with 1 cycle per stage. Minimum 2 stages or this won't work
+module pipectrl
+ #(parameter STAGES = 2,
+ parameter TAGWIDTH = 1)
+ (input clk,
+ input reset,
+ input src_rdy_i,
+ output dst_rdy_o,
+ output src_rdy_o,
+ input dst_rdy_i,
+ output [STAGES-1:0] strobes,
+ output [STAGES-1:0] valids,
+ input [TAGWIDTH-1:0] tag_i,
+ output [TAGWIDTH-1:0] tag_o);
+
+ wire new_input = src_rdy_i & dst_rdy_o;
+ wire new_output = src_rdy_o & dst_rdy_i;
+ wire [TAGWIDTH-1:0] tags [STAGES-1:0];
+
+ assign dst_rdy_o = ~valids[0] | strobes[1];
+
+ pipestage #(.TAGWIDTH(TAGWIDTH)) head
+ (.clk(clk),.reset(reset), .stb_in(strobes[0]), .stb_out(strobes[1]),.valid(valids[0]),
+ .tag_in(tag_i), .tag_out(tags[0]));
+ assign strobes[0] = src_rdy_i & (~valids[0] | strobes[1]);
+
+ genvar i;
+ generate
+ for(i = 1; i < STAGES - 1; i = i + 1)
+ begin : gen_stages
+ pipestage #(.TAGWIDTH(TAGWIDTH)) pipestage
+ (.clk(clk),.reset(reset), .stb_in(strobes[i]),.stb_out(strobes[i+1]),.valid(valids[i]),
+ .tag_in(tags[i-1]),.tag_out(tags[i]));
+ assign strobes[i] = valids[i-1] & (~valids[i] | strobes[i+1]);
+ end
+ endgenerate
+
+ pipestage #(.TAGWIDTH(TAGWIDTH)) tail
+ (.clk(clk),.reset(reset), .stb_in(strobes[STAGES-1]), .stb_out(dst_rdy_i),.valid(valids[STAGES-1]),
+ .tag_in(tags[STAGES-2]), .tag_out(tags[STAGES-1]));
+ assign strobes[STAGES-1] = valids[STAGES-2] & (~valids[STAGES-1] | new_output);
+
+ assign src_rdy_o = valids[STAGES-1];
+
+ assign tag_o = tags[STAGES-1];
+
+endmodule // pipectrl
+
+
diff --git a/fpga/usrp2/sdr_lib/pipestage.v b/fpga/usrp2/sdr_lib/pipestage.v
new file mode 100644
index 000000000..011afb1ba
--- /dev/null
+++ b/fpga/usrp2/sdr_lib/pipestage.v
@@ -0,0 +1,45 @@
+//
+// Copyright 2011 Ettus Research LLC
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+//
+
+module pipestage
+ #(parameter TAGWIDTH = 1)
+ (input clk,
+ input reset,
+ input stb_in,
+ input stb_out,
+ output reg valid,
+ input [TAGWIDTH-1:0] tag_in,
+ output reg [TAGWIDTH-1:0] tag_out);
+
+ always @(posedge clk)
+ if(reset)
+ begin
+ valid <= 0;
+ tag_out <= 0;
+ end
+ else if(stb_in)
+ begin
+ valid <= 1;
+ tag_out <= tag_in;
+ end
+ else if(stb_out)
+ begin
+ valid <= 0;
+ tag_out <= 0;
+ end
+
+endmodule // pipestage
diff --git a/fpga/usrp2/sdr_lib/round.v b/fpga/usrp2/sdr_lib/round.v
index 7a137d702..26d5a4cf4 100644
--- a/fpga/usrp2/sdr_lib/round.v
+++ b/fpga/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,36 @@
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,round_corr_trunc,round_corr_rtz,round_corr_nearest,round_corr_nearest_safe;
+
+ assign round_corr_trunc = 0;
+ assign round_corr_rtz = (in[bits_in-1] & |in[bits_in-bits_out-1:0]);
+ assign round_corr_nearest = in[bits_in-bits_out-1];
+
+ generate
+ if(bits_in-bits_out > 1)
+ assign round_corr_nearest_safe = (~in[bits_in-1] & (&in[bits_in-2:bits_out])) ? 0 :
+ round_corr_nearest;
+ else
+ assign round_corr_nearest_safe = round_corr_nearest;
+ endgenerate
+
+
+ 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/fpga/usrp2/sdr_lib/round_sd.v b/fpga/usrp2/sdr_lib/round_sd.v
index aeeb3502f..94584f6ef 100644
--- a/fpga/usrp2/sdr_lib/round_sd.v
+++ b/fpga/usrp2/sdr_lib/round_sd.v
@@ -2,7 +2,8 @@
module round_sd
#(parameter WIDTH_IN=18,
- parameter WIDTH_OUT=16)
+ parameter WIDTH_OUT=16,
+ parameter DISABLE_SD=0)
(input clk, input reset,
input [WIDTH_IN-1:0] in, input strobe_in,
output [WIDTH_OUT-1:0] out, output strobe_out);
@@ -15,7 +16,7 @@ module round_sd
sign_extend #(.bits_in(ERR_WIDTH),.bits_out(WIDTH_IN)) ext_err (.in(err), .out(err_ext));
add2_and_clip_reg #(.WIDTH(WIDTH_IN)) add2_and_clip_reg
- (.clk(clk), .rst(reset), .in1(in), .in2(err_ext), .strobe_in(strobe_in), .sum(sum), .strobe_out(strobe_out));
+ (.clk(clk), .rst(reset), .in1(in), .in2((DISABLE_SD == 0) ? err_ext : 0), .strobe_in(strobe_in), .sum(sum), .strobe_out(strobe_out));
round #(.bits_in(WIDTH_IN),.bits_out(WIDTH_OUT)) round_sum (.in(sum), .out(out), .err(err));
diff --git a/fpga/usrp2/sdr_lib/round_tb.v b/fpga/usrp2/sdr_lib/round_tb.v
new file mode 100644
index 000000000..ddc464f4a
--- /dev/null
+++ b/fpga/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
diff --git a/fpga/usrp2/sdr_lib/rx_dcoffset.v b/fpga/usrp2/sdr_lib/rx_dcoffset.v
index 9840e9e1f..04d7795c0 100644
--- a/fpga/usrp2/sdr_lib/rx_dcoffset.v
+++ b/fpga/usrp2/sdr_lib/rx_dcoffset.v
@@ -42,8 +42,9 @@ module rx_dcoffset
end
else if(set_now)
begin
- //integrator <= {set_data[30:0],{(31-int_width){1'b0}}};
fixed <= set_data[31];
+ if(set_data[30])
+ integrator <= {set_data[29:0],{(int_width-30){1'b0}}};
end
else if(~fixed)
integrator <= integrator + {{(alpha_shift){out[WIDTH-1]}},out};
diff --git a/fpga/usrp2/sdr_lib/small_hb_int.v b/fpga/usrp2/sdr_lib/small_hb_int.v
index 387f9e1cb..b69c45413 100644
--- a/fpga/usrp2/sdr_lib/small_hb_int.v
+++ b/fpga/usrp2/sdr_lib/small_hb_int.v
@@ -73,8 +73,8 @@ module small_hb_int
final_round (.clk(clk),.in(accum),.out(accum_rnd));
wire [WIDTH-1:0] clipped;
- clip_reg #(.bits_in(WIDTH+3),.bits_out(WIDTH))
- final_clip (.clk(clk),.in(accum_rnd),.out(clipped));
+ clip_reg #(.bits_in(WIDTH+3),.bits_out(WIDTH)) final_clip
+ (.clk(clk),.in(accum_rnd),.strobe_in(1'b1), .out(clipped));
reg [WIDTH-1:0] saved, saved_d3;
always @(posedge clk)