summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Ettus <matt@ettus.com>2011-05-24 23:32:10 -0700
committerMatt Ettus <matt@ettus.com>2011-06-08 10:55:22 -0700
commitf335b169f791977a2ff17f155f7e0d28c30073fb (patch)
tree52248a72ea69440f118a9287e27a977d92dd0cd3
parente0d0bbb809fc6465fd9e1257a10d09dceab6924c (diff)
downloaduhd-f335b169f791977a2ff17f155f7e0d28c30073fb.tar.gz
uhd-f335b169f791977a2ff17f155f7e0d28c30073fb.tar.bz2
uhd-f335b169f791977a2ff17f155f7e0d28c30073fb.zip
dsp: do everything at 24 bits wide
-rw-r--r--usrp2/sdr_lib/dsp_core_rx.v72
-rw-r--r--usrp2/sdr_lib/dsp_core_rx_tb.v15
-rw-r--r--usrp2/sdr_lib/hb_dec.v116
-rw-r--r--usrp2/sdr_lib/hb_dec_tb.v8
-rw-r--r--usrp2/sdr_lib/input.dat113
5 files changed, 204 insertions, 120 deletions
diff --git a/usrp2/sdr_lib/dsp_core_rx.v b/usrp2/sdr_lib/dsp_core_rx.v
index e5cb95fd9..639744de7 100644
--- a/usrp2/sdr_lib/dsp_core_rx.v
+++ b/usrp2/sdr_lib/dsp_core_rx.v
@@ -30,18 +30,15 @@ module dsp_core_rx
output [31:0] debug
);
- wire [15:0] scale_i, scale_q;
wire [31:0] phase_inc;
reg [31:0] phase;
- wire [35:0] prod_i, prod_q;
wire [24:0] i_cordic, q_cordic;
wire [23:0] i_cordic_clip, q_cordic_clip;
wire [23:0] i_cic, q_cic;
- wire [17:0] i_cic_scaled, q_cic_scaled;
- wire [17:0] i_hb1, q_hb1;
- wire [15:0] i_hb2, q_hb2;
-
+ wire [23:0] i_hb1, q_hb1;
+ wire [23:0] i_hb2, q_hb2;
+
wire strobe_cic, strobe_hb1, strobe_hb2;
wire enable_hb1, enable_hb2;
wire [7:0] cic_decim_rate;
@@ -54,9 +51,11 @@ module dsp_core_rx
(.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr),
.in(set_data),.out(phase_inc),.changed());
+ /*
setting_reg #(.my_addr(BASE+1)) sr_1
(.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr),
.in(set_data),.out({scale_i,scale_q}),.changed());
+ */
setting_reg #(.my_addr(BASE+2), .width(10)) sr_2
(.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr),
@@ -66,6 +65,8 @@ module dsp_core_rx
(.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr),
.in(set_data),.out({realmode,swap_iq}),.changed());
+ // MUX so we can do realmode signals on either input
+
always @(posedge clk)
if(swap_iq)
begin
@@ -77,7 +78,8 @@ module dsp_core_rx
adc_i_mux <= adc_i;
adc_q_mux <= realmode ? 24'd0 : adc_q;
end
-
+
+ // NCO
always @(posedge clk)
if(rst)
phase <= 0;
@@ -86,6 +88,7 @@ module dsp_core_rx
else
phase <= phase + phase_inc;
+ // CORDIC 24-bit I/O
cordic_z24 #(.bitwidth(25))
cordic(.clock(clk), .reset(rst), .enable(run),
.xi({adc_i_mux[23],adc_i_mux}),. yi({adc_q_mux[23],adc_q_mux}), .zi(phase[31:8]),
@@ -93,7 +96,8 @@ module dsp_core_rx
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));
-
+
+ // CIC decimator 24 bit I/O
cic_strober cic_strober(.clock(clk),.reset(rst),.enable(run),.rate(cic_decim_rate),
.strobe_fast(1),.strobe_slow(strobe_cic) );
@@ -107,54 +111,32 @@ module dsp_core_rx
.rate(cic_decim_rate),.strobe_in(1'b1),.strobe_out(strobe_cic),
.signal_in(q_cordic_clip),.signal_out(q_cic));
- wire strobe_cic_d1;
- round_sd #(.WIDTH_IN(24),.WIDTH_OUT(18)) round_icic
- (.clk(clk),.reset(rst), .in(i_cic), .strobe_in(strobe_cic), .out(i_cic_scaled), .strobe_out(strobe_cic_d1));
-
- round_sd #(.WIDTH_IN(24),.WIDTH_OUT(18)) round_qcic
- (.clk(clk),.reset(rst), .in(q_cic), .strobe_in(strobe_cic), .out(q_cic_scaled), .strobe_out());
-
- small_hb_dec #(.WIDTH(18)) small_hb_i
+ // First (small) halfband 24 bit I/O
+ small_hb_dec #(.WIDTH(24)) small_hb_i
(.clk(clk),.rst(rst),.bypass(~enable_hb1),.run(run),
- .stb_in(strobe_cic_d1),.data_in(i_cic_scaled),.stb_out(strobe_hb1),.data_out(i_hb1));
+ .stb_in(strobe_cic),.data_in(i_cic),.stb_out(strobe_hb1),.data_out(i_hb1));
- small_hb_dec #(.WIDTH(18)) small_hb_q
+ small_hb_dec #(.WIDTH(24)) small_hb_q
(.clk(clk),.rst(rst),.bypass(~enable_hb1),.run(run),
- .stb_in(strobe_cic_d1),.data_in(q_cic_scaled),.stb_out(),.data_out(q_hb1));
+ .stb_in(strobe_cic),.data_in(q_cic),.stb_out(),.data_out(q_hb1));
+ // Second (large) halfband 24 bit I/O
wire [8:0] cpi_hb = enable_hb1 ? {cic_decim_rate,1'b0} : {1'b0,cic_decim_rate};
- hb_dec #(.IWIDTH(18), .OWIDTH(16), .CWIDTH(18), .ACCWIDTH(24)) hb_i
+ hb_dec #(.WIDTH(24)) hb_i
(.clk(clk),.rst(rst),.bypass(~enable_hb2),.run(run),.cpi(cpi_hb),
.stb_in(strobe_hb1),.data_in(i_hb1),.stb_out(strobe_hb2),.data_out(i_hb2));
- hb_dec #(.IWIDTH(18), .OWIDTH(16), .CWIDTH(18), .ACCWIDTH(24)) hb_q
+ hb_dec #(.WIDTH(24)) hb_q
(.clk(clk),.rst(rst),.bypass(~enable_hb2),.run(run),.cpi(cpi_hb),
.stb_in(strobe_hb1),.data_in(q_hb1),.stb_out(),.data_out(q_hb2));
- assign sample = {i_hb2,q_hb2};
- assign strobe = strobe_hb2;
+ // Round final answer to 16 bits
+ round_sd #(.WIDTH_IN(24),.WIDTH_OUT(16)) round_i
+ (.clk(clk),.reset(rst), .in(i_hb2),.strobe_in(strobe_hb2), .out(sample[31:16]), .strobe_out(strobe));
+
+ round_sd #(.WIDTH_IN(24),.WIDTH_OUT(16)) round_q
+ (.clk(clk),.reset(rst), .in(q_hb2),.strobe_in(strobe_hb2), .out(sample[15:0]), .strobe_out());
- assign debug = {enable_hb1, enable_hb2, run, strobe, strobe_cic, strobe_cic_d1, strobe_hb1, strobe_hb2};
+ assign debug = {enable_hb1, enable_hb2, run, strobe, strobe_cic, strobe_hb1, strobe_hb2};
endmodule // dsp_core_rx
-
-/*
- MULT18X18S mult_i
- (.P(prod_i), // 36-bit multiplier output
- .A(adc_i_mux), // 18-bit multiplier input
- .B({{2{scale_i[15]}},scale_i}), // 18-bit multiplier input
- .C(clk), // Clock input
- .CE(1), // Clock enable input
- .R(rst) // Synchronous reset input
- );
-
- MULT18X18S mult_q
- (.P(prod_q), // 36-bit multiplier output
- .A(adc_q_mux), // 18-bit multiplier input
- .B({{2{scale_q[15]}},scale_q}), // 18-bit multiplier input
- .C(clk), // Clock input
- .CE(1), // Clock enable input
- .R(rst) // Synchronous reset input
- );
-
-*/
diff --git a/usrp2/sdr_lib/dsp_core_rx_tb.v b/usrp2/sdr_lib/dsp_core_rx_tb.v
index 0f36f1462..c3d9882bc 100644
--- a/usrp2/sdr_lib/dsp_core_rx_tb.v
+++ b/usrp2/sdr_lib/dsp_core_rx_tb.v
@@ -12,19 +12,14 @@ module dsp_core_rx_tb();
initial $dumpfile("dsp_core_rx_tb.vcd");
initial $dumpvars(0,dsp_core_rx_tb);
- reg [17:0] adc_in;
- wire [15:0] adc_out_i, adc_out_q;
+ reg signed [23:0] adc_in;
+ wire signed [15:0] adc_out_i, adc_out_q;
always @(posedge clk)
begin
- if(adc_in[17])
- $write("-%d,",-adc_in);
- else
- $write("%d,",adc_in);
- if(adc_out_i[15])
- $write("-%d\n",-adc_out_i);
- else
- $write("%d\n",adc_out_i);
+ $display(adc_in);
+ $display(adc_out_i);
+ $display(adc_out_q);
end
reg run;
diff --git a/usrp2/sdr_lib/hb_dec.v b/usrp2/sdr_lib/hb_dec.v
index 562e85b6b..8d21c21c0 100644
--- a/usrp2/sdr_lib/hb_dec.v
+++ b/usrp2/sdr_lib/hb_dec.v
@@ -22,17 +22,27 @@
// myfilt = round(2^18 * halfgen4(.7/4,8))
module hb_dec
- #(parameter IWIDTH=18, OWIDTH=18, CWIDTH=18, ACCWIDTH=24)
+ #(parameter WIDTH=24)
(input clk,
input rst,
input bypass,
input run,
input [8:0] cpi, // Clocks per input -- equal to the decimation ratio ahead of this block
input stb_in,
- input [IWIDTH-1:0] data_in,
+ input [WIDTH-1:0] data_in,
output reg stb_out,
- output reg [OWIDTH-1:0] data_out);
+ output reg [WIDTH-1:0] data_out);
+ localparam INTWIDTH = 17;
+ localparam ACCWIDTH = WIDTH + 3;
+
+ // Round off inputs to 17 bits because of 18 bit multipliers
+ wire [INTWIDTH-1:0] data_rnd;
+ wire stb_rnd;
+
+ round_sd #(.WIDTH_IN(WIDTH),.WIDTH_OUT(INTWIDTH)) round_in
+ (.clk(clk),.reset(rst),.in(data_in),.strobe_in(stb_in),.out(data_rnd),.strobe_out(stb_rnd));
+
// Control
reg [3:0] addr_odd_a, addr_odd_b, addr_odd_c, addr_odd_d;
wire write_odd, write_even, do_mult;
@@ -45,16 +55,16 @@ module hb_dec
always @(posedge clk)
if(rst | ~run)
odd <= 0;
- else if(stb_in)
+ else if(stb_rnd)
odd <= ~odd;
- assign write_odd = stb_in & odd;
- assign write_even = stb_in & ~odd;
+ assign write_odd = stb_rnd & odd;
+ assign write_even = stb_rnd & ~odd;
always @(posedge clk)
if(rst | ~run)
phase <= 0;
- else if(stb_in & odd)
+ else if(stb_rnd & odd)
phase <= 1;
else if(phase == 4)
phase <= 0;
@@ -69,7 +79,7 @@ module hb_dec
if(rst)
stb_out_pre <= 0;
else
- stb_out_pre <= {stb_out_pre[14:0],(stb_in & odd)};
+ stb_out_pre <= {stb_out_pre[14:0],(stb_rnd & odd)};
always @*
case(phase)
@@ -93,12 +103,12 @@ module hb_dec
assign clear = stb_out_pre[3];
// Data
- wire [IWIDTH-1:0] data_odd_a, data_odd_b, data_odd_c, data_odd_d;
- wire [IWIDTH-1:0] sum1, sum2;
- wire [OWIDTH:0] final_sum;
- wire [OWIDTH-1:0] final_sum_clip;
- reg [CWIDTH-1:0] coeff1, coeff2;
- wire [35:0] prod1, prod2;
+ wire [INTWIDTH-1:0] data_odd_a, data_odd_b, data_odd_c, data_odd_d;
+ reg [INTWIDTH:0] sum1, sum2; // these are 18-bit inputs to mult
+ reg [WIDTH:0] final_sum;
+ wire [WIDTH-1:0] final_sum_clip;
+ reg [17:0] coeff1, coeff2;
+ wire [35:0] prod1, prod2;
always @* // Outer coeffs
case(phase_d1)
@@ -118,19 +128,19 @@ module hb_dec
default : coeff2 = -6107;
endcase // case(phase)
- srl #(.WIDTH(IWIDTH)) srl_odd_a
- (.clk(clk),.write(write_odd),.in(data_in),.addr(addr_odd_a),.out(data_odd_a));
- srl #(.WIDTH(IWIDTH)) srl_odd_b
- (.clk(clk),.write(write_odd),.in(data_in),.addr(addr_odd_b),.out(data_odd_b));
- srl #(.WIDTH(IWIDTH)) srl_odd_c
- (.clk(clk),.write(write_odd),.in(data_in),.addr(addr_odd_c),.out(data_odd_c));
- srl #(.WIDTH(IWIDTH)) srl_odd_d
- (.clk(clk),.write(write_odd),.in(data_in),.addr(addr_odd_d),.out(data_odd_d));
-
- add2_reg #(.WIDTH(IWIDTH)) add1 (.clk(clk),.in1(data_odd_a),.in2(data_odd_b),.sum(sum1));
- add2_reg #(.WIDTH(IWIDTH)) add2 (.clk(clk),.in1(data_odd_c),.in2(data_odd_d),.sum(sum2));
-
- wire [IWIDTH-1:0] data_even;
+ srl #(.WIDTH(INTWIDTH)) srl_odd_a
+ (.clk(clk),.write(write_odd),.in(data_rnd),.addr(addr_odd_a),.out(data_odd_a));
+ srl #(.WIDTH(INTWIDTH)) srl_odd_b
+ (.clk(clk),.write(write_odd),.in(data_rnd),.addr(addr_odd_b),.out(data_odd_b));
+ srl #(.WIDTH(INTWIDTH)) srl_odd_c
+ (.clk(clk),.write(write_odd),.in(data_rnd),.addr(addr_odd_c),.out(data_odd_c));
+ srl #(.WIDTH(INTWIDTH)) srl_odd_d
+ (.clk(clk),.write(write_odd),.in(data_rnd),.addr(addr_odd_d),.out(data_odd_d));
+
+ always @(posedge clk) sum1 <= {data_odd_a[INTWIDTH-1],data_odd_a} + {data_odd_b[INTWIDTH-1],data_odd_b};
+ always @(posedge clk) sum2 <= {data_odd_c[INTWIDTH-1],data_odd_c} + {data_odd_d[INTWIDTH-1],data_odd_d};
+
+ wire [INTWIDTH-1:0] data_even;
reg [3:0] addr_even;
always @(posedge clk)
@@ -141,53 +151,39 @@ module hb_dec
default : addr_even <= 7;
endcase // case(cpi)
- srl #(.WIDTH(IWIDTH)) srl_even
- (.clk(clk),.write(write_even),.in(data_in),.addr(addr_even),.out(data_even));
-
- localparam MWIDTH = ACCWIDTH-2;
- wire [MWIDTH-1:0] sum_of_prod;
+ srl #(.WIDTH(INTWIDTH)) srl_even
+ (.clk(clk),.write(write_even),.in(data_rnd),.addr(addr_even),.out(data_even));
MULT18X18S mult1(.C(clk), .CE(do_mult), .R(rst), .P(prod1), .A(coeff1), .B(sum1) );
MULT18X18S mult2(.C(clk), .CE(do_mult), .R(rst), .P(prod2), .A(coeff2), .B(sum2) );
- add2_and_round_reg #(.WIDTH(MWIDTH))
- add3 (.clk(clk),.in1(prod1[35:36-MWIDTH]),.in2(prod2[35:36-MWIDTH]),.sum(sum_of_prod));
- wire [ACCWIDTH-1:0] acc_out;
+ reg [35:0] sum_of_prod;
+ always @(posedge clk) sum_of_prod <= prod1 + prod2; // Can't overflow
- acc #(.IWIDTH(MWIDTH),.OWIDTH(ACCWIDTH))
- acc (.clk(clk),.clear(clear),.acc(do_acc),.in(sum_of_prod),.out(acc_out));
+ wire [ACCWIDTH-1:0] acc_out;
+ acc #(.IWIDTH(ACCWIDTH-2),.OWIDTH(ACCWIDTH))
+ acc (.clk(clk),.clear(clear),.acc(do_acc),.in(sum_of_prod[35:38-ACCWIDTH]),.out(acc_out));
- localparam SHIFT_FACTOR = ACCWIDTH-IWIDTH-5;
wire [ACCWIDTH-1:0] data_even_signext;
- wire [ACCWIDTH:0] final_sum_unrounded;
- sign_extend #(.bits_in(IWIDTH),.bits_out(ACCWIDTH-SHIFT_FACTOR))
- signext_data_even (.in(data_even),.out(data_even_signext[ACCWIDTH-1:SHIFT_FACTOR]));
- assign data_even_signext[SHIFT_FACTOR-1:0] = 0;
+ localparam SHIFT_FACTOR = 6;
- add2_reg #(.WIDTH(ACCWIDTH+1))
- final_adder (.clk(clk), .in1({acc_out,1'b0}), .in2({data_even_signext,1'b0}), .sum(final_sum_unrounded));
+ sign_extend #(.bits_in(INTWIDTH),.bits_out(ACCWIDTH-SHIFT_FACTOR)) signext_data_even
+ (.in(data_even),.out(data_even_signext[ACCWIDTH-1:SHIFT_FACTOR]));
+ assign data_even_signext[SHIFT_FACTOR-1:0] = 0;
- wire [OWIDTH-1:0] bypass_data;
- wire stb_final, stb_bypass;
+ always @(posedge clk) final_sum <= acc_out + data_even_signext;
- round_sd #(.WIDTH_IN(ACCWIDTH-3),.WIDTH_OUT(OWIDTH+1))
- final_round (.clk(clk),.reset(rst),
- .in(final_sum_unrounded[ACCWIDTH-4:0]),.strobe_in(stb_out_pre[8]),
- .out(final_sum), .strobe_out(stb_final));
-
- clip #(.bits_in(OWIDTH+1), .bits_out(OWIDTH)) clip (.in(final_sum), .out(final_sum_clip));
+ clip #(.bits_in(WIDTH+1), .bits_out(WIDTH)) clip (.in(final_sum), .out(final_sum_clip));
+
+ // Output MUX to allow for bypass
+ wire selected_stb = bypass ? stb_in : stb_out_pre[8];
- round_sd #(.WIDTH_IN(IWIDTH),.WIDTH_OUT(OWIDTH))
- bypass_round (.clk(clk),.reset(rst),
- .in(data_in),.strobe_in(stb_in),
- .out(bypass_data), .strobe_out(stb_bypass));
-
- // Output
always @(posedge clk)
begin
- stb_out <= bypass ? stb_bypass : stb_final;
- data_out <= bypass ? bypass_data : final_sum_clip;
+ stb_out <= selected_stb;
+ if(selected_stb)
+ data_out <= bypass ? data_in : final_sum_clip;
end
endmodule // hb_dec
diff --git a/usrp2/sdr_lib/hb_dec_tb.v b/usrp2/sdr_lib/hb_dec_tb.v
index ac64f22a7..153cfba76 100644
--- a/usrp2/sdr_lib/hb_dec_tb.v
+++ b/usrp2/sdr_lib/hb_dec_tb.v
@@ -18,7 +18,7 @@
module hb_dec_tb( ) ;
// Parameters for instantiation
- parameter clocks = 9'd2 ; // Number of clocks per input
+ parameter clocks = 9'd12 ; // Number of clocks per input
parameter decim = 1 ; // Sets the filter to decimate
parameter rate = 2 ; // Sets the decimation rate
@@ -26,9 +26,9 @@ module hb_dec_tb( ) ;
reg reset ;
reg enable ;
reg strobe_in ;
- reg signed [17:0] data_in ;
+ reg signed [23:0] data_in ;
wire strobe_out ;
- wire signed [15:0] data_out ;
+ wire signed [23:0] data_out ;
initial
begin
@@ -65,7 +65,7 @@ module hb_dec_tb( ) ;
*/
- hb_dec #(.IWIDTH(18),.OWIDTH(16),.CWIDTH(18),.ACCWIDTH(24)) uut
+ hb_dec #(.WIDTH(24)) uut
(.clk(clock),.rst(reset),.bypass(0),.run(1),.cpi(clocks),.stb_in(strobe_in),.data_in(data_in),
.stb_out(strobe_out),.data_out(data_out) );
diff --git a/usrp2/sdr_lib/input.dat b/usrp2/sdr_lib/input.dat
index 486c0252f..85b5887e8 100644
--- a/usrp2/sdr_lib/input.dat
+++ b/usrp2/sdr_lib/input.dat
@@ -15,7 +15,7 @@
0
0
0
-100000
+8388607
0
0
0
@@ -54,6 +54,117 @@
0
0
0
+8388607
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+8388607
+8388607
+8388607
+8388607
+8388607
+8388607
+8388607
+8388607
+8388607
+8388607
+8388607
+8388607
+8388607
+8388607
+8388607
+8388607
+8388607
+8388607
+8388607
+8388607
+8388607
+8388607
+8388607
+8388607
+8388607
+8388607
+8388607
+8388607
+8388607
+8388607
+8388607
+8388607
+8388607
+8388607
+8388607
+8388607
+8388607
+8388607
+8388607
+8388607
+8388607
+8388607
+8388607
+8388607
+8388607
+8388607
+8388607
+8388607
+8388607
+8388607
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
0
0
0