From d7a3b89d4f7fea444602b0f8ff52029b0efa835f Mon Sep 17 00:00:00 2001 From: Matt Ettus Date: Fri, 3 Jun 2011 16:18:48 -0700 Subject: dsp: added tx_frontend, instantiated in u2/u2p --- usrp2/sdr_lib/tx_frontend.v | 54 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 usrp2/sdr_lib/tx_frontend.v (limited to 'usrp2/sdr_lib/tx_frontend.v') diff --git a/usrp2/sdr_lib/tx_frontend.v b/usrp2/sdr_lib/tx_frontend.v new file mode 100644 index 000000000..2817c1510 --- /dev/null +++ b/usrp2/sdr_lib/tx_frontend.v @@ -0,0 +1,54 @@ + +module tx_frontend + #(parameter BASE=0) + (input clk, input rst, + input set_stb, input [7:0] set_addr, input [31:0] set_data, + input [23:0] tx_i, input [23:0] tx_q, input run, + output reg [15:0] dac_a, output reg [15:0] dac_b + ); + + // IQ balance --> DC offset --> rounding --> mux + + wire [23:0] i_dco, q_dco, i_ofs, q_ofs; + wire [15:0] i_final, q_final; + wire [7:0] mux_ctrl; + + setting_reg #(.my_addr(BASE+0), .width(24)) sr_0 + (.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr), + .in(set_data),.out(i_dco),.changed()); + + setting_reg #(.my_addr(BASE+1), .width(24)) sr_1 + (.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr), + .in(set_data),.out(q_dco),.changed()); + + setting_reg #(.my_addr(BASE+2), .width(4)) sr_2 + (.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr), + .in(set_data),.out(mux_ctrl),.changed()); + + add2_and_clip_reg #(.WIDTH(24)) add_dco_i + (.clk(clk), .rst(rst), .in1(i_dco), .in2(tx_i), .strobe_in(1'b1), .sum(i_ofs), .strobe_out()); + + add2_and_clip_reg #(.WIDTH(24)) add_dco_q + (.clk(clk), .rst(rst), .in1(q_dco), .in2(tx_q), .strobe_in(1'b1), .sum(q_ofs), .strobe_out()); + + round_sd #(.WIDTH_IN(24),.WIDTH_OUT(16)) round_i + (.clk(clk), .reset(rst), .in(i_ofs),.strobe_in(1'b1), .out(i_final), .strobe_out()); + + round_sd #(.WIDTH_IN(24),.WIDTH_OUT(16)) round_q + (.clk(clk), .reset(rst), .in(q_ofs),.strobe_in(1'b1), .out(q_final), .strobe_out()); + + always @(posedge clk) + case(mux_ctrl[3:0]) + 0 : dac_a <= i_final; + 1 : dac_a <= q_final; + default : dac_a <= 0; + endcase // case (mux_ctrl[3:0]) + + always @(posedge clk) + case(mux_ctrl[7:4]) + 0 : dac_b <= i_final; + 1 : dac_b <= q_final; + default : dac_b <= 0; + endcase // case (mux_ctrl[7:4]) + +endmodule // tx_frontend -- cgit v1.2.3 From 9613e9d9f4dce93a090c2b94f24135a4e06653ee Mon Sep 17 00:00:00 2001 From: Matt Ettus Date: Sun, 12 Jun 2011 21:32:38 -0700 Subject: dsp: implement iqbal on tx --- usrp2/sdr_lib/tx_dcoffset.v | 26 -------------------------- usrp2/sdr_lib/tx_frontend.v | 39 +++++++++++++++++++++++++++++++++++---- 2 files changed, 35 insertions(+), 30 deletions(-) delete mode 100644 usrp2/sdr_lib/tx_dcoffset.v (limited to 'usrp2/sdr_lib/tx_frontend.v') diff --git a/usrp2/sdr_lib/tx_dcoffset.v b/usrp2/sdr_lib/tx_dcoffset.v deleted file mode 100644 index 737693611..000000000 --- a/usrp2/sdr_lib/tx_dcoffset.v +++ /dev/null @@ -1,26 +0,0 @@ - -// TX DC offset. Setting is 8 fractional bits, 8 integer bits - -module tx_dcoffset - #(parameter WIDTH_IN=16, - parameter WIDTH_OUT=16, - parameter ADDR=8'd0) - (input clk, input rst, - input set_stb, input [7:0] set_addr, input [31:0] set_data, - input [WIDTH_IN-1:0] in, output [WIDTH_OUT-1:0] out); - - wire [15:0] dco; - wire [WIDTH_IN+8-1:0] dco_ext, sum; - - setting_reg #(.my_addr(ADDR),.width(16)) sr_0 - (.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr),.in(set_data),.out(dco)); - - sign_extend #(.bits_in(16),.bits_out(WIDTH_IN+8)) ext_err (.in(dco), .out(dco_ext)); - - add2_and_clip_reg #(.WIDTH(WIDTH_IN+8)) add2_and_clip_reg - (.clk(clk), .rst(rst), .in1({in,8'd0}), .in2(dco_ext), .strobe_in(1'b1), .sum(sum), .strobe_out()); - - round_sd #(.WIDTH_IN(WIDTH_IN+8),.WIDTH_OUT(WIDTH_OUT)) round_sd - (.clk(clk), .reset(rst), .in(sum), .strobe_in(1'b1), .out(out), .strobe_out()); - -endmodule // rx_dcoffset diff --git a/usrp2/sdr_lib/tx_frontend.v b/usrp2/sdr_lib/tx_frontend.v index 2817c1510..82476ad0d 100644 --- a/usrp2/sdr_lib/tx_frontend.v +++ b/usrp2/sdr_lib/tx_frontend.v @@ -12,6 +12,9 @@ module tx_frontend wire [23:0] i_dco, q_dco, i_ofs, q_ofs; wire [15:0] i_final, q_final; wire [7:0] mux_ctrl; + wire [35:0] corr_i, corr_q; + wire [23:0] i_bal, q_bal; + wire [17:0] mag_corr, phase_corr; setting_reg #(.my_addr(BASE+0), .width(24)) sr_0 (.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr), @@ -21,22 +24,50 @@ module tx_frontend (.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr), .in(set_data),.out(q_dco),.changed()); - setting_reg #(.my_addr(BASE+2), .width(4)) sr_2 + setting_reg #(.my_addr(BASE+2),.width(18)) sr_2 + (.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr), + .in(set_data),.out(mag_corr),.changed()); + + setting_reg #(.my_addr(BASE+3),.width(18)) sr_3 + (.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr), + .in(set_data),.out(phase_corr),.changed()); + + setting_reg #(.my_addr(BASE+4), .width(8)) sr_4 (.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr), .in(set_data),.out(mux_ctrl),.changed()); + // IQ Balance + MULT18X18S mult_mag_corr + (.P(corr_i), .A(tx_i[23:6]), .B(mag_corr), .C(clk), .CE(1), .R(rst) ); + + MULT18X18S mult_phase_corr + (.P(corr_q), .A(tx_i[23:6]), .B(phase_corr), .C(clk), .CE(1), .R(rst) ); + + add2_and_clip_reg #(.WIDTH(24)) add_clip_i + (.clk(clk), .rst(rst), + .in1(tx_i), .in2({{4{corr_i[35]}},corr_i[35:16]}), .strobe_in(1'b1), + .sum(i_bal), .strobe_out()); + + add2_and_clip_reg #(.WIDTH(24)) add_clip_q + (.clk(clk), .rst(rst), + .in1(tx_q), .in2({{4{corr_q[35]}},corr_q[35:16]}), .strobe_in(1'b1), + .sum(q_bal), .strobe_out()); + + // DC Offset add2_and_clip_reg #(.WIDTH(24)) add_dco_i - (.clk(clk), .rst(rst), .in1(i_dco), .in2(tx_i), .strobe_in(1'b1), .sum(i_ofs), .strobe_out()); + (.clk(clk), .rst(rst), .in1(i_dco), .in2(i_bal), .strobe_in(1'b1), .sum(i_ofs), .strobe_out()); add2_and_clip_reg #(.WIDTH(24)) add_dco_q - (.clk(clk), .rst(rst), .in1(q_dco), .in2(tx_q), .strobe_in(1'b1), .sum(q_ofs), .strobe_out()); - + (.clk(clk), .rst(rst), .in1(q_dco), .in2(q_bal), .strobe_in(1'b1), .sum(q_ofs), .strobe_out()); + + // Rounding round_sd #(.WIDTH_IN(24),.WIDTH_OUT(16)) round_i (.clk(clk), .reset(rst), .in(i_ofs),.strobe_in(1'b1), .out(i_final), .strobe_out()); round_sd #(.WIDTH_IN(24),.WIDTH_OUT(16)) round_q (.clk(clk), .reset(rst), .in(q_ofs),.strobe_in(1'b1), .out(q_final), .strobe_out()); + // Mux always @(posedge clk) case(mux_ctrl[3:0]) 0 : dac_a <= i_final; -- cgit v1.2.3 From 948b90267866ceada3aef7960d9d7f6292e68f19 Mon Sep 17 00:00:00 2001 From: Matt Ettus Date: Tue, 14 Jun 2011 20:58:51 -0700 Subject: u1e-dsp: attach tx dc offset and iq balance --- usrp2/sdr_lib/tx_frontend.v | 9 +++++---- usrp2/top/E1x0/u1e_core.v | 15 +++++++++------ 2 files changed, 14 insertions(+), 10 deletions(-) (limited to 'usrp2/sdr_lib/tx_frontend.v') diff --git a/usrp2/sdr_lib/tx_frontend.v b/usrp2/sdr_lib/tx_frontend.v index 82476ad0d..283ed451e 100644 --- a/usrp2/sdr_lib/tx_frontend.v +++ b/usrp2/sdr_lib/tx_frontend.v @@ -1,10 +1,11 @@ module tx_frontend - #(parameter BASE=0) + #(parameter BASE=0, + parameter WIDTH_OUT=16) (input clk, input rst, input set_stb, input [7:0] set_addr, input [31:0] set_data, input [23:0] tx_i, input [23:0] tx_q, input run, - output reg [15:0] dac_a, output reg [15:0] dac_b + output reg [WIDTH_OUT-1:0] dac_a, output reg [WIDTH_OUT-1:0] dac_b ); // IQ balance --> DC offset --> rounding --> mux @@ -61,10 +62,10 @@ module tx_frontend (.clk(clk), .rst(rst), .in1(q_dco), .in2(q_bal), .strobe_in(1'b1), .sum(q_ofs), .strobe_out()); // Rounding - round_sd #(.WIDTH_IN(24),.WIDTH_OUT(16)) round_i + round_sd #(.WIDTH_IN(24),.WIDTH_OUT(WIDTH_OUT)) round_i (.clk(clk), .reset(rst), .in(i_ofs),.strobe_in(1'b1), .out(i_final), .strobe_out()); - round_sd #(.WIDTH_IN(24),.WIDTH_OUT(16)) round_q + round_sd #(.WIDTH_IN(24),.WIDTH_OUT(WIDTH_OUT)) round_q (.clk(clk), .reset(rst), .in(q_ofs),.strobe_in(1'b1), .out(q_final), .strobe_out()); // Mux diff --git a/usrp2/top/E1x0/u1e_core.v b/usrp2/top/E1x0/u1e_core.v index e038b78b8..3d5dced29 100644 --- a/usrp2/top/E1x0/u1e_core.v +++ b/usrp2/top/E1x0/u1e_core.v @@ -223,7 +223,7 @@ module u1e_core // /////////////////////////////////////////////////////////////////////////////////// // DSP TX - wire [15:0] tx_i_int, tx_q_int; + wire [23:0] tx_i_int, tx_q_int; wire run_tx; vita_tx_chain #(.BASE_CTRL(SR_TX_CTRL), .BASE_DSP(SR_TX_DSP), @@ -236,13 +236,16 @@ module u1e_core .vita_time(vita_time), .tx_data_i(tx_data), .tx_src_rdy_i(tx_src_rdy), .tx_dst_rdy_o(tx_dst_rdy), .err_data_o(tx_err_data), .err_src_rdy_o(tx_err_src_rdy), .err_dst_rdy_i(tx_err_dst_rdy), - .dac_a(tx_i_int),.dac_b(tx_q_int), + .tx_i(tx_i_int),.tx_q(tx_q_int), .underrun(tx_underrun_dsp), .run(run_tx), .debug(debug_vt)); - - assign tx_i = tx_i_int[15:2]; - assign tx_q = tx_q_int[15:2]; - + + tx_frontend #(.BASE(SR_TX_FRONT), .WIDTH_OUT(14)) tx_frontend + (.clk(dsp_clk), .rst(dsp_rst), + .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data), + .tx_i(tx_i_int), .tx_q(tx_q_int), .run(1'b1), + .dac_a(tx_i), .dac_b(tx_q)); + // ///////////////////////////////////////////////////////////////////////////////////// // Wishbone Intercon, single master wire [dw-1:0] s0_dat_mosi, s1_dat_mosi, s0_dat_miso, s1_dat_miso, s2_dat_mosi, s3_dat_mosi, s2_dat_miso, s3_dat_miso, -- cgit v1.2.3 From 10d489c3aee1b09dec3171f70251c95e744c5afc Mon Sep 17 00:00:00 2001 From: Matt Ettus Date: Thu, 16 Jun 2011 11:31:27 -0700 Subject: u1p/u1e: cleanup some warnings, connect the correct clocks --- usrp2/sdr_lib/tx_frontend.v | 2 +- usrp2/top/B100/u1plus_core.v | 15 +++++++-------- usrp2/top/E1x0/u1e_core.v | 6 +++--- 3 files changed, 11 insertions(+), 12 deletions(-) (limited to 'usrp2/sdr_lib/tx_frontend.v') diff --git a/usrp2/sdr_lib/tx_frontend.v b/usrp2/sdr_lib/tx_frontend.v index 283ed451e..d8525dd25 100644 --- a/usrp2/sdr_lib/tx_frontend.v +++ b/usrp2/sdr_lib/tx_frontend.v @@ -11,7 +11,7 @@ module tx_frontend // IQ balance --> DC offset --> rounding --> mux wire [23:0] i_dco, q_dco, i_ofs, q_ofs; - wire [15:0] i_final, q_final; + wire [WIDTH_OUT-1:0] i_final, q_final; wire [7:0] mux_ctrl; wire [35:0] corr_i, corr_q; wire [23:0] i_bal, q_bal; diff --git a/usrp2/top/B100/u1plus_core.v b/usrp2/top/B100/u1plus_core.v index cc27a3c12..3b2667e5b 100644 --- a/usrp2/top/B100/u1plus_core.v +++ b/usrp2/top/B100/u1plus_core.v @@ -57,8 +57,7 @@ module u1plus_core localparam SR_CLEAR_TX_FIFO = 62; // 1 reg localparam SR_GLOBAL_RESET = 63; // 1 reg - - wire [7:0] COMPAT_NUM = 8'd4; + wire [7:0] COMPAT_NUM = 8'd5; wire wb_clk = clk_fpga; wire wb_rst, global_reset; @@ -79,11 +78,11 @@ module u1plus_core wire [31:0] debug_vt; wire gpif_rst; - wire rx_overrun_dsp, rx_overrun_gpmc, tx_underrun_dsp, tx_underrun_gpmc; reg [7:0] frames_per_packet; - assign rx_overrun = rx_overrun_gpmc | rx_overrun_dsp; - assign tx_underrun = tx_underrun_gpmc | tx_underrun_dsp; + wire rx_overrun_dsp0, rx_overrun_dsp1, rx_overrun_gpif, tx_underrun_dsp, tx_underrun_gpif; + wire rx_overrun = rx_overrun_gpif | rx_overrun_dsp0 | rx_overrun_dsp1; + wire tx_underrun = tx_underrun_gpif | tx_underrun_dsp; setting_reg #(.my_addr(SR_GLOBAL_RESET), .width(1)) sr_reset (.clk(wb_clk),.rst(wb_rst),.strobe(set_stb),.addr(set_addr), @@ -104,7 +103,7 @@ module u1plus_core wire [sw-1:0] m0_sel; wire m0_cyc, m0_stb, m0_we, m0_ack, m0_err, m0_rty; - wire [31:0] debug_gpmc; + wire [31:0] debug_gpif; wire [35:0] tx_data, rx_data, tx_err_data; wire tx_src_rdy, tx_dst_rdy, rx_src_rdy, rx_dst_rdy, @@ -135,7 +134,7 @@ module u1plus_core .rx_data_i(rx_data), .rx_src_rdy_i(rx_src_rdy), .rx_dst_rdy_o(rx_dst_rdy), .tx_err_data_i(tx_err_data), .tx_err_src_rdy_i(tx_err_src_rdy), .tx_err_dst_rdy_o(tx_err_dst_rdy), - .tx_underrun(tx_underrun_gpmc), .rx_overrun(rx_overrun_gpmc), + .tx_underrun(tx_underrun_gpif), .rx_overrun(rx_overrun_gpif), .frames_per_packet(frames_per_packet), .test_len(test_len), .test_rate(test_rate), .test_ctrl(test_ctrl), .debug0(debug0), .debug1(debug1)); @@ -229,7 +228,7 @@ module u1plus_core .debug(debug_vt)); tx_frontend #(.BASE(SR_TX_FRONT), .WIDTH_OUT(14)) tx_frontend - (.clk(dsp_clk), .rst(dsp_rst), + (.clk(wb_clk), .rst(wb_rst), .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data), .tx_i(tx_i_int), .tx_q(tx_q_int), .run(1'b1), .dac_a(tx_i), .dac_b(tx_q)); diff --git a/usrp2/top/E1x0/u1e_core.v b/usrp2/top/E1x0/u1e_core.v index dff712a2f..b74f51d3c 100644 --- a/usrp2/top/E1x0/u1e_core.v +++ b/usrp2/top/E1x0/u1e_core.v @@ -76,8 +76,8 @@ module u1e_core wire [31:0] debug_vt; wire rx_overrun_dsp0, rx_overrun_dsp1, rx_overrun_gpmc, tx_underrun_dsp, tx_underrun_gpmc; - assign rx_overrun = rx_overrun_gpmc | rx_overrun_dsp0 | rx_overrun_dsp1; - assign tx_underrun = tx_underrun_gpmc | tx_underrun_dsp; + wire rx_overrun = rx_overrun_gpmc | rx_overrun_dsp0 | rx_overrun_dsp1; + wire tx_underrun = tx_underrun_gpmc | tx_underrun_dsp; setting_reg #(.my_addr(SR_GLOBAL_RESET), .width(1)) sr_reset (.clk(wb_clk),.rst(wb_rst),.strobe(set_stb),.addr(set_addr), @@ -241,7 +241,7 @@ module u1e_core .debug(debug_vt)); tx_frontend #(.BASE(SR_TX_FRONT), .WIDTH_OUT(14)) tx_frontend - (.clk(dsp_clk), .rst(dsp_rst), + (.clk(wb_clk), .rst(wb_rst), .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data), .tx_i(tx_i_int), .tx_q(tx_q_int), .run(1'b1), .dac_a(tx_i), .dac_b(tx_q)); -- cgit v1.2.3