summaryrefslogtreecommitdiff
path: root/gr-sounder
diff options
context:
space:
mode:
Diffstat (limited to 'gr-sounder')
-rw-r--r--gr-sounder/src/fpga/lib/Makefile.am1
-rw-r--r--gr-sounder/src/fpga/lib/dac_interface.v4
-rw-r--r--gr-sounder/src/fpga/lib/lfsr.v4
-rw-r--r--[-rwxr-xr-x]gr-sounder/src/fpga/lib/lfsr_constants.v66
-rw-r--r--gr-sounder/src/fpga/lib/sounder.v34
-rw-r--r--gr-sounder/src/fpga/lib/sounder_ctrl.v97
-rw-r--r--gr-sounder/src/fpga/lib/sounder_rx.v74
-rw-r--r--gr-sounder/src/fpga/lib/sounder_tx.v11
-rw-r--r--gr-sounder/src/fpga/lib/strobe.v48
-rw-r--r--gr-sounder/src/fpga/tb/sounder_tb.sav47
-rwxr-xr-xgr-sounder/src/fpga/tb/sounder_tb.sh5
-rw-r--r--gr-sounder/src/fpga/tb/sounder_tb.v76
-rw-r--r--[-rwxr-xr-x]gr-sounder/src/fpga/top/usrp_sounder.qsf9
-rwxr-xr-xgr-sounder/src/fpga/top/usrp_sounder.rbfbin112186 -> 113716 bytes
-rw-r--r--gr-sounder/src/fpga/top/usrp_sounder.v8
-rw-r--r--gr-sounder/src/python/sounder.py40
-rwxr-xr-xgr-sounder/src/python/usrp_sounder.py15
17 files changed, 334 insertions, 205 deletions
diff --git a/gr-sounder/src/fpga/lib/Makefile.am b/gr-sounder/src/fpga/lib/Makefile.am
index 0a03147a27..1c8f39ba14 100644
--- a/gr-sounder/src/fpga/lib/Makefile.am
+++ b/gr-sounder/src/fpga/lib/Makefile.am
@@ -25,6 +25,7 @@ EXTRA_DIST = \
dac_interface.v \
dacpll.v \
sounder.v \
+ sounder_ctrl.v \
sounder_rx.v \
sounder_tx.v
diff --git a/gr-sounder/src/fpga/lib/dac_interface.v b/gr-sounder/src/fpga/lib/dac_interface.v
index 9042e1c53d..93c72cca69 100644
--- a/gr-sounder/src/fpga/lib/dac_interface.v
+++ b/gr-sounder/src/fpga/lib/dac_interface.v
@@ -43,11 +43,11 @@ module dac_interface(clk_i,rst_i,ena_i,strobe_i,tx_i_i,tx_q_i,tx_data_o,tx_sync_
// Register the clk64 clock in the clk128 domain
always @(posedge clk128)
- clk64_d <= clk_i;
+ clk64_d <= #1 clk_i;
// Register the tx data in the clk128 domain
always @(posedge clk128)
- tx_data_o <= clk64_d ? tx_i_i : tx_q_i;
+ tx_data_o <= #1 clk64_d ? tx_i_i : tx_q_i;
assign tx_sync_o = clk64_d;
diff --git a/gr-sounder/src/fpga/lib/lfsr.v b/gr-sounder/src/fpga/lib/lfsr.v
index 6ae967ba93..bd0743e9cd 100644
--- a/gr-sounder/src/fpga/lib/lfsr.v
+++ b/gr-sounder/src/fpga/lib/lfsr.v
@@ -36,10 +36,10 @@ module lfsr(clk_i,rst_i,ena_i,strobe_i,mask_i,pn_o);
always @(posedge clk_i)
if (rst_i | ~ena_i)
- shifter <= 1;
+ shifter <= #5 1;
else
if (strobe_i)
- shifter <= {shifter[width-2:0],parity};
+ shifter <= #5 {shifter[width-2:0],parity};
assign pn_o = shifter[0];
diff --git a/gr-sounder/src/fpga/lib/lfsr_constants.v b/gr-sounder/src/fpga/lib/lfsr_constants.v
index 55ee613d28..e23ed66011 100755..100644
--- a/gr-sounder/src/fpga/lib/lfsr_constants.v
+++ b/gr-sounder/src/fpga/lib/lfsr_constants.v
@@ -19,33 +19,45 @@
// Foundation, Inc., 51 Franklin Street, Boston, MA 02110-1301 USA
//
-module lfsr_constants(degree_i,mask_o,len_o);
- input wire [4:0] degree_i;
- output reg [15:0] mask_o;
- output wire [15:0] len_o;
-
- assign len_o = (1 << degree_i) - 1;
+module lfsr_constants(clk_i,rst_i,degree_i,mask_o,len_o);
+ input clk_i;
+ input rst_i;
+ input [4:0] degree_i;
+ output reg [15:0] mask_o;
+ output reg [16:0] len_o;
+
+ integer len;
- always @*
- case (degree_i)
- 5'd00: mask_o = 16'h0000;
- 5'd01: mask_o = 16'h0001;
- 5'd02: mask_o = 16'h0003;
- 5'd03: mask_o = 16'h0005;
- 5'd04: mask_o = 16'h0009;
- 5'd05: mask_o = 16'h0012;
- 5'd06: mask_o = 16'h0021;
- 5'd07: mask_o = 16'h0041;
- 5'd08: mask_o = 16'h008E;
- 5'd09: mask_o = 16'h0108;
- 5'd10: mask_o = 16'h0204;
- 5'd11: mask_o = 16'h0402;
- 5'd12: mask_o = 16'h0829;
- 5'd13: mask_o = 16'h100D;
- 5'd14: mask_o = 16'h2015;
- 5'd15: mask_o = 16'h4001;
- 5'd16: mask_o = 16'h8016;
- default: mask_o = 16'h0000;
- endcase // case(degree_i)
+ always @(posedge clk_i)
+ if (rst_i)
+ begin
+ len_o <= #5 17'b0;
+ mask_o <= #5 16'b0;
+ end
+ else
+ begin
+ len_o <= #5 ((1 << degree_i) << 1)-3;
+
+ case (degree_i)
+ 5'd00: mask_o <= #5 16'h0000;
+ 5'd01: mask_o <= #5 16'h0001;
+ 5'd02: mask_o <= #5 16'h0003;
+ 5'd03: mask_o <= #5 16'h0005;
+ 5'd04: mask_o <= #5 16'h0009;
+ 5'd05: mask_o <= #5 16'h0012;
+ 5'd06: mask_o <= #5 16'h0021;
+ 5'd07: mask_o <= #5 16'h0041;
+ 5'd08: mask_o <= #5 16'h008E;
+ 5'd09: mask_o <= #5 16'h0108;
+ 5'd10: mask_o <= #5 16'h0204;
+ 5'd11: mask_o <= #5 16'h0402;
+ 5'd12: mask_o <= #5 16'h0829;
+ 5'd13: mask_o <= #5 16'h100D;
+ 5'd14: mask_o <= #5 16'h2015;
+ 5'd15: mask_o <= #5 16'h4001;
+ 5'd16: mask_o <= #5 16'h8016;
+ default: mask_o <= #5 16'h0000;
+ endcase // case(degree_i)
+ end // else: !if(rst_i)
endmodule // lfsr_constants
diff --git a/gr-sounder/src/fpga/lib/sounder.v b/gr-sounder/src/fpga/lib/sounder.v
index 58b563448d..675be88816 100644
--- a/gr-sounder/src/fpga/lib/sounder.v
+++ b/gr-sounder/src/fpga/lib/sounder.v
@@ -23,8 +23,8 @@
`include "../../../../usrp/firmware/include/fpga_regs_standard.v"
module sounder(clk_i, saddr_i, sdata_i, s_strobe_i,
- tx_strobe_i, tx_dac_i_o,tx_dac_q_o,
- rx_strobe_i, rx_adc_i_i,rx_adc_q_i,
+ tx_strobe_o, tx_dac_i_o, tx_dac_q_o,
+ rx_adc_i_i,rx_adc_q_i,
rx_strobe_o, rx_imp_i_o,rx_imp_q_o);
// System interface
@@ -34,12 +34,11 @@ module sounder(clk_i, saddr_i, sdata_i, s_strobe_i,
input s_strobe_i; // Configuration bus write
// Transmit subsystem
- input tx_strobe_i; // Generate an transmitter output sample
+ output tx_strobe_o; // Generate an transmitter output sample
output [13:0] tx_dac_i_o; // I channel transmitter output to DAC
output [13:0] tx_dac_q_o; // Q channel transmitter output to DAC
// Receive subsystem
- input rx_strobe_i; // Indicates receive sample ready from ADC
output rx_strobe_o; // Indicates output samples ready for Rx FIFO
input [15:0] rx_adc_i_i; // I channel input from ADC interface module
input [15:0] rx_adc_q_i; // Q channel input from ADC interface module
@@ -53,18 +52,17 @@ module sounder(clk_i, saddr_i, sdata_i, s_strobe_i,
wire loopback;
wire [4:0] degree;
+ wire [13:0] ampl;
wire [15:0] mask;
- wire [15:0] len;
-
- setting_reg #(`FR_USER_0) sr_mode
- ( .clock(clk_i),.reset(1'b0),.strobe(s_strobe_i),.addr(saddr_i),.in(sdata_i),
- .out({loopback,receive,transmit,reset}) );
-
- setting_reg #(`FR_USER_1) sr_lfsr_degree
- ( .clock(clk_i),.reset(1'b0),.strobe(s_strobe_i),.addr(saddr_i),.in(sdata_i),.out(degree) );
-
- lfsr_constants constants(.degree_i(degree),.mask_o(mask),.len_o(len));
+ wire ref_strobe;
+ wire sum_strobe;
+ sounder_ctrl master(.clk_i(clk_i),.rst_i(reset),.saddr_i(saddr_i),
+ .sdata_i(sdata_i),.s_strobe_i(s_strobe_i),
+ .reset_o(reset),.transmit_o(transmit),.receive_o(receive),.loopback_o(loopback),
+ .degree_o(degree),.ampl_o(ampl),.mask_o(mask),.tx_strobe_o(tx_strobe_o),
+ .rx_strobe_o(rx_strobe_o),.sum_strobe_o(sum_strobe),.ref_strobe_o(ref_strobe));
+
// Loopback implementation
wire [13:0] tx_i, tx_q;
wire [15:0] tx_i_ext, tx_q_ext;
@@ -80,13 +78,13 @@ module sounder(clk_i, saddr_i, sdata_i, s_strobe_i,
sounder_tx transmitter
( .clk_i(clk_i),.rst_i(reset),.ena_i(transmit),
- .strobe_i(tx_strobe_i),.mask_i(mask),
+ .strobe_i(tx_strobe_o),.mask_i(mask),.ampl_i(ampl),
.tx_i_o(tx_i),.tx_q_o(tx_q) );
sounder_rx receiver
( .clk_i(clk_i),.rst_i(reset),.ena_i(receive),
- .rx_strobe_i(rx_strobe_i),.tx_strobe_i(tx_strobe_i),.mask_i(mask),.degree_i(degree),.len_i(len),
- .rx_in_i_i(rx_i),.rx_in_q_i(rx_q),.rx_i_o(rx_imp_i_o),.rx_q_o(rx_imp_q_o),
- .rx_strobe_o(rx_strobe_o),.loop_i(loopback));
+ .sum_strobe_i(sum_strobe),.ref_strobe_i(ref_strobe),
+ .mask_i(mask),.degree_i(degree),
+ .rx_in_i_i(rx_i),.rx_in_q_i(rx_q),.rx_i_o(rx_imp_i_o),.rx_q_o(rx_imp_q_o));
endmodule // sounder
diff --git a/gr-sounder/src/fpga/lib/sounder_ctrl.v b/gr-sounder/src/fpga/lib/sounder_ctrl.v
new file mode 100644
index 0000000000..6e967a5ba7
--- /dev/null
+++ b/gr-sounder/src/fpga/lib/sounder_ctrl.v
@@ -0,0 +1,97 @@
+// -*- verilog -*-
+//
+// USRP - Universal Software Radio Peripheral
+//
+// Copyright (C) 2007 Corgan Enterprises 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 2 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, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Boston, MA 02110-1301 USA
+//
+
+`include "../../../../usrp/firmware/include/fpga_regs_common.v"
+`include "../../../../usrp/firmware/include/fpga_regs_standard.v"
+
+module sounder_ctrl(clk_i,rst_i,saddr_i,sdata_i,s_strobe_i,
+ reset_o,transmit_o,receive_o,loopback_o,
+ degree_o,ampl_o,mask_o,
+ tx_strobe_o,rx_strobe_o,sum_strobe_o,ref_strobe_o);
+
+ input clk_i; // Master clock @ 64 MHz
+ input rst_i; // Master synchronous reset
+ input [6:0] saddr_i; // Configuration bus address
+ input [31:0] sdata_i; // Configuration bus data
+ input s_strobe_i; // Configuration bus write
+ output reset_o;
+ output transmit_o;
+ output receive_o;
+ output loopback_o;
+ output [4:0] degree_o;
+ output [13:0] ampl_o;
+ output [15:0] mask_o;
+ output tx_strobe_o;
+ output rx_strobe_o;
+ output sum_strobe_o;
+ output ref_strobe_o;
+
+ setting_reg #(`FR_USER_0) sr_mode
+ ( .clock(clk_i),.reset(1'b0),.strobe(s_strobe_i),.addr(saddr_i),.in(sdata_i),
+ .out({loopback_o,receive_o,transmit_o,reset_o}) );
+
+ setting_reg #(`FR_USER_1) sr_lfsr_degree
+ ( .clock(clk_i),.reset(1'b0),.strobe(s_strobe_i),.addr(saddr_i),.in(sdata_i),
+ .out(degree_o) );
+
+ setting_reg #(`FR_USER_2) sr_lfsr_ampl
+ ( .clock(clk_i),.reset(1'b0),.strobe(s_strobe_i),.addr(saddr_i),.in(sdata_i),
+ .out(ampl_o) );
+
+ wire [16:0] len;
+ lfsr_constants constants
+ (.clk_i(clk_i),.rst_i(rst_i),.degree_i(degree_o),.mask_o(mask_o),
+ .len_o(len) );
+
+ reg [15:0] phase;
+ assign tx_strobe_o = ~phase[0];
+ assign ref_strobe_o = tx_strobe_o & !(phase>>1 == len>>1);
+ assign sum_strobe_o = (phase == len);
+
+ reg rx_strobe_o;
+ always @(posedge clk_i)
+ if (rst_i)
+ begin
+ phase <= #5 16'hFFFF;
+ rx_strobe_o <= #5 0;
+ end
+ else
+ if (sum_strobe_o)
+ begin
+ phase <= #5 0;
+ rx_strobe_o <= #5 1'b1;
+ end
+ else
+ begin
+ phase <= #5 phase + 16'b1;
+ rx_strobe_o <= #5 0;
+ end
+
+
+
+
+
+
+
+
+
+
+endmodule // sounder_ctrl
diff --git a/gr-sounder/src/fpga/lib/sounder_rx.v b/gr-sounder/src/fpga/lib/sounder_rx.v
index 338afd55e5..18038a3a1a 100644
--- a/gr-sounder/src/fpga/lib/sounder_rx.v
+++ b/gr-sounder/src/fpga/lib/sounder_rx.v
@@ -19,75 +19,63 @@
// Foundation, Inc., 51 Franklin Street, Boston, MA 02110-1301 USA
//
-module sounder_rx(clk_i,rst_i,ena_i,rx_strobe_i,tx_strobe_i,mask_i,degree_i,len_i,
- rx_in_i_i,rx_in_q_i,rx_i_o,rx_q_o,rx_strobe_o,
- loop_i);
+module sounder_rx(clk_i,rst_i,ena_i,sum_strobe_i,ref_strobe_i,
+ mask_i,degree_i,rx_in_i_i,rx_in_q_i,rx_i_o,rx_q_o);
input clk_i; // Master clock
input rst_i; // Subsystem reset
input ena_i; // Subsystem enable
- input rx_strobe_i; // Strobe every received sample
- input tx_strobe_i; // Strobe every transmitted sample
+ input sum_strobe_i; // Strobe on last sample per period
+ input ref_strobe_i; // PN code reference retarded one sample per period
input [15:0] mask_i; // PN code LFSR mask
input [4:0] degree_i; // PN code LFSR sequency degree
- input [15:0] len_i; // PN code LFSR sequence length
+
input [15:0] rx_in_i_i; // I channel on receive
input [15:0] rx_in_q_i; // Q channel on receive
output [15:0] rx_i_o; // I channel of impulse response
output [15:0] rx_q_o; // Q channel of impulse response
- output rx_strobe_o; // Impulse response value ready
-
- input loop_i; // Implement loopback
-
- wire strobe_in = loop_i ? tx_strobe_i : rx_strobe_i;
- wire [16:0] len = loop_i ? (len_i - 1) : ((len_i << 1) - 2);
-
- strobe #(17) phase_strobe(.clk_i(clk_i),.rst_i(rst_i),.ena_i(ena_i),
- .rate_i(len),.strobe_i(strobe_in),.strobe_o(rx_strobe_o),
- .count_o());
-
- wire pn_ref;
- wire ref_strobe = tx_strobe_i & ~rx_strobe_o; // Retard reference phase once per period
- lfsr ref_code
- ( .clk_i(clk_i),.rst_i(rst_i),.ena_i(ena_i),.strobe_i(ref_strobe),.mask_i(mask_i),.pn_o(pn_ref) );
- wire [5:0] offset = (5'd16-degree_i);
-
reg [31:0] sum_i, sum_q;
reg [31:0] total_i, total_q;
- wire [31:0] scaled_i = total_i << offset;
- wire [31:0] scaled_q = total_q << offset;
wire [31:0] i_ext, q_ext;
sign_extend #(16,32) i_extender(rx_in_i_i, i_ext);
sign_extend #(16,32) q_extender(rx_in_q_i, q_ext);
+ wire pn_ref;
+ lfsr ref_code
+ ( .clk_i(clk_i),.rst_i(rst_i),.ena_i(ena_i),.strobe_i(ref_strobe_i),.mask_i(mask_i),.pn_o(pn_ref) );
+
wire [31:0] prod_i = pn_ref ? i_ext : -i_ext;
wire [31:0] prod_q = pn_ref ? q_ext : -q_ext;
-
+
always @(posedge clk_i)
if (rst_i | ~ena_i)
begin
- sum_i <= 0;
- sum_q <= 0;
- total_i <= 0;
- total_q <= 0;
+ sum_i <= #5 0;
+ sum_q <= #5 0;
+ total_i <= #5 0;
+ total_q <= #5 0;
end
- else if (rx_strobe_o)
- begin
- total_i <= sum_i + prod_i;
- total_q <= sum_q + prod_q;
- sum_i <= 0;
- sum_q <= 0;
- end
- else if (strobe_in)
- begin
- sum_i = sum_i + prod_i;
- sum_q = sum_q + prod_q;
- end
-
+ else
+ if (sum_strobe_i)
+ begin
+ total_i <= #5 sum_i;
+ total_q <= #5 sum_q;
+ sum_i <= #5 prod_i;
+ sum_q <= #5 prod_q;
+ end
+ else
+ begin
+ sum_i <= #5 sum_i + prod_i;
+ sum_q <= #5 sum_q + prod_q;
+ end
+
+ wire [5:0] offset = (5'd16-degree_i);
+ wire [31:0] scaled_i = total_i << offset;
+ wire [31:0] scaled_q = total_q << offset;
assign rx_i_o = scaled_i[31:16];
assign rx_q_o = scaled_q[31:16];
diff --git a/gr-sounder/src/fpga/lib/sounder_tx.v b/gr-sounder/src/fpga/lib/sounder_tx.v
index 46165dde5f..148b1e5007 100644
--- a/gr-sounder/src/fpga/lib/sounder_tx.v
+++ b/gr-sounder/src/fpga/lib/sounder_tx.v
@@ -22,24 +22,23 @@
`include "../../../../usrp/firmware/include/fpga_regs_common.v"
`include "../../../../usrp/firmware/include/fpga_regs_standard.v"
-`define MAX_VALUE 14'h1FFF // 2s complement
-`define MIN_VALUE 14'h2001
-
-module sounder_tx(clk_i,rst_i,ena_i,strobe_i,mask_i,tx_i_o,tx_q_o);
+module sounder_tx(clk_i,rst_i,ena_i,strobe_i,ampl_i,mask_i,tx_i_o,tx_q_o);
input clk_i;
input rst_i;
input ena_i;
input strobe_i;
+ input [13:0] ampl_i;
input [15:0] mask_i;
output [13:0] tx_i_o;
output [13:0] tx_q_o;
wire pn;
-
+ wire [13:0] min_value = (~ampl_i)+14'b1;
+
lfsr pn_code
( .clk_i(clk_i),.rst_i(rst_i),.ena_i(ena_i),.strobe_i(strobe_i),.mask_i(mask_i),.pn_o(pn) );
- assign tx_i_o = ena_i ? (pn ? `MAX_VALUE : `MIN_VALUE) : 14'b0; // Bipolar
+ assign tx_i_o = ena_i ? (pn ? ampl_i : min_value) : 14'b0; // Bipolar
assign tx_q_o = 14'b0;
endmodule // sounder_tx
diff --git a/gr-sounder/src/fpga/lib/strobe.v b/gr-sounder/src/fpga/lib/strobe.v
deleted file mode 100644
index ed07f21f46..0000000000
--- a/gr-sounder/src/fpga/lib/strobe.v
+++ /dev/null
@@ -1,48 +0,0 @@
-// -*- verilog -*-
-//
-// USRP - Universal Software Radio Peripheral
-//
-// Copyright (C) 2007 Corgan Enterprises 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 2 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, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Boston, MA 02110-1301 USA
-//
-
-module strobe(clk_i,rst_i,ena_i,rate_i,strobe_i,strobe_o,count_o);
- parameter width = 16;
-
- input clk_i;
- input rst_i;
- input ena_i;
- input [width-1:0] rate_i; // Desired period minus one
- input strobe_i;
- output strobe_o;
- output [width-1:0] count_o;
-
-
- reg [width-1:0] counter;
-
- always @(posedge clk_i)
- if(rst_i | ~ena_i)
- counter <= 32'hFFFFFFFF; // First period is short by one
- else if(strobe_i)
- if(counter == rate_i)
- counter <= 0;
- else
- counter <= counter + 1;
-
- assign strobe_o = (counter == rate_i) & strobe_i;
- assign count_o = counter;
-
-endmodule // strobe
diff --git a/gr-sounder/src/fpga/tb/sounder_tb.sav b/gr-sounder/src/fpga/tb/sounder_tb.sav
index 3a73a9445b..25bc512bcc 100644
--- a/gr-sounder/src/fpga/tb/sounder_tb.sav
+++ b/gr-sounder/src/fpga/tb/sounder_tb.sav
@@ -1,10 +1,12 @@
-*-24.753519 93900000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
+*-29.807737 317080000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
+@200
+-
@28
-sounder_tb.uut.clk_i
-sounder_tb.rst
sounder_tb.s_strobe
@22
-sounder_tb.sdata[31:0]
+sounder_tb.saddr[6:0]
+@200
+-
@28
sounder_tb.uut.reset
sounder_tb.uut.transmit
@@ -14,27 +16,42 @@ sounder_tb.uut.loopback
-
@22
sounder_tb.uut.degree[4:0]
-sounder_tb.uut.len[15:0]
+sounder_tb.uut.mask[15:0]
+sounder_tb.uut.ampl[13:0]
+sounder_tb.uut.receiver.offset[5:0]
@200
-
-@28
+@8420
sounder_tb.tx_dac_i[13:0]
+@28
+sounder_tb.tx_strobe
@200
-
-@22
-sounder_tb.fifo_strobe
-@8421
+@8420
sounder_tb.fifo_i[15:0]
-@22
-sounder_tb.fifo_q[15:0]
+@28
+sounder_tb.fifo_strobe
@200
-
-@22
-sounder_tb.uut.transmitter.pn_code.pn_o
-sounder_tb.uut.receiver.pn_ref
+@28
+sounder_tb.uut.ref_strobe
+sounder_tb.uut.sum_strobe
@200
-
@28
-sounder_tb.tx_strobe
+sounder_tb.clk
+sounder_tb.uut.transmitter.pn
+sounder_tb.uut.receiver.pn_ref
@8420
+sounder_tb.uut.receiver.prod_i[31:0]
+sounder_tb.uut.receiver.scaled_i[31:0]
+@8421
sounder_tb.uut.receiver.sum_i[31:0]
+@8420
+sounder_tb.uut.receiver.total_i[31:0]
+@200
+-
+@22
+sounder_tb.uut.master.len[16:0]
+@200
+-
diff --git a/gr-sounder/src/fpga/tb/sounder_tb.sh b/gr-sounder/src/fpga/tb/sounder_tb.sh
index 9bc7143870..28efc8d31d 100755
--- a/gr-sounder/src/fpga/tb/sounder_tb.sh
+++ b/gr-sounder/src/fpga/tb/sounder_tb.sh
@@ -1,7 +1,6 @@
#!/bin/sh
iverilog -y ../lib/ -y ../../../../usrp/fpga/sdr_lib \
sounder_tb.v -o sounder_tb && \
-./sounder_tb > sounder_tb.out && \
-grep 'rst=0' sounder_tb.out | grep 'clk=1' > sounder_tb.out2 && \
-grep 'tx_strobe=1' sounder_tb.out2 > sounder_tb.out3
+./sounder_tb > sounder_tb.out && \
+ grep 'r=0' sounder_tb.out | grep 'c=1' > sounder_tb.out2
diff --git a/gr-sounder/src/fpga/tb/sounder_tb.v b/gr-sounder/src/fpga/tb/sounder_tb.v
index 6a9eff0ea0..0e0cb55c20 100644
--- a/gr-sounder/src/fpga/tb/sounder_tb.v
+++ b/gr-sounder/src/fpga/tb/sounder_tb.v
@@ -19,7 +19,7 @@
// Foundation, Inc., 51 Franklin Street, Boston, MA 02110-1301 USA
//
-`timescale 1ns/1ps
+`timescale 1ns/100ps
`include "../lib/sounder.v"
@@ -30,6 +30,7 @@
`define bmFR_MODE_LP 32'h0008
`define FR_DEGREE 7'd65
+`define FR_AMPL 7'd66
module sounder_tb;
@@ -44,12 +45,11 @@ module sounder_tb;
reg s_strobe;
// DAC bus
- reg tx_strobe;
+ wire tx_strobe;
wire [13:0] tx_dac_i;
wire [13:0] tx_dac_q;
// ADC bus
- reg rx_strobe;
reg [15:0] rx_adc_i;
reg [15:0] rx_adc_q;
@@ -64,14 +64,10 @@ module sounder_tb;
sounder uut
(.clk_i(clk),.saddr_i(saddr),.sdata_i(sdata),.s_strobe_i(s_strobe),
- .tx_strobe_i(tx_strobe),.tx_dac_i_o(tx_dac_i),.tx_dac_q_o(tx_dac_q),
- .rx_strobe_i(rx_strobe),.rx_adc_i_i(rx_adc_i),.rx_adc_q_i(rx_adc_q),
- .rx_strobe_o(fifo_strobe),.rx_imp_i_o(fifo_i),.rx_imp_q_o(fifo_q));
+ .tx_strobe_o(tx_strobe),.tx_dac_i_o(tx_dac_i),.tx_dac_q_o(tx_dac_q),
+ .rx_strobe_o(fifo_strobe),.rx_adc_i_i(rx_adc_i),.rx_adc_q_i(rx_adc_q),
+ .rx_imp_i_o(fifo_i),.rx_imp_q_o(fifo_q));
- // Drive tx_strobe @ half clock rate
- always @(posedge clk)
- tx_strobe <= ~tx_strobe;
-
// Start up initialization
initial
begin
@@ -81,8 +77,6 @@ module sounder_tb;
saddr = 0;
sdata = 0;
s_strobe = 0;
- tx_strobe = 0;
- rx_strobe = 1;
rx_adc_i = 0;
rx_adc_q = 0;
mode = 0;
@@ -101,9 +95,11 @@ module sounder_tb;
initial
begin
- $monitor($time, " clk=%b rst=%b tx_strobe=%b fifo_strobe=%b phs=%x pn_o=%b pn_ref=%b fifo_i=%x fifo_q=",
- clk, uut.reset, tx_strobe, fifo_strobe, uut.receiver.phase_strobe.count_o,
- uut.transmitter.pn, uut.receiver.pn_ref, fifo_i, fifo_q);
+ $monitor($time, " c=%b r=%b phs=%d txs=%b rfs=%b rxs=%b sms=%b pn=%b pnr=%b prd=%x sum=%x tot=%x",
+ clk, rst, uut.master.phase, uut.tx_strobe_o, uut.ref_strobe, uut.rx_strobe_o,
+ uut.sum_strobe, uut.transmitter.pn, uut.receiver.pn_ref, uut.receiver.prod_i,
+ uut.receiver.sum_i, uut.receiver.total_i);
+
$dumpfile("sounder_tb.vcd");
$dumpvars(0, sounder_tb);
end
@@ -115,11 +111,11 @@ module sounder_tb;
begin
@(posedge clk);
- saddr <= regno;
- sdata <= value;
- s_strobe <= 1'b1;
+ saddr <= #5 regno;
+ sdata <= #5 value;
+ s_strobe <= #5 1'b1;
@(posedge clk);
- s_strobe <= 0;
+ s_strobe <= #5 0;
end
endtask // write_cfg_register
@@ -141,6 +137,14 @@ module sounder_tb;
end
endtask // set_degree
+ // Set the PN amplitude
+ task set_amplitude;
+ input [13:0] ampl;
+ begin
+ write_cfg_register(`FR_AMPL, ampl);
+ end
+ endtask // set_ampl
+
// Turn on or off the transmitter
task enable_tx;
input tx;
@@ -175,20 +179,24 @@ module sounder_tb;
// Test transmitter functionality
task test_tx;
input [5:0] degree;
+ input [31:0] test_len;
begin
#20 set_reset(1);
#20 set_degree(degree);
+ #20 set_amplitude(14'h1000);
#20 enable_tx(1);
+ #20 enable_rx(0);
+ #20 enable_lp(0);
#20 set_reset(0);
- #(uut.len*20); // One PN code period
-
+ #(test_len);
end
endtask // test_tx
// Test loopback functionality
task test_lp;
input [5:0] degree;
+ input [31:0] test_len;
begin
#20 set_reset(1);
@@ -197,16 +205,34 @@ module sounder_tb;
#20 enable_rx(1);
#20 enable_lp(1);
#20 set_reset(0);
- #((uut.len+1)*uut.len*20*2);
+ #(test_len);
end
endtask // test_lp
+ // Test receiver only functionality
+ task test_rx;
+ input [5:0] degree;
+ input [31:0] test_len;
+
+ begin
+ #20 set_reset(1);
+ #20 set_degree(degree);
+ #20 enable_tx(0);
+ #20 enable_rx(1);
+ #20 enable_lp(0);
+ #20 set_reset(0);
+ #(test_len);
+ end
+ endtask // test_rx
+
// Execute tests
initial
begin
- // #20 test_tx(12);
- #20 test_lp(12);
- #100 $finish;
+ #20 test_tx(8,255*20);
+ #20 test_lp(8,255*255*20*5);
+ //#20 test_rx(8,255*255*20*5);
+ #500 $finish;
end
+
endmodule
diff --git a/gr-sounder/src/fpga/top/usrp_sounder.qsf b/gr-sounder/src/fpga/top/usrp_sounder.qsf
index 5ff52583f3..4d60f5f13f 100755..100644
--- a/gr-sounder/src/fpga/top/usrp_sounder.qsf
+++ b/gr-sounder/src/fpga/top/usrp_sounder.qsf
@@ -236,7 +236,7 @@ set_global_assignment -name PHYSICAL_SYNTHESIS_COMBO_LOGIC OFF
set_global_assignment -name PHYSICAL_SYNTHESIS_REGISTER_DUPLICATION OFF
set_global_assignment -name PHYSICAL_SYNTHESIS_REGISTER_RETIMING OFF
set_global_assignment -name IO_PLACEMENT_OPTIMIZATION OFF
-set_global_assignment -name PHYSICAL_SYNTHESIS_EFFORT NORMAL
+set_global_assignment -name PHYSICAL_SYNTHESIS_EFFORT EXTRA
set_global_assignment -name INC_PLC_MODE OFF
set_global_assignment -name ROUTING_BACK_ANNOTATION_MODE OFF
set_instance_assignment -name IO_STANDARD LVTTL -to usbdata[12]
@@ -368,13 +368,15 @@ set_instance_assignment -name CLOCK_SETTINGS master_clk -to master_clk
set_instance_assignment -name PARTITION_HIERARCHY no_file_for_top_partition -to | -section_id Top
set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top
-set_global_assignment -name VERILOG_FILE ../lib/strobe.v
+set_global_assignment -name PHYSICAL_SYNTHESIS_ASYNCHRONOUS_SIGNAL_PIPELINING OFF
+set_global_assignment -name FITTER_EARLY_TIMING_ESTIMATE_MODE REALISTIC
set_global_assignment -name VERILOG_FILE ../lib/lfsr_constants.v
set_global_assignment -name VERILOG_FILE ../lib/lfsr.v
set_global_assignment -name VERILOG_FILE ../lib/dac_interface.v
set_global_assignment -name VERILOG_FILE ../lib/dacpll.v
set_global_assignment -name VERILOG_FILE ../lib/sounder_rx.v
set_global_assignment -name VERILOG_FILE ../lib/sounder_tx.v
+set_global_assignment -name VERILOG_FILE ../lib/sounder_ctrl.v
set_global_assignment -name VERILOG_FILE ../lib/sounder.v
set_global_assignment -name VERILOG_FILE ../../../../usrp/fpga/sdr_lib/atr_delay.v
set_global_assignment -name VERILOG_FILE ../../../../usrp/fpga/sdr_lib/sign_extend.v
@@ -390,4 +392,5 @@ set_global_assignment -name VERILOG_FILE ../../../../usrp/fpga/sdr_lib/master_co
set_global_assignment -name VERILOG_FILE ../../../../usrp/fpga/sdr_lib/rssi.v
set_global_assignment -name VERILOG_FILE ../../../../usrp/fpga/sdr_lib/rx_dcoffset.v
set_global_assignment -name VERILOG_FILE ../../../../usrp/fpga/sdr_lib/serial_io.v
-set_global_assignment -name VERILOG_FILE usrp_sounder.v \ No newline at end of file
+set_global_assignment -name VERILOG_FILE usrp_sounder.v
+set_global_assignment -name FITTER_EFFORT "STANDARD FIT" \ No newline at end of file
diff --git a/gr-sounder/src/fpga/top/usrp_sounder.rbf b/gr-sounder/src/fpga/top/usrp_sounder.rbf
index b6f494227a..e2c9db6c4b 100755
--- a/gr-sounder/src/fpga/top/usrp_sounder.rbf
+++ b/gr-sounder/src/fpga/top/usrp_sounder.rbf
Binary files differ
diff --git a/gr-sounder/src/fpga/top/usrp_sounder.v b/gr-sounder/src/fpga/top/usrp_sounder.v
index bb6305691a..a88b2388e1 100644
--- a/gr-sounder/src/fpga/top/usrp_sounder.v
+++ b/gr-sounder/src/fpga/top/usrp_sounder.v
@@ -151,8 +151,8 @@ module usrp_sounder
sounder sounder
( .clk_i(clk64),.saddr_i(serial_addr),.sdata_i(serial_data),.s_strobe_i(serial_strobe),
- .tx_strobe_i(tx_sample_strobe),.tx_dac_i_o(tx_i),.tx_dac_q_o(tx_q),
- .rx_strobe_i(rx_sample_strobe),.rx_adc_i_i(rx_adc0_i),.rx_adc_q_i(rx_adc0_q),
+ .tx_strobe_o(tx_sample_strobe),.tx_dac_i_o(tx_i),.tx_dac_q_o(tx_q),
+ .rx_adc_i_i(rx_adc0_i),.rx_adc_q_i(rx_adc0_q),
.rx_strobe_o(rx_strobe),.rx_imp_i_o(rx_buf_i),.rx_imp_q_o(rx_buf_q)
);
@@ -170,7 +170,7 @@ module usrp_sounder
( .master_clk(clk64),.serial_clock(SCLK),.serial_data_in(SDI),
.enable(SEN_FPGA),.reset(1'b0),.serial_data_out(SDO),
.serial_addr(serial_addr),.serial_data(serial_data),.serial_strobe(serial_strobe),
- .readback_0(),.readback_1(),.readback_2(capabilities),.readback_3(),
+ .readback_0({io_rx_a,io_tx_a}),.readback_1({io_rx_b,io_tx_b}),.readback_2(capabilities),.readback_3(32'hf0f0931a),
.readback_4(),.readback_5(),.readback_6(),.readback_7()
);
@@ -182,7 +182,7 @@ module usrp_sounder
.tx_dsp_reset(tx_dsp_reset),.rx_dsp_reset(rx_dsp_reset),
.enable_tx(enable_tx),.enable_rx(enable_rx),
.interp_rate(),.decim_rate(),
- .tx_sample_strobe(tx_sample_strobe),.strobe_interp(),
+ .tx_sample_strobe(),.strobe_interp(),
.rx_sample_strobe(rx_sample_strobe),.strobe_decim(),
.tx_empty(tx_empty),
.debug_0(),.debug_1(),
diff --git a/gr-sounder/src/python/sounder.py b/gr-sounder/src/python/sounder.py
index b3c5423c41..ce00e964d0 100644
--- a/gr-sounder/src/python/sounder.py
+++ b/gr-sounder/src/python/sounder.py
@@ -32,6 +32,7 @@ bmFR_MODE_RX = 1 << 2 # bit 2: enable receiver
bmFR_MODE_LP = 1 << 3 # bit 3: enable digital loopback
FR_DEGREE = usrp.FR_USER_1
+FR_AMPL = usrp.FR_USER_2
def pick_subdevice(u):
"""
@@ -47,15 +48,18 @@ def pick_subdevice(u):
return (0, 0)
class sounder_tx:
- def __init__(self, loopback=False,verbose=False):
+ def __init__(self, loopback=False,ampl=4096,verbose=False,debug=False):
self._loopback=loopback
+ self._amplitude = ampl
self._verbose = verbose
+ self._debug = debug
self._u = usrp.sink_s(fpga_filename='usrp_sounder.rbf')
if not self._loopback:
self._subdev_spec = usrp.pick_tx_subdevice(self._u)
self._subdev = usrp.selected_subdev(self._u, self._subdev_spec)
if self._verbose:
print "Using", self._subdev.name(), "for sounder transmitter."
+ self.set_amplitude(ampl)
self._u.start()
def tune(self, frequency):
@@ -65,9 +69,16 @@ class sounder_tx:
if result == False:
raise RuntimeError("Failed to set transmitter frequency.")
+ def set_amplitude(self, ampl):
+ self._amplitude = ampl
+ if self._debug:
+ print "Writing amplitude register with:", hex(self._mode)
+ self._u._write_fpga_reg(FR_AMPL, self._amplitude)
+
class sounder_rx:
- def __init__(self,subdev_spec=None,length=1,msgq=None,loopback=False,verbose=False,debug=False):
+ def __init__(self,subdev_spec=None,gain=None,length=1,msgq=None,loopback=False,verbose=False,debug=False):
self._subdev_spec = subdev_spec
+ self._gain = gain
self._length = length
self._msgq = msgq
self._loopback = loopback
@@ -84,6 +95,7 @@ class sounder_rx:
if self._verbose:
print "Using", self._subdev.name(), "for sounder receiver."
+ self.set_gain(self._gain)
self._vblen = gr.sizeof_gr_complex*self._length
if self._debug:
print "Generating impulse vectors of length", self._length, "byte length", self._vblen
@@ -99,6 +111,19 @@ class sounder_rx:
if result == False:
raise RuntimeError("Failed to set receiver frequency.")
+ def set_gain(self, gain):
+ self._gain = gain
+ if self._loopback:
+ return
+
+ if self._gain is None:
+ # if no gain was specified, use the mid-point in dB
+ g = self._subdev.gain_range()
+ self._gain = float(g[0]+g[1])/2
+ if self._verbose:
+ print "Setting receiver gain to", gain
+ self._subdev.set_gain(self._gain)
+
def start(self):
if self._debug:
print "Starting receiver flow graph."
@@ -119,13 +144,15 @@ class sounder_rx:
class sounder:
- def __init__(self,transmit=False,receive=False,loopback=False,rx_subdev_spec=None,
- frequency=0.0,degree=10,length=1,msgq=None,verbose=False,debug=False):
+ def __init__(self,transmit=False,receive=False,loopback=False,rx_subdev_spec=None,ampl=0x1FFF,
+ frequency=0.0,rx_gain=None,degree=12,length=1,msgq=None,verbose=False,debug=False):
self._transmit = transmit
self._receive = receive
self._loopback = loopback
self._rx_subdev_spec = rx_subdev_spec
self._frequency = frequency
+ self._amplitude = ampl
+ self._rx_gain = rx_gain
self._degree = degree
self._length = length
self._msgq = msgq
@@ -139,11 +166,12 @@ class sounder:
self._receiving = False
if self._transmit:
- self._trans = sounder_tx(loopback=self._loopback,verbose=self._verbose)
+ self._trans = sounder_tx(loopback=self._loopback,ampl=self._amplitude,
+ verbose=self._verbose)
self._u = self._trans._u
if self._receive:
- self._rcvr = sounder_rx(subdev_spec=self._rx_subdev_spec,length=self._length,
+ self._rcvr = sounder_rx(subdev_spec=self._rx_subdev_spec,length=self._length,gain=self._rx_gain,
msgq=self._msgq,loopback=self._loopback,verbose=self._verbose,
debug=self._debug)
self._u = self._rcvr._u # either receiver or transmitter object will do
diff --git a/gr-sounder/src/python/usrp_sounder.py b/gr-sounder/src/python/usrp_sounder.py
index 4aada45d61..20f1871147 100755
--- a/gr-sounder/src/python/usrp_sounder.py
+++ b/gr-sounder/src/python/usrp_sounder.py
@@ -25,6 +25,7 @@ from gnuradio.sounder import sounder
from gnuradio import eng_notation
from gnuradio.eng_option import eng_option
from optparse import OptionParser
+import numpy
import sys
n2s = eng_notation.num_to_str
@@ -33,10 +34,14 @@ def main():
parser = OptionParser(option_class=eng_option)
parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=(0, 0),
help="select USRP Rx side A or B")
+ parser.add_option("-g", "--gain", type="eng_float", default=None,
+ help="set gain in dB (default is midpoint)")
parser.add_option("-f", "--frequency", type="eng_float", default=0.0,
help="set frequency to FREQ in Hz, default is %default", metavar="FREQ")
parser.add_option("-d", "--degree", type="int", default=12,
help="set sounding sequence degree (2-12), default is %default,")
+ parser.add_option("-a", "--amplitude", type="int", default=4096,
+ help="set waveform amplitude, default is %default,")
parser.add_option("-t", "--transmit", action="store_true", default=False,
help="enable sounding transmitter")
parser.add_option("-r", "--receive", action="store_true", default=False,
@@ -74,8 +79,9 @@ def main():
msgq = gr.msg_queue()
s = sounder(transmit=options.transmit,receive=options.receive,loopback=options.loopback,
- rx_subdev_spec=options.rx_subdev_spec,frequency=options.frequency,degree=options.degree,
- length=length,msgq=msgq,verbose=options.verbose,debug=options.debug)
+ rx_subdev_spec=options.rx_subdev_spec,frequency=options.frequency,rx_gain=options.gain,
+ degree=options.degree,length=length,msgq=msgq,verbose=options.verbose,ampl=options.amplitude,
+ debug=options.debug)
s.start()
if options.receive:
@@ -89,7 +95,10 @@ def main():
rec = msg.to_string()[:length*gr.sizeof_gr_complex]
if options.debug:
print "Received impulse vector of length", len(rec)
- f.write(rec)
+ recarray = numpy.fromstring(rec, dtype=numpy.complex64)
+ imparray = recarray[::-1]
+ data = imparray.tostring()
+ f.write(data)
except KeyboardInterrupt:
pass