From: jcorgan Date: Tue, 5 Jun 2007 04:21:29 +0000 (+0000) Subject: Merged r5566:5676 from jcorgan/snd into trunk, with minor changes. Component gr... X-Git-Url: https://git.gag.com/?a=commitdiff_plain;h=e283fe844c88aa33b6bde4a7cb74f0d1c2ddbbc5;p=debian%2Fgnuradio Merged r5566:5676 from jcorgan/snd into trunk, with minor changes. Component gr-sounder is now complete for recording impulse responses to a file. git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@5679 221aa14e-8319-0410-a670-987f0aec2ac5 --- diff --git a/gr-sounder/src/fpga/lib/Makefile.am b/gr-sounder/src/fpga/lib/Makefile.am index 0a03147a..1c8f39ba 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 9042e1c5..93c72cca 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 6ae967ba..bd0743e9 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 old mode 100755 new mode 100644 index 55ee613d..e23ed660 --- 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 58b56344..675be888 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 00000000..6e967a5b --- /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 338afd55..18038a3a 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 46165dde..148b1e50 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 ed07f21f..00000000 --- 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 3a73a944..25bc512b 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 9bc71438..28efc8d3 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 6a9eff0e..0e0cb55c 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 old mode 100755 new mode 100644 index 5ff52583..4d60f5f1 --- 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 b6f49422..e2c9db6c 100755 Binary files a/gr-sounder/src/fpga/top/usrp_sounder.rbf and b/gr-sounder/src/fpga/top/usrp_sounder.rbf differ diff --git a/gr-sounder/src/fpga/top/usrp_sounder.v b/gr-sounder/src/fpga/top/usrp_sounder.v index bb630569..a88b2388 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 b3c5423c..ce00e964 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 4aada45d..20f18711 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