aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosh Blum <josh@joshknows.com>2011-07-08 12:14:53 -0700
committerJosh Blum <josh@joshknows.com>2011-07-08 12:14:53 -0700
commit4ea6f7431e09d9f27ecaa1c1b187d2c2f613e8f4 (patch)
treed2e66eb4e5f7cf7f8ab033f5482a6f2477aa88b6
parentdd41da159157afe417e7f3b77ba30e189eb510fe (diff)
parentfbc01138d5f943b06ce1bf3f746287b9d6c7789d (diff)
downloaduhd-4ea6f7431e09d9f27ecaa1c1b187d2c2f613e8f4.tar.gz
uhd-4ea6f7431e09d9f27ecaa1c1b187d2c2f613e8f4.tar.bz2
uhd-4ea6f7431e09d9f27ecaa1c1b187d2c2f613e8f4.zip
Merge branch 'b100_shrink' into next
-rw-r--r--usrp2/sdr_lib/Makefile.srcs8
-rw-r--r--usrp2/sdr_lib/add2_and_clip.v12
-rw-r--r--usrp2/sdr_lib/add2_and_clip_reg.v25
-rw-r--r--usrp2/sdr_lib/dsp_core_rx.v135
-rw-r--r--usrp2/sdr_lib/dsp_core_rx_tb.v73
-rw-r--r--usrp2/sdr_lib/dsp_core_tx.v24
-rw-r--r--usrp2/sdr_lib/hb_dec.v121
-rw-r--r--usrp2/sdr_lib/hb_dec_tb.v10
-rw-r--r--usrp2/sdr_lib/input.dat276
-rw-r--r--usrp2/sdr_lib/round.v4
-rw-r--r--usrp2/sdr_lib/round_reg.v13
-rw-r--r--usrp2/sdr_lib/round_sd.v22
-rw-r--r--usrp2/sdr_lib/round_sd_tb.v58
-rw-r--r--usrp2/sdr_lib/rx_dcoffset.v43
-rw-r--r--usrp2/sdr_lib/rx_dcoffset_tb.v20
-rw-r--r--usrp2/sdr_lib/rx_frontend.v73
-rw-r--r--usrp2/sdr_lib/rx_frontend_tb.v45
-rw-r--r--usrp2/sdr_lib/small_hb_dec.v70
-rw-r--r--usrp2/sdr_lib/tx_frontend.v86
-rw-r--r--usrp2/top/B100/u1plus_core.v144
-rw-r--r--usrp2/top/E1x0/Makefile.passthru98
-rwxr-xr-xusrp2/top/E1x0/core_compile2
-rw-r--r--usrp2/top/E1x0/passthru.ucf6
-rw-r--r--usrp2/top/E1x0/passthru.v35
-rw-r--r--usrp2/top/E1x0/u1e.v34
-rw-r--r--usrp2/top/E1x0/u1e_core.v184
-rw-r--r--usrp2/top/N2x0/u2plus_core.v29
-rw-r--r--usrp2/top/USRP2/u2_core.v31
-rw-r--r--usrp2/vrt/vita_tx_chain.v4
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 92915814c..4f85b7d6e 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(clk_2x), .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 00335d118..d481867e3 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;