diff options
-rw-r--r-- | usrp2/sdr_lib/dsp_core_rx.v | 72 | ||||
-rw-r--r-- | usrp2/sdr_lib/dsp_core_rx_tb.v | 15 | ||||
-rw-r--r-- | usrp2/sdr_lib/hb_dec.v | 116 | ||||
-rw-r--r-- | usrp2/sdr_lib/hb_dec_tb.v | 8 | ||||
-rw-r--r-- | usrp2/sdr_lib/input.dat | 113 |
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 |