diff options
29 files changed, 967 insertions, 718 deletions
| diff --git a/usrp2/sdr_lib/Makefile.srcs b/usrp2/sdr_lib/Makefile.srcs index 90eede20f..defbced17 100644 --- a/usrp2/sdr_lib/Makefile.srcs +++ b/usrp2/sdr_lib/Makefile.srcs @@ -8,6 +8,8 @@  SDR_LIB_SRCS = $(abspath $(addprefix $(BASE_DIR)/../sdr_lib/, \  acc.v \  add2.v \ +add2_and_clip.v \ +add2_and_clip_reg.v \  add2_and_round.v \  add2_and_round_reg.v \  add2_reg.v \ @@ -22,16 +24,16 @@ cordic.v \  cordic_z24.v \  cordic_stage.v \  dsp_core_rx.v \ -dsp_core_rx_old.v \  dsp_core_tx.v \  hb_dec.v \  hb_interp.v \  round.v \  round_reg.v \ -rx_control.v \ +round_sd.v \  rx_dcoffset.v \ +rx_frontend.v \  sign_extend.v \  small_hb_dec.v \  small_hb_int.v \ -tx_control.v \ +tx_frontend.v \  )) diff --git a/usrp2/sdr_lib/add2_and_clip.v b/usrp2/sdr_lib/add2_and_clip.v new file mode 100644 index 000000000..663f5d004 --- /dev/null +++ b/usrp2/sdr_lib/add2_and_clip.v @@ -0,0 +1,12 @@ + +module add2_and_clip +  #(parameter WIDTH=16) +    (input [WIDTH-1:0] in1, +     input [WIDTH-1:0] in2, +     output [WIDTH-1:0] sum); + +   wire [WIDTH:0] 	sum_int = {in1[WIDTH-1],in1} + {in2[WIDTH-1],in2}; +   clip #(.bits_in(WIDTH+1),.bits_out(WIDTH)) clip +     (.in(sum_int),.out(sum)); +    +endmodule // add2_and_clip diff --git a/usrp2/sdr_lib/add2_and_clip_reg.v b/usrp2/sdr_lib/add2_and_clip_reg.v new file mode 100644 index 000000000..8073b3b54 --- /dev/null +++ b/usrp2/sdr_lib/add2_and_clip_reg.v @@ -0,0 +1,25 @@ + +module add2_and_clip_reg +  #(parameter WIDTH=16) +    (input clk, +     input rst, +     input [WIDTH-1:0] in1, +     input [WIDTH-1:0] in2, +     input strobe_in, +     output reg [WIDTH-1:0] sum, +     output reg strobe_out); + +   wire [WIDTH-1:0] sum_int; +    +   add2_and_clip #(.WIDTH(WIDTH)) add2_and_clip (.in1(in1),.in2(in2),.sum(sum_int)); + +   always @(posedge clk) +     if(rst) +       sum <= 0; +     else if(strobe_in) +       sum <= sum_int; + +   always @(posedge clk) +     strobe_out <= strobe_in; +    +endmodule // add2_and_clip_reg diff --git a/usrp2/sdr_lib/dsp_core_rx.v b/usrp2/sdr_lib/dsp_core_rx.v index 0e69e53f7..639744de7 100644 --- a/usrp2/sdr_lib/dsp_core_rx.v +++ b/usrp2/sdr_lib/dsp_core_rx.v @@ -21,8 +21,8 @@ module dsp_core_rx    (input clk, input rst,     input set_stb, input [7:0] set_addr, input [31:0] set_data, -   input [13:0] adc_a, input adc_ovf_a, -   input [13:0] adc_b, input adc_ovf_b, +   input [23:0] adc_i, input adc_ovf_i, +   input [23:0] adc_q, input adc_ovf_q,     output [31:0] sample,     input run, @@ -30,70 +30,56 @@ module dsp_core_rx     output [31:0] debug     ); -   wire [15:0] scale_i, scale_q; -   wire [13:0] adc_a_ofs, adc_b_ofs; -   reg [13:0] adc_i, adc_q;     wire [31:0] phase_inc;     reg [31:0]  phase; -   wire [35:0] prod_i, prod_q; -   wire [23:0] i_cordic, q_cordic; +   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 [17:0] i_hb2, q_hb2; -   wire [15:0] i_out, q_out; - +   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; +   reg [23:0]  adc_i_mux, adc_q_mux; +   wire        realmode; +   wire        swap_iq; +        setting_reg #(.my_addr(BASE+0)) sr_0       (.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),        .in(set_data),.out({enable_hb1, enable_hb2, cic_decim_rate}),.changed()); -   rx_dcoffset #(.WIDTH(14),.ADDR(BASE+3)) rx_dcoffset_a -     (.clk(clk),.rst(rst),.set_stb(set_stb),.set_addr(set_addr),.set_data(set_data), -      .adc_in(adc_a),.adc_out(adc_a_ofs)); -    -   rx_dcoffset #(.WIDTH(14),.ADDR(BASE+4)) rx_dcoffset_b -     (.clk(clk),.rst(rst),.set_stb(set_stb),.set_addr(set_addr),.set_data(set_data), -      .adc_in(adc_b),.adc_out(adc_b_ofs)); - -   wire [7:0]  muxctrl; -   setting_reg #(.my_addr(BASE+5), .width(8)) sr_8 -     (.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr), -      .in(set_data),.out(muxctrl),.changed()); - -   wire [1:0] gpio_ena; -   setting_reg #(.my_addr(BASE+6), .width(2)) sr_9 +   setting_reg #(.my_addr(BASE+3), .width(2)) sr_3       (.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr), -      .in(set_data),.out(gpio_ena),.changed()); +      .in(set_data),.out({realmode,swap_iq}),.changed()); -   always @(posedge clk) -     case(muxctrl[3:0])		// The I mapping -       0: adc_i <= adc_a_ofs; -       1: adc_i <= adc_b_ofs; -       2: adc_i <= 0; -       default: adc_i <= 0; -     endcase // case (muxctrl[3:0]) +   // MUX so we can do realmode signals on either input     always @(posedge clk) -     case(muxctrl[7:4])		// The Q mapping -       0: adc_q <= adc_a_ofs; -       1: adc_q <= adc_b_ofs; -       2: adc_q <= 0; -       default: adc_q <= 0; -     endcase // case (muxctrl[7:4]) -           +     if(swap_iq) +       begin +	  adc_i_mux <= adc_q; +	  adc_q_mux <= realmode ? 24'd0 : adc_i; +       end +     else +       begin +	  adc_i_mux <= adc_i; +	  adc_q_mux <= realmode ? 24'd0 : adc_q; +       end + +   // NCO     always @(posedge clk)       if(rst)         phase <= 0; @@ -102,74 +88,55 @@ module dsp_core_rx       else         phase <= phase + phase_inc; -   MULT18X18S mult_i -     (.P(prod_i),    // 36-bit multiplier output -      .A({{4{adc_i[13]}},adc_i} ),    // 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({{4{adc_q[13]}},adc_q} ),    // 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 -      );  - -    -   cordic_z24 #(.bitwidth(24)) +   // CORDIC  24-bit I/O +   cordic_z24 #(.bitwidth(25))       cordic(.clock(clk), .reset(rst), .enable(run), -	    .xi(prod_i[23:0]),. yi(prod_q[23:0]), .zi(phase[31:8]), +	    .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)); + +   // 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) );     cic_decim #(.bw(24))       decim_i (.clock(clk),.reset(rst),.enable(run),  	      .rate(cic_decim_rate),.strobe_in(1'b1),.strobe_out(strobe_cic), -	      .signal_in(i_cordic),.signal_out(i_cic)); +	      .signal_in(i_cordic_clip),.signal_out(i_cic));     cic_decim #(.bw(24))       decim_q (.clock(clk),.reset(rst),.enable(run),  	      .rate(cic_decim_rate),.strobe_in(1'b1),.strobe_out(strobe_cic), -	      .signal_in(q_cordic),.signal_out(q_cic)); +	      .signal_in(q_cordic_clip),.signal_out(q_cic)); -   round_reg #(.bits_in(24),.bits_out(18)) round_icic (.clk(clk),.in(i_cic),.out(i_cic_scaled)); -   round_reg #(.bits_in(24),.bits_out(18)) round_qcic (.clk(clk),.in(q_cic),.out(q_cic_scaled)); -   reg 	       strobe_cic_d1; -   always @(posedge clk) strobe_cic_d1 <= strobe_cic; -    -   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(18), .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(18), .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)); -   round #(.bits_in(18),.bits_out(16)) round_iout (.in(i_hb2),.out(i_out)); -   round #(.bits_in(18),.bits_out(16)) round_qout (.in(q_hb2),.out(q_out)); +   // 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)); -   reg [31:0] sample_reg; -   always @(posedge clk) -     sample_reg <= {i_out,q_out}; +   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      sample = sample_reg; -   assign      strobe = strobe_hb2; -   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 diff --git a/usrp2/sdr_lib/dsp_core_rx_tb.v b/usrp2/sdr_lib/dsp_core_rx_tb.v new file mode 100644 index 000000000..271db8cef --- /dev/null +++ b/usrp2/sdr_lib/dsp_core_rx_tb.v @@ -0,0 +1,73 @@ + +`timescale 1ns/1ns +module dsp_core_rx_tb(); +    +   reg clk, rst; + +   initial rst = 1; +   initial #1000 rst = 0; +   initial clk = 0; +   always #5 clk = ~clk; +    +   initial $dumpfile("dsp_core_rx_tb.vcd"); +   initial $dumpvars(0,dsp_core_rx_tb); +    +   reg signed [23:0] adc_in; +   wire signed [15:0] adc_out_i, adc_out_q; + +   always @(posedge clk) +     begin +	$display(adc_in); +	$display(adc_out_i); +	$display(adc_out_q); +     end	 + +   reg run; +   reg set_stb; +   reg [7:0] set_addr; +   reg [31:0] set_data; +    +   dsp_core_rx #(.BASE(0)) dsp_core_rx +     (.clk(clk),.rst(rst), +      .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data), +      .adc_i(adc_in), .adc_ovf_i(0), +      .adc_q(0), .adc_ovf_q(0), +      .sample({adc_out_i,adc_out_q}), +      .run(run), .strobe(), .debug()); + +   initial +     begin +	run <= 0; +	@(negedge rst); +	@(posedge clk); +	set_addr <= 1; +	set_data <= {16'd64,16'd64};  // set gains +	set_stb <= 1; +	@(posedge clk); +	set_addr <= 2; +	set_data <= {16'd0,8'd3,8'd1}; // set decim +	set_stb <= 1; +	@(posedge clk); +	set_addr <= 0; +	//set_data <= {32'h0000_0000}; +	set_data <= {32'h01CA_C083}; // 700 kHz +	set_stb <= 1; +	@(posedge clk); +	set_stb <= 0; +	@(posedge clk); +	run <= 1; +     end + +   always @(posedge clk) +     //adc_in <= 24'd1000000; +     adc_in <= 24'h80_0000; +    +   /* +   always @(posedge clk) +     if(rst) +       adc_in <= 0; +     else +       adc_in <= adc_in + 4; +   //adc_in <= (($random % 473) + 23)/4; +*/    +endmodule // dsp_core_rx_tb diff --git a/usrp2/sdr_lib/dsp_core_tx.v b/usrp2/sdr_lib/dsp_core_tx.v index 58bd82f6e..f02c63b42 100644 --- a/usrp2/sdr_lib/dsp_core_tx.v +++ b/usrp2/sdr_lib/dsp_core_tx.v @@ -21,8 +21,7 @@ module dsp_core_tx    (input clk, input rst,     input set_stb, input [7:0] set_addr, input [31:0] set_data, -   output reg [15:0] dac_a, -   output reg [15:0] dac_b, +   output [23:0] tx_i, output [23:0] tx_q,     // To tx_control     input [31:0] sample, @@ -50,10 +49,6 @@ module dsp_core_tx       (.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr),        .in(set_data),.out({enable_hb1, enable_hb2, interp_rate}),.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({dacmux_b,dacmux_a}),.changed()); -     // Strobes are all now delayed by 1 cycle for timing reasons     wire        strobe_cic_pre, strobe_hb1_pre, strobe_hb2_pre;     reg 	       strobe_cic = 1; @@ -148,20 +143,9 @@ module dsp_core_tx        .CE(1),  // Clock enable input        .R(rst)     // Synchronous reset input        ); -    -   always @(posedge clk) -     case(dacmux_a) -       0 : dac_a <= prod_i[28:13]; -       1 : dac_a <= prod_q[28:13]; -       default : dac_a <= 0; -     endcase // case(dacmux_a) -    -   always @(posedge clk) -     case(dacmux_b) -       0 : dac_b <= prod_i[28:13]; -       1 : dac_b <= prod_q[28:13]; -       default : dac_b <= 0; -     endcase // case(dacmux_b) + +   assign tx_i = prod_i[28:5]; +   assign tx_q = prod_q[28:5];     assign      debug = {strobe_cic, strobe_hb1, strobe_hb2,run}; diff --git a/usrp2/sdr_lib/hb_dec.v b/usrp2/sdr_lib/hb_dec.v index 9747f0adb..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,11 +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-1:0] final_sum; -   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) @@ -117,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 /*_and_round_reg*/ #(.WIDTH(IWIDTH)) add1 (.clk(clk),.in1(data_odd_a),.in2(data_odd_b),.sum(sum1)); -   add2_reg /*_and_round_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) @@ -140,49 +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 /* add2_and_round_reg */ #(.WIDTH(ACCWIDTH+1))  -     final_adder (.clk(clk), .in1({acc_out,1'b0}), .in2({data_even_signext,1'b0}), .sum(final_sum_unrounded)); - -   round_reg #(.bits_in(ACCWIDTH-4),.bits_out(OWIDTH)) -     final_round (.clk(clk),.in(final_sum_unrounded[ACCWIDTH-5:0]),.out(final_sum)); - -   // Output -   always @(posedge clk) -     if(bypass) -       data_out <= data_in; -     else if(stb_out_pre[9]) -       data_out <= final_sum; +   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; +   always @(posedge clk) final_sum <= acc_out + data_even_signext; +    +   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]; +        always @(posedge clk) -     if(rst) -       stb_out <= 0; -     else if(bypass) -       stb_out <= stb_in; -     else -       stb_out <= stb_out_pre[9]; -  +     begin +	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 256f6085d..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  [17:0]  data_out ; +    wire    signed  [23:0]  data_out ;     initial       begin @@ -65,8 +65,8 @@ module hb_dec_tb( ) ;      */ -   hb_dec #(.IWIDTH(18),.OWIDTH(18),.CWIDTH(18),.ACCWIDTH(24)) uut -     (.clk(clock),.rst(reset),.bypass(0),.cpi(clocks),.stb_in(strobe_in),.data_in(data_in), +   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) );      integer i, ri, ro, infile, outfile ; diff --git a/usrp2/sdr_lib/input.dat b/usrp2/sdr_lib/input.dat index 1e649ac2e..85b5887e8 100644 --- a/usrp2/sdr_lib/input.dat +++ b/usrp2/sdr_lib/input.dat @@ -6,7 +6,6 @@  0  0  0 --131072  0  0  0 @@ -16,6 +15,7 @@  0  0  0 +8388607  0  0  0 @@ -38,34 +38,6 @@  0  0  0 --131072 --131072 --131072 --131072 --131072 --131072 --131072 --131072 --131072 --131072 --131072 --131072 --131072 --131072 --131072 --131072 --131072 --131072 --131072 --131072 --131072 --131072 --131072 --131072 --131072 --131072 --131072 --131072  0  0  0 @@ -82,6 +54,7 @@  0  0  0 +8388607  0  0  0 @@ -96,200 +69,6 @@  0  0  0 -131071 -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 -131071 -131071 -131071 -131071 -131071 -131071 -131071 -131071 -131071 -131071 -131071 -131071 -131071 -131071 -131071 -131071 -131071 -131071 -131071 -131071 -131071 -131071 -131071 -131071 -131071 -131071 -131071 -131071 -131071 -131071 -131071 -131071 -131071 -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 -100000 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 --131072 -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 -0 -0 --131072 --131072 --131072 --131072 --131072 --131072 --131072 --131072 --131072 --131072 --131072 --131072 --131072 --131072 --131072 --131072 --131072 --131072 --131072 --131072 --131072 --131072 --131072 --131072 --131072 --131072 --131072 --131072 --131072 --131072 --131072 --131072 --131072 --131072 --131072 --131072 --131072 --131072 --131072 --131072 --131072 --131072 -0 -0  0  0  0 @@ -313,6 +92,56 @@  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 @@ -339,3 +168,4 @@  0  0  0 + diff --git a/usrp2/sdr_lib/round.v b/usrp2/sdr_lib/round.v index c4f9ec9cd..7a137d702 100644 --- a/usrp2/sdr_lib/round.v +++ b/usrp2/sdr_lib/round.v @@ -26,8 +26,10 @@ module round    #(parameter bits_in=0,      parameter bits_out=0)      (input [bits_in-1:0] in, -     output [bits_out-1:0] out); +     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]); +   assign err = in - {out,{(bits_in-bits_out){1'b0}}};  endmodule // round diff --git a/usrp2/sdr_lib/round_reg.v b/usrp2/sdr_lib/round_reg.v index aa0972dab..6f2e974d7 100644 --- a/usrp2/sdr_lib/round_reg.v +++ b/usrp2/sdr_lib/round_reg.v @@ -27,13 +27,18 @@ module round_reg      parameter bits_out=0)      (input clk,       input [bits_in-1:0] in, -     output reg [bits_out-1:0] out); +     output reg [bits_out-1:0] out, +     output reg [bits_in-bits_out:0] err);     wire [bits_out-1:0] temp; - -   round #(.bits_in(bits_in),.bits_out(bits_out)) round (.in(in),.out(temp)); +   wire [bits_in-bits_out:0] err_temp; +    +   round #(.bits_in(bits_in),.bits_out(bits_out)) round (.in(in),.out(temp), .err(err_temp));     always @(posedge clk)       out <= temp; + +   always @(posedge clk) +     err <= err_temp; -endmodule // round +endmodule // round_reg diff --git a/usrp2/sdr_lib/round_sd.v b/usrp2/sdr_lib/round_sd.v new file mode 100644 index 000000000..aeeb3502f --- /dev/null +++ b/usrp2/sdr_lib/round_sd.v @@ -0,0 +1,22 @@ + + +module round_sd +  #(parameter WIDTH_IN=18, +    parameter WIDTH_OUT=16) +   (input clk, input reset, +    input [WIDTH_IN-1:0] in, input strobe_in, +    output [WIDTH_OUT-1:0] out, output strobe_out); + +   localparam ERR_WIDTH = WIDTH_IN - WIDTH_OUT + 1; + +   wire [ERR_WIDTH-1:0]  err; +   wire [WIDTH_IN-1:0] 	 err_ext, sum; +   +   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)); +    +   round #(.bits_in(WIDTH_IN),.bits_out(WIDTH_OUT)) round_sum (.in(sum), .out(out), .err(err)); +    +endmodule // round_sd diff --git a/usrp2/sdr_lib/round_sd_tb.v b/usrp2/sdr_lib/round_sd_tb.v new file mode 100644 index 000000000..1e8e9a323 --- /dev/null +++ b/usrp2/sdr_lib/round_sd_tb.v @@ -0,0 +1,58 @@ + +module round_sd_tb(); +    +   reg clk, rst; + +   initial rst = 1; +   initial #1000 rst = 0; +   initial clk = 0; +   always #5 clk = ~clk; +    +   initial $dumpfile("round_sd_tb.vcd"); +   initial $dumpvars(0,round_sd_tb); + +   localparam WIDTH_IN = 8; +   localparam WIDTH_OUT = 5; +    +   reg [WIDTH_IN-1:0] adc_in, adc_in_del; +   wire [WIDTH_OUT-1:0] adc_out; + +   integer 		factor = 1<<(WIDTH_IN-WIDTH_OUT); +    +   always @(posedge clk) +     if(~rst) +	begin   +	   if(adc_in_del[WIDTH_IN-1]) +	     $write("-%d\t",-adc_in_del); +	   else +	     $write("%d\t",adc_in_del); +	   if(adc_out[WIDTH_OUT-1]) +	     $write("-%d\t",-adc_out); +	   else +	     $write("%d\t",adc_out); +	   $write("\n"); +	    +	   //$write("%f\t",adc_in_del/factor); +	   //$write("%f\n",adc_in_del/factor-adc_out); +	end	 +    +   round_sd #(.WIDTH_IN(WIDTH_IN),.WIDTH_OUT(WIDTH_OUT))  +   round_sd(.clk(clk),.reset(rst), .in(adc_in), .strobe_in(1'b1), .out(adc_out), .strobe_out()); + +   reg [5:0] counter = 0; +    +   always @(posedge clk) +     counter <= counter+1; +    +   always @(posedge clk) +     adc_in_del <= adc_in; + +   always @(posedge clk) +     if(rst) +       adc_in <= 0; +     else if(counter == 63) +       adc_in <= adc_in + 1; +    +   initial #300000 $finish; +    +endmodule // longfifo_tb diff --git a/usrp2/sdr_lib/rx_dcoffset.v b/usrp2/sdr_lib/rx_dcoffset.v index 64ff4110d..e43461261 100644 --- a/usrp2/sdr_lib/rx_dcoffset.v +++ b/usrp2/sdr_lib/rx_dcoffset.v @@ -18,43 +18,40 @@  module rx_dcoffset  -  #(parameter WIDTH=14, -    parameter ADDR=8'd0) -    (input clk, input rst,  -     input set_stb, input [7:0] set_addr, input [31:0] set_data, -     input signed [WIDTH-1:0] adc_in, output signed [WIDTH-1:0] adc_out); - -   // Because of some extra delays to make timing easier, the transfer function is: -   //     (z-1)/(z^2-z-alpha)  where alpha is 1/2^n +  #(parameter WIDTH=16, +    parameter ADDR=8'd0, +    parameter alpha_shift=16) +   (input clk, input rst,  +    input set_stb, input [7:0] set_addr, input [31:0] set_data, +    input [WIDTH-1:0] in, output [WIDTH-1:0] out); -   wire 	       set_now = set_stb & (ADDR == set_addr); +   wire 	      set_now = set_stb & (ADDR == set_addr); -   reg 		       fixed;  // uses fixed offset -   wire 	       signed [WIDTH-1:0] fixed_dco; -   reg 		       signed [31:0] integrator; +   reg 		      fixed;  // uses fixed offset +   wire [WIDTH-1:0]   fixed_dco; + +   localparam int_width = WIDTH + alpha_shift; +   reg [int_width-1:0] integrator; +   wire [WIDTH-1:0]    quantized;     always @(posedge clk)       if(rst)         begin  	  fixed <= 0; -	  integrator <= 32'd0; +	  integrator <= {int_width{1'b0}};         end       else if(set_now)         begin -	  integrator <= {set_data[WIDTH-1:0],{(32-WIDTH){1'b0}}}; +	  //integrator <= {set_data[30:0],{(31-int_width){1'b0}}};  	  fixed <= set_data[31];         end       else if(~fixed) -       integrator <= integrator + adc_out; -    -   wire [WIDTH:0] scaled_integrator; -    -   round #(.bits_in(33),.bits_out(15)) round (.in({integrator[31],integrator}),.out(scaled_integrator)); -    -   wire [WIDTH:0]      adc_out_int = {adc_in[WIDTH-1],adc_in} - scaled_integrator; +       integrator <= integrator +  {{(alpha_shift){out[WIDTH-1]}},out}; -   clip_reg #(.bits_in(WIDTH+1),.bits_out(WIDTH)) clip_adc -     (.clk(clk),.in(adc_out_int),.out(adc_out)); +   round_sd #(.WIDTH_IN(int_width),.WIDTH_OUT(WIDTH)) round_sd +     (.clk(clk), .reset(rst), .in(integrator), .strobe_in(1'b1), .out(quantized), .strobe_out()); +   add2_and_clip_reg #(.WIDTH(WIDTH)) add2_and_clip_reg +     (.clk(clk), .rst(rst), .in1(in), .in2(-quantized), .strobe_in(1'b1), .sum(out), .strobe_out());  endmodule // rx_dcoffset diff --git a/usrp2/sdr_lib/rx_dcoffset_tb.v b/usrp2/sdr_lib/rx_dcoffset_tb.v index b0dd8cb05..b4fb66ad7 100644 --- a/usrp2/sdr_lib/rx_dcoffset_tb.v +++ b/usrp2/sdr_lib/rx_dcoffset_tb.v @@ -29,14 +29,26 @@ module rx_dcoffset_tb();     initial $dumpfile("rx_dcoffset_tb.vcd");     initial $dumpvars(0,rx_dcoffset_tb); -   reg [13:0] adc_in = 7; +   reg [13:0] adc_in;     wire [13:0] adc_out;     always @(posedge clk) -     $display("%d\t%d",adc_in,adc_out); +     begin +	if(adc_in[13]) +	  $write("-%d,",-adc_in); +	else +	  $write("%d,",adc_in); +	if(adc_out[13]) +	  $write("-%d\n",-adc_out); +	else +	  $write("%d\n",adc_out); +     end	 -   rx_dcoffset #(.WIDTH(14),.ADDR(0)) +   rx_dcoffset #(.WIDTH(14),.ADDR(0), .alpha_shift(8))       rx_dcoffset(.clk(clk),.rst(rst),.set_stb(0),.set_addr(0),.set_data(0), -		 .adc_in(adc_in),.adc_out(adc_out)); +		 .in(adc_in),.out(adc_out)); + +   always @(posedge clk) +     adc_in <= (($random % 473) + 23)/4;  endmodule // longfifo_tb diff --git a/usrp2/sdr_lib/rx_frontend.v b/usrp2/sdr_lib/rx_frontend.v new file mode 100644 index 000000000..04b14787e --- /dev/null +++ b/usrp2/sdr_lib/rx_frontend.v @@ -0,0 +1,73 @@ + +module rx_frontend +  #(parameter BASE = 0) +   (input clk, input rst, +    input set_stb, input [7:0] set_addr, input [31:0] set_data, + +    input [15:0] adc_a, input adc_ovf_a, +    input [15:0] adc_b, input adc_ovf_b, + +    output [23:0] i_out, output [23:0] q_out, +    input run, +    output [31:0] debug +    ); +    +   reg [15:0] 	  adc_i, adc_q; +   wire [17:0] 	  adc_i_ofs, adc_q_ofs; +   wire [35:0] 	  corr_i, corr_q; wire [17:0] 	  mag_corr,phase_corr; +   wire 	  swap_iq; +   wire [23:0] 	  i_final, q_final; +    +   setting_reg #(.my_addr(BASE), .width(1)) sr_8 +     (.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr), +      .in(set_data),.out(swap_iq),.changed()); + +   always @(posedge clk) +     if(swap_iq) // Swap +       {adc_i,adc_q} <= {adc_b,adc_a}; +     else +       {adc_i,adc_q} <= {adc_a,adc_b}; +        +   setting_reg #(.my_addr(BASE+1),.width(18)) sr_1 +     (.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr), +      .in(set_data),.out(mag_corr),.changed()); +    +   setting_reg #(.my_addr(BASE+2),.width(18)) sr_2 +     (.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr), +      .in(set_data),.out(phase_corr),.changed()); +    +   rx_dcoffset #(.WIDTH(18),.ADDR(BASE+3)) rx_dcoffset_i +     (.clk(clk),.rst(rst),.set_stb(set_stb),.set_addr(set_addr),.set_data(set_data), +      .in({adc_i,2'b00}),.out(adc_i_ofs)); +    +   rx_dcoffset #(.WIDTH(18),.ADDR(BASE+4)) rx_dcoffset_q +     (.clk(clk),.rst(rst),.set_stb(set_stb),.set_addr(set_addr),.set_data(set_data), +      .in({adc_q,2'b00}),.out(adc_q_ofs)); +    +   MULT18X18S mult_mag_corr +     (.P(corr_i), .A(adc_i_ofs), .B(mag_corr), .C(clk), .CE(1), .R(rst) );  + +   MULT18X18S mult_phase_corr +     (.P(corr_q), .A(adc_i_ofs), .B(phase_corr), .C(clk), .CE(1), .R(rst) ); +    +   add2_and_clip_reg #(.WIDTH(24)) add_clip_i +     (.clk(clk), .rst(rst),  +      .in1({adc_i_ofs,6'd0}), .in2({{4{corr_i[35]}},corr_i[35:16]}), .strobe_in(1'b1),  +      .sum(i_final), .strobe_out()); +    +   add2_and_clip_reg #(.WIDTH(24)) add_clip_q +     (.clk(clk), .rst(rst),  +      .in1({adc_q_ofs,6'd0}), .in2({{4{corr_q[35]}},corr_q[35:16]}), .strobe_in(1'b1), +      .sum(q_final), .strobe_out()); + +   assign i_out = i_final; +   assign q_out = q_final; +    +   /* +   round_sd #(.WIDTH_IN(24),.WIDTH_OUT(18)) round_i +     (.clk(clk), .reset(rst), .in(i_final), .strobe_in(1'b1), .out(i_out), .strobe_out()); +    +   round_sd #(.WIDTH_IN(24),.WIDTH_OUT(18)) round_q +     (.clk(clk), .reset(rst), .in(q_final), .strobe_in(1'b1), .out(q_out), .strobe_out()); +   */ +endmodule // rx_frontend diff --git a/usrp2/sdr_lib/rx_frontend_tb.v b/usrp2/sdr_lib/rx_frontend_tb.v new file mode 100644 index 000000000..487b72687 --- /dev/null +++ b/usrp2/sdr_lib/rx_frontend_tb.v @@ -0,0 +1,45 @@ + +`timescale 1ns/1ns +module rx_frontend_tb(); +    +   reg clk, rst; + +   initial rst = 1; +   initial #1000 rst = 0; +   initial clk = 0; +   always #5 clk = ~clk; +    +   initial $dumpfile("rx_frontend_tb.vcd"); +   initial $dumpvars(0,rx_frontend_tb); + +   reg [15:0] adc_in; +   wire [17:0] adc_out; + +   always @(posedge clk) +     begin +	if(adc_in[13]) +	  $write("-%d,",-adc_in); +	else +	  $write("%d,",adc_in); +	if(adc_out[13]) +	  $write("-%d\n",-adc_out); +	else +	  $write("%d\n",adc_out); +     end	 +    +   rx_frontend #(.BASE(0)) rx_frontend +     (.clk(clk),.rst(rst), +      .set_stb(0),.set_addr(0),.set_data(0), +      .adc_a(adc_in), .adc_ovf_a(0), +      .adc_b(0), .adc_ovf_b(0), +      .i_out(adc_out),.q_out(), +      .run(), .debug()); + +   always @(posedge clk) +     if(rst) +       adc_in <= 0; +     else +       adc_in <= adc_in + 4; +   //adc_in <= (($random % 473) + 23)/4; +    +endmodule // rx_frontend_tb diff --git a/usrp2/sdr_lib/small_hb_dec.v b/usrp2/sdr_lib/small_hb_dec.v index 151b8c287..a7f93e056 100644 --- a/usrp2/sdr_lib/small_hb_dec.v +++ b/usrp2/sdr_lib/small_hb_dec.v @@ -29,21 +29,30 @@ module small_hb_dec       input stb_in,       input [WIDTH-1:0] data_in,       output reg stb_out, -     output [WIDTH-1:0] data_out); +     output reg [WIDTH-1:0] data_out); -   reg 			stb_in_d1; -   reg [WIDTH-1:0] 	data_in_d1; -   always @(posedge clk) stb_in_d1 <= stb_in; -   always @(posedge clk) data_in_d1 <= data_in; +   // Round off inputs to 17 bits because of 18 bit multipliers +   localparam INTWIDTH = 17; +   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)); +   	 +    +   reg 			stb_rnd_d1; +   reg [INTWIDTH-1:0] 	data_rnd_d1; +   always @(posedge clk) stb_rnd_d1 <= stb_rnd; +   always @(posedge clk) data_rnd_d1 <= data_rnd;     wire 		go;     reg 			phase, go_d1, go_d2, go_d3, go_d4;     always @(posedge clk)       if(rst | ~run)         phase <= 0; -     else if(stb_in_d1) +     else if(stb_rnd_d1)         phase <= ~phase; -   assign 		go = stb_in_d1 & phase; +   assign 		go = stb_rnd_d1 & phase;     always @(posedge clk)        if(rst | ~run)         begin @@ -63,11 +72,11 @@ module small_hb_dec     wire [17:0] 		coeff_a = -10690;     wire [17:0] 		coeff_b = 75809; -   reg [WIDTH-1:0] 	d1, d2, d3, d4 , d5, d6; +   reg [INTWIDTH-1:0] 	d1, d2, d3, d4 , d5, d6;     always @(posedge clk) -     if(stb_in_d1 | rst) +     if(stb_rnd_d1 | rst)         begin -	  d1 <= data_in_d1; +	  d1 <= data_rnd_d1;  	  d2 <= d1;  	  d3 <= d2;  	  d4 <= d3; @@ -76,16 +85,14 @@ module small_hb_dec         end     reg [17:0] sum_a, sum_b, middle, middle_d1; -   wire [17:0] sum_a_unreg, sum_b_unreg; -   add2 #(.WIDTH(18)) add2_a (.in1(data_in_d1),.in2(d6),.sum(sum_a_unreg)); -   add2 #(.WIDTH(18)) add2_b (.in1(d2),.in2(d4),.sum(sum_b_unreg)); -    +     always @(posedge clk)       if(go)         begin -	  sum_a <= sum_a_unreg; -	  sum_b <= sum_b_unreg; -	  middle <= d3; +	  sum_a <= {data_rnd_d1[INTWIDTH-1],data_rnd_d1} + {d6[INTWIDTH-1],d6}; +	  sum_b <= {d2[INTWIDTH-1],d2} + {d4[INTWIDTH-1],d4}; +	  //middle <= {d3[INTWIDTH-1],d3}; +	  middle <= {d3,1'b0};         end     always @(posedge clk) @@ -106,23 +113,22 @@ module small_hb_dec       else if(go_d3)         accum <= accum + {prod}; -   wire [17:0] 	 accum_rnd; -   round #(.bits_in(36),.bits_out(18)) round_acc (.in(accum),.out(accum_rnd)); +   wire [WIDTH:0] 	 accum_rnd; +   wire [WIDTH-1:0] 	 accum_rnd_clip; +    +   wire 	 stb_round; +    +   round_sd #(.WIDTH_IN(36),.WIDTH_OUT(WIDTH+1)) round_acc  +     (.clk(clk), .reset(rst), .in(accum), .strobe_in(go_d4), .out(accum_rnd), .strobe_out(stb_round)); -   reg [17:0] 	 final_sum; +   clip #(.bits_in(WIDTH+1),.bits_out(WIDTH)) clip (.in(accum_rnd), .out(accum_rnd_clip)); +    +   // Output     always @(posedge clk) -     if(bypass) -       final_sum <= data_in_d1; -     else if(go_d4) -       final_sum <= accum_rnd; +     begin +	stb_out  <= bypass ? stb_in : stb_round; +	data_out <= bypass ? data_in : accum_rnd_clip; +     end -   assign 	 data_out = final_sum; -   always @(posedge clk) -     if(rst) -       stb_out <= 0; -     else if(bypass) -       stb_out <= stb_in_d1; -     else -       stb_out <= go_d4;  endmodule // small_hb_dec diff --git a/usrp2/sdr_lib/tx_frontend.v b/usrp2/sdr_lib/tx_frontend.v new file mode 100644 index 000000000..d8525dd25 --- /dev/null +++ b/usrp2/sdr_lib/tx_frontend.v @@ -0,0 +1,86 @@ + +module tx_frontend +  #(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 [WIDTH_OUT-1:0] dac_a, output reg [WIDTH_OUT-1:0] dac_b +    ); + +   // IQ balance --> DC offset --> rounding --> mux + +   wire [23:0] i_dco, q_dco, i_ofs, q_ofs; +   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; +   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), +      .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(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(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(q_bal), .strobe_in(1'b1), .sum(q_ofs), .strobe_out()); + +   // Rounding +   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(WIDTH_OUT)) 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; +       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 diff --git a/usrp2/top/B100/u1plus_core.v b/usrp2/top/B100/u1plus_core.v index 8a02f0fb8..3c861fe08 100644 --- a/usrp2/top/B100/u1plus_core.v +++ b/usrp2/top/B100/u1plus_core.v @@ -30,7 +30,6 @@ module u1plus_core     output sclk, output [15:0] sen, output mosi, input miso,     input cgen_st_status, input cgen_st_ld, input cgen_st_refmon, output cgen_sync_b, output cgen_ref_sel,    -   output tx_underrun, output rx_overrun,     inout [15:0] io_tx, inout [15:0] io_rx,      output [13:0] tx_i, output [13:0] tx_q,      input [11:0] rx_i, input [11:0] rx_q,  @@ -41,24 +40,31 @@ module u1plus_core     localparam RXFIFOSIZE = 11;     // 64 total regs in address space -   localparam SR_RX_CTRL = 0;     // 9 regs (+0 to +8) -   localparam SR_RX_DSP = 16;     // 7 regs (+0 to +6) -   localparam SR_TX_CTRL = 24;    // 6 regs (+0 to +5) -   localparam SR_TX_DSP = 32;     // 5 regs (+0 to +4) -   localparam SR_TIME64 = 40;     // 6 regs (+0 to +5) -   localparam SR_CLEAR_RX_FIFO = 48; // 1 reg -   localparam SR_CLEAR_TX_FIFO = 49; // 1 reg -   localparam SR_GLOBAL_RESET = 50; // 1 reg -   localparam SR_REG_TEST32 = 52; // 1 reg - -   wire [7:0]	COMPAT_NUM = 8'd3; +   localparam SR_RX_CTRL0 = 0;       // 9 regs (+0 to +8) +   localparam SR_RX_DSP0 = 10;       // 4 regs (+0 to +3) +   localparam SR_RX_CTRL1 = 16;      // 9 regs (+0 to +8) +   localparam SR_RX_DSP1 = 26;       // 4 regs (+0 to +3) +   localparam SR_TX_CTRL = 32;       // 4 regs (+0 to +3) +   localparam SR_TX_DSP = 38;        // 3 regs (+0 to +2) + +   localparam SR_TIME64 = 42;        // 6 regs (+0 to +5) +   localparam SR_RX_FRONT = 48;      // 5 regs (+0 to +4) +   localparam SR_TX_FRONT = 54;      // 5 regs (+0 to +4) + +   localparam SR_REG_TEST32 = 60;    // 1 reg +   localparam SR_CLEAR_RX_FIFO = 61; // 1 reg +   localparam SR_CLEAR_TX_FIFO = 62; // 1 reg +   localparam SR_GLOBAL_RESET = 63;  // 1 reg + +   wire [7:0]	COMPAT_NUM = 8'd5;     wire 	wb_clk = clk_fpga;     wire 	wb_rst, global_reset;     wire 	pps_int;     wire [63:0] 	vita_time, vita_time_pps; -   reg [15:0] 	reg_leds, reg_cgen_ctrl, reg_test, xfer_rate; +   reg [15:0] 	reg_leds, reg_cgen_ctrl, reg_test; +   wire [15:0] 	xfer_rate = 0;     wire [7:0] 	test_rate;     wire [3:0] 	test_ctrl; @@ -72,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), @@ -97,13 +103,12 @@ 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,   		 tx_err_src_rdy, tx_err_dst_rdy; -   wire 	 bus_error;     wire 	 clear_tx, clear_rx;     setting_reg #(.my_addr(SR_CLEAR_RX_FIFO), .width(1)) sr_clear_rx @@ -128,36 +133,83 @@ 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));     // ///////////////////////////////////////////////////////////////////////// -   // DSP RX -   wire [31:0] 	 sample_rx; -   wire 	 strobe_rx, run_rx; -   wire [31:0] 	 debug_rx_dsp, vr_debug; +   // RX ADC Frontend, does IQ Balance, DC Offset, muxing + +   wire [23:0] 	 adc_i, adc_q;  // 24 bits is total overkill here, but it matches u2/u2p +   wire 	 run_rx, run_rx0, run_rx1; +    +   rx_frontend #(.BASE(SR_RX_FRONT)) rx_frontend +     (.clk(wb_clk),.rst(wb_rst), +      .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data), +      .adc_a({rx_i,4'b00}),.adc_ovf_a(0), +      .adc_b({rx_q,4'b00}),.adc_ovf_b(0), +      .i_out(adc_i), .q_out(adc_q), .run(run_rx0 | run_rx1), .debug()); +    +   // ///////////////////////////////////////////////////////////////////////// +   // DSP RX 0 + +   wire [31:0] 	 sample_rx0; +   wire 	 strobe_rx0; +   wire [35:0] 	 vita_rx_data0; +   wire 	 vita_rx_src_rdy0, vita_rx_dst_rdy0; -   dsp_core_rx #(.BASE(SR_RX_DSP)) dsp_core_rx +   dsp_core_rx #(.BASE(SR_RX_DSP0)) dsp_core_rx0       (.clk(wb_clk),.rst(wb_rst),        .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data), -      .adc_a({rx_i,2'b0}),.adc_ovf_a(0),.adc_b({rx_q,2'b0}),.adc_ovf_b(0), -      .sample(sample_rx), .run(run_rx), .strobe(strobe_rx), -      .debug(debug_rx_dsp) ); +      .adc_i(adc_i),.adc_ovf_i(0),.adc_q(adc_q),.adc_ovf_q(0), +      .sample(sample_rx0), .run(run_rx0), .strobe(strobe_rx0), +      .debug() ); + +   vita_rx_chain #(.BASE(SR_RX_CTRL0), .UNIT(0), .FIFOSIZE(9), .PROT_ENG_FLAGS(0)) vita_rx_chain0 +     (.clk(wb_clk),.reset(wb_rst),.clear(clear_rx), +      .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data), +      .vita_time(vita_time), .overrun(rx_overrun_dsp0), +      .sample(sample_rx0), .run(run_rx0), .strobe(strobe_rx0), +      .rx_data_o(vita_rx_data0), .rx_dst_rdy_i(vita_rx_dst_rdy0), .rx_src_rdy_o(vita_rx_src_rdy0), +      .debug() ); -   vita_rx_chain #(.BASE(SR_RX_CTRL), .UNIT(0), .FIFOSIZE(9), .PROT_ENG_FLAGS(0)) vita_rx_chain +   // ///////////////////////////////////////////////////////////////////////// +   // DSP RX 1 + +   wire [31:0] 	 sample_rx1; +   wire 	 strobe_rx1; +   wire [35:0] 	 vita_rx_data1; +   wire 	 vita_rx_src_rdy1, vita_rx_dst_rdy1; +    +   dsp_core_rx #(.BASE(SR_RX_DSP1)) dsp_core_rx1 +     (.clk(wb_clk),.rst(wb_rst), +      .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data), +      .adc_i(adc_i),.adc_ovf_i(0),.adc_q(adc_q),.adc_ovf_q(0), +      .sample(sample_rx1), .run(run_rx1), .strobe(strobe_rx1), +      .debug() ); + +   vita_rx_chain #(.BASE(SR_RX_CTRL1), .UNIT(1), .FIFOSIZE(9), .PROT_ENG_FLAGS(0)) vita_rx_chain1       (.clk(wb_clk),.reset(wb_rst),.clear(clear_rx),        .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data), -      .vita_time(vita_time), .overrun(rx_overrun_dsp), -      .sample(sample_rx), .run(run_rx), .strobe(strobe_rx), -      .rx_data_o(rx_data), .rx_dst_rdy_i(rx_dst_rdy), .rx_src_rdy_o(rx_src_rdy), -      .debug(vr_debug) ); +      .vita_time(vita_time), .overrun(rx_overrun_dsp1), +      .sample(sample_rx1), .run(run_rx1), .strobe(strobe_rx1), +      .rx_data_o(vita_rx_data1), .rx_dst_rdy_i(vita_rx_dst_rdy1), .rx_src_rdy_o(vita_rx_src_rdy1), +      .debug() ); + +   // ///////////////////////////////////////////////////////////////////////// +   // RX Stream muxing + +   fifo36_mux #(.prio(0)) mux_data_streams +     (.clk(wb_clk), .reset(wb_rst), .clear(0), +      .data0_i(vita_rx_data0), .src0_rdy_i(vita_rx_src_rdy0), .dst0_rdy_o(vita_rx_dst_rdy0), +      .data1_i(vita_rx_data1), .src1_rdy_i(vita_rx_src_rdy1), .dst1_rdy_o(vita_rx_dst_rdy1), +      .data_o(rx_data), .src_rdy_o(rx_src_rdy), .dst_rdy_i(rx_dst_rdy));     // ///////////////////////////////////////////////////////////////////////////////////     // 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),  @@ -170,13 +222,16 @@ module u1plus_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(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)); +     // /////////////////////////////////////////////////////////////////////////////////////     // 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, @@ -277,8 +332,8 @@ module u1plus_core  	     reg_test <= s0_dat_mosi;  	   REG_RX_FRAMELEN :  	     frames_per_packet <= s0_dat_mosi[7:0]; -	   REG_XFER_RATE : -	     xfer_rate <= s0_dat_mosi; +	   //REG_XFER_RATE : +	     //xfer_rate <= s0_dat_mosi;  	 endcase // case (s0_adr[6:0])     assign test_ctrl = xfer_rate[11:8]; @@ -300,14 +355,16 @@ module u1plus_core     // /////////////////////////////////////////////////////////////////////////////////////     // Slave 1, UART     //    depth of 3 is 128 entries, clkdiv of 278 gives 230.4k with a 64 MHz system clock -    + +/*        simple_uart #(.TXDEPTH(3),.RXDEPTH(3), .CLKDIV_DEFAULT(278)) uart        (.clk_i(wb_clk),.rst_i(wb_rst),        .we_i(s1_we),.stb_i(s1_stb),.cyc_i(s1_cyc),.ack_o(s1_ack),        .adr_i(s1_adr[3:1]),.dat_i({16'd0,s1_dat_mosi}),.dat_o(s1_dat_miso),        .rx_int_o(),.tx_int_o(),        .tx_o(debug_txd),.rx_i(debug_rxd),.baud_o()); - +*/ +        // /////////////////////////////////////////////////////////////////////////////////////     // Slave 2, SPI @@ -401,9 +458,8 @@ module u1plus_core     // Debug circuitry     assign debug_clk = { gpif_clk, clk_fpga }; -   assign debug = debug0; +   assign debug = 0;     assign debug_gpio_0 = 0;     assign debug_gpio_1 = 0; -   //assign {io_tx,io_rx} = {debug1};  endmodule // u1plus_core diff --git a/usrp2/top/E1x0/Makefile.passthru b/usrp2/top/E1x0/Makefile.passthru deleted file mode 100644 index f2d835608..000000000 --- a/usrp2/top/E1x0/Makefile.passthru +++ /dev/null @@ -1,98 +0,0 @@ -# -# Copyright 2008 Ettus Research LLC -# - -################################################## -# Project Setup -################################################## -TOP_MODULE = passthru -BUILD_DIR = $(abspath build$(ISE)) - -################################################## -# Include other makefiles -################################################## - -include ../Makefile.common -include ../../fifo/Makefile.srcs -include ../../control_lib/Makefile.srcs -include ../../sdr_lib/Makefile.srcs -include ../../serdes/Makefile.srcs -include ../../simple_gemac/Makefile.srcs -include ../../timing/Makefile.srcs -include ../../opencores/Makefile.srcs -include ../../vrt/Makefile.srcs -include ../../udp/Makefile.srcs -include ../../coregen/Makefile.srcs -include ../../gpmc/Makefile.srcs - -################################################## -# Project Properties -################################################## -export PROJECT_PROPERTIES := \ -family "Spartan-3A DSP" \ -device xc3sd1800a \ -package cs484 \ -speed -4 \ -top_level_module_type "HDL" \ -synthesis_tool "XST (VHDL/Verilog)" \ -simulator "ISE Simulator (VHDL/Verilog)" \ -"Preferred Language" "Verilog" \ -"Enable Message Filtering" FALSE \ -"Display Incremental Messages" FALSE  - -################################################## -# Sources -################################################## -TOP_SRCS = \ -passthru.v \ -passthru.ucf - -SOURCES = $(abspath $(TOP_SRCS)) $(FIFO_SRCS) \ -$(CONTROL_LIB_SRCS) $(SDR_LIB_SRCS) $(SERDES_SRCS) \ -$(SIMPLE_GEMAC_SRCS) $(TIMING_SRCS) $(OPENCORES_SRCS) \ -$(VRT_SRCS) $(UDP_SRCS) $(COREGEN_SRCS) \ -$(GPMC_SRCS) - -################################################## -# Process Properties -################################################## -SYNTHESIZE_PROPERTIES = \ -"Number of Clock Buffers" 8 \ -"Pack I/O Registers into IOBs" Yes \ -"Optimization Effort" High \ -"Optimize Instantiated Primitives" TRUE \ -"Register Balancing" Yes \ -"Use Clock Enable" Auto \ -"Use Synchronous Reset" Auto \ -"Use Synchronous Set" Auto - -TRANSLATE_PROPERTIES = \ -"Macro Search Path" "$(shell pwd)/../../coregen/" - -MAP_PROPERTIES = \ -"Allow Logic Optimization Across Hierarchy" TRUE \ -"Map to Input Functions" 4 \ -"Optimization Strategy (Cover Mode)" Speed \ -"Pack I/O Registers/Latches into IOBs" "For Inputs and Outputs" \ -"Perform Timing-Driven Packing and Placement" TRUE \ -"Map Effort Level" High \ -"Extra Effort" Normal \ -"Combinatorial Logic Optimization" TRUE \ -"Register Duplication" TRUE - -PLACE_ROUTE_PROPERTIES = \ -"Place & Route Effort Level (Overall)" High  - -STATIC_TIMING_PROPERTIES = \ -"Number of Paths in Error/Verbose Report" 10 \ -"Report Type" "Error Report" - -GEN_PROG_FILE_PROPERTIES = \ -"Configuration Rate" 6 \ -"Create Binary Configuration File" TRUE \ -"Done (Output Events)" 5 \ -"Enable Bitstream Compression" TRUE \ -"Enable Outputs (Output Events)" 6 \ -"Unused IOB Pins" "Pull Up" - -SIM_MODEL_PROPERTIES = "" diff --git a/usrp2/top/E1x0/core_compile b/usrp2/top/E1x0/core_compile index dc0cd081e..02d7f006e 100755 --- a/usrp2/top/E1x0/core_compile +++ b/usrp2/top/E1x0/core_compile @@ -1,3 +1,3 @@ -iverilog -Wall -y. -y ../../control_lib/ -y ../../fifo/ -y ../../gpmc/ -y ../../models/ -y ../../sdr_lib/ -y ../../coregen/ -y ../../vrt/ -y ../../opencores/i2c/rtl/verilog/ -y ../../opencores/spi/rtl/verilog/ -y ../../timing/ -y ../../opencores/8b10b/ -I ../../opencores/spi/rtl/verilog/ -I ../../opencores/i2c/rtl/verilog/ -y ../../simple_gemac u1e_core.v  2>&1  | grep -v timescale | grep -v coregen | grep -v models +iverilog -Wall -y. -y ../../control_lib/ -y ../../fifo/ -y ../../gpmc/ -y ../../models/ -y ../../sdr_lib/ -y ../../coregen/ -y ../../vrt/ -y ../../opencores/i2c/rtl/verilog/ -y ../../opencores/spi/rtl/verilog/ -y ../../timing/ -y ../../opencores/8b10b/ -I ../../opencores/spi/rtl/verilog/ -I ../../opencores/i2c/rtl/verilog/ -y ../../simple_gemac -y $XILINX/verilog/src/unisims u1e_core.v  2>&1  | grep -v timescale | grep -v coregen | grep -v models diff --git a/usrp2/top/E1x0/passthru.ucf b/usrp2/top/E1x0/passthru.ucf deleted file mode 100644 index 64e6f0440..000000000 --- a/usrp2/top/E1x0/passthru.ucf +++ /dev/null @@ -1,6 +0,0 @@ -NET "overo_gpio145"  LOC = "C7"  ; -NET "cgen_mosi"  LOC = "E22"  ; -NET "cgen_sclk"  LOC = "J19"  ; -NET "cgen_sen_b"  LOC = "H20"  ; -NET "fpga_cfg_din"  LOC = "W17"  ; -NET "fpga_cfg_cclk"  LOC = "V17"  ; diff --git a/usrp2/top/E1x0/passthru.v b/usrp2/top/E1x0/passthru.v deleted file mode 100644 index 486257366..000000000 --- a/usrp2/top/E1x0/passthru.v +++ /dev/null @@ -1,35 +0,0 @@ -// -// 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/>. -// - -`timescale 1ns / 1ps -////////////////////////////////////////////////////////////////////////////////// - -module passthru -  (input overo_gpio145, -   output cgen_sclk, -   output cgen_sen_b, -   output cgen_mosi, -   input fpga_cfg_din, -   input fpga_cfg_cclk -   ); -    -   assign cgen_sclk = fpga_cfg_cclk; -   assign cgen_sen_b = overo_gpio145; -   assign cgen_mosi = fpga_cfg_din; -    -    -endmodule // passthru diff --git a/usrp2/top/E1x0/u1e.v b/usrp2/top/E1x0/u1e.v index adf42fd07..dbd6173f3 100644 --- a/usrp2/top/E1x0/u1e.v +++ b/usrp2/top/E1x0/u1e.v @@ -36,11 +36,12 @@ module u1e     output cgen_sclk, output cgen_sen_b, output cgen_mosi, input cgen_miso,     // Clock gen SPI     input cgen_st_status, input cgen_st_ld, input cgen_st_refmon, output cgen_sync_b, output cgen_ref_sel, +   input overo_gpio65, input overo_gpio128, input overo_gpio145, output overo_gpio147, //aux SPI -   output overo_gpio144, output overo_gpio145, output overo_gpio146, output overo_gpio147,  // Fifo controls +   output overo_gpio144, output overo_gpio146,  // Fifo controls     input overo_gpio0, input overo_gpio14, input overo_gpio21, input overo_gpio22,  // Misc GPIO -   input overo_gpio23, input overo_gpio64, input overo_gpio65, input overo_gpio127, // Misc GPIO -   input overo_gpio128, input overo_gpio163, input overo_gpio170, input overo_gpio176, // Misc GPIO +   input overo_gpio23, input overo_gpio64, input overo_gpio127, // Misc GPIO +   input overo_gpio176, input overo_gpio163, input overo_gpio170, // Misc GPIO     inout [15:0] io_tx, inout [15:0] io_rx, @@ -78,16 +79,26 @@ module u1e                  .CLK2X(), .CLK2X180(),                   .CLK0(clk_fb), .CLK90(clk_fpga), .CLK180(), .CLK270(),                   .LOCKED(dcm_locked), .STATUS()); -    +     // /////////////////////////////////////////////////////////////////////////     // SPI     wire  mosi, sclk, miso;     assign { db_sclk_tx, db_mosi_tx } = ~db_sen_tx ? {sclk,mosi} : 2'b0;     assign { db_sclk_rx, db_mosi_rx } = ~db_sen_rx ? {sclk,mosi} : 2'b0;     assign { sclk_codec, mosi_codec } = ~sen_codec ? {sclk,mosi} : 2'b0; -   assign { cgen_sclk, cgen_mosi } = ~cgen_sen_b ? {sclk,mosi} : 2'b0; +   //assign { cgen_sclk, cgen_mosi } = ~cgen_sen_b ? {sclk,mosi} : 2'b0; //replaced by aux spi     assign miso = (~db_sen_tx & db_miso_tx) | (~db_sen_rx & db_miso_rx) | -		 (~sen_codec & miso_codec) | (~cgen_sen_b & cgen_miso); +                 (~sen_codec & miso_codec) | (~cgen_sen_b & cgen_miso); + +   //assign the aux spi to the cgen (bypasses wishbone) +   assign cgen_sclk = overo_gpio65; +   assign cgen_sen_b = overo_gpio128; +   assign cgen_mosi = overo_gpio145; +   wire proc_int; //re-purpose gpio for interrupt when we are not using aux spi +   assign overo_gpio147 = (cgen_sen_b == 1'b0)? cgen_miso : proc_int; + +   wire _cgen_sen_b; +   //assign cgen_sen_b = _cgen_sen_b; //replaced by aux spi     // /////////////////////////////////////////////////////////////////////////     // TX DAC -- handle the interleaved data bus to DAC, with clock doubling DLL @@ -137,18 +148,15 @@ module u1e  		     .EM_WAIT0(EM_WAIT0), .EM_NCS4(EM_NCS4), .EM_NCS5(EM_NCS5),   		     .EM_NCS6(EM_NCS6), .EM_NWE(EM_NWE), .EM_NOE(EM_NOE),  		     .db_sda(db_sda), .db_scl(db_scl), -		     .sclk(sclk), .sen({cgen_sen_b,sen_codec,db_sen_tx,db_sen_rx}), .mosi(mosi), .miso(miso), +		     .sclk(sclk), .sen({_cgen_sen_b,sen_codec,db_sen_tx,db_sen_rx}), .mosi(mosi), .miso(miso),  		     .cgen_st_status(cgen_st_status), .cgen_st_ld(cgen_st_ld),.cgen_st_refmon(cgen_st_refmon),   		     .cgen_sync_b(cgen_sync_b), .cgen_ref_sel(cgen_ref_sel), -		     .tx_have_space(overo_gpio144), .tx_underrun(overo_gpio145), -		     .rx_have_data(overo_gpio146), .rx_overrun(overo_gpio147), +		     .tx_have_space(overo_gpio144), +		     .rx_have_data(overo_gpio146),  		     .io_tx(io_tx), .io_rx(io_rx),  		     .tx_i(tx_i), .tx_q(tx_q),   		     .rx_i(DA), .rx_q(DB), -		     .misc_gpio( {{overo_gpio128,overo_gpio163,overo_gpio170,overo_gpio176}, -				  {overo_gpio0,overo_gpio14,overo_gpio21,overo_gpio22}, -				  {overo_gpio23,overo_gpio64,overo_gpio65,overo_gpio127}}), -		     .pps_in(PPS_IN) ); +		     .pps_in(PPS_IN), .proc_int(proc_int) );     // /////////////////////////////////////////////////////////////////////////     // Local Debug diff --git a/usrp2/top/E1x0/u1e_core.v b/usrp2/top/E1x0/u1e_core.v index 4c513587b..c4fc16444 100644 --- a/usrp2/top/E1x0/u1e_core.v +++ b/usrp2/top/E1x0/u1e_core.v @@ -31,29 +31,36 @@ module u1e_core     output sclk, output [15:0] sen, output mosi, input miso,     input cgen_st_status, input cgen_st_ld, input cgen_st_refmon, output cgen_sync_b, output cgen_ref_sel,    -   output tx_have_space, output tx_underrun, output rx_have_data, output rx_overrun, +   output tx_have_space, output rx_have_data,     inout [15:0] io_tx, inout [15:0] io_rx,      output [13:0] tx_i, output [13:0] tx_q,      input [11:0] rx_i, input [11:0] rx_q,  -   input [11:0] misc_gpio, input pps_in +   input pps_in, output proc_int     );     localparam TXFIFOSIZE = 13;     localparam RXFIFOSIZE = 13;     // 64 total regs in address space -   localparam SR_RX_CTRL = 0;     // 9 regs (+0 to +8) -   localparam SR_RX_DSP = 16;     // 7 regs (+0 to +6) -   localparam SR_TX_CTRL = 24;    // 6 regs (+0 to +5) -   localparam SR_TX_DSP = 32;     // 5 regs (+0 to +4) -   localparam SR_TIME64 = 40;     // 6 regs (+0 to +5) -   localparam SR_CLEAR_RX_FIFO = 48; // 1 reg -   localparam SR_CLEAR_TX_FIFO = 49; // 1 reg -   localparam SR_GLOBAL_RESET = 50; // 1 reg -   localparam SR_REG_TEST32 = 52; // 1 reg - -   wire [7:0]	COMPAT_NUM = 8'd4; +   localparam SR_RX_CTRL0 = 0;       // 9 regs (+0 to +8) +   localparam SR_RX_DSP0 = 10;       // 4 regs (+0 to +3) +   localparam SR_RX_CTRL1 = 16;      // 9 regs (+0 to +8) +   localparam SR_RX_DSP1 = 26;       // 4 regs (+0 to +3) +   localparam SR_ERR_CTRL = 30;      // 1 reg +   localparam SR_TX_CTRL = 32;       // 4 regs (+0 to +3) +   localparam SR_TX_DSP = 38;        // 3 regs (+0 to +2) + +   localparam SR_TIME64 = 42;        // 6 regs (+0 to +5) +   localparam SR_RX_FRONT = 48;      // 5 regs (+0 to +4) +   localparam SR_TX_FRONT = 54;      // 5 regs (+0 to +4) + +   localparam SR_REG_TEST32 = 60;    // 1 reg +   localparam SR_CLEAR_RX_FIFO = 61; // 1 reg +   localparam SR_CLEAR_TX_FIFO = 62; // 1 reg +   localparam SR_GLOBAL_RESET = 63;  // 1 reg + +   wire [7:0]	COMPAT_NUM = 8'd5;     wire 	wb_clk = clk_fpga;     wire 	wb_rst, global_reset; @@ -69,9 +76,9 @@ module u1e_core     wire 	set_stb;     wire [31:0] 	debug_vt; -   wire 	rx_overrun_dsp, rx_overrun_gpmc, tx_underrun_dsp, tx_underrun_gpmc; -   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_gpmc, tx_underrun_dsp, tx_underrun_gpmc; +   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), @@ -133,44 +140,82 @@ module u1e_core  	 .test_rate(test_rate), .test_ctrl(test_ctrl),  	 .debug(debug_gpmc)); -   wire 	 rx_sof = rx_data[32]; -   wire 	 rx_eof = rx_data[33];     wire 	 rx_src_rdy_int, rx_dst_rdy_int, tx_src_rdy_int, tx_dst_rdy_int;     wire [31:0] 	 debug_rx_dsp, vrc_debug, vrf_debug, vr_debug;     // ///////////////////////////////////////////////////////////////////////// -   // DSP RX -   wire [31:0] 	 sample_rx; -   wire 	 strobe_rx, run_rx; -   wire [35:0] 	 vita_rx_data; -   wire 	 vita_rx_src_rdy, vita_rx_dst_rdy; +   // RX ADC Frontend, does IQ Balance, DC Offset, muxing + +   wire [23:0] 	 adc_i, adc_q;  // 24 bits is total overkill here, but it matches u2/u2p +   wire 	 run_rx, run_rx0, run_rx1; -   dsp_core_rx #(.BASE(SR_RX_DSP)) dsp_core_rx +   rx_frontend #(.BASE(SR_RX_FRONT)) rx_frontend       (.clk(wb_clk),.rst(wb_rst),        .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data), -      .adc_a({rx_i,2'b0}),.adc_ovf_a(0),.adc_b({rx_q,2'b0}),.adc_ovf_b(0), -      .sample(sample_rx), .run(run_rx), .strobe(strobe_rx), -      .debug(debug_rx_dsp) ); +      .adc_a({rx_i,4'b00}),.adc_ovf_a(0), +      .adc_b({rx_q,4'b00}),.adc_ovf_b(0), +      .i_out(adc_i), .q_out(adc_q), .run(run_rx0 | run_rx1), .debug()); +    +   // ///////////////////////////////////////////////////////////////////////// +   // DSP RX 0 -   vita_rx_chain #(.BASE(SR_RX_CTRL), .UNIT(0), .FIFOSIZE(9), .PROT_ENG_FLAGS(0)) vita_rx_chain +   wire [31:0] 	 sample_rx0; +   wire 	 strobe_rx0; +   wire [35:0] 	 vita_rx_data0; +   wire 	 vita_rx_src_rdy0, vita_rx_dst_rdy0; +    +   dsp_core_rx #(.BASE(SR_RX_DSP0)) dsp_core_rx0 +     (.clk(wb_clk),.rst(wb_rst), +      .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data), +      .adc_i(adc_i),.adc_ovf_i(0),.adc_q(adc_q),.adc_ovf_q(0), +      .sample(sample_rx0), .run(run_rx0), .strobe(strobe_rx0), +      .debug() ); + +   vita_rx_chain #(.BASE(SR_RX_CTRL0), .UNIT(0), .FIFOSIZE(9), .PROT_ENG_FLAGS(0)) vita_rx_chain0       (.clk(wb_clk),.reset(wb_rst),.clear(clear_rx),        .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data), -      .vita_time(vita_time), .overrun(rx_overrun_dsp), -      .sample(sample_rx), .run(run_rx), .strobe(strobe_rx), -      .rx_data_o(vita_rx_data), .rx_dst_rdy_i(vita_rx_dst_rdy), .rx_src_rdy_o(vita_rx_src_rdy), -      .debug(vr_debug) ); +      .vita_time(vita_time), .overrun(rx_overrun_dsp0), +      .sample(sample_rx0), .run(run_rx0), .strobe(strobe_rx0), +      .rx_data_o(vita_rx_data0), .rx_dst_rdy_i(vita_rx_dst_rdy0), .rx_src_rdy_o(vita_rx_src_rdy0), +      .debug() ); -   fifo36_mux #(.prio(0)) mux_err_stream +   // ///////////////////////////////////////////////////////////////////////// +   // DSP RX 1 + +   wire [31:0] 	 sample_rx1; +   wire 	 strobe_rx1; +   wire [35:0] 	 vita_rx_data1; +   wire 	 vita_rx_src_rdy1, vita_rx_dst_rdy1; +    +   dsp_core_rx #(.BASE(SR_RX_DSP1)) dsp_core_rx1 +     (.clk(wb_clk),.rst(wb_rst), +      .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data), +      .adc_i(adc_i),.adc_ovf_i(0),.adc_q(adc_q),.adc_ovf_q(0), +      .sample(sample_rx1), .run(run_rx1), .strobe(strobe_rx1), +      .debug() ); + +   vita_rx_chain #(.BASE(SR_RX_CTRL1), .UNIT(1), .FIFOSIZE(9), .PROT_ENG_FLAGS(0)) vita_rx_chain1 +     (.clk(wb_clk),.reset(wb_rst),.clear(clear_rx), +      .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data), +      .vita_time(vita_time), .overrun(rx_overrun_dsp1), +      .sample(sample_rx1), .run(run_rx1), .strobe(strobe_rx1), +      .rx_data_o(vita_rx_data1), .rx_dst_rdy_i(vita_rx_dst_rdy1), .rx_src_rdy_o(vita_rx_src_rdy1), +      .debug() ); + +   // ///////////////////////////////////////////////////////////////////////// +   // RX Stream muxing + +   fifo36_mux #(.prio(0)) mux_data_streams       (.clk(wb_clk), .reset(wb_rst), .clear(0), -      .data0_i(vita_rx_data), .src0_rdy_i(vita_rx_src_rdy), .dst0_rdy_o(vita_rx_dst_rdy), -      .data1_i(tx_err_data), .src1_rdy_i(tx_err_src_rdy), .dst1_rdy_o(tx_err_dst_rdy), +      .data0_i(vita_rx_data0), .src0_rdy_i(vita_rx_src_rdy0), .dst0_rdy_o(vita_rx_dst_rdy0), +      .data1_i(vita_rx_data1), .src1_rdy_i(vita_rx_src_rdy1), .dst1_rdy_o(vita_rx_dst_rdy1),        .data_o(rx_data), .src_rdy_o(rx_src_rdy), .dst_rdy_i(rx_dst_rdy)); -    +     // ///////////////////////////////////////////////////////////////////////////////////     // 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),  @@ -183,13 +228,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(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)); +     // /////////////////////////////////////////////////////////////////////////////////////     // 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, @@ -255,7 +303,7 @@ module u1e_core        .sf_dat_o(sf_dat_mosi),.sf_adr_o(sf_adr),.sf_sel_o(sf_sel),.sf_we_o(sf_we),.sf_cyc_o(sf_cyc),.sf_stb_o(sf_stb),        .sf_dat_i(sf_dat_miso),.sf_ack_i(sf_ack),.sf_err_i(0),.sf_rty_i(0) ); -   assign s5_ack = 0;   assign s9_ack = 0;   assign sa_ack = 0;   assign sb_ack = 0; +   assign s9_ack = 0;   assign sa_ack = 0;   assign sb_ack = 0;     assign sc_ack = 0;   assign sd_ack = 0;   assign se_ack = 0;   assign sf_ack = 0;     // ///////////////////////////////////////////////////////////////////////////////////// @@ -336,7 +384,7 @@ module u1e_core     wire 	scl_pad_i, scl_pad_o, scl_pad_oen_o, sda_pad_i, sda_pad_o, sda_pad_oen_o;     i2c_master_top #(.ARST_LVL(1)) i2c        (.wb_clk_i(wb_clk),.wb_rst_i(wb_rst),.arst_i(1'b0),  -      .wb_adr_i(s3_adr[4:2]),.wb_dat_i(s3_dat_mosi[7:0]),.wb_dat_o(s3_dat_miso[7:0]), +      .wb_adr_i(s3_adr[3:1]),.wb_dat_i(s3_dat_mosi[7:0]),.wb_dat_o(s3_dat_miso[7:0]),        .wb_we_i(s3_we),.wb_stb_i(s3_stb),.wb_cyc_i(s3_cyc),        .wb_ack_o(s3_ack),.wb_inta_o(),        .scl_pad_i(scl_pad_i),.scl_pad_o(scl_pad_o),.scl_padoen_o(scl_pad_oen_o), @@ -361,6 +409,43 @@ module u1e_core  		.atr(atr_lines),.debug_0(debug_gpio_0),.debug_1(debug_gpio_1),  		.gpio( {io_tx,io_rx} ) ); +   //////////////////////////////////////////////////////////////////////////// +   // FIFO to WB slave for async messages - Slave #5 + +   //signals between fifo and buffer module +   wire [35:0] _tx_err_data; +   wire _tx_err_src_rdy, _tx_err_dst_rdy; + +   fifo_cascade #(.WIDTH(36), .SIZE(9/*512 lines plenty for short pkts*/)) err_fifo( +        .clk(wb_clk), .reset(wb_rst), .clear(wb_rst), +        .datain(tx_err_data),   .src_rdy_i(tx_err_src_rdy),   .dst_rdy_o(tx_err_dst_rdy), +        .dataout(_tx_err_data), .src_rdy_o(_tx_err_src_rdy),  .dst_rdy_i(_tx_err_dst_rdy) +   ); + +   wire [31:0] err_status, err_data32; +   //the buffer is 32 bits, but the data is 16, so mux based on the addr bit +   assign s5_dat_miso = (s5_adr[1] == 1'b0)? err_data32[15:0] : err_data32[31:16]; + +   buffer_int2 #(.BASE(SR_ERR_CTRL), .BUF_SIZE(5)) fifo_to_wb( +        .clk(wb_clk), .rst(wb_rst), +        .set_stb(set_stb), .set_addr(set_addr), .set_data(set_data), +        .status(err_status), +        // Wishbone interface to RAM +        .wb_clk_i(wb_clk), .wb_rst_i(wb_rst), +        .wb_we_i(s5_we),   .wb_stb_i(s5_stb), +        .wb_adr_i(s5_adr), .wb_dat_i({16'b0, s5_dat_mosi}), +        .wb_dat_o(err_data32), .wb_ack_o(s5_ack), +        // Write FIFO Interface +        .wr_data_i(_tx_err_data), .wr_ready_i(_tx_err_src_rdy), .wr_ready_o(_tx_err_dst_rdy), +        // Read FIFO Interface +        .rd_data_o(), .rd_ready_o(), .rd_ready_i(1'b0) +    ); + +   //////////////////////////////////////////////////////////////////////////// +   // Interrupts + +   assign proc_int = (|err_status[1:0]); +     // /////////////////////////////////////////////////////////////////////////     // Settings Bus -- Slave #8 + 9 @@ -369,7 +454,7 @@ module u1e_core       (.wb_clk(wb_clk),.wb_rst(wb_rst),.wb_adr_i(s8_adr),.wb_dat_i(s8_dat_mosi),        .wb_stb_i(s8_stb),.wb_we_i(s8_we),.wb_ack_o(s8_ack),        .strobe(set_stb),.addr(set_addr),.data(set_data) ); -    +     // /////////////////////////////////////////////////////////////////////////     // ATR Controller -- Slave #6 @@ -384,8 +469,9 @@ module u1e_core     wire [31:0] reg_test32; +   //this setting reg is persistent across resets, to check for fpga loaded     setting_reg #(.my_addr(SR_REG_TEST32)) sr_reg_test32 -     (.clk(wb_clk),.rst(wb_rst),.strobe(set_stb),.addr(set_addr), +     (.clk(wb_clk),.rst(/*wb_rst*/1'b0),.strobe(set_stb),.addr(set_addr),        .in(set_data),.out(reg_test32),.changed());     wb_readback_mux_16LE readback_mux_32 @@ -394,7 +480,7 @@ module u1e_core        .word00(vita_time[63:32]),        .word01(vita_time[31:0]),        .word02(vita_time_pps[63:32]),    .word03(vita_time_pps[31:0]), -      .word04(reg_test32),              .word05(32'b0), +      .word04(reg_test32),              .word05(err_status),        .word06(32'b0),                   .word07(32'b0),        .word08(32'b0),                   .word09(32'b0),        .word10(32'b0),                   .word11(32'b0), @@ -423,7 +509,7 @@ module u1e_core  */     assign debug = debug_gpmc; -   assign debug_gpio_0 = { {run_tx, 1'b0, run_rx, strobe_rx, tx_i[11:0]},  +   assign debug_gpio_0 = { {run_tx, 1'b0, run_rx, strobe_rx0, tx_i[11:0]},   			   {2'b00, tx_src_rdy, tx_dst_rdy, tx_q[11:0]} };     assign debug_gpio_1 = debug_vt; @@ -431,7 +517,7 @@ module u1e_core  /*        assign debug_gpio_1 = { {rx_enable, rx_src_rdy, rx_dst_rdy, rx_src_rdy & ~rx_dst_rdy},  			   {tx_enable, tx_src_rdy, tx_dst_rdy, tx_dst_rdy & ~tx_src_rdy}, -			   {rx_sof, rx_eof, rx_src_rdy, rx_dst_rdy, rx_data[33:32],2'b0}, +			   {2'b0, rx_src_rdy, rx_dst_rdy, rx_data[33:32],2'b0},  			   {2'b0, bus_error, debug_gpmc[4:0] },  			   {misc_gpio[7:0]} };    */  diff --git a/usrp2/top/N2x0/u2plus_core.v b/usrp2/top/N2x0/u2plus_core.v index 8a7c6ddee..e2142ad06 100644 --- a/usrp2/top/N2x0/u2plus_core.v +++ b/usrp2/top/N2x0/u2plus_core.v @@ -428,7 +428,7 @@ module u2plus_core     // Buffer Pool Status -- Slave #5        //compatibility number -> increment when the fpga has been sufficiently altered -   localparam compat_num = 32'd6; +   localparam compat_num = {16'd7, 16'd0}; //major, minor     wb_readback_mux buff_pool_status       (.wb_clk_i(wb_clk), .wb_rst_i(wb_rst), .wb_stb_i(s5_stb), @@ -584,6 +584,17 @@ module u2plus_core        .sclk_pad_o(spiflash_clk),.mosi_pad_o(spiflash_mosi),.miso_pad_i(spiflash_miso) );     // ///////////////////////////////////////////////////////////////////////// +   // ADC Frontend +   wire [23:0] 	 adc_i, adc_q; +    +   rx_frontend #(.BASE(SR_RX_FRONT)) rx_frontend +     (.clk(dsp_clk),.rst(dsp_rst), +      .set_stb(set_stb_dsp),.set_addr(set_addr_dsp),.set_data(set_data_dsp), +      .adc_a({adc_a,2'b00}),.adc_ovf_a(adc_ovf_a), +      .adc_b({adc_b,2'b00}),.adc_ovf_b(adc_ovf_b), +      .i_out(adc_i), .q_out(adc_q), .run(run_rx0_d1 | run_rx1_d1), .debug()); +    +   // /////////////////////////////////////////////////////////////////////////     // DSP RX 0     wire [31:0] 	 sample_rx0;     wire 	 clear_rx0, strobe_rx0; @@ -594,7 +605,7 @@ module u2plus_core     dsp_core_rx #(.BASE(SR_RX_DSP0)) dsp_core_rx0       (.clk(dsp_clk),.rst(dsp_rst),        .set_stb(set_stb_dsp),.set_addr(set_addr_dsp),.set_data(set_data_dsp), -      .adc_a(adc_a),.adc_ovf_a(adc_ovf_a),.adc_b(adc_b),.adc_ovf_b(adc_ovf_b), +      .adc_i(adc_i),.adc_ovf_i(adc_ovf_a),.adc_q(adc_q),.adc_ovf_q(adc_ovf_b),        .sample(sample_rx0), .run(run_rx0_d1), .strobe(strobe_rx0),        .debug() ); @@ -622,7 +633,7 @@ module u2plus_core     dsp_core_rx #(.BASE(SR_RX_DSP1)) dsp_core_rx1       (.clk(dsp_clk),.rst(dsp_rst),        .set_stb(set_stb_dsp),.set_addr(set_addr_dsp),.set_data(set_data_dsp), -      .adc_a(adc_a),.adc_ovf_a(adc_ovf_a),.adc_b(adc_b),.adc_ovf_b(adc_ovf_b), +      .adc_i(adc_i),.adc_ovf_i(adc_ovf_a),.adc_q(adc_q),.adc_ovf_q(adc_ovf_b),        .sample(sample_rx1), .run(run_rx1_d1), .strobe(strobe_rx1),        .debug() ); @@ -676,6 +687,8 @@ module u2plus_core  	.debug(debug_extfifo),  	.debug2(debug_extfifo2) ); +   wire [23:0] 	 tx_i, tx_q; +        vita_tx_chain #(.BASE_CTRL(SR_TX_CTRL), .BASE_DSP(SR_TX_DSP),   		   .REPORT_ERROR(1), .DO_FLOW_CONTROL(1),  		   .PROT_ENG_FLAGS(1), .USE_TRANS_HEADER(1), @@ -686,10 +699,16 @@ module u2plus_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(dac_a),.dac_b(dac_b), +      .tx_i(tx_i),.tx_q(tx_q),        .underrun(underrun), .run(run_tx),        .debug(debug_vt)); -    + +   tx_frontend #(.BASE(SR_TX_FRONT)) tx_frontend +     (.clk(dsp_clk), .rst(dsp_rst), +      .set_stb(set_stb_dsp),.set_addr(set_addr_dsp),.set_data(set_data_dsp), +      .tx_i(tx_i), .tx_q(tx_q), .run(1'b1), +      .dac_a(dac_a), .dac_b(dac_b)); +              // ///////////////////////////////////////////////////////////////////////////////////     // SERDES diff --git a/usrp2/top/USRP2/u2_core.v b/usrp2/top/USRP2/u2_core.v index ca9762ac5..2e3d41731 100644 --- a/usrp2/top/USRP2/u2_core.v +++ b/usrp2/top/USRP2/u2_core.v @@ -283,7 +283,7 @@ module u2_core        .sf_dat_o(sf_dat_o),.sf_adr_o(sf_adr),.sf_sel_o(sf_sel),.sf_we_o(sf_we),.sf_cyc_o(sf_cyc),.sf_stb_o(sf_stb),        .sf_dat_i(sf_dat_i),.sf_ack_i(sf_ack),.sf_err_i(0),.sf_rty_i(0)); -   ////////////////////////////////////////////////////////////////////////////////////////// +   // ////////////////////////////////////////////////////////////////////////////////////////     // Reset Controller     system_control sysctrl (.wb_clk_i(wb_clk), // .por_i(por),  			   .ram_loader_rst_o(ram_loader_rst), @@ -433,7 +433,7 @@ module u2_core     // Buffer Pool Status -- Slave #5        //compatibility number -> increment when the fpga has been sufficiently altered -   localparam compat_num = 32'd6; +   localparam compat_num = {16'd7, 16'd0}; //major, minor     wb_readback_mux buff_pool_status       (.wb_clk_i(wb_clk), .wb_rst_i(wb_rst), .wb_stb_i(s5_stb), @@ -583,6 +583,17 @@ module u2_core     assign sd_dat_i[31:8] = 0;     // ///////////////////////////////////////////////////////////////////////// +   // ADC Frontend +   wire [23:0] 	 adc_i, adc_q; +    +   rx_frontend #(.BASE(SR_RX_FRONT)) rx_frontend +     (.clk(dsp_clk),.rst(dsp_rst), +      .set_stb(set_stb_dsp),.set_addr(set_addr_dsp),.set_data(set_data_dsp), +      .adc_a({adc_a,2'b00}),.adc_ovf_a(adc_ovf_a), +      .adc_b({adc_b,2'b00}),.adc_ovf_b(adc_ovf_b), +      .i_out(adc_i), .q_out(adc_q), .run(run_rx0_d1 | run_rx1_d1), .debug()); +    +   // /////////////////////////////////////////////////////////////////////////     // DSP RX 0     wire [31:0] 	 sample_rx0;     wire 	 clear_rx0, strobe_rx0; @@ -593,7 +604,7 @@ module u2_core     dsp_core_rx #(.BASE(SR_RX_DSP0)) dsp_core_rx0       (.clk(dsp_clk),.rst(dsp_rst),        .set_stb(set_stb_dsp),.set_addr(set_addr_dsp),.set_data(set_data_dsp), -      .adc_a(adc_a),.adc_ovf_a(adc_ovf_a),.adc_b(adc_b),.adc_ovf_b(adc_ovf_b), +      .adc_i(adc_i),.adc_ovf_i(adc_ovf_a),.adc_q(adc_q),.adc_ovf_q(adc_ovf_b),        .sample(sample_rx0), .run(run_rx0_d1), .strobe(strobe_rx0),        .debug() ); @@ -621,7 +632,7 @@ module u2_core     dsp_core_rx #(.BASE(SR_RX_DSP1)) dsp_core_rx1       (.clk(dsp_clk),.rst(dsp_rst),        .set_stb(set_stb_dsp),.set_addr(set_addr_dsp),.set_data(set_data_dsp), -      .adc_a(adc_a),.adc_ovf_a(adc_ovf_a),.adc_b(adc_b),.adc_ovf_b(adc_ovf_b), +      .adc_i(adc_i),.adc_ovf_i(adc_ovf_a),.adc_q(adc_q),.adc_ovf_q(adc_ovf_b),        .sample(sample_rx1), .run(run_rx1_d1), .strobe(strobe_rx1),        .debug() ); @@ -673,6 +684,8 @@ module u2_core  	.debug(debug_extfifo),  	.debug2(debug_extfifo2) ); +   wire [23:0] 	 tx_i, tx_q; +        vita_tx_chain #(.BASE_CTRL(SR_TX_CTRL), .BASE_DSP(SR_TX_DSP),   		   .REPORT_ERROR(1), .DO_FLOW_CONTROL(1),  		   .PROT_ENG_FLAGS(1), .USE_TRANS_HEADER(1), @@ -683,10 +696,16 @@ module u2_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(dac_a),.dac_b(dac_b), +      .tx_i(tx_i),.tx_q(tx_q),        .underrun(underrun), .run(run_tx),        .debug(debug_vt)); -    + +   tx_frontend #(.BASE(SR_TX_FRONT)) tx_frontend +     (.clk(dsp_clk), .rst(dsp_rst), +      .set_stb(set_stb_dsp),.set_addr(set_addr_dsp),.set_data(set_data_dsp), +      .tx_i(tx_i), .tx_q(tx_q), .run(1'b1), +      .dac_a(dac_a), .dac_b(dac_b)); +              // ///////////////////////////////////////////////////////////////////////////////////     // SERDES diff --git a/usrp2/vrt/vita_tx_chain.v b/usrp2/vrt/vita_tx_chain.v index 542968afa..ac9f08fc8 100644 --- a/usrp2/vrt/vita_tx_chain.v +++ b/usrp2/vrt/vita_tx_chain.v @@ -29,7 +29,7 @@ module vita_tx_chain      input [63:0] vita_time,      input [35:0] tx_data_i, input tx_src_rdy_i, output tx_dst_rdy_o,      output [35:0] err_data_o, output err_src_rdy_o, input err_dst_rdy_i, -    output [15:0] dac_a, output [15:0] dac_b, +    output [23:0] tx_i, output [23:0] tx_q,      output underrun, output run,      output [31:0] debug); @@ -84,7 +84,7 @@ module vita_tx_chain       (.clk(clk),.rst(reset),        .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data),        .sample(sample_tx), .run(run), .strobe(strobe_tx), -      .dac_a(dac_a),.dac_b(dac_b), +      .tx_i(tx_i),.tx_q(tx_q),        .debug(debug_tx_dsp) );     wire [35:0] 		flow_data, err_data_int; | 
