From 3f7ff03c098b5bdbc1134a33c1ea14953f1c2f6f Mon Sep 17 00:00:00 2001 From: Nick Foster Date: Thu, 12 Jan 2012 11:14:10 -0800 Subject: Squashed slave mode changes onto master. --- usrp2/gpif/Makefile.srcs | 1 + usrp2/gpif/packet_reframer.v | 29 ++- usrp2/gpif/slave_fifo.v | 467 +++++++++++++++++++++++++++++++++++++++++++ usrp2/top/B100/B100.ucf | 13 +- usrp2/top/B100/B100.v | 11 +- usrp2/top/B100/core_compile | 1 - usrp2/top/B100/u1plus_core.v | 19 +- 7 files changed, 507 insertions(+), 34 deletions(-) create mode 100644 usrp2/gpif/slave_fifo.v delete mode 100755 usrp2/top/B100/core_compile diff --git a/usrp2/gpif/Makefile.srcs b/usrp2/gpif/Makefile.srcs index bf2b7f74d..06cde8afa 100644 --- a/usrp2/gpif/Makefile.srcs +++ b/usrp2/gpif/Makefile.srcs @@ -11,4 +11,5 @@ gpif_wr.v \ gpif_rd.v \ packet_reframer.v \ packet_splitter.v \ +slave_fifo.v \ )) diff --git a/usrp2/gpif/packet_reframer.v b/usrp2/gpif/packet_reframer.v index 923d499ae..0d8232653 100644 --- a/usrp2/gpif/packet_reframer.v +++ b/usrp2/gpif/packet_reframer.v @@ -16,7 +16,7 @@ // -// Join vita packets longer than one GPIF frame, drop padding on short frames +// Join vita packets longer than one GPIF frame module packet_reframer (input clk, input reset, input clear, @@ -25,14 +25,16 @@ module packet_reframer output dst_rdy_o, output [18:0] data_o, output src_rdy_o, - input dst_rdy_i); + input dst_rdy_i, + output reg state, + output eof_out, + output reg [15:0] length); - reg [1:0] state; - reg [15:0] length; + //reg state; + //reg [15:0] length; localparam RF_IDLE = 0; localparam RF_PKT = 1; - localparam RF_DUMP = 2; always @(posedge clk) if(reset | clear) @@ -48,25 +50,22 @@ module packet_reframer RF_PKT : begin if(length == 2) - if(data_i[17]) - state <= RF_IDLE; - else - state <= RF_DUMP; + begin + state <= RF_IDLE; + length <= 0; + end else length <= length - 1; end - RF_DUMP : - if(data_i[17]) - state <= RF_IDLE; default : - state<= RF_IDLE; + state <= RF_IDLE; endcase // case (state) assign dst_rdy_o = dst_rdy_i; // this is a little pessimistic but ok - assign src_rdy_o = src_rdy_i & (state != RF_DUMP); + assign src_rdy_o = src_rdy_i; wire occ_out = 0; - wire eof_out = (state == RF_PKT) & (length == 2); + assign eof_out = (state == RF_PKT) & (length == 2); wire sof_out = (state == RF_IDLE); wire [15:0] data_out = data_i[15:0]; assign data_o = {occ_out, eof_out, sof_out, data_out}; diff --git a/usrp2/gpif/slave_fifo.v b/usrp2/gpif/slave_fifo.v new file mode 100644 index 000000000..faba2b107 --- /dev/null +++ b/usrp2/gpif/slave_fifo.v @@ -0,0 +1,467 @@ +// +// 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 . +// + +////////////////////////////////////////////////////////////////////////////////// + +//this is a FIFO master interface for the FX2 in "slave fifo" mode. + +module slave_fifo + #(parameter TXFIFOSIZE = 11, parameter RXFIFOSIZE = 11) + (// GPIF signals + input gpif_clk, input gpif_rst, + inout [15:0] gpif_d, + input [3:0] gpif_ctl, + output sloe, output slrd, output slwr, output pktend, output [1:0] fifoadr, + + // Wishbone signals + input wb_clk, input wb_rst, + output [15:0] wb_adr_o, output [15:0] wb_dat_mosi, input [15:0] wb_dat_miso, + output [1:0] wb_sel_o, output wb_cyc_o, output wb_stb_o, output wb_we_o, input wb_ack_i, + input [7:0] triggers, + + input dsp_rx_run, + + // FIFO interface + input fifo_clk, input fifo_rst, input clear_tx, input clear_rx, + output [35:0] tx_data_o, output tx_src_rdy_o, input tx_dst_rdy_i, + input [35:0] rx_data_i, input rx_src_rdy_i, output rx_dst_rdy_o, + input [35:0] tx_err_data_i, input tx_err_src_rdy_i, output tx_err_dst_rdy_o, + output tx_underrun, output rx_overrun, + + input [15:0] test_len, input [7:0] test_rate, input [3:0] test_ctrl, + output [31:0] debug0, output [31:0] debug1 + ); + + // inputs to FPGA (all active low) + wire FX2_DE = ~gpif_ctl[0]; //EP2 FX2 FIFO empty (FLAGA) + wire FX2_CE = ~gpif_ctl[1]; //EP4 FX2 FIFO empty (FLAGB) + wire FX2_DF = ~gpif_ctl[2]; //EP6 FX2 FIFO full (FLAGC) + wire FX2_CF = ~gpif_ctl[3]; //EP8 FX2 FIFO full (FLAGD) + + wire [17:0] gpif_d_out_ctrl, gpif_d_out_data, gpif_d_out; + + // //////////////////////////////////////////////////////////////////// + // GPIF bus master state machine + + //transfer size for GPIF data. this can be anything really, it's specified only for + //fairness in bus sharing. 256 lines is 512 bytes over the wire, half the size of + //the double buffers in B100/B150. this should probably be a toplevel parameter or even + //a settings register value. + localparam data_transfer_size = 256; + localparam ctrl_transfer_size = 16; //probably unnecessary since ctrl xfers won't back up + + // state machine i/o to four fifos + //tx + wire ctrl_tx_dst_rdy; //sm input, ctrl tx path has space + wire ctrl_tx_src_rdy; //sm output, ctrl tx path enable + reg data_tx_dst_rdy; //sm input, data tx path has space + wire data_tx_src_rdy; //sm output, data tx path enable + + //rx + wire ctrl_rx_dst_rdy; //sm output, ctrl rx path enable + wire ctrl_rx_src_rdy; //sm input, ctrl rx path has space + wire data_rx_dst_rdy; //sm output, data rx path enable + wire data_rx_src_rdy; //sm input, data rx path has space + + reg [9:0] transfer_count; //number of lines (a line is 16 bits) in active transfer + + wire sop, eop; //SOP/EOP markers for TX data packets + + reg pktend_latch; + + reg [3:0] state; //state machine current state + localparam STATE_IDLE = 0; + localparam STATE_DATA_RX = 5; + localparam STATE_DATA_TX = 3; + localparam STATE_CTRL_RX = 6; + localparam STATE_CTRL_TX = 9; + localparam STATE_DATA_TX_SLOE = 2; + localparam STATE_CTRL_TX_SLOE = 8; + localparam STATE_DATA_RX_ADR = 1; + localparam STATE_CTRL_RX_ADR = 4; + localparam STATE_PKTEND = 7; + + //logs the last bus user for xfer fairness + //we only care about data rx vs. tx since ctrl pkts are so short + reg last_data_bus_hog; + localparam BUS_HOG_RX = 0; + localparam BUS_HOG_TX = 1; + + // ////////////////////////////////////////////////////////////// + // FX2 slave FIFO bus master state machine + // + always @(posedge gpif_clk) + if(gpif_rst) + state <= STATE_IDLE; + else + begin + case (state) + STATE_IDLE: + begin + transfer_count <= 0; + //handle transitions to other states + if(ctrl_tx_dst_rdy & ~FX2_CE) //if there's room in the ctrl fifo and the FX2 has ctrl data + state <= STATE_CTRL_TX_SLOE; + else if(ctrl_rx_src_rdy & ~FX2_CF) //if the ctrl fifo has data and the FX2 isn't full + state <= STATE_CTRL_RX_ADR; + else if(data_tx_dst_rdy & ~FX2_DE & last_data_bus_hog == BUS_HOG_RX) //if there's room in the data fifo and the FX2 has data + state <= STATE_DATA_TX_SLOE; + else if(data_rx_src_rdy & ~FX2_DF & last_data_bus_hog == BUS_HOG_TX) //if the data fifo has data and the FX2 isn't full + state <= STATE_DATA_RX_ADR; + else if(data_tx_dst_rdy & ~FX2_DE) + state <= STATE_DATA_TX_SLOE; + else if(data_rx_src_rdy & ~FX2_DF) + state <= STATE_DATA_RX_ADR; + else if(~data_rx_src_rdy & ~dsp_rx_run & pktend_latch) + state <= STATE_PKTEND; + + if(dsp_rx_run) + pktend_latch <= 1; + end + + STATE_DATA_TX_SLOE: //just to assert SLOE one cycle before SLRD + state <= STATE_DATA_TX; + STATE_CTRL_TX_SLOE: + state <= STATE_CTRL_TX; + + STATE_DATA_RX_ADR: //just to assert FIFOADR one cycle before SLWR + state <= STATE_DATA_RX; + STATE_CTRL_RX_ADR: + state <= STATE_CTRL_RX; + + STATE_DATA_RX: + begin + if((transfer_count == data_transfer_size) | FX2_DF | (~data_rx_src_rdy)) + state <= STATE_IDLE; + + transfer_count <= transfer_count + 1; + last_data_bus_hog <= BUS_HOG_RX; + end + + STATE_PKTEND: + begin + state <= STATE_IDLE; + pktend_latch <= 0; + end + + STATE_DATA_TX: + begin + if((transfer_count == data_transfer_size) | FX2_DE )/*| (~data_tx_dst_rdy))*/ + state <= STATE_IDLE; + transfer_count <= transfer_count + 1; + last_data_bus_hog <= BUS_HOG_TX; + end + STATE_CTRL_RX: + begin + if(FX2_CF | (~ctrl_rx_src_rdy)) + state <= STATE_IDLE; + transfer_count <= transfer_count + 1; + end + STATE_CTRL_TX: + begin + if(FX2_CE | (~ctrl_tx_dst_rdy)) + state <= STATE_IDLE; + transfer_count <= transfer_count + 1; + end + endcase + end + + // /////////////////////////////////////////////////////////////////// + // fifo signal assignments and enables + + //enable fifos + assign data_rx_dst_rdy = (state == STATE_DATA_RX); + assign data_tx_src_rdy = (state == STATE_DATA_TX); + assign ctrl_rx_dst_rdy = (state == STATE_CTRL_RX); + assign ctrl_tx_src_rdy = (state == STATE_CTRL_TX); + + //tx framing (this is super suspect) + //eop should be used only to set the EOP bit going into FIFOs + wire eop_data, eop_ctrl; + assign sop = (transfer_count == 0); + assign eop_data = (transfer_count == (data_transfer_size-1)); + assign eop_ctrl = (transfer_count == (ctrl_transfer_size-1)); + assign eop = (state == STATE_DATA_TX) ? eop_data : eop_ctrl; + + // //////////////////////////////////////////////////////////////////// + // set GPIF pins + + //set fifoadr to the appropriate endpoint + // {0,0}: EP2, data TX from host + // {0,1}: EP4, ctrl TX from host + // {1,0}: EP6, data RX to host + // {1,1}: EP8, ctrl RX to host + assign fifoadr = {(state == STATE_DATA_RX) | (state == STATE_CTRL_RX) | (state == STATE_DATA_RX_ADR) | (state == STATE_CTRL_RX_ADR) | (state == STATE_PKTEND), + (state == STATE_CTRL_RX) | (state == STATE_CTRL_RX_ADR) | (state == STATE_CTRL_TX) | (state == STATE_CTRL_TX_SLOE)}; + //set sloe, slwr, slrd (all active low) + //SLOE gets asserted when we want data from the FX2; i.e., TX mode + assign sloe = ~{(state == STATE_DATA_TX) | (state == STATE_CTRL_TX) | (state == STATE_DATA_TX_SLOE) | (state == STATE_CTRL_TX_SLOE)}; + //"read" and "write" here are from the master's point of view; + //so "read" means "transmit" and "write" means "receive" + assign slwr = ~{(state == STATE_DATA_RX) | (state == STATE_CTRL_RX)}; + assign slrd = ~{(state == STATE_DATA_TX) | (state == STATE_CTRL_TX)}; + + wire pktend_ctrl, pktend_data; + assign pktend_ctrl = ((~ctrl_rx_src_rdy | gpif_d_out_ctrl[17]) & (state == STATE_CTRL_RX)); + assign pktend_data = (state == STATE_PKTEND); + assign pktend = ~(pktend_ctrl | pktend_data); + + //mux between ctrl/data RX data out based on endpoint selection + assign gpif_d_out = fifoadr[0] ? gpif_d_out_ctrl : gpif_d_out_data; + // GPIF output data lines, tristate + assign gpif_d = sloe ? gpif_d_out : 16'bz; + + // //////////////////////////////////////////////////////////////////// + // TX Data Path + + wire [18:0] tx19_data; + wire tx19_src_rdy, tx19_dst_rdy; + wire [35:0] tx36_data; + wire tx36_src_rdy, tx36_dst_rdy; + wire [17:0] data_tx_int; + wire tx_src_rdy_int, tx_dst_rdy_int; + + wire [15:0] wr_fifo_space; + + always @(posedge gpif_clk) + if(gpif_rst) + data_tx_dst_rdy <= 0; + else + data_tx_dst_rdy <= wr_fifo_space >= 256; + + fifo_cascade #(.WIDTH(18), .SIZE(10)) wr_fifo + (.clk(gpif_clk), .reset(gpif_rst), .clear(0), + .datain({eop,sop,gpif_d}), .src_rdy_i(data_tx_src_rdy), .dst_rdy_o(/*data_tx_dst_rdy*/), .space(wr_fifo_space), + .dataout(data_tx_int), .src_rdy_o(tx_src_rdy_int), .dst_rdy_i(tx_dst_rdy_int), .occupied()); + + fifo_2clock_cascade #(.WIDTH(18), .SIZE(4)) wr_fifo_2clk + (.wclk(gpif_clk), .datain(data_tx_int), .src_rdy_i(tx_src_rdy_int), .dst_rdy_o(tx_dst_rdy_int), .space(), + .rclk(fifo_clk), .dataout(tx19_data[17:0]), .src_rdy_o(tx19_src_rdy), .dst_rdy_i(tx19_dst_rdy), .occupied(), + .arst(fifo_rst)); + + assign tx19_data[18] = 1'b0; + + // join vita packets which are longer than one frame, drop frame padding + wire [18:0] refr_data; + wire refr_src_rdy, refr_dst_rdy; + wire refr_state; + wire refr_eof; + wire [15:0] refr_len; + + packet_reframer tx_packet_reframer + (.clk(fifo_clk), .reset(fifo_rst), .clear(clear_tx), + .data_i(tx19_data), .src_rdy_i(tx19_src_rdy), .dst_rdy_o(tx19_dst_rdy), + .data_o(refr_data), .src_rdy_o(refr_src_rdy), .dst_rdy_i(refr_dst_rdy), + .state(refr_state), .eof_out(refr_eof), .length(refr_len)); + + fifo19_to_fifo36 #(.LE(1)) f19_to_f36 + (.clk(fifo_clk), .reset(fifo_rst), .clear(0), + .f19_datain(refr_data), .f19_src_rdy_i(refr_src_rdy), .f19_dst_rdy_o(refr_dst_rdy), + .f36_dataout(tx36_data), .f36_src_rdy_o(tx36_src_rdy), .f36_dst_rdy_i(tx36_dst_rdy)); + + fifo_cascade #(.WIDTH(36), .SIZE(TXFIFOSIZE)) tx_fifo36 + (.clk(fifo_clk), .reset(fifo_rst), .clear(clear_tx), + .datain(tx36_data), .src_rdy_i(tx36_src_rdy), .dst_rdy_o(tx36_dst_rdy), + .dataout(tx_data_o), .src_rdy_o(tx_src_rdy_o), .dst_rdy_i(tx_dst_rdy_i)); + + // //////////////////////////////////////////// + // RX Data Path + + wire [35:0] rx36_data; + wire rx36_src_rdy, rx36_dst_rdy; + wire [18:0] rx19_data; + wire rx19_src_rdy, rx19_dst_rdy; + wire [15:0] rxfifospace; + + //deep 36 bit wide input fifo buffers from DSP + fifo_cascade #(.WIDTH(36), .SIZE(8)) rx_fifo36 + (.clk(fifo_clk), .reset(fifo_rst), .clear(clear_rx), + .datain(rx_data_i), .src_rdy_i(rx_src_rdy_i), .dst_rdy_o(rx_dst_rdy_o), + .dataout(rx36_data), .src_rdy_o(rx36_src_rdy), .dst_rdy_i(rx36_dst_rdy)); + + //convert to fifo19 + fifo36_to_fifo19 #(.LE(1)) f36_to_f19 + (.clk(fifo_clk), .reset(fifo_rst), .clear(clear_rx), + .f36_datain(rx36_data), .f36_src_rdy_i(rx36_src_rdy), .f36_dst_rdy_o(rx36_dst_rdy), + .f19_dataout(rx19_data), .f19_src_rdy_o(rx19_src_rdy), .f19_dst_rdy_i(rx19_dst_rdy) ); + + wire [18:0] data_rx_int; + wire rx_src_rdy_int, rx_dst_rdy_int; + //clock domain crossing fifo for RX data + fifo_2clock_cascade #(.WIDTH(19), .SIZE(4)) rd_fifo_2clk + (.wclk(fifo_clk), .datain(rx19_data), .src_rdy_i(rx19_src_rdy), .dst_rdy_o(rx19_dst_rdy), .space(), + .rclk(~gpif_clk), .dataout(data_rx_int), .src_rdy_o(rx_src_rdy_int), .dst_rdy_i(rx_dst_rdy_int), .occupied(), + .arst(fifo_rst)); + + //rd_fifo buffers writes to the 2clock fifo above + fifo_cascade #(.WIDTH(19), .SIZE(12)) rd_fifo + (.clk(~gpif_clk), .reset(gpif_rst), .clear(0), + .datain(data_rx_int), .src_rdy_i(rx_src_rdy_int), .dst_rdy_o(rx_dst_rdy_int), .space(rxfifospace), + .dataout(gpif_d_out_data), .src_rdy_o(data_rx_src_rdy), .dst_rdy_i(data_rx_dst_rdy), .occupied()); + + // //////////////////////////////////////////////////////////////////// + // FIFO to Wishbone interface + + wire [18:0] resp_data, resp_int; + wire resp_src_rdy, resp_dst_rdy; + wire resp_src_rdy_int, resp_dst_rdy_int; + + wire [18:0] tx_err19_data; + wire tx_err19_src_rdy, tx_err19_dst_rdy; + + wire [18:0] ctrl_data; + wire ctrl_src_rdy, ctrl_dst_rdy; + + fifo_to_wb fifo_to_wb + (.clk(fifo_clk), .reset(fifo_rst), .clear(0), + .data_i(ctrl_data), .src_rdy_i(ctrl_src_rdy), .dst_rdy_o(ctrl_dst_rdy), + .data_o(resp_int), .src_rdy_o(resp_src_rdy_int), .dst_rdy_i(resp_dst_rdy_int), + .wb_adr_o(wb_adr_o), .wb_dat_mosi(wb_dat_mosi), .wb_dat_miso(wb_dat_miso), .wb_sel_o(wb_sel_o), + .wb_cyc_o(wb_cyc_o), .wb_stb_o(wb_stb_o), .wb_we_o(wb_we_o), .wb_ack_i(wb_ack_i), + .triggers(triggers), + .debug0(), .debug1()); + + // //////////////////////////////////////////////////////////////////// + // TX CTRL PATH (ctrl commands into Wishbone) + + //how does this use fifo_clk instead of wb_clk + //answer: on b100 fifo clk IS wb clk + fifo_2clock_cascade #(.WIDTH(19), .SIZE(4)) ctrl_fifo_2clk + (.wclk(gpif_clk), .datain({1'b0,eop,sop,gpif_d}), + .src_rdy_i(ctrl_tx_src_rdy), .dst_rdy_o(ctrl_tx_dst_rdy), .space(), + .rclk(fifo_clk), .dataout(ctrl_data), + .src_rdy_o(ctrl_src_rdy), .dst_rdy_i(ctrl_dst_rdy), .occupied(), + .arst(fifo_rst)); + + // //////////////////////////////////////////////////////////////////// + // RX CTRL PATH (async packets, ctrl response data) + + //tx_err_data_i is the 36wide tx async err data clocked on fifo_clk + fifo36_to_fifo19 #(.LE(1)) f36_to_f19_txerr + (.clk(fifo_clk), .reset(fifo_rst), .clear(clear_rx), + .f36_datain(tx_err_data_i), .f36_src_rdy_i(tx_err_src_rdy_i), .f36_dst_rdy_o(tx_err_dst_rdy_o), + .f19_dataout(tx_err19_data), .f19_src_rdy_o(tx_err19_src_rdy), .f19_dst_rdy_i(tx_err19_dst_rdy) ); + + //mux FIFO-to-WB along with async tx err pkts into one ctrl resp fifo + //how is this clocked on wb_clk? + fifo19_mux #(.prio(0)) mux_err_stream + (.clk(wb_clk), .reset(wb_rst), .clear(0), + .data0_i(resp_int), .src0_rdy_i(resp_src_rdy_int), .dst0_rdy_o(resp_dst_rdy_int), + .data1_i(tx_err19_data), .src1_rdy_i(tx_err19_src_rdy), .dst1_rdy_o(tx_err19_dst_rdy), + .data_o(resp_data), .src_rdy_o(resp_src_rdy), .dst_rdy_i(resp_dst_rdy)); + + //clock domain crossing cascade fifo for mux_err_stream to get from wb_clk to gpif_clk + //the output of this fifo is CTRL DATA PENDING FOR GPIF + fifo_2clock_cascade #(.WIDTH(18), .SIZE(4)) resp_fifo_2clk + (.wclk(wb_clk), .datain(resp_data[17:0]), .src_rdy_i(resp_src_rdy), .dst_rdy_o(resp_dst_rdy), .space(), + .rclk(~gpif_clk), .dataout(gpif_d_out_ctrl), + .src_rdy_o(ctrl_rx_src_rdy), .dst_rdy_i(ctrl_rx_dst_rdy), .occupied(), + .arst(wb_rst)); + + + // //////////////////////////////////////////////////////////////////// + // Debug support, timed and loopback + // RX side muxes test data into the same stream + + /////////////////////////////////////////////////////////////////////// + // debug lines + wire [31:0] debug_rd, debug_wr, debug_split0, debug_split1; + + wire [35:0] timedrx_data, loopbackrx_data, testrx_data; + wire [35:0] timedtx_data, loopbacktx_data, testtx_data; + wire timedrx_src_rdy, timedrx_dst_rdy, loopbackrx_src_rdy, loopbackrx_dst_rdy, + testrx_src_rdy, testrx_dst_rdy; + wire timedtx_src_rdy, timedtx_dst_rdy, loopbacktx_src_rdy, loopbacktx_dst_rdy, + testtx_src_rdy, testtx_dst_rdy; + wire timedrx_src_rdy_int, timedrx_dst_rdy_int, timedtx_src_rdy_int, timedtx_dst_rdy_int; + + wire [31:0] total, crc_err, seq_err, len_err; + wire sel_testtx = test_ctrl[0]; + wire sel_loopbacktx = test_ctrl[1]; + wire pkt_src_enable = test_ctrl[2]; + wire pkt_sink_enable = test_ctrl[3]; +/* + fifo36_mux rx_test_mux_lvl_1 + (.clk(fifo_clk), .reset(fifo_rst), .clear(clear_rx), + .data0_i(timedrx_data), .src0_rdy_i(timedrx_src_rdy), .dst0_rdy_o(timedrx_dst_rdy), + .data1_i(loopbackrx_data), .src1_rdy_i(loopbackrx_src_rdy), .dst1_rdy_o(loopbackrx_dst_rdy), + .data_o(testrx_data), .src_rdy_o(testrx_src_rdy), .dst_rdy_i(testrx_dst_rdy)); + + fifo36_mux rx_test_mux_lvl_2 + (.clk(fifo_clk), .reset(fifo_rst), .clear(clear_rx), + .data0_i(testrx_data), .src0_rdy_i(testrx_src_rdy), .dst0_rdy_o(testrx_dst_rdy), + .data1_i(rx_data_i), .src1_rdy_i(rx_src_rdy_i), .dst1_rdy_o(rx_dst_rdy_o), + .data_o(rx_data), .src_rdy_o(rx_src_rdy), .dst_rdy_i(rx_dst_rdy)); + + fifo_short #(.WIDTH(36)) loopback_fifo + (.clk(fifo_clk), .reset(fifo_rst), .clear(clear_tx | clear_rx), + .datain(loopbacktx_data), .src_rdy_i(loopbacktx_src_rdy), .dst_rdy_o(loopbacktx_dst_rdy), + .dataout(loopbackrx_data), .src_rdy_o(loopbackrx_src_rdy), .dst_rdy_i(loopbackrx_dst_rdy)); + + // Crossbar used as a demux for switching TX stream to main DSP or to test logic + crossbar36 tx_crossbar_lvl_1 + (.clk(fifo_clk), .reset(fifo_rst), .clear(clear_tx), + .cross(sel_testtx), + .data0_i(tx_data), .src0_rdy_i(tx_src_rdy), .dst0_rdy_o(tx_dst_rdy), + .data1_i(tx_data), .src1_rdy_i(1'b0), .dst1_rdy_o(), // No 2nd input + .data0_o(tx_data_o), .src0_rdy_o(tx_src_rdy_o), .dst0_rdy_i(tx_dst_rdy_i), + .data1_o(testtx_data), .src1_rdy_o(testtx_src_rdy), .dst1_rdy_i(testtx_dst_rdy) ); + + crossbar36 tx_crossbar_lvl_2 + (.clk(fifo_clk), .reset(fifo_rst), .clear(clear_tx), + .cross(sel_loopbacktx), + .data0_i(testtx_data), .src0_rdy_i(testtx_src_rdy), .dst0_rdy_o(testtx_dst_rdy), + .data1_i(testtx_data), .src1_rdy_i(1'b0), .dst1_rdy_o(), // No 2nd input + .data0_o(timedtx_data), .src0_rdy_o(timedtx_src_rdy), .dst0_rdy_i(timedtx_dst_rdy), + .data1_o(loopbacktx_data), .src1_rdy_o(loopbacktx_src_rdy), .dst1_rdy_i(loopbacktx_dst_rdy) ); + + // Fixed rate TX traffic consumer + fifo_pacer tx_pacer + (.clk(fifo_clk), .reset(fifo_rst), .rate(test_rate), .enable(pkt_sink_enable), + .src1_rdy_i(timedtx_src_rdy), .dst1_rdy_o(timedtx_dst_rdy), + .src2_rdy_o(timedtx_src_rdy_int), .dst2_rdy_i(timedtx_dst_rdy_int), + .underrun(tx_underrun), .overrun()); + + packet_verifier32 pktver32 + (.clk(fifo_clk), .reset(fifo_rst), .clear(clear_tx), + .data_i(timedtx_data), .src_rdy_i(timedtx_src_rdy_int), .dst_rdy_o(timedtx_dst_rdy_int), + .total(total), .crc_err(crc_err), .seq_err(seq_err), .len_err(len_err)); + + // Fixed rate RX traffic generator + vita_pkt_gen pktgen + (.clk(fifo_clk), .reset(fifo_rst), .clear(clear_rx), + .len(test_len), + .data_o(timedrx_data), .src_rdy_o(timedrx_src_rdy_int), .dst_rdy_i(timedrx_dst_rdy_int)); + + fifo_pacer rx_pacer + (.clk(fifo_clk), .reset(fifo_rst), .rate(test_rate), .enable(pkt_src_enable), + .src1_rdy_i(timedrx_src_rdy_int), .dst1_rdy_o(timedrx_dst_rdy_int), + .src2_rdy_o(timedrx_src_rdy), .dst2_rdy_i(timedrx_dst_rdy), + .underrun(), .overrun(rx_overrun)); +*/ + // //////////////////////////////////////////// + // DEBUG + + //assign debug0 = { data_tx_dst_rdy, refr_state, gpif_ctl[3:0], refr_eof, slrd, slwr, pktend, fifoadr[1:0], state[3:0], refr_len[15:0]}; + assign debug0 = { data_tx_src_rdy, data_tx_dst_rdy, tx_src_rdy_int, tx_dst_rdy_int, + tx19_src_rdy, tx19_dst_rdy, refr_src_rdy, refr_dst_rdy, + tx36_src_rdy, tx36_dst_rdy, + gpif_ctl[3:0], fifoadr[1:0], + wr_fifo_space[15:0]}; + assign debug1 = { 16'b0, transfer_count[7:0], ctrl_rx_src_rdy, ctrl_tx_dst_rdy, data_rx_src_rdy, + data_tx_dst_rdy, ctrl_tx_src_rdy, ctrl_rx_dst_rdy, data_tx_src_rdy, data_rx_dst_rdy}; +endmodule // slave_fifo diff --git a/usrp2/top/B100/B100.ucf b/usrp2/top/B100/B100.ucf index 69fd49971..c86501e72 100644 --- a/usrp2/top/B100/B100.ucf +++ b/usrp2/top/B100/B100.ucf @@ -43,17 +43,18 @@ NET "GPIF_D<2>" LOC = "N9" ; NET "GPIF_D<1>" LOC = "P9" ; NET "GPIF_D<0>" LOC = "P8" ; -NET "GPIF_CTL<3>" LOC = "N5" ; +##NET "GPIF_CTL<3>" LOC = "N5" ; +NET "GPIF_CTL<3>" LOC = "P12" ; NET "GPIF_CTL<2>" LOC = "M11" ; NET "GPIF_CTL<1>" LOC = "M9" ; NET "GPIF_CTL<0>" LOC = "M7" ; -NET "GPIF_RDY<3>" LOC = "N11" ; -NET "GPIF_RDY<2>" LOC = "T10" ; -NET "GPIF_RDY<1>" LOC = "T4" ; -NET "GPIF_RDY<0>" LOC = "R5" ; +##NET "GPIF_RDY<3>" LOC = "N11" ; +##NET "GPIF_RDY<2>" LOC = "T10" ; +NET "GPIF_SLWR" LOC = "T4" ; +NET "GPIF_SLRD" LOC = "R5" ; -NET "GPIF_CS" LOC = "P12" ; +##NET "GPIF_CS" LOC = "P12" ; NET "GPIF_SLOE" LOC = "R11" ; NET "GPIF_PKTEND" LOC = "P10" ; NET "GPIF_ADR<0>" LOC = "T11" ; diff --git a/usrp2/top/B100/B100.v b/usrp2/top/B100/B100.v index f2d75c54e..b5691d1c3 100644 --- a/usrp2/top/B100/B100.v +++ b/usrp2/top/B100/B100.v @@ -23,8 +23,8 @@ module B100 output [2:0] debug_led, output [31:0] debug, output [1:0] debug_clk, // GPIF - inout [15:0] GPIF_D, input [3:0] GPIF_CTL, output [3:0] GPIF_RDY, - input [1:0] GPIF_ADR, output GPIF_CS, output GPIF_SLOE, output GPIF_PKTEND, + inout [15:0] GPIF_D, input [3:0] GPIF_CTL, output GPIF_SLOE, + output [1:0] GPIF_ADR, output GPIF_SLWR, output GPIF_SLRD, output GPIF_PKTEND, input IFCLK, inout SDA_FPGA, inout SCL_FPGA, // I2C @@ -156,9 +156,10 @@ module B100 u1plus_core u1p_c(.clk_fpga(clk_fpga), .rst_fpga(reset), .debug_led(debug_led), .debug(debug), .debug_clk(debug_clk), .debug_txd(), .debug_rxd(1'b1), - .gpif_d(GPIF_D), .gpif_ctl(GPIF_CTL), .gpif_rdy(GPIF_RDY), - .gpif_misc({GPIF_CS,GPIF_SLOE,GPIF_PKTEND}), - .gpif_clk(IFCLK), + + .gpif_d(GPIF_D), .gpif_ctl(GPIF_CTL), .gpif_pktend(GPIF_PKTEND), + .gpif_sloe(GPIF_SLOE), .gpif_slwr(GPIF_SLWR), .gpif_slrd(GPIF_SLRD), + .gpif_fifoadr(GPIF_ADR), .gpif_clk(IFCLK), .db_sda(SDA_FPGA), .db_scl(SCL_FPGA), .sclk(sclk), .sen({SEN_CODEC,SEN_TX_DB,SEN_RX_DB}), .mosi(mosi), .miso(miso), diff --git a/usrp2/top/B100/core_compile b/usrp2/top/B100/core_compile deleted file mode 100755 index b2ccc8b49..000000000 --- a/usrp2/top/B100/core_compile +++ /dev/null @@ -1 +0,0 @@ -iverilog -Wall -y. -y ../../control_lib/ -y ../../fifo/ -y ../../gpif/ -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 u1plus_core.v 2>&1 | grep -v timescale | grep -v coregen | grep -v models diff --git a/usrp2/top/B100/u1plus_core.v b/usrp2/top/B100/u1plus_core.v index c883c5ca8..88fec3d99 100644 --- a/usrp2/top/B100/u1plus_core.v +++ b/usrp2/top/B100/u1plus_core.v @@ -23,8 +23,9 @@ module u1plus_core output debug_txd, input debug_rxd, // GPIF - inout [15:0] gpif_d, input [3:0] gpif_ctl, output [3:0] gpif_rdy, - output [2:0] gpif_misc, input gpif_clk, + inout [15:0] gpif_d, input [3:0] gpif_ctl, output gpif_sloe, + output gpif_slwr, output gpif_slrd, output gpif_pktend, output [1:0] gpif_fifoadr, + input gpif_clk, inout db_sda, inout db_scl, output sclk, output [15:0] sen, output mosi, input miso, @@ -114,16 +115,21 @@ module u1plus_core setting_reg #(.my_addr(SR_CLEAR_TX_FIFO), .width(1)) sr_clear_tx (.clk(wb_clk),.rst(wb_rst),.strobe(set_stb),.addr(set_addr), .in(set_data),.out(),.changed(clear_tx)); + + wire run_rx0, run_rx1; - gpif #(.TXFIFOSIZE(TXFIFOSIZE), .RXFIFOSIZE(RXFIFOSIZE)) - gpif (.gpif_clk(gpif_clk), .gpif_rst(gpif_rst), .gpif_d(gpif_d), - .gpif_ctl(gpif_ctl), .gpif_rdy(gpif_rdy), .gpif_misc(gpif_misc), + slave_fifo #(.TXFIFOSIZE(TXFIFOSIZE), .RXFIFOSIZE(RXFIFOSIZE)) + slave_fifo (.gpif_clk(gpif_clk), .gpif_rst(gpif_rst), .gpif_d(gpif_d), + .gpif_ctl(gpif_ctl), .sloe(gpif_sloe), .slwr(gpif_slwr), .slrd(gpif_slrd), + .pktend(gpif_pktend), .fifoadr(gpif_fifoadr), .wb_clk(wb_clk), .wb_rst(wb_rst), .wb_adr_o(m0_adr), .wb_dat_mosi(m0_dat_mosi), .wb_dat_miso(m0_dat_miso), .wb_sel_o(m0_sel), .wb_cyc_o(m0_cyc), .wb_stb_o(m0_stb), .wb_we_o(m0_we), .wb_ack_i(m0_ack), .triggers(8'd0), + .dsp_rx_run(run_rx0 | run_rx1), + .fifo_clk(wb_clk), .fifo_rst(wb_rst), .clear_tx(clear_tx), .clear_rx(clear_rx), .tx_data_o(tx_data), .tx_src_rdy_o(tx_src_rdy), .tx_dst_rdy_i(tx_dst_rdy), .rx_data_i(rx_data), .rx_src_rdy_i(rx_src_rdy), .rx_dst_rdy_o(rx_dst_rdy), @@ -131,14 +137,13 @@ module u1plus_core .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)); // ///////////////////////////////////////////////////////////////////////// // 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_rx0, run_rx1; rx_frontend #(.BASE(SR_RX_FRONT)) rx_frontend (.clk(wb_clk),.rst(wb_rst), -- cgit v1.2.3 From a2bb47b824e498cd10a190fac7fb2fdb2da074d0 Mon Sep 17 00:00:00 2001 From: Nick Foster Date: Thu, 12 Jan 2012 13:45:09 -0800 Subject: B100: moar buffering on TX for better performance in bidirectional applications --- usrp2/gpif/slave_fifo.v | 6 +++--- usrp2/top/B100/u1plus_core.v | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/usrp2/gpif/slave_fifo.v b/usrp2/gpif/slave_fifo.v index faba2b107..c1a51b008 100644 --- a/usrp2/gpif/slave_fifo.v +++ b/usrp2/gpif/slave_fifo.v @@ -20,7 +20,7 @@ //this is a FIFO master interface for the FX2 in "slave fifo" mode. module slave_fifo - #(parameter TXFIFOSIZE = 11, parameter RXFIFOSIZE = 11) + #(parameter TXFIFOSIZE = 12, parameter RXFIFOSIZE = 12) (// GPIF signals input gpif_clk, input gpif_rst, inout [15:0] gpif_d, @@ -243,7 +243,7 @@ module slave_fifo else data_tx_dst_rdy <= wr_fifo_space >= 256; - fifo_cascade #(.WIDTH(18), .SIZE(10)) wr_fifo + fifo_cascade #(.WIDTH(18), .SIZE(12)) wr_fifo (.clk(gpif_clk), .reset(gpif_rst), .clear(0), .datain({eop,sop,gpif_d}), .src_rdy_i(data_tx_src_rdy), .dst_rdy_o(/*data_tx_dst_rdy*/), .space(wr_fifo_space), .dataout(data_tx_int), .src_rdy_o(tx_src_rdy_int), .dst_rdy_i(tx_dst_rdy_int), .occupied()); @@ -308,7 +308,7 @@ module slave_fifo .arst(fifo_rst)); //rd_fifo buffers writes to the 2clock fifo above - fifo_cascade #(.WIDTH(19), .SIZE(12)) rd_fifo + fifo_cascade #(.WIDTH(19), .SIZE(RXFIFOSIZE)) rd_fifo (.clk(~gpif_clk), .reset(gpif_rst), .clear(0), .datain(data_rx_int), .src_rdy_i(rx_src_rdy_int), .dst_rdy_o(rx_dst_rdy_int), .space(rxfifospace), .dataout(gpif_d_out_data), .src_rdy_o(data_rx_src_rdy), .dst_rdy_i(data_rx_dst_rdy), .occupied()); diff --git a/usrp2/top/B100/u1plus_core.v b/usrp2/top/B100/u1plus_core.v index 88fec3d99..a7b6e677e 100644 --- a/usrp2/top/B100/u1plus_core.v +++ b/usrp2/top/B100/u1plus_core.v @@ -37,8 +37,8 @@ module u1plus_core input pps_in ); - localparam TXFIFOSIZE = 11; - localparam RXFIFOSIZE = 11; + localparam TXFIFOSIZE = 12; + localparam RXFIFOSIZE = 12; // 64 total regs in address space localparam SR_RX_CTRL0 = 0; // 9 regs (+0 to +8) -- cgit v1.2.3 From 59b3885e195570f7797b0d73a7162508bbb693ee Mon Sep 17 00:00:00 2001 From: Nick Foster Date: Thu, 12 Jan 2012 17:26:49 -0800 Subject: Slave FIFO: fix for PKTEND not asserting @ end of RX. --- usrp2/gpif/slave_fifo.v | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/usrp2/gpif/slave_fifo.v b/usrp2/gpif/slave_fifo.v index c1a51b008..2f98043ab 100644 --- a/usrp2/gpif/slave_fifo.v +++ b/usrp2/gpif/slave_fifo.v @@ -126,10 +126,10 @@ module slave_fifo state <= STATE_DATA_TX_SLOE; else if(data_rx_src_rdy & ~FX2_DF) state <= STATE_DATA_RX_ADR; - else if(~data_rx_src_rdy & ~dsp_rx_run & pktend_latch) + else if(~data_rx_src_rdy & ~dsp_rx_run & pktend_latch & ~FX2_DF) state <= STATE_PKTEND; - if(dsp_rx_run) + if(data_rx_src_rdy) pktend_latch <= 1; end @@ -456,12 +456,12 @@ module slave_fifo // //////////////////////////////////////////// // DEBUG - //assign debug0 = { data_tx_dst_rdy, refr_state, gpif_ctl[3:0], refr_eof, slrd, slwr, pktend, fifoadr[1:0], state[3:0], refr_len[15:0]}; - assign debug0 = { data_tx_src_rdy, data_tx_dst_rdy, tx_src_rdy_int, tx_dst_rdy_int, - tx19_src_rdy, tx19_dst_rdy, refr_src_rdy, refr_dst_rdy, - tx36_src_rdy, tx36_dst_rdy, - gpif_ctl[3:0], fifoadr[1:0], - wr_fifo_space[15:0]}; + assign debug0 = { pktend_latch, data_rx_src_rdy, gpif_ctl[3:0], sloe, slrd, slwr, pktend, fifoadr[1:0], state[3:0], gpif_d[15:0]}; + //assign debug0 = { data_tx_src_rdy, data_tx_dst_rdy, tx_src_rdy_int, tx_dst_rdy_int, + // tx19_src_rdy, tx19_dst_rdy, refr_src_rdy, refr_dst_rdy, + // tx36_src_rdy, tx36_dst_rdy, + // gpif_ctl[3:0], fifoadr[1:0], + // wr_fifo_space[15:0]}; assign debug1 = { 16'b0, transfer_count[7:0], ctrl_rx_src_rdy, ctrl_tx_dst_rdy, data_rx_src_rdy, data_tx_dst_rdy, ctrl_tx_src_rdy, ctrl_rx_dst_rdy, data_tx_src_rdy, data_rx_dst_rdy}; endmodule // slave_fifo -- cgit v1.2.3 From b36ab78c18d7c68ad9c9367004ff8decfb2ce817 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Thu, 12 Jan 2012 18:54:04 -0800 Subject: b100: bumped fpga compat number for slave fifo mode --- usrp2/top/B100/u1plus_core.v | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usrp2/top/B100/u1plus_core.v b/usrp2/top/B100/u1plus_core.v index a7b6e677e..0bada703c 100644 --- a/usrp2/top/B100/u1plus_core.v +++ b/usrp2/top/B100/u1plus_core.v @@ -396,7 +396,7 @@ module u1plus_core // Readback mux 32 -- Slave #7 //compatibility number -> increment when the fpga has been sufficiently altered - localparam compat_num = {16'd8, 16'd1}; //major, minor + localparam compat_num = {16'd9, 16'd0}; //major, minor wire [31:0] reg_test32; -- cgit v1.2.3 From 111216e5cd579996ec8f498e155e9485580327e6 Mon Sep 17 00:00:00 2001 From: Nick Foster Date: Mon, 23 Jan 2012 11:09:41 -0800 Subject: Fix missing B100 core_compile (poor Git hygeine) --- usrp2/top/B100/core_compile | 1 + 1 file changed, 1 insertion(+) create mode 100755 usrp2/top/B100/core_compile diff --git a/usrp2/top/B100/core_compile b/usrp2/top/B100/core_compile new file mode 100755 index 000000000..b2ccc8b49 --- /dev/null +++ b/usrp2/top/B100/core_compile @@ -0,0 +1 @@ +iverilog -Wall -y. -y ../../control_lib/ -y ../../fifo/ -y ../../gpif/ -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 u1plus_core.v 2>&1 | grep -v timescale | grep -v coregen | grep -v models -- cgit v1.2.3 From cbea8a3b14412b513b54167b745307a102f2fe68 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Thu, 26 Jan 2012 19:00:07 -0800 Subject: dsp rework: u2_core test implementation --- usrp2/sdr_lib/Makefile.srcs | 4 +- usrp2/sdr_lib/ddc_chain.v | 145 +++++++++++++++++++++++++++++ usrp2/sdr_lib/dsp_core_rx.v | 144 ----------------------------- usrp2/sdr_lib/dsp_core_rx_old.v | 200 ---------------------------------------- usrp2/sdr_lib/dsp_core_rx_tb.v | 10 +- usrp2/sdr_lib/dsp_core_rx_udp.v | 200 ---------------------------------------- usrp2/sdr_lib/dsp_core_tx.v | 153 ------------------------------ usrp2/sdr_lib/duc_chain.v | 155 +++++++++++++++++++++++++++++++ usrp2/sdr_lib/dummy_rx.v | 2 +- usrp2/top/B100/u1plus_core.v | 4 +- usrp2/top/E1x0/u1e_core.v | 4 +- usrp2/top/N2x0/u2plus_core.v | 4 +- usrp2/top/USRP2/u2_core.v | 21 +++-- usrp2/vrt/vita_rx_chain.v | 5 +- usrp2/vrt/vita_tx_chain.v | 26 ++---- 15 files changed, 340 insertions(+), 737 deletions(-) create mode 100644 usrp2/sdr_lib/ddc_chain.v delete mode 100644 usrp2/sdr_lib/dsp_core_rx.v delete mode 100644 usrp2/sdr_lib/dsp_core_rx_old.v delete mode 100644 usrp2/sdr_lib/dsp_core_rx_udp.v delete mode 100644 usrp2/sdr_lib/dsp_core_tx.v create mode 100644 usrp2/sdr_lib/duc_chain.v diff --git a/usrp2/sdr_lib/Makefile.srcs b/usrp2/sdr_lib/Makefile.srcs index 629b92cc8..0f1958991 100644 --- a/usrp2/sdr_lib/Makefile.srcs +++ b/usrp2/sdr_lib/Makefile.srcs @@ -23,8 +23,8 @@ clip_reg.v \ cordic.v \ cordic_z24.v \ cordic_stage.v \ -dsp_core_rx.v \ -dsp_core_tx.v \ +ddc_chain.v \ +duc_chain.v \ dspengine_16to8.v \ hb_dec.v \ hb_interp.v \ diff --git a/usrp2/sdr_lib/ddc_chain.v b/usrp2/sdr_lib/ddc_chain.v new file mode 100644 index 000000000..7f51d2865 --- /dev/null +++ b/usrp2/sdr_lib/ddc_chain.v @@ -0,0 +1,145 @@ +// +// 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 . +// + +//! The USRP digital down-conversion chain + +module ddc_chain + #(parameter BASE = 160) + (input clk, input rst, + input set_stb, input [7:0] set_addr, input [31:0] set_data, + + input [23:0] adc_i, + input [23:0] adc_q, + + output [31:0] sample, + input run, + output strobe, + output [31:0] debug + ); + + wire [31:0] phase_inc; + reg [31:0] phase; + + wire [24:0] i_cordic, q_cordic; + wire [23:0] i_cordic_clip, q_cordic_clip; + wire [23:0] i_cic, q_cic; + 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()); + + setting_reg #(.my_addr(BASE+3), .width(2)) sr_3 + (.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr), + .in(set_data),.out({realmode,swap_iq}),.changed()); + + // MUX so we can do realmode signals on either input + + always @(posedge clk) + 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; + else if(~run) + phase <= 0; + else + phase <= phase + phase_inc; + + // CORDIC 24-bit I/O + cordic_z24 #(.bitwidth(25)) + cordic(.clock(clk), .reset(rst), .enable(run), + .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), .strobe_in(1'b1), .out(i_cordic_clip)); + clip_reg #(.bits_in(25), .bits_out(24)) clip_q + (.clk(clk), .in(q_cordic), .strobe_in(1'b1), .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_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_clip),.signal_out(q_cic)); + + // 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),.data_in(i_cic),.stb_out(strobe_hb1),.data_out(i_hb1)); + + small_hb_dec #(.WIDTH(24)) small_hb_q + (.clk(clk),.rst(rst),.bypass(~enable_hb1),.run(run), + .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 #(.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 #(.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 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)); + + 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 debug = {enable_hb1, enable_hb2, run, strobe, strobe_cic, strobe_hb1, strobe_hb2}; + +endmodule // ddc_chain diff --git a/usrp2/sdr_lib/dsp_core_rx.v b/usrp2/sdr_lib/dsp_core_rx.v deleted file mode 100644 index d1c7e238a..000000000 --- a/usrp2/sdr_lib/dsp_core_rx.v +++ /dev/null @@ -1,144 +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 . -// - - -module dsp_core_rx - #(parameter BASE = 160) - (input clk, input rst, - input set_stb, input [7:0] set_addr, input [31:0] set_data, - - input [23:0] adc_i, input adc_ovf_i, - input [23:0] adc_q, input adc_ovf_q, - - output [31:0] sample, - input run, - output strobe, - output [31:0] debug - ); - - wire [31:0] phase_inc; - reg [31:0] phase; - - wire [24:0] i_cordic, q_cordic; - wire [23:0] i_cordic_clip, q_cordic_clip; - wire [23:0] i_cic, q_cic; - 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()); - - setting_reg #(.my_addr(BASE+3), .width(2)) sr_3 - (.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr), - .in(set_data),.out({realmode,swap_iq}),.changed()); - - // MUX so we can do realmode signals on either input - - always @(posedge clk) - 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; - else if(~run) - phase <= 0; - else - phase <= phase + phase_inc; - - // CORDIC 24-bit I/O - cordic_z24 #(.bitwidth(25)) - cordic(.clock(clk), .reset(rst), .enable(run), - .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), .strobe_in(1'b1), .out(i_cordic_clip)); - clip_reg #(.bits_in(25), .bits_out(24)) clip_q - (.clk(clk), .in(q_cordic), .strobe_in(1'b1), .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_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_clip),.signal_out(q_cic)); - - // 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),.data_in(i_cic),.stb_out(strobe_hb1),.data_out(i_hb1)); - - small_hb_dec #(.WIDTH(24)) small_hb_q - (.clk(clk),.rst(rst),.bypass(~enable_hb1),.run(run), - .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 #(.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 #(.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 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)); - - 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 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_old.v b/usrp2/sdr_lib/dsp_core_rx_old.v deleted file mode 100644 index 90d5d839f..000000000 --- a/usrp2/sdr_lib/dsp_core_rx_old.v +++ /dev/null @@ -1,200 +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 . -// - - -`define DSP_CORE_RX_BASE 160 -module dsp_core_rx_old - (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 [15:0] io_rx, - - output [31:0] sample, - input run, - output strobe, - 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 [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 strobe_cic, strobe_hb1, strobe_hb2; - wire enable_hb1, enable_hb2; - wire [7:0] cic_decim_rate; - - wire [31:10] UNUSED_1; - wire [31:4] UNUSED_2; - wire [31:2] UNUSED_3; - - setting_reg #(.my_addr(`DSP_CORE_RX_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(`DSP_CORE_RX_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(`DSP_CORE_RX_BASE+2)) sr_2 - (.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr), - .in(set_data),.out({UNUSED_1, enable_hb1, enable_hb2, cic_decim_rate}),.changed()); - - rx_dcoffset #(.WIDTH(14),.ADDR(`DSP_CORE_RX_BASE+6)) 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(`DSP_CORE_RX_BASE+7)) 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 [3:0] muxctrl; - setting_reg #(.my_addr(`DSP_CORE_RX_BASE+8)) sr_8 - (.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr), - .in(set_data),.out({UNUSED_2,muxctrl}),.changed()); - - wire [1:0] gpio_ena; - setting_reg #(.my_addr(`DSP_CORE_RX_BASE+9)) sr_9 - (.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr), - .in(set_data),.out({UNUSED_3,gpio_ena}),.changed()); - - // The TVRX connects to what is called adc_b, thus A and B are - // swapped throughout the design. - // - // In the interest of expediency and keeping the s/w sane, we just remap them here. - // The I & Q fields are mapped the same: - // 0 -> "the real A" (as determined by the TVRX) - // 1 -> "the real B" - // 2 -> const zero - - always @(posedge clk) - case(muxctrl[1:0]) // The I mapping - 0: adc_i <= adc_b_ofs; // "the real A" - 1: adc_i <= adc_a_ofs; - 2: adc_i <= 0; - default: adc_i <= 0; - endcase // case(muxctrl[1:0]) - - always @(posedge clk) - case(muxctrl[3:2]) // The Q mapping - 0: adc_q <= adc_b_ofs; // "the real A" - 1: adc_q <= adc_a_ofs; - 2: adc_q <= 0; - default: adc_q <= 0; - endcase // case(muxctrl[3:2]) - - always @(posedge clk) - if(rst) - phase <= 0; - else if(~run) - phase <= 0; - 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(.clock(clk), .reset(rst), .enable(run), - .xi(prod_i[23:0]),. yi(prod_q[23:0]), .zi(phase[31:8]), - .xo(i_cordic),.yo(q_cordic),.zo() ); - - 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)); - - 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)); - - 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 - (.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)); - - small_hb_dec #(.WIDTH(18)) 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)); - - 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 - (.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 - (.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)); - - // Streaming GPIO - // - // io_rx[15] => I channel LSB if gpio_ena[0] high - // io_rx[14] => Q channel LSB if gpio_ena[1] high - - reg [31:0] sample_reg; - always @(posedge clk) - begin - sample_reg[31:17] <= i_out[15:1]; - sample_reg[15:1] <= q_out[15:1]; - sample_reg[16] <= gpio_ena[0] ? io_rx[15] : i_out[0]; - sample_reg[0] <= gpio_ena[1] ? io_rx[14] : q_out[0]; - end - - 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}; - -endmodule // dsp_core_rx diff --git a/usrp2/sdr_lib/dsp_core_rx_tb.v b/usrp2/sdr_lib/dsp_core_rx_tb.v index 271db8cef..a221bed44 100644 --- a/usrp2/sdr_lib/dsp_core_rx_tb.v +++ b/usrp2/sdr_lib/dsp_core_rx_tb.v @@ -1,6 +1,6 @@ `timescale 1ns/1ns -module dsp_core_rx_tb(); +module ddc_chain_tb(); reg clk, rst; @@ -9,8 +9,8 @@ module dsp_core_rx_tb(); initial clk = 0; always #5 clk = ~clk; - initial $dumpfile("dsp_core_rx_tb.vcd"); - initial $dumpvars(0,dsp_core_rx_tb); + initial $dumpfile("ddc_chain_tb.vcd"); + initial $dumpvars(0,ddc_chain_tb); reg signed [23:0] adc_in; wire signed [15:0] adc_out_i, adc_out_q; @@ -27,7 +27,7 @@ module dsp_core_rx_tb(); reg [7:0] set_addr; reg [31:0] set_data; - dsp_core_rx #(.BASE(0)) dsp_core_rx + ddc_chain #(.BASE(0)) ddc_chain (.clk(clk),.rst(rst), .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data), .adc_i(adc_in), .adc_ovf_i(0), @@ -70,4 +70,4 @@ module dsp_core_rx_tb(); adc_in <= adc_in + 4; //adc_in <= (($random % 473) + 23)/4; */ -endmodule // dsp_core_rx_tb +endmodule // ddc_chain_tb diff --git a/usrp2/sdr_lib/dsp_core_rx_udp.v b/usrp2/sdr_lib/dsp_core_rx_udp.v deleted file mode 100644 index 08dab37e6..000000000 --- a/usrp2/sdr_lib/dsp_core_rx_udp.v +++ /dev/null @@ -1,200 +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 . -// - - -module dsp_core_rx - #(parameter BASE = 160) - (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 [15:0] io_rx, - - output [31:0] sample, - input run, - output strobe, - 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 [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 strobe_cic, strobe_hb1, strobe_hb2; - wire enable_hb1, enable_hb2; - wire [7:0] cic_decim_rate; - - wire [31:10] UNUSED_1; - wire [31:4] UNUSED_2; - wire [31:2] UNUSED_3; - - 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)) sr_2 - (.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr), - .in(set_data),.out({UNUSED_1, 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 [3:0] muxctrl; - setting_reg #(.my_addr(BASE+5)) sr_8 - (.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr), - .in(set_data),.out({UNUSED_2,muxctrl}),.changed()); - - wire [1:0] gpio_ena; - setting_reg #(.my_addr(BASE+6)) sr_9 - (.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr), - .in(set_data),.out({UNUSED_3,gpio_ena}),.changed()); - - // The TVRX connects to what is called adc_b, thus A and B are - // swapped throughout the design. - // - // In the interest of expediency and keeping the s/w sane, we just remap them here. - // The I & Q fields are mapped the same: - // 0 -> "the real A" (as determined by the TVRX) - // 1 -> "the real B" - // 2 -> const zero - - always @(posedge clk) - case(muxctrl[1:0]) // The I mapping - 0: adc_i <= adc_b_ofs; // "the real A" - 1: adc_i <= adc_a_ofs; - 2: adc_i <= 0; - default: adc_i <= 0; - endcase // case(muxctrl[1:0]) - - always @(posedge clk) - case(muxctrl[3:2]) // The Q mapping - 0: adc_q <= adc_b_ofs; // "the real A" - 1: adc_q <= adc_a_ofs; - 2: adc_q <= 0; - default: adc_q <= 0; - endcase // case(muxctrl[3:2]) - - always @(posedge clk) - if(rst) - phase <= 0; - else if(~run) - phase <= 0; - 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(.clock(clk), .reset(rst), .enable(run), - .xi(prod_i[23:0]),. yi(prod_q[23:0]), .zi(phase[31:8]), - .xo(i_cordic),.yo(q_cordic),.zo() ); - - 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)); - - 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)); - - 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 - (.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)); - - small_hb_dec #(.WIDTH(18)) 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)); - - 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 - (.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 - (.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)); - - // Streaming GPIO - // - // io_rx[15] => I channel LSB if gpio_ena[0] high - // io_rx[14] => Q channel LSB if gpio_ena[1] high - - reg [31:0] sample_reg; - always @(posedge clk) - begin - sample_reg[31:17] <= i_out[15:1]; - sample_reg[15:1] <= q_out[15:1]; - sample_reg[16] <= gpio_ena[0] ? io_rx[15] : i_out[0]; - sample_reg[0] <= gpio_ena[1] ? io_rx[14] : q_out[0]; - end - - 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}; - -endmodule // dsp_core_rx diff --git a/usrp2/sdr_lib/dsp_core_tx.v b/usrp2/sdr_lib/dsp_core_tx.v deleted file mode 100644 index 4e0163e0a..000000000 --- a/usrp2/sdr_lib/dsp_core_tx.v +++ /dev/null @@ -1,153 +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 . -// - - -module dsp_core_tx - #(parameter BASE=0) - (input clk, input rst, - input set_stb, input [7:0] set_addr, input [31:0] set_data, - - output [23:0] tx_i, output [23:0] tx_q, - - // To tx_control - input [31:0] sample, - input run, - output strobe, - output [31:0] debug - ); - - wire [15:0] i, q, scale_i, scale_q; - wire [31:0] phase_inc; - reg [31:0] phase; - wire [7:0] interp_rate; - wire [3:0] dacmux_a, dacmux_b; - wire enable_hb1, enable_hb2; - wire rate_change; - - 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, interp_rate}),.changed(rate_change)); - - // 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; - reg strobe_hb1 = 1; - reg strobe_hb2 = 1; - - cic_strober #(.WIDTH(8)) - cic_strober(.clock(clk),.reset(rst),.enable(run & ~rate_change),.rate(interp_rate), - .strobe_fast(1),.strobe_slow(strobe_cic_pre) ); - cic_strober #(.WIDTH(2)) - hb2_strober(.clock(clk),.reset(rst),.enable(run & ~rate_change),.rate(enable_hb2 ? 2 : 1), - .strobe_fast(strobe_cic_pre),.strobe_slow(strobe_hb2_pre) ); - cic_strober #(.WIDTH(2)) - hb1_strober(.clock(clk),.reset(rst),.enable(run & ~rate_change),.rate(enable_hb1 ? 2 : 1), - .strobe_fast(strobe_hb2_pre),.strobe_slow(strobe_hb1_pre) ); - - always @(posedge clk) strobe_hb1 <= strobe_hb1_pre; - always @(posedge clk) strobe_hb2 <= strobe_hb2_pre; - always @(posedge clk) strobe_cic <= strobe_cic_pre; - - // NCO - always @(posedge clk) - if(rst) - phase <= 0; - else if(~run) - phase <= 0; - else - phase <= phase + phase_inc; - - wire signed [17:0] da, db; - wire signed [35:0] prod_i, prod_q; - - wire [17:0] bb_i = {sample[31:16],2'b0}; - wire [17:0] bb_q = {sample[15:0],2'b0}; - wire [17:0] i_interp, q_interp; - - wire [17:0] hb1_i, hb1_q, hb2_i, hb2_q; - - wire [7:0] cpo = enable_hb2 ? ({interp_rate,1'b0}) : interp_rate; - // Note that max CIC rate is 128, which would give an overflow on cpo if enable_hb2 is true, - // but the default case inside hb_interp handles this - - hb_interp #(.IWIDTH(18),.OWIDTH(18),.ACCWIDTH(24)) hb_interp_i - (.clk(clk),.rst(rst),.bypass(~enable_hb1),.cpo(cpo),.stb_in(strobe_hb1),.data_in(bb_i),.stb_out(strobe_hb2),.data_out(hb1_i)); - hb_interp #(.IWIDTH(18),.OWIDTH(18),.ACCWIDTH(24)) hb_interp_q - (.clk(clk),.rst(rst),.bypass(~enable_hb1),.cpo(cpo),.stb_in(strobe_hb1),.data_in(bb_q),.stb_out(strobe_hb2),.data_out(hb1_q)); - - small_hb_int #(.WIDTH(18)) small_hb_interp_i - (.clk(clk),.rst(rst),.bypass(~enable_hb2),.stb_in(strobe_hb2),.data_in(hb1_i), - .output_rate(interp_rate),.stb_out(strobe_cic),.data_out(hb2_i)); - small_hb_int #(.WIDTH(18)) small_hb_interp_q - (.clk(clk),.rst(rst),.bypass(~enable_hb2),.stb_in(strobe_hb2),.data_in(hb1_q), - .output_rate(interp_rate),.stb_out(strobe_cic),.data_out(hb2_q)); - - cic_interp #(.bw(18),.N(4),.log2_of_max_rate(7)) - cic_interp_i(.clock(clk),.reset(rst),.enable(run & ~rate_change),.rate(interp_rate), - .strobe_in(strobe_cic),.strobe_out(1), - .signal_in(hb2_i),.signal_out(i_interp)); - - cic_interp #(.bw(18),.N(4),.log2_of_max_rate(7)) - cic_interp_q(.clock(clk),.reset(rst),.enable(run & ~rate_change),.rate(interp_rate), - .strobe_in(strobe_cic),.strobe_out(1), - .signal_in(hb2_q),.signal_out(q_interp)); - - assign strobe = strobe_hb1; - - localparam cwidth = 24; // was 18 - localparam zwidth = 24; // was 16 - - wire [cwidth-1:0] da_c, db_c; - - cordic_z24 #(.bitwidth(cwidth)) - cordic(.clock(clk), .reset(rst), .enable(run), - .xi({i_interp,{(cwidth-18){1'b0}}}),.yi({q_interp,{(cwidth-18){1'b0}}}), - .zi(phase[31:32-zwidth]), - .xo(da_c),.yo(db_c),.zo() ); - - MULT18X18S MULT18X18S_inst - (.P(prod_i), // 36-bit multiplier output - .A(da_c[cwidth-1:cwidth-18]), // 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 MULT18X18S_inst_2 - (.P(prod_q), // 36-bit multiplier output - .A(db_c[cwidth-1:cwidth-18]), // 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 - ); - - assign tx_i = prod_i[28:5]; - assign tx_q = prod_q[28:5]; - - assign debug = {strobe_cic, strobe_hb1, strobe_hb2,run}; - -endmodule // dsp_core diff --git a/usrp2/sdr_lib/duc_chain.v b/usrp2/sdr_lib/duc_chain.v new file mode 100644 index 000000000..248870a69 --- /dev/null +++ b/usrp2/sdr_lib/duc_chain.v @@ -0,0 +1,155 @@ +// +// 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 . +// + +//! The USRP digital up-conversion chain + +module duc_chain + #(parameter BASE=0) + (input clk, input rst, + input set_stb, input [7:0] set_addr, input [31:0] set_data, + + output [23:0] dac_i, + output [23:0] dac_q, + + // To tx_control + input [31:0] sample, + input run, + output strobe, + output [31:0] debug + ); + + wire [15:0] i, q, scale_i, scale_q; + wire [31:0] phase_inc; + reg [31:0] phase; + wire [7:0] interp_rate; + wire [3:0] dacmux_a, dacmux_b; + wire enable_hb1, enable_hb2; + wire rate_change; + + 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, interp_rate}),.changed(rate_change)); + + // 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; + reg strobe_hb1 = 1; + reg strobe_hb2 = 1; + + cic_strober #(.WIDTH(8)) + cic_strober(.clock(clk),.reset(rst),.enable(run & ~rate_change),.rate(interp_rate), + .strobe_fast(1),.strobe_slow(strobe_cic_pre) ); + cic_strober #(.WIDTH(2)) + hb2_strober(.clock(clk),.reset(rst),.enable(run & ~rate_change),.rate(enable_hb2 ? 2 : 1), + .strobe_fast(strobe_cic_pre),.strobe_slow(strobe_hb2_pre) ); + cic_strober #(.WIDTH(2)) + hb1_strober(.clock(clk),.reset(rst),.enable(run & ~rate_change),.rate(enable_hb1 ? 2 : 1), + .strobe_fast(strobe_hb2_pre),.strobe_slow(strobe_hb1_pre) ); + + always @(posedge clk) strobe_hb1 <= strobe_hb1_pre; + always @(posedge clk) strobe_hb2 <= strobe_hb2_pre; + always @(posedge clk) strobe_cic <= strobe_cic_pre; + + // NCO + always @(posedge clk) + if(rst) + phase <= 0; + else if(~run) + phase <= 0; + else + phase <= phase + phase_inc; + + wire signed [17:0] da, db; + wire signed [35:0] prod_i, prod_q; + + wire [17:0] bb_i = {sample[31:16],2'b0}; + wire [17:0] bb_q = {sample[15:0],2'b0}; + wire [17:0] i_interp, q_interp; + + wire [17:0] hb1_i, hb1_q, hb2_i, hb2_q; + + wire [7:0] cpo = enable_hb2 ? ({interp_rate,1'b0}) : interp_rate; + // Note that max CIC rate is 128, which would give an overflow on cpo if enable_hb2 is true, + // but the default case inside hb_interp handles this + + hb_interp #(.IWIDTH(18),.OWIDTH(18),.ACCWIDTH(24)) hb_interp_i + (.clk(clk),.rst(rst),.bypass(~enable_hb1),.cpo(cpo),.stb_in(strobe_hb1),.data_in(bb_i),.stb_out(strobe_hb2),.data_out(hb1_i)); + hb_interp #(.IWIDTH(18),.OWIDTH(18),.ACCWIDTH(24)) hb_interp_q + (.clk(clk),.rst(rst),.bypass(~enable_hb1),.cpo(cpo),.stb_in(strobe_hb1),.data_in(bb_q),.stb_out(strobe_hb2),.data_out(hb1_q)); + + small_hb_int #(.WIDTH(18)) small_hb_interp_i + (.clk(clk),.rst(rst),.bypass(~enable_hb2),.stb_in(strobe_hb2),.data_in(hb1_i), + .output_rate(interp_rate),.stb_out(strobe_cic),.data_out(hb2_i)); + small_hb_int #(.WIDTH(18)) small_hb_interp_q + (.clk(clk),.rst(rst),.bypass(~enable_hb2),.stb_in(strobe_hb2),.data_in(hb1_q), + .output_rate(interp_rate),.stb_out(strobe_cic),.data_out(hb2_q)); + + cic_interp #(.bw(18),.N(4),.log2_of_max_rate(7)) + cic_interp_i(.clock(clk),.reset(rst),.enable(run & ~rate_change),.rate(interp_rate), + .strobe_in(strobe_cic),.strobe_out(1), + .signal_in(hb2_i),.signal_out(i_interp)); + + cic_interp #(.bw(18),.N(4),.log2_of_max_rate(7)) + cic_interp_q(.clock(clk),.reset(rst),.enable(run & ~rate_change),.rate(interp_rate), + .strobe_in(strobe_cic),.strobe_out(1), + .signal_in(hb2_q),.signal_out(q_interp)); + + assign strobe = strobe_hb1; + + localparam cwidth = 24; // was 18 + localparam zwidth = 24; // was 16 + + wire [cwidth-1:0] da_c, db_c; + + cordic_z24 #(.bitwidth(cwidth)) + cordic(.clock(clk), .reset(rst), .enable(run), + .xi({i_interp,{(cwidth-18){1'b0}}}),.yi({q_interp,{(cwidth-18){1'b0}}}), + .zi(phase[31:32-zwidth]), + .xo(da_c),.yo(db_c),.zo() ); + + MULT18X18S MULT18X18S_inst + (.P(prod_i), // 36-bit multiplier output + .A(da_c[cwidth-1:cwidth-18]), // 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 MULT18X18S_inst_2 + (.P(prod_q), // 36-bit multiplier output + .A(db_c[cwidth-1:cwidth-18]), // 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 + ); + + assign tx_i = prod_i[28:5]; + assign tx_q = prod_q[28:5]; + + assign debug = {strobe_cic, strobe_hb1, strobe_hb2,run}; + +endmodule // dsp_core diff --git a/usrp2/sdr_lib/dummy_rx.v b/usrp2/sdr_lib/dummy_rx.v index b22d5f896..42bbe36b2 100644 --- a/usrp2/sdr_lib/dummy_rx.v +++ b/usrp2/sdr_lib/dummy_rx.v @@ -76,4 +76,4 @@ module dummy_rx q_out <= q_out + 1; -endmodule // dsp_core_rx +endmodule // ddc_chain diff --git a/usrp2/top/B100/u1plus_core.v b/usrp2/top/B100/u1plus_core.v index c883c5ca8..0a03517b6 100644 --- a/usrp2/top/B100/u1plus_core.v +++ b/usrp2/top/B100/u1plus_core.v @@ -155,7 +155,7 @@ module u1plus_core 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 + ddc_chain #(.BASE(SR_RX_DSP0)) ddc_chain0 (.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), @@ -178,7 +178,7 @@ module u1plus_core 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 + ddc_chain #(.BASE(SR_RX_DSP1)) ddc_chain1 (.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), diff --git a/usrp2/top/E1x0/u1e_core.v b/usrp2/top/E1x0/u1e_core.v index aede63bac..b581ed50a 100644 --- a/usrp2/top/E1x0/u1e_core.v +++ b/usrp2/top/E1x0/u1e_core.v @@ -160,7 +160,7 @@ module u1e_core 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 + ddc_chain #(.BASE(SR_RX_DSP0)) ddc_chain0 (.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), @@ -183,7 +183,7 @@ module u1e_core 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 + ddc_chain #(.BASE(SR_RX_DSP1)) ddc_chain1 (.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), diff --git a/usrp2/top/N2x0/u2plus_core.v b/usrp2/top/N2x0/u2plus_core.v index 3ead0db8e..f78d9013f 100644 --- a/usrp2/top/N2x0/u2plus_core.v +++ b/usrp2/top/N2x0/u2plus_core.v @@ -576,7 +576,7 @@ module u2plus_core always @(posedge dsp_clk) run_rx0_d1 <= run_rx0; - dsp_core_rx #(.BASE(SR_RX_DSP0)) dsp_core_rx0 + ddc_chain #(.BASE(SR_RX_DSP0)) ddc_chain0 (.clk(dsp_clk),.rst(dsp_rst), .set_stb(set_stb_dsp),.set_addr(set_addr_dsp),.set_data(set_data_dsp), .adc_i(adc_i),.adc_ovf_i(adc_ovf_a),.adc_q(adc_q),.adc_ovf_q(adc_ovf_b), @@ -604,7 +604,7 @@ module u2plus_core always @(posedge dsp_clk) run_rx1_d1 <= run_rx1; - dsp_core_rx #(.BASE(SR_RX_DSP1)) dsp_core_rx1 + ddc_chain #(.BASE(SR_RX_DSP1)) ddc_chain1 (.clk(dsp_clk),.rst(dsp_rst), .set_stb(set_stb_dsp),.set_addr(set_addr_dsp),.set_data(set_data_dsp), .adc_i(adc_i),.adc_ovf_i(adc_ovf_a),.adc_q(adc_q),.adc_ovf_q(adc_ovf_b), diff --git a/usrp2/top/USRP2/u2_core.v b/usrp2/top/USRP2/u2_core.v index bbd0e9337..da12371bb 100644 --- a/usrp2/top/USRP2/u2_core.v +++ b/usrp2/top/USRP2/u2_core.v @@ -564,10 +564,10 @@ module u2_core always @(posedge dsp_clk) run_rx0_d1 <= run_rx0; - dsp_core_rx #(.BASE(SR_RX_DSP0)) dsp_core_rx0 + ddc_chain #(.BASE(SR_RX_DSP0)) ddc_chain0 (.clk(dsp_clk),.rst(dsp_rst), .set_stb(set_stb_dsp),.set_addr(set_addr_dsp),.set_data(set_data_dsp), - .adc_i(adc_i),.adc_ovf_i(adc_ovf_a),.adc_q(adc_q),.adc_ovf_q(adc_ovf_b), + .adc_i(adc_i),.adc_q(adc_q), .sample(sample_rx0), .run(run_rx0_d1), .strobe(strobe_rx0), .debug() ); @@ -592,10 +592,10 @@ module u2_core always @(posedge dsp_clk) run_rx1_d1 <= run_rx1; - dsp_core_rx #(.BASE(SR_RX_DSP1)) dsp_core_rx1 + ddc_chain #(.BASE(SR_RX_DSP1)) ddc_chain1 (.clk(dsp_clk),.rst(dsp_rst), .set_stb(set_stb_dsp),.set_addr(set_addr_dsp),.set_data(set_data_dsp), - .adc_i(adc_i),.adc_ovf_i(adc_ovf_a),.adc_q(adc_q),.adc_ovf_q(adc_ovf_b), + .adc_i(adc_i),.adc_q(adc_q), .sample(sample_rx1), .run(run_rx1_d1), .strobe(strobe_rx1), .debug() ); @@ -648,8 +648,10 @@ module u2_core .debug2(debug_extfifo2) ); wire [23:0] tx_i, tx_q; + wire [31:0] sample_tx; + wire strobe_tx; - vita_tx_chain #(.BASE_CTRL(SR_TX_CTRL), .BASE_DSP(SR_TX_DSP), + vita_tx_chain #(.BASE(SR_TX_CTRL), .REPORT_ERROR(1), .DO_FLOW_CONTROL(1), .PROT_ENG_FLAGS(1), .USE_TRANS_HEADER(1), .DSP_NUMBER(0)) @@ -659,10 +661,17 @@ 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), - .tx_i(tx_i),.tx_q(tx_q), + .sample(sample_tx), .strobe(strobe_tx), .underrun(underrun), .run(run_tx), .debug(debug_vt)); + duc_chain #(.BASE(SR_TX_DSP)) duc_chain + (.clk(dsp_clk),.rst(dsp_rst), + .set_stb(set_stb_dsp),.set_addr(set_addr_dsp),.set_data(set_data_dsp), + .dac_i(tx_i),.dac_q(tx_q), + .sample(sample_tx), .run(run_tx), .strobe(strobe_tx), + .debug() ); + 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), diff --git a/usrp2/vrt/vita_rx_chain.v b/usrp2/vrt/vita_rx_chain.v index 8b41e5fa8..332fdce37 100644 --- a/usrp2/vrt/vita_rx_chain.v +++ b/usrp2/vrt/vita_rx_chain.v @@ -23,9 +23,10 @@ module vita_rx_chain parameter PROT_ENG_FLAGS=1) (input clk, input reset, input clear, input set_stb, input [7:0] set_addr, input [31:0] set_data, - input [63:0] vita_time, output overrun, - input [31:0] sample, output run, input strobe, + input [63:0] vita_time, + input [31:0] sample, input strobe, output [35:0] rx_data_o, output rx_src_rdy_o, input rx_dst_rdy_i, + output overrun, output run, output [31:0] debug ); wire [100:0] sample_data; diff --git a/usrp2/vrt/vita_tx_chain.v b/usrp2/vrt/vita_tx_chain.v index ac9f08fc8..5c211c51e 100644 --- a/usrp2/vrt/vita_tx_chain.v +++ b/usrp2/vrt/vita_tx_chain.v @@ -17,8 +17,7 @@ module vita_tx_chain - #(parameter BASE_CTRL=0, - parameter BASE_DSP=0, + #(parameter BASE=0, parameter REPORT_ERROR=0, parameter DO_FLOW_CONTROL=0, parameter PROT_ENG_FLAGS=0, @@ -29,7 +28,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 [23:0] tx_i, output [23:0] tx_q, + output [31:0] sample, input strobe, output underrun, output run, output [31:0] debug); @@ -39,7 +38,6 @@ module vita_tx_chain wire [FIFOWIDTH-1:0] tx1_data; wire tx1_src_rdy, tx1_dst_rdy; wire clear_vita; - wire [31:0] sample_tx; wire [31:0] streamid, message; wire trigger, sent; wire [31:0] debug_vtc, debug_vtd, debug_tx_dsp; @@ -48,20 +46,19 @@ module vita_tx_chain wire [31:0] error_code; wire clear_seqnum; wire [31:0] current_seqnum; - wire strobe_tx; assign underrun = error; assign message = error_code; - setting_reg #(.my_addr(BASE_CTRL+1)) sr + setting_reg #(.my_addr(BASE+1)) sr (.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr), .in(set_data),.out(),.changed(clear_vita)); - setting_reg #(.my_addr(BASE_CTRL+2), .at_reset(0)) sr_streamid + setting_reg #(.my_addr(BASE+2), .at_reset(0)) sr_streamid (.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr), .in(set_data),.out(streamid),.changed(clear_seqnum)); - vita_tx_deframer #(.BASE(BASE_CTRL), + vita_tx_deframer #(.BASE(BASE), .MAXCHAN(MAXCHAN), .USE_TRANS_HEADER(USE_TRANS_HEADER)) vita_tx_deframer @@ -72,20 +69,13 @@ module vita_tx_chain .current_seqnum(current_seqnum), .debug(debug_vtd) ); - vita_tx_control #(.BASE(BASE_CTRL), .WIDTH(32*MAXCHAN)) vita_tx_control + vita_tx_control #(.BASE(BASE), .WIDTH(32*MAXCHAN)) vita_tx_control (.clk(clk), .reset(reset), .clear(clear_vita), .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data), .vita_time(vita_time), .error(error), .ack(ack), .error_code(error_code), .sample_fifo_i(tx1_data), .sample_fifo_src_rdy_i(tx1_src_rdy), .sample_fifo_dst_rdy_o(tx1_dst_rdy), - .sample(sample_tx), .run(run), .strobe(strobe_tx), .packet_consumed(packet_consumed), + .sample(sample), .run(run), .strobe(strobe), .packet_consumed(packet_consumed), .debug(debug_vtc) ); - - dsp_core_tx #(.BASE(BASE_DSP)) dsp_core_tx - (.clk(clk),.rst(reset), - .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data), - .sample(sample_tx), .run(run), .strobe(strobe_tx), - .tx_i(tx_i),.tx_q(tx_q), - .debug(debug_tx_dsp) ); wire [35:0] flow_data, err_data_int; wire flow_src_rdy, flow_dst_rdy, err_src_rdy_int, err_dst_rdy_int; @@ -96,7 +86,7 @@ module vita_tx_chain .streamid(streamid), .vita_time(vita_time), .message(32'd0), .seqnum(current_seqnum), .data_o(flow_data), .src_rdy_o(flow_src_rdy), .dst_rdy_i(flow_dst_rdy)); - trigger_context_pkt #(.BASE(BASE_CTRL)) trigger_context_pkt + trigger_context_pkt #(.BASE(BASE)) trigger_context_pkt (.clk(clk), .reset(reset), .clear(clear_vita), .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data), .packet_consumed(packet_consumed), .trigger(trigger)); -- cgit v1.2.3 From e633f884d728c24e6f5749d5821b9c62ec8fd17e Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Fri, 27 Jan 2012 11:52:19 -0800 Subject: dsp rework: renamed dsp signals for frontend IO --- README.txt | 31 +++++++++++++++++++++++++++++++ usrp2/sdr_lib/ddc_chain.v | 24 +++++++++++++----------- usrp2/sdr_lib/duc_chain.v | 17 +++++++++-------- usrp2/top/USRP2/u2_core.v | 22 +++++++++++----------- usrp2/vrt/vita_rx_chain.v | 2 +- usrp2/vrt/vita_tx_chain.v | 2 +- 6 files changed, 66 insertions(+), 32 deletions(-) create mode 100644 README.txt diff --git a/README.txt b/README.txt new file mode 100644 index 000000000..bfdf317c1 --- /dev/null +++ b/README.txt @@ -0,0 +1,31 @@ +######################################################################## +## Welcome to the USRP FPGA source code tree +######################################################################## + +usrp1/ + + Description: generation 1 products + + Devices: USRP classic only + + Tools: Quartus from Altera + + Project file: usrp1/toplevel/usrp_std/ + +usrp2/ + + Description: generation 2 products + + Devices: USRP2, N2XX, B100, E1XX + + Tools: ISE from Xilinx, GNU make + + Build Instructions: + 1) ensure that xtclsh is in the $PATH + 2) cd usrp2/top/ + 3) make -f Makefile. bin + 4) bin file in build-/*.bin + + Customize the DSP: + Implement design in usrp2/custom/custom_*.v + Instructions are included in the module. diff --git a/usrp2/sdr_lib/ddc_chain.v b/usrp2/sdr_lib/ddc_chain.v index 7f51d2865..647ec212b 100644 --- a/usrp2/sdr_lib/ddc_chain.v +++ b/usrp2/sdr_lib/ddc_chain.v @@ -1,5 +1,5 @@ // -// Copyright 2011 Ettus Research LLC +// Copyright 2011-2012 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 @@ -18,13 +18,15 @@ //! The USRP digital down-conversion chain module ddc_chain - #(parameter BASE = 160) + #(parameter BASE = 0, parameter DSPNO = 0) (input clk, input rst, input set_stb, input [7:0] set_addr, input [31:0] set_data, - input [23:0] adc_i, - input [23:0] adc_q, - + // From RX frontend + input [23:0] rx_fe_i, + input [23:0] rx_fe_q, + + // To RX control output [31:0] sample, input run, output strobe, @@ -44,7 +46,7 @@ module ddc_chain wire enable_hb1, enable_hb2; wire [7:0] cic_decim_rate; - reg [23:0] adc_i_mux, adc_q_mux; + reg [23:0] rx_fe_i_mux, rx_fe_q_mux; wire realmode; wire swap_iq; @@ -71,13 +73,13 @@ module ddc_chain always @(posedge clk) if(swap_iq) begin - adc_i_mux <= adc_q; - adc_q_mux <= realmode ? 24'd0 : adc_i; + rx_fe_i_mux <= rx_fe_q; + rx_fe_q_mux <= realmode ? 24'd0 : rx_fe_i; end else begin - adc_i_mux <= adc_i; - adc_q_mux <= realmode ? 24'd0 : adc_q; + rx_fe_i_mux <= rx_fe_i; + rx_fe_q_mux <= realmode ? 24'd0 : rx_fe_q; end // NCO @@ -92,7 +94,7 @@ module ddc_chain // CORDIC 24-bit I/O cordic_z24 #(.bitwidth(25)) cordic(.clock(clk), .reset(rst), .enable(run), - .xi({adc_i_mux[23],adc_i_mux}),. yi({adc_q_mux[23],adc_q_mux}), .zi(phase[31:8]), + .xi({rx_fe_i_mux[23],rx_fe_i_mux}),. yi({rx_fe_q_mux[23],rx_fe_q_mux}), .zi(phase[31:8]), .xo(i_cordic),.yo(q_cordic),.zo() ); clip_reg #(.bits_in(25), .bits_out(24)) clip_i diff --git a/usrp2/sdr_lib/duc_chain.v b/usrp2/sdr_lib/duc_chain.v index 248870a69..f1c32a1b2 100644 --- a/usrp2/sdr_lib/duc_chain.v +++ b/usrp2/sdr_lib/duc_chain.v @@ -1,5 +1,5 @@ // -// Copyright 2011 Ettus Research LLC +// Copyright 2011-2012 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 @@ -18,14 +18,15 @@ //! The USRP digital up-conversion chain module duc_chain - #(parameter BASE=0) + #(parameter BASE = 0, parameter DSPNO = 0) (input clk, input rst, input set_stb, input [7:0] set_addr, input [31:0] set_data, - output [23:0] dac_i, - output [23:0] dac_q, + // From TX frontend + output [23:0] tx_fe_i, + output [23:0] tx_fe_q, - // To tx_control + // To TX control input [31:0] sample, input run, output strobe, @@ -36,7 +37,7 @@ module duc_chain wire [31:0] phase_inc; reg [31:0] phase; wire [7:0] interp_rate; - wire [3:0] dacmux_a, dacmux_b; + wire [3:0] tx_femux_a, tx_femux_b; wire enable_hb1, enable_hb2; wire rate_change; @@ -147,8 +148,8 @@ module duc_chain .R(rst) // Synchronous reset input ); - assign tx_i = prod_i[28:5]; - assign tx_q = prod_q[28:5]; + assign tx_fe_i = prod_i[28:5]; + assign tx_fe_q = prod_q[28:5]; assign debug = {strobe_cic, strobe_hb1, strobe_hb2,run}; diff --git a/usrp2/top/USRP2/u2_core.v b/usrp2/top/USRP2/u2_core.v index da12371bb..2315b41c7 100644 --- a/usrp2/top/USRP2/u2_core.v +++ b/usrp2/top/USRP2/u2_core.v @@ -1,5 +1,5 @@ // -// Copyright 2011 Ettus Research LLC +// Copyright 2011-2012 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 @@ -547,14 +547,14 @@ module u2_core // ///////////////////////////////////////////////////////////////////////// // ADC Frontend - wire [23:0] adc_i, adc_q; + wire [23:0] rx_fe_i, rx_fe_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()); + .i_out(rx_fe_i), .q_out(rx_fe_q), .run(run_rx0_d1 | run_rx1_d1), .debug()); // ///////////////////////////////////////////////////////////////////////// // DSP RX 0 @@ -564,10 +564,10 @@ module u2_core always @(posedge dsp_clk) run_rx0_d1 <= run_rx0; - ddc_chain #(.BASE(SR_RX_DSP0)) ddc_chain0 + ddc_chain #(.BASE(SR_RX_DSP0), .DSPNO(0)) ddc_chain0 (.clk(dsp_clk),.rst(dsp_rst), .set_stb(set_stb_dsp),.set_addr(set_addr_dsp),.set_data(set_data_dsp), - .adc_i(adc_i),.adc_q(adc_q), + .rx_fe_i(rx_fe_i),.rx_fe_q(rx_fe_q), .sample(sample_rx0), .run(run_rx0_d1), .strobe(strobe_rx0), .debug() ); @@ -592,10 +592,10 @@ module u2_core always @(posedge dsp_clk) run_rx1_d1 <= run_rx1; - ddc_chain #(.BASE(SR_RX_DSP1)) ddc_chain1 + ddc_chain #(.BASE(SR_RX_DSP1), .DSPNO(1)) ddc_chain1 (.clk(dsp_clk),.rst(dsp_rst), .set_stb(set_stb_dsp),.set_addr(set_addr_dsp),.set_data(set_data_dsp), - .adc_i(adc_i),.adc_q(adc_q), + .rx_fe_i(rx_fe_i),.rx_fe_q(rx_fe_q), .sample(sample_rx1), .run(run_rx1_d1), .strobe(strobe_rx1), .debug() ); @@ -647,7 +647,7 @@ module u2_core .debug(debug_extfifo), .debug2(debug_extfifo2) ); - wire [23:0] tx_i, tx_q; + wire [23:0] tx_fe_i, tx_fe_q; wire [31:0] sample_tx; wire strobe_tx; @@ -665,17 +665,17 @@ module u2_core .underrun(underrun), .run(run_tx), .debug(debug_vt)); - duc_chain #(.BASE(SR_TX_DSP)) duc_chain + duc_chain #(.BASE(SR_TX_DSP), .DSPNO(0)) duc_chain (.clk(dsp_clk),.rst(dsp_rst), .set_stb(set_stb_dsp),.set_addr(set_addr_dsp),.set_data(set_data_dsp), - .dac_i(tx_i),.dac_q(tx_q), + .tx_fe_i(tx_fe_i),.tx_fe_q(tx_fe_q), .sample(sample_tx), .run(run_tx), .strobe(strobe_tx), .debug() ); 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), + .tx_i(tx_fe_i), .tx_q(tx_fe_q), .run(1'b1), .dac_a(dac_a), .dac_b(dac_b)); // /////////////////////////////////////////////////////////////////////////////////// diff --git a/usrp2/vrt/vita_rx_chain.v b/usrp2/vrt/vita_rx_chain.v index 332fdce37..13defdbc6 100644 --- a/usrp2/vrt/vita_rx_chain.v +++ b/usrp2/vrt/vita_rx_chain.v @@ -1,5 +1,5 @@ // -// Copyright 2011 Ettus Research LLC +// Copyright 2011-2012 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 diff --git a/usrp2/vrt/vita_tx_chain.v b/usrp2/vrt/vita_tx_chain.v index 5c211c51e..1db16de63 100644 --- a/usrp2/vrt/vita_tx_chain.v +++ b/usrp2/vrt/vita_tx_chain.v @@ -1,5 +1,5 @@ // -// Copyright 2011 Ettus Research LLC +// Copyright 2011-2012 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 -- cgit v1.2.3 From bcda4624deb5a81ba2ad338157c44855dab56397 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Fri, 27 Jan 2012 13:20:34 -0800 Subject: dsp rework: implemented dsp changes for other top levels added user registers into each toplevel (not used yet) --- usrp2/control_lib/Makefile.srcs | 3 +- usrp2/control_lib/user_settings.v | 63 ++++++++++++++++++++++++++++++++++ usrp2/sdr_lib/ddc_chain.v | 2 +- usrp2/sdr_lib/duc_chain.v | 2 +- usrp2/top/B100/u1plus_core.v | 52 ++++++++++++++++++---------- usrp2/top/E1x0/u1e_core.v | 50 ++++++++++++++++++--------- usrp2/top/N2x0/u2plus_core.v | 72 ++++++++++++++++++++------------------- usrp2/top/USRP2/u2_core.v | 53 +++++++++++++--------------- usrp2/vrt/vita_rx_chain.v | 10 ++++-- usrp2/vrt/vita_tx_chain.v | 2 +- 10 files changed, 203 insertions(+), 106 deletions(-) create mode 100644 usrp2/control_lib/user_settings.v diff --git a/usrp2/control_lib/Makefile.srcs b/usrp2/control_lib/Makefile.srcs index 567feacde..6ee7ea262 100644 --- a/usrp2/control_lib/Makefile.srcs +++ b/usrp2/control_lib/Makefile.srcs @@ -1,5 +1,5 @@ # -# Copyright 2010 Ettus Research LLC +# Copyright 2010-2012 Ettus Research LLC # ################################################## @@ -54,4 +54,5 @@ settings_bus_16LE.v \ atr_controller16.v \ fifo_to_wb.v \ gpio_atr.v \ +user_settings.v \ )) diff --git a/usrp2/control_lib/user_settings.v b/usrp2/control_lib/user_settings.v new file mode 100644 index 000000000..96ee22427 --- /dev/null +++ b/usrp2/control_lib/user_settings.v @@ -0,0 +1,63 @@ +// +// Copyright 2011 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 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 . +// + +// User settings bus +// +// Provides 8-bit address, 32-bit data write only bus for user settings, consumes to addresses in +// normal settings bus. +// +// Write user address to BASE +// Write user data to BASE+1 +// +// The user_set_stb will strobe after data write, must write new address even if same as previous one. + +module user_settings + #(parameter BASE=0) + (input clk, + input rst, + + input set_stb, + input [7:0] set_addr, + input [31:0] set_data, + + output set_stb_user, + output [7:0] set_addr_user, + output [31:0] set_data_user + ); + + wire addr_changed, data_changed; + reg stb_int; + + setting_reg #(.my_addr(BASE+0),.width(8)) sr_0 + (.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr), + .in(set_data),.out(set_addr_user),.changed(addr_changed) ); + + setting_reg #(.my_addr(BASE+1)) sr_1 + (.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr), + .in(set_data),.out(set_data_user),.changed(data_changed) ); + + always @(posedge clk) + if (rst|set_stb_user) + stb_int <= 0; + else + if (addr_changed) + stb_int <= 1; + + assign set_stb_user = stb_int & data_changed; + +endmodule // user_settings + diff --git a/usrp2/sdr_lib/ddc_chain.v b/usrp2/sdr_lib/ddc_chain.v index 647ec212b..02544a0fe 100644 --- a/usrp2/sdr_lib/ddc_chain.v +++ b/usrp2/sdr_lib/ddc_chain.v @@ -18,7 +18,7 @@ //! The USRP digital down-conversion chain module ddc_chain - #(parameter BASE = 0, parameter DSPNO = 0) + #(parameter BASE = 0) (input clk, input rst, input set_stb, input [7:0] set_addr, input [31:0] set_data, diff --git a/usrp2/sdr_lib/duc_chain.v b/usrp2/sdr_lib/duc_chain.v index f1c32a1b2..0d3ca258f 100644 --- a/usrp2/sdr_lib/duc_chain.v +++ b/usrp2/sdr_lib/duc_chain.v @@ -18,7 +18,7 @@ //! The USRP digital up-conversion chain module duc_chain - #(parameter BASE = 0, parameter DSPNO = 0) + #(parameter BASE = 0) (input clk, input rst, input set_stb, input [7:0] set_addr, input [31:0] set_data, diff --git a/usrp2/top/B100/u1plus_core.v b/usrp2/top/B100/u1plus_core.v index 0a03517b6..64c8defb3 100644 --- a/usrp2/top/B100/u1plus_core.v +++ b/usrp2/top/B100/u1plus_core.v @@ -1,5 +1,5 @@ // -// Copyright 2011 Ettus Research LLC +// Copyright 2011-2012 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 @@ -55,6 +55,7 @@ module u1plus_core localparam SR_CLEAR_RX_FIFO = 61; // 1 reg localparam SR_CLEAR_TX_FIFO = 62; // 1 reg localparam SR_GLOBAL_RESET = 63; // 1 reg + localparam SR_USER_REGS = 64; // 2 regs localparam SR_GPIO = 128; // 5 regs @@ -64,11 +65,11 @@ module u1plus_core wire pps_int; wire [63:0] vita_time, vita_time_pps; reg [15:0] reg_cgen_ctrl, reg_test; - - wire [7:0] set_addr; - wire [31:0] set_data; - wire set_stb; - + + wire [7:0] set_addr, set_addr_user; + wire [31:0] set_data, set_data_user; + wire set_stb, set_stb_user; + wire [31:0] debug0; wire [31:0] debug1; @@ -137,7 +138,7 @@ module u1plus_core // ///////////////////////////////////////////////////////////////////////// // 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 [23:0] rx_fe_i, rx_fe_q; // 24 bits is total overkill here, but it matches u2/u2p wire run_rx0, run_rx1; rx_frontend #(.BASE(SR_RX_FRONT)) rx_frontend @@ -145,7 +146,7 @@ module u1plus_core .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()); + .i_out(rx_fe_i), .q_out(rx_fe_q), .run(run_rx0 | run_rx1), .debug()); // ///////////////////////////////////////////////////////////////////////// // DSP RX 0 @@ -158,12 +159,12 @@ module u1plus_core ddc_chain #(.BASE(SR_RX_DSP0)) ddc_chain0 (.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), + .rx_fe_i(rx_fe_i),.rx_fe_q(rx_fe_q), .sample(sample_rx0), .run(run_rx0), .strobe(strobe_rx0), .debug() ); vita_rx_chain #(.BASE(SR_RX_CTRL0), .UNIT(0), .FIFOSIZE(10), .PROT_ENG_FLAGS(0)) vita_rx_chain0 - (.clk(wb_clk),.reset(wb_rst),.clear(clear_rx), + (.clk(wb_clk),.reset(wb_rst), .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), @@ -181,12 +182,12 @@ module u1plus_core ddc_chain #(.BASE(SR_RX_DSP1)) ddc_chain1 (.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), + .rx_fe_i(rx_fe_i),.rx_fe_q(rx_fe_q), .sample(sample_rx1), .run(run_rx1), .strobe(strobe_rx1), .debug() ); vita_rx_chain #(.BASE(SR_RX_CTRL1), .UNIT(1), .FIFOSIZE(10), .PROT_ENG_FLAGS(0)) vita_rx_chain1 - (.clk(wb_clk),.reset(wb_rst),.clear(clear_rx), + (.clk(wb_clk),.reset(wb_rst), .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), @@ -205,10 +206,12 @@ module u1plus_core // /////////////////////////////////////////////////////////////////////////////////// // DSP TX - 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), + wire [23:0] tx_fe_i, tx_fe_q; + wire [31:0] sample_tx; + wire strobe_tx; + + vita_tx_chain #(.BASE(SR_TX_CTRL), .REPORT_ERROR(1), .DO_FLOW_CONTROL(0), .PROT_ENG_FLAGS(0), .USE_TRANS_HEADER(0), .DSP_NUMBER(0)) @@ -218,14 +221,21 @@ 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), - .tx_i(tx_i_int),.tx_q(tx_q_int), - .underrun(tx_underrun_dsp), .run(run_tx), + .sample(sample_tx), .strobe(strobe_tx), + .underrun(underrun), .run(run_tx), .debug(debug_vt)); + duc_chain #(.BASE(SR_TX_DSP)) duc_chain + (.clk(dsp_clk),.rst(dsp_rst), + .set_stb(set_stb_dsp),.set_addr(set_addr_dsp),.set_data(set_data_dsp), + .tx_fe_i(tx_fe_i),.tx_fe_q(tx_fe_q), + .sample(sample_tx), .run(run_tx), .strobe(strobe_tx), + .debug() ); + 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), + .tx_i(tx_fe_i), .tx_q(tx_fe_q), .run(1'b1), .dac_a(tx_i), .dac_b(tx_q)); // ///////////////////////////////////////////////////////////////////////////////////// @@ -387,6 +397,12 @@ module u1plus_core .wb_stb_i(s8_stb),.wb_we_i(s8_we),.wb_ack_o(s8_ack), .strobe(set_stb),.addr(set_addr),.data(set_data) ); + user_settings #(.BASE(SR_USER_REGS)) user_settings + (.clk(dsp_clk),.rst(dsp_rst),.set_stb(set_stb), + .set_addr(set_addr),.set_data(set_data), + .set_addr_user(set_addr_user),.set_data_user(set_data_user), + .set_stb_user(set_stb_user) ); + // ///////////////////////////////////////////////////////////////////////// // Readback mux 32 -- Slave #7 diff --git a/usrp2/top/E1x0/u1e_core.v b/usrp2/top/E1x0/u1e_core.v index b581ed50a..2c3690b0a 100644 --- a/usrp2/top/E1x0/u1e_core.v +++ b/usrp2/top/E1x0/u1e_core.v @@ -1,5 +1,5 @@ // -// Copyright 2011 Ettus Research LLC +// Copyright 2011-2012 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 @@ -59,6 +59,7 @@ module u1e_core localparam SR_CLEAR_RX_FIFO = 61; // 1 reg localparam SR_CLEAR_TX_FIFO = 62; // 1 reg localparam SR_GLOBAL_RESET = 63; // 1 reg + localparam SR_USER_REGS = 64; // 2 regs localparam SR_GPIO = 128; // 5 regs @@ -70,10 +71,10 @@ module u1e_core reg [15:0] reg_cgen_ctrl, reg_test, xfer_rate; wire [7:0] test_rate; wire [3:0] test_ctrl; - - wire [7:0] set_addr; - wire [31:0] set_data; - wire set_stb; + + wire [7:0] set_addr, set_addr_user; + wire [31:0] set_data, set_data_user; + wire set_stb, set_stb_user; wire [31:0] debug_vt; wire rx_overrun_dsp0, rx_overrun_dsp1, rx_overrun_gpmc, tx_underrun_dsp, tx_underrun_gpmc; @@ -142,7 +143,7 @@ module u1e_core // ///////////////////////////////////////////////////////////////////////// // 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 [23:0] rx_fe_i, rx_fe_q; // 24 bits is total overkill here, but it matches u2/u2p wire run_rx0, run_rx1; rx_frontend #(.BASE(SR_RX_FRONT)) rx_frontend @@ -150,7 +151,7 @@ module u1e_core .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()); + .i_out(rx_fe_i), .q_out(rx_fe_q), .run(run_rx0 | run_rx1), .debug()); // ///////////////////////////////////////////////////////////////////////// // DSP RX 0 @@ -163,12 +164,12 @@ module u1e_core ddc_chain #(.BASE(SR_RX_DSP0)) ddc_chain0 (.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), + .rx_fe_i(rx_fe_i),.rx_fe_q(rx_fe_q), .sample(sample_rx0), .run(run_rx0), .strobe(strobe_rx0), .debug() ); vita_rx_chain #(.BASE(SR_RX_CTRL0), .UNIT(0), .FIFOSIZE(10), .PROT_ENG_FLAGS(0)) vita_rx_chain0 - (.clk(wb_clk),.reset(wb_rst),.clear(clear_rx), + (.clk(wb_clk),.reset(wb_rst), .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), @@ -186,12 +187,12 @@ module u1e_core ddc_chain #(.BASE(SR_RX_DSP1)) ddc_chain1 (.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), + .rx_fe_i(rx_fe_i),.rx_fe_q(rx_fe_q), .sample(sample_rx1), .run(run_rx1), .strobe(strobe_rx1), .debug() ); vita_rx_chain #(.BASE(SR_RX_CTRL1), .UNIT(1), .FIFOSIZE(10), .PROT_ENG_FLAGS(0)) vita_rx_chain1 - (.clk(wb_clk),.reset(wb_rst),.clear(clear_rx), + (.clk(wb_clk),.reset(wb_rst), .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), @@ -210,10 +211,12 @@ module u1e_core // /////////////////////////////////////////////////////////////////////////////////// // DSP TX - 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), + wire [23:0] tx_fe_i, tx_fe_q; + wire [31:0] sample_tx; + wire strobe_tx; + + vita_tx_chain #(.BASE(SR_TX_CTRL), .REPORT_ERROR(1), .DO_FLOW_CONTROL(0), .PROT_ENG_FLAGS(0), .USE_TRANS_HEADER(0), .DSP_NUMBER(0)) @@ -223,14 +226,21 @@ 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), - .tx_i(tx_i_int),.tx_q(tx_q_int), - .underrun(tx_underrun_dsp), .run(run_tx), + .sample(sample_tx), .strobe(strobe_tx), + .underrun(underrun), .run(run_tx), .debug(debug_vt)); + duc_chain #(.BASE(SR_TX_DSP)) duc_chain + (.clk(dsp_clk),.rst(dsp_rst), + .set_stb(set_stb_dsp),.set_addr(set_addr_dsp),.set_data(set_data_dsp), + .tx_fe_i(tx_fe_i),.tx_fe_q(tx_fe_q), + .sample(sample_tx), .run(run_tx), .strobe(strobe_tx), + .debug() ); + 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), + .tx_i(tx_fe_i), .tx_q(tx_fe_q), .run(1'b1), .dac_a(tx_i), .dac_b(tx_q)); // ///////////////////////////////////////////////////////////////////////////////////// @@ -432,6 +442,12 @@ module u1e_core .wb_stb_i(s8_stb),.wb_we_i(s8_we),.wb_ack_o(s8_ack), .strobe(set_stb),.addr(set_addr),.data(set_data) ); + user_settings #(.BASE(SR_USER_REGS)) user_settings + (.clk(dsp_clk),.rst(dsp_rst),.set_stb(set_stb), + .set_addr(set_addr),.set_data(set_data), + .set_addr_user(set_addr_user),.set_data_user(set_data_user), + .set_stb_user(set_stb_user) ); + // ///////////////////////////////////////////////////////////////////////// // Readback mux 32 -- Slave #7 diff --git a/usrp2/top/N2x0/u2plus_core.v b/usrp2/top/N2x0/u2plus_core.v index f78d9013f..bd9cbf610 100644 --- a/usrp2/top/N2x0/u2plus_core.v +++ b/usrp2/top/N2x0/u2plus_core.v @@ -1,5 +1,5 @@ // -// Copyright 2011 Ettus Research LLC +// Copyright 2011-2012 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 @@ -152,7 +152,7 @@ module u2plus_core localparam SR_SIMTIMER = 8; // 2 localparam SR_TIME64 = 10; // 6 localparam SR_BUF_POOL = 16; // 4 - + localparam SR_USER_REGS = 20; // 2 localparam SR_RX_FRONT = 24; // 5 localparam SR_RX_CTRL0 = 32; // 9 localparam SR_RX_DSP0 = 48; // 7 @@ -174,11 +174,11 @@ module u2plus_core localparam ETH_RX_FIFOSIZE = 11; localparam SERDES_TX_FIFOSIZE = 9; localparam SERDES_RX_FIFOSIZE = 9; // RX currently doesn't use a fifo? - - wire [7:0] set_addr, set_addr_dsp; - wire [31:0] set_data, set_data_dsp; - wire set_stb, set_stb_dsp; - + + wire [7:0] set_addr, set_addr_dsp, set_addr_user; + wire [31:0] set_data, set_data_dsp, set_data_user; + wire set_stb, set_stb_dsp, set_stb_user; + reg wb_rst; wire dsp_rst = wb_rst; @@ -478,7 +478,13 @@ module u2plus_core settings_bus_crossclock settings_bus_crossclock (.clk_i(wb_clk), .rst_i(wb_rst), .set_stb_i(set_stb), .set_addr_i(set_addr), .set_data_i(set_data), .clk_o(dsp_clk), .rst_o(dsp_rst), .set_stb_o(set_stb_dsp), .set_addr_o(set_addr_dsp), .set_data_o(set_data_dsp)); - + + user_settings #(.BASE(SR_USER_REGS)) user_settings + (.clk(dsp_clk),.rst(dsp_rst),.set_stb(set_stb_dsp), + .set_addr(set_addr_dsp),.set_data(set_data_dsp), + .set_addr_user(set_addr_user),.set_data_user(set_data_user), + .set_stb_user(set_stb_user) ); + // Output control lines wire [7:0] clock_outs, serdes_outs, adc_outs; assign {clock_ready, clk_en[1:0], clk_sel[1:0]} = clock_outs[4:0]; @@ -559,19 +565,19 @@ module u2plus_core // ///////////////////////////////////////////////////////////////////////// // ADC Frontend - wire [23:0] adc_i, adc_q; + wire [23:0] rx_fe_i, rx_fe_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()); + .i_out(rx_fe_i), .q_out(rx_fe_q), .run(run_rx0_d1 | run_rx1_d1), .debug()); // ///////////////////////////////////////////////////////////////////////// // DSP RX 0 wire [31:0] sample_rx0; - wire clear_rx0, strobe_rx0; + wire strobe_rx0; always @(posedge dsp_clk) run_rx0_d1 <= run_rx0; @@ -579,17 +585,12 @@ module u2plus_core ddc_chain #(.BASE(SR_RX_DSP0)) ddc_chain0 (.clk(dsp_clk),.rst(dsp_rst), .set_stb(set_stb_dsp),.set_addr(set_addr_dsp),.set_data(set_data_dsp), - .adc_i(adc_i),.adc_ovf_i(adc_ovf_a),.adc_q(adc_q),.adc_ovf_q(adc_ovf_b), + .rx_fe_i(rx_fe_i),.rx_fe_q(rx_fe_q), .sample(sample_rx0), .run(run_rx0_d1), .strobe(strobe_rx0), .debug() ); - setting_reg #(.my_addr(SR_RX_CTRL0+3)) sr_clear_rx0 - (.clk(dsp_clk),.rst(dsp_rst), - .strobe(set_stb_dsp),.addr(set_addr_dsp),.in(set_data_dsp), - .out(),.changed(clear_rx0)); - vita_rx_chain #(.BASE(SR_RX_CTRL0),.UNIT(0),.FIFOSIZE(DSP_RX_FIFOSIZE)) vita_rx_chain0 - (.clk(dsp_clk), .reset(dsp_rst), .clear(clear_rx0), + (.clk(dsp_clk), .reset(dsp_rst), .set_stb(set_stb_dsp),.set_addr(set_addr_dsp),.set_data(set_data_dsp), .vita_time(vita_time), .overrun(overrun0), .sample(sample_rx0), .run(run_rx0), .strobe(strobe_rx0), @@ -599,7 +600,7 @@ module u2plus_core // ///////////////////////////////////////////////////////////////////////// // DSP RX 1 wire [31:0] sample_rx1; - wire clear_rx1, strobe_rx1; + wire strobe_rx1; always @(posedge dsp_clk) run_rx1_d1 <= run_rx1; @@ -607,17 +608,12 @@ module u2plus_core ddc_chain #(.BASE(SR_RX_DSP1)) ddc_chain1 (.clk(dsp_clk),.rst(dsp_rst), .set_stb(set_stb_dsp),.set_addr(set_addr_dsp),.set_data(set_data_dsp), - .adc_i(adc_i),.adc_ovf_i(adc_ovf_a),.adc_q(adc_q),.adc_ovf_q(adc_ovf_b), + .rx_fe_i(rx_fe_i),.rx_fe_q(rx_fe_q), .sample(sample_rx1), .run(run_rx1_d1), .strobe(strobe_rx1), .debug() ); - setting_reg #(.my_addr(SR_RX_CTRL1+3)) sr_clear_rx1 - (.clk(dsp_clk),.rst(dsp_rst), - .strobe(set_stb_dsp),.addr(set_addr_dsp),.in(set_data_dsp), - .out(),.changed(clear_rx1)); - vita_rx_chain #(.BASE(SR_RX_CTRL1),.UNIT(2),.FIFOSIZE(DSP_RX_FIFOSIZE)) vita_rx_chain1 - (.clk(dsp_clk), .reset(dsp_rst), .clear(clear_rx1), + (.clk(dsp_clk), .reset(dsp_rst), .set_stb(set_stb_dsp),.set_addr(set_addr_dsp),.set_data(set_data_dsp), .vita_time(vita_time), .overrun(overrun1), .sample(sample_rx1), .run(run_rx1), .strobe(strobe_rx1), @@ -632,10 +628,6 @@ module u2plus_core wire [31:0] debug_vt; wire clear_tx; - setting_reg #(.my_addr(SR_TX_CTRL+1)) sr_clear_tx - (.clk(dsp_clk),.rst(dsp_rst),.strobe(set_stb_dsp),.addr(set_addr_dsp), - .in(set_data_dsp),.out(),.changed(clear_tx)); - assign RAM_A[20:18] = 3'b0; ext_fifo #(.EXT_WIDTH(36),.INT_WIDTH(36),.RAM_DEPTH(18),.FIFO_DEPTH(18)) @@ -661,9 +653,11 @@ module u2plus_core .debug(debug_extfifo), .debug2(debug_extfifo2) ); - wire [23:0] tx_i, tx_q; + wire [23:0] tx_fe_i, tx_fe_q; + wire [31:0] sample_tx; + wire strobe_tx; - vita_tx_chain #(.BASE_CTRL(SR_TX_CTRL), .BASE_DSP(SR_TX_DSP), + vita_tx_chain #(.BASE(SR_TX_CTRL), .REPORT_ERROR(1), .DO_FLOW_CONTROL(1), .PROT_ENG_FLAGS(1), .USE_TRANS_HEADER(1), .DSP_NUMBER(0)) @@ -673,16 +667,24 @@ 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), - .tx_i(tx_i),.tx_q(tx_q), + .sample(sample_tx), .strobe(strobe_tx), .underrun(underrun), .run(run_tx), + .clear_vita(clear_tx), //output internal vita clear signal .debug(debug_vt)); + duc_chain #(.BASE(SR_TX_DSP)) duc_chain + (.clk(dsp_clk),.rst(dsp_rst), + .set_stb(set_stb_dsp),.set_addr(set_addr_dsp),.set_data(set_data_dsp), + .tx_fe_i(tx_fe_i),.tx_fe_q(tx_fe_q), + .sample(sample_tx), .run(run_tx), .strobe(strobe_tx), + .debug() ); + 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), + .tx_i(tx_fe_i), .tx_q(tx_fe_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 2315b41c7..a83a68204 100644 --- a/usrp2/top/USRP2/u2_core.v +++ b/usrp2/top/USRP2/u2_core.v @@ -157,7 +157,7 @@ module u2_core localparam SR_SIMTIMER = 8; // 2 localparam SR_TIME64 = 10; // 6 localparam SR_BUF_POOL = 16; // 4 - + localparam SR_USER_REGS = 20; // 2 localparam SR_RX_FRONT = 24; // 5 localparam SR_RX_CTRL0 = 32; // 9 localparam SR_RX_DSP0 = 48; // 7 @@ -179,11 +179,11 @@ module u2_core localparam ETH_RX_FIFOSIZE = 11; localparam SERDES_TX_FIFOSIZE = 9; localparam SERDES_RX_FIFOSIZE = 9; // RX currently doesn't use a fifo? - - wire [7:0] set_addr, set_addr_dsp; - wire [31:0] set_data, set_data_dsp; - wire set_stb, set_stb_dsp; - + + wire [7:0] set_addr, set_addr_dsp, set_addr_user; + wire [31:0] set_data, set_data_dsp, set_data_user; + wire set_stb, set_stb_dsp, set_stb_user; + wire ram_loader_done, ram_loader_rst; wire wb_rst; wire dsp_rst = wb_rst; @@ -441,7 +441,7 @@ module u2_core // Buffer Pool Status -- Slave #5 //compatibility number -> increment when the fpga has been sufficiently altered - localparam compat_num = {16'd8, 16'd2}; //major, minor + localparam compat_num = {16'd8, 16'd3}; //major, minor wb_readback_mux buff_pool_status (.wb_clk_i(wb_clk), .wb_rst_i(wb_rst), .wb_stb_i(s5_stb), @@ -484,7 +484,13 @@ module u2_core settings_bus_crossclock settings_bus_crossclock (.clk_i(wb_clk), .rst_i(wb_rst), .set_stb_i(set_stb), .set_addr_i(set_addr), .set_data_i(set_data), .clk_o(dsp_clk), .rst_o(dsp_rst), .set_stb_o(set_stb_dsp), .set_addr_o(set_addr_dsp), .set_data_o(set_data_dsp)); - + + user_settings #(.BASE(SR_USER_REGS)) user_settings + (.clk(dsp_clk),.rst(dsp_rst),.set_stb(set_stb_dsp), + .set_addr(set_addr_dsp),.set_data(set_data_dsp), + .set_addr_user(set_addr_user),.set_data_user(set_data_user), + .set_stb_user(set_stb_user) ); + // Output control lines wire [7:0] clock_outs, serdes_outs, adc_outs; assign {clock_ready, clk_en[1:0], clk_sel[1:0]} = clock_outs[4:0]; @@ -559,25 +565,20 @@ module u2_core // ///////////////////////////////////////////////////////////////////////// // DSP RX 0 wire [31:0] sample_rx0; - wire clear_rx0, strobe_rx0; + wire strobe_rx0; always @(posedge dsp_clk) run_rx0_d1 <= run_rx0; - ddc_chain #(.BASE(SR_RX_DSP0), .DSPNO(0)) ddc_chain0 + ddc_chain #(.BASE(SR_RX_DSP0)) ddc_chain0 (.clk(dsp_clk),.rst(dsp_rst), .set_stb(set_stb_dsp),.set_addr(set_addr_dsp),.set_data(set_data_dsp), .rx_fe_i(rx_fe_i),.rx_fe_q(rx_fe_q), .sample(sample_rx0), .run(run_rx0_d1), .strobe(strobe_rx0), .debug() ); - setting_reg #(.my_addr(SR_RX_CTRL0+3)) sr_clear_rx0 - (.clk(dsp_clk),.rst(dsp_rst), - .strobe(set_stb_dsp),.addr(set_addr_dsp),.in(set_data_dsp), - .out(),.changed(clear_rx0)); - vita_rx_chain #(.BASE(SR_RX_CTRL0),.UNIT(0),.FIFOSIZE(DSP_RX_FIFOSIZE)) vita_rx_chain0 - (.clk(dsp_clk), .reset(dsp_rst), .clear(clear_rx0), + (.clk(dsp_clk), .reset(dsp_rst), .set_stb(set_stb_dsp),.set_addr(set_addr_dsp),.set_data(set_data_dsp), .vita_time(vita_time), .overrun(overrun0), .sample(sample_rx0), .run(run_rx0), .strobe(strobe_rx0), @@ -587,25 +588,20 @@ module u2_core // ///////////////////////////////////////////////////////////////////////// // DSP RX 1 wire [31:0] sample_rx1; - wire clear_rx1, strobe_rx1; + wire strobe_rx1; always @(posedge dsp_clk) run_rx1_d1 <= run_rx1; - ddc_chain #(.BASE(SR_RX_DSP1), .DSPNO(1)) ddc_chain1 + ddc_chain #(.BASE(SR_RX_DSP1)) ddc_chain1 (.clk(dsp_clk),.rst(dsp_rst), .set_stb(set_stb_dsp),.set_addr(set_addr_dsp),.set_data(set_data_dsp), .rx_fe_i(rx_fe_i),.rx_fe_q(rx_fe_q), .sample(sample_rx1), .run(run_rx1_d1), .strobe(strobe_rx1), .debug() ); - setting_reg #(.my_addr(SR_RX_CTRL1+3)) sr_clear_rx1 - (.clk(dsp_clk),.rst(dsp_rst), - .strobe(set_stb_dsp),.addr(set_addr_dsp),.in(set_data_dsp), - .out(),.changed(clear_rx1)); - vita_rx_chain #(.BASE(SR_RX_CTRL1),.UNIT(2),.FIFOSIZE(DSP_RX_FIFOSIZE)) vita_rx_chain1 - (.clk(dsp_clk), .reset(dsp_rst), .clear(clear_rx1), + (.clk(dsp_clk), .reset(dsp_rst), .set_stb(set_stb_dsp),.set_addr(set_addr_dsp),.set_data(set_data_dsp), .vita_time(vita_time), .overrun(overrun1), .sample(sample_rx1), .run(run_rx1), .strobe(strobe_rx1), @@ -620,10 +616,6 @@ module u2_core wire [31:0] debug_vt; wire clear_tx; - setting_reg #(.my_addr(SR_TX_CTRL+1)) sr_clear_tx - (.clk(dsp_clk),.rst(dsp_rst),.strobe(set_stb_dsp),.addr(set_addr_dsp), - .in(set_data_dsp),.out(),.changed(clear_tx)); - ext_fifo #(.EXT_WIDTH(18),.INT_WIDTH(36),.RAM_DEPTH(19),.FIFO_DEPTH(19)) ext_fifo_i1 (.int_clk(dsp_clk), @@ -663,9 +655,10 @@ module u2_core .err_data_o(tx_err_data), .err_src_rdy_o(tx_err_src_rdy), .err_dst_rdy_i(tx_err_dst_rdy), .sample(sample_tx), .strobe(strobe_tx), .underrun(underrun), .run(run_tx), + .clear_vita(clear_tx), //output internal vita clear signal .debug(debug_vt)); - duc_chain #(.BASE(SR_TX_DSP), .DSPNO(0)) duc_chain + duc_chain #(.BASE(SR_TX_DSP)) duc_chain (.clk(dsp_clk),.rst(dsp_rst), .set_stb(set_stb_dsp),.set_addr(set_addr_dsp),.set_data(set_data_dsp), .tx_fe_i(tx_fe_i),.tx_fe_q(tx_fe_q), @@ -677,7 +670,7 @@ module u2_core .set_stb(set_stb_dsp),.set_addr(set_addr_dsp),.set_data(set_data_dsp), .tx_i(tx_fe_i), .tx_q(tx_fe_q), .run(1'b1), .dac_a(dac_a), .dac_b(dac_b)); - + // /////////////////////////////////////////////////////////////////////////////////// // SERDES diff --git a/usrp2/vrt/vita_rx_chain.v b/usrp2/vrt/vita_rx_chain.v index 13defdbc6..150da31c9 100644 --- a/usrp2/vrt/vita_rx_chain.v +++ b/usrp2/vrt/vita_rx_chain.v @@ -21,7 +21,7 @@ module vita_rx_chain parameter UNIT=0, parameter FIFOSIZE=10, parameter PROT_ENG_FLAGS=1) - (input clk, input reset, input clear, + (input clk, input reset, input set_stb, input [7:0] set_addr, input [31:0] set_data, input [63:0] vita_time, input [31:0] sample, input strobe, @@ -35,7 +35,13 @@ module vita_rx_chain wire [35:0] rx_data_int; wire rx_src_rdy_int, rx_dst_rdy_int; - + + wire clear; + + setting_reg #(.my_addr(BASE+3)) sr + (.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr), + .in(set_data),.out(),.changed(clear)); + vita_rx_control #(.BASE(BASE), .WIDTH(32)) vita_rx_control (.clk(clk), .reset(reset), .clear(clear), .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data), diff --git a/usrp2/vrt/vita_tx_chain.v b/usrp2/vrt/vita_tx_chain.v index 1db16de63..07e143f19 100644 --- a/usrp2/vrt/vita_tx_chain.v +++ b/usrp2/vrt/vita_tx_chain.v @@ -30,6 +30,7 @@ module vita_tx_chain output [35:0] err_data_o, output err_src_rdy_o, input err_dst_rdy_i, output [31:0] sample, input strobe, output underrun, output run, + output clear_vita, output [31:0] debug); localparam MAXCHAN = 1; @@ -37,7 +38,6 @@ module vita_tx_chain wire [FIFOWIDTH-1:0] tx1_data; wire tx1_src_rdy, tx1_dst_rdy; - wire clear_vita; wire [31:0] streamid, message; wire trigger, sent; wire [31:0] debug_vtc, debug_vtd, debug_tx_dsp; -- cgit v1.2.3 From 4f94819a4422a71251661fb501412565ffaea8be Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Fri, 27 Jan 2012 19:20:54 -0800 Subject: dsp rework: integrated custom dsp module shells --- usrp2/control_lib/user_settings.v | 2 +- usrp2/custom/Makefile.srcs | 11 +++ usrp2/custom/custom_dsp_rx.v | 139 ++++++++++++++++++++++++++++++++++++++ usrp2/custom/custom_dsp_tx.v | 139 ++++++++++++++++++++++++++++++++++++++ usrp2/sdr_lib/ddc_chain.v | 23 +++++-- usrp2/sdr_lib/duc_chain.v | 26 ++++--- usrp2/top/B100/Makefile.B100 | 3 +- usrp2/top/B100/u1plus_core.v | 11 +-- usrp2/top/E1x0/Makefile.E100 | 3 +- usrp2/top/E1x0/Makefile.E110 | 3 +- usrp2/top/E1x0/u1e_core.v | 10 +-- usrp2/top/N2x0/Makefile.N200R3 | 4 +- usrp2/top/N2x0/Makefile.N200R4 | 4 +- usrp2/top/N2x0/Makefile.N210R3 | 4 +- usrp2/top/N2x0/Makefile.N210R4 | 4 +- usrp2/top/N2x0/u2plus_core.v | 9 ++- usrp2/top/USRP2/Makefile | 4 +- usrp2/top/USRP2/u2_core.v | 9 ++- 18 files changed, 370 insertions(+), 38 deletions(-) create mode 100644 usrp2/custom/Makefile.srcs create mode 100644 usrp2/custom/custom_dsp_rx.v create mode 100644 usrp2/custom/custom_dsp_tx.v diff --git a/usrp2/control_lib/user_settings.v b/usrp2/control_lib/user_settings.v index 96ee22427..d87f1de21 100644 --- a/usrp2/control_lib/user_settings.v +++ b/usrp2/control_lib/user_settings.v @@ -1,5 +1,5 @@ // -// Copyright 2011 Corgan Enterprises LLC +// Copyright 2012 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 diff --git a/usrp2/custom/Makefile.srcs b/usrp2/custom/Makefile.srcs new file mode 100644 index 000000000..22cf063c9 --- /dev/null +++ b/usrp2/custom/Makefile.srcs @@ -0,0 +1,11 @@ +# +# Copyright 2012 Ettus Research LLC +# + +################################################## +# FIFO Sources +################################################## +CUSTOM_SRCS = $(abspath $(addprefix $(BASE_DIR)/../custom/, \ +custom_dsp_rx.v \ +custom_dsp_tx.v \ +)) diff --git a/usrp2/custom/custom_dsp_rx.v b/usrp2/custom/custom_dsp_rx.v new file mode 100644 index 000000000..64f966c31 --- /dev/null +++ b/usrp2/custom/custom_dsp_rx.v @@ -0,0 +1,139 @@ +// +// Copyright 2012 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 . +// + +//CUSTOMIZE ME! + +//The following module effects the IO of the DDC chain. +//By default, this entire module is a simple pass-through. + +//To implement DSP logic before the DDC: +//Implement custom DSP between frontend and ddc input. + +//To implement DSP logic after the DDC: +//Implement custom DSP between ddc output and baseband. + +//To bypass the DDC with custom logic: +//Implement custom DSP between frontend and baseband. + +module custom_dsp_rx +#( + parameter DSPNO = 0, + parameter ADCW = 24 +) +( + //control signals + input clock, input reset, input enable, + + //settings bus + input set_stb, input [7:0] set_addr, input [31:0] set_data, + + //full rate inputs directly from the RX frontend + input [ADCW-1:0] frontend_i, + input [ADCW-1:0] frontend_q, + + //full rate outputs directly to the DDC chain + output [ADCW-1:0] ddc_in_i, + output [ADCW-1:0] ddc_in_q, + + //strobed samples {I16,Q16} from the RX DDC chain + input [31:0] ddc_out_sample, + input ddc_out_strobe, //high on valid sample + + //strobbed baseband samples {I16,Q16} from this module + output [31:0] bb_sample, + output bb_strobe, //high on valid sample + + //debug output (optional) + output [31:0] debug +); + + generate + if (DSPNO==0) begin + `ifndef RX_DSP0_MODULE + assign ddc_in_i = frontend_i; + assign ddc_in_q = frontend_q; + assign bb_sample = ddc_out_sample; + assign bb_strobe = ddc_out_strobe; + `else + RX_DSP0_CUSTOM_MODULE_NAME rx_dsp0_custom + ( + .clock(clock), .reset(reset), .enable(enable), + .set_stb(set_stb), .set_addr(set_addr), .set_data(set_data), + .frontend_i(frontend_i), .frontend_q(frontend_q), + .ddc_in_i(ddc_in_i), .ddc_in_q(ddc_in_q), + .ddc_out_sample(ddc_out_sample), .ddc_out_strobe(ddc_out_strobe), + .bb_sample(bb_sample), .bb_strobe(bb_strobe) + ); + `endif + end + if (DSPNO==1) begin + `ifndef RX_DSP1_MODULE + assign ddc_in_i = frontend_i; + assign ddc_in_q = frontend_q; + assign bb_sample = ddc_out_sample; + assign bb_strobe = ddc_out_strobe; + `else + RX_DSP1_CUSTOM_MODULE_NAME rx_dsp1_custom + ( + .clock(clock), .reset(reset), .enable(enable), + .set_stb(set_stb), .set_addr(set_addr), .set_data(set_data), + .frontend_i(frontend_i), .frontend_q(frontend_q), + .ddc_in_i(ddc_in_i), .ddc_in_q(ddc_in_q), + .ddc_out_sample(ddc_out_sample), .ddc_out_strobe(ddc_out_strobe), + .bb_sample(bb_sample), .bb_strobe(bb_strobe) + ); + `endif + end + if (DSPNO==2) begin + `ifndef RX_DSP2_MODULE + assign ddc_in_i = frontend_i; + assign ddc_in_q = frontend_q; + assign bb_sample = ddc_out_sample; + assign bb_strobe = ddc_out_strobe; + `else + RX_DSP2_CUSTOM_MODULE_NAME rx_dsp2_custom + ( + .clock(clock), .reset(reset), .enable(enable), + .set_stb(set_stb), .set_addr(set_addr), .set_data(set_data), + .frontend_i(frontend_i), .frontend_q(frontend_q), + .ddc_in_i(ddc_in_i), .ddc_in_q(ddc_in_q), + .ddc_out_sample(ddc_out_sample), .ddc_out_strobe(ddc_out_strobe), + .bb_sample(bb_sample), .bb_strobe(bb_strobe) + ); + `endif + end + else begin + `ifndef RX_DSP3_MODULE + assign ddc_in_i = frontend_i; + assign ddc_in_q = frontend_q; + assign bb_sample = ddc_out_sample; + assign bb_strobe = ddc_out_strobe; + `else + RX_DSP3_CUSTOM_MODULE_NAME rx_dsp3_custom + ( + .clock(clock), .reset(reset), .enable(enable), + .set_stb(set_stb), .set_addr(set_addr), .set_data(set_data), + .frontend_i(frontend_i), .frontend_q(frontend_q), + .ddc_in_i(ddc_in_i), .ddc_in_q(ddc_in_q), + .ddc_out_sample(ddc_out_sample), .ddc_out_strobe(ddc_out_strobe), + .bb_sample(bb_sample), .bb_strobe(bb_strobe) + ); + `endif + end + endgenerate + +endmodule //custom_dsp_rx diff --git a/usrp2/custom/custom_dsp_tx.v b/usrp2/custom/custom_dsp_tx.v new file mode 100644 index 000000000..102805139 --- /dev/null +++ b/usrp2/custom/custom_dsp_tx.v @@ -0,0 +1,139 @@ +// +// Copyright 2012 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 . +// + +//CUSTOMIZE ME! + +//The following module effects the IO of the DUC chain. +//By default, this entire module is a simple pass-through. + +//To implement DSP logic before the DUC: +//Implement custom DSP between baseband and duc input. + +//To implement DSP logic after the DUC: +//Implement custom DSP between duc output and frontend. + +//To bypass the DUC with custom logic: +//Implement custom DSP between baseband and frontend. + +module custom_dsp_tx +#( + parameter DSPNO = 0, + parameter ADCW = 24 +) +( + //control signals + input clock, input reset, input enable, + + //settings bus + input set_stb, input [7:0] set_addr, input [31:0] set_data, + + //full rate outputs directly to the TX frontend + output [ADCW-1:0] frontend_i, + output [ADCW-1:0] frontend_q, + + //full rate outputs directly from the DUC chain + input [ADCW-1:0] duc_out_i, + input [ADCW-1:0] duc_out_q, + + //strobed samples {I16,Q16} to the TX DUC chain + output [31:0] duc_in_sample, + input duc_in_strobe, //this is a backpressure signal + + //strobbed baseband samples {I16,Q16} to this module + input [31:0] bb_sample, + output bb_strobe, //this is a backpressure signal + + //debug output (optional) + output [31:0] debug +); + + generate + if (DSPNO==0) begin + `ifndef TX_DSP0_MODULE + assign frontend_i = duc_out_i; + assign frontend_q = duc_out_q; + assign duc_in_sample = bb_sample; + assign bb_strobe = duc_in_strobe; + `else + TX_DSP0_CUSTOM_MODULE_NAME tx_dsp0_custom + ( + .clock(clock), .reset(reset), .enable(enable), + .set_stb(set_stb), .set_addr(set_addr), .set_data(set_data), + .frontend_i(frontend_i), .frontend_q(frontend_q), + .duc_out_i(duc_out_i), .duc_out_q(duc_out_q), + .duc_in_sample(duc_in_sample), .duc_in_strobe(duc_in_strobe), + .bb_sample(bb_sample), .bb_strobe(bb_strobe) + ); + `endif + end + if (DSPNO==1) begin + `ifndef TX_DSP1_MODULE + assign frontend_i = duc_out_i; + assign frontend_q = duc_out_q; + assign duc_in_sample = bb_sample; + assign bb_strobe = duc_in_strobe; + `else + TX_DSP1_CUSTOM_MODULE_NAME tx_dsp1_custom + ( + .clock(clock), .reset(reset), .enable(enable), + .set_stb(set_stb), .set_addr(set_addr), .set_data(set_data), + .frontend_i(frontend_i), .frontend_q(frontend_q), + .duc_out_i(duc_out_i), .duc_out_q(duc_out_q), + .duc_in_sample(duc_in_sample), .duc_in_strobe(duc_in_strobe), + .bb_sample(bb_sample), .bb_strobe(bb_strobe) + ); + `endif + end + if (DSPNO==2) begin + `ifndef TX_DSP2_MODULE + assign frontend_i = duc_out_i; + assign frontend_q = duc_out_q; + assign duc_in_sample = bb_sample; + assign bb_strobe = duc_in_strobe; + `else + TX_DSP2_CUSTOM_MODULE_NAME tx_dsp2_custom + ( + .clock(clock), .reset(reset), .enable(enable), + .set_stb(set_stb), .set_addr(set_addr), .set_data(set_data), + .frontend_i(frontend_i), .frontend_q(frontend_q), + .duc_out_i(duc_out_i), .duc_out_q(duc_out_q), + .duc_in_sample(duc_in_sample), .duc_in_strobe(duc_in_strobe), + .bb_sample(bb_sample), .bb_strobe(bb_strobe) + ); + `endif + end + else begin + `ifndef TX_DSP3_MODULE + assign frontend_i = duc_out_i; + assign frontend_q = duc_out_q; + assign duc_in_sample = bb_sample; + assign bb_strobe = duc_in_strobe; + `else + TX_DSP3_CUSTOM_MODULE_NAME tx_dsp3_custom + ( + .clock(clock), .reset(reset), .enable(enable), + .set_stb(set_stb), .set_addr(set_addr), .set_data(set_data), + .frontend_i(frontend_i), .frontend_q(frontend_q), + .duc_out_i(duc_out_i), .duc_out_q(duc_out_q), + .duc_in_sample(duc_in_sample), .duc_in_strobe(duc_in_strobe), + .bb_sample(bb_sample), .bb_strobe(bb_strobe) + ); + `endif + end + endgenerate + +endmodule //custom_dsp_tx diff --git a/usrp2/sdr_lib/ddc_chain.v b/usrp2/sdr_lib/ddc_chain.v index 02544a0fe..86ff2001b 100644 --- a/usrp2/sdr_lib/ddc_chain.v +++ b/usrp2/sdr_lib/ddc_chain.v @@ -18,9 +18,10 @@ //! The USRP digital down-conversion chain module ddc_chain - #(parameter BASE = 0) + #(parameter BASE = 0, parameter DSPNO = 0) (input clk, input rst, input set_stb, input [7:0] set_addr, input [31:0] set_data, + input set_stb_user, input [7:0] set_addr_user, input [31:0] set_data_user, // From RX frontend input [23:0] rx_fe_i, @@ -91,10 +92,12 @@ module ddc_chain else phase <= phase + phase_inc; + wire [23:0] to_cordic_i, to_cordic_q; + // CORDIC 24-bit I/O cordic_z24 #(.bitwidth(25)) cordic(.clock(clk), .reset(rst), .enable(run), - .xi({rx_fe_i_mux[23],rx_fe_i_mux}),. yi({rx_fe_q_mux[23],rx_fe_q_mux}), .zi(phase[31:8]), + .xi({to_cordic_i[23],to_cordic_i}),. yi({to_cordic_q[23],to_cordic_q}), .zi(phase[31:8]), .xo(i_cordic),.yo(q_cordic),.zo() ); clip_reg #(.bits_in(25), .bits_out(24)) clip_i @@ -136,12 +139,22 @@ module ddc_chain .stb_in(strobe_hb1),.data_in(q_hb1),.stb_out(),.data_out(q_hb2)); // Round final answer to 16 bits + wire [31:0] ddc_chain_out; + wire ddc_chain_stb; 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)); + (.clk(clk),.reset(rst), .in(i_hb2),.strobe_in(strobe_hb2), .out(ddc_chain_out[31:16]), .strobe_out(ddc_chain_stb)); 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()); - + (.clk(clk),.reset(rst), .in(q_hb2),.strobe_in(strobe_hb2), .out(ddc_chain_out[15:0]), .strobe_out()); + + custom_dsp_rx #(.DSPNO(DSPNO)) custom( + .clock(clk), .reset(rst), .enable(run), + .set_stb(set_stb_user), .set_addr(set_addr_user), .set_data(set_data_user), + .frontend_i(rx_fe_i_mux), .frontend_q(rx_fe_q_mux), + .ddc_in_i(to_cordic_i), .ddc_in_q(to_cordic_q), + .ddc_out_sample(ddc_chain_out), .ddc_out_strobe(ddc_chain_stb), + .bb_sample(sample), .bb_strobe(strobe)); + assign debug = {enable_hb1, enable_hb2, run, strobe, strobe_cic, strobe_hb1, strobe_hb2}; endmodule // ddc_chain diff --git a/usrp2/sdr_lib/duc_chain.v b/usrp2/sdr_lib/duc_chain.v index 0d3ca258f..66d15d0ad 100644 --- a/usrp2/sdr_lib/duc_chain.v +++ b/usrp2/sdr_lib/duc_chain.v @@ -18,15 +18,16 @@ //! The USRP digital up-conversion chain module duc_chain - #(parameter BASE = 0) + #(parameter BASE = 0, parameter DSPNO = 0) (input clk, input rst, input set_stb, input [7:0] set_addr, input [31:0] set_data, + input set_stb_user, input [7:0] set_addr_user, input [31:0] set_data_user, - // From TX frontend + // To TX frontend output [23:0] tx_fe_i, output [23:0] tx_fe_q, - // To TX control + // From TX control input [31:0] sample, input run, output strobe, @@ -85,8 +86,8 @@ module duc_chain wire signed [17:0] da, db; wire signed [35:0] prod_i, prod_q; - wire [17:0] bb_i = {sample[31:16],2'b0}; - wire [17:0] bb_q = {sample[15:0],2'b0}; + wire [15:0] bb_i; + wire [15:0] bb_q; wire [17:0] i_interp, q_interp; wire [17:0] hb1_i, hb1_q, hb2_i, hb2_q; @@ -96,9 +97,9 @@ module duc_chain // but the default case inside hb_interp handles this hb_interp #(.IWIDTH(18),.OWIDTH(18),.ACCWIDTH(24)) hb_interp_i - (.clk(clk),.rst(rst),.bypass(~enable_hb1),.cpo(cpo),.stb_in(strobe_hb1),.data_in(bb_i),.stb_out(strobe_hb2),.data_out(hb1_i)); + (.clk(clk),.rst(rst),.bypass(~enable_hb1),.cpo(cpo),.stb_in(strobe_hb1),.data_in({bb_i, 2'b0}),.stb_out(strobe_hb2),.data_out(hb1_i)); hb_interp #(.IWIDTH(18),.OWIDTH(18),.ACCWIDTH(24)) hb_interp_q - (.clk(clk),.rst(rst),.bypass(~enable_hb1),.cpo(cpo),.stb_in(strobe_hb1),.data_in(bb_q),.stb_out(strobe_hb2),.data_out(hb1_q)); + (.clk(clk),.rst(rst),.bypass(~enable_hb1),.cpo(cpo),.stb_in(strobe_hb1),.data_in({bb_q, 2'b0}),.stb_out(strobe_hb2),.data_out(hb1_q)); small_hb_int #(.WIDTH(18)) small_hb_interp_i (.clk(clk),.rst(rst),.bypass(~enable_hb2),.stb_in(strobe_hb2),.data_in(hb1_i), @@ -148,9 +149,14 @@ module duc_chain .R(rst) // Synchronous reset input ); - assign tx_fe_i = prod_i[28:5]; - assign tx_fe_q = prod_q[28:5]; - + custom_dsp_tx #(.DSPNO(DSPNO)) custom( + .clock(clk), .reset(rst), .enable(run), + .set_stb(set_stb_user), .set_addr(set_addr_user), .set_data(set_data_user), + .frontend_i(tx_fe_i), .frontend_q(tx_fe_q), + .duc_out_i(prod_i[28:5]), .duc_out_q(prod_q[28:5]), + .duc_in_sample({bb_i, bb_q}), .duc_in_strobe(strobe_hb1), + .bb_sample(sample), .bb_strobe(strobe)); + assign debug = {strobe_cic, strobe_hb1, strobe_hb2,run}; endmodule // dsp_core diff --git a/usrp2/top/B100/Makefile.B100 b/usrp2/top/B100/Makefile.B100 index 90dd25942..442b0b579 100644 --- a/usrp2/top/B100/Makefile.B100 +++ b/usrp2/top/B100/Makefile.B100 @@ -21,6 +21,7 @@ include ../../vrt/Makefile.srcs include ../../udp/Makefile.srcs include ../../coregen/Makefile.srcs include ../../gpif/Makefile.srcs +include ../../custom/Makefile.srcs ################################################## # Project Properties @@ -50,7 +51,7 @@ 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) $(EXTRAM_SRCS) \ -$(GPIF_SRCS) +$(GPIF_SRCS) $(CUSTOM_SRCS) ################################################## # Process Properties diff --git a/usrp2/top/B100/u1plus_core.v b/usrp2/top/B100/u1plus_core.v index 64c8defb3..4cc9386ab 100644 --- a/usrp2/top/B100/u1plus_core.v +++ b/usrp2/top/B100/u1plus_core.v @@ -156,9 +156,10 @@ module u1plus_core wire [35:0] vita_rx_data0; wire vita_rx_src_rdy0, vita_rx_dst_rdy0; - ddc_chain #(.BASE(SR_RX_DSP0)) ddc_chain0 + ddc_chain #(.BASE(SR_RX_DSP0), .DSPNO(0)) ddc_chain0 (.clk(wb_clk),.rst(wb_rst), .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data), + .set_stb_user(set_stb_user), .set_addr_user(set_addr_user), .set_data_user(set_data_user), .rx_fe_i(rx_fe_i),.rx_fe_q(rx_fe_q), .sample(sample_rx0), .run(run_rx0), .strobe(strobe_rx0), .debug() ); @@ -179,9 +180,10 @@ module u1plus_core wire [35:0] vita_rx_data1; wire vita_rx_src_rdy1, vita_rx_dst_rdy1; - ddc_chain #(.BASE(SR_RX_DSP1)) ddc_chain1 + ddc_chain #(.BASE(SR_RX_DSP1), .DSPNO(1)) ddc_chain1 (.clk(wb_clk),.rst(wb_rst), .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data), + .set_stb_user(set_stb_user), .set_addr_user(set_addr_user), .set_data_user(set_data_user), .rx_fe_i(rx_fe_i),.rx_fe_q(rx_fe_q), .sample(sample_rx1), .run(run_rx1), .strobe(strobe_rx1), .debug() ); @@ -222,12 +224,13 @@ module u1plus_core .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), .sample(sample_tx), .strobe(strobe_tx), - .underrun(underrun), .run(run_tx), + .underrun(tx_underrun_dsp), .run(run_tx), .debug(debug_vt)); - duc_chain #(.BASE(SR_TX_DSP)) duc_chain + duc_chain #(.BASE(SR_TX_DSP), .DSPNO(0)) duc_chain (.clk(dsp_clk),.rst(dsp_rst), .set_stb(set_stb_dsp),.set_addr(set_addr_dsp),.set_data(set_data_dsp), + .set_stb_user(set_stb_user), .set_addr_user(set_addr_user), .set_data_user(set_data_user), .tx_fe_i(tx_fe_i),.tx_fe_q(tx_fe_q), .sample(sample_tx), .run(run_tx), .strobe(strobe_tx), .debug() ); diff --git a/usrp2/top/E1x0/Makefile.E100 b/usrp2/top/E1x0/Makefile.E100 index 9b9a48911..397bac618 100644 --- a/usrp2/top/E1x0/Makefile.E100 +++ b/usrp2/top/E1x0/Makefile.E100 @@ -24,6 +24,7 @@ include ../../vrt/Makefile.srcs include ../../udp/Makefile.srcs include ../../coregen/Makefile.srcs include ../../gpmc/Makefile.srcs +include ../../custom/Makefile.srcs ################################################## # Project Properties @@ -53,7 +54,7 @@ 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) $(EXTRAM_SRCS) \ -$(GPMC_SRCS) +$(GPMC_SRCS) $(CUSTOM_SRCS) ################################################## # Process Properties diff --git a/usrp2/top/E1x0/Makefile.E110 b/usrp2/top/E1x0/Makefile.E110 index be2761baf..1f95954ae 100644 --- a/usrp2/top/E1x0/Makefile.E110 +++ b/usrp2/top/E1x0/Makefile.E110 @@ -24,6 +24,7 @@ include ../../vrt/Makefile.srcs include ../../udp/Makefile.srcs include ../../coregen/Makefile.srcs include ../../gpmc/Makefile.srcs +include ../../custom/Makefile.srcs ################################################## # Project Properties @@ -53,7 +54,7 @@ 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) $(EXTRAM_SRCS) \ -$(GPMC_SRCS) +$(GPMC_SRCS) $(CUSTOM_SRCS) ################################################## # Process Properties diff --git a/usrp2/top/E1x0/u1e_core.v b/usrp2/top/E1x0/u1e_core.v index 2c3690b0a..9257e5541 100644 --- a/usrp2/top/E1x0/u1e_core.v +++ b/usrp2/top/E1x0/u1e_core.v @@ -161,9 +161,10 @@ module u1e_core wire [35:0] vita_rx_data0; wire vita_rx_src_rdy0, vita_rx_dst_rdy0; - ddc_chain #(.BASE(SR_RX_DSP0)) ddc_chain0 + ddc_chain #(.BASE(SR_RX_DSP0), .DSPNO(0)) ddc_chain0 (.clk(wb_clk),.rst(wb_rst), .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data), + .set_stb_user(set_stb_user), .set_addr_user(set_addr_user), .set_data_user(set_data_user), .rx_fe_i(rx_fe_i),.rx_fe_q(rx_fe_q), .sample(sample_rx0), .run(run_rx0), .strobe(strobe_rx0), .debug() ); @@ -184,9 +185,10 @@ module u1e_core wire [35:0] vita_rx_data1; wire vita_rx_src_rdy1, vita_rx_dst_rdy1; - ddc_chain #(.BASE(SR_RX_DSP1)) ddc_chain1 + ddc_chain #(.BASE(SR_RX_DSP1), .DSPNO(1)) ddc_chain1 (.clk(wb_clk),.rst(wb_rst), .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data), + .set_stb_user(set_stb_user), .set_addr_user(set_addr_user), .set_data_user(set_data_user), .rx_fe_i(rx_fe_i),.rx_fe_q(rx_fe_q), .sample(sample_rx1), .run(run_rx1), .strobe(strobe_rx1), .debug() ); @@ -227,10 +229,10 @@ module u1e_core .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), .sample(sample_tx), .strobe(strobe_tx), - .underrun(underrun), .run(run_tx), + .underrun(tx_underrun_dsp), .run(run_tx), .debug(debug_vt)); - duc_chain #(.BASE(SR_TX_DSP)) duc_chain + duc_chain #(.BASE(SR_TX_DSP), .DSPNO(0)) duc_chain (.clk(dsp_clk),.rst(dsp_rst), .set_stb(set_stb_dsp),.set_addr(set_addr_dsp),.set_data(set_data_dsp), .tx_fe_i(tx_fe_i),.tx_fe_q(tx_fe_q), diff --git a/usrp2/top/N2x0/Makefile.N200R3 b/usrp2/top/N2x0/Makefile.N200R3 index 9ed5ece00..7181e7d62 100644 --- a/usrp2/top/N2x0/Makefile.N200R3 +++ b/usrp2/top/N2x0/Makefile.N200R3 @@ -24,6 +24,7 @@ include ../../vrt/Makefile.srcs include ../../udp/Makefile.srcs include ../../coregen/Makefile.srcs include ../../extramfifo/Makefile.srcs +include ../../custom/Makefile.srcs ################################################## @@ -52,7 +53,8 @@ u2plus.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) $(EXTRAM_SRCS) +$(VRT_SRCS) $(UDP_SRCS) $(COREGEN_SRCS) $(EXTRAM_SRCS) \ +$(CUSTOM_SRCS) ################################################## # Process Properties diff --git a/usrp2/top/N2x0/Makefile.N200R4 b/usrp2/top/N2x0/Makefile.N200R4 index f8640224f..551f7a232 100644 --- a/usrp2/top/N2x0/Makefile.N200R4 +++ b/usrp2/top/N2x0/Makefile.N200R4 @@ -24,6 +24,7 @@ include ../../vrt/Makefile.srcs include ../../udp/Makefile.srcs include ../../coregen/Makefile.srcs include ../../extramfifo/Makefile.srcs +include ../../custom/Makefile.srcs ################################################## @@ -53,7 +54,8 @@ u2plus.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) $(EXTRAM_SRCS) +$(VRT_SRCS) $(UDP_SRCS) $(COREGEN_SRCS) $(EXTRAM_SRCS) \ +$(CUSTOM_SRCS) ################################################## # Process Properties diff --git a/usrp2/top/N2x0/Makefile.N210R3 b/usrp2/top/N2x0/Makefile.N210R3 index 2937dc409..2514600f4 100644 --- a/usrp2/top/N2x0/Makefile.N210R3 +++ b/usrp2/top/N2x0/Makefile.N210R3 @@ -24,6 +24,7 @@ include ../../vrt/Makefile.srcs include ../../udp/Makefile.srcs include ../../coregen/Makefile.srcs include ../../extramfifo/Makefile.srcs +include ../../custom/Makefile.srcs ################################################## @@ -52,7 +53,8 @@ u2plus.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) $(EXTRAM_SRCS) +$(VRT_SRCS) $(UDP_SRCS) $(COREGEN_SRCS) $(EXTRAM_SRCS) \ +$(CUSTOM_SRCS) ################################################## # Process Properties diff --git a/usrp2/top/N2x0/Makefile.N210R4 b/usrp2/top/N2x0/Makefile.N210R4 index 39a2508f9..951df0c7c 100644 --- a/usrp2/top/N2x0/Makefile.N210R4 +++ b/usrp2/top/N2x0/Makefile.N210R4 @@ -24,6 +24,7 @@ include ../../vrt/Makefile.srcs include ../../udp/Makefile.srcs include ../../coregen/Makefile.srcs include ../../extramfifo/Makefile.srcs +include ../../custom/Makefile.srcs ################################################## @@ -53,7 +54,8 @@ u2plus.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) $(EXTRAM_SRCS) +$(VRT_SRCS) $(UDP_SRCS) $(COREGEN_SRCS) $(EXTRAM_SRCS) \ +$(CUSTOM_SRCS) ################################################## # Process Properties diff --git a/usrp2/top/N2x0/u2plus_core.v b/usrp2/top/N2x0/u2plus_core.v index bd9cbf610..63087842b 100644 --- a/usrp2/top/N2x0/u2plus_core.v +++ b/usrp2/top/N2x0/u2plus_core.v @@ -582,9 +582,10 @@ module u2plus_core always @(posedge dsp_clk) run_rx0_d1 <= run_rx0; - ddc_chain #(.BASE(SR_RX_DSP0)) ddc_chain0 + ddc_chain #(.BASE(SR_RX_DSP0), .DSPNO(0)) ddc_chain0 (.clk(dsp_clk),.rst(dsp_rst), .set_stb(set_stb_dsp),.set_addr(set_addr_dsp),.set_data(set_data_dsp), + .set_stb_user(set_stb_user), .set_addr_user(set_addr_user), .set_data_user(set_data_user), .rx_fe_i(rx_fe_i),.rx_fe_q(rx_fe_q), .sample(sample_rx0), .run(run_rx0_d1), .strobe(strobe_rx0), .debug() ); @@ -605,9 +606,10 @@ module u2plus_core always @(posedge dsp_clk) run_rx1_d1 <= run_rx1; - ddc_chain #(.BASE(SR_RX_DSP1)) ddc_chain1 + ddc_chain #(.BASE(SR_RX_DSP1), .DSPNO(1)) ddc_chain1 (.clk(dsp_clk),.rst(dsp_rst), .set_stb(set_stb_dsp),.set_addr(set_addr_dsp),.set_data(set_data_dsp), + .set_stb_user(set_stb_user), .set_addr_user(set_addr_user), .set_data_user(set_data_user), .rx_fe_i(rx_fe_i),.rx_fe_q(rx_fe_q), .sample(sample_rx1), .run(run_rx1_d1), .strobe(strobe_rx1), .debug() ); @@ -672,9 +674,10 @@ module u2plus_core .clear_vita(clear_tx), //output internal vita clear signal .debug(debug_vt)); - duc_chain #(.BASE(SR_TX_DSP)) duc_chain + duc_chain #(.BASE(SR_TX_DSP), .DSPNO(0)) duc_chain (.clk(dsp_clk),.rst(dsp_rst), .set_stb(set_stb_dsp),.set_addr(set_addr_dsp),.set_data(set_data_dsp), + .set_stb_user(set_stb_user), .set_addr_user(set_addr_user), .set_data_user(set_data_user), .tx_fe_i(tx_fe_i),.tx_fe_q(tx_fe_q), .sample(sample_tx), .run(run_tx), .strobe(strobe_tx), .debug() ); diff --git a/usrp2/top/USRP2/Makefile b/usrp2/top/USRP2/Makefile index 8ebb43639..adfaf06c4 100644 --- a/usrp2/top/USRP2/Makefile +++ b/usrp2/top/USRP2/Makefile @@ -24,6 +24,7 @@ include ../../vrt/Makefile.srcs include ../../udp/Makefile.srcs include ../../coregen/Makefile.srcs include ../../extramfifo/Makefile.srcs +include ../../custom/Makefile.srcs ################################################## @@ -52,7 +53,8 @@ u2_rev3.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) $(EXTRAM_SRCS) +$(VRT_SRCS) $(UDP_SRCS) $(COREGEN_SRCS) $(EXTRAM_SRCS) \ +$(CUSTOM_SRCS) ################################################## # Process Properties diff --git a/usrp2/top/USRP2/u2_core.v b/usrp2/top/USRP2/u2_core.v index a83a68204..f2ca1908b 100644 --- a/usrp2/top/USRP2/u2_core.v +++ b/usrp2/top/USRP2/u2_core.v @@ -570,9 +570,10 @@ module u2_core always @(posedge dsp_clk) run_rx0_d1 <= run_rx0; - ddc_chain #(.BASE(SR_RX_DSP0)) ddc_chain0 + ddc_chain #(.BASE(SR_RX_DSP0), .DSPNO(0)) ddc_chain0 (.clk(dsp_clk),.rst(dsp_rst), .set_stb(set_stb_dsp),.set_addr(set_addr_dsp),.set_data(set_data_dsp), + .set_stb_user(set_stb_user), .set_addr_user(set_addr_user), .set_data_user(set_data_user), .rx_fe_i(rx_fe_i),.rx_fe_q(rx_fe_q), .sample(sample_rx0), .run(run_rx0_d1), .strobe(strobe_rx0), .debug() ); @@ -593,9 +594,10 @@ module u2_core always @(posedge dsp_clk) run_rx1_d1 <= run_rx1; - ddc_chain #(.BASE(SR_RX_DSP1)) ddc_chain1 + ddc_chain #(.BASE(SR_RX_DSP1), .DSPNO(1)) ddc_chain1 (.clk(dsp_clk),.rst(dsp_rst), .set_stb(set_stb_dsp),.set_addr(set_addr_dsp),.set_data(set_data_dsp), + .set_stb_user(set_stb_user), .set_addr_user(set_addr_user), .set_data_user(set_data_user), .rx_fe_i(rx_fe_i),.rx_fe_q(rx_fe_q), .sample(sample_rx1), .run(run_rx1_d1), .strobe(strobe_rx1), .debug() ); @@ -658,9 +660,10 @@ module u2_core .clear_vita(clear_tx), //output internal vita clear signal .debug(debug_vt)); - duc_chain #(.BASE(SR_TX_DSP)) duc_chain + duc_chain #(.BASE(SR_TX_DSP), .DSPNO(0)) duc_chain (.clk(dsp_clk),.rst(dsp_rst), .set_stb(set_stb_dsp),.set_addr(set_addr_dsp),.set_data(set_data_dsp), + .set_stb_user(set_stb_user), .set_addr_user(set_addr_user), .set_data_user(set_data_user), .tx_fe_i(tx_fe_i),.tx_fe_q(tx_fe_q), .sample(sample_tx), .run(run_tx), .strobe(strobe_tx), .debug() ); -- cgit v1.2.3 From 0ff51a352d13f2ce6c59c82c90e853720936c88f Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Fri, 27 Jan 2012 21:19:47 -0800 Subject: dsp rework: top level fixes B100/E100 --- usrp2/top/B100/core_compile | 2 +- usrp2/top/B100/u1plus_core.v | 6 +++--- usrp2/top/E1x0/core_compile | 2 +- usrp2/top/E1x0/u1e_core.v | 7 ++++--- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/usrp2/top/B100/core_compile b/usrp2/top/B100/core_compile index b2ccc8b49..b62cbaee0 100755 --- a/usrp2/top/B100/core_compile +++ b/usrp2/top/B100/core_compile @@ -1 +1 @@ -iverilog -Wall -y. -y ../../control_lib/ -y ../../fifo/ -y ../../gpif/ -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 u1plus_core.v 2>&1 | grep -v timescale | grep -v coregen | grep -v models +iverilog -Wall -y. -y ../../control_lib/ -y ../../custom/ -y ../../fifo/ -y ../../gpif/ -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 u1plus_core.v 2>&1 | grep -v timescale | grep -v coregen | grep -v models diff --git a/usrp2/top/B100/u1plus_core.v b/usrp2/top/B100/u1plus_core.v index 4cc9386ab..126d899d5 100644 --- a/usrp2/top/B100/u1plus_core.v +++ b/usrp2/top/B100/u1plus_core.v @@ -228,8 +228,8 @@ module u1plus_core .debug(debug_vt)); duc_chain #(.BASE(SR_TX_DSP), .DSPNO(0)) duc_chain - (.clk(dsp_clk),.rst(dsp_rst), - .set_stb(set_stb_dsp),.set_addr(set_addr_dsp),.set_data(set_data_dsp), + (.clk(wb_clk),.rst(wb_rst), + .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data), .set_stb_user(set_stb_user), .set_addr_user(set_addr_user), .set_data_user(set_data_user), .tx_fe_i(tx_fe_i),.tx_fe_q(tx_fe_q), .sample(sample_tx), .run(run_tx), .strobe(strobe_tx), @@ -401,7 +401,7 @@ module u1plus_core .strobe(set_stb),.addr(set_addr),.data(set_data) ); user_settings #(.BASE(SR_USER_REGS)) user_settings - (.clk(dsp_clk),.rst(dsp_rst),.set_stb(set_stb), + (.clk(wb_clk),.rst(wb_rst),.set_stb(set_stb), .set_addr(set_addr),.set_data(set_data), .set_addr_user(set_addr_user),.set_data_user(set_data_user), .set_stb_user(set_stb_user) ); diff --git a/usrp2/top/E1x0/core_compile b/usrp2/top/E1x0/core_compile index 02d7f006e..14e138fa3 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 -y $XILINX/verilog/src/unisims u1e_core.v 2>&1 | grep -v timescale | grep -v coregen | grep -v models +iverilog -Wall -y. -y ../../control_lib/ -y ../../custom/ -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/u1e_core.v b/usrp2/top/E1x0/u1e_core.v index 9257e5541..bd7bd26f6 100644 --- a/usrp2/top/E1x0/u1e_core.v +++ b/usrp2/top/E1x0/u1e_core.v @@ -233,8 +233,9 @@ module u1e_core .debug(debug_vt)); duc_chain #(.BASE(SR_TX_DSP), .DSPNO(0)) duc_chain - (.clk(dsp_clk),.rst(dsp_rst), - .set_stb(set_stb_dsp),.set_addr(set_addr_dsp),.set_data(set_data_dsp), + (.clk(wb_clk),.rst(wb_rst), + .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data), + .set_stb_user(set_stb_user), .set_addr_user(set_addr_user), .set_data_user(set_data_user), .tx_fe_i(tx_fe_i),.tx_fe_q(tx_fe_q), .sample(sample_tx), .run(run_tx), .strobe(strobe_tx), .debug() ); @@ -445,7 +446,7 @@ module u1e_core .strobe(set_stb),.addr(set_addr),.data(set_data) ); user_settings #(.BASE(SR_USER_REGS)) user_settings - (.clk(dsp_clk),.rst(dsp_rst),.set_stb(set_stb), + (.clk(wb_clk),.rst(wb_rst),.set_stb(set_stb), .set_addr(set_addr),.set_data(set_data), .set_addr_user(set_addr_user),.set_data_user(set_data_user), .set_stb_user(set_stb_user) ); -- cgit v1.2.3 From 9f9729993197839d8be950d69eca4456c8e41323 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Sat, 28 Jan 2012 12:21:15 -0800 Subject: dsp rework: moved scale and round into ddc chain 16to8 engine now performs only a clip from 16->8 --- usrp2/sdr_lib/ddc_chain.v | 34 ++++++++++++++++++++++++++-------- usrp2/sdr_lib/dspengine_16to8.v | 38 ++++++++++++++------------------------ usrp2/sdr_lib/duc_chain.v | 10 +++++----- usrp2/top/B100/u1plus_core.v | 2 +- usrp2/top/E1x0/u1e_core.v | 2 +- usrp2/top/N2x0/u2plus_core.v | 2 +- usrp2/top/USRP2/u2_core.v | 2 +- 7 files changed, 49 insertions(+), 41 deletions(-) diff --git a/usrp2/sdr_lib/ddc_chain.v b/usrp2/sdr_lib/ddc_chain.v index 86ff2001b..7de0e6ae6 100644 --- a/usrp2/sdr_lib/ddc_chain.v +++ b/usrp2/sdr_lib/ddc_chain.v @@ -37,6 +37,7 @@ module ddc_chain wire [31:0] phase_inc; reg [31:0] phase; + wire [17:0] scale_factor; wire [24:0] i_cordic, q_cordic; wire [23:0] i_cordic_clip, q_cordic_clip; wire [23:0] i_cic, q_cic; @@ -54,13 +55,11 @@ module ddc_chain 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 + + setting_reg #(.my_addr(BASE+1), .width(18)) sr_1 (.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr), - .in(set_data),.out({scale_i,scale_q}),.changed()); - */ - + .in(set_data),.out(scale_factor),.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()); @@ -138,14 +137,33 @@ module ddc_chain (.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)); + //scalar operation (gain of 6 bits) + wire [35:0] prod_i, prod_q; + + MULT18X18S mult_i + (.P(prod_i), .A(i_hb2[23:6]), .B(scale_factor), .C(clk), .CE(strobe_hb2), .R(rst) ); + MULT18X18S mult_q + (.P(prod_q), .A(q_hb2[23:6]), .B(scale_factor), .C(clk), .CE(strobe_hb2), .R(rst) ); + + //pipeline for the multiplier (gain of 10 bits) + reg [23:0] prod_reg_i, prod_reg_q; + reg strobe_mult; + + always @(posedge clk) begin + strobe_mult <= strobe_hb2; + prod_reg_i <= prod_i[33:10]; + prod_reg_q <= prod_q[33:10]; + end + // Round final answer to 16 bits wire [31:0] ddc_chain_out; wire ddc_chain_stb; + round_sd #(.WIDTH_IN(24),.WIDTH_OUT(16)) round_i - (.clk(clk),.reset(rst), .in(i_hb2),.strobe_in(strobe_hb2), .out(ddc_chain_out[31:16]), .strobe_out(ddc_chain_stb)); + (.clk(clk),.reset(rst), .in(prod_reg_i),.strobe_in(strobe_mult), .out(ddc_chain_out[31:16]), .strobe_out(ddc_chain_stb)); round_sd #(.WIDTH_IN(24),.WIDTH_OUT(16)) round_q - (.clk(clk),.reset(rst), .in(q_hb2),.strobe_in(strobe_hb2), .out(ddc_chain_out[15:0]), .strobe_out()); + (.clk(clk),.reset(rst), .in(prod_reg_q),.strobe_in(strobe_mult), .out(ddc_chain_out[15:0]), .strobe_out()); custom_dsp_rx #(.DSPNO(DSPNO)) custom( .clock(clk), .reset(rst), .enable(run), diff --git a/usrp2/sdr_lib/dspengine_16to8.v b/usrp2/sdr_lib/dspengine_16to8.v index 53c5d29da..448c57d35 100644 --- a/usrp2/sdr_lib/dspengine_16to8.v +++ b/usrp2/sdr_lib/dspengine_16to8.v @@ -1,5 +1,5 @@ -// Copyright 2011 Ettus Research LLC +// Copyright 2011-2012 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 @@ -32,13 +32,11 @@ module dspengine_16to8 input [35:0] access_dat_i ); - wire convert; - wire [17:0] scale_factor; - - setting_reg #(.my_addr(BASE),.width(19)) sr_16to8 + wire convert; + setting_reg #(.my_addr(BASE),.width(1)) sr_16to8 (.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr), - .in(set_data),.out({convert,scale_factor}),.changed()); - + .in(set_data),.out(convert),.changed()); + reg [2:0] dsp_state; localparam DSP_IDLE = 0; localparam DSP_PARSE_HEADER = 1; @@ -63,7 +61,7 @@ module dspengine_16to8 wire [15:0] scaled_i, scaled_q; wire [7:0] i8, q8; reg [7:0] i8_reg, q8_reg; - wire stb_read, stb_mult, stb_clip, stb_round, val_read, val_mult, val_clip, val_round; + wire stb_read, stb_clip, val_read, val_clip; wire stb_out, stb_reg; reg even; @@ -193,29 +191,21 @@ module dspengine_16to8 wire [15:0] i16 = access_dat_i[31:16]; wire [15:0] q16 = access_dat_i[15:0]; - pipectrl #(.STAGES(4), .TAGWIDTH(2)) pipectrl + pipectrl #(.STAGES(2), .TAGWIDTH(2)) pipectrl (.clk(clk), .reset(reset), .src_rdy_i(send_to_pipe), .dst_rdy_o(), // dst_rdy_o will always be 1 since dst_rdy_i is 1, below .src_rdy_o(stb_out), .dst_rdy_i(1), // always accept output of chain - .strobes({stb_round,stb_clip,stb_mult,stb_read}), .valids({val_round,val_clip,val_mult,val_read}), + .strobes({stb_clip,stb_read}), .valids({val_clip,val_read}), .tag_i({last,even}), .tag_o({last_o,even_o})); always @(posedge clk) if(stb_out & ~even_o) {i8_reg,q8_reg} <= {i8,q8}; - - MULT18X18S mult_i - (.P(prod_i), .A(scale_factor), .B({i16,2'b00}), .C(clk), .CE(stb_mult), .R(reset) ); - clip_reg #(.bits_in(24),.bits_out(16),.STROBED(1)) clip_i - (.clk(clk), .in(prod_i[35:12]), .out(scaled_i), .strobe_in(stb_clip), .strobe_out()); - round_sd #(.WIDTH_IN(16),.WIDTH_OUT(8),.DISABLE_SD(1)) round_i - (.clk(clk), .reset(reset), .in(scaled_i), .strobe_in(stb_round), .out(i8), .strobe_out()); - - MULT18X18S mult_q - (.P(prod_q), .A(scale_factor), .B({q16,2'b00}), .C(clk), .CE(stb_mult), .R(reset) ); - clip_reg #(.bits_in(24),.bits_out(16),.STROBED(1)) clip_q - (.clk(clk), .in(prod_q[35:12]), .out(scaled_q), .strobe_in(stb_clip), .strobe_out()); - round_sd #(.WIDTH_IN(16),.WIDTH_OUT(8),.DISABLE_SD(1)) round_q - (.clk(clk), .reset(reset), .in(scaled_q), .strobe_in(stb_round), .out(q8), .strobe_out()); + + clip_reg #(.bits_in(16),.bits_out(8),.STROBED(1)) clip_i + (.clk(clk), .in(i16), .out(i8), .strobe_in(stb_clip), .strobe_out()); + + clip_reg #(.bits_in(16),.bits_out(8),.STROBED(1)) clip_q + (.clk(clk), .in(q16), .out(q8), .strobe_in(stb_clip), .strobe_out()); endmodule // dspengine_16to8 diff --git a/usrp2/sdr_lib/duc_chain.v b/usrp2/sdr_lib/duc_chain.v index 66d15d0ad..23325ef60 100644 --- a/usrp2/sdr_lib/duc_chain.v +++ b/usrp2/sdr_lib/duc_chain.v @@ -34,7 +34,7 @@ module duc_chain output [31:0] debug ); - wire [15:0] i, q, scale_i, scale_q; + wire [17:0] scale_factor; wire [31:0] phase_inc; reg [31:0] phase; wire [7:0] interp_rate; @@ -46,9 +46,9 @@ module duc_chain (.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 + setting_reg #(.my_addr(BASE+1), .width(18)) sr_1 (.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr), - .in(set_data),.out({scale_i,scale_q}),.changed()); + .in(set_data),.out(scale_factor),.changed()); setting_reg #(.my_addr(BASE+2), .width(10)) sr_2 (.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr), @@ -134,7 +134,7 @@ module duc_chain MULT18X18S MULT18X18S_inst (.P(prod_i), // 36-bit multiplier output .A(da_c[cwidth-1:cwidth-18]), // 18-bit multiplier input - .B({{2{scale_i[15]}},scale_i}), // 18-bit multiplier input + .B(scale_factor), // 18-bit multiplier input .C(clk), // Clock input .CE(1), // Clock enable input .R(rst) // Synchronous reset input @@ -143,7 +143,7 @@ module duc_chain MULT18X18S MULT18X18S_inst_2 (.P(prod_q), // 36-bit multiplier output .A(db_c[cwidth-1:cwidth-18]), // 18-bit multiplier input - .B({{2{scale_q[15]}},scale_q}), // 18-bit multiplier input + .B(scale_factor), // 18-bit multiplier input .C(clk), // Clock input .CE(1), // Clock enable input .R(rst) // Synchronous reset input diff --git a/usrp2/top/B100/u1plus_core.v b/usrp2/top/B100/u1plus_core.v index 126d899d5..c61d836d0 100644 --- a/usrp2/top/B100/u1plus_core.v +++ b/usrp2/top/B100/u1plus_core.v @@ -410,7 +410,7 @@ module u1plus_core // Readback mux 32 -- Slave #7 //compatibility number -> increment when the fpga has been sufficiently altered - localparam compat_num = {16'd8, 16'd1}; //major, minor + localparam compat_num = {16'd9, 16'd0}; //major, minor wire [31:0] reg_test32; diff --git a/usrp2/top/E1x0/u1e_core.v b/usrp2/top/E1x0/u1e_core.v index bd7bd26f6..5bf78bad2 100644 --- a/usrp2/top/E1x0/u1e_core.v +++ b/usrp2/top/E1x0/u1e_core.v @@ -455,7 +455,7 @@ module u1e_core // Readback mux 32 -- Slave #7 //compatibility number -> increment when the fpga has been sufficiently altered - localparam compat_num = {16'd8, 16'd1}; //major, minor + localparam compat_num = {16'd9, 16'd0}; //major, minor wire [31:0] reg_test32; diff --git a/usrp2/top/N2x0/u2plus_core.v b/usrp2/top/N2x0/u2plus_core.v index 63087842b..f3405e63a 100644 --- a/usrp2/top/N2x0/u2plus_core.v +++ b/usrp2/top/N2x0/u2plus_core.v @@ -435,7 +435,7 @@ module u2plus_core // Buffer Pool Status -- Slave #5 //compatibility number -> increment when the fpga has been sufficiently altered - localparam compat_num = {16'd8, 16'd2}; //major, minor + localparam compat_num = {16'd9, 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), diff --git a/usrp2/top/USRP2/u2_core.v b/usrp2/top/USRP2/u2_core.v index f2ca1908b..6c1a418d5 100644 --- a/usrp2/top/USRP2/u2_core.v +++ b/usrp2/top/USRP2/u2_core.v @@ -441,7 +441,7 @@ module u2_core // Buffer Pool Status -- Slave #5 //compatibility number -> increment when the fpga has been sufficiently altered - localparam compat_num = {16'd8, 16'd3}; //major, minor + localparam compat_num = {16'd9, 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), -- cgit v1.2.3 From 15a717c0ad95bb93b6740a187afbc781a860a39d Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Sat, 28 Jan 2012 14:26:53 -0800 Subject: dsp rework: added double buffer interface to vita tx --- usrp2/top/B100/u1plus_core.v | 2 +- usrp2/top/E1x0/u1e_core.v | 2 +- usrp2/top/N2x0/u2plus_core.v | 3 ++- usrp2/top/USRP2/u2_core.v | 3 ++- usrp2/vrt/vita_tx_chain.v | 43 +++++++++++++++++++++++++++++++++++-------- 5 files changed, 41 insertions(+), 12 deletions(-) diff --git a/usrp2/top/B100/u1plus_core.v b/usrp2/top/B100/u1plus_core.v index c61d836d0..b9a7e55a2 100644 --- a/usrp2/top/B100/u1plus_core.v +++ b/usrp2/top/B100/u1plus_core.v @@ -213,7 +213,7 @@ module u1plus_core wire [31:0] sample_tx; wire strobe_tx; - vita_tx_chain #(.BASE(SR_TX_CTRL), + vita_tx_chain #(.BASE(SR_TX_CTRL), .FIFOSIZE(10), .REPORT_ERROR(1), .DO_FLOW_CONTROL(0), .PROT_ENG_FLAGS(0), .USE_TRANS_HEADER(0), .DSP_NUMBER(0)) diff --git a/usrp2/top/E1x0/u1e_core.v b/usrp2/top/E1x0/u1e_core.v index 5bf78bad2..d3495707d 100644 --- a/usrp2/top/E1x0/u1e_core.v +++ b/usrp2/top/E1x0/u1e_core.v @@ -218,7 +218,7 @@ module u1e_core wire [31:0] sample_tx; wire strobe_tx; - vita_tx_chain #(.BASE(SR_TX_CTRL), + vita_tx_chain #(.BASE(SR_TX_CTRL), .FIFOSIZE(10), .REPORT_ERROR(1), .DO_FLOW_CONTROL(0), .PROT_ENG_FLAGS(0), .USE_TRANS_HEADER(0), .DSP_NUMBER(0)) diff --git a/usrp2/top/N2x0/u2plus_core.v b/usrp2/top/N2x0/u2plus_core.v index f3405e63a..0ee66d170 100644 --- a/usrp2/top/N2x0/u2plus_core.v +++ b/usrp2/top/N2x0/u2plus_core.v @@ -170,6 +170,7 @@ module u2plus_core // all (most?) are 36 bits wide, so 9 is 1 BRAM, 10 is 2, 11 is 4 BRAMs // localparam DSP_TX_FIFOSIZE = 9; unused -- DSPTX uses extram fifo localparam DSP_RX_FIFOSIZE = 10; + localparam DSP_TX_FIFOSIZE = 10; localparam ETH_TX_FIFOSIZE = 9; localparam ETH_RX_FIFOSIZE = 11; localparam SERDES_TX_FIFOSIZE = 9; @@ -659,7 +660,7 @@ module u2plus_core wire [31:0] sample_tx; wire strobe_tx; - vita_tx_chain #(.BASE(SR_TX_CTRL), + vita_tx_chain #(.BASE(SR_TX_CTRL), .FIFOSIZE(DSP_TX_FIFOSIZE), .REPORT_ERROR(1), .DO_FLOW_CONTROL(1), .PROT_ENG_FLAGS(1), .USE_TRANS_HEADER(1), .DSP_NUMBER(0)) diff --git a/usrp2/top/USRP2/u2_core.v b/usrp2/top/USRP2/u2_core.v index 6c1a418d5..746853fbf 100644 --- a/usrp2/top/USRP2/u2_core.v +++ b/usrp2/top/USRP2/u2_core.v @@ -175,6 +175,7 @@ module u2_core // all (most?) are 36 bits wide, so 9 is 1 BRAM, 10 is 2, 11 is 4 BRAMs // localparam DSP_TX_FIFOSIZE = 9; unused -- DSPTX uses extram fifo localparam DSP_RX_FIFOSIZE = 10; + localparam DSP_TX_FIFOSIZE = 10; localparam ETH_TX_FIFOSIZE = 9; localparam ETH_RX_FIFOSIZE = 11; localparam SERDES_TX_FIFOSIZE = 9; @@ -645,7 +646,7 @@ module u2_core wire [31:0] sample_tx; wire strobe_tx; - vita_tx_chain #(.BASE(SR_TX_CTRL), + vita_tx_chain #(.BASE(SR_TX_CTRL), .FIFOSIZE(DSP_TX_FIFOSIZE), .REPORT_ERROR(1), .DO_FLOW_CONTROL(1), .PROT_ENG_FLAGS(1), .USE_TRANS_HEADER(1), .DSP_NUMBER(0)) diff --git a/usrp2/vrt/vita_tx_chain.v b/usrp2/vrt/vita_tx_chain.v index 07e143f19..7ea3978af 100644 --- a/usrp2/vrt/vita_tx_chain.v +++ b/usrp2/vrt/vita_tx_chain.v @@ -18,6 +18,7 @@ module vita_tx_chain #(parameter BASE=0, + parameter FIFOSIZE=10, parameter REPORT_ERROR=0, parameter DO_FLOW_CONTROL=0, parameter PROT_ENG_FLAGS=0, @@ -46,31 +47,57 @@ module vita_tx_chain wire [31:0] error_code; wire clear_seqnum; wire [31:0] current_seqnum; - + + wire clear; + assign clear_vita = clear; assign underrun = error; assign message = error_code; setting_reg #(.my_addr(BASE+1)) sr (.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr), - .in(set_data),.out(),.changed(clear_vita)); + .in(set_data),.out(),.changed(clear)); setting_reg #(.my_addr(BASE+2), .at_reset(0)) sr_streamid (.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr), .in(set_data),.out(streamid),.changed(clear_seqnum)); + wire [FIFOSIZE-1:0] access_adr, access_len; + wire access_we, access_stb, access_ok, access_done, access_skip_read; + wire [35:0] dsp_to_buf, buf_to_dsp; + wire [35:0] tx_data_int2; + wire tx_src_rdy_int2, tx_dst_rdy_int2; + + double_buffer #(.BUF_SIZE(FIFOSIZE)) db + (.clk(clk),.reset(reset),.clear(clear), + .access_we(access_we), .access_stb(access_stb), .access_ok(access_ok), .access_done(access_done), + .access_skip_read(access_skip_read), .access_adr(access_adr), .access_len(access_len), + .access_dat_i(dsp_to_buf), .access_dat_o(buf_to_dsp), + + .data_i(tx_data_i), .src_rdy_i(tx_src_rdy_i), .dst_rdy_o(tx_dst_rdy_o), + .data_o(tx_data_int2), .src_rdy_o(tx_src_rdy_int2), .dst_rdy_i(tx_dst_rdy_int2)); +/* + dspengine_8to16 #(.BASE(BASE+X), .BUF_SIZE(FIFOSIZE)) dspengine_16to8 + (.clk(clk),.reset(reset),.clear(clear), + .set_stb(set_stb), .set_addr(set_addr), .set_data(set_data), + .access_we(access_we), .access_stb(access_stb), .access_ok(access_ok), .access_done(access_done), + .access_skip_read(access_skip_read), .access_adr(access_adr), .access_len(access_len), + .access_dat_i(buf_to_dsp), .access_dat_o(dsp_to_buf)); +*/ + assign access_done = access_ok; //passthrough + vita_tx_deframer #(.BASE(BASE), .MAXCHAN(MAXCHAN), .USE_TRANS_HEADER(USE_TRANS_HEADER)) vita_tx_deframer - (.clk(clk), .reset(reset), .clear(clear_vita), .clear_seqnum(clear_seqnum), + (.clk(clk), .reset(reset), .clear(clear), .clear_seqnum(clear_seqnum), .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data), - .data_i(tx_data_i), .src_rdy_i(tx_src_rdy_i), .dst_rdy_o(tx_dst_rdy_o), + .data_i(tx_data_int2), .src_rdy_i(tx_src_rdy_int2), .dst_rdy_o(tx_dst_rdy_int2), .sample_fifo_o(tx1_data), .sample_fifo_src_rdy_o(tx1_src_rdy), .sample_fifo_dst_rdy_i(tx1_dst_rdy), .current_seqnum(current_seqnum), .debug(debug_vtd) ); vita_tx_control #(.BASE(BASE), .WIDTH(32*MAXCHAN)) vita_tx_control - (.clk(clk), .reset(reset), .clear(clear_vita), + (.clk(clk), .reset(reset), .clear(clear), .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data), .vita_time(vita_time), .error(error), .ack(ack), .error_code(error_code), .sample_fifo_i(tx1_data), .sample_fifo_src_rdy_i(tx1_src_rdy), .sample_fifo_dst_rdy_o(tx1_dst_rdy), @@ -81,18 +108,18 @@ module vita_tx_chain wire flow_src_rdy, flow_dst_rdy, err_src_rdy_int, err_dst_rdy_int; gen_context_pkt #(.PROT_ENG_FLAGS(PROT_ENG_FLAGS),.DSP_NUMBER(DSP_NUMBER)) gen_flow_pkt - (.clk(clk), .reset(reset), .clear(clear_vita), + (.clk(clk), .reset(reset), .clear(clear), .trigger(trigger & (DO_FLOW_CONTROL==1)), .sent(), .streamid(streamid), .vita_time(vita_time), .message(32'd0), .seqnum(current_seqnum), .data_o(flow_data), .src_rdy_o(flow_src_rdy), .dst_rdy_i(flow_dst_rdy)); trigger_context_pkt #(.BASE(BASE)) trigger_context_pkt - (.clk(clk), .reset(reset), .clear(clear_vita), + (.clk(clk), .reset(reset), .clear(clear), .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data), .packet_consumed(packet_consumed), .trigger(trigger)); gen_context_pkt #(.PROT_ENG_FLAGS(PROT_ENG_FLAGS),.DSP_NUMBER(DSP_NUMBER)) gen_tx_err_pkt - (.clk(clk), .reset(reset), .clear(clear_vita), + (.clk(clk), .reset(reset), .clear(clear), .trigger((error|ack) & (REPORT_ERROR==1)), .sent(), .streamid(streamid), .vita_time(vita_time), .message(message), .seqnum(current_seqnum), -- cgit v1.2.3 From 724e4a9eba417bb053259f312060e5e3ebe4581d Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Sat, 28 Jan 2012 16:01:30 -0800 Subject: dsp rework: increase the number of effective bits in the duc scale factor This will be useful for effecting the dynamic range of the sc8 tx mode. --- usrp2/sdr_lib/duc_chain.v | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usrp2/sdr_lib/duc_chain.v b/usrp2/sdr_lib/duc_chain.v index 23325ef60..b5033d05a 100644 --- a/usrp2/sdr_lib/duc_chain.v +++ b/usrp2/sdr_lib/duc_chain.v @@ -153,7 +153,7 @@ module duc_chain .clock(clk), .reset(rst), .enable(run), .set_stb(set_stb_user), .set_addr(set_addr_user), .set_data(set_data_user), .frontend_i(tx_fe_i), .frontend_q(tx_fe_q), - .duc_out_i(prod_i[28:5]), .duc_out_q(prod_q[28:5]), + .duc_out_i(prod_i[33:10]), .duc_out_q(prod_q[33:10]), .duc_in_sample({bb_i, bb_q}), .duc_in_strobe(strobe_hb1), .bb_sample(sample), .bb_strobe(strobe)); -- cgit v1.2.3 From ac35b413a595617c1fa57766758c06ccfe3f320e Mon Sep 17 00:00:00 2001 From: Matt Ettus Date: Sun, 29 Jan 2012 18:23:23 -0800 Subject: dsp: 8 to 16 bit conversion for tx side. believed to be functional --- usrp2/control_lib/double_buffer_tb.v | 48 ++++++--- usrp2/sdr_lib/dspengine_8to16.v | 194 +++++++++++++++++++++++++++++++++++ 2 files changed, 230 insertions(+), 12 deletions(-) create mode 100644 usrp2/sdr_lib/dspengine_8to16.v diff --git a/usrp2/control_lib/double_buffer_tb.v b/usrp2/control_lib/double_buffer_tb.v index a9aae6956..3e0b04b8a 100644 --- a/usrp2/control_lib/double_buffer_tb.v +++ b/usrp2/control_lib/double_buffer_tb.v @@ -46,9 +46,9 @@ module double_buffer_tb(); .data_i(data_i), .src_rdy_i(src_rdy_i), .dst_rdy_o(dst_rdy_o), .data_o(data_o), .src_rdy_o(src_rdy_o), .dst_rdy_i(dst_rdy_i)); - dspengine_16to8 dspengine_16to8 + dspengine_8to16 dspengine_8to16 (.clk(clk),.reset(rst),.clear(0), - .set_stb(set_stb), .set_addr(0), .set_data({13'h0,1'b1,18'h00400}), + .set_stb(set_stb), .set_addr(0), .set_data(1), .access_we(access_we), .access_stb(access_stb), .access_ok(access_ok), .access_done(access_done), .access_skip_read(access_skip_read), .access_adr(access_adr), .access_len(access_len), .access_dat_i(buf_to_dsp), .access_dat_o(dsp_to_buf)); @@ -69,7 +69,7 @@ module double_buffer_tb(); @(posedge clk); @(posedge clk); @(posedge clk); - +/* // Passthrough $display("Passthrough"); src_rdy_i <= 1; @@ -86,12 +86,12 @@ module double_buffer_tb(); repeat (5) @(posedge clk); - +*/ $display("Enabled"); set_stb <= 1; @(posedge clk); set_stb <= 0; - +/* @(posedge clk); $display("Non-IF Data Passthrough"); src_rdy_i <= 1; @@ -159,23 +159,23 @@ module double_buffer_tb(); while(~dst_rdy_o) @(posedge clk); - +*/ $display("No StreamID, Trailer, Even"); src_rdy_i <= 1; data_i <= { 2'b00,1'b0,1'b1,32'h0400FFFF}; @(posedge clk); - data_i <= { 2'b00,1'b0,1'b0,32'h21002200}; + data_i <= { 2'b00,1'b0,1'b0,32'h21222324}; @(posedge clk); - data_i <= { 2'b00,1'b0,1'b0,32'h23002400}; + data_i <= { 2'b00,1'b0,1'b0,32'h25262728}; src_rdy_i <= 0; @(posedge clk); src_rdy_i <= 1; @(posedge clk); - data_i <= { 2'b00,1'b0,1'b0,32'h25002600}; + data_i <= { 2'b00,1'b0,1'b0,32'h292a2b2c}; @(posedge clk); - data_i <= { 2'b00,1'b0,1'b0,32'h27002800}; + data_i <= { 2'b00,1'b0,1'b0,32'h2d2e2f30}; @(posedge clk); - data_i <= { 2'b00,1'b1,1'b0,32'h29002a00}; + data_i <= { 2'b00,1'b1,1'b0,32'hDEADBEEF}; @(posedge clk); src_rdy_i <= 0; @(posedge clk); @@ -183,6 +183,30 @@ module double_buffer_tb(); while(~dst_rdy_o) @(posedge clk); + $display("No StreamID, Trailer, Odd"); + src_rdy_i <= 1; + data_i <= { 2'b00,1'b0,1'b1,32'h0400FFFF}; + @(posedge clk); + data_i <= { 2'b00,1'b0,1'b0,32'h21222324}; + @(posedge clk); + data_i <= { 2'b00,1'b0,1'b0,32'h25262728}; + src_rdy_i <= 0; + @(posedge clk); + src_rdy_i <= 1; + @(posedge clk); + data_i <= { 2'b00,1'b0,1'b0,32'h292a2b2c}; + @(posedge clk); + data_i <= { 2'b00,1'b0,1'b0,32'h2d2e2f30}; + @(posedge clk); + data_i <= { 2'b00,1'b1,1'b0,32'hDEBDBF0D}; + @(posedge clk); + src_rdy_i <= 0; + @(posedge clk); + + while(~dst_rdy_o) + @(posedge clk); + +/* $display("No StreamID, Trailer, Odd"); src_rdy_i <= 1; data_i <= { 2'b00,1'b0,1'b1,32'h0400FFFF}; @@ -246,7 +270,7 @@ module double_buffer_tb(); @(posedge clk); src_rdy_i <= 0; @(posedge clk); - +*/ end initial #28000 $finish; diff --git a/usrp2/sdr_lib/dspengine_8to16.v b/usrp2/sdr_lib/dspengine_8to16.v new file mode 100644 index 000000000..39cf440f6 --- /dev/null +++ b/usrp2/sdr_lib/dspengine_8to16.v @@ -0,0 +1,194 @@ + +// 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 . +// + +module dspengine_8to16 + #(parameter BASE = 0, + parameter BUF_SIZE = 9) + (input clk, input reset, input clear, + input set_stb, input [7:0] set_addr, input [31:0] set_data, + + output access_we, + output access_stb, + input access_ok, + output access_done, + output access_skip_read, + output [BUF_SIZE-1:0] access_adr, + input [BUF_SIZE-1:0] access_len, + output [35:0] access_dat_o, + input [35:0] access_dat_i + ); + + wire convert; + + setting_reg #(.my_addr(BASE),.width(1)) sr_8to16 + (.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr), + .in(set_data),.out(convert),.changed()); + + reg [3:0] dsp_state; + localparam DSP_IDLE = 0; + localparam DSP_PARSE_HEADER = 1; + localparam DSP_READ = 2; + localparam DSP_WRITE_0 = 3; + localparam DSP_WRITE_1 = 4; + localparam DSP_READ_TRAILER = 5; + localparam DSP_WRITE_TRAILER = 6; + localparam DSP_WRITE_HEADER = 7; + localparam DSP_DONE = 8; + + // Parse VITA header + wire is_if_data = (access_dat_i[31:29] == 3'b000); + wire has_streamid = access_dat_i[28]; + wire has_classid = access_dat_i[27]; + wire has_trailer = access_dat_i[26]; + // 25:24 reserved, aka SOB/EOB + wire has_secs = |access_dat_i[23:22]; + wire has_tics = |access_dat_i[21:20]; + wire [3:0] hdr_length = 1 + has_streamid + has_classid + has_classid + has_secs + has_tics + has_tics; + reg [15:0] hdr_length_reg; + + reg odd; + + reg [BUF_SIZE-1:0] read_adr, write_adr; + reg has_trailer_reg; + + wire last = (read_adr + 1) == (access_len - has_trailer_reg); + + reg [31:0] new_header, new_trailer, trailer_mask; + reg [15:0] length; + reg wait_for_trailer; + reg [15:0] data_in_len, data_out_len; + + reg [7:0] i8_0, q8_0; + wire [7:0] i8_1 = access_dat_i[15:8]; + wire [7:0] q8_1 = access_dat_i[7:0]; + reg skip; + + + always @(posedge clk) + { i8_0, q8_0 } <= access_dat_i[31:16]; + + always @(posedge clk) + if(reset | clear) + dsp_state <= DSP_IDLE; + else + case(dsp_state) + DSP_IDLE : + begin + read_adr <= 0; + write_adr <= 0; + if(access_ok) + dsp_state <= DSP_PARSE_HEADER; + end + + DSP_PARSE_HEADER : + begin + // FIXME is data always valid here? + + has_trailer_reg <= has_trailer; + new_header[31:16] <= access_dat_i[31:16]; + new_header[15:0] <= access_len; + length <= access_len; + hdr_length_reg <= hdr_length; + if(~is_if_data | ~convert | ~has_trailer) + // ~convert is valid (16 bit mode) but both ~trailer and ~is_if_data are both + // really error conditions on the TX side. We shouldn't ever see them in the TX chain + dsp_state <= DSP_WRITE_HEADER; + else + begin + read_adr <= access_len-1; // point to trailer + dsp_state <= DSP_READ_TRAILER; + wait_for_trailer <= 0; + data_in_len <= access_len - hdr_length - 1; + end + end + + DSP_READ_TRAILER : + begin + wait_for_trailer <= 1; + if(wait_for_trailer) + dsp_state <= DSP_WRITE_TRAILER; + new_trailer <= access_dat_i[31:0]; // Leave trailer unchanged + odd <= access_dat_i[20] & access_dat_i[8]; + data_out_len <= {data_in_len,1'b0} - (access_dat_i[20] & access_dat_i[8]); + write_adr <= hdr_length_reg + {data_in_len,1'b0} - (access_dat_i[20] & access_dat_i[8]); + end + + DSP_WRITE_TRAILER : + begin + dsp_state <= DSP_READ; + write_adr <= write_adr - 1; + read_adr <= read_adr - 1; + new_header[15:0] <= write_adr + 1; // length = addr of trailer + 1 + end + + DSP_READ : + begin + dsp_state <= DSP_WRITE_1; + read_adr <= read_adr - 1; + end + + DSP_WRITE_1 : + begin + write_adr <= write_adr - 1; + odd <= 0; + if(write_adr == hdr_length_reg) + dsp_state <= DSP_WRITE_HEADER; + else if(odd) + dsp_state <= DSP_READ; + else + dsp_state <= DSP_WRITE_0; + end + + DSP_WRITE_0 : + begin + write_adr <= write_adr - 1; + if(write_adr == hdr_length_reg) + dsp_state <= DSP_WRITE_HEADER; + else + dsp_state <= DSP_READ; + end + + DSP_WRITE_HEADER : + dsp_state <= DSP_DONE; + + DSP_DONE : + begin + read_adr <= 0; + write_adr <= 0; + dsp_state <= DSP_IDLE; + end + endcase // case (dsp_state) + + assign access_skip_read = 0; + assign access_done = (dsp_state == DSP_DONE); + + assign access_stb = 1; + + assign access_we = (dsp_state == DSP_WRITE_HEADER) | + (dsp_state == DSP_WRITE_TRAILER) | + (dsp_state == DSP_WRITE_0) | + (dsp_state == DSP_WRITE_1); + + assign access_dat_o = (dsp_state == DSP_WRITE_HEADER) ? { 4'h1, new_header } : + (dsp_state == DSP_WRITE_TRAILER) ? { 4'h2, new_trailer } : + (dsp_state == DSP_WRITE_0) ? { 4'h0, i8_0, 8'd0, q8_0, 8'd0 } : + (dsp_state == DSP_WRITE_1) ? { 4'h0, i8_1, 8'd0, q8_1, 8'd0 } : + 34'h0DEADBEEF; + + assign access_adr = access_we ? write_adr : read_adr; + +endmodule // dspengine_16to8 -- cgit v1.2.3 From 05644d7d4fe2df455b01833cc0fc8aa1b4b6e1f3 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Mon, 30 Jan 2012 15:09:47 -0800 Subject: dsp rework: integrated dspengine_8to16, some tweaks --- usrp2/sdr_lib/Makefile.srcs | 3 ++- usrp2/sdr_lib/dspengine_8to16.v | 7 ++++--- usrp2/vrt/vita_tx_chain.v | 6 ++---- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/usrp2/sdr_lib/Makefile.srcs b/usrp2/sdr_lib/Makefile.srcs index 0f1958991..840627e6d 100644 --- a/usrp2/sdr_lib/Makefile.srcs +++ b/usrp2/sdr_lib/Makefile.srcs @@ -1,5 +1,5 @@ # -# Copyright 2010 Ettus Research LLC +# Copyright 2010-2012 Ettus Research LLC # ################################################## @@ -26,6 +26,7 @@ cordic_stage.v \ ddc_chain.v \ duc_chain.v \ dspengine_16to8.v \ +dspengine_8to16.v \ hb_dec.v \ hb_interp.v \ pipectrl.v \ diff --git a/usrp2/sdr_lib/dspengine_8to16.v b/usrp2/sdr_lib/dspengine_8to16.v index 39cf440f6..a0d2f7e7e 100644 --- a/usrp2/sdr_lib/dspengine_8to16.v +++ b/usrp2/sdr_lib/dspengine_8to16.v @@ -1,5 +1,5 @@ -// Copyright 2011 Ettus Research LLC +// Copyright 2012 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 @@ -71,6 +71,7 @@ module dspengine_8to16 reg [15:0] length; reg wait_for_trailer; reg [15:0] data_in_len, data_out_len; + wire [15:0] data_in_lenx2 = {data_in_len[14:0], 1'b0} - (access_dat_i[20] & access_dat_i[8]); reg [7:0] i8_0, q8_0; wire [7:0] i8_1 = access_dat_i[15:8]; @@ -123,8 +124,8 @@ module dspengine_8to16 dsp_state <= DSP_WRITE_TRAILER; new_trailer <= access_dat_i[31:0]; // Leave trailer unchanged odd <= access_dat_i[20] & access_dat_i[8]; - data_out_len <= {data_in_len,1'b0} - (access_dat_i[20] & access_dat_i[8]); - write_adr <= hdr_length_reg + {data_in_len,1'b0} - (access_dat_i[20] & access_dat_i[8]); + data_out_len <= data_in_lenx2; + write_adr <= hdr_length_reg + data_in_lenx2; end DSP_WRITE_TRAILER : diff --git a/usrp2/vrt/vita_tx_chain.v b/usrp2/vrt/vita_tx_chain.v index 7ea3978af..f9348bbfd 100644 --- a/usrp2/vrt/vita_tx_chain.v +++ b/usrp2/vrt/vita_tx_chain.v @@ -75,15 +75,13 @@ module vita_tx_chain .data_i(tx_data_i), .src_rdy_i(tx_src_rdy_i), .dst_rdy_o(tx_dst_rdy_o), .data_o(tx_data_int2), .src_rdy_o(tx_src_rdy_int2), .dst_rdy_i(tx_dst_rdy_int2)); -/* - dspengine_8to16 #(.BASE(BASE+X), .BUF_SIZE(FIFOSIZE)) dspengine_16to8 + + dspengine_8to16 #(.BASE(BASE+6), .BUF_SIZE(FIFOSIZE)) dspengine_8to16 (.clk(clk),.reset(reset),.clear(clear), .set_stb(set_stb), .set_addr(set_addr), .set_data(set_data), .access_we(access_we), .access_stb(access_stb), .access_ok(access_ok), .access_done(access_done), .access_skip_read(access_skip_read), .access_adr(access_adr), .access_len(access_len), .access_dat_i(buf_to_dsp), .access_dat_o(dsp_to_buf)); -*/ - assign access_done = access_ok; //passthrough vita_tx_deframer #(.BASE(BASE), .MAXCHAN(MAXCHAN), -- cgit v1.2.3 From 9803334f95c548b7fdf9a9d73c41e6e22f252dcb Mon Sep 17 00:00:00 2001 From: Matt Ettus Date: Mon, 30 Jan 2012 16:35:07 -0800 Subject: dsp_engine: work with transport header --- usrp2/sdr_lib/dspengine_8to16.v | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/usrp2/sdr_lib/dspengine_8to16.v b/usrp2/sdr_lib/dspengine_8to16.v index a0d2f7e7e..a8accee8b 100644 --- a/usrp2/sdr_lib/dspengine_8to16.v +++ b/usrp2/sdr_lib/dspengine_8to16.v @@ -42,8 +42,8 @@ module dspengine_8to16 localparam DSP_IDLE = 0; localparam DSP_PARSE_HEADER = 1; localparam DSP_READ = 2; - localparam DSP_WRITE_0 = 3; - localparam DSP_WRITE_1 = 4; + localparam DSP_WRITE_1 = 3; + localparam DSP_WRITE_0 = 4; localparam DSP_READ_TRAILER = 5; localparam DSP_WRITE_TRAILER = 6; localparam DSP_WRITE_HEADER = 7; @@ -65,8 +65,6 @@ module dspengine_8to16 reg [BUF_SIZE-1:0] read_adr, write_adr; reg has_trailer_reg; - wire last = (read_adr + 1) == (access_len - has_trailer_reg); - reg [31:0] new_header, new_trailer, trailer_mask; reg [15:0] length; reg wait_for_trailer; @@ -89,8 +87,8 @@ module dspengine_8to16 case(dsp_state) DSP_IDLE : begin - read_adr <= 0; - write_adr <= 0; + read_adr <= 1; // Skip 0 for transport header + write_adr <= 1; // Skip 0 for transport header if(access_ok) dsp_state <= DSP_PARSE_HEADER; end @@ -101,7 +99,7 @@ module dspengine_8to16 has_trailer_reg <= has_trailer; new_header[31:16] <= access_dat_i[31:16]; - new_header[15:0] <= access_len; + new_header[15:0] <= access_len-1; length <= access_len; hdr_length_reg <= hdr_length; if(~is_if_data | ~convert | ~has_trailer) @@ -110,10 +108,10 @@ module dspengine_8to16 dsp_state <= DSP_WRITE_HEADER; else begin - read_adr <= access_len-1; // point to trailer + read_adr <= access_len - 1; // point to trailer dsp_state <= DSP_READ_TRAILER; wait_for_trailer <= 0; - data_in_len <= access_len - hdr_length - 1; + data_in_len <= access_len - hdr_length - 2; end end @@ -125,7 +123,7 @@ module dspengine_8to16 new_trailer <= access_dat_i[31:0]; // Leave trailer unchanged odd <= access_dat_i[20] & access_dat_i[8]; data_out_len <= data_in_lenx2; - write_adr <= hdr_length_reg + data_in_lenx2; + write_adr <= hdr_length_reg + data_in_lenx2 + 1; end DSP_WRITE_TRAILER : @@ -133,7 +131,7 @@ module dspengine_8to16 dsp_state <= DSP_READ; write_adr <= write_adr - 1; read_adr <= read_adr - 1; - new_header[15:0] <= write_adr + 1; // length = addr of trailer + 1 + new_header[15:0] <= write_adr; // length = addr of trailer + 1 end DSP_READ : @@ -146,7 +144,7 @@ module dspengine_8to16 begin write_adr <= write_adr - 1; odd <= 0; - if(write_adr == hdr_length_reg) + if(write_adr == (hdr_length_reg+1)) dsp_state <= DSP_WRITE_HEADER; else if(odd) dsp_state <= DSP_READ; @@ -157,7 +155,7 @@ module dspengine_8to16 DSP_WRITE_0 : begin write_adr <= write_adr - 1; - if(write_adr == hdr_length_reg) + if(write_adr == (hdr_length_reg+1)) dsp_state <= DSP_WRITE_HEADER; else dsp_state <= DSP_READ; @@ -168,8 +166,8 @@ module dspengine_8to16 DSP_DONE : begin - read_adr <= 0; - write_adr <= 0; + read_adr <= 1; + write_adr <= 1; dsp_state <= DSP_IDLE; end endcase // case (dsp_state) @@ -184,7 +182,7 @@ module dspengine_8to16 (dsp_state == DSP_WRITE_0) | (dsp_state == DSP_WRITE_1); - assign access_dat_o = (dsp_state == DSP_WRITE_HEADER) ? { 4'h1, new_header } : + assign access_dat_o = (dsp_state == DSP_WRITE_HEADER) ? { 4'h0, new_header } : (dsp_state == DSP_WRITE_TRAILER) ? { 4'h2, new_trailer } : (dsp_state == DSP_WRITE_0) ? { 4'h0, i8_0, 8'd0, q8_0, 8'd0 } : (dsp_state == DSP_WRITE_1) ? { 4'h0, i8_1, 8'd0, q8_1, 8'd0 } : -- cgit v1.2.3 From 327c25864e3d09fdc34fe9f438dded1329b0c65c Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Mon, 30 Jan 2012 22:22:56 -0800 Subject: dsp rework: work on 8 to 16 engine (usrp2 ok) --- usrp2/sdr_lib/dspengine_8to16.v | 49 +++++++++++++++++++++-------------------- usrp2/vrt/vita_tx_chain.v | 2 +- 2 files changed, 26 insertions(+), 25 deletions(-) diff --git a/usrp2/sdr_lib/dspengine_8to16.v b/usrp2/sdr_lib/dspengine_8to16.v index a8accee8b..66568bc12 100644 --- a/usrp2/sdr_lib/dspengine_8to16.v +++ b/usrp2/sdr_lib/dspengine_8to16.v @@ -17,7 +17,8 @@ module dspengine_8to16 #(parameter BASE = 0, - parameter BUF_SIZE = 9) + parameter BUF_SIZE = 9, + parameter HEADER_OFFSET = 0) (input clk, input reset, input clear, input set_stb, input [7:0] set_addr, input [31:0] set_data, @@ -40,14 +41,15 @@ module dspengine_8to16 reg [3:0] dsp_state; localparam DSP_IDLE = 0; - localparam DSP_PARSE_HEADER = 1; - localparam DSP_READ = 2; - localparam DSP_WRITE_1 = 3; - localparam DSP_WRITE_0 = 4; - localparam DSP_READ_TRAILER = 5; - localparam DSP_WRITE_TRAILER = 6; - localparam DSP_WRITE_HEADER = 7; - localparam DSP_DONE = 8; + localparam DSP_IDLE_RD = 1; + localparam DSP_PARSE_HEADER = 2; + localparam DSP_READ = 3; + localparam DSP_WRITE_1 = 4; + localparam DSP_WRITE_0 = 5; + localparam DSP_READ_TRAILER = 6; + localparam DSP_WRITE_TRAILER = 7; + localparam DSP_WRITE_HEADER = 8; + localparam DSP_DONE = 9; // Parse VITA header wire is_if_data = (access_dat_i[31:29] == 3'b000); @@ -66,10 +68,10 @@ module dspengine_8to16 reg has_trailer_reg; reg [31:0] new_header, new_trailer, trailer_mask; - reg [15:0] length; reg wait_for_trailer; - reg [15:0] data_in_len, data_out_len; - wire [15:0] data_in_lenx2 = {data_in_len[14:0], 1'b0} - (access_dat_i[20] & access_dat_i[8]); + reg [15:0] data_in_len; + wire is_odd = access_dat_i[22] & access_dat_i[10]; + wire [15:0] data_in_lenx2 = {data_in_len[14:0], 1'b0} - is_odd; reg [7:0] i8_0, q8_0; wire [7:0] i8_1 = access_dat_i[15:8]; @@ -87,20 +89,20 @@ module dspengine_8to16 case(dsp_state) DSP_IDLE : begin - read_adr <= 1; // Skip 0 for transport header - write_adr <= 1; // Skip 0 for transport header + read_adr <= HEADER_OFFSET; + write_adr <= HEADER_OFFSET; if(access_ok) - dsp_state <= DSP_PARSE_HEADER; + dsp_state <= DSP_IDLE_RD; end - + + DSP_IDLE_RD: //extra idle state for read to become valid + dsp_state <= DSP_PARSE_HEADER; + DSP_PARSE_HEADER : begin - // FIXME is data always valid here? - has_trailer_reg <= has_trailer; new_header[31:16] <= access_dat_i[31:16]; - new_header[15:0] <= access_len-1; - length <= access_len; + new_header[15:0] <= access_len-HEADER_OFFSET; hdr_length_reg <= hdr_length; if(~is_if_data | ~convert | ~has_trailer) // ~convert is valid (16 bit mode) but both ~trailer and ~is_if_data are both @@ -111,7 +113,7 @@ module dspengine_8to16 read_adr <= access_len - 1; // point to trailer dsp_state <= DSP_READ_TRAILER; wait_for_trailer <= 0; - data_in_len <= access_len - hdr_length - 2; + data_in_len <= access_len - hdr_length - HEADER_OFFSET - 1 /*trailer*/; end end @@ -121,9 +123,8 @@ module dspengine_8to16 if(wait_for_trailer) dsp_state <= DSP_WRITE_TRAILER; new_trailer <= access_dat_i[31:0]; // Leave trailer unchanged - odd <= access_dat_i[20] & access_dat_i[8]; - data_out_len <= data_in_lenx2; - write_adr <= hdr_length_reg + data_in_lenx2 + 1; + odd <= is_odd; + write_adr <= hdr_length_reg + data_in_lenx2 + HEADER_OFFSET; end DSP_WRITE_TRAILER : diff --git a/usrp2/vrt/vita_tx_chain.v b/usrp2/vrt/vita_tx_chain.v index f9348bbfd..8002eae83 100644 --- a/usrp2/vrt/vita_tx_chain.v +++ b/usrp2/vrt/vita_tx_chain.v @@ -76,7 +76,7 @@ module vita_tx_chain .data_i(tx_data_i), .src_rdy_i(tx_src_rdy_i), .dst_rdy_o(tx_dst_rdy_o), .data_o(tx_data_int2), .src_rdy_o(tx_src_rdy_int2), .dst_rdy_i(tx_dst_rdy_int2)); - dspengine_8to16 #(.BASE(BASE+6), .BUF_SIZE(FIFOSIZE)) dspengine_8to16 + dspengine_8to16 #(.BASE(BASE+6), .BUF_SIZE(FIFOSIZE), .HEADER_OFFSET(USE_TRANS_HEADER)) dspengine_8to16 (.clk(clk),.reset(reset),.clear(clear), .set_stb(set_stb), .set_addr(set_addr), .set_data(set_data), .access_we(access_we), .access_stb(access_stb), .access_ok(access_ok), .access_done(access_done), -- cgit v1.2.3 From 531a7910c22dce40de5ddccee0cb05275b73fe32 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Mon, 30 Jan 2012 23:04:31 -0800 Subject: dsp rework: finished engine HEADER_OFFSET stuff, add post_engine_buffering --- usrp2/sdr_lib/dspengine_8to16.v | 10 +++++----- usrp2/vrt/vita_tx_chain.v | 11 ++++++++--- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/usrp2/sdr_lib/dspengine_8to16.v b/usrp2/sdr_lib/dspengine_8to16.v index 66568bc12..7319451e5 100644 --- a/usrp2/sdr_lib/dspengine_8to16.v +++ b/usrp2/sdr_lib/dspengine_8to16.v @@ -132,7 +132,7 @@ module dspengine_8to16 dsp_state <= DSP_READ; write_adr <= write_adr - 1; read_adr <= read_adr - 1; - new_header[15:0] <= write_adr; // length = addr of trailer + 1 + new_header[15:0] <= write_adr + (1 - HEADER_OFFSET); // length = addr of trailer + 1 end DSP_READ : @@ -145,7 +145,7 @@ module dspengine_8to16 begin write_adr <= write_adr - 1; odd <= 0; - if(write_adr == (hdr_length_reg+1)) + if(write_adr == (hdr_length_reg+HEADER_OFFSET)) dsp_state <= DSP_WRITE_HEADER; else if(odd) dsp_state <= DSP_READ; @@ -156,7 +156,7 @@ module dspengine_8to16 DSP_WRITE_0 : begin write_adr <= write_adr - 1; - if(write_adr == (hdr_length_reg+1)) + if(write_adr == (hdr_length_reg+HEADER_OFFSET)) dsp_state <= DSP_WRITE_HEADER; else dsp_state <= DSP_READ; @@ -167,8 +167,8 @@ module dspengine_8to16 DSP_DONE : begin - read_adr <= 1; - write_adr <= 1; + read_adr <= HEADER_OFFSET; + write_adr <= HEADER_OFFSET; dsp_state <= DSP_IDLE; end endcase // case (dsp_state) diff --git a/usrp2/vrt/vita_tx_chain.v b/usrp2/vrt/vita_tx_chain.v index 8002eae83..189876015 100644 --- a/usrp2/vrt/vita_tx_chain.v +++ b/usrp2/vrt/vita_tx_chain.v @@ -64,8 +64,8 @@ module vita_tx_chain wire [FIFOSIZE-1:0] access_adr, access_len; wire access_we, access_stb, access_ok, access_done, access_skip_read; wire [35:0] dsp_to_buf, buf_to_dsp; - wire [35:0] tx_data_int2; - wire tx_src_rdy_int2, tx_dst_rdy_int2; + wire [35:0] tx_data_int1, tx_data_int2; + wire tx_src_rdy_int1, tx_dst_rdy_int1, tx_src_rdy_int2, tx_dst_rdy_int2; double_buffer #(.BUF_SIZE(FIFOSIZE)) db (.clk(clk),.reset(reset),.clear(clear), @@ -74,7 +74,7 @@ module vita_tx_chain .access_dat_i(dsp_to_buf), .access_dat_o(buf_to_dsp), .data_i(tx_data_i), .src_rdy_i(tx_src_rdy_i), .dst_rdy_o(tx_dst_rdy_o), - .data_o(tx_data_int2), .src_rdy_o(tx_src_rdy_int2), .dst_rdy_i(tx_dst_rdy_int2)); + .data_o(tx_data_int1), .src_rdy_o(tx_src_rdy_int1), .dst_rdy_i(tx_dst_rdy_int1)); dspengine_8to16 #(.BASE(BASE+6), .BUF_SIZE(FIFOSIZE), .HEADER_OFFSET(USE_TRANS_HEADER)) dspengine_8to16 (.clk(clk),.reset(reset),.clear(clear), @@ -83,6 +83,11 @@ module vita_tx_chain .access_skip_read(access_skip_read), .access_adr(access_adr), .access_len(access_len), .access_dat_i(buf_to_dsp), .access_dat_o(dsp_to_buf)); + fifo_cascade #(.WIDTH(36), .SIZE(9)) post_engine_buffering( + .clk(clk), .reset(reset), .clear(clear), + .datain(tx_data_int1), .src_rdy_i(tx_src_rdy_int1), .dst_rdy_o(tx_dst_rdy_int1), + .dataout(tx_data_int2), .src_rdy_o(tx_src_rdy_int2), .dst_rdy_i(tx_dst_rdy_int2)); + vita_tx_deframer #(.BASE(BASE), .MAXCHAN(MAXCHAN), .USE_TRANS_HEADER(USE_TRANS_HEADER)) -- cgit v1.2.3 From 08b60ada2f025deac298faa2492c838db7c31d10 Mon Sep 17 00:00:00 2001 From: Matt Ettus Date: Tue, 31 Jan 2012 12:06:22 -0800 Subject: dsp_rework: more thorough test --- usrp2/control_lib/double_buffer_tb.v | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/usrp2/control_lib/double_buffer_tb.v b/usrp2/control_lib/double_buffer_tb.v index 3e0b04b8a..a9d1e0b29 100644 --- a/usrp2/control_lib/double_buffer_tb.v +++ b/usrp2/control_lib/double_buffer_tb.v @@ -73,7 +73,9 @@ module double_buffer_tb(); // Passthrough $display("Passthrough"); src_rdy_i <= 1; - data_i <= { 2'b00,1'b0,1'b1,32'hFFFFFFFF}; + data_i <= { 2'b00,1'b0,1'b1,32'h01234567}; + @(posedge clk); + data_i <= { 2'b00,1'b0,1'b0,32'hFFFFFFFF}; @(posedge clk); data_i <= { 2'b00,1'b0,1'b0,32'h04050607}; @(posedge clk); @@ -95,7 +97,9 @@ module double_buffer_tb(); @(posedge clk); $display("Non-IF Data Passthrough"); src_rdy_i <= 1; - data_i <= { 2'b00,1'b0,1'b1,32'hC0000000}; + data_i <= { 2'b00,1'b0,1'b1,32'h89acdef0}; + @(posedge clk); + data_i <= { 2'b00,1'b0,1'b0,32'hC0000000}; @(posedge clk); data_i <= { 2'b00,1'b0,1'b0,32'h14151617}; @(posedge clk); @@ -111,7 +115,9 @@ module double_buffer_tb(); $display("No StreamID, No Trailer, Even"); src_rdy_i <= 1; - data_i <= { 2'b00,1'b0,1'b1,32'h0000FFFF}; + data_i <= { 2'b00,1'b0,1'b1,32'hAAAAAAAA}; + @(posedge clk); + data_i <= { 2'b00,1'b0,1'b0,32'h0000FFFF}; @(posedge clk); data_i <= { 2'b00,1'b0,1'b0,32'h01000200}; @(posedge clk); @@ -139,7 +145,9 @@ module double_buffer_tb(); $display("No StreamID, No Trailer, Odd"); src_rdy_i <= 1; - data_i <= { 2'b00,1'b0,1'b1,32'h0000FFFF}; + data_i <= { 2'b00,1'b0,1'b1,32'hBBBBBBBB}; + @(posedge clk); + data_i <= { 2'b00,1'b0,1'b0,32'h0000FFFF}; @(posedge clk); data_i <= { 2'b00,1'b0,1'b0,32'h11001200}; @(posedge clk); @@ -162,7 +170,9 @@ module double_buffer_tb(); */ $display("No StreamID, Trailer, Even"); src_rdy_i <= 1; - data_i <= { 2'b00,1'b0,1'b1,32'h0400FFFF}; + data_i <= { 2'b00,1'b0,1'b1,32'hCCCCCCCC}; + @(posedge clk); + data_i <= { 2'b00,1'b0,1'b0,32'h0400FFFF}; @(posedge clk); data_i <= { 2'b00,1'b0,1'b0,32'h21222324}; @(posedge clk); @@ -182,10 +192,12 @@ module double_buffer_tb(); while(~dst_rdy_o) @(posedge clk); - +/* $display("No StreamID, Trailer, Odd"); src_rdy_i <= 1; - data_i <= { 2'b00,1'b0,1'b1,32'h0400FFFF}; + data_i <= { 2'b00,1'b0,1'b1,32'hDDDDDDDD}; + @(posedge clk); + data_i <= { 2'b00,1'b0,1'b0,32'h0400FFFF}; @(posedge clk); data_i <= { 2'b00,1'b0,1'b0,32'h21222324}; @(posedge clk); @@ -202,7 +214,7 @@ module double_buffer_tb(); @(posedge clk); src_rdy_i <= 0; @(posedge clk); - +*/ while(~dst_rdy_o) @(posedge clk); -- cgit v1.2.3 From 72359ea15846ab87c781ab4d072f694e97cc3cd1 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Tue, 17 Jan 2012 13:42:37 -0800 Subject: uhd: implement convert_sc8to_sc16 table w/ scalar --- host/lib/convert/convert_with_tables.cpp | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/host/lib/convert/convert_with_tables.cpp b/host/lib/convert/convert_with_tables.cpp index c45415d5d..c033a2959 100644 --- a/host/lib/convert/convert_with_tables.cpp +++ b/host/lib/convert/convert_with_tables.cpp @@ -17,6 +17,7 @@ #include "convert_common.hpp" #include +#include #include using namespace uhd::convert; @@ -68,6 +69,19 @@ public: convert_sc8_item32_1_to_fcxx_1(void): _table(sc16_table_len){} void set_scalar(const double scalar){ + + //special case, this is converts sc8 to sc16, + //use the scale-factor but no normalization + if (sizeof(type) == sizeof(s16_t)){ + for (size_t i = 0; i < sc16_table_len; i++){ + const boost::uint16_t val = tohost(boost::uint16_t(i & 0xffff)); + const type real = type(boost::math::iround(boost::int8_t(val >> 8)*scalar*32767)); + const type imag = type(boost::math::iround(boost::int8_t(val >> 0)*scalar*32767)); + _table[i] = std::complex(real, imag); + } + return; + } + for (size_t i = 0; i < sc16_table_len; i++){ const boost::uint16_t val = tohost(boost::uint16_t(i & 0xffff)); const type real = type(boost::int8_t(val >> 8)*scalar); @@ -149,6 +163,14 @@ static converter::sptr make_convert_sc8_item32_le_1_to_fc64_1(void){ return converter::sptr(new convert_sc8_item32_1_to_fcxx_1()); } +static converter::sptr make_convert_sc8_item32_be_1_to_sc16_1(void){ + return converter::sptr(new convert_sc8_item32_1_to_fcxx_1()); +} + +static converter::sptr make_convert_sc8_item32_le_1_to_sc16_1(void){ + return converter::sptr(new convert_sc8_item32_1_to_fcxx_1()); +} + UHD_STATIC_BLOCK(register_convert_sc16_item32_1_to_fcxx_1){ uhd::convert::id_type id; id.num_inputs = 1; @@ -185,4 +207,12 @@ UHD_STATIC_BLOCK(register_convert_sc16_item32_1_to_fcxx_1){ id.output_format = "fc64"; id.input_format = "sc8_item32_le"; uhd::convert::register_converter(id, &make_convert_sc8_item32_le_1_to_fc64_1, PRIORITY_TABLE); + + id.output_format = "sc16"; + id.input_format = "sc8_item32_be"; + uhd::convert::register_converter(id, &make_convert_sc8_item32_be_1_to_sc16_1, PRIORITY_TABLE); + + id.output_format = "sc16"; + id.input_format = "sc8_item32_le"; + uhd::convert::register_converter(id, &make_convert_sc8_item32_le_1_to_sc16_1, PRIORITY_TABLE); } -- cgit v1.2.3 From 8f25550d1a8ac634ee3873ae90a86d1e07dd5482 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Sat, 28 Jan 2012 12:21:01 -0800 Subject: dsp rework: implemented new scalefactor in rx dsp core --- host/include/uhd/stream.hpp | 5 +++-- host/lib/usrp/b100/b100_impl.hpp | 2 +- host/lib/usrp/b100/io_impl.cpp | 2 +- host/lib/usrp/cores/rx_dsp_core_200.cpp | 33 +++++++++++++++++++++++---------- host/lib/usrp/cores/tx_dsp_core_200.cpp | 4 ++-- host/lib/usrp/e100/e100_impl.hpp | 2 +- host/lib/usrp/e100/io_impl.cpp | 2 +- host/lib/usrp/usrp2/fw_common.h | 4 ++-- host/lib/usrp/usrp2/io_impl.cpp | 2 +- 9 files changed, 35 insertions(+), 21 deletions(-) diff --git a/host/include/uhd/stream.hpp b/host/include/uhd/stream.hpp index 352f63e4e..0c9282545 100644 --- a/host/include/uhd/stream.hpp +++ b/host/include/uhd/stream.hpp @@ -80,8 +80,9 @@ struct UHD_API stream_args_t{ * Possible keys used by args (depends on implementation): * * - scalar: an integer scaling factor used with the sc8 wire format. - * The key/value pair scalar=1024 means that the sample in the DSP - * was multiplied by 1024 before its upper 8 bits were harvested. + * Use scalar=1 to harvest the lower 8-bits. + * Use scalar=256 to harvest the upper 8-bits. + * Any scalar in-between is also a possibility. * * - underflow_policy: how the TX DSP should recover from underflow. * Possible options are "next_burst" or "next_packet". diff --git a/host/lib/usrp/b100/b100_impl.hpp b/host/lib/usrp/b100/b100_impl.hpp index 96d90b14c..310daa842 100644 --- a/host/lib/usrp/b100/b100_impl.hpp +++ b/host/lib/usrp/b100/b100_impl.hpp @@ -47,7 +47,7 @@ static const double B100_LINK_RATE_BPS = 256e6/8; //pratical link rate static const std::string B100_FW_FILE_NAME = "usrp_b100_fw.ihx"; static const std::string B100_FPGA_FILE_NAME = "usrp_b100_fpga.bin"; static const boost::uint16_t B100_FW_COMPAT_NUM = 0x02; -static const boost::uint16_t B100_FPGA_COMPAT_NUM = 0x08; +static const boost::uint16_t B100_FPGA_COMPAT_NUM = 0x09; static const boost::uint32_t B100_RX_SID_BASE = 2; static const boost::uint32_t B100_TX_ASYNC_SID = 1; static const double B100_DEFAULT_TICK_RATE = 64e6; diff --git a/host/lib/usrp/b100/io_impl.cpp b/host/lib/usrp/b100/io_impl.cpp index 494d5d123..c98f71754 100644 --- a/host/lib/usrp/b100/io_impl.cpp +++ b/host/lib/usrp/b100/io_impl.cpp @@ -202,7 +202,7 @@ rx_streamer::sptr b100_impl::get_rx_stream(const uhd::stream_args_t &args_){ //setup defaults for unspecified values args.otw_format = args.otw_format.empty()? "sc16" : args.otw_format; args.channels = args.channels.empty()? std::vector(1, 0) : args.channels; - const unsigned sc8_scalar = unsigned(args.args.cast("scalar", 0x400)); + const unsigned sc8_scalar = unsigned(args.args.cast("scalar", 1)); //calculate packet size static const size_t hdr_size = 0 diff --git a/host/lib/usrp/cores/rx_dsp_core_200.cpp b/host/lib/usrp/cores/rx_dsp_core_200.cpp index 2e21cc895..cbc732c9c 100644 --- a/host/lib/usrp/cores/rx_dsp_core_200.cpp +++ b/host/lib/usrp/cores/rx_dsp_core_200.cpp @@ -18,6 +18,7 @@ #include "rx_dsp_core_200.hpp" #include #include +#include #include #include #include //thread sleep @@ -27,7 +28,7 @@ #include #define REG_DSP_RX_FREQ _dsp_base + 0 -//skip one right here +#define REG_DSP_RX_SCALE_IQ _dsp_base + 4 #define REG_DSP_RX_DECIM _dsp_base + 8 #define REG_DSP_RX_MUX _dsp_base + 12 @@ -60,6 +61,11 @@ public: ): _iface(iface), _dsp_base(dsp_base), _ctrl_base(ctrl_base), _sid(sid) { + //init to something so update method has reasonable defaults + _scaling_adjustment = 1.0; + _extra_scaling = 1.0; + _fxpt_scalar_correction = 1.0; + //This is a hack/fix for the lingering packet problem. //The caller should also flush the recv transports if (lingering_packet){ @@ -175,12 +181,20 @@ public: // Calculate closest multiplier constant to reverse gain absent scale multipliers const double rate_pow = std::pow(double(decim & 0xff), 4); _scaling_adjustment = std::pow(2, ceil_log2(rate_pow))/(1.65*rate_pow); + this->update_scalar(); return _tick_rate/decim_rate; } + void update_scalar(void){ + const double target_scalar = (1 << 16)*_scaling_adjustment/_extra_scaling; + const boost::int32_t actual_scalar = boost::math::iround(target_scalar); + _fxpt_scalar_correction = target_scalar/actual_scalar; //should be small + _iface->poke32(REG_DSP_RX_SCALE_IQ, actual_scalar); + } + double get_scaling_adjustment(void){ - return _scaling_adjustment/_fxpt_scale_adj; + return _fxpt_scalar_correction*_extra_scaling/32767.; } double set_freq(const double freq_){ @@ -214,18 +228,17 @@ public: unsigned format_word = 0; if (format == "sc16"){ format_word = 0; - _fxpt_scale_adj = 32767.; + _extra_scaling = 1.0; } else if (format == "sc8"){ - format_word = (1 << 18); - _fxpt_scale_adj = 127. * scale; - _fxpt_scale_adj /= 256; //engine 16to8 drops lower 8 bits - _fxpt_scale_adj /= 4; //scale operation 2-bit pad + format_word = (1 << 0); + _extra_scaling = scale; } else throw uhd::value_error("USRP RX cannot handle requested wire format: " + format); - const unsigned scale_word = scale & 0x3ffff; //18 bits; - _iface->poke32(REG_RX_CTRL_FORMAT, format_word | scale_word); + this->update_scalar(); + + _iface->poke32(REG_RX_CTRL_FORMAT, format_word); } private: @@ -233,7 +246,7 @@ private: const size_t _dsp_base, _ctrl_base; double _tick_rate, _link_rate; bool _continuous_streaming; - double _scaling_adjustment, _fxpt_scale_adj; + double _scaling_adjustment, _extra_scaling, _fxpt_scalar_correction; const boost::uint32_t _sid; }; diff --git a/host/lib/usrp/cores/tx_dsp_core_200.cpp b/host/lib/usrp/cores/tx_dsp_core_200.cpp index c5de4e361..f4c303d05 100644 --- a/host/lib/usrp/cores/tx_dsp_core_200.cpp +++ b/host/lib/usrp/cores/tx_dsp_core_200.cpp @@ -122,8 +122,8 @@ public: // Calculate CIC interpolation (i.e., without halfband interpolators) // Calculate closest multiplier constant to reverse gain absent scale multipliers double rate_cubed = std::pow(double(interp & 0xff), 3); - const boost::int16_t scale = boost::math::iround((4096*std::pow(2, ceil_log2(rate_cubed)))/(1.65*rate_cubed)); - _iface->poke32(REG_DSP_TX_SCALE_IQ, (boost::uint32_t(scale) << 16) | (boost::uint32_t(scale) << 0)); + const boost::int32_t scale = boost::math::iround((4096*std::pow(2, ceil_log2(rate_cubed)))/(1.65*rate_cubed)); + _iface->poke32(REG_DSP_TX_SCALE_IQ, scale); return _tick_rate/interp_rate; } diff --git a/host/lib/usrp/e100/e100_impl.hpp b/host/lib/usrp/e100/e100_impl.hpp index 2ea890375..f94061a24 100644 --- a/host/lib/usrp/e100/e100_impl.hpp +++ b/host/lib/usrp/e100/e100_impl.hpp @@ -48,7 +48,7 @@ static const double E100_RX_LINK_RATE_BPS = 166e6/3/2*2; static const double E100_TX_LINK_RATE_BPS = 166e6/3/1*2; static const std::string E100_I2C_DEV_NODE = "/dev/i2c-3"; static const std::string E100_UART_DEV_NODE = "/dev/ttyO0"; -static const boost::uint16_t E100_FPGA_COMPAT_NUM = 0x08; +static const boost::uint16_t E100_FPGA_COMPAT_NUM = 0x09; static const boost::uint32_t E100_RX_SID_BASE = 2; static const boost::uint32_t E100_TX_ASYNC_SID = 1; static const double E100_DEFAULT_CLOCK_RATE = 64e6; diff --git a/host/lib/usrp/e100/io_impl.cpp b/host/lib/usrp/e100/io_impl.cpp index 441e32a8d..97f4db6f1 100644 --- a/host/lib/usrp/e100/io_impl.cpp +++ b/host/lib/usrp/e100/io_impl.cpp @@ -278,7 +278,7 @@ rx_streamer::sptr e100_impl::get_rx_stream(const uhd::stream_args_t &args_){ //setup defaults for unspecified values args.otw_format = args.otw_format.empty()? "sc16" : args.otw_format; args.channels = args.channels.empty()? std::vector(1, 0) : args.channels; - const unsigned sc8_scalar = unsigned(args.args.cast("scalar", 0x400)); + const unsigned sc8_scalar = unsigned(args.args.cast("scalar", 1)); //calculate packet size static const size_t hdr_size = 0 diff --git a/host/lib/usrp/usrp2/fw_common.h b/host/lib/usrp/usrp2/fw_common.h index 1af1db860..0babf7445 100644 --- a/host/lib/usrp/usrp2/fw_common.h +++ b/host/lib/usrp/usrp2/fw_common.h @@ -30,9 +30,9 @@ extern "C" { #endif //fpga and firmware compatibility numbers -#define USRP2_FPGA_COMPAT_NUM 8 +#define USRP2_FPGA_COMPAT_NUM 9 #define USRP2_FW_COMPAT_NUM 11 -#define USRP2_FW_VER_MINOR 1 +#define USRP2_FW_VER_MINOR 2 //used to differentiate control packets over data port #define USRP2_INVALID_VRT_HEADER 0 diff --git a/host/lib/usrp/usrp2/io_impl.cpp b/host/lib/usrp/usrp2/io_impl.cpp index e3fa46920..5f5369f7d 100644 --- a/host/lib/usrp/usrp2/io_impl.cpp +++ b/host/lib/usrp/usrp2/io_impl.cpp @@ -380,7 +380,7 @@ rx_streamer::sptr usrp2_impl::get_rx_stream(const uhd::stream_args_t &args_){ //setup defaults for unspecified values args.otw_format = args.otw_format.empty()? "sc16" : args.otw_format; args.channels = args.channels.empty()? std::vector(1, 0) : args.channels; - const unsigned sc8_scalar = unsigned(args.args.cast("scalar", 0x400)); + const unsigned sc8_scalar = unsigned(args.args.cast("scalar", 1)); //calculate packet size static const size_t hdr_size = 0 -- cgit v1.2.3 From aa95e53a91fa52b61b6796fcfc811251b20dcb73 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Sat, 28 Jan 2012 16:08:17 -0800 Subject: dsp rework: work on scaling and args parsing on RX and TX dsp This simplified some copy pasta in the io_impl.cpp files, and adds a place for sc8 tx mode in the tx dsp core code. --- host/lib/usrp/b100/io_impl.cpp | 13 ++++------- host/lib/usrp/cores/rx_dsp_core_200.cpp | 12 ++++++----- host/lib/usrp/cores/rx_dsp_core_200.hpp | 3 ++- host/lib/usrp/cores/tx_dsp_core_200.cpp | 38 ++++++++++++++++++++++++++++++--- host/lib/usrp/cores/tx_dsp_core_200.hpp | 6 ++++-- host/lib/usrp/e100/io_impl.cpp | 13 ++++------- host/lib/usrp/usrp2/io_impl.cpp | 13 ++++------- 7 files changed, 60 insertions(+), 38 deletions(-) diff --git a/host/lib/usrp/b100/io_impl.cpp b/host/lib/usrp/b100/io_impl.cpp index c98f71754..6e9e017aa 100644 --- a/host/lib/usrp/b100/io_impl.cpp +++ b/host/lib/usrp/b100/io_impl.cpp @@ -154,6 +154,8 @@ void b100_impl::update_tx_samp_rate(const size_t dspno, const double rate){ if (my_streamer.get() == NULL) return; my_streamer->set_samp_rate(rate); + const double adj = _tx_dsp->get_scaling_adjustment(); + my_streamer->set_scale_factor(adj); } void b100_impl::update_rx_subdev_spec(const uhd::usrp::subdev_spec_t &spec){ @@ -202,7 +204,6 @@ rx_streamer::sptr b100_impl::get_rx_stream(const uhd::stream_args_t &args_){ //setup defaults for unspecified values args.otw_format = args.otw_format.empty()? "sc16" : args.otw_format; args.channels = args.channels.empty()? std::vector(1, 0) : args.channels; - const unsigned sc8_scalar = unsigned(args.args.cast("scalar", 1)); //calculate packet size static const size_t hdr_size = 0 @@ -233,8 +234,7 @@ rx_streamer::sptr b100_impl::get_rx_stream(const uhd::stream_args_t &args_){ for (size_t chan_i = 0; chan_i < args.channels.size(); chan_i++){ const size_t dsp = args.channels[chan_i]; _rx_dsps[dsp]->set_nsamps_per_packet(spp); //seems to be a good place to set this - if (not args.args.has_key("noclear")) _rx_dsps[dsp]->clear(); - _rx_dsps[dsp]->set_format(args.otw_format, sc8_scalar); + _rx_dsps[dsp]->setup(args); my_streamer->set_xport_chan_get_buff(chan_i, boost::bind( &recv_packet_demuxer::get_recv_buff, _io_impl->demuxer, dsp, _1 ), true /*flush*/); @@ -260,10 +260,6 @@ tx_streamer::sptr b100_impl::get_tx_stream(const uhd::stream_args_t &args_){ args.otw_format = args.otw_format.empty()? "sc16" : args.otw_format; args.channels = args.channels.empty()? std::vector(1, 0) : args.channels; - if (args.otw_format != "sc16"){ - throw uhd::value_error("USRP TX cannot handle requested wire format: " + args.otw_format); - } - //calculate packet size static const size_t hdr_size = 0 + vrt::max_if_hdr_words32*sizeof(boost::uint32_t) @@ -291,8 +287,7 @@ tx_streamer::sptr b100_impl::get_tx_stream(const uhd::stream_args_t &args_){ for (size_t chan_i = 0; chan_i < args.channels.size(); chan_i++){ const size_t dsp = args.channels[chan_i]; UHD_ASSERT_THROW(dsp == 0); //always 0 - if (not args.args.has_key("noclear")) _tx_dsp->clear(); - if (args.args.has_key("underflow_policy")) _tx_dsp->set_underflow_policy(args.args["underflow_policy"]); + _tx_dsp->setup(args); my_streamer->set_xport_chan_get_buff(chan_i, boost::bind( &zero_copy_if::get_send_buff, _data_transport, _1 )); diff --git a/host/lib/usrp/cores/rx_dsp_core_200.cpp b/host/lib/usrp/cores/rx_dsp_core_200.cpp index cbc732c9c..b2bf934bc 100644 --- a/host/lib/usrp/cores/rx_dsp_core_200.cpp +++ b/host/lib/usrp/cores/rx_dsp_core_200.cpp @@ -224,17 +224,19 @@ public: if (_continuous_streaming) issue_stream_command(stream_cmd_t::STREAM_MODE_START_CONTINUOUS); } - void set_format(const std::string &format, const unsigned scale){ + void setup(const uhd::stream_args_t &stream_args){ + if (not stream_args.args.has_key("noclear")) this->clear(); + unsigned format_word = 0; - if (format == "sc16"){ + if (stream_args.otw_format == "sc16"){ format_word = 0; _extra_scaling = 1.0; } - else if (format == "sc8"){ + else if (stream_args.otw_format == "sc8"){ format_word = (1 << 0); - _extra_scaling = scale; + _extra_scaling = stream_args.args.cast("scalar", 1.0); } - else throw uhd::value_error("USRP RX cannot handle requested wire format: " + format); + else throw uhd::value_error("USRP RX cannot handle requested wire format: " + stream_args.otw_format); this->update_scalar(); diff --git a/host/lib/usrp/cores/rx_dsp_core_200.hpp b/host/lib/usrp/cores/rx_dsp_core_200.hpp index 58be51eee..b01f751e9 100644 --- a/host/lib/usrp/cores/rx_dsp_core_200.hpp +++ b/host/lib/usrp/cores/rx_dsp_core_200.hpp @@ -19,6 +19,7 @@ #define INCLUDED_LIBUHD_USRP_RX_DSP_CORE_200_HPP #include +#include #include #include #include @@ -60,7 +61,7 @@ public: virtual void handle_overflow(void) = 0; - virtual void set_format(const std::string &format, const unsigned scale) = 0; + virtual void setup(const uhd::stream_args_t &stream_args) = 0; }; #endif /* INCLUDED_LIBUHD_USRP_RX_DSP_CORE_200_HPP */ diff --git a/host/lib/usrp/cores/tx_dsp_core_200.cpp b/host/lib/usrp/cores/tx_dsp_core_200.cpp index f4c303d05..2c5b86bfc 100644 --- a/host/lib/usrp/cores/tx_dsp_core_200.cpp +++ b/host/lib/usrp/cores/tx_dsp_core_200.cpp @@ -58,6 +58,11 @@ public: ): _iface(iface), _dsp_base(dsp_base), _ctrl_base(ctrl_base), _sid(sid) { + //init to something so update method has reasonable defaults + _scaling_adjustment = 1.0; + _extra_scaling = 1.0; + _fxpt_scalar_correction = 1.0; + //init the tx control registers this->clear(); this->set_underflow_policy("next_packet"); @@ -121,13 +126,24 @@ public: // Calculate CIC interpolation (i.e., without halfband interpolators) // Calculate closest multiplier constant to reverse gain absent scale multipliers - double rate_cubed = std::pow(double(interp & 0xff), 3); - const boost::int32_t scale = boost::math::iround((4096*std::pow(2, ceil_log2(rate_cubed)))/(1.65*rate_cubed)); - _iface->poke32(REG_DSP_TX_SCALE_IQ, scale); + const double rate_pow = std::pow(double(interp & 0xff), 3); + _scaling_adjustment = std::pow(2, ceil_log2(rate_pow))/(1.65*rate_pow); + this->update_scalar(); return _tick_rate/interp_rate; } + void update_scalar(void){ + const double target_scalar = (1 << 17)*_scaling_adjustment/_extra_scaling; + const boost::int32_t actual_scalar = boost::math::iround(target_scalar); + _fxpt_scalar_correction = target_scalar/actual_scalar; //should be small + _iface->poke32(REG_DSP_TX_SCALE_IQ, actual_scalar); + } + + double get_scaling_adjustment(void){ + return _fxpt_scalar_correction*_extra_scaling*32767.; + } + double set_freq(const double freq_){ //correct for outside of rate (wrap around) double freq = std::fmod(freq_, _tick_rate); @@ -156,10 +172,26 @@ public: _iface->poke32(REG_TX_CTRL_PACKETS_PER_UP, (packets_per_up == 0)? 0 : (FLAG_TX_CTRL_UP_ENB | packets_per_up)); } + void setup(const uhd::stream_args_t &stream_args){ + if (not stream_args.args.has_key("noclear")) this->clear(); + + if (stream_args.otw_format == "sc16"){ + _extra_scaling = 1.0; + } + else throw uhd::value_error("USRP TX cannot handle requested wire format: " + stream_args.otw_format); + + this->update_scalar(); + + if (stream_args.args.has_key("underflow_policy")){ + this->set_underflow_policy(stream_args.args["underflow_policy"]); + } + } + private: wb_iface::sptr _iface; const size_t _dsp_base, _ctrl_base; double _tick_rate, _link_rate; + double _scaling_adjustment, _extra_scaling, _fxpt_scalar_correction; const boost::uint32_t _sid; }; diff --git a/host/lib/usrp/cores/tx_dsp_core_200.hpp b/host/lib/usrp/cores/tx_dsp_core_200.hpp index 4b39a5b07..0e1cfb6bc 100644 --- a/host/lib/usrp/cores/tx_dsp_core_200.hpp +++ b/host/lib/usrp/cores/tx_dsp_core_200.hpp @@ -19,6 +19,7 @@ #define INCLUDED_LIBUHD_USRP_TX_DSP_CORE_200_HPP #include +#include #include #include #include @@ -44,14 +45,15 @@ public: virtual uhd::meta_range_t get_host_rates(void) = 0; + virtual double get_scaling_adjustment(void) = 0; + virtual uhd::meta_range_t get_freq_range(void) = 0; virtual double set_freq(const double freq) = 0; virtual void set_updates(const size_t cycles_per_up, const size_t packets_per_up) = 0; - virtual void set_underflow_policy(const std::string &policy) = 0; - + virtual void setup(const uhd::stream_args_t &stream_args) = 0; }; #endif /* INCLUDED_LIBUHD_USRP_TX_DSP_CORE_200_HPP */ diff --git a/host/lib/usrp/e100/io_impl.cpp b/host/lib/usrp/e100/io_impl.cpp index 97f4db6f1..89a4ed00b 100644 --- a/host/lib/usrp/e100/io_impl.cpp +++ b/host/lib/usrp/e100/io_impl.cpp @@ -217,6 +217,8 @@ void e100_impl::update_tx_samp_rate(const size_t dspno, const double rate){ if (my_streamer.get() == NULL) return; my_streamer->set_samp_rate(rate); + const double adj = _tx_dsp->get_scaling_adjustment(); + my_streamer->set_scale_factor(adj); } void e100_impl::update_rates(void){ @@ -278,7 +280,6 @@ rx_streamer::sptr e100_impl::get_rx_stream(const uhd::stream_args_t &args_){ //setup defaults for unspecified values args.otw_format = args.otw_format.empty()? "sc16" : args.otw_format; args.channels = args.channels.empty()? std::vector(1, 0) : args.channels; - const unsigned sc8_scalar = unsigned(args.args.cast("scalar", 1)); //calculate packet size static const size_t hdr_size = 0 @@ -309,8 +310,7 @@ rx_streamer::sptr e100_impl::get_rx_stream(const uhd::stream_args_t &args_){ for (size_t chan_i = 0; chan_i < args.channels.size(); chan_i++){ const size_t dsp = args.channels[chan_i]; _rx_dsps[dsp]->set_nsamps_per_packet(spp); //seems to be a good place to set this - if (not args.args.has_key("noclear")) _rx_dsps[dsp]->clear(); - _rx_dsps[dsp]->set_format(args.otw_format, sc8_scalar); + _rx_dsps[dsp]->setup(args); my_streamer->set_xport_chan_get_buff(chan_i, boost::bind( &recv_packet_demuxer::get_recv_buff, _io_impl->demuxer, dsp, _1 ), true /*flush*/); @@ -336,10 +336,6 @@ tx_streamer::sptr e100_impl::get_tx_stream(const uhd::stream_args_t &args_){ args.otw_format = args.otw_format.empty()? "sc16" : args.otw_format; args.channels = args.channels.empty()? std::vector(1, 0) : args.channels; - if (args.otw_format != "sc16"){ - throw uhd::value_error("USRP TX cannot handle requested wire format: " + args.otw_format); - } - //calculate packet size static const size_t hdr_size = 0 + vrt::max_if_hdr_words32*sizeof(boost::uint32_t) @@ -367,8 +363,7 @@ tx_streamer::sptr e100_impl::get_tx_stream(const uhd::stream_args_t &args_){ for (size_t chan_i = 0; chan_i < args.channels.size(); chan_i++){ const size_t dsp = args.channels[chan_i]; UHD_ASSERT_THROW(dsp == 0); //always 0 - if (not args.args.has_key("noclear")) _tx_dsp->clear(); - if (args.args.has_key("underflow_policy")) _tx_dsp->set_underflow_policy(args.args["underflow_policy"]); + _tx_dsp->setup(args); my_streamer->set_xport_chan_get_buff(chan_i, boost::bind( &zero_copy_if::get_send_buff, _data_transport, _1 )); diff --git a/host/lib/usrp/usrp2/io_impl.cpp b/host/lib/usrp/usrp2/io_impl.cpp index 5f5369f7d..58a5df2a5 100644 --- a/host/lib/usrp/usrp2/io_impl.cpp +++ b/host/lib/usrp/usrp2/io_impl.cpp @@ -307,6 +307,8 @@ void usrp2_impl::update_tx_samp_rate(const std::string &mb, const size_t dsp, co if (my_streamer.get() == NULL) return; my_streamer->set_samp_rate(rate); + const double adj = _mbc[mb].tx_dsp->get_scaling_adjustment(); + my_streamer->set_scale_factor(adj); } void usrp2_impl::update_rates(void){ @@ -380,7 +382,6 @@ rx_streamer::sptr usrp2_impl::get_rx_stream(const uhd::stream_args_t &args_){ //setup defaults for unspecified values args.otw_format = args.otw_format.empty()? "sc16" : args.otw_format; args.channels = args.channels.empty()? std::vector(1, 0) : args.channels; - const unsigned sc8_scalar = unsigned(args.args.cast("scalar", 1)); //calculate packet size static const size_t hdr_size = 0 @@ -416,8 +417,7 @@ rx_streamer::sptr usrp2_impl::get_rx_stream(const uhd::stream_args_t &args_){ if (chan < num_chan_so_far){ const size_t dsp = chan + _mbc[mb].rx_chan_occ - num_chan_so_far; _mbc[mb].rx_dsps[dsp]->set_nsamps_per_packet(spp); //seems to be a good place to set this - if (not args.args.has_key("noclear")) _mbc[mb].rx_dsps[dsp]->clear(); - _mbc[mb].rx_dsps[dsp]->set_format(args.otw_format, sc8_scalar); + _mbc[mb].rx_dsps[dsp]->setup(args); my_streamer->set_xport_chan_get_buff(chan_i, boost::bind( &zero_copy_if::get_recv_buff, _mbc[mb].rx_dsp_xports[dsp], _1 ), true /*flush*/); @@ -447,10 +447,6 @@ tx_streamer::sptr usrp2_impl::get_tx_stream(const uhd::stream_args_t &args_){ args.otw_format = args.otw_format.empty()? "sc16" : args.otw_format; args.channels = args.channels.empty()? std::vector(1, 0) : args.channels; - if (args.otw_format != "sc16"){ - throw uhd::value_error("USRP TX cannot handle requested wire format: " + args.otw_format); - } - //calculate packet size static const size_t hdr_size = 0 + vrt::max_if_hdr_words32*sizeof(boost::uint32_t) @@ -485,10 +481,9 @@ tx_streamer::sptr usrp2_impl::get_tx_stream(const uhd::stream_args_t &args_){ if (chan < num_chan_so_far){ const size_t dsp = chan + _mbc[mb].tx_chan_occ - num_chan_so_far; if (not args.args.has_key("noclear")){ - _mbc[mb].tx_dsp->clear(); _io_impl->fc_mons[abs]->clear(); } - if (args.args.has_key("underflow_policy")) _mbc[mb].tx_dsp->set_underflow_policy(args.args["underflow_policy"]); + _mbc[mb].tx_dsp->setup(args); my_streamer->set_xport_chan_get_buff(chan_i, boost::bind( &usrp2_impl::io_impl::get_send_buff, _io_impl.get(), abs, _1 )); -- cgit v1.2.3 From 781cafa8717f00b883a4543b4a9150060691eee3 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Sat, 28 Jan 2012 17:21:40 -0800 Subject: gen2: added user setting regs api and user core --- host/include/uhd/usrp/multi_usrp.hpp | 10 ++++++ host/lib/usrp/b100/b100_impl.cpp | 7 +++++ host/lib/usrp/b100/b100_impl.hpp | 2 ++ host/lib/usrp/b100/b100_regs.hpp | 1 + host/lib/usrp/cores/CMakeLists.txt | 3 +- host/lib/usrp/cores/user_settings_core_200.cpp | 43 ++++++++++++++++++++++++++ host/lib/usrp/cores/user_settings_core_200.hpp | 36 +++++++++++++++++++++ host/lib/usrp/e100/e100_impl.cpp | 7 +++++ host/lib/usrp/e100/e100_impl.hpp | 2 ++ host/lib/usrp/e100/e100_regs.hpp | 1 + host/lib/usrp/multi_usrp.cpp | 11 +++++++ host/lib/usrp/usrp2/usrp2_impl.cpp | 7 +++++ host/lib/usrp/usrp2/usrp2_impl.hpp | 2 ++ host/lib/usrp/usrp2/usrp2_regs.hpp | 2 +- 14 files changed, 132 insertions(+), 2 deletions(-) create mode 100644 host/lib/usrp/cores/user_settings_core_200.cpp create mode 100644 host/lib/usrp/cores/user_settings_core_200.hpp diff --git a/host/include/uhd/usrp/multi_usrp.hpp b/host/include/uhd/usrp/multi_usrp.hpp index 49354f1af..88affa40c 100644 --- a/host/include/uhd/usrp/multi_usrp.hpp +++ b/host/include/uhd/usrp/multi_usrp.hpp @@ -24,6 +24,7 @@ #define UHD_USRP_MULTI_USRP_FRONTEND_CAL_API #define UHD_USRP_MULTI_USRP_COMMAND_TIME_API #define UHD_USRP_MULTI_USRP_BW_RANGE_API +#define UHD_USRP_MULTI_USRP_USER_REGS_API #include #include @@ -338,6 +339,15 @@ public: */ virtual std::vector get_mboard_sensor_names(size_t mboard = 0) = 0; + /*! + * Perform write on the user configuration register bus. These only exist if + * the user has implemented custom setting registers in the device FPGA. + * \param addr 8-bit register address + * \param data 32-bit register value + * \param mboard which motherboard to set the user register + */ + virtual void set_user_register(const boost::uint8_t addr, const boost::uint32_t data, size_t mboard = ALL_MBOARDS) = 0; + /******************************************************************* * RX methods ******************************************************************/ diff --git a/host/lib/usrp/b100/b100_impl.cpp b/host/lib/usrp/b100/b100_impl.cpp index 61bc58bce..87aee9568 100644 --- a/host/lib/usrp/b100/b100_impl.cpp +++ b/host/lib/usrp/b100/b100_impl.cpp @@ -387,6 +387,13 @@ b100_impl::b100_impl(const device_addr_t &device_addr){ static const std::vector clock_sources = boost::assign::list_of("internal")("external")("auto"); _tree->create >(mb_path / "clock_source/options").set(clock_sources); + //////////////////////////////////////////////////////////////////// + // create user-defined control objects + //////////////////////////////////////////////////////////////////// + _user = user_settings_core_200::make(_fpga_ctrl, B100_REG_SR_ADDR(B100_SR_USER_REGS)); + _tree->create(mb_path / "user/regs") + .subscribe(boost::bind(&user_settings_core_200::set_reg, _user, _1)); + //////////////////////////////////////////////////////////////////// // create dboard control objects //////////////////////////////////////////////////////////////////// diff --git a/host/lib/usrp/b100/b100_impl.hpp b/host/lib/usrp/b100/b100_impl.hpp index 310daa842..5e7794fe8 100644 --- a/host/lib/usrp/b100/b100_impl.hpp +++ b/host/lib/usrp/b100/b100_impl.hpp @@ -29,6 +29,7 @@ #include "rx_dsp_core_200.hpp" #include "tx_dsp_core_200.hpp" #include "time64_core_200.hpp" +#include "user_settings_core_200.hpp" #include #include #include @@ -84,6 +85,7 @@ private: std::vector _rx_dsps; tx_dsp_core_200::sptr _tx_dsp; time64_core_200::sptr _time64; + user_settings_core_200::sptr _user; b100_clock_ctrl::sptr _clock_ctrl; b100_codec_ctrl::sptr _codec_ctrl; b100_ctrl::sptr _fpga_ctrl; diff --git a/host/lib/usrp/b100/b100_regs.hpp b/host/lib/usrp/b100/b100_regs.hpp index 491e16eef..b625e65a5 100644 --- a/host/lib/usrp/b100/b100_regs.hpp +++ b/host/lib/usrp/b100/b100_regs.hpp @@ -95,6 +95,7 @@ #define B100_SR_CLEAR_RX_FIFO 61 // 1 reg #define B100_SR_CLEAR_TX_FIFO 62 // 1 reg #define B100_SR_GLOBAL_RESET 63 // 1 reg +#define B100_SR_USER_REGS 64 // 2 regs #define B100_SR_GPIO 128 diff --git a/host/lib/usrp/cores/CMakeLists.txt b/host/lib/usrp/cores/CMakeLists.txt index 2aa8f6b99..aa5f0bcbb 100644 --- a/host/lib/usrp/cores/CMakeLists.txt +++ b/host/lib/usrp/cores/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2011 Ettus Research LLC +# Copyright 2011-2012 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 @@ -30,4 +30,5 @@ LIBUHD_APPEND_SOURCES( ${CMAKE_CURRENT_SOURCE_DIR}/tx_dsp_core_200.cpp ${CMAKE_CURRENT_SOURCE_DIR}/rx_frontend_core_200.cpp ${CMAKE_CURRENT_SOURCE_DIR}/tx_frontend_core_200.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/user_settings_core_200.cpp ) diff --git a/host/lib/usrp/cores/user_settings_core_200.cpp b/host/lib/usrp/cores/user_settings_core_200.cpp new file mode 100644 index 000000000..d262631b1 --- /dev/null +++ b/host/lib/usrp/cores/user_settings_core_200.cpp @@ -0,0 +1,43 @@ +// +// Copyright 2012 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 . +// + +#include "user_settings_core_200.hpp" + +#define REG_USER_ADDR _base + 0 +#define REG_USER_DATA _base + 4 + +class user_settings_core_200_impl : public user_settings_core_200{ +public: + user_settings_core_200_impl(wb_iface::sptr iface, const size_t base): + _iface(iface), _base(base) + { + //NOP + } + + void set_reg(const user_reg_t ®){ + _iface->poke32(REG_USER_ADDR, reg.first); + _iface->poke32(REG_USER_DATA, reg.second); + } + +private: + wb_iface::sptr _iface; + const size_t _base; +}; + +user_settings_core_200::sptr user_settings_core_200::make(wb_iface::sptr iface, const size_t base){ + return sptr(new user_settings_core_200_impl(iface, base)); +} diff --git a/host/lib/usrp/cores/user_settings_core_200.hpp b/host/lib/usrp/cores/user_settings_core_200.hpp new file mode 100644 index 000000000..1f5d13de7 --- /dev/null +++ b/host/lib/usrp/cores/user_settings_core_200.hpp @@ -0,0 +1,36 @@ +// +// Copyright 2012 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 . +// + +#ifndef INCLUDED_LIBUHD_USRP_USER_SETTINGS_CORE_200_HPP +#define INCLUDED_LIBUHD_USRP_USER_SETTINGS_CORE_200_HPP + +#include +#include +#include +#include "wb_iface.hpp" + +class user_settings_core_200 : boost::noncopyable{ +public: + typedef boost::shared_ptr sptr; + typedef std::pair user_reg_t; + + static sptr make(wb_iface::sptr iface, const size_t base); + + virtual void set_reg(const user_reg_t ®) = 0; +}; + +#endif /* INCLUDED_LIBUHD_USRP_USER_SETTINGS_CORE_200_HPP */ diff --git a/host/lib/usrp/e100/e100_impl.cpp b/host/lib/usrp/e100/e100_impl.cpp index f58138ae6..cd6143a16 100644 --- a/host/lib/usrp/e100/e100_impl.cpp +++ b/host/lib/usrp/e100/e100_impl.cpp @@ -352,6 +352,13 @@ e100_impl::e100_impl(const uhd::device_addr_t &device_addr){ static const std::vector clock_sources = boost::assign::list_of("internal")("external")("auto"); _tree->create >(mb_path / "clock_source/options").set(clock_sources); + //////////////////////////////////////////////////////////////////// + // create user-defined control objects + //////////////////////////////////////////////////////////////////// + _user = user_settings_core_200::make(_fpga_ctrl, E100_REG_SR_ADDR(UE_SR_USER_REGS)); + _tree->create(mb_path / "user/regs") + .subscribe(boost::bind(&user_settings_core_200::set_reg, _user, _1)); + //////////////////////////////////////////////////////////////////// // create dboard control objects //////////////////////////////////////////////////////////////////// diff --git a/host/lib/usrp/e100/e100_impl.hpp b/host/lib/usrp/e100/e100_impl.hpp index f94061a24..e641aeea9 100644 --- a/host/lib/usrp/e100/e100_impl.hpp +++ b/host/lib/usrp/e100/e100_impl.hpp @@ -25,6 +25,7 @@ #include "rx_dsp_core_200.hpp" #include "tx_dsp_core_200.hpp" #include "time64_core_200.hpp" +#include "user_settings_core_200.hpp" #include #include #include @@ -92,6 +93,7 @@ private: std::vector _rx_dsps; tx_dsp_core_200::sptr _tx_dsp; time64_core_200::sptr _time64; + user_settings_core_200::sptr _user; e100_clock_ctrl::sptr _clock_ctrl; e100_codec_ctrl::sptr _codec_ctrl; e100_ctrl::sptr _fpga_ctrl; diff --git a/host/lib/usrp/e100/e100_regs.hpp b/host/lib/usrp/e100/e100_regs.hpp index f24f5895b..265086540 100644 --- a/host/lib/usrp/e100/e100_regs.hpp +++ b/host/lib/usrp/e100/e100_regs.hpp @@ -104,6 +104,7 @@ #define UE_SR_CLEAR_RX_FIFO 61 // 1 reg #define UE_SR_CLEAR_TX_FIFO 62 // 1 reg #define UE_SR_GLOBAL_RESET 63 // 1 reg +#define UE_SR_USER_REGS 64 // 2 regs #define UE_SR_GPIO 128 diff --git a/host/lib/usrp/multi_usrp.cpp b/host/lib/usrp/multi_usrp.cpp index 6cd9f95bb..d9be19b83 100644 --- a/host/lib/usrp/multi_usrp.cpp +++ b/host/lib/usrp/multi_usrp.cpp @@ -445,6 +445,17 @@ public: return _tree->list(mb_root(mboard) / "sensors"); } + void set_user_register(const boost::uint8_t addr, const boost::uint32_t data, size_t mboard){ + if (mboard != ALL_MBOARDS){ + typedef std::pair user_reg_t; + _tree->access(mb_root(mboard) / "user/reg").set(user_reg_t(addr, data)); + return; + } + for (size_t m = 0; m < get_num_mboards(); m++){ + set_user_register(addr, data, m); + } + } + /******************************************************************* * RX methods ******************************************************************/ diff --git a/host/lib/usrp/usrp2/usrp2_impl.cpp b/host/lib/usrp/usrp2/usrp2_impl.cpp index ef7151cee..206016972 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.cpp +++ b/host/lib/usrp/usrp2/usrp2_impl.cpp @@ -572,6 +572,13 @@ usrp2_impl::usrp2_impl(const device_addr_t &_device_addr){ static const std::vector clock_sources = boost::assign::list_of("internal")("external")("mimo"); _tree->create >(mb_path / "clock_source/options").set(clock_sources); + //////////////////////////////////////////////////////////////////// + // create user-defined control objects + //////////////////////////////////////////////////////////////////// + _mbc[mb].user = user_settings_core_200::make(_mbc[mb].iface, U2_REG_SR_ADDR(SR_USER_REGS)); + _tree->create(mb_path / "user/regs") + .subscribe(boost::bind(&user_settings_core_200::set_reg, _mbc[mb].user, _1)); + //////////////////////////////////////////////////////////////// // create dboard control objects //////////////////////////////////////////////////////////////// diff --git a/host/lib/usrp/usrp2/usrp2_impl.hpp b/host/lib/usrp/usrp2/usrp2_impl.hpp index 278dc713e..c060f75b5 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.hpp +++ b/host/lib/usrp/usrp2/usrp2_impl.hpp @@ -26,6 +26,7 @@ #include "rx_dsp_core_200.hpp" #include "tx_dsp_core_200.hpp" #include "time64_core_200.hpp" +#include "user_settings_core_200.hpp" #include #include #include @@ -91,6 +92,7 @@ private: std::vector > tx_streamers; tx_dsp_core_200::sptr tx_dsp; time64_core_200::sptr time64; + user_settings_core_200::sptr user; std::vector rx_dsp_xports; uhd::transport::zero_copy_if::sptr tx_dsp_xport; uhd::usrp::dboard_manager::sptr dboard_manager; diff --git a/host/lib/usrp/usrp2/usrp2_regs.hpp b/host/lib/usrp/usrp2/usrp2_regs.hpp index 179a930c6..8f714cbbc 100644 --- a/host/lib/usrp/usrp2/usrp2_regs.hpp +++ b/host/lib/usrp/usrp2/usrp2_regs.hpp @@ -39,7 +39,7 @@ #define SR_SIMTIMER 8 // 2 #define SR_TIME64 10 // 6 #define SR_BUF_POOL 16 // 4 - +#define SR_USER_REGS 20 // 2 #define SR_RX_FRONT 24 // 5 #define SR_RX_CTRL0 32 // 9 #define SR_RX_DSP0 48 // 7 -- cgit v1.2.3 From d46c176af34b728fd43b3dd46485b38623a7335e Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Mon, 30 Jan 2012 22:23:38 -0800 Subject: dsp rework: tx trailer, scaling work (peak) --- host/include/uhd/stream.hpp | 9 +++-- host/lib/convert/convert_common.hpp | 48 ++++++++++++++++++++++++ host/lib/convert/convert_with_tables.cpp | 21 ++++------- host/lib/convert/gen_convert_general.py | 16 ++++++++ host/lib/transport/gen_vrt_if_packet.py | 0 host/lib/transport/super_send_packet_handler.hpp | 2 +- host/lib/usrp/b100/io_impl.cpp | 1 + host/lib/usrp/cores/rx_dsp_core_200.cpp | 17 +++++---- host/lib/usrp/cores/tx_dsp_core_200.cpp | 25 +++++++++--- host/lib/usrp/e100/io_impl.cpp | 1 + host/lib/usrp/usrp2/io_impl.cpp | 1 + 11 files changed, 110 insertions(+), 31 deletions(-) mode change 100755 => 100644 host/lib/transport/gen_vrt_if_packet.py diff --git a/host/include/uhd/stream.hpp b/host/include/uhd/stream.hpp index 0c9282545..cec2eee79 100644 --- a/host/include/uhd/stream.hpp +++ b/host/include/uhd/stream.hpp @@ -79,10 +79,11 @@ struct UHD_API stream_args_t{ * The args parameter is used to pass arbitrary key/value pairs. * Possible keys used by args (depends on implementation): * - * - scalar: an integer scaling factor used with the sc8 wire format. - * Use scalar=1 to harvest the lower 8-bits. - * Use scalar=256 to harvest the upper 8-bits. - * Any scalar in-between is also a possibility. + * - peak: specifies a fractional sample level to calculate scaling with the sc8 wire format. + * When using sc8 samples over the wire, the device must scale samples + * (both on the host and in the device) to satisfy the dynamic range needs. + * The peak value specifies a fraction of the maximum sample level (1.0 = 100%). + * Set peak to max_sample_level/full_scale_level to ensure optimum dynamic range. * * - underflow_policy: how the TX DSP should recover from underflow. * Possible options are "next_burst" or "next_packet". diff --git a/host/lib/convert/convert_common.hpp b/host/lib/convert/convert_common.hpp index 699d6301b..aab59de4b 100644 --- a/host/lib/convert/convert_common.hpp +++ b/host/lib/convert/convert_common.hpp @@ -190,4 +190,52 @@ static UHD_INLINE void item32_sc8_to_fc64(item32_t item, fc64_t &out0, fc64_t &o ); } +/*********************************************************************** + * Convert complex char to items32 sc8 buffer + **********************************************************************/ +static UHD_INLINE item32_t sc8_to_item32_sc8(sc8_t in0, sc8_t in1, double){ + return + (item32_t(boost::uint8_t(in0.real())) << 8) | + (item32_t(boost::uint8_t(in0.imag())) << 0) | + (item32_t(boost::uint8_t(in1.real())) << 24) | + (item32_t(boost::uint8_t(in1.imag())) << 16) + ; +} + +/*********************************************************************** + * Convert complex short to items32 sc8 buffer + **********************************************************************/ +static UHD_INLINE item32_t sc16_to_item32_sc8(sc16_t in0, sc16_t in1, double){ + return + (item32_t(boost::uint8_t(in0.real())) << 8) | + (item32_t(boost::uint8_t(in0.imag())) << 0) | + (item32_t(boost::uint8_t(in1.real())) << 24) | + (item32_t(boost::uint8_t(in1.imag())) << 16) + ; +} + +/*********************************************************************** + * Convert complex float to items32 sc8 buffer + **********************************************************************/ +static UHD_INLINE item32_t fc32_to_item32_sc8(fc32_t in0, fc32_t in1, double scale_factor){ + return + (item32_t(boost::uint8_t(in0.real()*float(scale_factor))) << 8) | + (item32_t(boost::uint8_t(in0.imag()*float(scale_factor))) << 0) | + (item32_t(boost::uint8_t(in1.real()*float(scale_factor))) << 24) | + (item32_t(boost::uint8_t(in1.imag()*float(scale_factor))) << 16) + ; +} + +/*********************************************************************** + * Convert complex double to items32 sc8 buffer + **********************************************************************/ +static UHD_INLINE item32_t fc64_to_item32_sc8(fc64_t in0, fc64_t in1, double scale_factor){ + return + (item32_t(boost::uint8_t(in0.real()*(scale_factor))) << 8) | + (item32_t(boost::uint8_t(in0.imag()*(scale_factor))) << 0) | + (item32_t(boost::uint8_t(in1.real()*(scale_factor))) << 24) | + (item32_t(boost::uint8_t(in1.imag()*(scale_factor))) << 16) + ; +} + #endif /* INCLUDED_LIBUHD_CONVERT_COMMON_HPP */ diff --git a/host/lib/convert/convert_with_tables.cpp b/host/lib/convert/convert_with_tables.cpp index c033a2959..2379739a7 100644 --- a/host/lib/convert/convert_with_tables.cpp +++ b/host/lib/convert/convert_with_tables.cpp @@ -68,24 +68,19 @@ class convert_sc8_item32_1_to_fcxx_1 : public converter{ public: convert_sc8_item32_1_to_fcxx_1(void): _table(sc16_table_len){} - void set_scalar(const double scalar){ - - //special case, this is converts sc8 to sc16, - //use the scale-factor but no normalization + //special case for sc16 type, 32767 undoes float normalization + static type conv(const boost::int8_t &num, const double scalar){ if (sizeof(type) == sizeof(s16_t)){ - for (size_t i = 0; i < sc16_table_len; i++){ - const boost::uint16_t val = tohost(boost::uint16_t(i & 0xffff)); - const type real = type(boost::math::iround(boost::int8_t(val >> 8)*scalar*32767)); - const type imag = type(boost::math::iround(boost::int8_t(val >> 0)*scalar*32767)); - _table[i] = std::complex(real, imag); - } - return; + return type(boost::math::iround(num*scalar*32767)); } + return type(num*scalar); + } + void set_scalar(const double scalar){ for (size_t i = 0; i < sc16_table_len; i++){ const boost::uint16_t val = tohost(boost::uint16_t(i & 0xffff)); - const type real = type(boost::int8_t(val >> 8)*scalar); - const type imag = type(boost::int8_t(val >> 0)*scalar); + const type real = conv(boost::int8_t(val >> 8), scalar); + const type imag = conv(boost::int8_t(val >> 0), scalar); _table[i] = std::complex(real, imag); } } diff --git a/host/lib/convert/gen_convert_general.py b/host/lib/convert/gen_convert_general.py index b8d64aa4b..a6ae3f810 100644 --- a/host/lib/convert/gen_convert_general.py +++ b/host/lib/convert/gen_convert_general.py @@ -92,6 +92,22 @@ DECLARE_CONVERTER(sc8_item32_$(end), 1, $(cpu_type), 1, PRIORITY_GENERAL){ item32_sc8_to_$(cpu_type)(item_n, output[num_samps-1], dummy, scale_factor); } } + +DECLARE_CONVERTER($(cpu_type), 1, sc8_item32_$(end), 1, PRIORITY_GENERAL){ + const $(cpu_type)_t *input = reinterpret_cast(inputs[0]); + item32_t *output = reinterpret_cast(outputs[0]); + + const size_t num_pairs = nsamps/2; + for (size_t i = 0, j = 0; i < num_pairs; i++, j+=2){ + const item32_t item = $(cpu_type)_to_item32_sc8(input[j], input[j+1], scale_factor); + output[i] = $(to_wire)(item); + } + + if (nsamps != num_pairs*2){ + const item32_t item = $(cpu_type)_to_item32_sc8(input[nsamps-1], 0, scale_factor); + output[num_pairs] = $(to_wire)(item); + } +} """ TMPL_CONV_USRP1_COMPLEX = """ diff --git a/host/lib/transport/gen_vrt_if_packet.py b/host/lib/transport/gen_vrt_if_packet.py old mode 100755 new mode 100644 diff --git a/host/lib/transport/super_send_packet_handler.hpp b/host/lib/transport/super_send_packet_handler.hpp index 5ed8e0143..57304a7d4 100644 --- a/host/lib/transport/super_send_packet_handler.hpp +++ b/host/lib/transport/super_send_packet_handler.hpp @@ -134,7 +134,7 @@ public: vrt::if_packet_info_t if_packet_info; if_packet_info.has_sid = false; if_packet_info.has_cid = false; - if_packet_info.has_tlr = false; + if_packet_info.has_tlr = true; if_packet_info.has_tsi = metadata.has_time_spec; if_packet_info.has_tsf = metadata.has_time_spec; if_packet_info.tsi = boost::uint32_t(metadata.time_spec.get_full_secs()); diff --git a/host/lib/usrp/b100/io_impl.cpp b/host/lib/usrp/b100/io_impl.cpp index 6e9e017aa..9474268ef 100644 --- a/host/lib/usrp/b100/io_impl.cpp +++ b/host/lib/usrp/b100/io_impl.cpp @@ -263,6 +263,7 @@ tx_streamer::sptr b100_impl::get_tx_stream(const uhd::stream_args_t &args_){ //calculate packet size static const size_t hdr_size = 0 + vrt::max_if_hdr_words32*sizeof(boost::uint32_t) + + sizeof(vrt::if_packet_info_t().tlr) //forced to have trailer - sizeof(vrt::if_packet_info_t().cid) //no class id ever used ; static const size_t bpp = 2048 - hdr_size; diff --git a/host/lib/usrp/cores/rx_dsp_core_200.cpp b/host/lib/usrp/cores/rx_dsp_core_200.cpp index b2bf934bc..7b35daa42 100644 --- a/host/lib/usrp/cores/rx_dsp_core_200.cpp +++ b/host/lib/usrp/cores/rx_dsp_core_200.cpp @@ -63,8 +63,7 @@ public: { //init to something so update method has reasonable defaults _scaling_adjustment = 1.0; - _extra_scaling = 1.0; - _fxpt_scalar_correction = 1.0; + _dsp_extra_scaling = 1.0; //This is a hack/fix for the lingering packet problem. //The caller should also flush the recv transports @@ -187,14 +186,14 @@ public: } void update_scalar(void){ - const double target_scalar = (1 << 16)*_scaling_adjustment/_extra_scaling; + const double target_scalar = (1 << 16)*_scaling_adjustment/_dsp_extra_scaling; const boost::int32_t actual_scalar = boost::math::iround(target_scalar); _fxpt_scalar_correction = target_scalar/actual_scalar; //should be small _iface->poke32(REG_DSP_RX_SCALE_IQ, actual_scalar); } double get_scaling_adjustment(void){ - return _fxpt_scalar_correction*_extra_scaling/32767.; + return _fxpt_scalar_correction*_host_extra_scaling/32767.; } double set_freq(const double freq_){ @@ -230,11 +229,15 @@ public: unsigned format_word = 0; if (stream_args.otw_format == "sc16"){ format_word = 0; - _extra_scaling = 1.0; + _dsp_extra_scaling = 1.0; + _host_extra_scaling = 1.0; } else if (stream_args.otw_format == "sc8"){ format_word = (1 << 0); - _extra_scaling = stream_args.args.cast("scalar", 1.0); + double peak = stream_args.args.cast("peak", 1.0); + peak = std::max(peak, 1.0/256); + _host_extra_scaling = peak*256; + _dsp_extra_scaling = peak*256; } else throw uhd::value_error("USRP RX cannot handle requested wire format: " + stream_args.otw_format); @@ -248,7 +251,7 @@ private: const size_t _dsp_base, _ctrl_base; double _tick_rate, _link_rate; bool _continuous_streaming; - double _scaling_adjustment, _extra_scaling, _fxpt_scalar_correction; + double _scaling_adjustment, _dsp_extra_scaling, _host_extra_scaling, _fxpt_scalar_correction; const boost::uint32_t _sid; }; diff --git a/host/lib/usrp/cores/tx_dsp_core_200.cpp b/host/lib/usrp/cores/tx_dsp_core_200.cpp index 2c5b86bfc..15358e184 100644 --- a/host/lib/usrp/cores/tx_dsp_core_200.cpp +++ b/host/lib/usrp/cores/tx_dsp_core_200.cpp @@ -18,6 +18,7 @@ #include "tx_dsp_core_200.hpp" #include #include +#include #include #include #include @@ -35,6 +36,7 @@ #define REG_TX_CTRL_POLICY _ctrl_base + 12 #define REG_TX_CTRL_CYCLES_PER_UP _ctrl_base + 16 #define REG_TX_CTRL_PACKETS_PER_UP _ctrl_base + 20 +#define REG_TX_CTRL_FORMAT _ctrl_base + 24 #define FLAG_TX_CTRL_POLICY_WAIT (0x1 << 0) #define FLAG_TX_CTRL_POLICY_NEXT_PACKET (0x1 << 1) @@ -60,8 +62,7 @@ public: { //init to something so update method has reasonable defaults _scaling_adjustment = 1.0; - _extra_scaling = 1.0; - _fxpt_scalar_correction = 1.0; + _dsp_extra_scaling = 1.0; //init the tx control registers this->clear(); @@ -134,14 +135,14 @@ public: } void update_scalar(void){ - const double target_scalar = (1 << 17)*_scaling_adjustment/_extra_scaling; + const double target_scalar = (1 << 17)*_scaling_adjustment/_dsp_extra_scaling; const boost::int32_t actual_scalar = boost::math::iround(target_scalar); _fxpt_scalar_correction = target_scalar/actual_scalar; //should be small _iface->poke32(REG_DSP_TX_SCALE_IQ, actual_scalar); } double get_scaling_adjustment(void){ - return _fxpt_scalar_correction*_extra_scaling*32767.; + return _fxpt_scalar_correction*_host_extra_scaling*32767.; } double set_freq(const double freq_){ @@ -175,13 +176,25 @@ public: void setup(const uhd::stream_args_t &stream_args){ if (not stream_args.args.has_key("noclear")) this->clear(); + unsigned format_word = 0; if (stream_args.otw_format == "sc16"){ - _extra_scaling = 1.0; + format_word = 0; + _dsp_extra_scaling = 1.0; + _host_extra_scaling = 1.0; + } + else if (stream_args.otw_format == "sc8"){ + format_word = (1 << 0); + double peak = stream_args.args.cast("peak", 1.0); + peak = std::max(peak, 1.0/256); + _host_extra_scaling = 1.0/peak/256; + _dsp_extra_scaling = 1.0/peak; } else throw uhd::value_error("USRP TX cannot handle requested wire format: " + stream_args.otw_format); this->update_scalar(); + _iface->poke32(REG_TX_CTRL_FORMAT, format_word); + if (stream_args.args.has_key("underflow_policy")){ this->set_underflow_policy(stream_args.args["underflow_policy"]); } @@ -191,7 +204,7 @@ private: wb_iface::sptr _iface; const size_t _dsp_base, _ctrl_base; double _tick_rate, _link_rate; - double _scaling_adjustment, _extra_scaling, _fxpt_scalar_correction; + double _scaling_adjustment, _dsp_extra_scaling, _host_extra_scaling, _fxpt_scalar_correction; const boost::uint32_t _sid; }; diff --git a/host/lib/usrp/e100/io_impl.cpp b/host/lib/usrp/e100/io_impl.cpp index 89a4ed00b..53f783a3f 100644 --- a/host/lib/usrp/e100/io_impl.cpp +++ b/host/lib/usrp/e100/io_impl.cpp @@ -339,6 +339,7 @@ tx_streamer::sptr e100_impl::get_tx_stream(const uhd::stream_args_t &args_){ //calculate packet size static const size_t hdr_size = 0 + vrt::max_if_hdr_words32*sizeof(boost::uint32_t) + + sizeof(vrt::if_packet_info_t().tlr) //forced to have trailer - sizeof(vrt::if_packet_info_t().cid) //no class id ever used ; static const size_t bpp = _data_transport->get_send_frame_size() - hdr_size; diff --git a/host/lib/usrp/usrp2/io_impl.cpp b/host/lib/usrp/usrp2/io_impl.cpp index 58a5df2a5..6dcec6f1f 100644 --- a/host/lib/usrp/usrp2/io_impl.cpp +++ b/host/lib/usrp/usrp2/io_impl.cpp @@ -450,6 +450,7 @@ tx_streamer::sptr usrp2_impl::get_tx_stream(const uhd::stream_args_t &args_){ //calculate packet size static const size_t hdr_size = 0 + vrt::max_if_hdr_words32*sizeof(boost::uint32_t) + + sizeof(vrt::if_packet_info_t().tlr) //forced to have trailer + vrt_send_header_offset_words32*sizeof(boost::uint32_t) - sizeof(vrt::if_packet_info_t().cid) //no class id ever used ; -- cgit v1.2.3 From 7b69532aca8cc44017dedc1bfb07fa0d27b8ea6d Mon Sep 17 00:00:00 2001 From: Matt Ettus Date: Tue, 31 Jan 2012 17:22:12 -0800 Subject: dsp_rework: handle longer headers --- usrp2/sdr_lib/dspengine_8to16.v | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/usrp2/sdr_lib/dspengine_8to16.v b/usrp2/sdr_lib/dspengine_8to16.v index 7319451e5..ca808d2a6 100644 --- a/usrp2/sdr_lib/dspengine_8to16.v +++ b/usrp2/sdr_lib/dspengine_8to16.v @@ -146,7 +146,10 @@ module dspengine_8to16 write_adr <= write_adr - 1; odd <= 0; if(write_adr == (hdr_length_reg+HEADER_OFFSET)) - dsp_state <= DSP_WRITE_HEADER; + begin + write_adr <= HEADER_OFFSET; + dsp_state <= DSP_WRITE_HEADER; + end else if(odd) dsp_state <= DSP_READ; else @@ -157,7 +160,10 @@ module dspengine_8to16 begin write_adr <= write_adr - 1; if(write_adr == (hdr_length_reg+HEADER_OFFSET)) - dsp_state <= DSP_WRITE_HEADER; + begin + write_adr <= HEADER_OFFSET; + dsp_state <= DSP_WRITE_HEADER; + end else dsp_state <= DSP_READ; end -- cgit v1.2.3 From c407516349601831767952a9b12a077a2f23ea51 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Wed, 1 Feb 2012 09:47:07 -0800 Subject: dsp rework: paramaterize post_engine_buffering --- usrp2/top/N2x0/u2plus_core.v | 1 + usrp2/top/USRP2/u2_core.v | 1 + usrp2/vrt/vita_tx_chain.v | 18 ++++++++++++++---- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/usrp2/top/N2x0/u2plus_core.v b/usrp2/top/N2x0/u2plus_core.v index 0ee66d170..f04d449be 100644 --- a/usrp2/top/N2x0/u2plus_core.v +++ b/usrp2/top/N2x0/u2plus_core.v @@ -661,6 +661,7 @@ module u2plus_core wire strobe_tx; vita_tx_chain #(.BASE(SR_TX_CTRL), .FIFOSIZE(DSP_TX_FIFOSIZE), + .POST_ENGINE_FIFOSIZE(DSP_TX_FIFOSIZE+1), .REPORT_ERROR(1), .DO_FLOW_CONTROL(1), .PROT_ENG_FLAGS(1), .USE_TRANS_HEADER(1), .DSP_NUMBER(0)) diff --git a/usrp2/top/USRP2/u2_core.v b/usrp2/top/USRP2/u2_core.v index 746853fbf..d29f31b8f 100644 --- a/usrp2/top/USRP2/u2_core.v +++ b/usrp2/top/USRP2/u2_core.v @@ -647,6 +647,7 @@ module u2_core wire strobe_tx; vita_tx_chain #(.BASE(SR_TX_CTRL), .FIFOSIZE(DSP_TX_FIFOSIZE), + .POST_ENGINE_FIFOSIZE(DSP_TX_FIFOSIZE+1), .REPORT_ERROR(1), .DO_FLOW_CONTROL(1), .PROT_ENG_FLAGS(1), .USE_TRANS_HEADER(1), .DSP_NUMBER(0)) diff --git a/usrp2/vrt/vita_tx_chain.v b/usrp2/vrt/vita_tx_chain.v index 189876015..61df19097 100644 --- a/usrp2/vrt/vita_tx_chain.v +++ b/usrp2/vrt/vita_tx_chain.v @@ -19,6 +19,7 @@ module vita_tx_chain #(parameter BASE=0, parameter FIFOSIZE=10, + parameter POST_ENGINE_FIFOSIZE=0, parameter REPORT_ERROR=0, parameter DO_FLOW_CONTROL=0, parameter PROT_ENG_FLAGS=0, @@ -83,10 +84,19 @@ module vita_tx_chain .access_skip_read(access_skip_read), .access_adr(access_adr), .access_len(access_len), .access_dat_i(buf_to_dsp), .access_dat_o(dsp_to_buf)); - fifo_cascade #(.WIDTH(36), .SIZE(9)) post_engine_buffering( - .clk(clk), .reset(reset), .clear(clear), - .datain(tx_data_int1), .src_rdy_i(tx_src_rdy_int1), .dst_rdy_o(tx_dst_rdy_int1), - .dataout(tx_data_int2), .src_rdy_o(tx_src_rdy_int2), .dst_rdy_i(tx_dst_rdy_int2)); + generate + if (POST_ENGINE_FIFOSIZE==0) begin + assign tx_data_int2 = tx_data_int1; + assign tx_src_rdy_int2 = tx_src_rdy_int1; + assign tx_dst_rdy_int1 = tx_dst_rdy_int2; + end + else begin + fifo_cascade #(.WIDTH(36), .SIZE(POST_ENGINE_FIFOSIZE)) post_engine_buffering( + .clk(clk), .reset(reset), .clear(clear), + .datain(tx_data_int1), .src_rdy_i(tx_src_rdy_int1), .dst_rdy_o(tx_dst_rdy_int1), + .dataout(tx_data_int2), .src_rdy_o(tx_src_rdy_int2), .dst_rdy_i(tx_dst_rdy_int2)); + end + endgenerate vita_tx_deframer #(.BASE(BASE), .MAXCHAN(MAXCHAN), -- cgit v1.2.3 From d27125b9ab86e0d44db1317707aff7e9f9f8f32f Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Wed, 1 Feb 2012 09:48:28 -0800 Subject: dsp rework: account for no sid used in tx vita pkt --- host/lib/usrp/b100/io_impl.cpp | 1 + host/lib/usrp/e100/io_impl.cpp | 1 + host/lib/usrp/usrp2/io_impl.cpp | 3 ++- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/host/lib/usrp/b100/io_impl.cpp b/host/lib/usrp/b100/io_impl.cpp index 9474268ef..da3abada8 100644 --- a/host/lib/usrp/b100/io_impl.cpp +++ b/host/lib/usrp/b100/io_impl.cpp @@ -264,6 +264,7 @@ tx_streamer::sptr b100_impl::get_tx_stream(const uhd::stream_args_t &args_){ static const size_t hdr_size = 0 + vrt::max_if_hdr_words32*sizeof(boost::uint32_t) + sizeof(vrt::if_packet_info_t().tlr) //forced to have trailer + - sizeof(vrt::if_packet_info_t().sid) //no stream id ever used - sizeof(vrt::if_packet_info_t().cid) //no class id ever used ; static const size_t bpp = 2048 - hdr_size; diff --git a/host/lib/usrp/e100/io_impl.cpp b/host/lib/usrp/e100/io_impl.cpp index 53f783a3f..2b64e7f17 100644 --- a/host/lib/usrp/e100/io_impl.cpp +++ b/host/lib/usrp/e100/io_impl.cpp @@ -340,6 +340,7 @@ tx_streamer::sptr e100_impl::get_tx_stream(const uhd::stream_args_t &args_){ static const size_t hdr_size = 0 + vrt::max_if_hdr_words32*sizeof(boost::uint32_t) + sizeof(vrt::if_packet_info_t().tlr) //forced to have trailer + - sizeof(vrt::if_packet_info_t().sid) //no stream id ever used - sizeof(vrt::if_packet_info_t().cid) //no class id ever used ; static const size_t bpp = _data_transport->get_send_frame_size() - hdr_size; diff --git a/host/lib/usrp/usrp2/io_impl.cpp b/host/lib/usrp/usrp2/io_impl.cpp index 6dcec6f1f..9b6c1c2f0 100644 --- a/host/lib/usrp/usrp2/io_impl.cpp +++ b/host/lib/usrp/usrp2/io_impl.cpp @@ -449,10 +449,11 @@ tx_streamer::sptr usrp2_impl::get_tx_stream(const uhd::stream_args_t &args_){ //calculate packet size static const size_t hdr_size = 0 + + vrt_send_header_offset_words32*sizeof(boost::uint32_t) + vrt::max_if_hdr_words32*sizeof(boost::uint32_t) + sizeof(vrt::if_packet_info_t().tlr) //forced to have trailer - + vrt_send_header_offset_words32*sizeof(boost::uint32_t) - sizeof(vrt::if_packet_info_t().cid) //no class id ever used + - sizeof(vrt::if_packet_info_t().sid) //no stream id ever used ; const size_t bpp = _mbc[_mbc.keys().front()].tx_dsp_xport->get_send_frame_size() - hdr_size; const size_t spp = bpp/convert::get_bytes_per_item(args.otw_format); -- cgit v1.2.3 From 81b4689cf5a16b71c85b4a0f94746d61091fa29f Mon Sep 17 00:00:00 2001 From: Nick Foster Date: Thu, 12 Jan 2012 10:58:42 -0800 Subject: B100 host code changes to remove TX padding, remove RX padding, increase max allowed rate. --- host/lib/transport/usb_zero_copy_wrapper.cpp | 4 ++-- host/lib/usrp/b100/b100_impl.hpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/host/lib/transport/usb_zero_copy_wrapper.cpp b/host/lib/transport/usb_zero_copy_wrapper.cpp index 227c4b392..74f07f956 100644 --- a/host/lib/transport/usb_zero_copy_wrapper.cpp +++ b/host/lib/transport/usb_zero_copy_wrapper.cpp @@ -72,7 +72,7 @@ public: void commit(size_t len){ if (_msb.get() == NULL) return; - _msb->commit(next_boundary(len, _boundary)); + _msb->commit(len); _queue.push_with_haste(this); _msb.reset(); } @@ -133,7 +133,7 @@ public: managed_recv_buffer::sptr recv_buff; //the buffer to be returned to the user recv_buff = wmrb->get_new(_last_recv_buff, mem, len); - _last_recv_offset = next_boundary(_last_recv_offset + len, _usb_frame_boundary); + _last_recv_offset = next_boundary(_last_recv_offset + len, 4); //check if this receive buffer has been exhausted if (_last_recv_offset >= _last_recv_buff->size()) { diff --git a/host/lib/usrp/b100/b100_impl.hpp b/host/lib/usrp/b100/b100_impl.hpp index 5e7794fe8..ec86e41a2 100644 --- a/host/lib/usrp/b100/b100_impl.hpp +++ b/host/lib/usrp/b100/b100_impl.hpp @@ -44,7 +44,7 @@ #include #include -static const double B100_LINK_RATE_BPS = 256e6/8; //pratical link rate (< 480 Mbps) +static const double B100_LINK_RATE_BPS = 256e6/5; //pratical link rate (< 480 Mbps) static const std::string B100_FW_FILE_NAME = "usrp_b100_fw.ihx"; static const std::string B100_FPGA_FILE_NAME = "usrp_b100_fpga.bin"; static const boost::uint16_t B100_FW_COMPAT_NUM = 0x02; -- cgit v1.2.3 From 081714b4ce40701067e5513127dd9b9322cbfa5d Mon Sep 17 00:00:00 2001 From: Nick Foster Date: Thu, 12 Jan 2012 11:03:43 -0800 Subject: B100 firmware changes to allow slave mode TX/RX. --- firmware/fx2/b100/usrp_common.c | 17 +++-- firmware/fx2/b100/usrp_main.c | 159 +++++++++------------------------------- firmware/fx2/b100/usrp_regs.h | 28 ------- firmware/fx2/common/fx2regs.h | 17 ++++- 4 files changed, 59 insertions(+), 162 deletions(-) diff --git a/firmware/fx2/b100/usrp_common.c b/firmware/fx2/b100/usrp_common.c index 4b6dde881..7aedce9f7 100644 --- a/firmware/fx2/b100/usrp_common.c +++ b/firmware/fx2/b100/usrp_common.c @@ -32,12 +32,11 @@ init_usrp (void) CPUCS = bmCLKSPD1; // CPU runs @ 48 MHz CKCON = 0; // MOVX takes 2 cycles - // IFCLK is generated internally and runs at 48 MHz; GPIF "master mode" - - IFCONFIG = bmIFCLKSRC | bm3048MHZ | bmIFCLKOE | bmIFCLKPOL | bmIFGPIF; + // IFCLK is generated internally and runs at 48 MHz; slave FIFO mode + IFCONFIG = bmIFCLKSRC | bm3048MHZ | bmIFCLKOE | bmIFSLAVE; SYNCDELAY; - // configure IO ports (B and D are used by GPIF) + // configure IO ports (B and D are used by slave FIFO) IOA = bmPORT_A_INITIAL; // Port A initial state OEA = bmPORT_A_OUTPUTS; // Port A direction register @@ -77,23 +76,25 @@ init_usrp (void) EP2FIFOCFG = bmWORDWIDE; SYNCDELAY; EP2FIFOCFG = bmAUTOOUT | bmWORDWIDE; SYNCDELAY; - EP6FIFOCFG = bmZEROLENIN | bmWORDWIDE; SYNCDELAY; + EP6FIFOCFG = bmZEROLENIN | bmWORDWIDE; SYNCDELAY; + EP6FIFOCFG = bmZEROLENIN | bmAUTOIN | bmWORDWIDE; SYNCDELAY; //EP6FIFOCFG = bmWORDWIDE; SYNCDELAY; EP4FIFOCFG = bmWORDWIDE; SYNCDELAY; EP4FIFOCFG = bmAUTOOUT | bmWORDWIDE; SYNCDELAY; - EP8FIFOCFG = bmAUTOIN | bmWORDWIDE; SYNCDELAY; + EP8FIFOCFG = bmZEROLENIN | bmWORDWIDE; SYNCDELAY; + EP8FIFOCFG = bmZEROLENIN | bmAUTOIN | bmWORDWIDE; SYNCDELAY; EP0BCH = 0; SYNCDELAY; // arm EP1OUT so we can receive "out" packets (TRM pg 8-8) EP1OUTBC = 0; SYNCDELAY; - +/* EP2GPIFFLGSEL = 0x00; SYNCDELAY; // For EP2OUT, GPIF uses EF flag EP6GPIFFLGSEL = 0x00; SYNCDELAY; // For EP6IN, GPIF uses FF flag EP4GPIFFLGSEL = 0x00; SYNCDELAY; EP8GPIFFLGSEL = 0x00; SYNCDELAY; - +*/ // set autoin length for EP6 // FIXME should be f(enumeration) diff --git a/firmware/fx2/b100/usrp_main.c b/firmware/fx2/b100/usrp_main.c index 391a6d94f..45fa60ae9 100644 --- a/firmware/fx2/b100/usrp_main.c +++ b/firmware/fx2/b100/usrp_main.c @@ -21,7 +21,6 @@ #include "usrp_common.h" #include "usrp_commands.h" #include "fpga.h" -#include "usrp_gpif_inline.h" #include "timer.h" #include "i2c.h" #include "isr.h" @@ -64,7 +63,7 @@ bit enable_gpif = 0; #define USRP_HASH_SIZE 16 xdata at USRP_HASH_SLOT_1_ADDR unsigned char hash1[USRP_HASH_SIZE]; -void clear_fpga_data_fifo(void); +//void clear_fpga_data_fifo(void); static void get_ep0_data (void) @@ -175,12 +174,10 @@ app_vendor_cmd (void) break; case VRQ_ENABLE_GPIF: - enable_gpif = (wValueL != 0) ? 1 : 0; - set_led_1(enable_gpif); break; case VRQ_CLEAR_FPGA_FIFO: - clear_fpga_data_fifo(); + //clear_fpga_data_fifo(); break; default: @@ -194,125 +191,12 @@ app_vendor_cmd (void) return 1; } -static int short_pkt_state = 0; -#define SHORT_PACKET_DETECTED (short_pkt_state != bitSHORT_PACKET_SIGNAL) - -//yes, this is a little opaque -//basically this is necessary because while all the logic to inform the FPGA -//of what we're trying to do via the CTL pins is contained within the flowstates, -//we need to assert the endpoint select pin one clock cycle before the flowstate starts. -//this is the job of the wave descriptor. rather than switch between waves, since that -//involves a little more setup, we just modify the wave table on the fly. -inline static void setup_wave_data_read(void) { - GPIF_WAVE_DATA[80] = 0x06; - GPIF_WAVE_DATA[81] = 0x06; -} - -inline static void setup_wave_ctrl_read(void) { - GPIF_WAVE_DATA[80] = 0x0E; - GPIF_WAVE_DATA[81] = 0x0E; -} - -inline static void setup_wave_data_write(void) { - GPIF_WAVE_DATA[112] = 0x00; - GPIF_WAVE_DATA[113] = 0x00; -} - -inline static void setup_wave_ctrl_write(void) { - GPIF_WAVE_DATA[112] = 0x08; - GPIF_WAVE_DATA[113] = 0x08; -} - -inline static void handle_data_write(void) { - GPIFTCB1 = 0x01; //SYNCDELAY; - GPIFTCB0 = 0x00; - setup_flowstate_data_write (); - setup_wave_data_write(); - GPIFTRIG = bmGPIF_EP2_START | bmGPIF_WRITE; // start the xfer - SYNCDELAY; - while (!(GPIFTRIG & bmGPIF_IDLE)); -} - -inline static void handle_ctrl_write(void) { - GPIFTCB1 = 0x00; - GPIFTCB0 = 0x10; - setup_flowstate_ctrl_write (); - setup_wave_ctrl_write(); - GPIFTRIG = bmGPIF_EP4_START | bmGPIF_WRITE; // start the xfer - SYNCDELAY; - while (!(GPIFTRIG & bmGPIF_IDLE)); -} - -inline static void handle_data_read(void) { - GPIFTCB1 = 0x01; - GPIFTCB0 = 0x00; - setup_flowstate_data_read (); - setup_wave_data_read(); - short_pkt_state = bitSHORT_PACKET_SIGNAL; - GPIFTRIG = bmGPIF_EP6_START | bmGPIF_READ; // start the xfer - SYNCDELAY; - while (!(GPIFTRIG & bmGPIF_IDLE)); - INPKTEND = 0x06; // tell USB we filled buffer (6 is our endpoint num) - SYNCDELAY; - if(SHORT_PACKET_DETECTED) { - while(!(EP6CS & bmEPEMPTY)); //wait for packet to send - INPKTEND = 0x06; //send a ZLP - //toggle_led_1(); //FIXME DEBUG - } -} - -inline static void handle_ctrl_read(void) { - GPIFTCB1 = 0x00; - GPIFTCB0 = 0x10; - setup_flowstate_ctrl_read (); - setup_wave_ctrl_read(); - GPIFTRIG = bmGPIF_EP8_START | bmGPIF_READ; // start the xfer - SYNCDELAY; - while (!(GPIFTRIG & bmGPIF_IDLE)); - INPKTEND = 8; // tell USB we filled buffer (8 is our endpoint num) -} - -//clear the FPGA datapath by reading but not submitting, instead clearing the FIFO after each transaction -void clear_fpga_data_fifo(void) { - while(fpga_has_data_packet_avail()) { - GPIFTCB1 = 0x01; - GPIFTCB0 = 0x00; - setup_flowstate_data_read (); - setup_wave_data_read(); - GPIFTRIG = bmGPIF_EP6_START | bmGPIF_READ; // start the xfer - SYNCDELAY; - while (!(GPIFTRIG & bmGPIF_IDLE)); - initialize_gpif_buffer(6); //reset the FIFO instead of committing it - } -} - static void main_loop (void) { while (1){ if (usb_setup_packet_avail ()) usb_handle_setup_packet (); - - if(enable_gpif){ - if (fx2_has_ctrl_packet_avail() && fpga_has_room_for_ctrl_packet()) handle_ctrl_write(); - if (fx2_has_room_for_ctrl_packet() && fpga_has_ctrl_packet_avail()) handle_ctrl_read(); - - //we do this - if (fx2_has_data_packet_avail() && fpga_has_room_for_data_packet()) handle_data_write(); - if (fx2_has_room_for_data_packet() && fpga_has_data_packet_avail()) handle_data_read(); - //five times so that - if (fx2_has_data_packet_avail() && fpga_has_room_for_data_packet()) handle_data_write(); - if (fx2_has_room_for_data_packet() && fpga_has_data_packet_avail()) handle_data_read(); - //we can piggyback - if (fx2_has_data_packet_avail() && fpga_has_room_for_data_packet()) handle_data_write(); - if (fx2_has_room_for_data_packet() && fpga_has_data_packet_avail()) handle_data_read(); - //data transfers - if (fx2_has_data_packet_avail() && fpga_has_room_for_data_packet()) handle_data_write(); - if (fx2_has_room_for_data_packet() && fpga_has_data_packet_avail()) handle_data_read(); - //without loop overhead - if (fx2_has_data_packet_avail() && fpga_has_room_for_data_packet()) handle_data_write(); - if (fx2_has_room_for_data_packet() && fpga_has_data_packet_avail()) handle_data_read(); - } } } @@ -363,15 +247,9 @@ patch_usb_descriptors(void) void main (void) { - enable_gpif = 0; - memset (hash1, 0, USRP_HASH_SIZE); // zero fpga bitstream hash. This forces reload init_usrp (); - init_gpif (); - - // if (UC_START_WITH_GSTATE_OUTPUT_ENABLED) - //IFCONFIG |= bmGSTATE; // no conflict, start with it on set_led_0 (0); set_led_1 (0); @@ -389,6 +267,37 @@ main (void) fx2_renumerate (); // simulates disconnect / reconnect - setup_flowstate_common(); +// setup_flowstate_common(); + +//set up gpif slave mode here + //set slave FIFO mode + //set synchronous slave mode + ////both done in init_usrp() + + //set FLAGA, FLAGB, FLAGC, FLAGD to be EP2EF, EP4EF, EP6PF, EP8PF + PINFLAGSAB = (bmEP2EF) | (bmEP4EF << 4); + PINFLAGSCD = (bmEP6PF) | (bmEP8PF << 4); + + //ok as far as i can tell, DECIS is reversed compared to the FX2 TRM. + //p15.34 says DECIS high implements [assert when (fill > level)], observed opposite + + EP6FIFOPFH = 0x09; + SYNCDELAY; + EP6FIFOPFL = 0xFD; + SYNCDELAY; + +// EP2FIFOPFH = 0x08; +// SYNCDELAY; +// EP2FIFOPFL = 0x00; +// SYNCDELAY; + + //assert FIFOEMPTY one cycle sooner so we get it in time at the FPGA + EP2FIFOCFG |= bmBIT5; + + //set FIFOPINPOLAR to normal (active low) mode + FIFOPINPOLAR = 0x00; + SYNCDELAY; + PORTACFG = 0x80; + main_loop (); } diff --git a/firmware/fx2/b100/usrp_regs.h b/firmware/fx2/b100/usrp_regs.h index f6695d9f9..3d65337f5 100644 --- a/firmware/fx2/b100/usrp_regs.h +++ b/firmware/fx2/b100/usrp_regs.h @@ -41,8 +41,6 @@ #define bmALTERA_NCONFIG bmBIT1 #define bmALTERA_DATA0 bmBIT3 #define bmALTERA_NSTATUS bmBIT4 -#define bmRESET_FPGA_FIFOS bmBIT7 - #define bmALTERA_BITS (bmALTERA_DCLK \ | bmALTERA_NCONFIG \ @@ -64,7 +62,6 @@ sbit at PORT_A_ADDR+0 bitALTERA_DCLK; // 0x80 is the bit address of PORT A sbit at PORT_A_ADDR+1 bitALTERA_NCONFIG; sbit at PORT_A_ADDR+3 bitALTERA_DATA0; -sbit at PORT_A_ADDR+6 bitSHORT_PACKET_SIGNAL; sbit at PORT_C_ADDR+7 bitALTERA_CONF_DONE; @@ -102,29 +99,4 @@ sbit at PORT_C_ADDR+7 bitALTERA_CONF_DONE; #define bmPORT_E_OUTPUTS (0) #define bmPORT_E_INITIAL (0) -/* - * FPGA output lines that are tied to FX2 RDYx inputs. - * These are readable using GPIFREADYSTAT. - */ -//#define bmFPGA_HAS_SPACE bmBIT0 // usbrdy[0] has room for 512 byte packet -//#define bmFPGA_PKT_AVAIL bmBIT1 // usbrdy[1] has >= 512 bytes available - -#define bmDATA_EMPTY bmBIT0 //data output FIFO has no data ready -#define bmDATA_FIFO_FULL bmBIT1 //data input FIFO is full -#define bmCTRL_EMPTY bmBIT2 //control output FIFO has no data ready -#define bmCTRL_FIFO_FULL bmBIT3 //control input FIFO is full - -// #define bmTX_UNDERRUN bmBIT2 // usbrdy[2] D/A ran out of data -// #define bmRX_OVERRUN bmBIT3 // usbrdy[3] A/D ran out of buffer - -/* - * FPGA input lines that are tied to the FX2 CTLx outputs. - * - * These are controlled by the GPIF microprogram... - */ -// WE bmBIT0 // usbctl[0] write enable -// RE bmBIT1 // usbctl[1] read enable -// OE bmBIT2 // usbctl[2] output enable -// EP bmBIT3 // usbctl[3] endpoint select (data/ctrl) - #endif /* _USRP_REV1_REGS_H_ */ diff --git a/firmware/fx2/common/fx2regs.h b/firmware/fx2/common/fx2regs.h index aa44791d0..acbc0b89e 100644 --- a/firmware/fx2/common/fx2regs.h +++ b/firmware/fx2/common/fx2regs.h @@ -91,7 +91,6 @@ EXTERN xdata _AT_(0xE60A) volatile BYTE REVID ; // Chip Revision EXTERN xdata _AT_(0xE60B) volatile BYTE REVCTL ; // Chip Revision Control // Endpoint Configuration - EXTERN xdata _AT_(0xE610) volatile BYTE EP1OUTCFG ; // Endpoint 1-OUT Configuration EXTERN xdata _AT_(0xE611) volatile BYTE EP1INCFG ; // Endpoint 1-IN Configuration EXTERN xdata _AT_(0xE612) volatile BYTE EP2CFG ; // Endpoint 2 Configuration @@ -654,6 +653,22 @@ sfr at 0xF8 EIP; // EIP Bit Values differ from Reg320 #define bmIFCFG0 bmBIT0 #define bmIFCFGMASK (bmIFCFG0 | bmIFCFG1) #define bmIFGPIF bmIFCFG1 +#define bmIFSLAVE (bmIFCFG0 | bmIFCFG1) + +/* Slave FIFO pin flags configuration bits (PINFLAGS) */ +#define bmINDEXED 0x0 //which fifo selected by FIFOADR +#define bmEP2PF 0x4 +#define bmEP4PF 0x5 +#define bmEP6PF 0x6 +#define bmEP8PF 0x7 +#define bmEP2EF 0x8 +#define bmEP4EF 0x9 +#define bmEP6EF 0xA +#define bmEP8EF 0xB +#define bmEP2FF 0xC +#define bmEP4FF 0xD +#define bmEP6FF 0xE +#define bmEP8FF 0xF /* EP 2468 FIFO Configuration bits (EP2FIFOCFG,EP4FIFOCFG,EP6FIFOCFG,EP8FIFOCFG) */ #define bmINFM bmBIT6 -- cgit v1.2.3 From be14ffa819f2c88d24903d01a32eb85afc182a7d Mon Sep 17 00:00:00 2001 From: Nick Foster Date: Thu, 12 Jan 2012 11:43:40 -0800 Subject: B100: Modified TX send size to achieve 10.7Msps. --- host/lib/usrp/b100/io_impl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/host/lib/usrp/b100/io_impl.cpp b/host/lib/usrp/b100/io_impl.cpp index da3abada8..60c37bded 100644 --- a/host/lib/usrp/b100/io_impl.cpp +++ b/host/lib/usrp/b100/io_impl.cpp @@ -267,7 +267,7 @@ tx_streamer::sptr b100_impl::get_tx_stream(const uhd::stream_args_t &args_){ - sizeof(vrt::if_packet_info_t().sid) //no stream id ever used - sizeof(vrt::if_packet_info_t().cid) //no class id ever used ; - static const size_t bpp = 2048 - hdr_size; + static const size_t bpp = _data_transport->get_send_frame_size() - hdr_size; const size_t spp = bpp/convert::get_bytes_per_item(args.otw_format); //make the new streamer given the samples per packet -- cgit v1.2.3 From a0887f3bd37e840f5b8ccb894478213e5eae7ed1 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Thu, 12 Jan 2012 20:05:38 -0800 Subject: b100: bump compat numbers for slave fifo mode Conflicts: host/lib/usrp/b100/b100_impl.hpp --- firmware/fx2/b100/usrp_main.c | 2 +- host/lib/usrp/b100/b100_impl.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/firmware/fx2/b100/usrp_main.c b/firmware/fx2/b100/usrp_main.c index 45fa60ae9..fdc4fce48 100644 --- a/firmware/fx2/b100/usrp_main.c +++ b/firmware/fx2/b100/usrp_main.c @@ -111,7 +111,7 @@ app_vendor_cmd (void) case VRQ_FW_COMPAT: EP0BCH = 0; - EP0BCL = 2; + EP0BCL = 3; break; default: diff --git a/host/lib/usrp/b100/b100_impl.hpp b/host/lib/usrp/b100/b100_impl.hpp index ec86e41a2..433f45aef 100644 --- a/host/lib/usrp/b100/b100_impl.hpp +++ b/host/lib/usrp/b100/b100_impl.hpp @@ -47,7 +47,7 @@ static const double B100_LINK_RATE_BPS = 256e6/5; //pratical link rate (< 480 Mbps) static const std::string B100_FW_FILE_NAME = "usrp_b100_fw.ihx"; static const std::string B100_FPGA_FILE_NAME = "usrp_b100_fpga.bin"; -static const boost::uint16_t B100_FW_COMPAT_NUM = 0x02; +static const boost::uint16_t B100_FW_COMPAT_NUM = 0x03; static const boost::uint16_t B100_FPGA_COMPAT_NUM = 0x09; static const boost::uint32_t B100_RX_SID_BASE = 2; static const boost::uint32_t B100_TX_ASYNC_SID = 1; -- cgit v1.2.3 From 6bbcb202183c5a0ab5351a0c052981408e4719cb Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Wed, 1 Feb 2012 16:35:08 -0800 Subject: dsp rework: register the sample in vita tx ctrl --- usrp2/vrt/vita_tx_control.v | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/usrp2/vrt/vita_tx_control.v b/usrp2/vrt/vita_tx_control.v index 5df89bdbe..eaaf61815 100644 --- a/usrp2/vrt/vita_tx_control.v +++ b/usrp2/vrt/vita_tx_control.v @@ -187,8 +187,17 @@ module vita_tx_control assign sample_fifo_dst_rdy_o = (ibs_state == IBS_ERROR) | (strobe & (ibs_state == IBS_RUN)); // FIXME also cleanout - assign sample = (ibs_state == IBS_RUN) ? sample_fifo_i[5+64+16+WIDTH-1:5+64+16] : {WIDTH{1'b0}}; - //assign run = (ibs_state == IBS_RUN) | (ibs_state == IBS_CONT_BURST); + //register the output sample + reg [31:0] sample_held; + assign sample = sample_held; + always @(posedge clk) + if(reset | clear) + sample_held <= 0; + else if (~run) + sample_held <= 0; + else if (strobe) + sample_held <= sample_fifo_i[5+64+16+WIDTH-1:5+64+16]; + assign error = send_error; assign ack = send_ack; -- cgit v1.2.3 From 7e6a08556b01fcb6ad113c2ff0db4abe5aeac38f Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Wed, 1 Feb 2012 18:02:10 -0800 Subject: dsp rework: custom engine module for rx/tx vita chain --- usrp2/custom/Makefile.srcs | 2 + usrp2/custom/custom_dsp_rx.v | 58 ++++++---------------- usrp2/custom/custom_dsp_tx.v | 58 ++++++---------------- usrp2/custom/custom_engine_rx.v | 100 ++++++++++++++++++++++++++++++++++++++ usrp2/custom/custom_engine_tx.v | 104 ++++++++++++++++++++++++++++++++++++++++ usrp2/sdr_lib/ddc_chain.v | 3 +- usrp2/sdr_lib/duc_chain.v | 5 +- usrp2/top/B100/u1plus_core.v | 9 ++-- usrp2/top/E1x0/u1e_core.v | 7 ++- usrp2/top/N2x0/u2plus_core.v | 8 ++-- usrp2/top/USRP2/u2_core.v | 8 ++-- usrp2/vrt/vita_rx_chain.v | 11 +++-- usrp2/vrt/vita_tx_chain.v | 59 +++++++++++------------ 13 files changed, 294 insertions(+), 138 deletions(-) create mode 100644 usrp2/custom/custom_engine_rx.v create mode 100644 usrp2/custom/custom_engine_tx.v diff --git a/usrp2/custom/Makefile.srcs b/usrp2/custom/Makefile.srcs index 22cf063c9..8a4f70fca 100644 --- a/usrp2/custom/Makefile.srcs +++ b/usrp2/custom/Makefile.srcs @@ -8,4 +8,6 @@ CUSTOM_SRCS = $(abspath $(addprefix $(BASE_DIR)/../custom/, \ custom_dsp_rx.v \ custom_dsp_tx.v \ +custom_engine_rx.v \ +custom_engine_tx.v \ )) diff --git a/usrp2/custom/custom_dsp_rx.v b/usrp2/custom/custom_dsp_rx.v index 64f966c31..73294566e 100644 --- a/usrp2/custom/custom_dsp_rx.v +++ b/usrp2/custom/custom_dsp_rx.v @@ -31,23 +31,29 @@ module custom_dsp_rx #( + //the dsp unit number: 0, 1, 2... parameter DSPNO = 0, - parameter ADCW = 24 + + //frontend bus width + parameter WIDTH = 24 ) ( //control signals input clock, input reset, input enable, - //settings bus - input set_stb, input [7:0] set_addr, input [31:0] set_data, + //main settings bus for built-in modules + input set_stb_main, input [7:0] set_addr_main, input [31:0] set_data_main, + + //user settings bus, controlled through user setting regs API + input set_stb_user, input [7:0] set_addr_user, input [31:0] set_data_user, //full rate inputs directly from the RX frontend - input [ADCW-1:0] frontend_i, - input [ADCW-1:0] frontend_q, + input [WIDTH-1:0] frontend_i, + input [WIDTH-1:0] frontend_q, //full rate outputs directly to the DDC chain - output [ADCW-1:0] ddc_in_i, - output [ADCW-1:0] ddc_in_q, + output [WIDTH-1:0] ddc_in_i, + output [WIDTH-1:0] ddc_in_q, //strobed samples {I16,Q16} from the RX DDC chain input [31:0] ddc_out_sample, @@ -80,7 +86,7 @@ module custom_dsp_rx ); `endif end - if (DSPNO==1) begin + else begin `ifndef RX_DSP1_MODULE assign ddc_in_i = frontend_i; assign ddc_in_q = frontend_q; @@ -98,42 +104,6 @@ module custom_dsp_rx ); `endif end - if (DSPNO==2) begin - `ifndef RX_DSP2_MODULE - assign ddc_in_i = frontend_i; - assign ddc_in_q = frontend_q; - assign bb_sample = ddc_out_sample; - assign bb_strobe = ddc_out_strobe; - `else - RX_DSP2_CUSTOM_MODULE_NAME rx_dsp2_custom - ( - .clock(clock), .reset(reset), .enable(enable), - .set_stb(set_stb), .set_addr(set_addr), .set_data(set_data), - .frontend_i(frontend_i), .frontend_q(frontend_q), - .ddc_in_i(ddc_in_i), .ddc_in_q(ddc_in_q), - .ddc_out_sample(ddc_out_sample), .ddc_out_strobe(ddc_out_strobe), - .bb_sample(bb_sample), .bb_strobe(bb_strobe) - ); - `endif - end - else begin - `ifndef RX_DSP3_MODULE - assign ddc_in_i = frontend_i; - assign ddc_in_q = frontend_q; - assign bb_sample = ddc_out_sample; - assign bb_strobe = ddc_out_strobe; - `else - RX_DSP3_CUSTOM_MODULE_NAME rx_dsp3_custom - ( - .clock(clock), .reset(reset), .enable(enable), - .set_stb(set_stb), .set_addr(set_addr), .set_data(set_data), - .frontend_i(frontend_i), .frontend_q(frontend_q), - .ddc_in_i(ddc_in_i), .ddc_in_q(ddc_in_q), - .ddc_out_sample(ddc_out_sample), .ddc_out_strobe(ddc_out_strobe), - .bb_sample(bb_sample), .bb_strobe(bb_strobe) - ); - `endif - end endgenerate endmodule //custom_dsp_rx diff --git a/usrp2/custom/custom_dsp_tx.v b/usrp2/custom/custom_dsp_tx.v index 102805139..cb0d7522b 100644 --- a/usrp2/custom/custom_dsp_tx.v +++ b/usrp2/custom/custom_dsp_tx.v @@ -31,23 +31,29 @@ module custom_dsp_tx #( + //the dsp unit number: 0, 1, 2... parameter DSPNO = 0, - parameter ADCW = 24 + + //frontend bus width + parameter WIDTH = 24 ) ( //control signals input clock, input reset, input enable, - //settings bus - input set_stb, input [7:0] set_addr, input [31:0] set_data, + //main settings bus for built-in modules + input set_stb_main, input [7:0] set_addr_main, input [31:0] set_data_main, + + //user settings bus, controlled through user setting regs API + input set_stb_user, input [7:0] set_addr_user, input [31:0] set_data_user, //full rate outputs directly to the TX frontend - output [ADCW-1:0] frontend_i, - output [ADCW-1:0] frontend_q, + output [WIDTH-1:0] frontend_i, + output [WIDTH-1:0] frontend_q, //full rate outputs directly from the DUC chain - input [ADCW-1:0] duc_out_i, - input [ADCW-1:0] duc_out_q, + input [WIDTH-1:0] duc_out_i, + input [WIDTH-1:0] duc_out_q, //strobed samples {I16,Q16} to the TX DUC chain output [31:0] duc_in_sample, @@ -80,7 +86,7 @@ module custom_dsp_tx ); `endif end - if (DSPNO==1) begin + else begin `ifndef TX_DSP1_MODULE assign frontend_i = duc_out_i; assign frontend_q = duc_out_q; @@ -98,42 +104,6 @@ module custom_dsp_tx ); `endif end - if (DSPNO==2) begin - `ifndef TX_DSP2_MODULE - assign frontend_i = duc_out_i; - assign frontend_q = duc_out_q; - assign duc_in_sample = bb_sample; - assign bb_strobe = duc_in_strobe; - `else - TX_DSP2_CUSTOM_MODULE_NAME tx_dsp2_custom - ( - .clock(clock), .reset(reset), .enable(enable), - .set_stb(set_stb), .set_addr(set_addr), .set_data(set_data), - .frontend_i(frontend_i), .frontend_q(frontend_q), - .duc_out_i(duc_out_i), .duc_out_q(duc_out_q), - .duc_in_sample(duc_in_sample), .duc_in_strobe(duc_in_strobe), - .bb_sample(bb_sample), .bb_strobe(bb_strobe) - ); - `endif - end - else begin - `ifndef TX_DSP3_MODULE - assign frontend_i = duc_out_i; - assign frontend_q = duc_out_q; - assign duc_in_sample = bb_sample; - assign bb_strobe = duc_in_strobe; - `else - TX_DSP3_CUSTOM_MODULE_NAME tx_dsp3_custom - ( - .clock(clock), .reset(reset), .enable(enable), - .set_stb(set_stb), .set_addr(set_addr), .set_data(set_data), - .frontend_i(frontend_i), .frontend_q(frontend_q), - .duc_out_i(duc_out_i), .duc_out_q(duc_out_q), - .duc_in_sample(duc_in_sample), .duc_in_strobe(duc_in_strobe), - .bb_sample(bb_sample), .bb_strobe(bb_strobe) - ); - `endif - end endgenerate endmodule //custom_dsp_tx diff --git a/usrp2/custom/custom_engine_rx.v b/usrp2/custom/custom_engine_rx.v new file mode 100644 index 000000000..48276665f --- /dev/null +++ b/usrp2/custom/custom_engine_rx.v @@ -0,0 +1,100 @@ +// +// Copyright 2012 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 . +// + +//CUSTOMIZE ME! + +//The following module is used to re-write receive packets to the host. +//This module provides a packet-based ram interface for manipulating packets. +//The user writes a custom engine (state machine) to read the input packet, +//and to produce a new output packet. For users customizing the DSP operation, +//your customizations may be better suited for the custom_dsp_rx module. +//By default, this module uses the built-in 16 to 8 bit converter engine. + +module custom_engine_rx +#( + //the dsp unit number: 0, 1, 2... + parameter DSPNO = 0, + + //buffer size for ram interface engine + parameter BUF_SIZE = 10, + + //base address for built-in settings registers used in this module + parameter MAIN_SETTINGS_BASE = 0 +) +( + //control signals + input clock, input reset, input clear, + + //main settings bus for built-in modules + input set_stb_main, input [7:0] set_addr_main, input [31:0] set_data_main, + + //user settings bus, controlled through user setting regs API + input set_stb_user, input [7:0] set_addr_user, input [31:0] set_data_user, + + //ram interface for engine + output access_we, + output access_stb, + input access_ok, + output access_done, + output access_skip_read, + output [BUF_SIZE-1:0] access_adr, + input [BUF_SIZE-1:0] access_len, + output [35:0] access_dat_o, + input [35:0] access_dat_i, + + //debug output (optional) + output [31:0] debug +); + + generate + if (DSPNO==0) begin + `ifndef RX_ENG0_MODULE + dspengine_16to8 #(.BASE(MAIN_SETTINGS_BASE), .BUF_SIZE(BUF_SIZE)) dspengine_16to8 + (.clk(clock),.reset(reset),.clear(clear), + .set_stb(set_stb_main), .set_addr(set_addr_main), .set_data(set_data_main), + .access_we(access_we), .access_stb(access_stb), .access_ok(access_ok), .access_done(access_done), + .access_skip_read(access_skip_read), .access_adr(access_adr), .access_len(access_len), + .access_dat_i(access_dat_i), .access_dat_o(access_dat_o)); + `else + RX_ENG0_MODULE #(.BUF_SIZE(BUF_SIZE)) rx_eng0_custom + (.clock(clock),.reset(reset),.clear(clear), + .set_stb(set_stb_user), .set_addr(set_addr_user), .set_data(set_data_user), + .access_we(access_we), .access_stb(access_stb), .access_ok(access_ok), .access_done(access_done), + .access_skip_read(access_skip_read), .access_adr(access_adr), .access_len(access_len), + .access_dat_i(access_dat_i), .access_dat_o(access_dat_o)); + `endif + end + else begin + `ifndef RX_ENG1_MODULE + dspengine_16to8 #(.BASE(MAIN_SETTINGS_BASE), .BUF_SIZE(BUF_SIZE)) dspengine_16to8 + (.clk(clock),.reset(reset),.clear(clear), + .set_stb(set_stb_main), .set_addr(set_addr_main), .set_data(set_data_main), + .access_we(access_we), .access_stb(access_stb), .access_ok(access_ok), .access_done(access_done), + .access_skip_read(access_skip_read), .access_adr(access_adr), .access_len(access_len), + .access_dat_i(access_dat_i), .access_dat_o(access_dat_o)); + `else + RX_ENG1_MODULE #(.BUF_SIZE(BUF_SIZE)) rx_eng1_custom + (.clock(clock),.reset(reset),.clear(clear), + .set_stb(set_stb_user), .set_addr(set_addr_user), .set_data(set_data_user), + .access_we(access_we), .access_stb(access_stb), .access_ok(access_ok), .access_done(access_done), + .access_skip_read(access_skip_read), .access_adr(access_adr), .access_len(access_len), + .access_dat_i(access_dat_i), .access_dat_o(access_dat_o)); + `endif + end + endgenerate + +endmodule //custom_engine_rx diff --git a/usrp2/custom/custom_engine_tx.v b/usrp2/custom/custom_engine_tx.v new file mode 100644 index 000000000..6227b0f45 --- /dev/null +++ b/usrp2/custom/custom_engine_tx.v @@ -0,0 +1,104 @@ +// +// Copyright 2012 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 . +// + +//CUSTOMIZE ME! + +//The following module is used to re-write transmit packets from the host. +//This module provides a packet-based ram interface for manipulating packets. +//The user writes a custom engine (state machine) to read the input packet, +//and to produce a new output packet. For users customizing the DSP operation, +//your customizations may be better suited for the custom_dsp_tx module. +//By default, this module uses the built-in 8 to 16 bit converter engine. + +module custom_engine_tx +#( + //the dsp unit number: 0, 1, 2... + parameter DSPNO = 0, + + //buffer size for ram interface engine + parameter BUF_SIZE = 10, + + //base address for built-in settings registers used in this module + parameter MAIN_SETTINGS_BASE = 0, + + //the number of 32bit lines between start of buffer and vita header + //the metadata before the header should be preserved by the engine + parameter HEADER_OFFSET = 0 +) +( + //control signals + input clock, input reset, input clear, + + //main settings bus for built-in modules + input set_stb_main, input [7:0] set_addr_main, input [31:0] set_data_main, + + //user settings bus, controlled through user setting regs API + input set_stb_user, input [7:0] set_addr_user, input [31:0] set_data_user, + + //ram interface for engine + output access_we, + output access_stb, + input access_ok, + output access_done, + output access_skip_read, + output [BUF_SIZE-1:0] access_adr, + input [BUF_SIZE-1:0] access_len, + output [35:0] access_dat_o, + input [35:0] access_dat_i, + + //debug output (optional) + output [31:0] debug +); + + generate + if (DSPNO==0) begin + `ifndef TX_ENG0_MODULE + dspengine_8to16 #(.BASE(MAIN_SETTINGS_BASE), .BUF_SIZE(BUF_SIZE), .HEADER_OFFSET(HEADER_OFFSET)) dspengine_8to16 + (.clk(clock),.reset(reset),.clear(clear), + .set_stb(set_stb_main), .set_addr(set_addr_main), .set_data(set_data_main), + .access_we(access_we), .access_stb(access_stb), .access_ok(access_ok), .access_done(access_done), + .access_skip_read(access_skip_read), .access_adr(access_adr), .access_len(access_len), + .access_dat_i(access_dat_i), .access_dat_o(access_dat_o)); + `else + TX_ENG0_MODULE #(.BUF_SIZE(BUF_SIZE)) tx_eng0_custom + (.clock(clock),.reset(reset),.clear(clear), + .set_stb(set_stb_user), .set_addr(set_addr_user), .set_data(set_data_user), + .access_we(access_we), .access_stb(access_stb), .access_ok(access_ok), .access_done(access_done), + .access_skip_read(access_skip_read), .access_adr(access_adr), .access_len(access_len), + .access_dat_i(access_dat_i), .access_dat_o(access_dat_o)); + `endif + end + else begin + `ifndef TX_ENG1_MODULE + dspengine_8to16 #(.BASE(MAIN_SETTINGS_BASE), .BUF_SIZE(BUF_SIZE), .HEADER_OFFSET(HEADER_OFFSET)) dspengine_8to16 + (.clk(clock),.reset(reset),.clear(clear), + .set_stb(set_stb_main), .set_addr(set_addr_main), .set_data(set_data_main), + .access_we(access_we), .access_stb(access_stb), .access_ok(access_ok), .access_done(access_done), + .access_skip_read(access_skip_read), .access_adr(access_adr), .access_len(access_len), + .access_dat_i(access_dat_i), .access_dat_o(access_dat_o)); + `else + TX_ENG1_MODULE #(.BUF_SIZE(BUF_SIZE)) tx_eng1_custom + (.clock(clock),.reset(reset),.clear(clear), + .set_stb(set_stb_user), .set_addr(set_addr_user), .set_data(set_data_user), + .access_we(access_we), .access_stb(access_stb), .access_ok(access_ok), .access_done(access_done), + .access_skip_read(access_skip_read), .access_adr(access_adr), .access_len(access_len), + .access_dat_i(access_dat_i), .access_dat_o(access_dat_o)); + `endif + end + endgenerate + +endmodule //custom_engine_tx diff --git a/usrp2/sdr_lib/ddc_chain.v b/usrp2/sdr_lib/ddc_chain.v index 7de0e6ae6..270da45db 100644 --- a/usrp2/sdr_lib/ddc_chain.v +++ b/usrp2/sdr_lib/ddc_chain.v @@ -167,7 +167,8 @@ module ddc_chain custom_dsp_rx #(.DSPNO(DSPNO)) custom( .clock(clk), .reset(rst), .enable(run), - .set_stb(set_stb_user), .set_addr(set_addr_user), .set_data(set_data_user), + .set_stb_main(set_stb), .set_addr_main(set_addr), .set_data_main(set_data), + .set_stb_user(set_stb_user), .set_addr_user(set_addr_user), .set_data_user(set_data_user), .frontend_i(rx_fe_i_mux), .frontend_q(rx_fe_q_mux), .ddc_in_i(to_cordic_i), .ddc_in_q(to_cordic_q), .ddc_out_sample(ddc_chain_out), .ddc_out_strobe(ddc_chain_stb), diff --git a/usrp2/sdr_lib/duc_chain.v b/usrp2/sdr_lib/duc_chain.v index b5033d05a..d9ede6bc2 100644 --- a/usrp2/sdr_lib/duc_chain.v +++ b/usrp2/sdr_lib/duc_chain.v @@ -118,8 +118,6 @@ module duc_chain .strobe_in(strobe_cic),.strobe_out(1), .signal_in(hb2_q),.signal_out(q_interp)); - assign strobe = strobe_hb1; - localparam cwidth = 24; // was 18 localparam zwidth = 24; // was 16 @@ -151,7 +149,8 @@ module duc_chain custom_dsp_tx #(.DSPNO(DSPNO)) custom( .clock(clk), .reset(rst), .enable(run), - .set_stb(set_stb_user), .set_addr(set_addr_user), .set_data(set_data_user), + .set_stb_main(set_stb), .set_addr_main(set_addr), .set_data_main(set_data), + .set_stb_user(set_stb_user), .set_addr_user(set_addr_user), .set_data_user(set_data_user), .frontend_i(tx_fe_i), .frontend_q(tx_fe_q), .duc_out_i(prod_i[33:10]), .duc_out_q(prod_q[33:10]), .duc_in_sample({bb_i, bb_q}), .duc_in_strobe(strobe_hb1), diff --git a/usrp2/top/B100/u1plus_core.v b/usrp2/top/B100/u1plus_core.v index 1981123bc..4c3acaa27 100644 --- a/usrp2/top/B100/u1plus_core.v +++ b/usrp2/top/B100/u1plus_core.v @@ -169,9 +169,10 @@ module u1plus_core .sample(sample_rx0), .run(run_rx0), .strobe(strobe_rx0), .debug() ); - vita_rx_chain #(.BASE(SR_RX_CTRL0), .UNIT(0), .FIFOSIZE(10), .PROT_ENG_FLAGS(0)) vita_rx_chain0 + vita_rx_chain #(.BASE(SR_RX_CTRL0), .UNIT(0), .FIFOSIZE(10), .PROT_ENG_FLAGS(0), .DSP_NUMBER(0)) vita_rx_chain0 (.clk(wb_clk),.reset(wb_rst), .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data), + .set_stb_user(set_stb_user), .set_addr_user(set_addr_user), .set_data_user(set_data_user), .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), @@ -193,9 +194,10 @@ module u1plus_core .sample(sample_rx1), .run(run_rx1), .strobe(strobe_rx1), .debug() ); - vita_rx_chain #(.BASE(SR_RX_CTRL1), .UNIT(1), .FIFOSIZE(10), .PROT_ENG_FLAGS(0)) vita_rx_chain1 + vita_rx_chain #(.BASE(SR_RX_CTRL1), .UNIT(1), .FIFOSIZE(10), .PROT_ENG_FLAGS(0), .DSP_NUMBER(1)) vita_rx_chain1 (.clk(wb_clk),.reset(wb_rst), .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data), + .set_stb_user(set_stb_user), .set_addr_user(set_addr_user), .set_data_user(set_data_user), .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), @@ -218,13 +220,14 @@ module u1plus_core wire [31:0] sample_tx; wire strobe_tx; - vita_tx_chain #(.BASE(SR_TX_CTRL), .FIFOSIZE(10), + vita_tx_chain #(.BASE(SR_TX_CTRL), .FIFOSIZE(0/*no engine*/), .REPORT_ERROR(1), .DO_FLOW_CONTROL(0), .PROT_ENG_FLAGS(0), .USE_TRANS_HEADER(0), .DSP_NUMBER(0)) vita_tx_chain (.clk(wb_clk), .reset(wb_rst), .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data), + .set_stb_user(set_stb_user), .set_addr_user(set_addr_user), .set_data_user(set_data_user), .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), diff --git a/usrp2/top/E1x0/u1e_core.v b/usrp2/top/E1x0/u1e_core.v index d3495707d..5f2edca1a 100644 --- a/usrp2/top/E1x0/u1e_core.v +++ b/usrp2/top/E1x0/u1e_core.v @@ -169,9 +169,10 @@ module u1e_core .sample(sample_rx0), .run(run_rx0), .strobe(strobe_rx0), .debug() ); - vita_rx_chain #(.BASE(SR_RX_CTRL0), .UNIT(0), .FIFOSIZE(10), .PROT_ENG_FLAGS(0)) vita_rx_chain0 + vita_rx_chain #(.BASE(SR_RX_CTRL0), .UNIT(0), .FIFOSIZE(10), .PROT_ENG_FLAGS(0), .DSP_NUMBER(0)) vita_rx_chain0 (.clk(wb_clk),.reset(wb_rst), .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data), + .set_stb_user(set_stb_user), .set_addr_user(set_addr_user), .set_data_user(set_data_user), .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), @@ -193,9 +194,10 @@ module u1e_core .sample(sample_rx1), .run(run_rx1), .strobe(strobe_rx1), .debug() ); - vita_rx_chain #(.BASE(SR_RX_CTRL1), .UNIT(1), .FIFOSIZE(10), .PROT_ENG_FLAGS(0)) vita_rx_chain1 + vita_rx_chain #(.BASE(SR_RX_CTRL1), .UNIT(1), .FIFOSIZE(10), .PROT_ENG_FLAGS(0), .DSP_NUMBER(1)) vita_rx_chain1 (.clk(wb_clk),.reset(wb_rst), .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data), + .set_stb_user(set_stb_user), .set_addr_user(set_addr_user), .set_data_user(set_data_user), .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), @@ -225,6 +227,7 @@ module u1e_core vita_tx_chain (.clk(wb_clk), .reset(wb_rst), .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data), + .set_stb_user(set_stb_user), .set_addr_user(set_addr_user), .set_data_user(set_data_user), .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), diff --git a/usrp2/top/N2x0/u2plus_core.v b/usrp2/top/N2x0/u2plus_core.v index f04d449be..8b804bb0c 100644 --- a/usrp2/top/N2x0/u2plus_core.v +++ b/usrp2/top/N2x0/u2plus_core.v @@ -591,9 +591,10 @@ module u2plus_core .sample(sample_rx0), .run(run_rx0_d1), .strobe(strobe_rx0), .debug() ); - vita_rx_chain #(.BASE(SR_RX_CTRL0),.UNIT(0),.FIFOSIZE(DSP_RX_FIFOSIZE)) vita_rx_chain0 + vita_rx_chain #(.BASE(SR_RX_CTRL0),.UNIT(0),.FIFOSIZE(DSP_RX_FIFOSIZE), .DSP_NUMBER(0)) vita_rx_chain0 (.clk(dsp_clk), .reset(dsp_rst), .set_stb(set_stb_dsp),.set_addr(set_addr_dsp),.set_data(set_data_dsp), + .set_stb_user(set_stb_user), .set_addr_user(set_addr_user), .set_data_user(set_data_user), .vita_time(vita_time), .overrun(overrun0), .sample(sample_rx0), .run(run_rx0), .strobe(strobe_rx0), .rx_data_o(wr1_dat), .rx_src_rdy_o(wr1_ready_i), .rx_dst_rdy_i(wr1_ready_o), @@ -615,9 +616,10 @@ module u2plus_core .sample(sample_rx1), .run(run_rx1_d1), .strobe(strobe_rx1), .debug() ); - vita_rx_chain #(.BASE(SR_RX_CTRL1),.UNIT(2),.FIFOSIZE(DSP_RX_FIFOSIZE)) vita_rx_chain1 + vita_rx_chain #(.BASE(SR_RX_CTRL1),.UNIT(2),.FIFOSIZE(DSP_RX_FIFOSIZE), .DSP_NUMBER(1)) vita_rx_chain1 (.clk(dsp_clk), .reset(dsp_rst), .set_stb(set_stb_dsp),.set_addr(set_addr_dsp),.set_data(set_data_dsp), + .set_stb_user(set_stb_user), .set_addr_user(set_addr_user), .set_data_user(set_data_user), .vita_time(vita_time), .overrun(overrun1), .sample(sample_rx1), .run(run_rx1), .strobe(strobe_rx1), .rx_data_o(wr3_dat), .rx_src_rdy_o(wr3_ready_i), .rx_dst_rdy_i(wr3_ready_o), @@ -661,13 +663,13 @@ module u2plus_core wire strobe_tx; vita_tx_chain #(.BASE(SR_TX_CTRL), .FIFOSIZE(DSP_TX_FIFOSIZE), - .POST_ENGINE_FIFOSIZE(DSP_TX_FIFOSIZE+1), .REPORT_ERROR(1), .DO_FLOW_CONTROL(1), .PROT_ENG_FLAGS(1), .USE_TRANS_HEADER(1), .DSP_NUMBER(0)) vita_tx_chain (.clk(dsp_clk), .reset(dsp_rst), .set_stb(set_stb_dsp),.set_addr(set_addr_dsp),.set_data(set_data_dsp), + .set_stb_user(set_stb_user), .set_addr_user(set_addr_user), .set_data_user(set_data_user), .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), diff --git a/usrp2/top/USRP2/u2_core.v b/usrp2/top/USRP2/u2_core.v index d29f31b8f..4b2276e4a 100644 --- a/usrp2/top/USRP2/u2_core.v +++ b/usrp2/top/USRP2/u2_core.v @@ -579,9 +579,10 @@ module u2_core .sample(sample_rx0), .run(run_rx0_d1), .strobe(strobe_rx0), .debug() ); - vita_rx_chain #(.BASE(SR_RX_CTRL0),.UNIT(0),.FIFOSIZE(DSP_RX_FIFOSIZE)) vita_rx_chain0 + vita_rx_chain #(.BASE(SR_RX_CTRL0),.UNIT(0),.FIFOSIZE(DSP_RX_FIFOSIZE), .DSP_NUMBER(0)) vita_rx_chain0 (.clk(dsp_clk), .reset(dsp_rst), .set_stb(set_stb_dsp),.set_addr(set_addr_dsp),.set_data(set_data_dsp), + .set_stb_user(set_stb_user), .set_addr_user(set_addr_user), .set_data_user(set_data_user), .vita_time(vita_time), .overrun(overrun0), .sample(sample_rx0), .run(run_rx0), .strobe(strobe_rx0), .rx_data_o(wr1_dat), .rx_src_rdy_o(wr1_ready_i), .rx_dst_rdy_i(wr1_ready_o), @@ -603,9 +604,10 @@ module u2_core .sample(sample_rx1), .run(run_rx1_d1), .strobe(strobe_rx1), .debug() ); - vita_rx_chain #(.BASE(SR_RX_CTRL1),.UNIT(2),.FIFOSIZE(DSP_RX_FIFOSIZE)) vita_rx_chain1 + vita_rx_chain #(.BASE(SR_RX_CTRL1),.UNIT(2),.FIFOSIZE(DSP_RX_FIFOSIZE), .DSP_NUMBER(1)) vita_rx_chain1 (.clk(dsp_clk), .reset(dsp_rst), .set_stb(set_stb_dsp),.set_addr(set_addr_dsp),.set_data(set_data_dsp), + .set_stb_user(set_stb_user), .set_addr_user(set_addr_user), .set_data_user(set_data_user), .vita_time(vita_time), .overrun(overrun1), .sample(sample_rx1), .run(run_rx1), .strobe(strobe_rx1), .rx_data_o(wr3_dat), .rx_src_rdy_o(wr3_ready_i), .rx_dst_rdy_i(wr3_ready_o), @@ -647,13 +649,13 @@ module u2_core wire strobe_tx; vita_tx_chain #(.BASE(SR_TX_CTRL), .FIFOSIZE(DSP_TX_FIFOSIZE), - .POST_ENGINE_FIFOSIZE(DSP_TX_FIFOSIZE+1), .REPORT_ERROR(1), .DO_FLOW_CONTROL(1), .PROT_ENG_FLAGS(1), .USE_TRANS_HEADER(1), .DSP_NUMBER(0)) vita_tx_chain (.clk(dsp_clk), .reset(dsp_rst), .set_stb(set_stb_dsp),.set_addr(set_addr_dsp),.set_data(set_data_dsp), + .set_stb_user(set_stb_user), .set_addr_user(set_addr_user), .set_data_user(set_data_user), .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), diff --git a/usrp2/vrt/vita_rx_chain.v b/usrp2/vrt/vita_rx_chain.v index 150da31c9..bd416f563 100644 --- a/usrp2/vrt/vita_rx_chain.v +++ b/usrp2/vrt/vita_rx_chain.v @@ -20,9 +20,11 @@ module vita_rx_chain #(parameter BASE=0, parameter UNIT=0, parameter FIFOSIZE=10, - parameter PROT_ENG_FLAGS=1) + parameter PROT_ENG_FLAGS=1, + parameter DSP_NUMBER=0) (input clk, input reset, input set_stb, input [7:0] set_addr, input [31:0] set_data, + input set_stb_user, input [7:0] set_addr_user, input [31:0] set_data_user, input [63:0] vita_time, input [31:0] sample, input strobe, output [35:0] rx_data_o, output rx_src_rdy_o, input rx_dst_rdy_i, @@ -72,9 +74,10 @@ module vita_rx_chain .data_i(rx_data_int), .src_rdy_i(rx_src_rdy_int), .dst_rdy_o(rx_dst_rdy_int), .data_o(rx_data_int2), .src_rdy_o(rx_src_rdy_int2), .dst_rdy_i(rx_dst_rdy_int2)); - dspengine_16to8 #(.BASE(BASE+9), .BUF_SIZE(FIFOSIZE)) dspengine_16to8 - (.clk(clk),.reset(reset),.clear(clear), - .set_stb(set_stb), .set_addr(set_addr), .set_data(set_data), + custom_engine_rx #(.DSPNO(DSP_NUMBER), .MAIN_SETTINGS_BASE(BASE+9), .BUF_SIZE(FIFOSIZE)) dspengine_rx + (.clock(clk),.reset(reset),.clear(clear), + .set_stb_main(set_stb), .set_addr_main(set_addr), .set_data_main(set_data), + .set_stb_user(set_stb_user), .set_addr_user(set_addr_user), .set_data_user(set_data_user), .access_we(access_we), .access_stb(access_stb), .access_ok(access_ok), .access_done(access_done), .access_skip_read(access_skip_read), .access_adr(access_adr), .access_len(access_len), .access_dat_i(buf_to_dsp), .access_dat_o(dsp_to_buf)); diff --git a/usrp2/vrt/vita_tx_chain.v b/usrp2/vrt/vita_tx_chain.v index 61df19097..78f63b555 100644 --- a/usrp2/vrt/vita_tx_chain.v +++ b/usrp2/vrt/vita_tx_chain.v @@ -19,7 +19,6 @@ module vita_tx_chain #(parameter BASE=0, parameter FIFOSIZE=10, - parameter POST_ENGINE_FIFOSIZE=0, parameter REPORT_ERROR=0, parameter DO_FLOW_CONTROL=0, parameter PROT_ENG_FLAGS=0, @@ -27,6 +26,7 @@ module vita_tx_chain parameter DSP_NUMBER=0) (input clk, input reset, input set_stb, input [7:0] set_addr, input [31:0] set_data, + input set_stb_user, input [7:0] set_addr_user, input [31:0] set_data_user, 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, @@ -62,39 +62,36 @@ module vita_tx_chain (.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr), .in(set_data),.out(streamid),.changed(clear_seqnum)); - wire [FIFOSIZE-1:0] access_adr, access_len; - wire access_we, access_stb, access_ok, access_done, access_skip_read; - wire [35:0] dsp_to_buf, buf_to_dsp; - wire [35:0] tx_data_int1, tx_data_int2; - wire tx_src_rdy_int1, tx_dst_rdy_int1, tx_src_rdy_int2, tx_dst_rdy_int2; - - double_buffer #(.BUF_SIZE(FIFOSIZE)) db - (.clk(clk),.reset(reset),.clear(clear), - .access_we(access_we), .access_stb(access_stb), .access_ok(access_ok), .access_done(access_done), - .access_skip_read(access_skip_read), .access_adr(access_adr), .access_len(access_len), - .access_dat_i(dsp_to_buf), .access_dat_o(buf_to_dsp), - - .data_i(tx_data_i), .src_rdy_i(tx_src_rdy_i), .dst_rdy_o(tx_dst_rdy_o), - .data_o(tx_data_int1), .src_rdy_o(tx_src_rdy_int1), .dst_rdy_i(tx_dst_rdy_int1)); - - dspengine_8to16 #(.BASE(BASE+6), .BUF_SIZE(FIFOSIZE), .HEADER_OFFSET(USE_TRANS_HEADER)) dspengine_8to16 - (.clk(clk),.reset(reset),.clear(clear), - .set_stb(set_stb), .set_addr(set_addr), .set_data(set_data), - .access_we(access_we), .access_stb(access_stb), .access_ok(access_ok), .access_done(access_done), - .access_skip_read(access_skip_read), .access_adr(access_adr), .access_len(access_len), - .access_dat_i(buf_to_dsp), .access_dat_o(dsp_to_buf)); + wire [35:0] tx_data_int1; + wire tx_src_rdy_int1, tx_dst_rdy_int1; generate - if (POST_ENGINE_FIFOSIZE==0) begin - assign tx_data_int2 = tx_data_int1; - assign tx_src_rdy_int2 = tx_src_rdy_int1; - assign tx_dst_rdy_int1 = tx_dst_rdy_int2; + if (FIFOSIZE==0) begin + assign tx_data_int1 = tx_data_i; + assign tx_src_rdy_int1 = tx_src_rdy_i; + assign tx_dst_rdy_o = tx_dst_rdy_int1; end else begin - fifo_cascade #(.WIDTH(36), .SIZE(POST_ENGINE_FIFOSIZE)) post_engine_buffering( - .clk(clk), .reset(reset), .clear(clear), - .datain(tx_data_int1), .src_rdy_i(tx_src_rdy_int1), .dst_rdy_o(tx_dst_rdy_int1), - .dataout(tx_data_int2), .src_rdy_o(tx_src_rdy_int2), .dst_rdy_i(tx_dst_rdy_int2)); + wire [FIFOSIZE-1:0] access_adr, access_len; + wire access_we, access_stb, access_ok, access_done, access_skip_read; + wire [35:0] dsp_to_buf, buf_to_dsp; + + double_buffer #(.BUF_SIZE(FIFOSIZE)) db + (.clk(clk),.reset(reset),.clear(clear), + .access_we(access_we), .access_stb(access_stb), .access_ok(access_ok), .access_done(access_done), + .access_skip_read(access_skip_read), .access_adr(access_adr), .access_len(access_len), + .access_dat_i(dsp_to_buf), .access_dat_o(buf_to_dsp), + + .data_i(tx_data_i), .src_rdy_i(tx_src_rdy_i), .dst_rdy_o(tx_dst_rdy_o), + .data_o(tx_data_int1), .src_rdy_o(tx_src_rdy_int1), .dst_rdy_i(tx_dst_rdy_int1)); + + custom_engine_tx #(.DSPNO(DSP_NUMBER), .MAIN_SETTINGS_BASE(BASE+6), .BUF_SIZE(FIFOSIZE), .HEADER_OFFSET(USE_TRANS_HEADER)) dspengine_tx + (.clock(clk),.reset(reset),.clear(clear), + .set_stb_main(set_stb), .set_addr_main(set_addr), .set_data_main(set_data), + .set_stb_user(set_stb_user), .set_addr_user(set_addr_user), .set_data_user(set_data_user), + .access_we(access_we), .access_stb(access_stb), .access_ok(access_ok), .access_done(access_done), + .access_skip_read(access_skip_read), .access_adr(access_adr), .access_len(access_len), + .access_dat_i(buf_to_dsp), .access_dat_o(dsp_to_buf)); end endgenerate @@ -104,7 +101,7 @@ module vita_tx_chain vita_tx_deframer (.clk(clk), .reset(reset), .clear(clear), .clear_seqnum(clear_seqnum), .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data), - .data_i(tx_data_int2), .src_rdy_i(tx_src_rdy_int2), .dst_rdy_o(tx_dst_rdy_int2), + .data_i(tx_data_int1), .src_rdy_i(tx_src_rdy_int1), .dst_rdy_o(tx_dst_rdy_int1), .sample_fifo_o(tx1_data), .sample_fifo_src_rdy_o(tx1_src_rdy), .sample_fifo_dst_rdy_i(tx1_dst_rdy), .current_seqnum(current_seqnum), .debug(debug_vtd) ); -- cgit v1.2.3 From 5e972e7446edb79f8ed582970b2dff40a93919ae Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Wed, 1 Feb 2012 18:02:59 -0800 Subject: b100: sc8 mode not implemented error --- host/lib/usrp/b100/io_impl.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/host/lib/usrp/b100/io_impl.cpp b/host/lib/usrp/b100/io_impl.cpp index 60c37bded..7c07c6349 100644 --- a/host/lib/usrp/b100/io_impl.cpp +++ b/host/lib/usrp/b100/io_impl.cpp @@ -260,6 +260,10 @@ tx_streamer::sptr b100_impl::get_tx_stream(const uhd::stream_args_t &args_){ args.otw_format = args.otw_format.empty()? "sc16" : args.otw_format; args.channels = args.channels.empty()? std::vector(1, 0) : args.channels; + if (args.otw_format == "sc8"){ + throw uhd::value_error("USRP TX requested wire format not implemented in FPGA: " + args.otw_format); + } + //calculate packet size static const size_t hdr_size = 0 + vrt::max_if_hdr_words32*sizeof(boost::uint32_t) -- cgit v1.2.3 From 17f5776c9cac89516a82b1e8f84f8a2dcc1a16ad Mon Sep 17 00:00:00 2001 From: Matt Ettus Date: Thu, 2 Feb 2012 11:00:52 -0800 Subject: dsp_rework: testbench enhancements --- usrp2/control_lib/double_buffer_tb.v | 45 +++++++++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 11 deletions(-) diff --git a/usrp2/control_lib/double_buffer_tb.v b/usrp2/control_lib/double_buffer_tb.v index a9d1e0b29..804e8804d 100644 --- a/usrp2/control_lib/double_buffer_tb.v +++ b/usrp2/control_lib/double_buffer_tb.v @@ -27,7 +27,7 @@ module double_buffer_tb(); reg src_rdy_i = 0; wire dst_rdy_o; - wire dst_rdy_i = 1; + wire dst_rdy_i = 0; wire [35:0] data_o; reg [35:0] data_i; @@ -46,7 +46,7 @@ module double_buffer_tb(); .data_i(data_i), .src_rdy_i(src_rdy_i), .dst_rdy_o(dst_rdy_o), .data_o(data_o), .src_rdy_o(src_rdy_o), .dst_rdy_i(dst_rdy_i)); - dspengine_8to16 dspengine_8to16 + dspengine_8to16 #(.HEADER_OFFSET(1)) dspengine_8to16 (.clk(clk),.reset(rst),.clear(0), .set_stb(set_stb), .set_addr(0), .set_data(1), .access_we(access_we), .access_stb(access_stb), .access_ok(access_ok), .access_done(access_done), @@ -168,6 +168,7 @@ module double_buffer_tb(); while(~dst_rdy_o) @(posedge clk); */ + /* $display("No StreamID, Trailer, Even"); src_rdy_i <= 1; data_i <= { 2'b00,1'b0,1'b1,32'hCCCCCCCC}; @@ -189,7 +190,7 @@ module double_buffer_tb(); @(posedge clk); src_rdy_i <= 0; @(posedge clk); - +*/ while(~dst_rdy_o) @(posedge clk); /* @@ -262,27 +263,49 @@ module double_buffer_tb(); while(~dst_rdy_o) @(posedge clk); - +*/ $display("StreamID, Trailer, Odd"); src_rdy_i <= 1; - data_i <= { 2'b00,1'b0,1'b1,32'h1400FFFF}; + data_i <= { 2'b00,1'b0,1'b1,32'hABCDEF98}; + @(posedge clk); + data_i <= { 2'b00,1'b0,1'b0,32'h1c034567}; + @(posedge clk); + data_i <= { 2'b00,1'b0,1'b0,32'ha0a1a2a3}; + @(posedge clk); + data_i <= { 2'b00,1'b0,1'b0,32'ha4a5a6a7}; +// src_rdy_i <= 0; +// @(posedge clk); +// src_rdy_i <= 1; @(posedge clk); - data_i <= { 2'b00,1'b0,1'b0,32'ha100a200}; + data_i <= { 2'b00,1'b0,1'b0,32'ha8a9aaab}; + @(posedge clk); + data_i <= { 2'b00,1'b0,1'b0,32'hacadaeaf}; + @(posedge clk); + data_i <= { 2'b00,1'b1,1'b0,32'hdeadbeef}; @(posedge clk); - data_i <= { 2'b00,1'b0,1'b0,32'ha300a400}; src_rdy_i <= 0; @(posedge clk); src_rdy_i <= 1; + data_i <= { 2'b00,1'b0,1'b1,32'hABCDEF98}; + @(posedge clk); + data_i <= { 2'b00,1'b0,1'b0,32'h1c034567}; + @(posedge clk); + data_i <= { 2'b00,1'b0,1'b0,32'ha0a1a2a3}; @(posedge clk); - data_i <= { 2'b00,1'b0,1'b0,32'ha500a600}; + data_i <= { 2'b00,1'b0,1'b0,32'ha4a5a6a7}; +// src_rdy_i <= 0; +// @(posedge clk); +// src_rdy_i <= 1; @(posedge clk); - data_i <= { 2'b00,1'b0,1'b0,32'ha700a800}; + data_i <= { 2'b00,1'b0,1'b0,32'ha8a9aaab}; @(posedge clk); - data_i <= { 2'b00,1'b1,1'b0,32'hbbb0bbb0}; + data_i <= { 2'b00,1'b0,1'b0,32'hacadaeaf}; + @(posedge clk); + data_i <= { 2'b00,1'b1,1'b0,32'hdeadbeef}; @(posedge clk); src_rdy_i <= 0; @(posedge clk); -*/ + end initial #28000 $finish; -- cgit v1.2.3 From b7ff81c9a8316bb0310d9291afe722c48b441f29 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Thu, 2 Feb 2012 15:15:54 -0800 Subject: dsp rework: work on usb wrapper for smaller packets, large luts --- host/lib/transport/libusb1_zero_copy.cpp | 17 +++-- host/lib/transport/usb_zero_copy_wrapper.cpp | 100 +++++++++++++-------------- host/lib/usrp/b100/b100_impl.cpp | 5 +- host/lib/usrp/b100/b100_impl.hpp | 3 +- host/lib/usrp/b100/b100_regs.hpp | 17 ++++- host/lib/usrp/b100/io_impl.cpp | 10 +-- host/lib/usrp/e100/e100_impl.cpp | 2 +- host/lib/usrp/e100/e100_impl.hpp | 2 +- host/lib/usrp/e100/e100_regs.hpp | 17 ++++- host/lib/usrp/e100/io_impl.cpp | 2 +- host/lib/usrp/usrp1/io_impl.cpp | 2 +- host/lib/usrp/usrp2/io_impl.cpp | 2 +- host/lib/usrp/usrp2/usrp2_impl.cpp | 2 +- host/lib/usrp/usrp2/usrp2_impl.hpp | 2 +- host/lib/usrp/usrp2/usrp2_regs.hpp | 2 +- 15 files changed, 105 insertions(+), 80 deletions(-) diff --git a/host/lib/transport/libusb1_zero_copy.cpp b/host/lib/transport/libusb1_zero_copy.cpp index 28d6cdd5b..3e67264cd 100644 --- a/host/lib/transport/libusb1_zero_copy.cpp +++ b/host/lib/transport/libusb1_zero_copy.cpp @@ -80,13 +80,14 @@ UHD_INLINE bool wait_for_completion(libusb_context *ctx, const double timeout, b **********************************************************************/ class libusb_zero_copy_mrb : public managed_recv_buffer{ public: - libusb_zero_copy_mrb(libusb_transfer *lut): + libusb_zero_copy_mrb(libusb_transfer *lut, const size_t frame_size): _ctx(libusb::session::get_global_session()->get_context()), - _lut(lut), _expired(false) { /* NOP */ } + _lut(lut), _expired(false), _frame_size(frame_size) { /* NOP */ } void release(void){ if (_expired) return; completed = false; + _lut->length = _frame_size; //always reset length UHD_ASSERT_THROW(libusb_submit_transfer(_lut) == 0); _expired = true; } @@ -109,6 +110,7 @@ private: libusb_context *_ctx; libusb_transfer *_lut; bool _expired; + const size_t _frame_size; }; /*********************************************************************** @@ -118,9 +120,9 @@ private: **********************************************************************/ class libusb_zero_copy_msb : public managed_send_buffer{ public: - libusb_zero_copy_msb(libusb_transfer *lut): + libusb_zero_copy_msb(libusb_transfer *lut, const size_t frame_size): _ctx(libusb::session::get_global_session()->get_context()), - _lut(lut), _expired(false) { /* NOP */ } + _lut(lut), _expired(false), _frame_size(frame_size) { /* NOP */ } void commit(size_t len){ if (_expired) return; @@ -144,11 +146,12 @@ public: private: void *get_buff(void) const{return _lut->buffer;} - size_t get_size(void) const{return _lut->length;} + size_t get_size(void) const{return _frame_size;} libusb_context *_ctx; libusb_transfer *_lut; bool _expired; + const size_t _frame_size; }; /*********************************************************************** @@ -184,7 +187,7 @@ public: libusb_transfer *lut = libusb_alloc_transfer(0); UHD_ASSERT_THROW(lut != NULL); - _mrb_pool.push_back(boost::shared_ptr(new libusb_zero_copy_mrb(lut))); + _mrb_pool.push_back(boost::shared_ptr(new libusb_zero_copy_mrb(lut, this->get_recv_frame_size()))); libusb_fill_bulk_transfer( lut, // transfer @@ -207,7 +210,7 @@ public: libusb_transfer *lut = libusb_alloc_transfer(0); UHD_ASSERT_THROW(lut != NULL); - _msb_pool.push_back(boost::shared_ptr(new libusb_zero_copy_msb(lut))); + _msb_pool.push_back(boost::shared_ptr(new libusb_zero_copy_msb(lut, this->get_send_frame_size()))); libusb_fill_bulk_transfer( lut, // transfer diff --git a/host/lib/transport/usb_zero_copy_wrapper.cpp b/host/lib/transport/usb_zero_copy_wrapper.cpp index 74f07f956..07105cad3 100644 --- a/host/lib/transport/usb_zero_copy_wrapper.cpp +++ b/host/lib/transport/usb_zero_copy_wrapper.cpp @@ -1,5 +1,5 @@ // -// Copyright 2011 Ettus Research LLC +// Copyright 2011-2012 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 @@ -18,17 +18,13 @@ #include #include #include +#include +#include #include #include #include using namespace uhd::transport; -bool debug = true; - -static inline size_t next_boundary(size_t length, size_t boundary){ - //pad to the boundary, assumes boundary is a power of 2 - return (length + (boundary-1)) & ~(boundary-1); -} /*********************************************************************** * USB zero copy wrapper - managed receive buffer @@ -45,7 +41,7 @@ public: _mrb.reset(); } - sptr get_new(managed_recv_buffer::sptr mrb, const void *mem, size_t len){ + UHD_INLINE sptr get_new(managed_recv_buffer::sptr mrb, const void *mem, size_t len){ _mrb = mrb; _mem = mem; _len = len; @@ -67,28 +63,46 @@ private: **********************************************************************/ class usb_zero_copy_wrapper_msb : public managed_send_buffer{ public: - usb_zero_copy_wrapper_msb(bounded_buffer &queue, size_t boundary): - _queue(queue), _boundary(boundary){/*NOP*/} + usb_zero_copy_wrapper_msb(const usb_zero_copy::sptr internal, const size_t fragmentation_size): + _internal(internal), _fragmentation_size(fragmentation_size){/*NOP*/} void commit(size_t len){ - if (_msb.get() == NULL) return; - _msb->commit(len); - _queue.push_with_haste(this); - _msb.reset(); + if (len == 0) return; + + //get a reference to the VITA header before incrementing + const boost::uint32_t vita_header = reinterpret_cast(_mem_buffer_tip)[0]; + + _bytes_in_buffer += len; + _mem_buffer_tip += len; + + //extract VITA end of packet flag, we must force flush under eof conditions + const bool eop = (uhd::wtohx(vita_header) & (0x1 << 24)) != 0; + const bool full = _bytes_in_buffer >= (_last_send_buff->size() - _fragmentation_size); + if (eop or full){ + _last_send_buff->commit(_bytes_in_buffer); + _last_send_buff.reset(); + } } - sptr get_new(managed_send_buffer::sptr msb){ - _msb = msb; + UHD_INLINE sptr get_new(const double timeout){ + if (not _last_send_buff){ + _last_send_buff = _internal->get_send_buff(timeout); + if (not _last_send_buff) return sptr(); + _mem_buffer_tip = _last_send_buff->cast(); + _bytes_in_buffer = 0; + } return make_managed_buffer(this); } private: - void *get_buff(void) const{return _msb->cast();} - size_t get_size(void) const{return _msb->size();} - - bounded_buffer &_queue; - size_t _boundary; - managed_send_buffer::sptr _msb; + void *get_buff(void) const{return reinterpret_cast(_mem_buffer_tip);} + size_t get_size(void) const{return _fragmentation_size;} + + usb_zero_copy::sptr _internal; + const size_t _fragmentation_size; + managed_send_buffer::sptr _last_send_buff; + size_t _bytes_in_buffer; + char *_mem_buffer_tip; }; /*********************************************************************** @@ -96,23 +110,15 @@ private: **********************************************************************/ class usb_zero_copy_wrapper : public usb_zero_copy{ public: - usb_zero_copy_wrapper( - sptr usb_zc, size_t usb_frame_boundary - ): + usb_zero_copy_wrapper(sptr usb_zc, const size_t frame_boundary): _internal_zc(usb_zc), - _usb_frame_boundary(usb_frame_boundary), _available_recv_buffs(this->get_num_recv_frames()), - _available_send_buffs(this->get_num_send_frames()), _mrb_pool(this->get_num_recv_frames(), usb_zero_copy_wrapper_mrb(_available_recv_buffs)), - _msb_pool(this->get_num_send_frames(), usb_zero_copy_wrapper_msb(_available_send_buffs, usb_frame_boundary)) + _the_only_msb(usb_zero_copy_wrapper_msb(usb_zc, frame_boundary)) { BOOST_FOREACH(usb_zero_copy_wrapper_mrb &mrb, _mrb_pool){ _available_recv_buffs.push_with_haste(&mrb); } - - BOOST_FOREACH(usb_zero_copy_wrapper_msb &msb, _msb_pool){ - _available_send_buffs.push_with_haste(&msb); - } } managed_recv_buffer::sptr get_recv_buff(double timeout){ @@ -128,18 +134,17 @@ public: //extract this packet's memory address and length in bytes const char *mem = _last_recv_buff->cast() + _last_recv_offset; const boost::uint32_t *mem32 = reinterpret_cast(mem); - size_t len = (mem32[0] & 0xffff)*sizeof(boost::uint32_t); //length in bytes (from VRT header) - + const size_t len = (uhd::wtohx(mem32[0]) & 0xffff)*sizeof(boost::uint32_t); //length in bytes (from VRT header) + managed_recv_buffer::sptr recv_buff; //the buffer to be returned to the user - recv_buff = wmrb->get_new(_last_recv_buff, mem, len); - _last_recv_offset = next_boundary(_last_recv_offset + len, 4); - + _last_recv_offset += len; + //check if this receive buffer has been exhausted if (_last_recv_offset >= _last_recv_buff->size()) { _last_recv_buff.reset(); } - + return recv_buff; } @@ -156,16 +161,7 @@ public: } managed_send_buffer::sptr get_send_buff(double timeout){ - managed_send_buffer::sptr send_buff = _internal_zc->get_send_buff(timeout); - - //attempt to get a wrapper for a managed send buffer - usb_zero_copy_wrapper_msb *wmsb = NULL; - if (send_buff.get() and _available_send_buffs.pop_with_haste(wmsb)){ - return wmsb->get_new(send_buff); - } - - //otherwise return a null sptr for failure - return managed_send_buffer::sptr(); + return _the_only_msb.get_new(timeout); } size_t get_num_send_frames(void) const{ @@ -178,15 +174,13 @@ public: private: sptr _internal_zc; - size_t _usb_frame_boundary; bounded_buffer _available_recv_buffs; - bounded_buffer _available_send_buffs; std::vector _mrb_pool; - std::vector _msb_pool; - + usb_zero_copy_wrapper_msb _the_only_msb; + //buffer to store partially-received VRT packets in buffer_pool::sptr _fragment_mem; - + //state for last recv buffer to create multiple managed buffers managed_recv_buffer::sptr _last_recv_buff; size_t _last_recv_offset; diff --git a/host/lib/usrp/b100/b100_impl.cpp b/host/lib/usrp/b100/b100_impl.cpp index 87aee9568..455efa2fe 100644 --- a/host/lib/usrp/b100/b100_impl.cpp +++ b/host/lib/usrp/b100/b100_impl.cpp @@ -1,5 +1,5 @@ // -// Copyright 2011 Ettus Research LLC +// Copyright 2012 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 @@ -229,7 +229,8 @@ b100_impl::b100_impl(const device_addr_t &device_addr){ 2, 6, // IN interface, endpoint 1, 2, // OUT interface, endpoint data_xport_args // param hints - ) + ), + B100_MAX_PKT_BYTE_LIMIT ); //////////////////////////////////////////////////////////////////// diff --git a/host/lib/usrp/b100/b100_impl.hpp b/host/lib/usrp/b100/b100_impl.hpp index 433f45aef..49a3139f0 100644 --- a/host/lib/usrp/b100/b100_impl.hpp +++ b/host/lib/usrp/b100/b100_impl.hpp @@ -1,5 +1,5 @@ // -// Copyright 2011 Ettus Research LLC +// Copyright 2011-2012 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 @@ -52,6 +52,7 @@ static const boost::uint16_t B100_FPGA_COMPAT_NUM = 0x09; static const boost::uint32_t B100_RX_SID_BASE = 2; static const boost::uint32_t B100_TX_ASYNC_SID = 1; static const double B100_DEFAULT_TICK_RATE = 64e6; +static const size_t B100_MAX_PKT_BYTE_LIMIT = 2048; //! Make a b100 dboard interface uhd::usrp::dboard_iface::sptr make_b100_dboard_iface( diff --git a/host/lib/usrp/b100/b100_regs.hpp b/host/lib/usrp/b100/b100_regs.hpp index b625e65a5..b87a0ad73 100644 --- a/host/lib/usrp/b100/b100_regs.hpp +++ b/host/lib/usrp/b100/b100_regs.hpp @@ -1,4 +1,19 @@ - +// +// Copyright 2010-2012 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 . +// //////////////////////////////////////////////////////////////// // diff --git a/host/lib/usrp/b100/io_impl.cpp b/host/lib/usrp/b100/io_impl.cpp index 7c07c6349..b1a44d70e 100644 --- a/host/lib/usrp/b100/io_impl.cpp +++ b/host/lib/usrp/b100/io_impl.cpp @@ -1,5 +1,5 @@ // -// Copyright 2011 Ettus Research LLC +// Copyright 2011-2012 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 @@ -211,7 +211,7 @@ rx_streamer::sptr b100_impl::get_rx_stream(const uhd::stream_args_t &args_){ + sizeof(vrt::if_packet_info_t().tlr) //forced to have trailer - sizeof(vrt::if_packet_info_t().cid) //no class id ever used ; - const size_t bpp = 2048 - hdr_size; //limited by FPGA pkt buffer size + const size_t bpp = B100_MAX_PKT_BYTE_LIMIT - hdr_size; const size_t bpi = convert::get_bytes_per_item(args.otw_format); const size_t spp = unsigned(args.args.cast("spp", bpp/bpi)); @@ -260,10 +260,6 @@ tx_streamer::sptr b100_impl::get_tx_stream(const uhd::stream_args_t &args_){ args.otw_format = args.otw_format.empty()? "sc16" : args.otw_format; args.channels = args.channels.empty()? std::vector(1, 0) : args.channels; - if (args.otw_format == "sc8"){ - throw uhd::value_error("USRP TX requested wire format not implemented in FPGA: " + args.otw_format); - } - //calculate packet size static const size_t hdr_size = 0 + vrt::max_if_hdr_words32*sizeof(boost::uint32_t) @@ -271,7 +267,7 @@ tx_streamer::sptr b100_impl::get_tx_stream(const uhd::stream_args_t &args_){ - sizeof(vrt::if_packet_info_t().sid) //no stream id ever used - sizeof(vrt::if_packet_info_t().cid) //no class id ever used ; - static const size_t bpp = _data_transport->get_send_frame_size() - hdr_size; + static const size_t bpp = B100_MAX_PKT_BYTE_LIMIT - hdr_size; const size_t spp = bpp/convert::get_bytes_per_item(args.otw_format); //make the new streamer given the samples per packet diff --git a/host/lib/usrp/e100/e100_impl.cpp b/host/lib/usrp/e100/e100_impl.cpp index cd6143a16..8ab6ab533 100644 --- a/host/lib/usrp/e100/e100_impl.cpp +++ b/host/lib/usrp/e100/e100_impl.cpp @@ -1,5 +1,5 @@ // -// Copyright 2010-2011 Ettus Research LLC +// Copyright 2010-2012 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 diff --git a/host/lib/usrp/e100/e100_impl.hpp b/host/lib/usrp/e100/e100_impl.hpp index e641aeea9..1d36cb2ac 100644 --- a/host/lib/usrp/e100/e100_impl.hpp +++ b/host/lib/usrp/e100/e100_impl.hpp @@ -1,5 +1,5 @@ // -// Copyright 2010-2011 Ettus Research LLC +// Copyright 2010-2012 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 diff --git a/host/lib/usrp/e100/e100_regs.hpp b/host/lib/usrp/e100/e100_regs.hpp index 265086540..eee27b5b3 100644 --- a/host/lib/usrp/e100/e100_regs.hpp +++ b/host/lib/usrp/e100/e100_regs.hpp @@ -1,4 +1,19 @@ - +// +// Copyright 2010-2012 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 . +// //////////////////////////////////////////////////////////////// // diff --git a/host/lib/usrp/e100/io_impl.cpp b/host/lib/usrp/e100/io_impl.cpp index 2b64e7f17..4d530585b 100644 --- a/host/lib/usrp/e100/io_impl.cpp +++ b/host/lib/usrp/e100/io_impl.cpp @@ -1,5 +1,5 @@ // -// Copyright 2010-2011 Ettus Research LLC +// Copyright 2010-2012 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 diff --git a/host/lib/usrp/usrp1/io_impl.cpp b/host/lib/usrp/usrp1/io_impl.cpp index e9d9b65c2..f3cad188a 100644 --- a/host/lib/usrp/usrp1/io_impl.cpp +++ b/host/lib/usrp/usrp1/io_impl.cpp @@ -1,5 +1,5 @@ // -// Copyright 2010-2011 Ettus Research LLC +// Copyright 2010-2012 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 diff --git a/host/lib/usrp/usrp2/io_impl.cpp b/host/lib/usrp/usrp2/io_impl.cpp index 9b6c1c2f0..f19f49e28 100644 --- a/host/lib/usrp/usrp2/io_impl.cpp +++ b/host/lib/usrp/usrp2/io_impl.cpp @@ -1,5 +1,5 @@ // -// Copyright 2010-2011 Ettus Research LLC +// Copyright 2010-2012 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 diff --git a/host/lib/usrp/usrp2/usrp2_impl.cpp b/host/lib/usrp/usrp2/usrp2_impl.cpp index 206016972..7101e040a 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.cpp +++ b/host/lib/usrp/usrp2/usrp2_impl.cpp @@ -1,5 +1,5 @@ // -// Copyright 2010-2011 Ettus Research LLC +// Copyright 2010-2012 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 diff --git a/host/lib/usrp/usrp2/usrp2_impl.hpp b/host/lib/usrp/usrp2/usrp2_impl.hpp index c060f75b5..882a61f80 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.hpp +++ b/host/lib/usrp/usrp2/usrp2_impl.hpp @@ -1,5 +1,5 @@ // -// Copyright 2010-2011 Ettus Research LLC +// Copyright 2010-2012 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 diff --git a/host/lib/usrp/usrp2/usrp2_regs.hpp b/host/lib/usrp/usrp2/usrp2_regs.hpp index 8f714cbbc..5d39e527d 100644 --- a/host/lib/usrp/usrp2/usrp2_regs.hpp +++ b/host/lib/usrp/usrp2/usrp2_regs.hpp @@ -1,5 +1,5 @@ // -// Copyright 2010-2011 Ettus Research LLC +// Copyright 2010-2012 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 -- cgit v1.2.3 From 1ce83a07e188844d81db62d9e3027267fae97fb7 Mon Sep 17 00:00:00 2001 From: Matt Ettus Date: Thu, 2 Feb 2012 17:57:53 -0800 Subject: power_trig: first cut at power trigger with fixed delay --- usrp2/custom/power_trig.v | 115 +++++++++++++++++++++++++++++++++++++++++++++ usrp2/sdr_lib/cordic_z24.v | 2 - 2 files changed, 115 insertions(+), 2 deletions(-) create mode 100644 usrp2/custom/power_trig.v diff --git a/usrp2/custom/power_trig.v b/usrp2/custom/power_trig.v new file mode 100644 index 000000000..ca213e901 --- /dev/null +++ b/usrp2/custom/power_trig.v @@ -0,0 +1,115 @@ +// +// Copyright 2012 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 . +// + +//CUSTOMIZE ME! + +//The following module effects the IO of the DDC chain. +//By default, this entire module is a simple pass-through. + +//To implement DSP logic before the DDC: +//Implement custom DSP between frontend and ddc input. + +//To implement DSP logic after the DDC: +//Implement custom DSP between ddc output and baseband. + +//To bypass the DDC with custom logic: +//Implement custom DSP between frontend and baseband. + +module power_trig + #(parameter BASE=0) + (//control signals + input clk, input reset, input enable, + + // Setting Bus + input set_stb, input [7:0] set_addr, input [31:0] set_data, + + input run, + + //strobed samples {I16,Q16} from the RX DDC chain + input [31:0] ddc_out_sample, + input ddc_out_strobe, //high on valid sample + + //strobed baseband samples {I16,Q16} from this module + output [31:0] bb_sample, + output bb_strobe, //high on valid sample + + //debug output (optional) + output [31:0] debug + ); + + reg [8:0] wr_addr; + wire [8:0] rd_addr; + reg triggered, triggerable; + wire trigger; + + wire [31:0] delayed_sample; + wire [31:0] thresh; + + setting_reg #(.my_addr(BASE+0)) sr_0 + (.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr), + .in(set_data),.out(thresh),.changed()); + + assign rd_addr = wr_addr + 1; // FIXME adjustable delay + + ram_2port #(.DWIDTH(32),.AWIDTH(9)) delay_line + (.clka(clk),.ena(1),.wea(ddc_out_strobe),.addra(wr_addr),.dia(ddc_out_sample),.doa(), + .clkb(clk),.enb(ddc_out_strobe),.web(1'b0),.addrb(rd_addr),.dib(32'hFFFF),.dob(delayed_sample)); + + always @(posedge clk) + if(reset | ~run) + wr_addr <= 0; + else + if(ddc_out_strobe) + wr_addr <= wr_addr + 1; + + always @(posedge clk) + if(reset | ~run) + triggerable <= 0; + else if(wr_addr == 9'h1FF) // Wait till we're nearly full + triggerable <= 1; + + + reg stb_d1, stb_d2; + always @(posedge clk) stb_d1 <= ddc_out_strobe; + always @(posedge clk) stb_d2 <= stb_d1; + + assign bb_sample = delayed_sample; + assign bb_strobe = stb_d1 & triggered; + + // Compute Mag + wire [17:0] mult_in = stb_d1 ? { ddc_out_sample[15],ddc_out_sample[15:0], 1'b0 } : + { ddc_out_sample[31], ddc_out_sample[31:16], 1'b0 }; + wire [35:0] prod; + reg [31:0] sum; + + MULT18X18S mult (.P(prod), .A(mult_in), .B(mult_in), .C(clk), .CE(ddc_out_strobe | stb_d1), .R(reset) ); + + always @(posedge clk) + if(stb_d1) + sum <= prod[35:4]; + else if(stb_d2) + sum <= sum + prod[35:4]; + + always @(posedge clk) + if(reset | ~run | ~triggerable) + triggered <= 0; + else if(trigger) + triggered <= 1; + + assign trigger = (sum > thresh); + +endmodule // power_trig diff --git a/usrp2/sdr_lib/cordic_z24.v b/usrp2/sdr_lib/cordic_z24.v index 97b7beaf7..51b074a33 100644 --- a/usrp2/sdr_lib/cordic_z24.v +++ b/usrp2/sdr_lib/cordic_z24.v @@ -119,8 +119,6 @@ module cordic_z24(clock, reset, enable, xi, yi, zi, xo, yo, zo ); assign xo = x20[bitwidth:1]; assign yo = y20[bitwidth:1]; assign zo = z20; - //assign xo = x20[bitwidth+1:2]; // CORDIC gain is ~1.6, plus gain from rotating vectors - //assign yo = y20[bitwidth+1:2]; endmodule // cordic -- cgit v1.2.3 From e64b6e6cddc2f9a5374cf23dbb8cf066d2fecbf8 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Thu, 2 Feb 2012 20:08:47 -0800 Subject: dsp rework: rehash of the custom module stuff and readme --- README.txt | 53 ++++++++++++++++++++-- usrp2/custom/Makefile.srcs | 13 ------ usrp2/custom/custom_dsp_rx.v | 57 +++--------------------- usrp2/custom/custom_dsp_tx.v | 57 +++--------------------- usrp2/custom/custom_engine_rx.v | 63 ++++---------------------- usrp2/custom/custom_engine_tx.v | 61 +++---------------------- usrp2/sdr_lib/Makefile.srcs | 2 + usrp2/sdr_lib/ddc_chain.v | 5 +-- usrp2/sdr_lib/dsp_rx_glue.v | 95 +++++++++++++++++++++++++++++++++++++++ usrp2/sdr_lib/dsp_tx_glue.v | 95 +++++++++++++++++++++++++++++++++++++++ usrp2/sdr_lib/duc_chain.v | 5 +-- usrp2/top/B100/Makefile.B100 | 15 +++++-- usrp2/top/B100/u1plus_core.v | 4 +- usrp2/top/E1x0/Makefile.E100 | 10 +++-- usrp2/top/E1x0/Makefile.E110 | 10 +++-- usrp2/top/E1x0/u1e_core.v | 2 +- usrp2/top/N2x0/Makefile.N200R3 | 10 +++-- usrp2/top/N2x0/Makefile.N200R4 | 9 ++-- usrp2/top/N2x0/Makefile.N210R3 | 10 +++-- usrp2/top/N2x0/Makefile.N210R4 | 9 ++-- usrp2/top/USRP2/Makefile | 10 +++-- usrp2/vrt/Makefile.srcs | 2 + usrp2/vrt/vita_rx_chain.v | 2 +- usrp2/vrt/vita_rx_engine_glue.v | 95 +++++++++++++++++++++++++++++++++++++++ usrp2/vrt/vita_tx_chain.v | 13 +++++- usrp2/vrt/vita_tx_engine_glue.v | 99 +++++++++++++++++++++++++++++++++++++++++ 26 files changed, 544 insertions(+), 262 deletions(-) delete mode 100644 usrp2/custom/Makefile.srcs create mode 100644 usrp2/sdr_lib/dsp_rx_glue.v create mode 100644 usrp2/sdr_lib/dsp_tx_glue.v create mode 100644 usrp2/vrt/vita_rx_engine_glue.v create mode 100644 usrp2/vrt/vita_tx_engine_glue.v diff --git a/README.txt b/README.txt index bfdf317c1..29e891f6d 100644 --- a/README.txt +++ b/README.txt @@ -26,6 +26,53 @@ usrp2/ 3) make -f Makefile. bin 4) bin file in build-/*.bin - Customize the DSP: - Implement design in usrp2/custom/custom_*.v - Instructions are included in the module. +######################################################################## +## Customizing the DSP +######################################################################## + +As part of the USRP FPGA build-framework, +there are several convenient places for users to insert +custom DSP modules into the transmit and receive chains. + +* before the DDC module +* after the DDC module +* replace the DDC module +* before the DUC module +* after the DUC module +* replace of the DUC module +* as an RX packet engine +* as an TX packet engine + +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Customizing the top level makefile +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Each USRP device has a makefile associated with it. +This makefile contains all of the necessary build rules. +When making a customized FPGA design, +start by copying the current makefile for your device. +Makefiles can be found in the usrp2/top//Makefile.* + +Edit your new makefile: +* set BUILD_DIR to a unique directory name +* set CUSTOM_SRCS for your verilog sources +* set CUSTOM_DEFS (see section below) + +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Inserting custom modules +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +CUSTOM_DEFS is a string of space-separate key-value pairs. +Set the CUSTOM_DEFS variable so the FPGA fabric glue +will substitute your custom modules into the DSP chain. + +Example: +CUSTOM_DEFS = "TX_ENG0_MODULE=my_tx_engine RX_ENG0_MODULE=my_rx_engine" +Where my_tx_engine and my_rx_engine are the names of custom verilog modules. + +The following module definition keys are possible (X is a DSP number): + +* TX_ENG_MODULE: set the module for the transmit chain engine. +* RX_ENG_MODULE: set the module for the receive chain engine. +* RX_DSP_MODULE: set the module for the transmit dsp chain. +* TX_DSP_MODULE: set the module for the receive dsp chain. + +Examples of custom modules can be found in usrp2/custom/*.v diff --git a/usrp2/custom/Makefile.srcs b/usrp2/custom/Makefile.srcs deleted file mode 100644 index 8a4f70fca..000000000 --- a/usrp2/custom/Makefile.srcs +++ /dev/null @@ -1,13 +0,0 @@ -# -# Copyright 2012 Ettus Research LLC -# - -################################################## -# FIFO Sources -################################################## -CUSTOM_SRCS = $(abspath $(addprefix $(BASE_DIR)/../custom/, \ -custom_dsp_rx.v \ -custom_dsp_tx.v \ -custom_engine_rx.v \ -custom_engine_tx.v \ -)) diff --git a/usrp2/custom/custom_dsp_rx.v b/usrp2/custom/custom_dsp_rx.v index 73294566e..b90cd54e9 100644 --- a/usrp2/custom/custom_dsp_rx.v +++ b/usrp2/custom/custom_dsp_rx.v @@ -15,7 +15,7 @@ // along with this program. If not, see . // -//CUSTOMIZE ME! +//COPY ME, CUSTOMIZE ME... //The following module effects the IO of the DDC chain. //By default, this entire module is a simple pass-through. @@ -31,9 +31,6 @@ module custom_dsp_rx #( - //the dsp unit number: 0, 1, 2... - parameter DSPNO = 0, - //frontend bus width parameter WIDTH = 24 ) @@ -41,11 +38,8 @@ module custom_dsp_rx //control signals input clock, input reset, input enable, - //main settings bus for built-in modules - input set_stb_main, input [7:0] set_addr_main, input [31:0] set_data_main, - //user settings bus, controlled through user setting regs API - input set_stb_user, input [7:0] set_addr_user, input [31:0] set_data_user, + input set_stb, input [7:0] set_addr, input [31:0] set_data, //full rate inputs directly from the RX frontend input [WIDTH-1:0] frontend_i, @@ -61,49 +55,12 @@ module custom_dsp_rx //strobbed baseband samples {I16,Q16} from this module output [31:0] bb_sample, - output bb_strobe, //high on valid sample - - //debug output (optional) - output [31:0] debug + output bb_strobe //high on valid sample ); - generate - if (DSPNO==0) begin - `ifndef RX_DSP0_MODULE - assign ddc_in_i = frontend_i; - assign ddc_in_q = frontend_q; - assign bb_sample = ddc_out_sample; - assign bb_strobe = ddc_out_strobe; - `else - RX_DSP0_CUSTOM_MODULE_NAME rx_dsp0_custom - ( - .clock(clock), .reset(reset), .enable(enable), - .set_stb(set_stb), .set_addr(set_addr), .set_data(set_data), - .frontend_i(frontend_i), .frontend_q(frontend_q), - .ddc_in_i(ddc_in_i), .ddc_in_q(ddc_in_q), - .ddc_out_sample(ddc_out_sample), .ddc_out_strobe(ddc_out_strobe), - .bb_sample(bb_sample), .bb_strobe(bb_strobe) - ); - `endif - end - else begin - `ifndef RX_DSP1_MODULE - assign ddc_in_i = frontend_i; - assign ddc_in_q = frontend_q; - assign bb_sample = ddc_out_sample; - assign bb_strobe = ddc_out_strobe; - `else - RX_DSP1_CUSTOM_MODULE_NAME rx_dsp1_custom - ( - .clock(clock), .reset(reset), .enable(enable), - .set_stb(set_stb), .set_addr(set_addr), .set_data(set_data), - .frontend_i(frontend_i), .frontend_q(frontend_q), - .ddc_in_i(ddc_in_i), .ddc_in_q(ddc_in_q), - .ddc_out_sample(ddc_out_sample), .ddc_out_strobe(ddc_out_strobe), - .bb_sample(bb_sample), .bb_strobe(bb_strobe) - ); - `endif - end - endgenerate + assign ddc_in_i = frontend_i; + assign ddc_in_q = frontend_q; + assign bb_sample = ddc_out_sample; + assign bb_strobe = ddc_out_strobe; endmodule //custom_dsp_rx diff --git a/usrp2/custom/custom_dsp_tx.v b/usrp2/custom/custom_dsp_tx.v index cb0d7522b..4b1388b02 100644 --- a/usrp2/custom/custom_dsp_tx.v +++ b/usrp2/custom/custom_dsp_tx.v @@ -15,7 +15,7 @@ // along with this program. If not, see . // -//CUSTOMIZE ME! +//COPY ME, CUSTOMIZE ME... //The following module effects the IO of the DUC chain. //By default, this entire module is a simple pass-through. @@ -31,9 +31,6 @@ module custom_dsp_tx #( - //the dsp unit number: 0, 1, 2... - parameter DSPNO = 0, - //frontend bus width parameter WIDTH = 24 ) @@ -41,11 +38,8 @@ module custom_dsp_tx //control signals input clock, input reset, input enable, - //main settings bus for built-in modules - input set_stb_main, input [7:0] set_addr_main, input [31:0] set_data_main, - //user settings bus, controlled through user setting regs API - input set_stb_user, input [7:0] set_addr_user, input [31:0] set_data_user, + input set_stb, input [7:0] set_addr, input [31:0] set_data, //full rate outputs directly to the TX frontend output [WIDTH-1:0] frontend_i, @@ -61,49 +55,12 @@ module custom_dsp_tx //strobbed baseband samples {I16,Q16} to this module input [31:0] bb_sample, - output bb_strobe, //this is a backpressure signal - - //debug output (optional) - output [31:0] debug + output bb_strobe //this is a backpressure signal ); - generate - if (DSPNO==0) begin - `ifndef TX_DSP0_MODULE - assign frontend_i = duc_out_i; - assign frontend_q = duc_out_q; - assign duc_in_sample = bb_sample; - assign bb_strobe = duc_in_strobe; - `else - TX_DSP0_CUSTOM_MODULE_NAME tx_dsp0_custom - ( - .clock(clock), .reset(reset), .enable(enable), - .set_stb(set_stb), .set_addr(set_addr), .set_data(set_data), - .frontend_i(frontend_i), .frontend_q(frontend_q), - .duc_out_i(duc_out_i), .duc_out_q(duc_out_q), - .duc_in_sample(duc_in_sample), .duc_in_strobe(duc_in_strobe), - .bb_sample(bb_sample), .bb_strobe(bb_strobe) - ); - `endif - end - else begin - `ifndef TX_DSP1_MODULE - assign frontend_i = duc_out_i; - assign frontend_q = duc_out_q; - assign duc_in_sample = bb_sample; - assign bb_strobe = duc_in_strobe; - `else - TX_DSP1_CUSTOM_MODULE_NAME tx_dsp1_custom - ( - .clock(clock), .reset(reset), .enable(enable), - .set_stb(set_stb), .set_addr(set_addr), .set_data(set_data), - .frontend_i(frontend_i), .frontend_q(frontend_q), - .duc_out_i(duc_out_i), .duc_out_q(duc_out_q), - .duc_in_sample(duc_in_sample), .duc_in_strobe(duc_in_strobe), - .bb_sample(bb_sample), .bb_strobe(bb_strobe) - ); - `endif - end - endgenerate + assign frontend_i = duc_out_i; + assign frontend_q = duc_out_q; + assign duc_in_sample = bb_sample; + assign bb_strobe = duc_in_strobe; endmodule //custom_dsp_tx diff --git a/usrp2/custom/custom_engine_rx.v b/usrp2/custom/custom_engine_rx.v index 48276665f..dfeaad2cd 100644 --- a/usrp2/custom/custom_engine_rx.v +++ b/usrp2/custom/custom_engine_rx.v @@ -15,35 +15,26 @@ // along with this program. If not, see . // -//CUSTOMIZE ME! +//COPY ME, CUSTOMIZE ME... //The following module is used to re-write receive packets to the host. //This module provides a packet-based ram interface for manipulating packets. //The user writes a custom engine (state machine) to read the input packet, -//and to produce a new output packet. For users customizing the DSP operation, -//your customizations may be better suited for the custom_dsp_rx module. -//By default, this module uses the built-in 16 to 8 bit converter engine. +//and to produce a new output packet. + +//By default, this entire module is a simple pass-through. module custom_engine_rx #( - //the dsp unit number: 0, 1, 2... - parameter DSPNO = 0, - //buffer size for ram interface engine - parameter BUF_SIZE = 10, - - //base address for built-in settings registers used in this module - parameter MAIN_SETTINGS_BASE = 0 + parameter BUF_SIZE = 10 ) ( //control signals input clock, input reset, input clear, - //main settings bus for built-in modules - input set_stb_main, input [7:0] set_addr_main, input [31:0] set_data_main, - //user settings bus, controlled through user setting regs API - input set_stb_user, input [7:0] set_addr_user, input [31:0] set_data_user, + input set_stb, input [7:0] set_addr, input [31:0] set_data, //ram interface for engine output access_we, @@ -54,47 +45,9 @@ module custom_engine_rx output [BUF_SIZE-1:0] access_adr, input [BUF_SIZE-1:0] access_len, output [35:0] access_dat_o, - input [35:0] access_dat_i, - - //debug output (optional) - output [31:0] debug + input [35:0] access_dat_i ); - generate - if (DSPNO==0) begin - `ifndef RX_ENG0_MODULE - dspengine_16to8 #(.BASE(MAIN_SETTINGS_BASE), .BUF_SIZE(BUF_SIZE)) dspengine_16to8 - (.clk(clock),.reset(reset),.clear(clear), - .set_stb(set_stb_main), .set_addr(set_addr_main), .set_data(set_data_main), - .access_we(access_we), .access_stb(access_stb), .access_ok(access_ok), .access_done(access_done), - .access_skip_read(access_skip_read), .access_adr(access_adr), .access_len(access_len), - .access_dat_i(access_dat_i), .access_dat_o(access_dat_o)); - `else - RX_ENG0_MODULE #(.BUF_SIZE(BUF_SIZE)) rx_eng0_custom - (.clock(clock),.reset(reset),.clear(clear), - .set_stb(set_stb_user), .set_addr(set_addr_user), .set_data(set_data_user), - .access_we(access_we), .access_stb(access_stb), .access_ok(access_ok), .access_done(access_done), - .access_skip_read(access_skip_read), .access_adr(access_adr), .access_len(access_len), - .access_dat_i(access_dat_i), .access_dat_o(access_dat_o)); - `endif - end - else begin - `ifndef RX_ENG1_MODULE - dspengine_16to8 #(.BASE(MAIN_SETTINGS_BASE), .BUF_SIZE(BUF_SIZE)) dspengine_16to8 - (.clk(clock),.reset(reset),.clear(clear), - .set_stb(set_stb_main), .set_addr(set_addr_main), .set_data(set_data_main), - .access_we(access_we), .access_stb(access_stb), .access_ok(access_ok), .access_done(access_done), - .access_skip_read(access_skip_read), .access_adr(access_adr), .access_len(access_len), - .access_dat_i(access_dat_i), .access_dat_o(access_dat_o)); - `else - RX_ENG1_MODULE #(.BUF_SIZE(BUF_SIZE)) rx_eng1_custom - (.clock(clock),.reset(reset),.clear(clear), - .set_stb(set_stb_user), .set_addr(set_addr_user), .set_data(set_data_user), - .access_we(access_we), .access_stb(access_stb), .access_ok(access_ok), .access_done(access_done), - .access_skip_read(access_skip_read), .access_adr(access_adr), .access_len(access_len), - .access_dat_i(access_dat_i), .access_dat_o(access_dat_o)); - `endif - end - endgenerate + assign access_done = access_ok; endmodule //custom_engine_rx diff --git a/usrp2/custom/custom_engine_tx.v b/usrp2/custom/custom_engine_tx.v index 6227b0f45..9be728484 100644 --- a/usrp2/custom/custom_engine_tx.v +++ b/usrp2/custom/custom_engine_tx.v @@ -15,26 +15,20 @@ // along with this program. If not, see . // -//CUSTOMIZE ME! +//COPY ME, CUSTOMIZE ME... //The following module is used to re-write transmit packets from the host. //This module provides a packet-based ram interface for manipulating packets. //The user writes a custom engine (state machine) to read the input packet, -//and to produce a new output packet. For users customizing the DSP operation, -//your customizations may be better suited for the custom_dsp_tx module. -//By default, this module uses the built-in 8 to 16 bit converter engine. +//and to produce a new output packet. + +//By default, this entire module is a simple pass-through. module custom_engine_tx #( - //the dsp unit number: 0, 1, 2... - parameter DSPNO = 0, - //buffer size for ram interface engine parameter BUF_SIZE = 10, - //base address for built-in settings registers used in this module - parameter MAIN_SETTINGS_BASE = 0, - //the number of 32bit lines between start of buffer and vita header //the metadata before the header should be preserved by the engine parameter HEADER_OFFSET = 0 @@ -43,11 +37,8 @@ module custom_engine_tx //control signals input clock, input reset, input clear, - //main settings bus for built-in modules - input set_stb_main, input [7:0] set_addr_main, input [31:0] set_data_main, - //user settings bus, controlled through user setting regs API - input set_stb_user, input [7:0] set_addr_user, input [31:0] set_data_user, + input set_stb, input [7:0] set_addr, input [31:0] set_data, //ram interface for engine output access_we, @@ -58,47 +49,9 @@ module custom_engine_tx output [BUF_SIZE-1:0] access_adr, input [BUF_SIZE-1:0] access_len, output [35:0] access_dat_o, - input [35:0] access_dat_i, - - //debug output (optional) - output [31:0] debug + input [35:0] access_dat_i ); - generate - if (DSPNO==0) begin - `ifndef TX_ENG0_MODULE - dspengine_8to16 #(.BASE(MAIN_SETTINGS_BASE), .BUF_SIZE(BUF_SIZE), .HEADER_OFFSET(HEADER_OFFSET)) dspengine_8to16 - (.clk(clock),.reset(reset),.clear(clear), - .set_stb(set_stb_main), .set_addr(set_addr_main), .set_data(set_data_main), - .access_we(access_we), .access_stb(access_stb), .access_ok(access_ok), .access_done(access_done), - .access_skip_read(access_skip_read), .access_adr(access_adr), .access_len(access_len), - .access_dat_i(access_dat_i), .access_dat_o(access_dat_o)); - `else - TX_ENG0_MODULE #(.BUF_SIZE(BUF_SIZE)) tx_eng0_custom - (.clock(clock),.reset(reset),.clear(clear), - .set_stb(set_stb_user), .set_addr(set_addr_user), .set_data(set_data_user), - .access_we(access_we), .access_stb(access_stb), .access_ok(access_ok), .access_done(access_done), - .access_skip_read(access_skip_read), .access_adr(access_adr), .access_len(access_len), - .access_dat_i(access_dat_i), .access_dat_o(access_dat_o)); - `endif - end - else begin - `ifndef TX_ENG1_MODULE - dspengine_8to16 #(.BASE(MAIN_SETTINGS_BASE), .BUF_SIZE(BUF_SIZE), .HEADER_OFFSET(HEADER_OFFSET)) dspengine_8to16 - (.clk(clock),.reset(reset),.clear(clear), - .set_stb(set_stb_main), .set_addr(set_addr_main), .set_data(set_data_main), - .access_we(access_we), .access_stb(access_stb), .access_ok(access_ok), .access_done(access_done), - .access_skip_read(access_skip_read), .access_adr(access_adr), .access_len(access_len), - .access_dat_i(access_dat_i), .access_dat_o(access_dat_o)); - `else - TX_ENG1_MODULE #(.BUF_SIZE(BUF_SIZE)) tx_eng1_custom - (.clock(clock),.reset(reset),.clear(clear), - .set_stb(set_stb_user), .set_addr(set_addr_user), .set_data(set_data_user), - .access_we(access_we), .access_stb(access_stb), .access_ok(access_ok), .access_done(access_done), - .access_skip_read(access_skip_read), .access_adr(access_adr), .access_len(access_len), - .access_dat_i(access_dat_i), .access_dat_o(access_dat_o)); - `endif - end - endgenerate + assign access_done = access_ok; endmodule //custom_engine_tx diff --git a/usrp2/sdr_lib/Makefile.srcs b/usrp2/sdr_lib/Makefile.srcs index 840627e6d..e6c4c5343 100644 --- a/usrp2/sdr_lib/Makefile.srcs +++ b/usrp2/sdr_lib/Makefile.srcs @@ -40,4 +40,6 @@ sign_extend.v \ small_hb_dec.v \ small_hb_int.v \ tx_frontend.v \ +dsp_tx_glue.v \ +dsp_rx_glue.v \ )) diff --git a/usrp2/sdr_lib/ddc_chain.v b/usrp2/sdr_lib/ddc_chain.v index 270da45db..3dee978a5 100644 --- a/usrp2/sdr_lib/ddc_chain.v +++ b/usrp2/sdr_lib/ddc_chain.v @@ -165,10 +165,9 @@ module ddc_chain round_sd #(.WIDTH_IN(24),.WIDTH_OUT(16)) round_q (.clk(clk),.reset(rst), .in(prod_reg_q),.strobe_in(strobe_mult), .out(ddc_chain_out[15:0]), .strobe_out()); - custom_dsp_rx #(.DSPNO(DSPNO)) custom( + dsp_rx_glue #(.DSPNO(DSPNO)) custom( .clock(clk), .reset(rst), .enable(run), - .set_stb_main(set_stb), .set_addr_main(set_addr), .set_data_main(set_data), - .set_stb_user(set_stb_user), .set_addr_user(set_addr_user), .set_data_user(set_data_user), + .set_stb(set_stb_user), .set_addr(set_addr_user), .set_data(set_data_user), .frontend_i(rx_fe_i_mux), .frontend_q(rx_fe_q_mux), .ddc_in_i(to_cordic_i), .ddc_in_q(to_cordic_q), .ddc_out_sample(ddc_chain_out), .ddc_out_strobe(ddc_chain_stb), diff --git a/usrp2/sdr_lib/dsp_rx_glue.v b/usrp2/sdr_lib/dsp_rx_glue.v new file mode 100644 index 000000000..2c7c188e0 --- /dev/null +++ b/usrp2/sdr_lib/dsp_rx_glue.v @@ -0,0 +1,95 @@ +// +// Copyright 2012 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 . +// + +//The following module effects the IO of the DDC chain. +//By default, this entire module is a simple pass-through. + +module dsp_rx_glue +#( + //the dsp unit number: 0, 1, 2... + parameter DSPNO = 0, + + //frontend bus width + parameter WIDTH = 24 +) +( + //control signals + input clock, input reset, input enable, + + //user settings bus, controlled through user setting regs API + input set_stb, input [7:0] set_addr, input [31:0] set_data, + + //full rate inputs directly from the RX frontend + input [WIDTH-1:0] frontend_i, + input [WIDTH-1:0] frontend_q, + + //full rate outputs directly to the DDC chain + output [WIDTH-1:0] ddc_in_i, + output [WIDTH-1:0] ddc_in_q, + + //strobed samples {I16,Q16} from the RX DDC chain + input [31:0] ddc_out_sample, + input ddc_out_strobe, //high on valid sample + + //strobbed baseband samples {I16,Q16} from this module + output [31:0] bb_sample, + output bb_strobe, //high on valid sample + + //debug output (optional) + output [31:0] debug +); + + generate + if (DSPNO==0) begin + `ifndef RX_DSP0_MODULE + assign ddc_in_i = frontend_i; + assign ddc_in_q = frontend_q; + assign bb_sample = ddc_out_sample; + assign bb_strobe = ddc_out_strobe; + `else + RX_DSP0_MODULE rx_dsp0_custom + ( + .clock(clock), .reset(reset), .enable(enable), + .set_stb(set_stb), .set_addr(set_addr), .set_data(set_data), + .frontend_i(frontend_i), .frontend_q(frontend_q), + .ddc_in_i(ddc_in_i), .ddc_in_q(ddc_in_q), + .ddc_out_sample(ddc_out_sample), .ddc_out_strobe(ddc_out_strobe), + .bb_sample(bb_sample), .bb_strobe(bb_strobe) + ); + `endif + end + else begin + `ifndef RX_DSP1_MODULE + assign ddc_in_i = frontend_i; + assign ddc_in_q = frontend_q; + assign bb_sample = ddc_out_sample; + assign bb_strobe = ddc_out_strobe; + `else + RX_DSP1_MODULE rx_dsp1_custom + ( + .clock(clock), .reset(reset), .enable(enable), + .set_stb(set_stb), .set_addr(set_addr), .set_data(set_data), + .frontend_i(frontend_i), .frontend_q(frontend_q), + .ddc_in_i(ddc_in_i), .ddc_in_q(ddc_in_q), + .ddc_out_sample(ddc_out_sample), .ddc_out_strobe(ddc_out_strobe), + .bb_sample(bb_sample), .bb_strobe(bb_strobe) + ); + `endif + end + endgenerate + +endmodule //dsp_rx_glue diff --git a/usrp2/sdr_lib/dsp_tx_glue.v b/usrp2/sdr_lib/dsp_tx_glue.v new file mode 100644 index 000000000..8eccd2bfc --- /dev/null +++ b/usrp2/sdr_lib/dsp_tx_glue.v @@ -0,0 +1,95 @@ +// +// Copyright 2012 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 . +// + +//The following module effects the IO of the DUC chain. +//By default, this entire module is a simple pass-through. + +module dsp_tx_glue +#( + //the dsp unit number: 0, 1, 2... + parameter DSPNO = 0, + + //frontend bus width + parameter WIDTH = 24 +) +( + //control signals + input clock, input reset, input enable, + + //user settings bus, controlled through user setting regs API + input set_stb, input [7:0] set_addr, input [31:0] set_data, + + //full rate outputs directly to the TX frontend + output [WIDTH-1:0] frontend_i, + output [WIDTH-1:0] frontend_q, + + //full rate outputs directly from the DUC chain + input [WIDTH-1:0] duc_out_i, + input [WIDTH-1:0] duc_out_q, + + //strobed samples {I16,Q16} to the TX DUC chain + output [31:0] duc_in_sample, + input duc_in_strobe, //this is a backpressure signal + + //strobbed baseband samples {I16,Q16} to this module + input [31:0] bb_sample, + output bb_strobe, //this is a backpressure signal + + //debug output (optional) + output [31:0] debug +); + + generate + if (DSPNO==0) begin + `ifndef TX_DSP0_MODULE + assign frontend_i = duc_out_i; + assign frontend_q = duc_out_q; + assign duc_in_sample = bb_sample; + assign bb_strobe = duc_in_strobe; + `else + TX_DSP0_MODULE tx_dsp0_custom + ( + .clock(clock), .reset(reset), .enable(enable), + .set_stb(set_stb), .set_addr(set_addr), .set_data(set_data), + .frontend_i(frontend_i), .frontend_q(frontend_q), + .duc_out_i(duc_out_i), .duc_out_q(duc_out_q), + .duc_in_sample(duc_in_sample), .duc_in_strobe(duc_in_strobe), + .bb_sample(bb_sample), .bb_strobe(bb_strobe) + ); + `endif + end + else begin + `ifndef TX_DSP1_MODULE + assign frontend_i = duc_out_i; + assign frontend_q = duc_out_q; + assign duc_in_sample = bb_sample; + assign bb_strobe = duc_in_strobe; + `else + TX_DSP1_MODULE tx_dsp1_custom + ( + .clock(clock), .reset(reset), .enable(enable), + .set_stb(set_stb), .set_addr(set_addr), .set_data(set_data), + .frontend_i(frontend_i), .frontend_q(frontend_q), + .duc_out_i(duc_out_i), .duc_out_q(duc_out_q), + .duc_in_sample(duc_in_sample), .duc_in_strobe(duc_in_strobe), + .bb_sample(bb_sample), .bb_strobe(bb_strobe) + ); + `endif + end + endgenerate + +endmodule //dsp_tx_glue diff --git a/usrp2/sdr_lib/duc_chain.v b/usrp2/sdr_lib/duc_chain.v index d9ede6bc2..d3b2b394f 100644 --- a/usrp2/sdr_lib/duc_chain.v +++ b/usrp2/sdr_lib/duc_chain.v @@ -147,10 +147,9 @@ module duc_chain .R(rst) // Synchronous reset input ); - custom_dsp_tx #(.DSPNO(DSPNO)) custom( + dsp_tx_glue #(.DSPNO(DSPNO)) dsp_tx_glue( .clock(clk), .reset(rst), .enable(run), - .set_stb_main(set_stb), .set_addr_main(set_addr), .set_data_main(set_data), - .set_stb_user(set_stb_user), .set_addr_user(set_addr_user), .set_data_user(set_data_user), + .set_stb(set_stb_user), .set_addr(set_addr_user), .set_data(set_data_user), .frontend_i(tx_fe_i), .frontend_q(tx_fe_q), .duc_out_i(prod_i[33:10]), .duc_out_q(prod_q[33:10]), .duc_in_sample({bb_i, bb_q}), .duc_in_strobe(strobe_hb1), diff --git a/usrp2/top/B100/Makefile.B100 b/usrp2/top/B100/Makefile.B100 index 442b0b579..3cdbb62c0 100644 --- a/usrp2/top/B100/Makefile.B100 +++ b/usrp2/top/B100/Makefile.B100 @@ -1,5 +1,5 @@ # -# Copyright 2008 Ettus Research LLC +# Copyright 2008-2012 Ettus Research LLC # ################################################## @@ -7,7 +7,14 @@ ################################################## TOP_MODULE := B100 BUILD_DIR := build-B100/ -export PROJ_FILE := $(BUILD_DIR)$(TOP_MODULE).ise + +# set me in a custom makefile +CUSTOM_SRCS = +CUSTOM_DEFS = + +################################################## +# Include other makefiles +################################################## include ../Makefile.common include ../../fifo/Makefile.srcs @@ -21,7 +28,6 @@ include ../../vrt/Makefile.srcs include ../../udp/Makefile.srcs include ../../coregen/Makefile.srcs include ../../gpif/Makefile.srcs -include ../../custom/Makefile.srcs ################################################## # Project Properties @@ -64,7 +70,8 @@ SYNTHESIZE_PROPERTIES = \ "Register Balancing" Yes \ "Use Clock Enable" Auto \ "Use Synchronous Reset" Auto \ -"Use Synchronous Set" Auto +"Use Synchronous Set" Auto \ +"Verilog Macros" "$(CUSTOM_MOD_DEFS)" TRANSLATE_PROPERTIES = \ "Macro Search Path" "$(shell pwd)/../../coregen/" diff --git a/usrp2/top/B100/u1plus_core.v b/usrp2/top/B100/u1plus_core.v index 4c3acaa27..88a8b4f4b 100644 --- a/usrp2/top/B100/u1plus_core.v +++ b/usrp2/top/B100/u1plus_core.v @@ -37,7 +37,7 @@ module u1plus_core input pps_in ); - localparam TXFIFOSIZE = 12; + localparam TXFIFOSIZE = 11; localparam RXFIFOSIZE = 12; // 64 total regs in address space @@ -220,7 +220,7 @@ module u1plus_core wire [31:0] sample_tx; wire strobe_tx; - vita_tx_chain #(.BASE(SR_TX_CTRL), .FIFOSIZE(0/*no engine*/), + vita_tx_chain #(.BASE(SR_TX_CTRL), .FIFOSIZE(10), .POST_ENGINE_FIFOSIZE(11), .REPORT_ERROR(1), .DO_FLOW_CONTROL(0), .PROT_ENG_FLAGS(0), .USE_TRANS_HEADER(0), .DSP_NUMBER(0)) diff --git a/usrp2/top/E1x0/Makefile.E100 b/usrp2/top/E1x0/Makefile.E100 index 397bac618..ad5a0c1bd 100644 --- a/usrp2/top/E1x0/Makefile.E100 +++ b/usrp2/top/E1x0/Makefile.E100 @@ -1,5 +1,5 @@ # -# Copyright 2008 Ettus Research LLC +# Copyright 2008-2012 Ettus Research LLC # ################################################## @@ -8,6 +8,10 @@ TOP_MODULE = u1e BUILD_DIR = $(abspath build$(ISE)-E100) +# set me in a custom makefile +CUSTOM_SRCS = +CUSTOM_DEFS = + ################################################## # Include other makefiles ################################################## @@ -24,7 +28,6 @@ include ../../vrt/Makefile.srcs include ../../udp/Makefile.srcs include ../../coregen/Makefile.srcs include ../../gpmc/Makefile.srcs -include ../../custom/Makefile.srcs ################################################## # Project Properties @@ -67,7 +70,8 @@ SYNTHESIZE_PROPERTIES = \ "Register Balancing" Yes \ "Use Clock Enable" Auto \ "Use Synchronous Reset" Auto \ -"Use Synchronous Set" Auto +"Use Synchronous Set" Auto \ +"Verilog Macros" "$(CUSTOM_MOD_DEFS)" TRANSLATE_PROPERTIES = \ "Macro Search Path" "$(shell pwd)/../../coregen/" diff --git a/usrp2/top/E1x0/Makefile.E110 b/usrp2/top/E1x0/Makefile.E110 index 1f95954ae..291ac0a44 100644 --- a/usrp2/top/E1x0/Makefile.E110 +++ b/usrp2/top/E1x0/Makefile.E110 @@ -1,5 +1,5 @@ # -# Copyright 2008 Ettus Research LLC +# Copyright 2008-2012 Ettus Research LLC # ################################################## @@ -8,6 +8,10 @@ TOP_MODULE = u1e BUILD_DIR = $(abspath build$(ISE)-E110) +# set me in a custom makefile +CUSTOM_SRCS = +CUSTOM_DEFS = + ################################################## # Include other makefiles ################################################## @@ -24,7 +28,6 @@ include ../../vrt/Makefile.srcs include ../../udp/Makefile.srcs include ../../coregen/Makefile.srcs include ../../gpmc/Makefile.srcs -include ../../custom/Makefile.srcs ################################################## # Project Properties @@ -67,7 +70,8 @@ SYNTHESIZE_PROPERTIES = \ "Register Balancing" Yes \ "Use Clock Enable" Auto \ "Use Synchronous Reset" Auto \ -"Use Synchronous Set" Auto +"Use Synchronous Set" Auto \ +"Verilog Macros" "$(CUSTOM_MOD_DEFS)" TRANSLATE_PROPERTIES = \ "Macro Search Path" "$(shell pwd)/../../coregen/" diff --git a/usrp2/top/E1x0/u1e_core.v b/usrp2/top/E1x0/u1e_core.v index 5f2edca1a..765023e29 100644 --- a/usrp2/top/E1x0/u1e_core.v +++ b/usrp2/top/E1x0/u1e_core.v @@ -220,7 +220,7 @@ module u1e_core wire [31:0] sample_tx; wire strobe_tx; - vita_tx_chain #(.BASE(SR_TX_CTRL), .FIFOSIZE(10), + vita_tx_chain #(.BASE(SR_TX_CTRL), .FIFOSIZE(10), .POST_ENGINE_FIFOSIZE(11), .REPORT_ERROR(1), .DO_FLOW_CONTROL(0), .PROT_ENG_FLAGS(0), .USE_TRANS_HEADER(0), .DSP_NUMBER(0)) diff --git a/usrp2/top/N2x0/Makefile.N200R3 b/usrp2/top/N2x0/Makefile.N200R3 index 7181e7d62..680cadf44 100644 --- a/usrp2/top/N2x0/Makefile.N200R3 +++ b/usrp2/top/N2x0/Makefile.N200R3 @@ -1,5 +1,5 @@ # -# Copyright 2008 Ettus Research LLC +# Copyright 2008-2012 Ettus Research LLC # ################################################## @@ -8,6 +8,10 @@ TOP_MODULE = u2plus BUILD_DIR = $(abspath build$(ISE)-N200R3) +# set me in a custom makefile +CUSTOM_SRCS = +CUSTOM_DEFS = + ################################################## # Include other makefiles ################################################## @@ -24,7 +28,6 @@ include ../../vrt/Makefile.srcs include ../../udp/Makefile.srcs include ../../coregen/Makefile.srcs include ../../extramfifo/Makefile.srcs -include ../../custom/Makefile.srcs ################################################## @@ -67,7 +70,8 @@ SYNTHESIZE_PROPERTIES = \ "Register Balancing" Yes \ "Use Clock Enable" Auto \ "Use Synchronous Reset" Auto \ -"Use Synchronous Set" Auto +"Use Synchronous Set" Auto \ +"Verilog Macros" "$(CUSTOM_DEFS)" TRANSLATE_PROPERTIES = \ "Macro Search Path" "$(shell pwd)/../../coregen/" diff --git a/usrp2/top/N2x0/Makefile.N200R4 b/usrp2/top/N2x0/Makefile.N200R4 index 551f7a232..5c9ffd7a6 100644 --- a/usrp2/top/N2x0/Makefile.N200R4 +++ b/usrp2/top/N2x0/Makefile.N200R4 @@ -1,5 +1,5 @@ # -# Copyright 2008 Ettus Research LLC +# Copyright 2008-2012 Ettus Research LLC # ################################################## @@ -8,6 +8,10 @@ TOP_MODULE = u2plus BUILD_DIR = $(abspath build$(ISE)-N200R4) +# set me in a custom makefile +CUSTOM_SRCS = +CUSTOM_DEFS = + ################################################## # Include other makefiles ################################################## @@ -24,7 +28,6 @@ include ../../vrt/Makefile.srcs include ../../udp/Makefile.srcs include ../../coregen/Makefile.srcs include ../../extramfifo/Makefile.srcs -include ../../custom/Makefile.srcs ################################################## @@ -69,7 +72,7 @@ SYNTHESIZE_PROPERTIES = \ "Use Clock Enable" Auto \ "Use Synchronous Reset" Auto \ "Use Synchronous Set" Auto \ -"Verilog Macros" "LVDS=1" +"Verilog Macros" "LVDS=1 $(CUSTOM_DEFS)" TRANSLATE_PROPERTIES = \ "Macro Search Path" "$(shell pwd)/../../coregen/" diff --git a/usrp2/top/N2x0/Makefile.N210R3 b/usrp2/top/N2x0/Makefile.N210R3 index 2514600f4..0b53ac951 100644 --- a/usrp2/top/N2x0/Makefile.N210R3 +++ b/usrp2/top/N2x0/Makefile.N210R3 @@ -1,5 +1,5 @@ # -# Copyright 2008 Ettus Research LLC +# Copyright 2008-2012 Ettus Research LLC # ################################################## @@ -8,6 +8,10 @@ TOP_MODULE = u2plus BUILD_DIR = $(abspath build$(ISE)-N210R3) +# set me in a custom makefile +CUSTOM_SRCS = +CUSTOM_DEFS = + ################################################## # Include other makefiles ################################################## @@ -24,7 +28,6 @@ include ../../vrt/Makefile.srcs include ../../udp/Makefile.srcs include ../../coregen/Makefile.srcs include ../../extramfifo/Makefile.srcs -include ../../custom/Makefile.srcs ################################################## @@ -67,7 +70,8 @@ SYNTHESIZE_PROPERTIES = \ "Register Balancing" Yes \ "Use Clock Enable" Auto \ "Use Synchronous Reset" Auto \ -"Use Synchronous Set" Auto +"Use Synchronous Set" Auto \ +"Verilog Macros" "$(CUSTOM_DEFS)" TRANSLATE_PROPERTIES = \ "Macro Search Path" "$(shell pwd)/../../coregen/" diff --git a/usrp2/top/N2x0/Makefile.N210R4 b/usrp2/top/N2x0/Makefile.N210R4 index 951df0c7c..a7d2a9b49 100644 --- a/usrp2/top/N2x0/Makefile.N210R4 +++ b/usrp2/top/N2x0/Makefile.N210R4 @@ -1,5 +1,5 @@ # -# Copyright 2008 Ettus Research LLC +# Copyright 2008-2012 Ettus Research LLC # ################################################## @@ -8,6 +8,10 @@ TOP_MODULE = u2plus BUILD_DIR = $(abspath build$(ISE)-N210R4) +# set me in a custom makefile +CUSTOM_SRCS = +CUSTOM_DEFS = + ################################################## # Include other makefiles ################################################## @@ -24,7 +28,6 @@ include ../../vrt/Makefile.srcs include ../../udp/Makefile.srcs include ../../coregen/Makefile.srcs include ../../extramfifo/Makefile.srcs -include ../../custom/Makefile.srcs ################################################## @@ -69,7 +72,7 @@ SYNTHESIZE_PROPERTIES = \ "Use Clock Enable" Auto \ "Use Synchronous Reset" Auto \ "Use Synchronous Set" Auto \ -"Verilog Macros" "LVDS=1" +"Verilog Macros" "LVDS=1 $(CUSTOM_DEFS)" TRANSLATE_PROPERTIES = \ "Macro Search Path" "$(shell pwd)/../../coregen/" diff --git a/usrp2/top/USRP2/Makefile b/usrp2/top/USRP2/Makefile index adfaf06c4..1fc375c76 100644 --- a/usrp2/top/USRP2/Makefile +++ b/usrp2/top/USRP2/Makefile @@ -1,5 +1,5 @@ # -# Copyright 2008 Ettus Research LLC +# Copyright 2008-2012 Ettus Research LLC # ################################################## @@ -8,6 +8,10 @@ TOP_MODULE = u2_rev3 BUILD_DIR = $(abspath build) +# set me in a custom makefile +CUSTOM_SRCS = +CUSTOM_DEFS = + ################################################## # Include other makefiles ################################################## @@ -24,7 +28,6 @@ include ../../vrt/Makefile.srcs include ../../udp/Makefile.srcs include ../../coregen/Makefile.srcs include ../../extramfifo/Makefile.srcs -include ../../custom/Makefile.srcs ################################################## @@ -67,7 +70,8 @@ SYNTHESIZE_PROPERTIES = \ "Register Balancing" Yes \ "Use Clock Enable" Auto \ "Use Synchronous Reset" Auto \ -"Use Synchronous Set" Auto +"Use Synchronous Set" Auto \ +"Verilog Macros" "$(CUSTOM_DEFS)" TRANSLATE_PROPERTIES = \ "Macro Search Path" "$(shell pwd)/../../coregen/" diff --git a/usrp2/vrt/Makefile.srcs b/usrp2/vrt/Makefile.srcs index 166ed44ef..84ba5dc29 100644 --- a/usrp2/vrt/Makefile.srcs +++ b/usrp2/vrt/Makefile.srcs @@ -15,4 +15,6 @@ vita_tx_chain.v \ gen_context_pkt.v \ trigger_context_pkt.v \ vita_pkt_gen.v \ +vita_rx_engine_glue.v \ +vita_tx_engine_glue.v \ )) diff --git a/usrp2/vrt/vita_rx_chain.v b/usrp2/vrt/vita_rx_chain.v index bd416f563..e4f7e9864 100644 --- a/usrp2/vrt/vita_rx_chain.v +++ b/usrp2/vrt/vita_rx_chain.v @@ -74,7 +74,7 @@ module vita_rx_chain .data_i(rx_data_int), .src_rdy_i(rx_src_rdy_int), .dst_rdy_o(rx_dst_rdy_int), .data_o(rx_data_int2), .src_rdy_o(rx_src_rdy_int2), .dst_rdy_i(rx_dst_rdy_int2)); - custom_engine_rx #(.DSPNO(DSP_NUMBER), .MAIN_SETTINGS_BASE(BASE+9), .BUF_SIZE(FIFOSIZE)) dspengine_rx + vita_rx_engine_glue #(.DSPNO(DSP_NUMBER), .MAIN_SETTINGS_BASE(BASE+3), .BUF_SIZE(FIFOSIZE)) dspengine_rx (.clock(clk),.reset(reset),.clear(clear), .set_stb_main(set_stb), .set_addr_main(set_addr), .set_data_main(set_data), .set_stb_user(set_stb_user), .set_addr_user(set_addr_user), .set_data_user(set_data_user), diff --git a/usrp2/vrt/vita_rx_engine_glue.v b/usrp2/vrt/vita_rx_engine_glue.v new file mode 100644 index 000000000..86e3d1114 --- /dev/null +++ b/usrp2/vrt/vita_rx_engine_glue.v @@ -0,0 +1,95 @@ +// +// Copyright 2012 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 . +// + +//The following module is used to re-write receive packets to the host. +//This module provides a packet-based ram interface for manipulating packets. +//By default, this module uses the built-in 16 to 8 bit converter engine. + +module vita_rx_engine_glue +#( + //the dsp unit number: 0, 1, 2... + parameter DSPNO = 0, + + //buffer size for ram interface engine + parameter BUF_SIZE = 10, + + //base address for built-in settings registers used in this module + parameter MAIN_SETTINGS_BASE = 0 +) +( + //control signals + input clock, input reset, input clear, + + //main settings bus for built-in modules + input set_stb_main, input [7:0] set_addr_main, input [31:0] set_data_main, + + //user settings bus, controlled through user setting regs API + input set_stb_user, input [7:0] set_addr_user, input [31:0] set_data_user, + + //ram interface for engine + output access_we, + output access_stb, + input access_ok, + output access_done, + output access_skip_read, + output [BUF_SIZE-1:0] access_adr, + input [BUF_SIZE-1:0] access_len, + output [35:0] access_dat_o, + input [35:0] access_dat_i, + + //debug output (optional) + output [31:0] debug +); + + generate + if (DSPNO==0) begin + `ifndef RX_ENG0_MODULE + dspengine_16to8 #(.BASE(MAIN_SETTINGS_BASE), .BUF_SIZE(BUF_SIZE)) dspengine_16to8 + (.clk(clock),.reset(reset),.clear(clear), + .set_stb(set_stb_main), .set_addr(set_addr_main), .set_data(set_data_main), + .access_we(access_we), .access_stb(access_stb), .access_ok(access_ok), .access_done(access_done), + .access_skip_read(access_skip_read), .access_adr(access_adr), .access_len(access_len), + .access_dat_i(access_dat_i), .access_dat_o(access_dat_o)); + `else + RX_ENG0_MODULE #(.BUF_SIZE(BUF_SIZE)) rx_eng0_custom + (.clock(clock),.reset(reset),.clear(clear), + .set_stb(set_stb_user), .set_addr(set_addr_user), .set_data(set_data_user), + .access_we(access_we), .access_stb(access_stb), .access_ok(access_ok), .access_done(access_done), + .access_skip_read(access_skip_read), .access_adr(access_adr), .access_len(access_len), + .access_dat_i(access_dat_i), .access_dat_o(access_dat_o)); + `endif + end + else begin + `ifndef RX_ENG1_MODULE + dspengine_16to8 #(.BASE(MAIN_SETTINGS_BASE), .BUF_SIZE(BUF_SIZE)) dspengine_16to8 + (.clk(clock),.reset(reset),.clear(clear), + .set_stb(set_stb_main), .set_addr(set_addr_main), .set_data(set_data_main), + .access_we(access_we), .access_stb(access_stb), .access_ok(access_ok), .access_done(access_done), + .access_skip_read(access_skip_read), .access_adr(access_adr), .access_len(access_len), + .access_dat_i(access_dat_i), .access_dat_o(access_dat_o)); + `else + RX_ENG1_MODULE #(.BUF_SIZE(BUF_SIZE)) rx_eng1_custom + (.clock(clock),.reset(reset),.clear(clear), + .set_stb(set_stb_user), .set_addr(set_addr_user), .set_data(set_data_user), + .access_we(access_we), .access_stb(access_stb), .access_ok(access_ok), .access_done(access_done), + .access_skip_read(access_skip_read), .access_adr(access_adr), .access_len(access_len), + .access_dat_i(access_dat_i), .access_dat_o(access_dat_o)); + `endif + end + endgenerate + +endmodule //vita_rx_engine_glue diff --git a/usrp2/vrt/vita_tx_chain.v b/usrp2/vrt/vita_tx_chain.v index 78f63b555..93bc703cd 100644 --- a/usrp2/vrt/vita_tx_chain.v +++ b/usrp2/vrt/vita_tx_chain.v @@ -19,6 +19,7 @@ module vita_tx_chain #(parameter BASE=0, parameter FIFOSIZE=10, + parameter POST_ENGINE_FIFOSIZE=10, parameter REPORT_ERROR=0, parameter DO_FLOW_CONTROL=0, parameter PROT_ENG_FLAGS=0, @@ -75,6 +76,8 @@ module vita_tx_chain wire [FIFOSIZE-1:0] access_adr, access_len; wire access_we, access_stb, access_ok, access_done, access_skip_read; wire [35:0] dsp_to_buf, buf_to_dsp; + wire [35:0] tx_data_int0; + wire tx_src_rdy_int0, tx_dst_rdy_int0; double_buffer #(.BUF_SIZE(FIFOSIZE)) db (.clk(clk),.reset(reset),.clear(clear), @@ -83,15 +86,21 @@ module vita_tx_chain .access_dat_i(dsp_to_buf), .access_dat_o(buf_to_dsp), .data_i(tx_data_i), .src_rdy_i(tx_src_rdy_i), .dst_rdy_o(tx_dst_rdy_o), - .data_o(tx_data_int1), .src_rdy_o(tx_src_rdy_int1), .dst_rdy_i(tx_dst_rdy_int1)); + .data_o(tx_data_int0), .src_rdy_o(tx_src_rdy_int0), .dst_rdy_i(tx_dst_rdy_int0)); - custom_engine_tx #(.DSPNO(DSP_NUMBER), .MAIN_SETTINGS_BASE(BASE+6), .BUF_SIZE(FIFOSIZE), .HEADER_OFFSET(USE_TRANS_HEADER)) dspengine_tx + vita_tx_engine_glue #(.DSPNO(DSP_NUMBER), .MAIN_SETTINGS_BASE(BASE+1), .BUF_SIZE(FIFOSIZE), .HEADER_OFFSET(USE_TRANS_HEADER)) dspengine_tx (.clock(clk),.reset(reset),.clear(clear), .set_stb_main(set_stb), .set_addr_main(set_addr), .set_data_main(set_data), .set_stb_user(set_stb_user), .set_addr_user(set_addr_user), .set_data_user(set_data_user), .access_we(access_we), .access_stb(access_stb), .access_ok(access_ok), .access_done(access_done), .access_skip_read(access_skip_read), .access_adr(access_adr), .access_len(access_len), .access_dat_i(buf_to_dsp), .access_dat_o(dsp_to_buf)); + + fifo_cascade #(.WIDTH(36), .SIZE(POST_ENGINE_FIFOSIZE)) post_engine_buffering( + .clk(clk), .reset(reset), .clear(clear), + .datain(tx_data_int0), .src_rdy_i(tx_src_rdy_int0), .dst_rdy_o(tx_dst_rdy_int0), + .dataout(tx_data_int1), .src_rdy_o(tx_src_rdy_int1), .dst_rdy_i(tx_dst_rdy_int1)); + end endgenerate diff --git a/usrp2/vrt/vita_tx_engine_glue.v b/usrp2/vrt/vita_tx_engine_glue.v new file mode 100644 index 000000000..b0a81c3e9 --- /dev/null +++ b/usrp2/vrt/vita_tx_engine_glue.v @@ -0,0 +1,99 @@ +// +// Copyright 2012 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 . +// + +//The following module is used to re-write transmit packets from the host. +//This module provides a packet-based ram interface for manipulating packets. +//By default, this module uses the built-in 8 to 16 bit converter engine. + +module vita_tx_engine_glue +#( + //the dsp unit number: 0, 1, 2... + parameter DSPNO = 0, + + //buffer size for ram interface engine + parameter BUF_SIZE = 10, + + //base address for built-in settings registers used in this module + parameter MAIN_SETTINGS_BASE = 0, + + //the number of 32bit lines between start of buffer and vita header + //the metadata before the header should be preserved by the engine + parameter HEADER_OFFSET = 0 +) +( + //control signals + input clock, input reset, input clear, + + //main settings bus for built-in modules + input set_stb_main, input [7:0] set_addr_main, input [31:0] set_data_main, + + //user settings bus, controlled through user setting regs API + input set_stb_user, input [7:0] set_addr_user, input [31:0] set_data_user, + + //ram interface for engine + output access_we, + output access_stb, + input access_ok, + output access_done, + output access_skip_read, + output [BUF_SIZE-1:0] access_adr, + input [BUF_SIZE-1:0] access_len, + output [35:0] access_dat_o, + input [35:0] access_dat_i, + + //debug output (optional) + output [31:0] debug +); + + generate + if (DSPNO==0) begin + `ifndef TX_ENG0_MODULE + dspengine_8to16 #(.BASE(MAIN_SETTINGS_BASE), .BUF_SIZE(BUF_SIZE), .HEADER_OFFSET(HEADER_OFFSET)) dspengine_8to16 + (.clk(clock),.reset(reset),.clear(clear), + .set_stb(set_stb_main), .set_addr(set_addr_main), .set_data(set_data_main), + .access_we(access_we), .access_stb(access_stb), .access_ok(access_ok), .access_done(access_done), + .access_skip_read(access_skip_read), .access_adr(access_adr), .access_len(access_len), + .access_dat_i(access_dat_i), .access_dat_o(access_dat_o)); + `else + TX_ENG0_MODULE #(.BUF_SIZE(BUF_SIZE), .HEADER_OFFSET(HEADER_OFFSET)) tx_eng0_custom + (.clock(clock),.reset(reset),.clear(clear), + .set_stb(set_stb_user), .set_addr(set_addr_user), .set_data(set_data_user), + .access_we(access_we), .access_stb(access_stb), .access_ok(access_ok), .access_done(access_done), + .access_skip_read(access_skip_read), .access_adr(access_adr), .access_len(access_len), + .access_dat_i(access_dat_i), .access_dat_o(access_dat_o)); + `endif + end + else begin + `ifndef TX_ENG1_MODULE + dspengine_8to16 #(.BASE(MAIN_SETTINGS_BASE), .BUF_SIZE(BUF_SIZE), .HEADER_OFFSET(HEADER_OFFSET)) dspengine_8to16 + (.clk(clock),.reset(reset),.clear(clear), + .set_stb(set_stb_main), .set_addr(set_addr_main), .set_data(set_data_main), + .access_we(access_we), .access_stb(access_stb), .access_ok(access_ok), .access_done(access_done), + .access_skip_read(access_skip_read), .access_adr(access_adr), .access_len(access_len), + .access_dat_i(access_dat_i), .access_dat_o(access_dat_o)); + `else + TX_ENG1_MODULE #(.BUF_SIZE(BUF_SIZE), .HEADER_OFFSET(HEADER_OFFSET)) tx_eng1_custom + (.clock(clock),.reset(reset),.clear(clear), + .set_stb(set_stb_user), .set_addr(set_addr_user), .set_data(set_data_user), + .access_we(access_we), .access_stb(access_stb), .access_ok(access_ok), .access_done(access_done), + .access_skip_read(access_skip_read), .access_adr(access_adr), .access_len(access_len), + .access_dat_i(access_dat_i), .access_dat_o(access_dat_o)); + `endif + end + endgenerate + +endmodule //vita_tx_engine_glue -- cgit v1.2.3 From 97a8f455c1c023d39e72138a736f08c97dbfe346 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Thu, 2 Feb 2012 20:09:28 -0800 Subject: dsp rework: move setting address of format register --- host/lib/usrp/cores/rx_dsp_core_200.cpp | 2 +- host/lib/usrp/cores/tx_dsp_core_200.cpp | 8 +++----- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/host/lib/usrp/cores/rx_dsp_core_200.cpp b/host/lib/usrp/cores/rx_dsp_core_200.cpp index 7b35daa42..d9ca84e0f 100644 --- a/host/lib/usrp/cores/rx_dsp_core_200.cpp +++ b/host/lib/usrp/cores/rx_dsp_core_200.cpp @@ -44,7 +44,7 @@ #define REG_RX_CTRL_VRT_TLR _ctrl_base + 24 #define REG_RX_CTRL_NSAMPS_PP _ctrl_base + 28 #define REG_RX_CTRL_NCHANNELS _ctrl_base + 32 -#define REG_RX_CTRL_FORMAT _ctrl_base + 36 +#define REG_RX_CTRL_FORMAT REG_RX_CTRL_CLEAR //re-use clear address template T ceil_log2(T num){ return std::ceil(std::log(num)/std::log(T(2))); diff --git a/host/lib/usrp/cores/tx_dsp_core_200.cpp b/host/lib/usrp/cores/tx_dsp_core_200.cpp index 15358e184..e25528213 100644 --- a/host/lib/usrp/cores/tx_dsp_core_200.cpp +++ b/host/lib/usrp/cores/tx_dsp_core_200.cpp @@ -30,13 +30,12 @@ #define REG_DSP_TX_SCALE_IQ _dsp_base + 4 #define REG_DSP_TX_INTERP _dsp_base + 8 -#define REG_TX_CTRL_NUM_CHAN _ctrl_base + 0 -#define REG_TX_CTRL_CLEAR_STATE _ctrl_base + 4 +#define REG_TX_CTRL_CLEAR _ctrl_base + 4 #define REG_TX_CTRL_REPORT_SID _ctrl_base + 8 #define REG_TX_CTRL_POLICY _ctrl_base + 12 #define REG_TX_CTRL_CYCLES_PER_UP _ctrl_base + 16 #define REG_TX_CTRL_PACKETS_PER_UP _ctrl_base + 20 -#define REG_TX_CTRL_FORMAT _ctrl_base + 24 +#define REG_TX_CTRL_FORMAT REG_TX_CTRL_CLEAR //re-use clear address #define FLAG_TX_CTRL_POLICY_WAIT (0x1 << 0) #define FLAG_TX_CTRL_POLICY_NEXT_PACKET (0x1 << 1) @@ -70,8 +69,7 @@ public: } void clear(void){ - _iface->poke32(REG_TX_CTRL_CLEAR_STATE, 1); //reset - _iface->poke32(REG_TX_CTRL_NUM_CHAN, 0); //1 channel + _iface->poke32(REG_TX_CTRL_CLEAR, 1); //reset _iface->poke32(REG_TX_CTRL_REPORT_SID, _sid); } -- cgit v1.2.3 From ae1997f869695726c71cb671bb80e29709c9888d Mon Sep 17 00:00:00 2001 From: Matt Ettus Date: Thu, 2 Feb 2012 20:57:39 -0800 Subject: power_trig: test code for power trigger --- usrp2/custom/power_trig_tb.v | 71 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 usrp2/custom/power_trig_tb.v diff --git a/usrp2/custom/power_trig_tb.v b/usrp2/custom/power_trig_tb.v new file mode 100644 index 000000000..b8f3385ce --- /dev/null +++ b/usrp2/custom/power_trig_tb.v @@ -0,0 +1,71 @@ +// +// Copyright 2012 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 . +// + + +module power_trig_tb(); + initial $dumpfile("power_trig_tb.vcd"); + initial $dumpvars(0,power_trig_tb); + + reg clk = 0; + always #10 clk <= ~clk; + reg rst = 1; + initial #100 rst <= 0; + + initial + begin + set_stb <= 0; + #1000; + set_stb <= 1; + end + + reg [31:0] sample_in; + reg strobe_in; + wire [31:0] sample_out; + wire strobe_out; + reg set_stb, run; + + power_trig #(.BASE(0)) power_trig + (.clk(clk), .reset(rst), .enable(1), + .set_stb(set_stb), .set_addr(0), .set_data(32'h000B_B000), + .run(run), + + .ddc_out_sample(sample_in), .ddc_out_strobe(strobe_in), + .bb_sample(sample_out), .bb_strobe(strobe_out)); + + initial sample_in <= 32'h0100_0300; + + always @(posedge clk) + if(~strobe_in) + sample_in <= sample_in + 32'h0001_0001; + + initial + #100000 $finish; + + initial + begin + run <= 0; + #2000 run <= 1; + #30000 run <= 0; + end + + always @(posedge clk) + if(rst | ~run) + strobe_in <= 0; + else + strobe_in <= ~strobe_in; + +endmodule // power_trig_tb -- cgit v1.2.3 From f88dd2289b714b53a59d0fd6da1ddef549940e51 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Fri, 3 Feb 2012 10:57:49 -0800 Subject: dsp rework: added otw mode for benchmark app --- host/examples/benchmark_rate.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/host/examples/benchmark_rate.cpp b/host/examples/benchmark_rate.cpp index fce184514..8f00e25de 100644 --- a/host/examples/benchmark_rate.cpp +++ b/host/examples/benchmark_rate.cpp @@ -40,11 +40,11 @@ unsigned long long num_seq_errors = 0; /*********************************************************************** * Benchmark RX Rate **********************************************************************/ -void benchmark_rx_rate(uhd::usrp::multi_usrp::sptr usrp){ +void benchmark_rx_rate(uhd::usrp::multi_usrp::sptr usrp, const std::string &rx_otw){ uhd::set_thread_priority_safe(); //create a receive streamer - uhd::stream_args_t stream_args("fc32"); //complex floats + uhd::stream_args_t stream_args("fc32", rx_otw); //complex floats uhd::rx_streamer::sptr rx_stream = usrp->get_rx_stream(stream_args); //print pre-test summary @@ -94,11 +94,11 @@ void benchmark_rx_rate(uhd::usrp::multi_usrp::sptr usrp){ /*********************************************************************** * Benchmark TX Rate **********************************************************************/ -void benchmark_tx_rate(uhd::usrp::multi_usrp::sptr usrp){ +void benchmark_tx_rate(uhd::usrp::multi_usrp::sptr usrp, const std::string &tx_otw){ uhd::set_thread_priority_safe(); //create a transmit streamer - uhd::stream_args_t stream_args("fc32"); //complex floats + uhd::stream_args_t stream_args("fc32", tx_otw); //complex floats uhd::tx_streamer::sptr tx_stream = usrp->get_tx_stream(stream_args); //print pre-test summary @@ -162,6 +162,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ std::string args; double duration; double rx_rate, tx_rate; + std::string rx_otw, tx_otw; //setup the program options po::options_description desc("Allowed options"); @@ -171,6 +172,8 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ ("duration", po::value(&duration)->default_value(10.0), "duration for the test in seconds") ("rx_rate", po::value(&rx_rate), "specify to perform a RX rate test (sps)") ("tx_rate", po::value(&tx_rate), "specify to perform a TX rate test (sps)") + ("rx_otw", po::value(&rx_otw)->default_value("sc16"), "specify the over-the-wire sample mode for RX") + ("tx_otw", po::value(&tx_otw)->default_value("sc16"), "specify the over-the-wire sample mode for TX") ; po::variables_map vm; po::store(po::parse_command_line(argc, argv, desc), vm); @@ -203,13 +206,13 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ //spawn the receive test thread if (vm.count("rx_rate")){ usrp->set_rx_rate(rx_rate); - thread_group.create_thread(boost::bind(&benchmark_rx_rate, usrp)); + thread_group.create_thread(boost::bind(&benchmark_rx_rate, usrp, rx_otw)); } //spawn the transmit test thread if (vm.count("tx_rate")){ usrp->set_tx_rate(tx_rate); - thread_group.create_thread(boost::bind(&benchmark_tx_rate, usrp)); + thread_group.create_thread(boost::bind(&benchmark_tx_rate, usrp, tx_otw)); thread_group.create_thread(boost::bind(&benchmark_tx_rate_async_helper, usrp)); } -- cgit v1.2.3 From 1b489be22ca07a949a9bea59f0040c0c3d770d8a Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Fri, 3 Feb 2012 15:35:07 -0800 Subject: b100: connect all clears for gpif --- usrp2/gpif/packet_reframer.v | 13 +++---------- usrp2/gpif/slave_fifo.v | 8 ++++---- usrp2/top/B100/u1plus_core.v | 2 +- 3 files changed, 8 insertions(+), 15 deletions(-) diff --git a/usrp2/gpif/packet_reframer.v b/usrp2/gpif/packet_reframer.v index 0d8232653..1e913fd77 100644 --- a/usrp2/gpif/packet_reframer.v +++ b/usrp2/gpif/packet_reframer.v @@ -38,7 +38,7 @@ module packet_reframer always @(posedge clk) if(reset | clear) - state <= 0; + state <= RF_IDLE; else if(src_rdy_i & dst_rdy_i) case(state) @@ -49,16 +49,9 @@ module packet_reframer end RF_PKT : begin - if(length == 2) - begin - state <= RF_IDLE; - length <= 0; - end - else - length <= length - 1; + if(eof_out) state <= RF_IDLE; + length <= length - 1; end - default : - state <= RF_IDLE; endcase // case (state) assign dst_rdy_o = dst_rdy_i; // this is a little pessimistic but ok diff --git a/usrp2/gpif/slave_fifo.v b/usrp2/gpif/slave_fifo.v index 2f98043ab..b7d740619 100644 --- a/usrp2/gpif/slave_fifo.v +++ b/usrp2/gpif/slave_fifo.v @@ -244,7 +244,7 @@ module slave_fifo data_tx_dst_rdy <= wr_fifo_space >= 256; fifo_cascade #(.WIDTH(18), .SIZE(12)) wr_fifo - (.clk(gpif_clk), .reset(gpif_rst), .clear(0), + (.clk(gpif_clk), .reset(gpif_rst), .clear(clear_tx), .datain({eop,sop,gpif_d}), .src_rdy_i(data_tx_src_rdy), .dst_rdy_o(/*data_tx_dst_rdy*/), .space(wr_fifo_space), .dataout(data_tx_int), .src_rdy_o(tx_src_rdy_int), .dst_rdy_i(tx_dst_rdy_int), .occupied()); @@ -269,7 +269,7 @@ module slave_fifo .state(refr_state), .eof_out(refr_eof), .length(refr_len)); fifo19_to_fifo36 #(.LE(1)) f19_to_f36 - (.clk(fifo_clk), .reset(fifo_rst), .clear(0), + (.clk(fifo_clk), .reset(fifo_rst), .clear(clear_tx), .f19_datain(refr_data), .f19_src_rdy_i(refr_src_rdy), .f19_dst_rdy_o(refr_dst_rdy), .f36_dataout(tx36_data), .f36_src_rdy_o(tx36_src_rdy), .f36_dst_rdy_i(tx36_dst_rdy)); @@ -309,7 +309,7 @@ module slave_fifo //rd_fifo buffers writes to the 2clock fifo above fifo_cascade #(.WIDTH(19), .SIZE(RXFIFOSIZE)) rd_fifo - (.clk(~gpif_clk), .reset(gpif_rst), .clear(0), + (.clk(~gpif_clk), .reset(gpif_rst), .clear(clear_rx), .datain(data_rx_int), .src_rdy_i(rx_src_rdy_int), .dst_rdy_o(rx_dst_rdy_int), .space(rxfifospace), .dataout(gpif_d_out_data), .src_rdy_o(data_rx_src_rdy), .dst_rdy_i(data_rx_dst_rdy), .occupied()); @@ -359,7 +359,7 @@ module slave_fifo //mux FIFO-to-WB along with async tx err pkts into one ctrl resp fifo //how is this clocked on wb_clk? fifo19_mux #(.prio(0)) mux_err_stream - (.clk(wb_clk), .reset(wb_rst), .clear(0), + (.clk(wb_clk), .reset(wb_rst), .clear(clear_rx), .data0_i(resp_int), .src0_rdy_i(resp_src_rdy_int), .dst0_rdy_o(resp_dst_rdy_int), .data1_i(tx_err19_data), .src1_rdy_i(tx_err19_src_rdy), .dst1_rdy_o(tx_err19_dst_rdy), .data_o(resp_data), .src_rdy_o(resp_src_rdy), .dst_rdy_i(resp_dst_rdy)); diff --git a/usrp2/top/B100/u1plus_core.v b/usrp2/top/B100/u1plus_core.v index 88a8b4f4b..c6ef80751 100644 --- a/usrp2/top/B100/u1plus_core.v +++ b/usrp2/top/B100/u1plus_core.v @@ -207,7 +207,7 @@ module u1plus_core // RX Stream muxing fifo36_mux #(.prio(0)) mux_data_streams - (.clk(wb_clk), .reset(wb_rst), .clear(0), + (.clk(wb_clk), .reset(wb_rst), .clear(clear_rx), .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)); -- cgit v1.2.3 From 0d2acffaf4d3e3b02dc9745e94b407356650f923 Mon Sep 17 00:00:00 2001 From: Nick Foster Date: Fri, 3 Feb 2012 17:36:07 -0800 Subject: B100/B150: firmware disable FIFOs until host enables to keep junk out --- firmware/fx2/b100/usrp_common.c | 2 +- firmware/fx2/b100/usrp_main.c | 17 ++++++++++------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/firmware/fx2/b100/usrp_common.c b/firmware/fx2/b100/usrp_common.c index 7aedce9f7..a8f29d1fa 100644 --- a/firmware/fx2/b100/usrp_common.c +++ b/firmware/fx2/b100/usrp_common.c @@ -33,7 +33,7 @@ init_usrp (void) CKCON = 0; // MOVX takes 2 cycles // IFCLK is generated internally and runs at 48 MHz; slave FIFO mode - IFCONFIG = bmIFCLKSRC | bm3048MHZ | bmIFCLKOE | bmIFSLAVE; + IFCONFIG = bmIFCLKSRC | bm3048MHZ | bmIFCLKOE; SYNCDELAY; // configure IO ports (B and D are used by slave FIFO) diff --git a/firmware/fx2/b100/usrp_main.c b/firmware/fx2/b100/usrp_main.c index fdc4fce48..436bdeb36 100644 --- a/firmware/fx2/b100/usrp_main.c +++ b/firmware/fx2/b100/usrp_main.c @@ -81,6 +81,15 @@ static void initialize_gpif_buffer(int ep) { FIFORESET = 0x00; SYNCDELAY; } +void enable_xfers(int enable) { + if(enable) { + IFCONFIG |= bmIFSLAVE; + } else { + IFCONFIG &= ~bmIFSLAVE; + } + set_led_0(enable); +} + /* * Handle our "Vendor Extension" commands on endpoint 0. * If we handle this one, return non-zero. @@ -174,6 +183,7 @@ app_vendor_cmd (void) break; case VRQ_ENABLE_GPIF: + enable_xfers(wValueL); break; case VRQ_CLEAR_FPGA_FIFO: @@ -266,13 +276,6 @@ main (void) EA = 1; // global interrupt enable fx2_renumerate (); // simulates disconnect / reconnect - -// setup_flowstate_common(); - -//set up gpif slave mode here - //set slave FIFO mode - //set synchronous slave mode - ////both done in init_usrp() //set FLAGA, FLAGB, FLAGC, FLAGD to be EP2EF, EP4EF, EP6PF, EP8PF PINFLAGSAB = (bmEP2EF) | (bmEP4EF << 4); -- cgit v1.2.3 From 04e9d23d5f9f300164182597b0e0525063bd91e4 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Sat, 4 Feb 2012 08:41:54 -0800 Subject: b100: delete some unused registers from map --- host/lib/usrp/b100/b100_regs.hpp | 4 ---- host/lib/usrp/b100/io_impl.cpp | 3 --- 2 files changed, 7 deletions(-) diff --git a/host/lib/usrp/b100/b100_regs.hpp b/host/lib/usrp/b100/b100_regs.hpp index b87a0ad73..cc94d0a2a 100644 --- a/host/lib/usrp/b100/b100_regs.hpp +++ b/host/lib/usrp/b100/b100_regs.hpp @@ -42,10 +42,6 @@ #define B100_REG_MISC_SW B100_REG_MISC_BASE + 2 #define B100_REG_MISC_CGEN_CTRL B100_REG_MISC_BASE + 4 #define B100_REG_MISC_CGEN_ST B100_REG_MISC_BASE + 6 -#define B100_REG_MISC_TEST B100_REG_MISC_BASE + 8 -#define B100_REG_MISC_RX_LEN B100_REG_MISC_BASE + 10 -#define B100_REG_MISC_TX_LEN B100_REG_MISC_BASE + 12 -#define B100_REG_MISC_XFER_RATE B100_REG_MISC_BASE + 14 ///////////////////////////////////////////////////// // Slave 1 -- UART diff --git a/host/lib/usrp/b100/io_impl.cpp b/host/lib/usrp/b100/io_impl.cpp index b1a44d70e..db5af0dc5 100644 --- a/host/lib/usrp/b100/io_impl.cpp +++ b/host/lib/usrp/b100/io_impl.cpp @@ -58,9 +58,6 @@ void b100_impl::io_init(void){ _fpga_ctrl->poke32(B100_REG_CLEAR_RX, 0); _fpga_ctrl->poke32(B100_REG_CLEAR_TX, 0); - //set the expected packet size in USB frames - _fpga_ctrl->poke32(B100_REG_MISC_RX_LEN, 4); - //allocate streamer weak ptrs containers _rx_streamers.resize(_rx_dsps.size()); _tx_streamers.resize(1/*known to be 1 dsp*/); -- cgit v1.2.3 From 89ce89c9aca6daf7e293b80c70e14a3e2710e137 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Sat, 4 Feb 2012 15:12:03 -0800 Subject: b100: timing constraints on GPIF lines --- usrp2/top/B100/timing.ucf | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/usrp2/top/B100/timing.ucf b/usrp2/top/B100/timing.ucf index b2a455f6d..96c47cf2c 100644 --- a/usrp2/top/B100/timing.ucf +++ b/usrp2/top/B100/timing.ucf @@ -3,3 +3,12 @@ TIMESPEC "TS_CLK_FPGA_P" = PERIOD "CLK_FPGA_P" 15625 ps HIGH 50 %; NET "IFCLK" TNM_NET = "IFCLK"; TIMESPEC "TS_IFCLK" = PERIOD "IFCLK" 20833 ps HIGH 50 %; + +#constrain FX2 IO +NET "GPIF_D<*>" MAXDELAY = 5.5 ns; +NET "GPIF_CTL<*>" MAXDELAY = 5.5 ns; +NET "GPIF_ADR<*>" MAXDELAY = 5.5ns; +NET "GPIF_SLWR" MAXDELAY = 5.5 ns; +NET "GPIF_SLRD" MAXDELAY = 5.5 ns; +NET "GPIF_SLOE" MAXDELAY = 5.5 ns; +NET "GPIF_PKTEND" MAXDELAY = 5.5 ns; -- cgit v1.2.3 From 1e3cb86432ee1d695a12fd99590206e43caab2cc Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Sat, 4 Feb 2012 15:12:37 -0800 Subject: uhd: added/renamed various readme files --- README.txt | 19 ++++++++++++++ firmware/README | 6 ----- firmware/README.txt | 31 +++++++++++++++++++++++ fix-copyright-years | 71 ----------------------------------------------------- fpga/README | 4 --- images/README | 25 ------------------- images/README.txt | 25 +++++++++++++++++++ 7 files changed, 75 insertions(+), 106 deletions(-) create mode 100644 README.txt delete mode 100644 firmware/README create mode 100644 firmware/README.txt delete mode 100755 fix-copyright-years delete mode 100644 fpga/README delete mode 100644 images/README create mode 100644 images/README.txt diff --git a/README.txt b/README.txt new file mode 100644 index 000000000..64066d522 --- /dev/null +++ b/README.txt @@ -0,0 +1,19 @@ +######################################################################## +## Welcome to the USRP source code tree +######################################################################## + +host/ + + Description: source code for user-space driver + +firmware/ + + Description: source code for various micro processors + +fpga/ + + Description: source code for FPGA designs + +images/ + + Description: package builder for FPGA and firmware images diff --git a/firmware/README b/firmware/README deleted file mode 100644 index 251486955..000000000 --- a/firmware/README +++ /dev/null @@ -1,6 +0,0 @@ -######################################################################## -# Firmware for USRP devices -######################################################################## - -fx2 - firmware for USRP1 -zpu - firmware for USRP2 and N Series diff --git a/firmware/README.txt b/firmware/README.txt new file mode 100644 index 000000000..1c233de1d --- /dev/null +++ b/firmware/README.txt @@ -0,0 +1,31 @@ +######################################################################## +# Firmware for USRP devices +######################################################################## + +fx2/ + + Description: firmware for FX2 device + + Devices: USRP1 and B100 + + Tools: sdcc, cmake + + Build Instructions: + 1) mkdir + 2) cd + 3) cmake + 4) make + +zpu/ + + Description: firmware for soft CPU in FPGA + + Devices: USRP2 and N Series + + Tools: zpu-gcc, cmake + + Build Instructions: + 1) mkdir + 2) cd + 3) cmake + 4) make diff --git a/fix-copyright-years b/fix-copyright-years deleted file mode 100755 index 97630041b..000000000 --- a/fix-copyright-years +++ /dev/null @@ -1,71 +0,0 @@ -#!/usr/bin/env python - -import re -import optparse -import datetime -import subprocess -import multiprocessing - -co_line_matcher = re.compile('^.*Copyright (.*) Ettus Research LLC$') - -def command(*args): return subprocess.Popen(args, stdout=subprocess.PIPE).communicate()[0] - -def get_co_line(lines): - for i, line in enumerate(lines[:5]): - if co_line_matcher.match(line): return line, i - return None, None - -def fix_co_years(files, keep_years): - for file in files: - print file - lines = open(file).readlines() - line, num = get_co_line(lines) - if line is None: continue - - #extract the years from the git history - log_years = map( - lambda l: int(l.split()[-2]), - filter( - lambda l: l.startswith('Date'), - command('git', 'log', file).splitlines(), - ), - ) - log_years = min(log_years), max(log_years) - - #extract years from co string - try: - co_years_str = co_line_matcher.match(line).groups()[0] - co_years = map(int, co_years_str.split('-')) - co_years = min(co_years), max(co_years) - except Exception, e: - print ' format error on line %d: "%s"'%(num, line), e - continue - - #keep years means log years is a superset - if keep_years: log_years = min(co_years+log_years), max(co_years+log_years) - - if log_years != co_years: - print ' log years: %s != copyright years: %s'%(log_years, co_years) - year_now = datetime.datetime.now().year - all_years = min(log_years), max(list(log_years)+[year_now]) #add the current year - all_years_str = '%s-%s'%all_years - if all_years[0] == all_years[1]: all_years_str = str(all_years[0]) - new_text = ''.join(lines[:num] + [line.replace(co_years_str, all_years_str)] + lines[num+1:]) - open(file, 'w').write(new_text) - -if __name__ == "__main__": - parser = optparse.OptionParser(usage="usage: %prog [options] path") - parser.add_option("-k", "--keep", action="store_true", help="keep copyright years", default=False) - (options, args) = parser.parse_args() - - #get recursive list of files in the repo - files = command('git', 'ls-tree', '--name-only', 'HEAD', '-r', args[0]).splitlines() - - #start n+1 processes to handle the files - num_procs = multiprocessing.cpu_count() - procs = [multiprocessing.Process( - target=lambda *files: fix_co_years(files, keep_years=options.keep), - args=files[num::num_procs], - ) for num in range(num_procs)] - map(multiprocessing.Process.start, procs) - map(multiprocessing.Process.join, procs) diff --git a/fpga/README b/fpga/README deleted file mode 100644 index aacafecfd..000000000 --- a/fpga/README +++ /dev/null @@ -1,4 +0,0 @@ -This is a placeholder for the fpga code (verilog, makefiles, corgens...) - -The layout should have a common library and various top level builds -and testbenches that are organized hierarchically. diff --git a/images/README b/images/README deleted file mode 100644 index 2f9c6a95e..000000000 --- a/images/README +++ /dev/null @@ -1,25 +0,0 @@ -The images directory contains the following: - - a Makefile for building firmware and fpga images - - a CMake file for building an images package - -The Makefile and build systems for the images are probably Unix specific. -Its best to build the images on a Unix system with standard build tools. -The CMake package target will create an images package for your system. - -To build the images (unix): - make clean - make images - -To build the package (unix): - mkdir build - cd build - cmake -DCPACK_GENERATOR= ../ - make package - -The package generator types are described here: - http://www.cmake.org/Wiki/CMake:CPackPackageGenerators - -Fedora note: - The sdcc binaries are prefixed with "sdcc-" which breaks the build. - However, /usr/libexec/sdcc contains properly named sdcc binaries. - export PATH=${PATH}:/usr/libexec/sdcc diff --git a/images/README.txt b/images/README.txt new file mode 100644 index 000000000..2f9c6a95e --- /dev/null +++ b/images/README.txt @@ -0,0 +1,25 @@ +The images directory contains the following: + - a Makefile for building firmware and fpga images + - a CMake file for building an images package + +The Makefile and build systems for the images are probably Unix specific. +Its best to build the images on a Unix system with standard build tools. +The CMake package target will create an images package for your system. + +To build the images (unix): + make clean + make images + +To build the package (unix): + mkdir build + cd build + cmake -DCPACK_GENERATOR= ../ + make package + +The package generator types are described here: + http://www.cmake.org/Wiki/CMake:CPackPackageGenerators + +Fedora note: + The sdcc binaries are prefixed with "sdcc-" which breaks the build. + However, /usr/libexec/sdcc contains properly named sdcc binaries. + export PATH=${PATH}:/usr/libexec/sdcc -- cgit v1.2.3 From c6e63c9d2af2c0b2e168aa6fdd63fe7b214927de Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Sat, 4 Feb 2012 16:38:15 -0800 Subject: b100/e100: unify rx/tx fifo clears into one --- host/lib/usrp/b100/b100_regs.hpp | 6 ++---- host/lib/usrp/b100/io_impl.cpp | 5 ++--- host/lib/usrp/e100/e100_regs.hpp | 6 ++---- host/lib/usrp/e100/io_impl.cpp | 5 ++--- 4 files changed, 8 insertions(+), 14 deletions(-) diff --git a/host/lib/usrp/b100/b100_regs.hpp b/host/lib/usrp/b100/b100_regs.hpp index cc94d0a2a..77b643372 100644 --- a/host/lib/usrp/b100/b100_regs.hpp +++ b/host/lib/usrp/b100/b100_regs.hpp @@ -103,8 +103,7 @@ #define B100_SR_TX_FRONT 54 // 5 regs (+0 to +4) #define B100_SR_REG_TEST32 60 // 1 reg -#define B100_SR_CLEAR_RX_FIFO 61 // 1 reg -#define B100_SR_CLEAR_TX_FIFO 62 // 1 reg +#define B100_SR_CLEAR_FIFO 61 // 1 reg #define B100_SR_GLOBAL_RESET 63 // 1 reg #define B100_SR_USER_REGS 64 // 2 regs @@ -117,8 +116,7 @@ ///////////////////////////////////////////////// // Magic reset regs //////////////////////////////////////////////// -#define B100_REG_CLEAR_RX B100_REG_SR_ADDR(B100_SR_CLEAR_RX_FIFO) -#define B100_REG_CLEAR_TX B100_REG_SR_ADDR(B100_SR_CLEAR_RX_FIFO) +#define B100_REG_CLEAR_FIFO B100_REG_SR_ADDR(B100_SR_CLEAR_FIFO) #define B100_REG_GLOBAL_RESET B100_REG_SR_ADDR(B100_SR_GLOBAL_RESET) #endif diff --git a/host/lib/usrp/b100/io_impl.cpp b/host/lib/usrp/b100/io_impl.cpp index db5af0dc5..ac7c860d2 100644 --- a/host/lib/usrp/b100/io_impl.cpp +++ b/host/lib/usrp/b100/io_impl.cpp @@ -54,9 +54,8 @@ struct b100_impl::io_impl{ **********************************************************************/ void b100_impl::io_init(void){ - //clear state machines - _fpga_ctrl->poke32(B100_REG_CLEAR_RX, 0); - _fpga_ctrl->poke32(B100_REG_CLEAR_TX, 0); + //clear fifo state machines + _fpga_ctrl->poke32(B100_REG_CLEAR_FIFO, 0); //allocate streamer weak ptrs containers _rx_streamers.resize(_rx_dsps.size()); diff --git a/host/lib/usrp/e100/e100_regs.hpp b/host/lib/usrp/e100/e100_regs.hpp index eee27b5b3..0ec5f4de3 100644 --- a/host/lib/usrp/e100/e100_regs.hpp +++ b/host/lib/usrp/e100/e100_regs.hpp @@ -116,8 +116,7 @@ #define UE_SR_TX_FRONT 54 // 5 regs (+0 to +4) #define UE_SR_REG_TEST32 60 // 1 reg -#define UE_SR_CLEAR_RX_FIFO 61 // 1 reg -#define UE_SR_CLEAR_TX_FIFO 62 // 1 reg +#define UE_SR_CLEAR_FIFO 61 // 1 reg #define UE_SR_GLOBAL_RESET 63 // 1 reg #define UE_SR_USER_REGS 64 // 2 regs @@ -131,8 +130,7 @@ ///////////////////////////////////////////////// // Magic reset regs //////////////////////////////////////////////// -#define E100_REG_CLEAR_RX E100_REG_SR_ADDR(UE_SR_CLEAR_RX_FIFO) -#define E100_REG_CLEAR_TX E100_REG_SR_ADDR(UE_SR_CLEAR_RX_FIFO) +#define E100_REG_CLEAR_FIFO E100_REG_SR_ADDR(UE_SR_CLEAR_FIFO) #define E100_REG_GLOBAL_RESET E100_REG_SR_ADDR(UE_SR_GLOBAL_RESET) #endif diff --git a/host/lib/usrp/e100/io_impl.cpp b/host/lib/usrp/e100/io_impl.cpp index 4d530585b..8c7f5e742 100644 --- a/host/lib/usrp/e100/io_impl.cpp +++ b/host/lib/usrp/e100/io_impl.cpp @@ -164,9 +164,8 @@ void e100_impl::io_init(void){ _io_impl->demuxer = recv_packet_demuxer::make(_data_transport, _rx_dsps.size(), E100_RX_SID_BASE); _io_impl->iface = _fpga_ctrl; - //clear state machines - _fpga_ctrl->poke32(E100_REG_CLEAR_RX, 0); - _fpga_ctrl->poke32(E100_REG_CLEAR_TX, 0); + //clear fifo state machines + _fpga_ctrl->poke32(E100_REG_CLEAR_FIFO, 0); //allocate streamer weak ptrs containers _rx_streamers.resize(_rx_dsps.size()); -- cgit v1.2.3 From a9d307124faa679df8180b5624e9250555306d67 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Sat, 4 Feb 2012 16:38:54 -0800 Subject: dsp rework: pass vita clears into dsp modules, unified fifo clears --- usrp2/custom/custom_dsp_rx.v | 5 ++++- usrp2/custom/custom_dsp_tx.v | 5 ++++- usrp2/gpif/packet_reframer.v | 2 +- usrp2/gpif/slave_fifo.v | 2 +- usrp2/sdr_lib/ddc_chain.v | 4 ++-- usrp2/sdr_lib/dsp_rx_glue.v | 6 +++--- usrp2/sdr_lib/dsp_tx_glue.v | 6 +++--- usrp2/sdr_lib/duc_chain.v | 4 ++-- usrp2/top/B100/u1plus_core.v | 39 +++++++++++++++++---------------------- usrp2/top/E1x0/u1e_core.v | 40 ++++++++++++++++++---------------------- usrp2/top/N2x0/u2plus_core.v | 17 ++++++++--------- usrp2/top/USRP2/u2_core.v | 17 ++++++++--------- usrp2/vrt/vita_rx_chain.v | 5 +++-- usrp2/vrt/vita_tx_chain.v | 5 ++--- 14 files changed, 76 insertions(+), 81 deletions(-) diff --git a/usrp2/custom/custom_dsp_rx.v b/usrp2/custom/custom_dsp_rx.v index b90cd54e9..2ceda7481 100644 --- a/usrp2/custom/custom_dsp_rx.v +++ b/usrp2/custom/custom_dsp_rx.v @@ -36,7 +36,10 @@ module custom_dsp_rx ) ( //control signals - input clock, input reset, input enable, + input clock, //dsp clock + input reset, //active high synchronous reset + input clear, //active high on packet control init + input enable, //active high when streaming enabled //user settings bus, controlled through user setting regs API input set_stb, input [7:0] set_addr, input [31:0] set_data, diff --git a/usrp2/custom/custom_dsp_tx.v b/usrp2/custom/custom_dsp_tx.v index 4b1388b02..5206a63a6 100644 --- a/usrp2/custom/custom_dsp_tx.v +++ b/usrp2/custom/custom_dsp_tx.v @@ -36,7 +36,10 @@ module custom_dsp_tx ) ( //control signals - input clock, input reset, input enable, + input clock, //dsp clock + input reset, //active high synchronous reset + input clear, //active high on packet control init + input enable, //active high when streaming enabled //user settings bus, controlled through user setting regs API input set_stb, input [7:0] set_addr, input [31:0] set_data, diff --git a/usrp2/gpif/packet_reframer.v b/usrp2/gpif/packet_reframer.v index 1e913fd77..8bb8a3678 100644 --- a/usrp2/gpif/packet_reframer.v +++ b/usrp2/gpif/packet_reframer.v @@ -1,5 +1,5 @@ // -// Copyright 2011 Ettus Research LLC +// Copyright 2011-2012 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 diff --git a/usrp2/gpif/slave_fifo.v b/usrp2/gpif/slave_fifo.v index b7d740619..10740942b 100644 --- a/usrp2/gpif/slave_fifo.v +++ b/usrp2/gpif/slave_fifo.v @@ -1,5 +1,5 @@ // -// Copyright 2011 Ettus Research LLC +// Copyright 2011-2012 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 diff --git a/usrp2/sdr_lib/ddc_chain.v b/usrp2/sdr_lib/ddc_chain.v index 3dee978a5..800bb5b13 100644 --- a/usrp2/sdr_lib/ddc_chain.v +++ b/usrp2/sdr_lib/ddc_chain.v @@ -19,7 +19,7 @@ module ddc_chain #(parameter BASE = 0, parameter DSPNO = 0) - (input clk, input rst, + (input clk, input rst, input clr, input set_stb, input [7:0] set_addr, input [31:0] set_data, input set_stb_user, input [7:0] set_addr_user, input [31:0] set_data_user, @@ -166,7 +166,7 @@ module ddc_chain (.clk(clk),.reset(rst), .in(prod_reg_q),.strobe_in(strobe_mult), .out(ddc_chain_out[15:0]), .strobe_out()); dsp_rx_glue #(.DSPNO(DSPNO)) custom( - .clock(clk), .reset(rst), .enable(run), + .clock(clk), .reset(rst), .clear(clr), .enable(run), .set_stb(set_stb_user), .set_addr(set_addr_user), .set_data(set_data_user), .frontend_i(rx_fe_i_mux), .frontend_q(rx_fe_q_mux), .ddc_in_i(to_cordic_i), .ddc_in_q(to_cordic_q), diff --git a/usrp2/sdr_lib/dsp_rx_glue.v b/usrp2/sdr_lib/dsp_rx_glue.v index 2c7c188e0..e2a1d52b1 100644 --- a/usrp2/sdr_lib/dsp_rx_glue.v +++ b/usrp2/sdr_lib/dsp_rx_glue.v @@ -28,7 +28,7 @@ module dsp_rx_glue ) ( //control signals - input clock, input reset, input enable, + input clock, input reset, input clear, input enable, //user settings bus, controlled through user setting regs API input set_stb, input [7:0] set_addr, input [31:0] set_data, @@ -63,7 +63,7 @@ module dsp_rx_glue `else RX_DSP0_MODULE rx_dsp0_custom ( - .clock(clock), .reset(reset), .enable(enable), + .clock(clock), .reset(reset), .clear(clear), .enable(enable), .set_stb(set_stb), .set_addr(set_addr), .set_data(set_data), .frontend_i(frontend_i), .frontend_q(frontend_q), .ddc_in_i(ddc_in_i), .ddc_in_q(ddc_in_q), @@ -81,7 +81,7 @@ module dsp_rx_glue `else RX_DSP1_MODULE rx_dsp1_custom ( - .clock(clock), .reset(reset), .enable(enable), + .clock(clock), .reset(reset), .clear(clear), .enable(enable), .set_stb(set_stb), .set_addr(set_addr), .set_data(set_data), .frontend_i(frontend_i), .frontend_q(frontend_q), .ddc_in_i(ddc_in_i), .ddc_in_q(ddc_in_q), diff --git a/usrp2/sdr_lib/dsp_tx_glue.v b/usrp2/sdr_lib/dsp_tx_glue.v index 8eccd2bfc..9af13c6c1 100644 --- a/usrp2/sdr_lib/dsp_tx_glue.v +++ b/usrp2/sdr_lib/dsp_tx_glue.v @@ -28,7 +28,7 @@ module dsp_tx_glue ) ( //control signals - input clock, input reset, input enable, + input clock, input reset, input clear, input enable, //user settings bus, controlled through user setting regs API input set_stb, input [7:0] set_addr, input [31:0] set_data, @@ -63,7 +63,7 @@ module dsp_tx_glue `else TX_DSP0_MODULE tx_dsp0_custom ( - .clock(clock), .reset(reset), .enable(enable), + .clock(clock), .reset(reset), .clear(clear), .enable(enable), .set_stb(set_stb), .set_addr(set_addr), .set_data(set_data), .frontend_i(frontend_i), .frontend_q(frontend_q), .duc_out_i(duc_out_i), .duc_out_q(duc_out_q), @@ -81,7 +81,7 @@ module dsp_tx_glue `else TX_DSP1_MODULE tx_dsp1_custom ( - .clock(clock), .reset(reset), .enable(enable), + .clock(clock), .reset(reset), .clear(clear), .enable(enable), .set_stb(set_stb), .set_addr(set_addr), .set_data(set_data), .frontend_i(frontend_i), .frontend_q(frontend_q), .duc_out_i(duc_out_i), .duc_out_q(duc_out_q), diff --git a/usrp2/sdr_lib/duc_chain.v b/usrp2/sdr_lib/duc_chain.v index d3b2b394f..7a72903a6 100644 --- a/usrp2/sdr_lib/duc_chain.v +++ b/usrp2/sdr_lib/duc_chain.v @@ -19,7 +19,7 @@ module duc_chain #(parameter BASE = 0, parameter DSPNO = 0) - (input clk, input rst, + (input clk, input rst, input clr, input set_stb, input [7:0] set_addr, input [31:0] set_data, input set_stb_user, input [7:0] set_addr_user, input [31:0] set_data_user, @@ -148,7 +148,7 @@ module duc_chain ); dsp_tx_glue #(.DSPNO(DSPNO)) dsp_tx_glue( - .clock(clk), .reset(rst), .enable(run), + .clock(clk), .reset(rst), .clear(clr), .enable(run), .set_stb(set_stb_user), .set_addr(set_addr_user), .set_data(set_data_user), .frontend_i(tx_fe_i), .frontend_q(tx_fe_q), .duc_out_i(prod_i[33:10]), .duc_out_q(prod_q[33:10]), diff --git a/usrp2/top/B100/u1plus_core.v b/usrp2/top/B100/u1plus_core.v index c6ef80751..c5fe368a5 100644 --- a/usrp2/top/B100/u1plus_core.v +++ b/usrp2/top/B100/u1plus_core.v @@ -53,8 +53,7 @@ module u1plus_core 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_CLEAR_FIFO = 61; // 1 reg localparam SR_GLOBAL_RESET = 63; // 1 reg localparam SR_USER_REGS = 64; // 2 regs @@ -107,16 +106,12 @@ module u1plus_core wire tx_src_rdy, tx_dst_rdy, rx_src_rdy, rx_dst_rdy, tx_err_src_rdy, tx_err_dst_rdy; - wire clear_tx, clear_rx; - - setting_reg #(.my_addr(SR_CLEAR_RX_FIFO), .width(1)) sr_clear_rx - (.clk(wb_clk),.rst(wb_rst),.strobe(set_stb),.addr(set_addr), - .in(set_data),.out(),.changed(clear_rx)); + wire clear_fifo; - setting_reg #(.my_addr(SR_CLEAR_TX_FIFO), .width(1)) sr_clear_tx + setting_reg #(.my_addr(SR_CLEAR_FIFO), .width(1)) sr_clear_fifo (.clk(wb_clk),.rst(wb_rst),.strobe(set_stb),.addr(set_addr), - .in(set_data),.out(),.changed(clear_tx)); - + .in(set_data),.out(),.changed(clear_fifo)); + wire run_rx0, run_rx1; slave_fifo #(.TXFIFOSIZE(TXFIFOSIZE), .RXFIFOSIZE(RXFIFOSIZE)) @@ -131,7 +126,7 @@ module u1plus_core .dsp_rx_run(run_rx0 | run_rx1), - .fifo_clk(wb_clk), .fifo_rst(wb_rst), .clear_tx(clear_tx), .clear_rx(clear_rx), + .fifo_clk(wb_clk), .fifo_rst(wb_rst), .clear_tx(clear_fifo), .clear_rx(clear_fifo), .tx_data_o(tx_data), .tx_src_rdy_o(tx_src_rdy), .tx_dst_rdy_i(tx_dst_rdy), .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), @@ -145,7 +140,7 @@ module u1plus_core // RX ADC Frontend, does IQ Balance, DC Offset, muxing wire [23:0] rx_fe_i, rx_fe_q; // 24 bits is total overkill here, but it matches u2/u2p - + 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), @@ -157,12 +152,12 @@ module u1plus_core // DSP RX 0 wire [31:0] sample_rx0; - wire strobe_rx0; + wire strobe_rx0, clear_rx0; wire [35:0] vita_rx_data0; wire vita_rx_src_rdy0, vita_rx_dst_rdy0; ddc_chain #(.BASE(SR_RX_DSP0), .DSPNO(0)) ddc_chain0 - (.clk(wb_clk),.rst(wb_rst), + (.clk(wb_clk), .rst(wb_rst), .clr(clear_rx0), .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data), .set_stb_user(set_stb_user), .set_addr_user(set_addr_user), .set_data_user(set_data_user), .rx_fe_i(rx_fe_i),.rx_fe_q(rx_fe_q), @@ -174,7 +169,7 @@ module u1plus_core .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data), .set_stb_user(set_stb_user), .set_addr_user(set_addr_user), .set_data_user(set_data_user), .vita_time(vita_time), .overrun(rx_overrun_dsp0), - .sample(sample_rx0), .run(run_rx0), .strobe(strobe_rx0), + .sample(sample_rx0), .run(run_rx0), .strobe(strobe_rx0), .clear_o(clear_rx0), .rx_data_o(vita_rx_data0), .rx_dst_rdy_i(vita_rx_dst_rdy0), .rx_src_rdy_o(vita_rx_src_rdy0), .debug() ); @@ -182,12 +177,12 @@ module u1plus_core // DSP RX 1 wire [31:0] sample_rx1; - wire strobe_rx1; + wire strobe_rx1, clear_rx1; wire [35:0] vita_rx_data1; wire vita_rx_src_rdy1, vita_rx_dst_rdy1; ddc_chain #(.BASE(SR_RX_DSP1), .DSPNO(1)) ddc_chain1 - (.clk(wb_clk),.rst(wb_rst), + (.clk(wb_clk),.rst(wb_rst), .clr(clear_rx1), .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data), .set_stb_user(set_stb_user), .set_addr_user(set_addr_user), .set_data_user(set_data_user), .rx_fe_i(rx_fe_i),.rx_fe_q(rx_fe_q), @@ -199,7 +194,7 @@ module u1plus_core .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data), .set_stb_user(set_stb_user), .set_addr_user(set_addr_user), .set_data_user(set_data_user), .vita_time(vita_time), .overrun(rx_overrun_dsp1), - .sample(sample_rx1), .run(run_rx1), .strobe(strobe_rx1), + .sample(sample_rx1), .run(run_rx1), .strobe(strobe_rx1), .clear_o(clear_rx1), .rx_data_o(vita_rx_data1), .rx_dst_rdy_i(vita_rx_dst_rdy1), .rx_src_rdy_o(vita_rx_src_rdy1), .debug() ); @@ -207,7 +202,7 @@ module u1plus_core // RX Stream muxing fifo36_mux #(.prio(0)) mux_data_streams - (.clk(wb_clk), .reset(wb_rst), .clear(clear_rx), + (.clk(wb_clk), .reset(wb_rst), .clear(clear_fifo), .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)); @@ -218,7 +213,7 @@ module u1plus_core wire run_tx; wire [23:0] tx_fe_i, tx_fe_q; wire [31:0] sample_tx; - wire strobe_tx; + wire strobe_tx, clear_tx; vita_tx_chain #(.BASE(SR_TX_CTRL), .FIFOSIZE(10), .POST_ENGINE_FIFOSIZE(11), .REPORT_ERROR(1), .DO_FLOW_CONTROL(0), @@ -232,11 +227,11 @@ module u1plus_core .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), .sample(sample_tx), .strobe(strobe_tx), - .underrun(tx_underrun_dsp), .run(run_tx), + .underrun(tx_underrun_dsp), .run(run_tx), .clear_o(clear_tx), .debug(debug_vt)); duc_chain #(.BASE(SR_TX_DSP), .DSPNO(0)) duc_chain - (.clk(wb_clk),.rst(wb_rst), + (.clk(wb_clk), .rst(wb_rst), .clr(clear_tx), .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data), .set_stb_user(set_stb_user), .set_addr_user(set_addr_user), .set_data_user(set_data_user), .tx_fe_i(tx_fe_i),.tx_fe_q(tx_fe_q), diff --git a/usrp2/top/E1x0/u1e_core.v b/usrp2/top/E1x0/u1e_core.v index 765023e29..032c320e0 100644 --- a/usrp2/top/E1x0/u1e_core.v +++ b/usrp2/top/E1x0/u1e_core.v @@ -56,8 +56,7 @@ module u1e_core 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_CLEAR_FIFO = 61; // 1 reg localparam SR_GLOBAL_RESET = 63; // 1 reg localparam SR_USER_REGS = 64; // 2 regs @@ -104,15 +103,13 @@ module u1e_core wire tx_src_rdy, tx_dst_rdy, rx_src_rdy, rx_dst_rdy, tx_err_src_rdy, tx_err_dst_rdy; - wire clear_tx, clear_rx; - - setting_reg #(.my_addr(SR_CLEAR_RX_FIFO), .width(1)) sr_clear_rx - (.clk(wb_clk),.rst(wb_rst),.strobe(set_stb),.addr(set_addr), - .in(set_data),.out(),.changed(clear_rx)); + wire clear_fifo; - setting_reg #(.my_addr(SR_CLEAR_TX_FIFO), .width(1)) sr_clear_tx + setting_reg #(.my_addr(SR_CLEAR_FIFO), .width(1)) sr_clear_fifo (.clk(wb_clk),.rst(wb_rst),.strobe(set_stb),.addr(set_addr), - .in(set_data),.out(),.changed(clear_tx)); + .in(set_data),.out(),.changed(clear_fifo)); + + wire run_rx0, run_rx1; gpmc #(.TXFIFOSIZE(TXFIFOSIZE), .RXFIFOSIZE(RXFIFOSIZE)) gpmc (.arst(wb_rst), @@ -127,7 +124,7 @@ module u1e_core .wb_sel_o(m0_sel), .wb_cyc_o(m0_cyc), .wb_stb_o(m0_stb), .wb_we_o(m0_we), .wb_ack_i(m0_ack), - .fifo_clk(wb_clk), .fifo_rst(wb_rst), .clear_tx(clear_tx), .clear_rx(clear_rx), + .fifo_clk(wb_clk), .fifo_rst(wb_rst), .clear_tx(clear_fifo), .clear_rx(clear_fifo), .tx_data_o(tx_data), .tx_src_rdy_o(tx_src_rdy), .tx_dst_rdy_i(tx_dst_rdy), .rx_data_i(rx_data), .rx_src_rdy_i(rx_src_rdy), .rx_dst_rdy_o(rx_dst_rdy), @@ -144,8 +141,7 @@ module u1e_core // RX ADC Frontend, does IQ Balance, DC Offset, muxing wire [23:0] rx_fe_i, rx_fe_q; // 24 bits is total overkill here, but it matches u2/u2p - wire 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), @@ -157,12 +153,12 @@ module u1e_core // DSP RX 0 wire [31:0] sample_rx0; - wire strobe_rx0; + wire strobe_rx0, clear_rx0; wire [35:0] vita_rx_data0; wire vita_rx_src_rdy0, vita_rx_dst_rdy0; ddc_chain #(.BASE(SR_RX_DSP0), .DSPNO(0)) ddc_chain0 - (.clk(wb_clk),.rst(wb_rst), + (.clk(wb_clk), .rst(wb_rst), .clr(clear_rx0), .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data), .set_stb_user(set_stb_user), .set_addr_user(set_addr_user), .set_data_user(set_data_user), .rx_fe_i(rx_fe_i),.rx_fe_q(rx_fe_q), @@ -174,7 +170,7 @@ module u1e_core .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data), .set_stb_user(set_stb_user), .set_addr_user(set_addr_user), .set_data_user(set_data_user), .vita_time(vita_time), .overrun(rx_overrun_dsp0), - .sample(sample_rx0), .run(run_rx0), .strobe(strobe_rx0), + .sample(sample_rx0), .run(run_rx0), .strobe(strobe_rx0), .clear_o(clear_rx0), .rx_data_o(vita_rx_data0), .rx_dst_rdy_i(vita_rx_dst_rdy0), .rx_src_rdy_o(vita_rx_src_rdy0), .debug() ); @@ -182,12 +178,12 @@ module u1e_core // DSP RX 1 wire [31:0] sample_rx1; - wire strobe_rx1; + wire strobe_rx1, clear_rx1; wire [35:0] vita_rx_data1; wire vita_rx_src_rdy1, vita_rx_dst_rdy1; ddc_chain #(.BASE(SR_RX_DSP1), .DSPNO(1)) ddc_chain1 - (.clk(wb_clk),.rst(wb_rst), + (.clk(wb_clk),.rst(wb_rst), .clr(clear_rx1), .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data), .set_stb_user(set_stb_user), .set_addr_user(set_addr_user), .set_data_user(set_data_user), .rx_fe_i(rx_fe_i),.rx_fe_q(rx_fe_q), @@ -199,7 +195,7 @@ module u1e_core .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data), .set_stb_user(set_stb_user), .set_addr_user(set_addr_user), .set_data_user(set_data_user), .vita_time(vita_time), .overrun(rx_overrun_dsp1), - .sample(sample_rx1), .run(run_rx1), .strobe(strobe_rx1), + .sample(sample_rx1), .run(run_rx1), .strobe(strobe_rx1), .clear_o(clear_rx1), .rx_data_o(vita_rx_data1), .rx_dst_rdy_i(vita_rx_dst_rdy1), .rx_src_rdy_o(vita_rx_src_rdy1), .debug() ); @@ -207,7 +203,7 @@ module u1e_core // RX Stream muxing fifo36_mux #(.prio(0)) mux_data_streams - (.clk(wb_clk), .reset(wb_rst), .clear(0), + (.clk(wb_clk), .reset(wb_rst), .clear(clear_fifo), .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)); @@ -218,7 +214,7 @@ module u1e_core wire run_tx; wire [23:0] tx_fe_i, tx_fe_q; wire [31:0] sample_tx; - wire strobe_tx; + wire strobe_tx, clear_tx; vita_tx_chain #(.BASE(SR_TX_CTRL), .FIFOSIZE(10), .POST_ENGINE_FIFOSIZE(11), .REPORT_ERROR(1), .DO_FLOW_CONTROL(0), @@ -232,11 +228,11 @@ module u1e_core .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), .sample(sample_tx), .strobe(strobe_tx), - .underrun(tx_underrun_dsp), .run(run_tx), + .underrun(tx_underrun_dsp), .run(run_tx), .clear_o(clear_tx), .debug(debug_vt)); duc_chain #(.BASE(SR_TX_DSP), .DSPNO(0)) duc_chain - (.clk(wb_clk),.rst(wb_rst), + (.clk(wb_clk), .rst(wb_rst), .clr(clear_tx), .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data), .set_stb_user(set_stb_user), .set_addr_user(set_addr_user), .set_data_user(set_data_user), .tx_fe_i(tx_fe_i),.tx_fe_q(tx_fe_q), diff --git a/usrp2/top/N2x0/u2plus_core.v b/usrp2/top/N2x0/u2plus_core.v index 8b804bb0c..a0c2e7be6 100644 --- a/usrp2/top/N2x0/u2plus_core.v +++ b/usrp2/top/N2x0/u2plus_core.v @@ -578,13 +578,13 @@ module u2plus_core // ///////////////////////////////////////////////////////////////////////// // DSP RX 0 wire [31:0] sample_rx0; - wire strobe_rx0; + wire strobe_rx0, clear_rx0; always @(posedge dsp_clk) run_rx0_d1 <= run_rx0; ddc_chain #(.BASE(SR_RX_DSP0), .DSPNO(0)) ddc_chain0 - (.clk(dsp_clk),.rst(dsp_rst), + (.clk(dsp_clk), .rst(dsp_rst), .clr(clear_rx0), .set_stb(set_stb_dsp),.set_addr(set_addr_dsp),.set_data(set_data_dsp), .set_stb_user(set_stb_user), .set_addr_user(set_addr_user), .set_data_user(set_data_user), .rx_fe_i(rx_fe_i),.rx_fe_q(rx_fe_q), @@ -596,20 +596,20 @@ module u2plus_core .set_stb(set_stb_dsp),.set_addr(set_addr_dsp),.set_data(set_data_dsp), .set_stb_user(set_stb_user), .set_addr_user(set_addr_user), .set_data_user(set_data_user), .vita_time(vita_time), .overrun(overrun0), - .sample(sample_rx0), .run(run_rx0), .strobe(strobe_rx0), + .sample(sample_rx0), .run(run_rx0), .strobe(strobe_rx0), .clear_o(clear_rx0), .rx_data_o(wr1_dat), .rx_src_rdy_o(wr1_ready_i), .rx_dst_rdy_i(wr1_ready_o), .debug() ); // ///////////////////////////////////////////////////////////////////////// // DSP RX 1 wire [31:0] sample_rx1; - wire strobe_rx1; + wire strobe_rx1, clear_rx1; always @(posedge dsp_clk) run_rx1_d1 <= run_rx1; ddc_chain #(.BASE(SR_RX_DSP1), .DSPNO(1)) ddc_chain1 - (.clk(dsp_clk),.rst(dsp_rst), + (.clk(dsp_clk), .rst(dsp_rst), .clr(clear_rx1), .set_stb(set_stb_dsp),.set_addr(set_addr_dsp),.set_data(set_data_dsp), .set_stb_user(set_stb_user), .set_addr_user(set_addr_user), .set_data_user(set_data_user), .rx_fe_i(rx_fe_i),.rx_fe_q(rx_fe_q), @@ -621,7 +621,7 @@ module u2plus_core .set_stb(set_stb_dsp),.set_addr(set_addr_dsp),.set_data(set_data_dsp), .set_stb_user(set_stb_user), .set_addr_user(set_addr_user), .set_data_user(set_data_user), .vita_time(vita_time), .overrun(overrun1), - .sample(sample_rx1), .run(run_rx1), .strobe(strobe_rx1), + .sample(sample_rx1), .run(run_rx1), .strobe(strobe_rx1), .clear_o(clear_rx1), .rx_data_o(wr3_dat), .rx_src_rdy_o(wr3_ready_i), .rx_dst_rdy_i(wr3_ready_o), .debug() ); @@ -674,12 +674,11 @@ module u2plus_core .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), .sample(sample_tx), .strobe(strobe_tx), - .underrun(underrun), .run(run_tx), - .clear_vita(clear_tx), //output internal vita clear signal + .underrun(underrun), .run(run_tx), .clear_o(clear_tx), .debug(debug_vt)); duc_chain #(.BASE(SR_TX_DSP), .DSPNO(0)) duc_chain - (.clk(dsp_clk),.rst(dsp_rst), + (.clk(dsp_clk),.rst(dsp_rst), .clr(clear_tx), .set_stb(set_stb_dsp),.set_addr(set_addr_dsp),.set_data(set_data_dsp), .set_stb_user(set_stb_user), .set_addr_user(set_addr_user), .set_data_user(set_data_user), .tx_fe_i(tx_fe_i),.tx_fe_q(tx_fe_q), diff --git a/usrp2/top/USRP2/u2_core.v b/usrp2/top/USRP2/u2_core.v index 4b2276e4a..7461ded68 100644 --- a/usrp2/top/USRP2/u2_core.v +++ b/usrp2/top/USRP2/u2_core.v @@ -566,13 +566,13 @@ module u2_core // ///////////////////////////////////////////////////////////////////////// // DSP RX 0 wire [31:0] sample_rx0; - wire strobe_rx0; + wire strobe_rx0, clear_rx0; always @(posedge dsp_clk) run_rx0_d1 <= run_rx0; ddc_chain #(.BASE(SR_RX_DSP0), .DSPNO(0)) ddc_chain0 - (.clk(dsp_clk),.rst(dsp_rst), + (.clk(dsp_clk), .rst(dsp_rst), .clr(clear_rx0), .set_stb(set_stb_dsp),.set_addr(set_addr_dsp),.set_data(set_data_dsp), .set_stb_user(set_stb_user), .set_addr_user(set_addr_user), .set_data_user(set_data_user), .rx_fe_i(rx_fe_i),.rx_fe_q(rx_fe_q), @@ -584,20 +584,20 @@ module u2_core .set_stb(set_stb_dsp),.set_addr(set_addr_dsp),.set_data(set_data_dsp), .set_stb_user(set_stb_user), .set_addr_user(set_addr_user), .set_data_user(set_data_user), .vita_time(vita_time), .overrun(overrun0), - .sample(sample_rx0), .run(run_rx0), .strobe(strobe_rx0), + .sample(sample_rx0), .run(run_rx0), .strobe(strobe_rx0), .clear_o(clear_rx0), .rx_data_o(wr1_dat), .rx_src_rdy_o(wr1_ready_i), .rx_dst_rdy_i(wr1_ready_o), .debug() ); // ///////////////////////////////////////////////////////////////////////// // DSP RX 1 wire [31:0] sample_rx1; - wire strobe_rx1; + wire strobe_rx1, clear_rx1; always @(posedge dsp_clk) run_rx1_d1 <= run_rx1; ddc_chain #(.BASE(SR_RX_DSP1), .DSPNO(1)) ddc_chain1 - (.clk(dsp_clk),.rst(dsp_rst), + (.clk(dsp_clk), .rst(dsp_rst), .clr(clear_rx1), .set_stb(set_stb_dsp),.set_addr(set_addr_dsp),.set_data(set_data_dsp), .set_stb_user(set_stb_user), .set_addr_user(set_addr_user), .set_data_user(set_data_user), .rx_fe_i(rx_fe_i),.rx_fe_q(rx_fe_q), @@ -609,7 +609,7 @@ module u2_core .set_stb(set_stb_dsp),.set_addr(set_addr_dsp),.set_data(set_data_dsp), .set_stb_user(set_stb_user), .set_addr_user(set_addr_user), .set_data_user(set_data_user), .vita_time(vita_time), .overrun(overrun1), - .sample(sample_rx1), .run(run_rx1), .strobe(strobe_rx1), + .sample(sample_rx1), .run(run_rx1), .strobe(strobe_rx1), .clear_o(clear_rx1), .rx_data_o(wr3_dat), .rx_src_rdy_o(wr3_ready_i), .rx_dst_rdy_i(wr3_ready_o), .debug() ); @@ -660,12 +660,11 @@ module u2_core .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), .sample(sample_tx), .strobe(strobe_tx), - .underrun(underrun), .run(run_tx), - .clear_vita(clear_tx), //output internal vita clear signal + .underrun(underrun), .run(run_tx), .clear_o(clear_tx), .debug(debug_vt)); duc_chain #(.BASE(SR_TX_DSP), .DSPNO(0)) duc_chain - (.clk(dsp_clk),.rst(dsp_rst), + (.clk(dsp_clk),.rst(dsp_rst), .clr(clear_tx), .set_stb(set_stb_dsp),.set_addr(set_addr_dsp),.set_data(set_data_dsp), .set_stb_user(set_stb_user), .set_addr_user(set_addr_user), .set_data_user(set_data_user), .tx_fe_i(tx_fe_i),.tx_fe_q(tx_fe_q), diff --git a/usrp2/vrt/vita_rx_chain.v b/usrp2/vrt/vita_rx_chain.v index e4f7e9864..c57e6cc05 100644 --- a/usrp2/vrt/vita_rx_chain.v +++ b/usrp2/vrt/vita_rx_chain.v @@ -28,9 +28,9 @@ module vita_rx_chain input [63:0] vita_time, input [31:0] sample, input strobe, output [35:0] rx_data_o, output rx_src_rdy_o, input rx_dst_rdy_i, - output overrun, output run, + output overrun, output run, output clear_o, output [31:0] debug ); - + wire [100:0] sample_data; wire sample_dst_rdy, sample_src_rdy; wire [31:0] vrc_debug, vrf_debug; @@ -39,6 +39,7 @@ module vita_rx_chain wire rx_src_rdy_int, rx_dst_rdy_int; wire clear; + assign clear_o = clear; setting_reg #(.my_addr(BASE+3)) sr (.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr), diff --git a/usrp2/vrt/vita_tx_chain.v b/usrp2/vrt/vita_tx_chain.v index 93bc703cd..9b478081f 100644 --- a/usrp2/vrt/vita_tx_chain.v +++ b/usrp2/vrt/vita_tx_chain.v @@ -32,8 +32,7 @@ module vita_tx_chain 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 [31:0] sample, input strobe, - output underrun, output run, - output clear_vita, + output underrun, output run, output clear_o, output [31:0] debug); localparam MAXCHAN = 1; @@ -51,7 +50,7 @@ module vita_tx_chain wire [31:0] current_seqnum; wire clear; - assign clear_vita = clear; + assign clear_o = clear; assign underrun = error; assign message = error_code; -- cgit v1.2.3 From 5c56ca574ffdf7ad469ab3a3f54def944a978bee Mon Sep 17 00:00:00 2001 From: Nick Foster Date: Mon, 6 Feb 2012 13:01:15 -0800 Subject: B100: use FPGA external reset on init --- firmware/fx2/b100/usrp_main.c | 7 ++++++- host/lib/usrp/b100/b100_impl.cpp | 6 ++++++ host/lib/usrp/b100/b100_impl.hpp | 1 + 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/firmware/fx2/b100/usrp_main.c b/firmware/fx2/b100/usrp_main.c index 436bdeb36..d9e09ca34 100644 --- a/firmware/fx2/b100/usrp_main.c +++ b/firmware/fx2/b100/usrp_main.c @@ -65,6 +65,11 @@ xdata at USRP_HASH_SLOT_1_ADDR unsigned char hash1[USRP_HASH_SIZE]; //void clear_fpga_data_fifo(void); +//use the B100 fpga_config_cclk/ext_reset line to reset the FPGA +void fpga_reset(int level) { + bitALTERA_DCLK = level; +} + static void get_ep0_data (void) { @@ -169,7 +174,7 @@ app_vendor_cmd (void) break; case VRQ_FPGA_SET_RESET: - //fpga_set_reset (wValueL); + fpga_reset(wValueL); break; case VRQ_I2C_WRITE: diff --git a/host/lib/usrp/b100/b100_impl.cpp b/host/lib/usrp/b100/b100_impl.cpp index 455efa2fe..08a2cdeec 100644 --- a/host/lib/usrp/b100/b100_impl.cpp +++ b/host/lib/usrp/b100/b100_impl.cpp @@ -181,6 +181,8 @@ b100_impl::b100_impl(const device_addr_t &device_addr){ //load FPGA image, gpif is disabled while loading this->enable_gpif(false); _fx2_ctrl->usrp_load_fpga(b100_fpga_image); + this->set_reset_fpga(1); + this->set_reset_fpga(0); this->enable_gpif(true); //create the control transport @@ -525,6 +527,10 @@ void b100_impl::clear_fpga_fifo(void) { _fx2_ctrl->usrp_control_write(VRQ_CLEAR_FPGA_FIFO, 0, 0, 0, 0); } +void b100_impl::set_reset_fpga(const bool en) { + _fx2_ctrl->usrp_control_write(VRQ_FPGA_SET_RESET, en ? 0 : 1, 0, 0, 0); +} + sensor_value_t b100_impl::get_ref_locked(void){ const bool lock = _clock_ctrl->get_locked(); return sensor_value_t("Ref", lock, "locked", "unlocked"); diff --git a/host/lib/usrp/b100/b100_impl.hpp b/host/lib/usrp/b100/b100_impl.hpp index 49a3139f0..b71b65562 100644 --- a/host/lib/usrp/b100/b100_impl.hpp +++ b/host/lib/usrp/b100/b100_impl.hpp @@ -126,6 +126,7 @@ private: void reset_gpif(const boost::uint16_t); void enable_gpif(const bool); void clear_fpga_fifo(void); + void set_reset_fpga(const bool en); void handle_async_message(uhd::transport::managed_recv_buffer::sptr); uhd::sensor_value_t get_ref_locked(void); void set_rx_fe_corrections(const double); -- cgit v1.2.3 From 947d0ffabc72b1f74ff4507df12b6bf2a021dc3b Mon Sep 17 00:00:00 2001 From: Nick Foster Date: Mon, 6 Feb 2012 13:01:32 -0800 Subject: B100: External FPGA reset from FX2 reuses fpga_cfg_cclk. --- usrp2/top/B100/B100.ucf | 3 +++ usrp2/top/B100/B100.v | 5 +++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/usrp2/top/B100/B100.ucf b/usrp2/top/B100/B100.ucf index c86501e72..1c04c5d8d 100644 --- a/usrp2/top/B100/B100.ucf +++ b/usrp2/top/B100/B100.ucf @@ -25,6 +25,9 @@ NET "reset_n" LOC = "D5" ; NET "PPS_IN" LOC = "M14" ; NET "reset_codec" LOC = "B14" ; +## recycles fpga_cfg_cclk for reset from fw +NET "ext_reset" LOC = "R14" ; + ## GPIF NET "GPIF_D<15>" LOC = "P7" ; NET "GPIF_D<14>" LOC = "N8" ; diff --git a/usrp2/top/B100/B100.v b/usrp2/top/B100/B100.v index b5691d1c3..dcda974b4 100644 --- a/usrp2/top/B100/B100.v +++ b/usrp2/top/B100/B100.v @@ -41,7 +41,8 @@ module B100 input [11:0] adc, input RXSYNC, input PPS_IN, - input reset_n, output reset_codec + input reset_n, output reset_codec, + input ext_reset ); assign reset_codec = 1; // Believed to be active low @@ -55,7 +56,7 @@ module B100 BUFG clk_fpga_BUFG (.I(clk_fpga_in), .O(clk_fpga)); - reset_sync reset_sync(.clk(clk_fpga), .reset_in(~reset_n), .reset_out(reset)); + reset_sync reset_sync(.clk(clk_fpga), .reset_in((~reset_n) | (~ext_reset)), .reset_out(reset)); // ///////////////////////////////////////////////////////////////////////// // SPI -- cgit v1.2.3 From 34db74740704ce2de2a71447b3d202e9c4be800b Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Mon, 6 Feb 2012 16:40:17 -0800 Subject: dsp rework: implement 64 bit ticks no seconds --- usrp2/timing/time_64bit.v | 48 +++++++++++++++----------------------------- usrp2/timing/time_compare.v | 44 +++++++--------------------------------- usrp2/top/B100/u1plus_core.v | 2 +- usrp2/top/E1x0/u1e_core.v | 2 +- usrp2/top/N2x0/u2plus_core.v | 2 +- usrp2/top/USRP2/u2_core.v | 2 +- usrp2/vrt/gen_context_pkt.v | 18 ++++++++--------- usrp2/vrt/vita_rx_framer.v | 38 ++++++++++++++++------------------- usrp2/vrt/vita_tx_control.v | 4 +--- usrp2/vrt/vita_tx_deframer.v | 8 ++++---- 10 files changed, 57 insertions(+), 111 deletions(-) diff --git a/usrp2/timing/time_64bit.v b/usrp2/timing/time_64bit.v index 03df07108..6f335890e 100644 --- a/usrp2/timing/time_64bit.v +++ b/usrp2/timing/time_64bit.v @@ -1,5 +1,5 @@ // -// Copyright 2011 Ettus Research LLC +// Copyright 2011-2012 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 @@ -18,7 +18,7 @@ module time_64bit - #(parameter TICKS_PER_SEC = 32'd100000000, + #( parameter BASE = 0) (input clk, input rst, input set_stb, input [7:0] set_addr, input [31:0] set_data, @@ -31,23 +31,20 @@ module time_64bit output [31:0] debug ); - localparam NEXT_SECS = 0; - localparam NEXT_TICKS = 1; + localparam NEXT_TICKS_HI = 0; + localparam NEXT_TICKS_LO = 1; localparam PPS_POLSRC = 2; localparam PPS_IMM = 3; - localparam TPS = 4; localparam MIMO_SYNC = 5; - reg [31:0] seconds, ticks; - wire end_of_second; + reg [63:0] ticks; always @(posedge clk) - vita_time <= {seconds,ticks}; + vita_time <= ticks; wire [63:0] vita_time_rcvd; - wire [31:0] next_ticks_preset, next_seconds_preset; - wire [31:0] ticks_per_sec_reg; + wire [63:0] next_ticks_preset; wire set_on_pps_trig; reg set_on_next_pps; wire pps_polarity, pps_source, set_imm; @@ -57,18 +54,18 @@ module time_64bit reg [15:0] sync_counter; wire sync_rcvd; - wire [31:0] mimo_secs, mimo_ticks; + wire [63:0] mimo_ticks; wire mimo_sync_now; wire mimo_sync; wire [7:0] sync_delay; - setting_reg #(.my_addr(BASE+NEXT_TICKS)) sr_next_ticks + setting_reg #(.my_addr(BASE+NEXT_TICKS_LO)) sr_next_ticks_lo (.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr), - .in(set_data),.out(next_ticks_preset),.changed()); + .in(set_data),.out(next_ticks_preset[31:0]),.changed()); - setting_reg #(.my_addr(BASE+NEXT_SECS)) sr_next_secs + setting_reg #(.my_addr(BASE+NEXT_TICKS_HI)) sr_next_ticks_hi (.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr), - .in(set_data),.out(next_seconds_preset),.changed(set_on_pps_trig)); + .in(set_data),.out(next_ticks_preset[63:32]),.changed(set_on_pps_trig)); setting_reg #(.my_addr(BASE+PPS_POLSRC), .width(2)) sr_pps_polsrc (.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr), @@ -78,10 +75,6 @@ module time_64bit (.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr), .in(set_data),.out(set_imm),.changed()); - setting_reg #(.my_addr(BASE+TPS), .at_reset(TICKS_PER_SEC)) sr_tps - (.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr), - .in(set_data),.out(ticks_per_sec_reg),.changed()); - setting_reg #(.my_addr(BASE+MIMO_SYNC), .at_reset(0), .width(9)) sr_mimosync (.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr), .in(set_data),.out({mimo_sync,sync_delay}),.changed()); @@ -110,29 +103,21 @@ module time_64bit else if(set_imm | pps_edge) set_on_next_pps <= 0; - wire [31:0] ticks_plus_one = ticks + 1; + wire [63:0] ticks_plus_one = ticks + 1; always @(posedge clk) if(rst) begin - seconds <= 32'd0; - ticks <= 32'd0; + ticks <= 64'd0; end else if((set_imm | pps_edge) & set_on_next_pps) begin - seconds <= next_seconds_preset; ticks <= next_ticks_preset; end else if(mimo_sync_now) begin - seconds <= mimo_secs; ticks <= mimo_ticks; end - else if(ticks_plus_one == ticks_per_sec_reg) - begin - seconds <= seconds + 1; - ticks <= 0; - end else ticks <= ticks_plus_one; @@ -162,9 +147,8 @@ module time_64bit .sync_rcvd(sync_rcvd), .exp_time_in(exp_time_in) ); - assign mimo_secs = vita_time_rcvd[63:32]; - assign mimo_ticks = vita_time_rcvd[31:0] + {16'd0,sync_delay}; - assign mimo_sync_now = mimo_sync & sync_rcvd & (mimo_ticks <= TICKS_PER_SEC); + assign mimo_ticks = vita_time_rcvd[63:0] + {48'd0,sync_delay}; + assign mimo_sync_now = mimo_sync & sync_rcvd; assign debug = { { 24'b0} , { 2'b0, exp_time_in, exp_time_out, mimo_sync, mimo_sync_now, sync_rcvd, send_sync} }; diff --git a/usrp2/timing/time_compare.v b/usrp2/timing/time_compare.v index 54ea000d6..21607f51c 100644 --- a/usrp2/timing/time_compare.v +++ b/usrp2/timing/time_compare.v @@ -1,5 +1,5 @@ // -// Copyright 2011 Ettus Research LLC +// Copyright 2011-2012 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 @@ -16,49 +16,19 @@ // -// Top 32 bits are integer seconds, bottom 32 are clock ticks within a second +// 64 bits worth of ticks module time_compare (input [63:0] time_now, input [63:0] trigger_time, output now, output early, - output late, + output late, output too_early); - - wire sec_match = (time_now[63:32] == trigger_time[63:32]); - wire sec_late = (time_now[63:32] > trigger_time[63:32]); - wire tick_match = (time_now[31:0] == trigger_time[31:0]); - wire tick_late = (time_now[31:0] > trigger_time[31:0]); -/* - assign now = sec_match & tick_match; - assign late = sec_late | (sec_match & tick_late); - assign early = ~now & ~late; -*/ + assign now = time_now == trigger_time; + assign late = time_now > trigger_time; + assign early = ~now & ~late; + assign too_early = 0; //not implemented - /* - assign now = (time_now == trigger_time); - assign late = (time_now > trigger_time); - assign early = (time_now < trigger_time); - */ - - // Compare fewer bits instead of 64 to speed up logic - // Unused bits are not significant - // Top bit of seconds would put us in year 2038, long after - // the warranty has run out :) - // Top 5 bits of ticks are always zero for clocks less than 134MHz - // "late" can drop bottom few bits of ticks, and just delay signaling - // of late. - // "now" cannot drop those bits, it needs to be exact. - - wire [57:0] short_now = {time_now[62:32],time_now[26:0]}; - wire [57:0] short_trig = {trigger_time[62:32],trigger_time[26:0]}; - - assign now = (short_now == short_trig); - assign late = (short_now[57:5] > short_trig[57:5]); - assign early = (short_now < short_trig); - - assign too_early = (trigger_time[63:32] > (time_now[63:32] + 4)); // Don't wait too long - endmodule // time_compare diff --git a/usrp2/top/B100/u1plus_core.v b/usrp2/top/B100/u1plus_core.v index c5fe368a5..e335fb8bb 100644 --- a/usrp2/top/B100/u1plus_core.v +++ b/usrp2/top/B100/u1plus_core.v @@ -438,7 +438,7 @@ module u1plus_core // ///////////////////////////////////////////////////////////////////////// // VITA Timing - time_64bit #(.TICKS_PER_SEC(32'd64000000),.BASE(SR_TIME64)) time_64bit + time_64bit #(.BASE(SR_TIME64)) time_64bit (.clk(wb_clk), .rst(wb_rst), .set_stb(set_stb), .set_addr(set_addr), .set_data(set_data), .pps(pps_in), .vita_time(vita_time), .vita_time_pps(vita_time_pps), .pps_int(pps_int), .exp_time_in(0)); diff --git a/usrp2/top/E1x0/u1e_core.v b/usrp2/top/E1x0/u1e_core.v index 032c320e0..ee27af939 100644 --- a/usrp2/top/E1x0/u1e_core.v +++ b/usrp2/top/E1x0/u1e_core.v @@ -480,7 +480,7 @@ module u1e_core // ///////////////////////////////////////////////////////////////////////// // VITA Timing - time_64bit #(.TICKS_PER_SEC(32'd64000000),.BASE(SR_TIME64)) time_64bit + time_64bit #(.BASE(SR_TIME64)) time_64bit (.clk(wb_clk), .rst(wb_rst), .set_stb(set_stb), .set_addr(set_addr), .set_data(set_data), .pps(pps_in), .vita_time(vita_time), .vita_time_pps(vita_time_pps), .pps_int(pps_int), .exp_time_in(0)); diff --git a/usrp2/top/N2x0/u2plus_core.v b/usrp2/top/N2x0/u2plus_core.v index a0c2e7be6..378f212e4 100644 --- a/usrp2/top/N2x0/u2plus_core.v +++ b/usrp2/top/N2x0/u2plus_core.v @@ -709,7 +709,7 @@ module u2plus_core wire [31:0] debug_sync; - time_64bit #(.TICKS_PER_SEC(32'd100000000),.BASE(SR_TIME64)) time_64bit + time_64bit #(.BASE(SR_TIME64)) time_64bit (.clk(dsp_clk), .rst(dsp_rst), .set_stb(set_stb_dsp), .set_addr(set_addr_dsp), .set_data(set_data_dsp), .pps(pps_in), .vita_time(vita_time), .vita_time_pps(vita_time_pps), .pps_int(pps_int), .exp_time_in(exp_time_in), .exp_time_out(exp_time_out), .good_sync(good_sync), .debug(debug_sync)); diff --git a/usrp2/top/USRP2/u2_core.v b/usrp2/top/USRP2/u2_core.v index 7461ded68..9b26b98e1 100644 --- a/usrp2/top/USRP2/u2_core.v +++ b/usrp2/top/USRP2/u2_core.v @@ -697,7 +697,7 @@ module u2_core wire [31:0] debug_sync; - time_64bit #(.TICKS_PER_SEC(32'd100000000),.BASE(SR_TIME64)) time_64bit + time_64bit #(.BASE(SR_TIME64)) time_64bit (.clk(dsp_clk), .rst(dsp_rst), .set_stb(set_stb_dsp), .set_addr(set_addr_dsp), .set_data(set_data_dsp), .pps(pps_in), .vita_time(vita_time), .vita_time_pps(vita_time_pps), .pps_int(pps_int), .exp_time_in(exp_time_in), .exp_time_out(exp_time_out), .good_sync(good_sync), .debug(debug_sync)); diff --git a/usrp2/vrt/gen_context_pkt.v b/usrp2/vrt/gen_context_pkt.v index bdfca8237..d6674e887 100644 --- a/usrp2/vrt/gen_context_pkt.v +++ b/usrp2/vrt/gen_context_pkt.v @@ -32,12 +32,11 @@ module gen_context_pkt localparam CTXT_PROT_ENG = 1; localparam CTXT_HEADER = 2; localparam CTXT_STREAMID = 3; - localparam CTXT_SECS = 4; - localparam CTXT_TICS = 5; - localparam CTXT_TICS2 = 6; - localparam CTXT_MESSAGE = 7; - localparam CTXT_FLOWCTRL = 8; - localparam CTXT_DONE = 9; + localparam CTXT_TICS = 4; + localparam CTXT_TICS2 = 5; + localparam CTXT_MESSAGE = 6; + localparam CTXT_FLOWCTRL = 7; + localparam CTXT_DONE = 8; reg [33:0] data_int; wire src_rdy_int, dst_rdy_int; @@ -88,11 +87,10 @@ module gen_context_pkt always @* case(ctxt_state) - CTXT_PROT_ENG : data_int <= { 2'b01, 13'b0, DSP_NUMBER[0], 1'b1, 1'b1, 16'd28 }; // UDP port 1 or 3 - CTXT_HEADER : data_int <= { 1'b0, (PROT_ENG_FLAGS ? 1'b0 : 1'b1), 12'b010100001101, seqno, 16'd7 }; + CTXT_PROT_ENG : data_int <= { 2'b01, 13'b0, DSP_NUMBER[0], 1'b1, 1'b1, 16'd24 }; // UDP port 1 or 3 + CTXT_HEADER : data_int <= { 1'b0, (PROT_ENG_FLAGS ? 1'b0 : 1'b1), 12'b010100000001, seqno, 16'd6 }; CTXT_STREAMID : data_int <= { 2'b00, streamid }; - CTXT_SECS : data_int <= { 2'b00, err_time[63:32] }; - CTXT_TICS : data_int <= { 2'b00, 32'd0 }; + CTXT_TICS : data_int <= { 2'b00, err_time[63:32] }; CTXT_TICS2 : data_int <= { 2'b00, err_time[31:0] }; CTXT_MESSAGE : data_int <= { 2'b00, message }; CTXT_FLOWCTRL : data_int <= { 2'b10, seqnum }; diff --git a/usrp2/vrt/vita_rx_framer.v b/usrp2/vrt/vita_rx_framer.v index bd09315bc..514df1151 100644 --- a/usrp2/vrt/vita_rx_framer.v +++ b/usrp2/vrt/vita_rx_framer.v @@ -1,5 +1,5 @@ // -// Copyright 2011 Ettus Research LLC +// Copyright 2011-2012 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 @@ -93,18 +93,16 @@ module vita_rx_framer localparam VITA_IDLE = 0; localparam VITA_HEADER = 1; localparam VITA_STREAMID = 2; - localparam VITA_SECS = 3; - localparam VITA_TICS = 4; - localparam VITA_TICS2 = 5; - localparam VITA_PAYLOAD = 6; - localparam VITA_TRAILER = 7; - localparam VITA_ERR_HEADER = 9; // All ERR at 4'b1000 or'ed with base - localparam VITA_ERR_STREAMID = 10; - localparam VITA_ERR_SECS = 11; - localparam VITA_ERR_TICS = 12; - localparam VITA_ERR_TICS2 = 13; - localparam VITA_ERR_PAYLOAD = 14; - localparam VITA_ERR_TRAILER = 15; // Extension context packets have no trailer + localparam VITA_TICS = 3; + localparam VITA_TICS2 = 4; + localparam VITA_PAYLOAD = 5; + localparam VITA_TRAILER = 6; + localparam VITA_ERR_HEADER = 7; // All ERR at 4'b1000 or'ed with base + localparam VITA_ERR_STREAMID = 8; + localparam VITA_ERR_TICS = 9; + localparam VITA_ERR_TICS2 = 10; + localparam VITA_ERR_PAYLOAD = 11; + localparam VITA_ERR_TRAILER = 12; // Extension context packets have no trailer always @(posedge clk) if(reset | clear | clear_pkt_count) @@ -122,17 +120,15 @@ module vita_rx_framer VITA_HEADER : pkt_fifo_line <= {2'b01,3'b000,vita_header[28],2'b01,vita_header[25:24], vita_header[23:20],pkt_count[3:0],vita_pkt_len[15:0]}; VITA_STREAMID : pkt_fifo_line <= {2'b00,vita_streamid}; - VITA_SECS : pkt_fifo_line <= {2'b00,vita_time_fifo_o[63:32]}; - VITA_TICS : pkt_fifo_line <= {2'b00,32'd0}; + VITA_TICS : pkt_fifo_line <= {2'b00,vita_time_fifo_o[63:32]}; VITA_TICS2 : pkt_fifo_line <= {2'b00,vita_time_fifo_o[31:0]}; VITA_PAYLOAD : pkt_fifo_line <= {2'b00,data_fifo_o}; VITA_TRAILER : pkt_fifo_line <= {2'b10,vita_trailer[31:21],1'b1,vita_trailer[19:9],trl_eob,8'd0}; // Error packets are Extension Context packets, which have no trailer - VITA_ERR_HEADER : pkt_fifo_line <= {2'b01,4'b0101,4'b0000,vita_header[23:20],pkt_count,16'd6}; + VITA_ERR_HEADER : pkt_fifo_line <= {2'b01,4'b0101,4'b0000,vita_header[23:20],pkt_count,16'd5}; VITA_ERR_STREAMID : pkt_fifo_line <= {2'b00,vita_streamid}; - VITA_ERR_SECS : pkt_fifo_line <= {2'b00,vita_time_fifo_o[63:32]}; - VITA_ERR_TICS : pkt_fifo_line <= {2'b00,32'd0}; + VITA_ERR_TICS : pkt_fifo_line <= {2'b00,vita_time_fifo_o[63:32]}; VITA_ERR_TICS2 : pkt_fifo_line <= {2'b00,vita_time_fifo_o[31:0]}; VITA_ERR_PAYLOAD : pkt_fifo_line <= {2'b10,27'd0,flags_fifo_o}; //VITA_ERR_TRAILER : pkt_fifo_line <= {2'b11,vita_trailer}; @@ -164,7 +160,7 @@ module vita_rx_framer if(has_streamid) vita_state <= VITA_STREAMID; else - vita_state <= VITA_SECS; + vita_state <= VITA_TICS; VITA_PAYLOAD : if(sample_fifo_src_rdy_i) begin @@ -194,12 +190,12 @@ module vita_rx_framer case(vita_state) VITA_IDLE : req_write_pkt_fifo <= 0; - VITA_HEADER, VITA_STREAMID, VITA_SECS, VITA_TICS, VITA_TICS2, VITA_TRAILER : + VITA_HEADER, VITA_STREAMID, VITA_TICS, VITA_TICS2, VITA_TRAILER : req_write_pkt_fifo <= 1; VITA_PAYLOAD : // Write if sample ready and no error flags req_write_pkt_fifo <= (sample_fifo_src_rdy_i & ~|flags_fifo_o[4:1]); - VITA_ERR_HEADER, VITA_ERR_STREAMID, VITA_ERR_SECS, VITA_ERR_TICS, VITA_ERR_TICS2, VITA_ERR_PAYLOAD : + VITA_ERR_HEADER, VITA_ERR_STREAMID, VITA_ERR_TICS, VITA_ERR_TICS2, VITA_ERR_PAYLOAD : req_write_pkt_fifo <= 1; default : req_write_pkt_fifo <= 0; diff --git a/usrp2/vrt/vita_tx_control.v b/usrp2/vrt/vita_tx_control.v index eaaf61815..c3ce2b96a 100644 --- a/usrp2/vrt/vita_tx_control.v +++ b/usrp2/vrt/vita_tx_control.v @@ -50,11 +50,9 @@ module vita_tx_control wire now, early, late, too_early; - // FIXME ignore too_early for now for timing reasons - assign too_early = 0; time_compare time_compare (.time_now(vita_time), .trigger_time(send_time), - .now(now), .early(early), .late(late), .too_early()); + .now(now), .early(early), .late(late), .too_early(too_early)); reg late_qual, late_del; diff --git a/usrp2/vrt/vita_tx_deframer.v b/usrp2/vrt/vita_tx_deframer.v index 06ca27767..62498836f 100644 --- a/usrp2/vrt/vita_tx_deframer.v +++ b/usrp2/vrt/vita_tx_deframer.v @@ -1,5 +1,5 @@ // -// Copyright 2011 Ettus Research LLC +// Copyright 2011-2012 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 @@ -214,7 +214,7 @@ module vita_tx_deframer always @(posedge clk) case(vita_state) - VITA_SECS : + VITA_TICS : send_time[63:32] <= data_i[31:0]; VITA_TICS2 : send_time[31:0] <= data_i[31:0]; @@ -235,8 +235,8 @@ module vita_tx_deframer .datain(fifo_i), .src_rdy_i(store), .dst_rdy_o(fifo_space), .dataout(sample_fifo_o), .src_rdy_o(sample_fifo_src_rdy_o), .dst_rdy_i(sample_fifo_dst_rdy_i) ); - // sob, eob, has_secs (send_at) ignored on all lines except first - assign fifo_i = {sample_d,sample_c,sample_b,sample_a,seqnum_err,has_secs_reg,is_sob_reg,is_eob_reg,eop, + // sob, eob, has_tics (send_at) ignored on all lines except first + assign fifo_i = {sample_d,sample_c,sample_b,sample_a,seqnum_err,has_tics_reg,is_sob_reg,is_eob_reg,eop, 12'd0,seqnum_reg[3:0],send_time}; assign dst_rdy_o = ~(vita_state == VITA_PAYLOAD) & ~((vita_state==VITA_STORE)& ~fifo_space) ; -- cgit v1.2.3 From 5eec31fab45649b529428cda756d04bcdaeb3134 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Mon, 6 Feb 2012 16:40:42 -0800 Subject: dsp rework: implement 64 bit ticks, no seconds --- host/include/uhd/types/time_spec.hpp | 20 ++++++++++++-- host/lib/transport/super_recv_packet_handler.hpp | 8 +++--- host/lib/transport/super_send_packet_handler.hpp | 12 ++++----- host/lib/types/time_spec.cpp | 29 ++++++++++---------- host/lib/usrp/b100/b100_impl.cpp | 8 +++--- host/lib/usrp/b100/b100_regs.hpp | 8 +++--- host/lib/usrp/b100/io_impl.cpp | 8 +++--- host/lib/usrp/cores/rx_dsp_core_200.cpp | 10 +++---- host/lib/usrp/cores/time64_core_200.cpp | 34 +++++++++++++----------- host/lib/usrp/cores/time64_core_200.hpp | 4 +-- host/lib/usrp/e100/e100_impl.cpp | 8 +++--- host/lib/usrp/e100/e100_regs.hpp | 8 +++--- host/lib/usrp/e100/io_impl.cpp | 8 +++--- host/lib/usrp/usrp2/io_impl.cpp | 8 +++--- host/lib/usrp/usrp2/usrp2_iface.cpp | 4 +-- host/lib/usrp/usrp2/usrp2_impl.cpp | 8 +++--- host/lib/usrp/usrp2/usrp2_regs.hpp | 8 +++--- host/tests/sph_recv_test.cpp | 24 ++++++++--------- host/tests/sph_send_test.cpp | 6 +---- host/tests/time_spec_test.cpp | 6 ++--- 20 files changed, 120 insertions(+), 109 deletions(-) diff --git a/host/include/uhd/types/time_spec.hpp b/host/include/uhd/types/time_spec.hpp index 02de20ea1..cf8588c5b 100644 --- a/host/include/uhd/types/time_spec.hpp +++ b/host/include/uhd/types/time_spec.hpp @@ -1,5 +1,5 @@ // -// Copyright 2010-2011 Ettus Research LLC +// Copyright 2010-2012 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 @@ -60,7 +60,7 @@ namespace uhd{ time_spec_t(time_t full_secs, double frac_secs = 0); /*! - * Create a time_spec_t from whole and fractional seconds. + * Create a time_spec_t from whole seconds and fractional ticks. * Translation from clock-domain specific units. * \param full_secs the whole/integer seconds count * \param tick_count the fractional seconds tick count @@ -68,6 +68,14 @@ namespace uhd{ */ time_spec_t(time_t full_secs, long tick_count, double tick_rate); + /*! + * Create a time_spec_t from a 64-bit tick count. + * Translation from clock-domain specific units. + * \param ticks an integer count of ticks + * \param tick_rate the number of ticks per second + */ + static time_spec_t from_ticks(long long ticks, double tick_rate); + /*! * Convert the fractional seconds to clock ticks. * Translation into clock-domain specific units. @@ -76,6 +84,14 @@ namespace uhd{ */ long get_tick_count(double tick_rate) const; + /*! + * Convert the time spec into a 64-bit tick count. + * Translation into clock-domain specific units. + * \param tick_rate the number of ticks per second + * \return an integer number of ticks + */ + long long to_ticks(const double tick_rate) const; + /*! * Get the time as a real-valued seconds count. * Note: If this time_spec_t represents an absolute time, diff --git a/host/lib/transport/super_recv_packet_handler.hpp b/host/lib/transport/super_recv_packet_handler.hpp index a5876c8bf..939e7aeb3 100644 --- a/host/lib/transport/super_recv_packet_handler.hpp +++ b/host/lib/transport/super_recv_packet_handler.hpp @@ -1,5 +1,5 @@ // -// Copyright 2011 Ettus Research LLC +// Copyright 2011-2012 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 @@ -283,7 +283,7 @@ private: info.ifpi.num_packet_words32 = num_packet_words32 - _header_offset_words32; info.vrt_hdr = buff->cast() + _header_offset_words32; _vrt_unpacker(info.vrt_hdr, info.ifpi); - info.time = time_spec_t(time_t(info.ifpi.tsi), size_t(info.ifpi.tsf), _tick_rate); //assumes has_tsi and has_tsf are true + info.time = time_spec_t::from_ticks(info.ifpi.tsf, _tick_rate); //assumes has_tsf is true info.copy_buff = reinterpret_cast(info.vrt_hdr + info.ifpi.num_header_words32); //-------------------------------------------------------------- @@ -436,7 +436,7 @@ private: alignment_check(index, curr_info); std::swap(curr_info, next_info); //save progress from curr -> next curr_info.metadata.has_time_spec = prev_info.metadata.has_time_spec; - curr_info.metadata.time_spec = prev_info.metadata.time_spec + time_spec_t(0, + curr_info.metadata.time_spec = prev_info.metadata.time_spec + time_spec_t::from_ticks( prev_info[index].ifpi.num_payload_words32*sizeof(boost::uint32_t)/_bytes_per_otw_item, _samp_rate); curr_info.metadata.more_fragments = false; curr_info.metadata.fragment_offset = 0; @@ -508,7 +508,7 @@ private: metadata = info.metadata; //interpolate the time spec (useful when this is a fragment) - metadata.time_spec += time_spec_t(0, info.fragment_offset_in_samps, _samp_rate); + metadata.time_spec += time_spec_t::from_ticks(info.fragment_offset_in_samps, _samp_rate); //extract the number of samples available to copy const size_t nsamps_available = info.data_bytes_to_copy/_bytes_per_otw_item; diff --git a/host/lib/transport/super_send_packet_handler.hpp b/host/lib/transport/super_send_packet_handler.hpp index 57304a7d4..3d68507ed 100644 --- a/host/lib/transport/super_send_packet_handler.hpp +++ b/host/lib/transport/super_send_packet_handler.hpp @@ -1,5 +1,5 @@ // -// Copyright 2011 Ettus Research LLC +// Copyright 2011-2012 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 @@ -135,10 +135,9 @@ public: if_packet_info.has_sid = false; if_packet_info.has_cid = false; if_packet_info.has_tlr = true; - if_packet_info.has_tsi = metadata.has_time_spec; + if_packet_info.has_tsi = false; if_packet_info.has_tsf = metadata.has_time_spec; - if_packet_info.tsi = boost::uint32_t(metadata.time_spec.get_full_secs()); - if_packet_info.tsf = boost::uint64_t(metadata.time_spec.get_tick_count(_tick_rate)); + if_packet_info.tsf = metadata.time_spec.to_ticks(_tick_rate); if_packet_info.sob = metadata.start_of_burst; if_packet_info.eob = metadata.end_of_burst; @@ -174,9 +173,8 @@ public: if (num_samps_sent == 0) return total_num_samps_sent; //setup metadata for the next fragment - const time_spec_t time_spec = metadata.time_spec + time_spec_t(0, total_num_samps_sent, _samp_rate); - if_packet_info.tsi = boost::uint32_t(time_spec.get_full_secs()); - if_packet_info.tsf = boost::uint64_t(time_spec.get_tick_count(_tick_rate)); + const time_spec_t time_spec = metadata.time_spec + time_spec_t::from_ticks(total_num_samps_sent, _samp_rate); + if_packet_info.tsf = time_spec.to_ticks(_tick_rate); if_packet_info.sob = false; } diff --git a/host/lib/types/time_spec.cpp b/host/lib/types/time_spec.cpp index 8e540c14c..176ee8079 100644 --- a/host/lib/types/time_spec.cpp +++ b/host/lib/types/time_spec.cpp @@ -1,5 +1,5 @@ // -// Copyright 2011 Ettus Research LLC +// Copyright 2011-2012 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 @@ -16,6 +16,7 @@ // #include +#include //imaxdiv, intmax_t using namespace uhd; @@ -23,18 +24,6 @@ using namespace uhd; * Time spec system time **********************************************************************/ -/*! - * Creates a time spec from system counts: - * TODO make part of API as a static factory function - * The counts type is 64 bits and will overflow the ticks type of long. - * Therefore, divmod the counts into seconds + sub-second counts first. - */ -#include //imaxdiv, intmax_t -static UHD_INLINE time_spec_t time_spec_t_from_counts(intmax_t counts, intmax_t freq){ - imaxdiv_t divres = imaxdiv(counts, freq); - return time_spec_t(time_t(divres.quot), double(divres.rem)/freq); -} - #ifdef HAVE_CLOCK_GETTIME #include time_spec_t time_spec_t::get_system_time(void){ @@ -49,7 +38,7 @@ time_spec_t time_spec_t::get_system_time(void){ time_spec_t time_spec_t::get_system_time(void){ mach_timebase_info_data_t info; mach_timebase_info(&info); intmax_t nanosecs = mach_absolute_time()*info.numer/info.denom; - return time_spec_t_from_counts(nanosecs, intmax_t(1e9)); + return time_spec_t::from_ticks(nanosecs, intmax_t(1e9)); } #endif /* HAVE_MACH_ABSOLUTE_TIME */ @@ -60,7 +49,7 @@ time_spec_t time_spec_t::get_system_time(void){ LARGE_INTEGER counts, freq; QueryPerformanceCounter(&counts); QueryPerformanceFrequency(&freq); - return time_spec_t_from_counts(counts.QuadPart, freq.QuadPart); + return time_spec_t::from_ticks(counts.QuadPart, freq.QuadPart); } #endif /* HAVE_QUERY_PERFORMANCE_COUNTER */ @@ -104,6 +93,11 @@ time_spec_t::time_spec_t(time_t full_secs, long tick_count, double tick_rate){ time_spec_init(full_secs, frac_secs); } +time_spec_t time_spec_t::from_ticks(long long ticks, double tick_rate){ + const imaxdiv_t divres = imaxdiv(ticks, tick_rate); + return time_spec_t(time_t(divres.quot), double(divres.rem)/tick_rate); +} + /*********************************************************************** * Time spec accessors **********************************************************************/ @@ -111,6 +105,11 @@ long time_spec_t::get_tick_count(double tick_rate) const{ return long(this->get_frac_secs()*tick_rate + 0.5); } +long long time_spec_t::to_ticks(double tick_rate) const{ + return (long long)(this->get_frac_secs()*tick_rate + 0.5) + \ + (long long)((this->get_full_secs()) * (long long)(tick_rate)); +} + double time_spec_t::get_real_secs(void) const{ return this->_full_secs + this->_frac_secs; } diff --git a/host/lib/usrp/b100/b100_impl.cpp b/host/lib/usrp/b100/b100_impl.cpp index 08a2cdeec..ce0b9453b 100644 --- a/host/lib/usrp/b100/b100_impl.cpp +++ b/host/lib/usrp/b100/b100_impl.cpp @@ -364,10 +364,10 @@ b100_impl::b100_impl(const device_addr_t &device_addr){ // create time control objects //////////////////////////////////////////////////////////////////// time64_core_200::readback_bases_type time64_rb_bases; - time64_rb_bases.rb_secs_now = B100_REG_RB_TIME_NOW_SECS; - time64_rb_bases.rb_ticks_now = B100_REG_RB_TIME_NOW_TICKS; - time64_rb_bases.rb_secs_pps = B100_REG_RB_TIME_PPS_SECS; - time64_rb_bases.rb_ticks_pps = B100_REG_RB_TIME_PPS_TICKS; + time64_rb_bases.rb_hi_now = B100_REG_RB_TIME_NOW_HI; + time64_rb_bases.rb_lo_now = B100_REG_RB_TIME_NOW_LO; + time64_rb_bases.rb_hi_pps = B100_REG_RB_TIME_PPS_HI; + time64_rb_bases.rb_lo_pps = B100_REG_RB_TIME_PPS_LO; _time64 = time64_core_200::make( _fpga_ctrl, B100_REG_SR_ADDR(B100_SR_TIME64), time64_rb_bases ); diff --git a/host/lib/usrp/b100/b100_regs.hpp b/host/lib/usrp/b100/b100_regs.hpp index 77b643372..987a09f03 100644 --- a/host/lib/usrp/b100/b100_regs.hpp +++ b/host/lib/usrp/b100/b100_regs.hpp @@ -76,10 +76,10 @@ #define B100_REG_RB_MUX_32_BASE B100_REG_SLAVE(7) -#define B100_REG_RB_TIME_NOW_SECS B100_REG_RB_MUX_32_BASE + 0 -#define B100_REG_RB_TIME_NOW_TICKS B100_REG_RB_MUX_32_BASE + 4 -#define B100_REG_RB_TIME_PPS_SECS B100_REG_RB_MUX_32_BASE + 8 -#define B100_REG_RB_TIME_PPS_TICKS B100_REG_RB_MUX_32_BASE + 12 +#define B100_REG_RB_TIME_NOW_HI B100_REG_RB_MUX_32_BASE + 0 +#define B100_REG_RB_TIME_NOW_LO B100_REG_RB_MUX_32_BASE + 4 +#define B100_REG_RB_TIME_PPS_HI B100_REG_RB_MUX_32_BASE + 8 +#define B100_REG_RB_TIME_PPS_LO B100_REG_RB_MUX_32_BASE + 12 #define B100_REG_RB_MISC_TEST32 B100_REG_RB_MUX_32_BASE + 16 #define B100_REG_RB_COMPAT B100_REG_RB_MUX_32_BASE + 24 #define B100_REG_RB_GPIO B100_REG_RB_MUX_32_BASE + 28 diff --git a/host/lib/usrp/b100/io_impl.cpp b/host/lib/usrp/b100/io_impl.cpp index ac7c860d2..bd60e75cf 100644 --- a/host/lib/usrp/b100/io_impl.cpp +++ b/host/lib/usrp/b100/io_impl.cpp @@ -84,10 +84,8 @@ void b100_impl::handle_async_message(managed_recv_buffer::sptr rbuf){ //fill in the async metadata async_metadata_t metadata; metadata.channel = 0; - metadata.has_time_spec = if_packet_info.has_tsi and if_packet_info.has_tsf; - metadata.time_spec = time_spec_t( - time_t(if_packet_info.tsi), size_t(if_packet_info.tsf), _clock_ctrl->get_fpga_clock_rate() - ); + metadata.has_time_spec = if_packet_info.has_tsf; + metadata.time_spec = time_spec_t::from_ticks(if_packet_info.tsf, _clock_ctrl->get_fpga_clock_rate()); metadata.event_code = async_metadata_t::event_code_t(sph::get_context_code(vrt_hdr, if_packet_info)); _io_impl->async_msg_fifo.push_with_pop_on_full(metadata); if (metadata.event_code & @@ -206,6 +204,7 @@ rx_streamer::sptr b100_impl::get_rx_stream(const uhd::stream_args_t &args_){ + vrt::max_if_hdr_words32*sizeof(boost::uint32_t) + sizeof(vrt::if_packet_info_t().tlr) //forced to have trailer - sizeof(vrt::if_packet_info_t().cid) //no class id ever used + - sizeof(vrt::if_packet_info_t().tsi) //no int time ever used ; const size_t bpp = B100_MAX_PKT_BYTE_LIMIT - hdr_size; const size_t bpi = convert::get_bytes_per_item(args.otw_format); @@ -262,6 +261,7 @@ tx_streamer::sptr b100_impl::get_tx_stream(const uhd::stream_args_t &args_){ + sizeof(vrt::if_packet_info_t().tlr) //forced to have trailer - sizeof(vrt::if_packet_info_t().sid) //no stream id ever used - sizeof(vrt::if_packet_info_t().cid) //no class id ever used + - sizeof(vrt::if_packet_info_t().tsi) //no int time ever used ; static const size_t bpp = B100_MAX_PKT_BYTE_LIMIT - hdr_size; const size_t spp = bpp/convert::get_bytes_per_item(args.otw_format); diff --git a/host/lib/usrp/cores/rx_dsp_core_200.cpp b/host/lib/usrp/cores/rx_dsp_core_200.cpp index d9ca84e0f..ea0384dbe 100644 --- a/host/lib/usrp/cores/rx_dsp_core_200.cpp +++ b/host/lib/usrp/cores/rx_dsp_core_200.cpp @@ -36,8 +36,8 @@ #define FLAG_DSP_RX_MUX_REAL_MODE (1 << 1) #define REG_RX_CTRL_STREAM_CMD _ctrl_base + 0 -#define REG_RX_CTRL_TIME_SECS _ctrl_base + 4 -#define REG_RX_CTRL_TIME_TICKS _ctrl_base + 8 +#define REG_RX_CTRL_TIME_HI _ctrl_base + 4 +#define REG_RX_CTRL_TIME_LO _ctrl_base + 8 #define REG_RX_CTRL_CLEAR _ctrl_base + 12 #define REG_RX_CTRL_VRT_HDR _ctrl_base + 16 #define REG_RX_CTRL_VRT_SID _ctrl_base + 20 @@ -83,7 +83,6 @@ public: _iface->poke32(REG_RX_CTRL_VRT_HDR, 0 | (0x1 << 28) //if data with stream id | (0x1 << 26) //has trailer - | (0x3 << 22) //integer time other | (0x1 << 20) //fractional time sample count ); _iface->poke32(REG_RX_CTRL_VRT_SID, _sid); @@ -122,8 +121,9 @@ public: //issue the stream command _iface->poke32(REG_RX_CTRL_STREAM_CMD, cmd_word); - _iface->poke32(REG_RX_CTRL_TIME_SECS, boost::uint32_t(stream_cmd.time_spec.get_full_secs())); - _iface->poke32(REG_RX_CTRL_TIME_TICKS, stream_cmd.time_spec.get_tick_count(_tick_rate)); //latches the command + const boost::uint64_t ticks = stream_cmd.time_spec.to_ticks(_tick_rate); + _iface->poke32(REG_RX_CTRL_TIME_HI, boost::uint32_t(ticks >> 32)); + _iface->poke32(REG_RX_CTRL_TIME_LO, boost::uint32_t(ticks >> 0)); //latches the command } void set_mux(const std::string &mode, const bool fe_swapped){ diff --git a/host/lib/usrp/cores/time64_core_200.cpp b/host/lib/usrp/cores/time64_core_200.cpp index 23d1bdea2..e460d1106 100644 --- a/host/lib/usrp/cores/time64_core_200.cpp +++ b/host/lib/usrp/cores/time64_core_200.cpp @@ -20,11 +20,10 @@ #include #include -#define REG_TIME64_SECS _base + 0 -#define REG_TIME64_TICKS _base + 4 +#define REG_TIME64_TICKS_HI _base + 0 +#define REG_TIME64_TICKS_LO _base + 4 #define REG_TIME64_FLAGS _base + 8 #define REG_TIME64_IMM _base + 12 -#define REG_TIME64_TPS _base + 16 #define REG_TIME64_MIMO_SYNC _base + 20 //lower byte is delay cycles //pps flags (see above) @@ -59,39 +58,42 @@ public: void set_tick_rate(const double rate){ _tick_rate = rate; - _iface->poke32(REG_TIME64_TPS, boost::math::iround(rate)); } uhd::time_spec_t get_time_now(void){ for (size_t i = 0; i < 3; i++){ //special algorithm because we cant read 64 bits synchronously - const boost::uint32_t secs = _iface->peek32(_readback_bases.rb_secs_now); - const boost::uint32_t ticks = _iface->peek32(_readback_bases.rb_ticks_now); - if (secs != _iface->peek32(_readback_bases.rb_secs_now)) continue; - return time_spec_t(secs, ticks, _tick_rate); + const boost::uint32_t ticks_hi = _iface->peek32(_readback_bases.rb_hi_now); + const boost::uint32_t ticks_lo = _iface->peek32(_readback_bases.rb_lo_now); + if (ticks_hi != _iface->peek32(_readback_bases.rb_hi_now)) continue; + const boost::uint64_t ticks = (boost::uint64_t(ticks_hi) << 32) | ticks_lo; + return time_spec_t::from_ticks(ticks, _tick_rate); } throw uhd::runtime_error("time64_core_200: get time now timeout"); } uhd::time_spec_t get_time_last_pps(void){ for (size_t i = 0; i < 3; i++){ //special algorithm because we cant read 64 bits synchronously - const boost::uint32_t secs = _iface->peek32(_readback_bases.rb_secs_pps); - const boost::uint32_t ticks = _iface->peek32(_readback_bases.rb_ticks_pps); - if (secs != _iface->peek32(_readback_bases.rb_secs_pps)) continue; - return time_spec_t(secs, ticks, _tick_rate); + const boost::uint32_t ticks_hi = _iface->peek32(_readback_bases.rb_hi_pps); + const boost::uint32_t ticks_lo = _iface->peek32(_readback_bases.rb_lo_pps); + if (ticks_hi != _iface->peek32(_readback_bases.rb_hi_pps)) continue; + const boost::uint64_t ticks = (boost::uint64_t(ticks_hi) << 32) | ticks_lo; + return time_spec_t::from_ticks(ticks, _tick_rate); } throw uhd::runtime_error("time64_core_200: get time last pps timeout"); } void set_time_now(const uhd::time_spec_t &time){ - _iface->poke32(REG_TIME64_TICKS, time.get_tick_count(_tick_rate)); + const boost::uint64_t ticks = time.to_ticks(_tick_rate); + _iface->poke32(REG_TIME64_TICKS_LO, boost::uint32_t(ticks >> 0)); _iface->poke32(REG_TIME64_IMM, FLAG_TIME64_LATCH_NOW); - _iface->poke32(REG_TIME64_SECS, boost::uint32_t(time.get_full_secs())); //latches all 3 + _iface->poke32(REG_TIME64_TICKS_HI, boost::uint32_t(ticks >> 32)); //latches all 3 } void set_time_next_pps(const uhd::time_spec_t &time){ - _iface->poke32(REG_TIME64_TICKS, time.get_tick_count(_tick_rate)); + const boost::uint64_t ticks = time.to_ticks(_tick_rate); + _iface->poke32(REG_TIME64_TICKS_LO, boost::uint32_t(ticks >> 0)); _iface->poke32(REG_TIME64_IMM, FLAG_TIME64_LATCH_NEXT_PPS); - _iface->poke32(REG_TIME64_SECS, boost::uint32_t(time.get_full_secs())); //latches all 3 + _iface->poke32(REG_TIME64_TICKS_HI, boost::uint32_t(ticks >> 32)); //latches all 3 } void set_time_source(const std::string &source){ diff --git a/host/lib/usrp/cores/time64_core_200.hpp b/host/lib/usrp/cores/time64_core_200.hpp index ebd51a02f..7571573a5 100644 --- a/host/lib/usrp/cores/time64_core_200.hpp +++ b/host/lib/usrp/cores/time64_core_200.hpp @@ -31,8 +31,8 @@ public: typedef boost::shared_ptr sptr; struct readback_bases_type{ - size_t rb_secs_now, rb_ticks_now; - size_t rb_secs_pps, rb_ticks_pps; + size_t rb_hi_now, rb_lo_now; + size_t rb_hi_pps, rb_lo_pps; }; //! makes a new time64 core from iface and slave base diff --git a/host/lib/usrp/e100/e100_impl.cpp b/host/lib/usrp/e100/e100_impl.cpp index 8ab6ab533..a01ce4a7b 100644 --- a/host/lib/usrp/e100/e100_impl.cpp +++ b/host/lib/usrp/e100/e100_impl.cpp @@ -326,10 +326,10 @@ e100_impl::e100_impl(const uhd::device_addr_t &device_addr){ // create time control objects //////////////////////////////////////////////////////////////////// time64_core_200::readback_bases_type time64_rb_bases; - time64_rb_bases.rb_secs_now = E100_REG_RB_TIME_NOW_SECS; - time64_rb_bases.rb_ticks_now = E100_REG_RB_TIME_NOW_TICKS; - time64_rb_bases.rb_secs_pps = E100_REG_RB_TIME_PPS_SECS; - time64_rb_bases.rb_ticks_pps = E100_REG_RB_TIME_PPS_TICKS; + time64_rb_bases.rb_hi_now = E100_REG_RB_TIME_NOW_HI; + time64_rb_bases.rb_lo_now = E100_REG_RB_TIME_NOW_LO; + time64_rb_bases.rb_hi_pps = E100_REG_RB_TIME_PPS_HI; + time64_rb_bases.rb_lo_pps = E100_REG_RB_TIME_PPS_LO; _time64 = time64_core_200::make( _fpga_ctrl, E100_REG_SR_ADDR(UE_SR_TIME64), time64_rb_bases ); diff --git a/host/lib/usrp/e100/e100_regs.hpp b/host/lib/usrp/e100/e100_regs.hpp index 0ec5f4de3..75be2cfbe 100644 --- a/host/lib/usrp/e100/e100_regs.hpp +++ b/host/lib/usrp/e100/e100_regs.hpp @@ -86,10 +86,10 @@ #define E100_REG_RB_MUX_32_BASE E100_REG_SLAVE(7) -#define E100_REG_RB_TIME_NOW_SECS E100_REG_RB_MUX_32_BASE + 0 -#define E100_REG_RB_TIME_NOW_TICKS E100_REG_RB_MUX_32_BASE + 4 -#define E100_REG_RB_TIME_PPS_SECS E100_REG_RB_MUX_32_BASE + 8 -#define E100_REG_RB_TIME_PPS_TICKS E100_REG_RB_MUX_32_BASE + 12 +#define E100_REG_RB_TIME_NOW_HI E100_REG_RB_MUX_32_BASE + 0 +#define E100_REG_RB_TIME_NOW_LO E100_REG_RB_MUX_32_BASE + 4 +#define E100_REG_RB_TIME_PPS_HI E100_REG_RB_MUX_32_BASE + 8 +#define E100_REG_RB_TIME_PPS_LO E100_REG_RB_MUX_32_BASE + 12 #define E100_REG_RB_MISC_TEST32 E100_REG_RB_MUX_32_BASE + 16 #define E100_REG_RB_ERR_STATUS E100_REG_RB_MUX_32_BASE + 20 #define E100_REG_RB_COMPAT E100_REG_RB_MUX_32_BASE + 24 diff --git a/host/lib/usrp/e100/io_impl.cpp b/host/lib/usrp/e100/io_impl.cpp index 8c7f5e742..f8e15f3fd 100644 --- a/host/lib/usrp/e100/io_impl.cpp +++ b/host/lib/usrp/e100/io_impl.cpp @@ -124,10 +124,8 @@ void e100_impl::io_impl::handle_irq(void){ //fill in the async metadata async_metadata_t metadata; metadata.channel = 0; - metadata.has_time_spec = if_packet_info.has_tsi and if_packet_info.has_tsf; - metadata.time_spec = time_spec_t( - time_t(if_packet_info.tsi), long(if_packet_info.tsf), tick_rate - ); + metadata.has_time_spec = if_packet_info.has_tsf; + metadata.time_spec = time_spec_t::from_ticks(if_packet_info.tsf, tick_rate); metadata.event_code = async_metadata_t::event_code_t(sph::get_context_code(data.buf, if_packet_info)); //push the message onto the queue @@ -285,6 +283,7 @@ rx_streamer::sptr e100_impl::get_rx_stream(const uhd::stream_args_t &args_){ + vrt::max_if_hdr_words32*sizeof(boost::uint32_t) + sizeof(vrt::if_packet_info_t().tlr) //forced to have trailer - sizeof(vrt::if_packet_info_t().cid) //no class id ever used + - sizeof(vrt::if_packet_info_t().tsi) //no int time ever used ; const size_t bpp = _data_transport->get_recv_frame_size() - hdr_size; const size_t bpi = convert::get_bytes_per_item(args.otw_format); @@ -341,6 +340,7 @@ tx_streamer::sptr e100_impl::get_tx_stream(const uhd::stream_args_t &args_){ + sizeof(vrt::if_packet_info_t().tlr) //forced to have trailer - sizeof(vrt::if_packet_info_t().sid) //no stream id ever used - sizeof(vrt::if_packet_info_t().cid) //no class id ever used + - sizeof(vrt::if_packet_info_t().tsi) //no int time ever used ; static const size_t bpp = _data_transport->get_send_frame_size() - hdr_size; const size_t spp = bpp/convert::get_bytes_per_item(args.otw_format); diff --git a/host/lib/usrp/usrp2/io_impl.cpp b/host/lib/usrp/usrp2/io_impl.cpp index f19f49e28..f0c159f16 100644 --- a/host/lib/usrp/usrp2/io_impl.cpp +++ b/host/lib/usrp/usrp2/io_impl.cpp @@ -202,10 +202,8 @@ void usrp2_impl::io_impl::recv_pirate_loop( //fill in the async metadata async_metadata_t metadata; metadata.channel = index; - metadata.has_time_spec = if_packet_info.has_tsi and if_packet_info.has_tsf; - metadata.time_spec = time_spec_t( - time_t(if_packet_info.tsi), size_t(if_packet_info.tsf), tick_rate - ); + metadata.has_time_spec = if_packet_info.has_tsf; + metadata.time_spec = time_spec_t::from_ticks(if_packet_info.tsf, tick_rate); metadata.event_code = async_metadata_t::event_code_t(sph::get_context_code(vrt_hdr, if_packet_info)); //catch the flow control packets and react @@ -388,6 +386,7 @@ rx_streamer::sptr usrp2_impl::get_rx_stream(const uhd::stream_args_t &args_){ + vrt::max_if_hdr_words32*sizeof(boost::uint32_t) + sizeof(vrt::if_packet_info_t().tlr) //forced to have trailer - sizeof(vrt::if_packet_info_t().cid) //no class id ever used + - sizeof(vrt::if_packet_info_t().tsi) //no int time ever used ; const size_t bpp = _mbc[_mbc.keys().front()].rx_dsp_xports[0]->get_recv_frame_size() - hdr_size; const size_t bpi = convert::get_bytes_per_item(args.otw_format); @@ -454,6 +453,7 @@ tx_streamer::sptr usrp2_impl::get_tx_stream(const uhd::stream_args_t &args_){ + sizeof(vrt::if_packet_info_t().tlr) //forced to have trailer - sizeof(vrt::if_packet_info_t().cid) //no class id ever used - sizeof(vrt::if_packet_info_t().sid) //no stream id ever used + - sizeof(vrt::if_packet_info_t().tsi) //no int time ever used ; const size_t bpp = _mbc[_mbc.keys().front()].tx_dsp_xport->get_send_frame_size() - hdr_size; const size_t spp = bpp/convert::get_bytes_per_item(args.otw_format); diff --git a/host/lib/usrp/usrp2/usrp2_iface.cpp b/host/lib/usrp/usrp2/usrp2_iface.cpp index 4830c10d9..f3d474a2d 100644 --- a/host/lib/usrp/usrp2/usrp2_iface.cpp +++ b/host/lib/usrp/usrp2/usrp2_iface.cpp @@ -126,7 +126,7 @@ public: bool is_device_locked(void){ boost::uint32_t lock_secs = this->get_reg(U2_FW_REG_LOCK_TIME); boost::uint32_t lock_gpid = this->get_reg(U2_FW_REG_LOCK_GPID); - boost::uint32_t curr_secs = this->peek32(U2_REG_TIME64_SECS_RB_IMM); + boost::uint32_t curr_secs = this->peek32(U2_REG_TIME64_LO_RB_IMM)/100e6; //if the difference is larger, assume not locked anymore if (curr_secs - lock_secs >= 3) return false; @@ -137,7 +137,7 @@ public: void lock_task(void){ //re-lock in task - boost::uint32_t curr_secs = this->peek32(U2_REG_TIME64_SECS_RB_IMM); + boost::uint32_t curr_secs = this->peek32(U2_REG_TIME64_LO_RB_IMM)/100e6; this->get_reg(U2_FW_REG_LOCK_TIME, curr_secs); //sleep for a bit boost::this_thread::sleep(boost::posix_time::milliseconds(1500)); diff --git a/host/lib/usrp/usrp2/usrp2_impl.cpp b/host/lib/usrp/usrp2/usrp2_impl.cpp index 7101e040a..2077ab009 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.cpp +++ b/host/lib/usrp/usrp2/usrp2_impl.cpp @@ -546,10 +546,10 @@ usrp2_impl::usrp2_impl(const device_addr_t &_device_addr){ // create time control objects //////////////////////////////////////////////////////////////// time64_core_200::readback_bases_type time64_rb_bases; - time64_rb_bases.rb_secs_now = U2_REG_TIME64_SECS_RB_IMM; - time64_rb_bases.rb_ticks_now = U2_REG_TIME64_TICKS_RB_IMM; - time64_rb_bases.rb_secs_pps = U2_REG_TIME64_SECS_RB_PPS; - time64_rb_bases.rb_ticks_pps = U2_REG_TIME64_TICKS_RB_PPS; + time64_rb_bases.rb_hi_now = U2_REG_TIME64_HI_RB_IMM; + time64_rb_bases.rb_lo_now = U2_REG_TIME64_LO_RB_IMM; + time64_rb_bases.rb_hi_pps = U2_REG_TIME64_HI_RB_PPS; + time64_rb_bases.rb_lo_pps = U2_REG_TIME64_LO_RB_PPS; _mbc[mb].time64 = time64_core_200::make( _mbc[mb].iface, U2_REG_SR_ADDR(SR_TIME64), time64_rb_bases, mimo_clock_sync_delay_cycles ); diff --git a/host/lib/usrp/usrp2/usrp2_regs.hpp b/host/lib/usrp/usrp2/usrp2_regs.hpp index 5d39e527d..e14798ecb 100644 --- a/host/lib/usrp/usrp2/usrp2_regs.hpp +++ b/host/lib/usrp/usrp2/usrp2_regs.hpp @@ -97,11 +97,11 @@ //////////////////////////////////////////////// #define U2_REG_STATUS READBACK_BASE + 4*8 #define U2_REG_GPIO_RB READBACK_BASE + 4*9 -#define U2_REG_TIME64_SECS_RB_IMM READBACK_BASE + 4*10 -#define U2_REG_TIME64_TICKS_RB_IMM READBACK_BASE + 4*11 +#define U2_REG_TIME64_HI_RB_IMM READBACK_BASE + 4*10 +#define U2_REG_TIME64_LO_RB_IMM READBACK_BASE + 4*11 #define U2_REG_COMPAT_NUM_RB READBACK_BASE + 4*12 #define U2_REG_IRQ_RB READBACK_BASE + 4*13 -#define U2_REG_TIME64_SECS_RB_PPS READBACK_BASE + 4*14 -#define U2_REG_TIME64_TICKS_RB_PPS READBACK_BASE + 4*15 +#define U2_REG_TIME64_HI_RB_PPS READBACK_BASE + 4*14 +#define U2_REG_TIME64_LO_RB_PPS READBACK_BASE + 4*15 #endif /* INCLUDED_USRP2_REGS_HPP */ diff --git a/host/tests/sph_recv_test.cpp b/host/tests/sph_recv_test.cpp index 85d06aa0d..9b45d7016 100644 --- a/host/tests/sph_recv_test.cpp +++ b/host/tests/sph_recv_test.cpp @@ -1,5 +1,5 @@ // -// Copyright 2011 Ettus Research LLC +// Copyright 2011-2012 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 @@ -159,7 +159,7 @@ BOOST_AUTO_TEST_CASE(test_sph_recv_one_channel_normal){ BOOST_CHECK_EQUAL(metadata.error_code, uhd::rx_metadata_t::ERROR_CODE_NONE); BOOST_CHECK(not metadata.more_fragments); BOOST_CHECK(metadata.has_time_spec); - BOOST_CHECK_TS_CLOSE(metadata.time_spec, uhd::time_spec_t(0, num_accum_samps, SAMP_RATE)); + BOOST_CHECK_TS_CLOSE(metadata.time_spec, uhd::time_spec_t::from_ticks(num_accum_samps, SAMP_RATE)); BOOST_CHECK_EQUAL(num_samps_ret, 10 + i%10); num_accum_samps += num_samps_ret; } @@ -232,14 +232,14 @@ BOOST_AUTO_TEST_CASE(test_sph_recv_one_channel_sequence_error){ if (i == NUM_PKTS_TO_TEST/2){ //must get the soft overflow here BOOST_REQUIRE(metadata.error_code == uhd::rx_metadata_t::ERROR_CODE_OVERFLOW); - BOOST_CHECK_TS_CLOSE(metadata.time_spec, uhd::time_spec_t(0, num_accum_samps, SAMP_RATE)); + BOOST_CHECK_TS_CLOSE(metadata.time_spec, uhd::time_spec_t::from_ticks(num_accum_samps, SAMP_RATE)); num_accum_samps += 10 + i%10; } else{ BOOST_CHECK_EQUAL(metadata.error_code, uhd::rx_metadata_t::ERROR_CODE_NONE); BOOST_CHECK(not metadata.more_fragments); BOOST_CHECK(metadata.has_time_spec); - BOOST_CHECK_TS_CLOSE(metadata.time_spec, uhd::time_spec_t(0, num_accum_samps, SAMP_RATE)); + BOOST_CHECK_TS_CLOSE(metadata.time_spec, uhd::time_spec_t::from_ticks(num_accum_samps, SAMP_RATE)); BOOST_CHECK_EQUAL(num_samps_ret, 10 + i%10); num_accum_samps += num_samps_ret; } @@ -323,7 +323,7 @@ BOOST_AUTO_TEST_CASE(test_sph_recv_one_channel_inline_message){ BOOST_CHECK_EQUAL(metadata.error_code, uhd::rx_metadata_t::ERROR_CODE_NONE); BOOST_CHECK(not metadata.more_fragments); BOOST_CHECK(metadata.has_time_spec); - BOOST_CHECK_TS_CLOSE(metadata.time_spec, uhd::time_spec_t(0, num_accum_samps, SAMP_RATE)); + BOOST_CHECK_TS_CLOSE(metadata.time_spec, uhd::time_spec_t::from_ticks(num_accum_samps, SAMP_RATE)); BOOST_CHECK_EQUAL(num_samps_ret, 10 + i%10); num_accum_samps += num_samps_ret; if (i == NUM_PKTS_TO_TEST/2){ @@ -332,7 +332,7 @@ BOOST_AUTO_TEST_CASE(test_sph_recv_one_channel_inline_message){ ); std::cout << "metadata.error_code " << metadata.error_code << std::endl; BOOST_REQUIRE(metadata.error_code == uhd::rx_metadata_t::ERROR_CODE_OVERFLOW); - BOOST_CHECK_TS_CLOSE(metadata.time_spec, uhd::time_spec_t(0, num_accum_samps, SAMP_RATE)); + BOOST_CHECK_TS_CLOSE(metadata.time_spec, uhd::time_spec_t::from_ticks(num_accum_samps, SAMP_RATE)); BOOST_CHECK_EQUAL(overflow_handler.num_overflow, size_t(1)); } } @@ -414,7 +414,7 @@ BOOST_AUTO_TEST_CASE(test_sph_recv_multi_channel_normal){ BOOST_CHECK_EQUAL(metadata.error_code, uhd::rx_metadata_t::ERROR_CODE_NONE); BOOST_CHECK(not metadata.more_fragments); BOOST_CHECK(metadata.has_time_spec); - BOOST_CHECK_TS_CLOSE(metadata.time_spec, uhd::time_spec_t(0, num_accum_samps, SAMP_RATE)); + BOOST_CHECK_TS_CLOSE(metadata.time_spec, uhd::time_spec_t::from_ticks(num_accum_samps, SAMP_RATE)); BOOST_CHECK_EQUAL(num_samps_ret, 10 + i%10); num_accum_samps += num_samps_ret; } @@ -500,14 +500,14 @@ BOOST_AUTO_TEST_CASE(test_sph_recv_multi_channel_sequence_error){ if (i == NUM_PKTS_TO_TEST/2){ //must get the soft overflow here BOOST_REQUIRE(metadata.error_code == uhd::rx_metadata_t::ERROR_CODE_OVERFLOW); - BOOST_CHECK_TS_CLOSE(metadata.time_spec, uhd::time_spec_t(0, num_accum_samps, SAMP_RATE)); + BOOST_CHECK_TS_CLOSE(metadata.time_spec, uhd::time_spec_t::from_ticks(num_accum_samps, SAMP_RATE)); num_accum_samps += 10 + i%10; } else{ BOOST_CHECK_EQUAL(metadata.error_code, uhd::rx_metadata_t::ERROR_CODE_NONE); BOOST_CHECK(not metadata.more_fragments); BOOST_CHECK(metadata.has_time_spec); - BOOST_CHECK_TS_CLOSE(metadata.time_spec, uhd::time_spec_t(0, num_accum_samps, SAMP_RATE)); + BOOST_CHECK_TS_CLOSE(metadata.time_spec, uhd::time_spec_t::from_ticks(num_accum_samps, SAMP_RATE)); BOOST_CHECK_EQUAL(num_samps_ret, 10 + i%10); num_accum_samps += num_samps_ret; } @@ -593,7 +593,7 @@ BOOST_AUTO_TEST_CASE(test_sph_recv_multi_channel_time_error){ BOOST_CHECK_EQUAL(metadata.error_code, uhd::rx_metadata_t::ERROR_CODE_NONE); BOOST_CHECK(not metadata.more_fragments); BOOST_CHECK(metadata.has_time_spec); - BOOST_CHECK_TS_CLOSE(metadata.time_spec, uhd::time_spec_t(0, num_accum_samps, SAMP_RATE)); + BOOST_CHECK_TS_CLOSE(metadata.time_spec, uhd::time_spec_t::from_ticks(num_accum_samps, SAMP_RATE)); BOOST_CHECK_EQUAL(num_samps_ret, 10 + i%10); num_accum_samps += num_samps_ret; if (i == NUM_PKTS_TO_TEST/2){ @@ -677,7 +677,7 @@ BOOST_AUTO_TEST_CASE(test_sph_recv_multi_channel_fragment){ ); BOOST_CHECK_EQUAL(metadata.error_code, uhd::rx_metadata_t::ERROR_CODE_NONE); BOOST_CHECK(metadata.has_time_spec); - BOOST_CHECK_TS_CLOSE(metadata.time_spec, uhd::time_spec_t(0, num_accum_samps, SAMP_RATE)); + BOOST_CHECK_TS_CLOSE(metadata.time_spec, uhd::time_spec_t::from_ticks(num_accum_samps, SAMP_RATE)); BOOST_CHECK_EQUAL(num_samps_ret, 10); num_accum_samps += num_samps_ret; @@ -690,7 +690,7 @@ BOOST_AUTO_TEST_CASE(test_sph_recv_multi_channel_fragment){ BOOST_CHECK(not metadata.more_fragments); BOOST_CHECK_EQUAL(metadata.fragment_offset, 10); BOOST_CHECK(metadata.has_time_spec); - BOOST_CHECK_TS_CLOSE(metadata.time_spec, uhd::time_spec_t(0, num_accum_samps, SAMP_RATE)); + BOOST_CHECK_TS_CLOSE(metadata.time_spec, uhd::time_spec_t::from_ticks(num_accum_samps, SAMP_RATE)); BOOST_CHECK_EQUAL(num_samps_ret, i%10); num_accum_samps += num_samps_ret; } diff --git a/host/tests/sph_send_test.cpp b/host/tests/sph_send_test.cpp index 25a3f97ee..c31399d12 100644 --- a/host/tests/sph_send_test.cpp +++ b/host/tests/sph_send_test.cpp @@ -1,5 +1,5 @@ // -// Copyright 2011 Ettus Research LLC +// Copyright 2011-2012 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 @@ -136,9 +136,7 @@ BOOST_AUTO_TEST_CASE(test_sph_send_one_channel_one_packet_mode){ std::cout << "data check " << i << std::endl; dummy_send_xport.pop_front_packet(ifpi); BOOST_CHECK_EQUAL(ifpi.num_payload_words32, 10+i%10); - BOOST_CHECK(ifpi.has_tsi); BOOST_CHECK(ifpi.has_tsf); - BOOST_CHECK_EQUAL(ifpi.tsi, 0); BOOST_CHECK_EQUAL(ifpi.tsf, num_accum_samps*TICK_RATE/SAMP_RATE); BOOST_CHECK_EQUAL(ifpi.sob, i == 0); BOOST_CHECK_EQUAL(ifpi.eob, i == NUM_PKTS_TO_TEST-1); @@ -191,9 +189,7 @@ BOOST_AUTO_TEST_CASE(test_sph_send_one_channel_full_buffer_mode){ std::cout << "data check " << i << std::endl; dummy_send_xport.pop_front_packet(ifpi); BOOST_CHECK_EQUAL(ifpi.num_payload_words32, 20); - BOOST_CHECK(ifpi.has_tsi); BOOST_CHECK(ifpi.has_tsf); - BOOST_CHECK_EQUAL(ifpi.tsi, 0); BOOST_CHECK_EQUAL(ifpi.tsf, num_accum_samps*TICK_RATE/SAMP_RATE); BOOST_CHECK_EQUAL(ifpi.sob, i == 0); BOOST_CHECK_EQUAL(ifpi.eob, i == NUM_PKTS_TO_TEST-1); diff --git a/host/tests/time_spec_test.cpp b/host/tests/time_spec_test.cpp index 467da5c18..102b7cda3 100644 --- a/host/tests/time_spec_test.cpp +++ b/host/tests/time_spec_test.cpp @@ -1,5 +1,5 @@ // -// Copyright 2010-2011 Ettus Research LLC +// Copyright 2010-2012 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 @@ -54,11 +54,11 @@ BOOST_AUTO_TEST_CASE(test_time_spec_parts){ BOOST_CHECK_EQUAL(uhd::time_spec_t(1.1).get_full_secs(), 1); BOOST_CHECK_CLOSE(uhd::time_spec_t(1.1).get_frac_secs(), 0.1, 0.001); - BOOST_CHECK_EQUAL(uhd::time_spec_t(1.1).get_tick_count(100), 10); + BOOST_CHECK_EQUAL(uhd::time_spec_t(1.1).to_ticks(100), 110); BOOST_CHECK_EQUAL(uhd::time_spec_t(-1.1).get_full_secs(), -2); BOOST_CHECK_CLOSE(uhd::time_spec_t(-1.1).get_frac_secs(), 0.9, 0.001); - BOOST_CHECK_EQUAL(uhd::time_spec_t(-1.1).get_tick_count(100), 90); + BOOST_CHECK_EQUAL(uhd::time_spec_t(-1.1).to_ticks(100), -110); } BOOST_AUTO_TEST_CASE(test_time_spec_get_system_time){ -- cgit v1.2.3 From 893af3dc280a5d85be2a5beb266dba9bb538292c Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Tue, 7 Feb 2012 11:59:42 -0800 Subject: uhd: added sc8 conversion tests --- host/lib/convert/convert_common.hpp | 2 +- host/lib/convert/convert_with_tables.cpp | 71 +++++++++++++++++++++++++++++- host/lib/convert/gen_convert_general.py | 2 +- host/tests/convert_test.cpp | 74 +++++++++++++++++++++++++++++--- 4 files changed, 139 insertions(+), 10 deletions(-) diff --git a/host/lib/convert/convert_common.hpp b/host/lib/convert/convert_common.hpp index aab59de4b..55bc2e99d 100644 --- a/host/lib/convert/convert_common.hpp +++ b/host/lib/convert/convert_common.hpp @@ -1,5 +1,5 @@ // -// Copyright 2011 Ettus Research LLC +// Copyright 2011-2012 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 diff --git a/host/lib/convert/convert_with_tables.cpp b/host/lib/convert/convert_with_tables.cpp index 2379739a7..4a3ce29b2 100644 --- a/host/lib/convert/convert_with_tables.cpp +++ b/host/lib/convert/convert_with_tables.cpp @@ -1,5 +1,5 @@ // -// Copyright 2011 Ettus Research LLC +// Copyright 2011-2012 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 @@ -26,6 +26,55 @@ static const size_t sc16_table_len = size_t(1 << 16); typedef boost::uint16_t (*tohost16_type)(boost::uint16_t); +/*********************************************************************** + * Implementation for sc16 to sc8 lookup table + * - Lookup the real and imaginary parts individually + **********************************************************************/ +template +class convert_sc16_1_to_sc8_item32_1 : public converter{ +public: + convert_sc16_1_to_sc8_item32_1(void): _table(sc16_table_len){} + + void set_scalar(const double scalar){ + for (size_t i = 0; i < sc16_table_len; i++){ + const boost::int16_t val = boost::uint16_t(i); + _table[i] = boost::int8_t(boost::math::iround(val * scalar / 32767.)); + } + } + + void operator()(const input_type &inputs, const output_type &outputs, const size_t nsamps){ + const sc16_t *input = reinterpret_cast(inputs[0]); + item32_t *output = reinterpret_cast(outputs[0]); + + const size_t num_pairs = nsamps/2; + for (size_t i = 0, j = 0; i < num_pairs; i++, j+=2){ + output[i] = this->lookup(input[j], input[j+1]); + } + + if (nsamps != num_pairs*2){ + output[num_pairs] = this->lookup(input[nsamps-1], 0);; + } + } + + item32_t lookup(const sc16_t &in0, const sc16_t &in1){ + if (swap){ //hope this compiles out, its a template constant + return + (item32_t(_table[size_t(in0.real())]) << 16) | + (item32_t(_table[size_t(in0.imag())]) << 24) | + (item32_t(_table[size_t(in1.real())]) << 0) | + (item32_t(_table[size_t(in1.imag())]) << 8) ; + } + return + (item32_t(_table[size_t(in0.real())]) << 8) | + (item32_t(_table[size_t(in0.imag())]) << 0) | + (item32_t(_table[size_t(in1.real())]) << 24) | + (item32_t(_table[size_t(in1.imag())]) << 16) ; + } + +private: + std::vector _table; +}; + /*********************************************************************** * Implementation for sc16 lookup table * - Lookup the real and imaginary parts individually @@ -121,9 +170,13 @@ private: #ifdef BOOST_BIG_ENDIAN # define SHIFT_PAIR0 16, 0 # define SHIFT_PAIR1 0, 16 +# define BE_SWAP false +# define LE_SWAP true #else # define SHIFT_PAIR0 0, 16 # define SHIFT_PAIR1 16, 0 +# define BE_SWAP true +# define LE_SWAP false #endif static converter::sptr make_convert_sc16_item32_be_1_to_fc32_1(void){ @@ -166,6 +219,14 @@ static converter::sptr make_convert_sc8_item32_le_1_to_sc16_1(void){ return converter::sptr(new convert_sc8_item32_1_to_fcxx_1()); } +static converter::sptr make_convert_sc16_1_to_sc8_item32_be_1(void){ + return converter::sptr(new convert_sc16_1_to_sc8_item32_1()); +} + +static converter::sptr make_convert_sc16_1_to_sc8_item32_le_1(void){ + return converter::sptr(new convert_sc16_1_to_sc8_item32_1()); +} + UHD_STATIC_BLOCK(register_convert_sc16_item32_1_to_fcxx_1){ uhd::convert::id_type id; id.num_inputs = 1; @@ -210,4 +271,12 @@ UHD_STATIC_BLOCK(register_convert_sc16_item32_1_to_fcxx_1){ id.output_format = "sc16"; id.input_format = "sc8_item32_le"; uhd::convert::register_converter(id, &make_convert_sc8_item32_le_1_to_sc16_1, PRIORITY_TABLE); + + id.output_format = "sc16"; + id.input_format = "sc8_item32_be"; + uhd::convert::register_converter(id, &make_convert_sc16_1_to_sc8_item32_be_1, PRIORITY_TABLE); + + id.output_format = "sc16"; + id.input_format = "sc8_item32_le"; + uhd::convert::register_converter(id, &make_convert_sc16_1_to_sc8_item32_le_1, PRIORITY_TABLE); } diff --git a/host/lib/convert/gen_convert_general.py b/host/lib/convert/gen_convert_general.py index a6ae3f810..24729d0d5 100644 --- a/host/lib/convert/gen_convert_general.py +++ b/host/lib/convert/gen_convert_general.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2011 Ettus Research LLC +# Copyright 2011-2012 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 diff --git a/host/tests/convert_test.cpp b/host/tests/convert_test.cpp index 1a5d30080..519b7b711 100644 --- a/host/tests/convert_test.cpp +++ b/host/tests/convert_test.cpp @@ -1,5 +1,5 @@ // -// Copyright 2011-2011 Ettus Research LLC +// Copyright 2011-2012 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 @@ -67,13 +67,13 @@ template static void loopback( * Test short conversion **********************************************************************/ static void test_convert_types_sc16( - size_t nsamps, convert::id_type &id + size_t nsamps, convert::id_type &id, const int extra_div = 1 ){ //fill the input samples std::vector input(nsamps), output(nsamps); BOOST_FOREACH(sc16_t &in, input) in = sc16_t( - std::rand()-(RAND_MAX/2), - std::rand()-(RAND_MAX/2) + short(((std::rand()/double(RAND_MAX/2)) - 1)*32767/extra_div), + short(((std::rand()/double(RAND_MAX/2)) - 1)*32767/extra_div) ); //run the loopback and test @@ -116,15 +116,15 @@ BOOST_AUTO_TEST_CASE(test_convert_types_le_sc16){ **********************************************************************/ template static void test_convert_types_for_floats( - size_t nsamps, convert::id_type &id + size_t nsamps, convert::id_type &id, const double extra_scale = 1.0 ){ typedef typename data_type::value_type value_type; //fill the input samples std::vector input(nsamps), output(nsamps); BOOST_FOREACH(data_type &in, input) in = data_type( - (std::rand()/value_type(RAND_MAX/2)) - 1, - (std::rand()/value_type(RAND_MAX/2)) - 1 + ((std::rand()/value_type(RAND_MAX/2)) - 1)*extra_scale, + ((std::rand()/value_type(RAND_MAX/2)) - 1)*extra_scale ); //run the loopback and test @@ -280,3 +280,63 @@ BOOST_AUTO_TEST_CASE(test_convert_types_sc16_to_fc32){ MY_CHECK_CLOSE(input[i].imag()/float(32767), output[i].imag(), float(0.01)); } } + +/*********************************************************************** + * Test sc8 conversions + **********************************************************************/ +BOOST_AUTO_TEST_CASE(test_convert_types_fc64_and_sc8){ + convert::id_type id; + id.input_format = "fc64"; + id.num_inputs = 1; + id.num_outputs = 1; + + //try various lengths to test edge cases + id.output_format = "sc8_item32_le"; + for (size_t nsamps = 1; nsamps < 16; nsamps++){ + test_convert_types_for_floats(nsamps, id, 1./256); + } + + //try various lengths to test edge cases + id.output_format = "sc8_item32_be"; + for (size_t nsamps = 1; nsamps < 16; nsamps++){ + test_convert_types_for_floats(nsamps, id, 1./256); + } +} + +BOOST_AUTO_TEST_CASE(test_convert_types_fc32_and_sc8){ + convert::id_type id; + id.input_format = "fc32"; + id.num_inputs = 1; + id.num_outputs = 1; + + //try various lengths to test edge cases + id.output_format = "sc8_item32_le"; + for (size_t nsamps = 1; nsamps < 16; nsamps++){ + test_convert_types_for_floats(nsamps, id, 1./256); + } + + //try various lengths to test edge cases + id.output_format = "sc8_item32_be"; + for (size_t nsamps = 1; nsamps < 16; nsamps++){ + test_convert_types_for_floats(nsamps, id, 1./256); + } +} + +BOOST_AUTO_TEST_CASE(test_convert_types_sc16_and_sc8){ + convert::id_type id; + id.input_format = "sc16"; + id.num_inputs = 1; + id.num_outputs = 1; + + //try various lengths to test edge cases + id.output_format = "sc8_item32_le"; + for (size_t nsamps = 1; nsamps < 16; nsamps++){ + test_convert_types_sc16(nsamps, id, 256); + } + + //try various lengths to test edge cases + id.output_format = "sc8_item32_be"; + for (size_t nsamps = 1; nsamps < 16; nsamps++){ + test_convert_types_sc16(nsamps, id, 256); + } +} -- cgit v1.2.3 From 2a79f1928087660b07e183dd81e259fa764a9945 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Wed, 8 Feb 2012 12:37:58 -0800 Subject: uhd: better quantization check for convert test --- host/tests/convert_test.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/host/tests/convert_test.cpp b/host/tests/convert_test.cpp index 519b7b711..0ce4ebacb 100644 --- a/host/tests/convert_test.cpp +++ b/host/tests/convert_test.cpp @@ -31,8 +31,9 @@ typedef std::complex sc16_t; typedef std::complex fc32_t; typedef std::complex fc64_t; -#define MY_CHECK_CLOSE(a, b, f) if ((std::abs(a) > (f))) \ - BOOST_CHECK_CLOSE_FRACTION(a, b, f) +#define MY_CHECK_CLOSE(a, b, f) { \ + BOOST_CHECK_MESSAGE(std::abs((a)-(b)) < f, " " << #a << " (" << (a) << ") error " << #b << " (" << (b) << ")"); \ +} /*********************************************************************** * Loopback runner: @@ -134,8 +135,8 @@ static void test_convert_types_for_floats( std::swap(out_id.num_inputs, out_id.num_outputs); loopback(nsamps, in_id, out_id, input, output); for (size_t i = 0; i < nsamps; i++){ - MY_CHECK_CLOSE(input[i].real(), output[i].real(), value_type(0.01)); - MY_CHECK_CLOSE(input[i].imag(), output[i].imag(), value_type(0.01)); + MY_CHECK_CLOSE(input[i].real(), output[i].real(), value_type(1./32767)); + MY_CHECK_CLOSE(input[i].imag(), output[i].imag(), value_type(1./32767)); } } -- cgit v1.2.3 From 9429905c9713bef42cd7358d01c173eafda0d29e Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Wed, 8 Feb 2012 13:12:44 -0800 Subject: e100: loopback test fix after register tweaks --- host/usrp_e_utils/usrp-e-loopback.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/host/usrp_e_utils/usrp-e-loopback.cpp b/host/usrp_e_utils/usrp-e-loopback.cpp index 5b289c648..d4220adc3 100644 --- a/host/usrp_e_utils/usrp-e-loopback.cpp +++ b/host/usrp_e_utils/usrp-e-loopback.cpp @@ -261,8 +261,7 @@ int main(int argc, char *argv[]){ poke16(E100_REG_MISC_XFER_RATE, (1<<8) | (1<<9)); //clear FIFO state in FPGA and kernel - poke32(E100_REG_CLEAR_RX, 0); - poke32(E100_REG_CLEAR_TX, 0); + poke32(E100_REG_CLEAR_FIFO, 0); ::close(fp); if ((fp = ::open("/dev/usrp_e0", O_RDWR)) < 0){ std::cerr << "Open failed" << std::endl; -- cgit v1.2.3 From 52a10572378d627d3b9467d02fa2b3244bd3cb44 Mon Sep 17 00:00:00 2001 From: Nick Foster Date: Wed, 8 Feb 2012 13:44:52 -0800 Subject: Add Orc functions to convert to sc8. bswap version is a bit of a hack. --- host/lib/convert/convert_orc.orc | 17 +++++++++++++++++ host/lib/convert/convert_with_orc.cpp | 11 +++++++++++ 2 files changed, 28 insertions(+) diff --git a/host/lib/convert/convert_orc.orc b/host/lib/convert/convert_orc.orc index 5450bf4db..f7075606e 100644 --- a/host/lib/convert/convert_orc.orc +++ b/host/lib/convert/convert_orc.orc @@ -61,3 +61,20 @@ x2 swapw dst, tmp .temp 4 tmp x2 swapw tmp, src swapl dst, tmp + +.function _convert_swap_byte_pairs_orc +.source 4 src +.dest 4 dst +swapl dst, src + +.function _convert_fc32_1_to_sc8_1_nswap_orc +.source 8 src +.dest 2 dst +.temp 8 tmp +.temp 4 tmp2 +.floatparam 4 scalar +x2 mulf tmp, src, scalar +x2 convfl tmp, tmp +swaplq tmp, tmp +x2 convlw tmp2, tmp +x2 convwb dst, tmp2 diff --git a/host/lib/convert/convert_with_orc.cpp b/host/lib/convert/convert_with_orc.cpp index 0c46bcf1e..630554564 100644 --- a/host/lib/convert/convert_with_orc.cpp +++ b/host/lib/convert/convert_with_orc.cpp @@ -27,6 +27,8 @@ extern void _convert_item32_1_to_fc32_1_nswap_orc(void *, const void *, float, i extern void _convert_item32_1_to_fc32_1_bswap_orc(void *, const void *, float, int); extern void _convert_sc16_1_to_item32_1_nswap_orc(void *, const void *, float, int); extern void _convert_item32_1_to_sc16_1_nswap_orc(void *, const void *, float, int); +extern void _convert_fc32_1_to_sc8_1_nswap_orc(void *, const void *, float, int); +extern void _convert_swap_byte_pairs_orc(void *, const void *, int); } DECLARE_CONVERTER(fc32, 1, sc16_item32_le, 1, PRIORITY_LIBORC){ @@ -52,3 +54,12 @@ DECLARE_CONVERTER(sc16, 1, sc16_item32_le, 1, PRIORITY_LIBORC){ DECLARE_CONVERTER(sc16_item32_le, 1, sc16, 1, PRIORITY_LIBORC){ _convert_item32_1_to_sc16_1_nswap_orc(outputs[0], inputs[0], scale_factor, nsamps); } + +DECLARE_CONVERTER(fc32, 1, sc8_item32_be, 1, PRIORITY_LIBORC){ + _convert_fc32_1_to_sc8_1_nswap_orc(outputs[0], inputs[0], scale_factor, nsamps); + _convert_swap_byte_pairs_orc(outputs[0], outputs[0], nsamps); +} + +DECLARE_CONVERTER(fc32, 1, sc8_item32_le, 1, PRIORITY_LIBORC){ + _convert_fc32_1_to_sc8_1_nswap_orc(outputs[0], inputs[0], scale_factor, nsamps); +} -- cgit v1.2.3 From d46684710950a6695ee22c079327253a91eb268d Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Wed, 8 Feb 2012 19:22:38 -0800 Subject: uhd: added sse2 conversions for fc64 to sc8 --- host/lib/convert/CMakeLists.txt | 3 +- host/lib/convert/convert_fc32_with_sse2.cpp | 8 +- host/lib/convert/convert_fc64_to_sc8_with_sse2.cpp | 156 +++++++++++++++++++++ host/lib/convert/convert_fc64_with_sse2.cpp | 8 +- host/tests/convert_test.cpp | 2 +- 5 files changed, 167 insertions(+), 10 deletions(-) create mode 100644 host/lib/convert/convert_fc64_to_sc8_with_sse2.cpp diff --git a/host/lib/convert/CMakeLists.txt b/host/lib/convert/CMakeLists.txt index 98907dc29..a2a61cb9a 100644 --- a/host/lib/convert/CMakeLists.txt +++ b/host/lib/convert/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2011 Ettus Research LLC +# Copyright 2011-2012 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 @@ -73,6 +73,7 @@ IF(HAVE_EMMINTRIN_H) SET(convert_with_sse2_sources ${CMAKE_CURRENT_SOURCE_DIR}/convert_fc32_with_sse2.cpp ${CMAKE_CURRENT_SOURCE_DIR}/convert_fc64_with_sse2.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/convert_fc64_to_sc8_with_sse2.cpp ) SET_SOURCE_FILES_PROPERTIES( ${convert_with_sse2_sources} diff --git a/host/lib/convert/convert_fc32_with_sse2.cpp b/host/lib/convert/convert_fc32_with_sse2.cpp index 24a939d6c..97a3e8cdc 100644 --- a/host/lib/convert/convert_fc32_with_sse2.cpp +++ b/host/lib/convert/convert_fc32_with_sse2.cpp @@ -28,7 +28,7 @@ DECLARE_CONVERTER(fc32, 1, sc16_item32_le, 1, PRIORITY_SIMD){ const __m128 scalar = _mm_set_ps1(float(scale_factor)); #define convert_fc32_1_to_item32_1_nswap_guts(_al_) \ - for (; i+4 < nsamps; i+=4){ \ + for (; i+3 < nsamps; i+=4){ \ /* load from input */ \ __m128 tmplo = _mm_load ## _al_ ## ps(reinterpret_cast(input+i+0)); \ __m128 tmphi = _mm_load ## _al_ ## ps(reinterpret_cast(input+i+2)); \ @@ -71,7 +71,7 @@ DECLARE_CONVERTER(fc32, 1, sc16_item32_be, 1, PRIORITY_SIMD){ const __m128 scalar = _mm_set_ps1(float(scale_factor)); #define convert_fc32_1_to_item32_1_bswap_guts(_al_) \ - for (; i+4 < nsamps; i+=4){ \ + for (; i+3 < nsamps; i+=4){ \ /* load from input */ \ __m128 tmplo = _mm_load ## _al_ ## ps(reinterpret_cast(input+i+0)); \ __m128 tmphi = _mm_load ## _al_ ## ps(reinterpret_cast(input+i+2)); \ @@ -114,7 +114,7 @@ DECLARE_CONVERTER(sc16_item32_le, 1, fc32, 1, PRIORITY_SIMD){ const __m128i zeroi = _mm_setzero_si128(); #define convert_item32_1_to_fc32_1_nswap_guts(_al_) \ - for (; i+4 < nsamps; i+=4){ \ + for (; i+3 < nsamps; i+=4){ \ /* load from input */ \ __m128i tmpi = _mm_loadu_si128(reinterpret_cast(input+i)); \ \ @@ -159,7 +159,7 @@ DECLARE_CONVERTER(sc16_item32_be, 1, fc32, 1, PRIORITY_SIMD){ const __m128i zeroi = _mm_setzero_si128(); #define convert_item32_1_to_fc32_1_bswap_guts(_al_) \ - for (; i+4 < nsamps; i+=4){ \ + for (; i+3 < nsamps; i+=4){ \ /* load from input */ \ __m128i tmpi = _mm_loadu_si128(reinterpret_cast(input+i)); \ \ diff --git a/host/lib/convert/convert_fc64_to_sc8_with_sse2.cpp b/host/lib/convert/convert_fc64_to_sc8_with_sse2.cpp new file mode 100644 index 000000000..405850601 --- /dev/null +++ b/host/lib/convert/convert_fc64_to_sc8_with_sse2.cpp @@ -0,0 +1,156 @@ +// +// Copyright 2012 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 . +// + +#include "convert_common.hpp" +#include +#include + +using namespace uhd::convert; + +UHD_INLINE __m128i pack_sc8_item32_4x( + const __m128i &in0, const __m128i &in1, + const __m128i &in2, const __m128i &in3 +){ + const __m128i lo = _mm_packs_epi32(in0, in1); + const __m128i hi = _mm_packs_epi32(in2, in3); + return _mm_packs_epi16(lo, hi); +} + +UHD_INLINE __m128i pack_sc32_4x_be( + const __m128d &lo, const __m128d &hi, + const __m128d &scalar +){ + const __m128i tmpi_lo = _mm_cvttpd_epi32(_mm_mul_pd(hi, scalar)); + const __m128i tmpi_hi = _mm_cvttpd_epi32(_mm_mul_pd(lo, scalar)); + return _mm_unpacklo_epi64(tmpi_lo, tmpi_hi); +} + +UHD_INLINE __m128i pack_sc32_4x_le( + const __m128d &lo, const __m128d &hi, + const __m128d &scalar +){ + const __m128i tmpi_lo = _mm_cvttpd_epi32(_mm_mul_pd(lo, scalar)); + const __m128i tmpi_hi = _mm_cvttpd_epi32(_mm_mul_pd(hi, scalar)); + const __m128i tmpi = _mm_unpacklo_epi64(tmpi_lo, tmpi_hi); + return _mm_shuffle_epi32(tmpi, _MM_SHUFFLE(2, 3, 0, 1)); +} + +DECLARE_CONVERTER(fc64, 1, sc8_item32_be, 1, PRIORITY_SIMD){ + const fc64_t *input = reinterpret_cast(inputs[0]); + item32_t *output = reinterpret_cast(outputs[0]); + + const __m128d scalar = _mm_set1_pd(scale_factor); + + #define convert_fc64_1_to_sc8_item32_1_bswap_guts(_al_) \ + for (size_t j = 0; i+7 < nsamps; i+=8, j+=4){ \ + /* load from input */ \ + __m128d tmp0 = _mm_load ## _al_ ## pd(reinterpret_cast(input+i+0)); \ + __m128d tmp1 = _mm_load ## _al_ ## pd(reinterpret_cast(input+i+1)); \ + __m128d tmp2 = _mm_load ## _al_ ## pd(reinterpret_cast(input+i+2)); \ + __m128d tmp3 = _mm_load ## _al_ ## pd(reinterpret_cast(input+i+3)); \ + __m128d tmp4 = _mm_load ## _al_ ## pd(reinterpret_cast(input+i+4)); \ + __m128d tmp5 = _mm_load ## _al_ ## pd(reinterpret_cast(input+i+5)); \ + __m128d tmp6 = _mm_load ## _al_ ## pd(reinterpret_cast(input+i+6)); \ + __m128d tmp7 = _mm_load ## _al_ ## pd(reinterpret_cast(input+i+7)); \ + \ + /* interleave */ \ + const __m128i tmpi = pack_sc8_item32_4x( \ + pack_sc32_4x_be(tmp0, tmp1, scalar), \ + pack_sc32_4x_be(tmp2, tmp3, scalar), \ + pack_sc32_4x_be(tmp4, tmp5, scalar), \ + pack_sc32_4x_be(tmp6, tmp7, scalar) \ + ); \ + \ + /* store to output */ \ + _mm_storeu_si128(reinterpret_cast<__m128i *>(output+j), tmpi); \ + } \ + + size_t i = 0; + + //dispatch according to alignment + if ((size_t(input) & 0xf) == 0){ + convert_fc64_1_to_sc8_item32_1_bswap_guts(_) + } + else{ + convert_fc64_1_to_sc8_item32_1_bswap_guts(u_) + } + + //convert remainder + const size_t num_pairs = nsamps/2; + for (size_t j = i/2; j < num_pairs; j++, i+=2){ + const item32_t item = fc64_to_item32_sc8(input[i], input[i+1], scale_factor); + output[j] = uhd::byteswap(item); + } + + if (nsamps != num_pairs*2){ + const item32_t item = fc64_to_item32_sc8(input[nsamps-1], 0, scale_factor); + output[num_pairs] = uhd::byteswap(item); + } +} + +DECLARE_CONVERTER(fc64, 1, sc8_item32_le, 1, PRIORITY_SIMD){ + const fc64_t *input = reinterpret_cast(inputs[0]); + item32_t *output = reinterpret_cast(outputs[0]); + + const __m128d scalar = _mm_set1_pd(scale_factor); + + #define convert_fc64_1_to_sc8_item32_1_nswap_guts(_al_) \ + for (size_t j = 0; i+7 < nsamps; i+=8, j+=4){ \ + /* load from input */ \ + __m128d tmp0 = _mm_load ## _al_ ## pd(reinterpret_cast(input+i+0)); \ + __m128d tmp1 = _mm_load ## _al_ ## pd(reinterpret_cast(input+i+1)); \ + __m128d tmp2 = _mm_load ## _al_ ## pd(reinterpret_cast(input+i+2)); \ + __m128d tmp3 = _mm_load ## _al_ ## pd(reinterpret_cast(input+i+3)); \ + __m128d tmp4 = _mm_load ## _al_ ## pd(reinterpret_cast(input+i+4)); \ + __m128d tmp5 = _mm_load ## _al_ ## pd(reinterpret_cast(input+i+5)); \ + __m128d tmp6 = _mm_load ## _al_ ## pd(reinterpret_cast(input+i+6)); \ + __m128d tmp7 = _mm_load ## _al_ ## pd(reinterpret_cast(input+i+7)); \ + \ + /* interleave */ \ + const __m128i tmpi = pack_sc8_item32_4x( \ + pack_sc32_4x_le(tmp0, tmp1, scalar), \ + pack_sc32_4x_le(tmp2, tmp3, scalar), \ + pack_sc32_4x_le(tmp4, tmp5, scalar), \ + pack_sc32_4x_le(tmp6, tmp7, scalar) \ + ); \ + \ + /* store to output */ \ + _mm_storeu_si128(reinterpret_cast<__m128i *>(output+j), tmpi); \ + } \ + + size_t i = 0; + + //dispatch according to alignment + if ((size_t(input) & 0xf) == 0){ + convert_fc64_1_to_sc8_item32_1_nswap_guts(_) + } + else{ + convert_fc64_1_to_sc8_item32_1_nswap_guts(u_) + } + + //convert remainder + const size_t num_pairs = nsamps/2; + for (size_t j = i/2; j < num_pairs; j++, i+=2){ + const item32_t item = fc64_to_item32_sc8(input[i], input[i+1], scale_factor); + output[j] = (item); + } + + if (nsamps != num_pairs*2){ + const item32_t item = fc64_to_item32_sc8(input[nsamps-1], 0, scale_factor); + output[num_pairs] = (item); + } +} diff --git a/host/lib/convert/convert_fc64_with_sse2.cpp b/host/lib/convert/convert_fc64_with_sse2.cpp index 837bb584e..6e097e380 100644 --- a/host/lib/convert/convert_fc64_with_sse2.cpp +++ b/host/lib/convert/convert_fc64_with_sse2.cpp @@ -28,7 +28,7 @@ DECLARE_CONVERTER(fc64, 1, sc16_item32_le, 1, PRIORITY_SIMD){ const __m128d scalar = _mm_set1_pd(scale_factor); #define convert_fc64_1_to_item32_1_nswap_guts(_al_) \ - for (; i+4 < nsamps; i+=4){ \ + for (; i+3 < nsamps; i+=4){ \ /* load from input */ \ __m128d tmp0 = _mm_load ## _al_ ## pd(reinterpret_cast(input+i+0)); \ __m128d tmp1 = _mm_load ## _al_ ## pd(reinterpret_cast(input+i+1)); \ @@ -75,7 +75,7 @@ DECLARE_CONVERTER(fc64, 1, sc16_item32_be, 1, PRIORITY_SIMD){ const __m128d scalar = _mm_set1_pd(scale_factor); #define convert_fc64_1_to_item32_1_bswap_guts(_al_) \ - for (; i+4 < nsamps; i+=4){ \ + for (; i+3 < nsamps; i+=4){ \ /* load from input */ \ __m128d tmp0 = _mm_load ## _al_ ## pd(reinterpret_cast(input+i+0)); \ __m128d tmp1 = _mm_load ## _al_ ## pd(reinterpret_cast(input+i+1)); \ @@ -122,7 +122,7 @@ DECLARE_CONVERTER(sc16_item32_le, 1, fc64, 1, PRIORITY_SIMD){ const __m128i zeroi = _mm_setzero_si128(); #define convert_item32_1_to_fc64_1_nswap_guts(_al_) \ - for (; i+4 < nsamps; i+=4){ \ + for (; i+3 < nsamps; i+=4){ \ /* load from input */ \ __m128i tmpi = _mm_loadu_si128(reinterpret_cast(input+i)); \ \ @@ -171,7 +171,7 @@ DECLARE_CONVERTER(sc16_item32_be, 1, fc64, 1, PRIORITY_SIMD){ const __m128i zeroi = _mm_setzero_si128(); #define convert_item32_1_to_fc64_1_bswap_guts(_al_) \ - for (; i+4 < nsamps; i+=4){ \ + for (; i+3 < nsamps; i+=4){ \ /* load from input */ \ __m128i tmpi = _mm_loadu_si128(reinterpret_cast(input+i)); \ \ diff --git a/host/tests/convert_test.cpp b/host/tests/convert_test.cpp index 0ce4ebacb..d82014d3f 100644 --- a/host/tests/convert_test.cpp +++ b/host/tests/convert_test.cpp @@ -32,7 +32,7 @@ typedef std::complex fc32_t; typedef std::complex fc64_t; #define MY_CHECK_CLOSE(a, b, f) { \ - BOOST_CHECK_MESSAGE(std::abs((a)-(b)) < f, " " << #a << " (" << (a) << ") error " << #b << " (" << (b) << ")"); \ + BOOST_CHECK_MESSAGE(std::abs((a)-(b)) < f, "\n\t" << #a << " (" << (a) << ") error " << #b << " (" << (b) << ")"); \ } /*********************************************************************** -- cgit v1.2.3 From cfba2388ce71121bbadbf0366dbf95f726e78748 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Wed, 8 Feb 2012 23:01:46 -0800 Subject: uhd: added sse2 conversions for fc32 to sc8 --- host/lib/convert/CMakeLists.txt | 1 + host/lib/convert/convert_fc32_to_sc8_with_sse2.cpp | 150 +++++++++++++++++++++ 2 files changed, 151 insertions(+) create mode 100644 host/lib/convert/convert_fc32_to_sc8_with_sse2.cpp diff --git a/host/lib/convert/CMakeLists.txt b/host/lib/convert/CMakeLists.txt index a2a61cb9a..c42a0a434 100644 --- a/host/lib/convert/CMakeLists.txt +++ b/host/lib/convert/CMakeLists.txt @@ -73,6 +73,7 @@ IF(HAVE_EMMINTRIN_H) SET(convert_with_sse2_sources ${CMAKE_CURRENT_SOURCE_DIR}/convert_fc32_with_sse2.cpp ${CMAKE_CURRENT_SOURCE_DIR}/convert_fc64_with_sse2.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/convert_fc32_to_sc8_with_sse2.cpp ${CMAKE_CURRENT_SOURCE_DIR}/convert_fc64_to_sc8_with_sse2.cpp ) SET_SOURCE_FILES_PROPERTIES( diff --git a/host/lib/convert/convert_fc32_to_sc8_with_sse2.cpp b/host/lib/convert/convert_fc32_to_sc8_with_sse2.cpp new file mode 100644 index 000000000..b8545bad0 --- /dev/null +++ b/host/lib/convert/convert_fc32_to_sc8_with_sse2.cpp @@ -0,0 +1,150 @@ +// +// Copyright 2012 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 . +// + +#include "convert_common.hpp" +#include +#include + +using namespace uhd::convert; + +UHD_INLINE __m128i pack_sc32_4x_be( + const __m128 &in0, const __m128 &in1, + const __m128 &in2, const __m128 &in3, + const __m128 &scalar +){ + __m128i tmpi0 = _mm_cvtps_epi32(_mm_mul_ps(in0, scalar)); + tmpi0 = _mm_shuffle_epi32(tmpi0, _MM_SHUFFLE(1, 0, 3, 2)); + __m128i tmpi1 = _mm_cvtps_epi32(_mm_mul_ps(in1, scalar)); + tmpi1 = _mm_shuffle_epi32(tmpi1, _MM_SHUFFLE(1, 0, 3, 2)); + const __m128i lo = _mm_packs_epi32(tmpi0, tmpi1); + + __m128i tmpi2 = _mm_cvtps_epi32(_mm_mul_ps(in2, scalar)); + tmpi2 = _mm_shuffle_epi32(tmpi2, _MM_SHUFFLE(1, 0, 3, 2)); + __m128i tmpi3 = _mm_cvtps_epi32(_mm_mul_ps(in3, scalar)); + tmpi3 = _mm_shuffle_epi32(tmpi3, _MM_SHUFFLE(1, 0, 3, 2)); + const __m128i hi = _mm_packs_epi32(tmpi2, tmpi3); + + return _mm_packs_epi16(lo, hi); +} + +UHD_INLINE __m128i pack_sc32_4x_le( + const __m128 &in0, const __m128 &in1, + const __m128 &in2, const __m128 &in3, + const __m128 &scalar +){ + __m128i tmpi0 = _mm_cvtps_epi32(_mm_mul_ps(in0, scalar)); + tmpi0 = _mm_shuffle_epi32(tmpi0, _MM_SHUFFLE(2, 3, 0, 1)); + __m128i tmpi1 = _mm_cvtps_epi32(_mm_mul_ps(in1, scalar)); + tmpi1 = _mm_shuffle_epi32(tmpi1, _MM_SHUFFLE(2, 3, 0, 1)); + const __m128i lo = _mm_packs_epi32(tmpi0, tmpi1); + + __m128i tmpi2 = _mm_cvtps_epi32(_mm_mul_ps(in2, scalar)); + tmpi2 = _mm_shuffle_epi32(tmpi2, _MM_SHUFFLE(2, 3, 0, 1)); + __m128i tmpi3 = _mm_cvtps_epi32(_mm_mul_ps(in3, scalar)); + tmpi3 = _mm_shuffle_epi32(tmpi3, _MM_SHUFFLE(2, 3, 0, 1)); + const __m128i hi = _mm_packs_epi32(tmpi2, tmpi3); + + return _mm_packs_epi16(lo, hi); +} + +DECLARE_CONVERTER(fc32, 1, sc8_item32_be, 1, PRIORITY_SIMD){ + const fc32_t *input = reinterpret_cast(inputs[0]); + item32_t *output = reinterpret_cast(outputs[0]); + + const __m128 scalar = _mm_set_ps1(float(scale_factor)); + + #define convert_fc32_1_to_sc8_item32_1_bswap_guts(_al_) \ + for (size_t j = 0; i+7 < nsamps; i+=8, j+=2){ \ + /* load from input */ \ + __m128 tmp0 = _mm_load ## _al_ ## ps(reinterpret_cast(input+i+0)); \ + __m128 tmp1 = _mm_load ## _al_ ## ps(reinterpret_cast(input+i+2)); \ + __m128 tmp2 = _mm_load ## _al_ ## ps(reinterpret_cast(input+i+4)); \ + __m128 tmp3 = _mm_load ## _al_ ## ps(reinterpret_cast(input+i+6)); \ + \ + /* convert */ \ + const __m128i tmpi = pack_sc32_4x_be(tmp0, tmp1, tmp2, tmp3, scalar); \ + \ + /* store to output */ \ + _mm_storeu_si128(reinterpret_cast<__m128i *>(output+j), tmpi); \ + } \ + + size_t i = 0; + + //dispatch according to alignment + if ((size_t(input) & 0xf) == 0){ + convert_fc32_1_to_sc8_item32_1_bswap_guts(_) + } + else{ + convert_fc32_1_to_sc8_item32_1_bswap_guts(u_) + } + + //convert remainder + const size_t num_pairs = nsamps/2; + for (size_t j = i/2; j < num_pairs; j++, i+=2){ + const item32_t item = fc32_to_item32_sc8(input[i], input[i+1], scale_factor); + output[j] = uhd::byteswap(item); + } + + if (nsamps != num_pairs*2){ + const item32_t item = fc32_to_item32_sc8(input[nsamps-1], 0, scale_factor); + output[num_pairs] = uhd::byteswap(item); + } +} + +DECLARE_CONVERTER(fc32, 1, sc8_item32_le, 1, PRIORITY_SIMD){ + const fc32_t *input = reinterpret_cast(inputs[0]); + item32_t *output = reinterpret_cast(outputs[0]); + + const __m128 scalar = _mm_set_ps1(float(scale_factor)); + + #define convert_fc32_1_to_sc8_item32_1_nswap_guts(_al_) \ + for (size_t j = 0; i+7 < nsamps; i+=8, j+=2){ \ + /* load from input */ \ + __m128 tmp0 = _mm_load ## _al_ ## ps(reinterpret_cast(input+i+0)); \ + __m128 tmp1 = _mm_load ## _al_ ## ps(reinterpret_cast(input+i+2)); \ + __m128 tmp2 = _mm_load ## _al_ ## ps(reinterpret_cast(input+i+4)); \ + __m128 tmp3 = _mm_load ## _al_ ## ps(reinterpret_cast(input+i+6)); \ + \ + /* convert */ \ + const __m128i tmpi = pack_sc32_4x_le(tmp0, tmp1, tmp2, tmp3, scalar); \ + \ + /* store to output */ \ + _mm_storeu_si128(reinterpret_cast<__m128i *>(output+j), tmpi); \ + } \ + + size_t i = 0; + + //dispatch according to alignment + if ((size_t(input) & 0xf) == 0){ + convert_fc32_1_to_sc8_item32_1_nswap_guts(_) + } + else{ + convert_fc32_1_to_sc8_item32_1_nswap_guts(u_) + } + + //convert remainder + const size_t num_pairs = nsamps/2; + for (size_t j = i/2; j < num_pairs; j++, i+=2){ + const item32_t item = fc32_to_item32_sc8(input[i], input[i+1], scale_factor); + output[j] = (item); + } + + if (nsamps != num_pairs*2){ + const item32_t item = fc32_to_item32_sc8(input[nsamps-1], 0, scale_factor); + output[num_pairs] = (item); + } +} -- cgit v1.2.3 From 10a4d951a1548a99cfd7ac8c015e0bb18ce5e343 Mon Sep 17 00:00:00 2001 From: Nick Foster Date: Thu, 9 Feb 2012 10:53:39 -0800 Subject: B100: Firmware reset tweaks. --- firmware/fx2/b100/usrp_common.c | 46 +++++++++++++++++++++++----------------- firmware/fx2/b100/usrp_main.c | 30 ++------------------------ host/lib/usrp/b100/b100_impl.cpp | 2 +- 3 files changed, 30 insertions(+), 48 deletions(-) diff --git a/firmware/fx2/b100/usrp_common.c b/firmware/fx2/b100/usrp_common.c index a8f29d1fa..a21353688 100644 --- a/firmware/fx2/b100/usrp_common.c +++ b/firmware/fx2/b100/usrp_common.c @@ -32,12 +32,11 @@ init_usrp (void) CPUCS = bmCLKSPD1; // CPU runs @ 48 MHz CKCON = 0; // MOVX takes 2 cycles - // IFCLK is generated internally and runs at 48 MHz; slave FIFO mode + // IFCLK is generated internally and runs at 48 MHz, external clk en IFCONFIG = bmIFCLKSRC | bm3048MHZ | bmIFCLKOE; SYNCDELAY; // configure IO ports (B and D are used by slave FIFO) - IOA = bmPORT_A_INITIAL; // Port A initial state OEA = bmPORT_A_OUTPUTS; // Port A direction register @@ -52,7 +51,6 @@ init_usrp (void) // SYNCDELAY; // configure end points - EP1OUTCFG = bmVALID | bmBULK; SYNCDELAY; EP1INCFG = bmVALID | bmBULK | bmIN; SYNCDELAY; @@ -62,7 +60,6 @@ init_usrp (void) EP8CFG = bmVALID | bmBULK | bmDOUBLEBUF | bmIN; SYNCDELAY; // 512 dbl bulk IN // reset FIFOs - FIFORESET = bmNAKALL; SYNCDELAY; FIFORESET = 2; SYNCDELAY; FIFORESET = 4; SYNCDELAY; @@ -71,39 +68,50 @@ init_usrp (void) FIFORESET = 0; SYNCDELAY; // configure end point FIFOs - - // let core see 0 to 1 transistion of autoout bit - + // let core see 0 to 1 transistion of autoin/out bit EP2FIFOCFG = bmWORDWIDE; SYNCDELAY; EP2FIFOCFG = bmAUTOOUT | bmWORDWIDE; SYNCDELAY; EP6FIFOCFG = bmZEROLENIN | bmWORDWIDE; SYNCDELAY; EP6FIFOCFG = bmZEROLENIN | bmAUTOIN | bmWORDWIDE; SYNCDELAY; - //EP6FIFOCFG = bmWORDWIDE; SYNCDELAY; EP4FIFOCFG = bmWORDWIDE; SYNCDELAY; EP4FIFOCFG = bmAUTOOUT | bmWORDWIDE; SYNCDELAY; EP8FIFOCFG = bmZEROLENIN | bmWORDWIDE; SYNCDELAY; EP8FIFOCFG = bmZEROLENIN | bmAUTOIN | bmWORDWIDE; SYNCDELAY; EP0BCH = 0; SYNCDELAY; - // arm EP1OUT so we can receive "out" packets (TRM pg 8-8) - EP1OUTBC = 0; SYNCDELAY; -/* - EP2GPIFFLGSEL = 0x00; SYNCDELAY; // For EP2OUT, GPIF uses EF flag - EP6GPIFFLGSEL = 0x00; SYNCDELAY; // For EP6IN, GPIF uses FF flag - EP4GPIFFLGSEL = 0x00; SYNCDELAY; - EP8GPIFFLGSEL = 0x00; SYNCDELAY; -*/ - // set autoin length for EP6 - // FIXME should be f(enumeration) + // set autoin length for EP6/EP8 EP6AUTOINLENH = (512) >> 8; SYNCDELAY; // this is the length for high speed EP6AUTOINLENL = (512) & 0xff; SYNCDELAY; - EP8AUTOINLENH = (32) >> 8; SYNCDELAY; EP8AUTOINLENL = (32) & 0xff; SYNCDELAY; + //set FLAGA, FLAGB, FLAGC, FLAGD to be EP2EF, EP4EF, EP6PF, EP8PF + PINFLAGSAB = (bmEP2EF) | (bmEP4EF << 4); + PINFLAGSCD = (bmEP6PF) | (bmEP8PF << 4); + + //ok as far as i can tell, DECIS is reversed compared to the FX2 TRM. + //p15.34 says DECIS high implements [assert when (fill > level)], observed opposite + EP6FIFOPFH = 0x09; + SYNCDELAY; + EP6FIFOPFL = 0xFD; + SYNCDELAY; + +// EP2FIFOPFH = 0x08; +// SYNCDELAY; +// EP2FIFOPFL = 0x00; +// SYNCDELAY; + + //assert FIFOEMPTY one cycle sooner so we get it in time at the FPGA + EP2FIFOCFG |= bmBIT5; + + //set FIFOPINPOLAR to normal (active low) mode + FIFOPINPOLAR = 0x00; + SYNCDELAY; + PORTACFG = 0x80; + init_board (); } diff --git a/firmware/fx2/b100/usrp_main.c b/firmware/fx2/b100/usrp_main.c index d9e09ca34..7c4dd479d 100644 --- a/firmware/fx2/b100/usrp_main.c +++ b/firmware/fx2/b100/usrp_main.c @@ -79,8 +79,7 @@ get_ep0_data (void) ; } -static void initialize_gpif_buffer(int ep) { - //clear the GPIF buffers on startup to keep crap out of the data path +static void clear_fifo(int ep) { FIFORESET = 0x80; SYNCDELAY; //activate NAKALL FIFORESET = ep; SYNCDELAY; FIFORESET = 0x00; SYNCDELAY; @@ -184,7 +183,7 @@ app_vendor_cmd (void) break; case VRQ_RESET_GPIF: - initialize_gpif_buffer(wValueL); + clear_fifo(wValueL); break; case VRQ_ENABLE_GPIF: @@ -282,30 +281,5 @@ main (void) fx2_renumerate (); // simulates disconnect / reconnect - //set FLAGA, FLAGB, FLAGC, FLAGD to be EP2EF, EP4EF, EP6PF, EP8PF - PINFLAGSAB = (bmEP2EF) | (bmEP4EF << 4); - PINFLAGSCD = (bmEP6PF) | (bmEP8PF << 4); - - //ok as far as i can tell, DECIS is reversed compared to the FX2 TRM. - //p15.34 says DECIS high implements [assert when (fill > level)], observed opposite - - EP6FIFOPFH = 0x09; - SYNCDELAY; - EP6FIFOPFL = 0xFD; - SYNCDELAY; - -// EP2FIFOPFH = 0x08; -// SYNCDELAY; -// EP2FIFOPFL = 0x00; -// SYNCDELAY; - - //assert FIFOEMPTY one cycle sooner so we get it in time at the FPGA - EP2FIFOCFG |= bmBIT5; - - //set FIFOPINPOLAR to normal (active low) mode - FIFOPINPOLAR = 0x00; - SYNCDELAY; - PORTACFG = 0x80; - main_loop (); } diff --git a/host/lib/usrp/b100/b100_impl.cpp b/host/lib/usrp/b100/b100_impl.cpp index ce0b9453b..4c9f93249 100644 --- a/host/lib/usrp/b100/b100_impl.cpp +++ b/host/lib/usrp/b100/b100_impl.cpp @@ -181,9 +181,9 @@ b100_impl::b100_impl(const device_addr_t &device_addr){ //load FPGA image, gpif is disabled while loading this->enable_gpif(false); _fx2_ctrl->usrp_load_fpga(b100_fpga_image); + this->enable_gpif(true); this->set_reset_fpga(1); this->set_reset_fpga(0); - this->enable_gpif(true); //create the control transport device_addr_t ctrl_xport_args; -- cgit v1.2.3 From 4044a9eeb6fb195b8e64cd1879b0d40973dc27cb Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Thu, 9 Feb 2012 16:54:08 -0800 Subject: uhd: fixed orc conversion fc32 to sc8_item32_be --- host/lib/convert/convert_with_orc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/host/lib/convert/convert_with_orc.cpp b/host/lib/convert/convert_with_orc.cpp index 630554564..e44c8ca73 100644 --- a/host/lib/convert/convert_with_orc.cpp +++ b/host/lib/convert/convert_with_orc.cpp @@ -57,7 +57,7 @@ DECLARE_CONVERTER(sc16_item32_le, 1, sc16, 1, PRIORITY_LIBORC){ DECLARE_CONVERTER(fc32, 1, sc8_item32_be, 1, PRIORITY_LIBORC){ _convert_fc32_1_to_sc8_1_nswap_orc(outputs[0], inputs[0], scale_factor, nsamps); - _convert_swap_byte_pairs_orc(outputs[0], outputs[0], nsamps); + _convert_swap_byte_pairs_orc(outputs[0], outputs[0], (nsamps + 1)/2); } DECLARE_CONVERTER(fc32, 1, sc8_item32_le, 1, PRIORITY_LIBORC){ -- cgit v1.2.3 From b6da2fe9af84663fa4dda923833e2319433b6f20 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Thu, 9 Feb 2012 17:06:37 -0800 Subject: uhd: fixed sse2 conversion fc32 to sc8_item32_be --- host/lib/convert/convert_fc32_to_sc8_with_sse2.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/host/lib/convert/convert_fc32_to_sc8_with_sse2.cpp b/host/lib/convert/convert_fc32_to_sc8_with_sse2.cpp index b8545bad0..b633f487c 100644 --- a/host/lib/convert/convert_fc32_to_sc8_with_sse2.cpp +++ b/host/lib/convert/convert_fc32_to_sc8_with_sse2.cpp @@ -68,7 +68,7 @@ DECLARE_CONVERTER(fc32, 1, sc8_item32_be, 1, PRIORITY_SIMD){ const __m128 scalar = _mm_set_ps1(float(scale_factor)); #define convert_fc32_1_to_sc8_item32_1_bswap_guts(_al_) \ - for (size_t j = 0; i+7 < nsamps; i+=8, j+=2){ \ + for (size_t j = 0; i+7 < nsamps; i+=8, j+=4){ \ /* load from input */ \ __m128 tmp0 = _mm_load ## _al_ ## ps(reinterpret_cast(input+i+0)); \ __m128 tmp1 = _mm_load ## _al_ ## ps(reinterpret_cast(input+i+2)); \ @@ -112,7 +112,7 @@ DECLARE_CONVERTER(fc32, 1, sc8_item32_le, 1, PRIORITY_SIMD){ const __m128 scalar = _mm_set_ps1(float(scale_factor)); #define convert_fc32_1_to_sc8_item32_1_nswap_guts(_al_) \ - for (size_t j = 0; i+7 < nsamps; i+=8, j+=2){ \ + for (size_t j = 0; i+7 < nsamps; i+=8, j+=4){ \ /* load from input */ \ __m128 tmp0 = _mm_load ## _al_ ## ps(reinterpret_cast(input+i+0)); \ __m128 tmp1 = _mm_load ## _al_ ## ps(reinterpret_cast(input+i+2)); \ -- cgit v1.2.3 From 115100034071b3b58de1fce7c795995f6ee615a1 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Thu, 9 Feb 2012 17:59:48 -0800 Subject: uhd: various tweaks for compiler warns and valgrind --- host/examples/test_messages.cpp | 3 ++- host/lib/types/time_spec.cpp | 14 +++++++++----- host/lib/usrp/b100/io_impl.cpp | 2 +- host/lib/usrp/cores/rx_dsp_core_200.cpp | 2 +- host/lib/usrp/e100/io_impl.cpp | 2 +- host/lib/usrp/usrp1/soft_time_ctrl.cpp | 4 ++-- host/lib/usrp/usrp2/io_impl.cpp | 3 ++- host/lib/usrp/usrp2/usrp2_iface.cpp | 13 ++++++++----- host/tests/convert_test.cpp | 4 ++-- 9 files changed, 28 insertions(+), 19 deletions(-) diff --git a/host/examples/test_messages.cpp b/host/examples/test_messages.cpp index f24a172d1..afb092092 100644 --- a/host/examples/test_messages.cpp +++ b/host/examples/test_messages.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -326,7 +327,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ } //run the tests, pick at random - std::srand(uhd::time_spec_t::get_system_time().get_full_secs()); + std::srand((unsigned int) time(NULL)); for (size_t n = 0; n < ntests; n++){ std::string key = tests.keys()[std::rand() % tests.size()]; bool pass = tests[key](usrp, rx_stream, tx_stream); diff --git a/host/lib/types/time_spec.cpp b/host/lib/types/time_spec.cpp index 176ee8079..0c3a3dbea 100644 --- a/host/lib/types/time_spec.cpp +++ b/host/lib/types/time_spec.cpp @@ -38,7 +38,7 @@ time_spec_t time_spec_t::get_system_time(void){ time_spec_t time_spec_t::get_system_time(void){ mach_timebase_info_data_t info; mach_timebase_info(&info); intmax_t nanosecs = mach_absolute_time()*info.numer/info.denom; - return time_spec_t::from_ticks(nanosecs, intmax_t(1e9)); + return time_spec_t::from_ticks(nanosecs, 1e9); } #endif /* HAVE_MACH_ABSOLUTE_TIME */ @@ -80,6 +80,10 @@ time_spec_t time_spec_t::get_system_time(void){ } \ } +UHD_INLINE long long fast_llround(const double x){ + return (long long)(x + 0.5); // assumption of non-negativity +} + time_spec_t::time_spec_t(double secs){ time_spec_init(0, secs); } @@ -94,7 +98,7 @@ time_spec_t::time_spec_t(time_t full_secs, long tick_count, double tick_rate){ } time_spec_t time_spec_t::from_ticks(long long ticks, double tick_rate){ - const imaxdiv_t divres = imaxdiv(ticks, tick_rate); + const imaxdiv_t divres = imaxdiv(ticks, fast_llround(tick_rate)); return time_spec_t(time_t(divres.quot), double(divres.rem)/tick_rate); } @@ -102,12 +106,12 @@ time_spec_t time_spec_t::from_ticks(long long ticks, double tick_rate){ * Time spec accessors **********************************************************************/ long time_spec_t::get_tick_count(double tick_rate) const{ - return long(this->get_frac_secs()*tick_rate + 0.5); + return long(fast_llround(this->get_frac_secs()*tick_rate)); } long long time_spec_t::to_ticks(double tick_rate) const{ - return (long long)(this->get_frac_secs()*tick_rate + 0.5) + \ - (long long)((this->get_full_secs()) * (long long)(tick_rate)); + return fast_llround(this->get_frac_secs()*tick_rate) + \ + (this->get_full_secs() * fast_llround(tick_rate)); } double time_spec_t::get_real_secs(void) const{ diff --git a/host/lib/usrp/b100/io_impl.cpp b/host/lib/usrp/b100/io_impl.cpp index bd60e75cf..d7effcac1 100644 --- a/host/lib/usrp/b100/io_impl.cpp +++ b/host/lib/usrp/b100/io_impl.cpp @@ -41,7 +41,7 @@ using namespace uhd::transport; **********************************************************************/ struct b100_impl::io_impl{ io_impl(void): - async_msg_fifo(100/*messages deep*/) + async_msg_fifo(1000/*messages deep*/) { /* NOP */ } zero_copy_if::sptr data_transport; diff --git a/host/lib/usrp/cores/rx_dsp_core_200.cpp b/host/lib/usrp/cores/rx_dsp_core_200.cpp index ea0384dbe..cebf92f6a 100644 --- a/host/lib/usrp/cores/rx_dsp_core_200.cpp +++ b/host/lib/usrp/cores/rx_dsp_core_200.cpp @@ -121,7 +121,7 @@ public: //issue the stream command _iface->poke32(REG_RX_CTRL_STREAM_CMD, cmd_word); - const boost::uint64_t ticks = stream_cmd.time_spec.to_ticks(_tick_rate); + const boost::uint64_t ticks = (stream_cmd.stream_now)? 0 : stream_cmd.time_spec.to_ticks(_tick_rate); _iface->poke32(REG_RX_CTRL_TIME_HI, boost::uint32_t(ticks >> 32)); _iface->poke32(REG_RX_CTRL_TIME_LO, boost::uint32_t(ticks >> 0)); //latches the command } diff --git a/host/lib/usrp/e100/io_impl.cpp b/host/lib/usrp/e100/io_impl.cpp index f8e15f3fd..b090e45c7 100644 --- a/host/lib/usrp/e100/io_impl.cpp +++ b/host/lib/usrp/e100/io_impl.cpp @@ -50,7 +50,7 @@ using namespace uhd::transport; **********************************************************************/ struct e100_impl::io_impl{ io_impl(void): - false_alarm(0), async_msg_fifo(100/*messages deep*/) + false_alarm(0), async_msg_fifo(1000/*messages deep*/) { /* NOP */ } double tick_rate; //set by update tick rate method diff --git a/host/lib/usrp/usrp1/soft_time_ctrl.cpp b/host/lib/usrp/usrp1/soft_time_ctrl.cpp index b8af8af06..90b3a92da 100644 --- a/host/lib/usrp/usrp1/soft_time_ctrl.cpp +++ b/host/lib/usrp/usrp1/soft_time_ctrl.cpp @@ -39,8 +39,8 @@ public: _nsamps_remaining(0), _stream_mode(stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS), _cmd_queue(2), - _async_msg_queue(100), - _inline_msg_queue(100), + _async_msg_queue(1000), + _inline_msg_queue(1000), _stream_on_off(stream_on_off) { //synchronously spawn a new thread diff --git a/host/lib/usrp/usrp2/io_impl.cpp b/host/lib/usrp/usrp2/io_impl.cpp index f0c159f16..221b747cb 100644 --- a/host/lib/usrp/usrp2/io_impl.cpp +++ b/host/lib/usrp/usrp2/io_impl.cpp @@ -135,7 +135,8 @@ private: struct usrp2_impl::io_impl{ io_impl(void): - async_msg_fifo(100/*messages deep*/) + async_msg_fifo(1000/*messages deep*/), + tick_rate(1 /*non-zero default*/) { /* NOP */ } diff --git a/host/lib/usrp/usrp2/usrp2_iface.cpp b/host/lib/usrp/usrp2/usrp2_iface.cpp index f3d474a2d..eeba6756e 100644 --- a/host/lib/usrp/usrp2/usrp2_iface.cpp +++ b/host/lib/usrp/usrp2/usrp2_iface.cpp @@ -87,7 +87,7 @@ public: //Obtain the firmware's compat number. //Save the response compat number for communication. //TODO can choose to reject certain older compat numbers - usrp2_ctrl_data_t ctrl_data; + usrp2_ctrl_data_t ctrl_data = usrp2_ctrl_data_t(); ctrl_data.id = htonl(USRP2_CTRL_ID_WAZZUP_BRO); ctrl_data = ctrl_send_and_recv(ctrl_data, 0, ~0); if (ntohl(ctrl_data.id) != USRP2_CTRL_ID_WAZZUP_DUDE) @@ -126,10 +126,9 @@ public: bool is_device_locked(void){ boost::uint32_t lock_secs = this->get_reg(U2_FW_REG_LOCK_TIME); boost::uint32_t lock_gpid = this->get_reg(U2_FW_REG_LOCK_GPID); - boost::uint32_t curr_secs = this->peek32(U2_REG_TIME64_LO_RB_IMM)/100e6; //if the difference is larger, assume not locked anymore - if (curr_secs - lock_secs >= 3) return false; + if (this->get_curr_secs() - lock_secs >= 3) return false; //otherwise only lock if the device hash is different that ours return lock_gpid != boost::uint32_t(get_gpid()); @@ -137,12 +136,16 @@ public: void lock_task(void){ //re-lock in task - boost::uint32_t curr_secs = this->peek32(U2_REG_TIME64_LO_RB_IMM)/100e6; - this->get_reg(U2_FW_REG_LOCK_TIME, curr_secs); + this->get_reg(U2_FW_REG_LOCK_TIME, this->get_curr_secs()); //sleep for a bit boost::this_thread::sleep(boost::posix_time::milliseconds(1500)); } + boost::uint32_t get_curr_secs(void){ + //may not be the right tick rate, but this is ok for locking purposes + return boost::uint32_t(this->peek32(U2_REG_TIME64_LO_RB_IMM)/100e6); + } + /*********************************************************************** * Peek and Poke **********************************************************************/ diff --git a/host/tests/convert_test.cpp b/host/tests/convert_test.cpp index d82014d3f..6b0ae53a9 100644 --- a/host/tests/convert_test.cpp +++ b/host/tests/convert_test.cpp @@ -124,8 +124,8 @@ static void test_convert_types_for_floats( //fill the input samples std::vector input(nsamps), output(nsamps); BOOST_FOREACH(data_type &in, input) in = data_type( - ((std::rand()/value_type(RAND_MAX/2)) - 1)*extra_scale, - ((std::rand()/value_type(RAND_MAX/2)) - 1)*extra_scale + ((std::rand()/value_type(RAND_MAX/2)) - 1)*float(extra_scale), + ((std::rand()/value_type(RAND_MAX/2)) - 1)*float(extra_scale) ); //run the loopback and test -- cgit v1.2.3 From 8442ea5e2cfec89db6e58736a969da2842734631 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Thu, 9 Feb 2012 19:02:43 -0800 Subject: b100/usrp1: various tweaks for compiler warns and valgrind --- host/lib/usrp/b100/b100_ctrl.cpp | 4 ++-- host/lib/usrp/common/fx2_ctrl.cpp | 4 ++-- host/lib/usrp/usrp1/io_impl.cpp | 10 +++++----- host/lib/usrp/usrp1/usrp1_impl.cpp | 1 + 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/host/lib/usrp/b100/b100_ctrl.cpp b/host/lib/usrp/b100/b100_ctrl.cpp index 7d40daa32..e6136c00e 100644 --- a/host/lib/usrp/b100/b100_ctrl.cpp +++ b/host/lib/usrp/b100/b100_ctrl.cpp @@ -165,7 +165,7 @@ int b100_ctrl_impl::write(boost::uint32_t addr, const ctrl_data_t &data) { pkt.pkt_meta.seq = _seq++; pkt.pkt_meta.len = pkt.data.size(); pkt.pkt_meta.addr = addr; - boost::uint16_t pkt_buff[CTRL_PACKET_LENGTH / sizeof(boost::uint16_t)]; + boost::uint16_t pkt_buff[CTRL_PACKET_LENGTH / sizeof(boost::uint16_t)] = {}; pack_ctrl_pkt(pkt_buff, pkt); size_t result = send_pkt(pkt_buff); @@ -181,7 +181,7 @@ ctrl_data_t b100_ctrl_impl::read(boost::uint32_t addr, size_t len) { pkt.pkt_meta.seq = _seq++; pkt.pkt_meta.len = len; pkt.pkt_meta.addr = addr; - boost::uint16_t pkt_buff[CTRL_PACKET_LENGTH / sizeof(boost::uint16_t)]; + boost::uint16_t pkt_buff[CTRL_PACKET_LENGTH / sizeof(boost::uint16_t)] = {}; //flush anything that might be in the queue while (get_ctrl_data(pkt.data, 0.0)){ diff --git a/host/lib/usrp/common/fx2_ctrl.cpp b/host/lib/usrp/common/fx2_ctrl.cpp index 3c6df7079..baf8f5e68 100644 --- a/host/lib/usrp/common/fx2_ctrl.cpp +++ b/host/lib/usrp/common/fx2_ctrl.cpp @@ -419,7 +419,7 @@ public: { UHD_ASSERT_THROW(bytes.size() < max_i2c_data_bytes); - unsigned char buff[max_i2c_data_bytes]; + unsigned char buff[max_i2c_data_bytes] = {}; std::copy(bytes.begin(), bytes.end(), buff); int ret = this->usrp_i2c_write(addr & 0xff, @@ -434,7 +434,7 @@ public: { UHD_ASSERT_THROW(num_bytes < max_i2c_data_bytes); - unsigned char buff[max_i2c_data_bytes]; + unsigned char buff[max_i2c_data_bytes] = {}; int ret = this->usrp_i2c_read(addr & 0xff, buff, num_bytes); diff --git a/host/lib/usrp/usrp1/io_impl.cpp b/host/lib/usrp/usrp1/io_impl.cpp index f3cad188a..f27135562 100644 --- a/host/lib/usrp/usrp1/io_impl.cpp +++ b/host/lib/usrp/usrp1/io_impl.cpp @@ -221,17 +221,17 @@ void usrp1_impl::io_init(void){ _io_impl = UHD_PIMPL_MAKE(io_impl, (_data_transport)); - //create a new vandal thread to poll xerflow conditions - _io_impl->vandal_task = task::make(boost::bind( - &usrp1_impl::vandal_conquest_loop, this - )); - //init as disabled, then call the real function (uses restore) this->enable_rx(false); this->enable_tx(false); rx_stream_on_off(false); tx_stream_on_off(false); _io_impl->flush_send_buff(); + + //create a new vandal thread to poll xerflow conditions + _io_impl->vandal_task = task::make(boost::bind( + &usrp1_impl::vandal_conquest_loop, this + )); } void usrp1_impl::rx_stream_on_off(bool enb){ diff --git a/host/lib/usrp/usrp1/usrp1_impl.cpp b/host/lib/usrp/usrp1/usrp1_impl.cpp index ef8ae950d..430ea59c8 100644 --- a/host/lib/usrp/usrp1/usrp1_impl.cpp +++ b/host/lib/usrp/usrp1/usrp1_impl.cpp @@ -210,6 +210,7 @@ usrp1_impl::usrp1_impl(const device_addr_t &device_addr){ //////////////////////////////////////////////////////////////////// // Initialize the properties tree //////////////////////////////////////////////////////////////////// + _rx_dc_offset_shadow = 0; _tree = property_tree::make(); _tree->create("/name").set("USRP1 Device"); const fs_path mb_path = "/mboards/0"; -- cgit v1.2.3 From 6d45600ada785cb50a01a17dcddf561d12501d22 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Fri, 10 Feb 2012 12:13:51 -0800 Subject: dsp rework: pass enables into glue, update power trig, parameterize, fix module inc DSP enables now pass through the glue and custom modules so it can be user-controlled. Updated power trigger to current spec, and added comments Pass width from dsp into glue, and use width to parameterize wires Fix custom module includes so they will build --- usrp2/custom/custom_dsp_rx.v | 2 + usrp2/custom/custom_dsp_tx.v | 2 + usrp2/custom/power_trig.v | 83 +++++++++++++++++++++--------------- usrp2/sdr_lib/ddc_chain.v | 94 +++++++++++++++++++++++------------------ usrp2/sdr_lib/dsp_rx_glue.v | 11 +++-- usrp2/sdr_lib/dsp_tx_glue.v | 11 +++-- usrp2/sdr_lib/duc_chain.v | 37 +++++++++------- usrp2/vrt/vita_rx_engine_glue.v | 4 +- usrp2/vrt/vita_tx_engine_glue.v | 4 +- 9 files changed, 145 insertions(+), 103 deletions(-) diff --git a/usrp2/custom/custom_dsp_rx.v b/usrp2/custom/custom_dsp_rx.v index 2ceda7481..355adf008 100644 --- a/usrp2/custom/custom_dsp_rx.v +++ b/usrp2/custom/custom_dsp_rx.v @@ -55,6 +55,7 @@ module custom_dsp_rx //strobed samples {I16,Q16} from the RX DDC chain input [31:0] ddc_out_sample, input ddc_out_strobe, //high on valid sample + output ddc_out_enable, //enables DDC module //strobbed baseband samples {I16,Q16} from this module output [31:0] bb_sample, @@ -65,5 +66,6 @@ module custom_dsp_rx assign ddc_in_q = frontend_q; assign bb_sample = ddc_out_sample; assign bb_strobe = ddc_out_strobe; + assign ddc_out_enable = enable; endmodule //custom_dsp_rx diff --git a/usrp2/custom/custom_dsp_tx.v b/usrp2/custom/custom_dsp_tx.v index 5206a63a6..0848a187f 100644 --- a/usrp2/custom/custom_dsp_tx.v +++ b/usrp2/custom/custom_dsp_tx.v @@ -55,6 +55,7 @@ module custom_dsp_tx //strobed samples {I16,Q16} to the TX DUC chain output [31:0] duc_in_sample, input duc_in_strobe, //this is a backpressure signal + output duc_in_enable, //enables DUC module //strobbed baseband samples {I16,Q16} to this module input [31:0] bb_sample, @@ -65,5 +66,6 @@ module custom_dsp_tx assign frontend_q = duc_out_q; assign duc_in_sample = bb_sample; assign bb_strobe = duc_in_strobe; + assign duc_in_enable = enable; endmodule //custom_dsp_tx diff --git a/usrp2/custom/power_trig.v b/usrp2/custom/power_trig.v index ca213e901..b38059030 100644 --- a/usrp2/custom/power_trig.v +++ b/usrp2/custom/power_trig.v @@ -15,41 +15,56 @@ // along with this program. If not, see . // -//CUSTOMIZE ME! +// This a power trigger module implemented on top of the custom dsp template. +// Power triggering is implemented after the existing DDC chain. +// Triggering is controlled via user settings registers. -//The following module effects the IO of the DDC chain. -//By default, this entire module is a simple pass-through. - -//To implement DSP logic before the DDC: -//Implement custom DSP between frontend and ddc input. - -//To implement DSP logic after the DDC: -//Implement custom DSP between ddc output and baseband. - -//To bypass the DDC with custom logic: -//Implement custom DSP between frontend and baseband. +// Register 0: +// threshold for power trigger +// 32 bit unsigned fixed-point number of some arbitrary scaling module power_trig - #(parameter BASE=0) - (//control signals - input clk, input reset, input enable, - - // Setting Bus +#( + //frontend bus width + parameter WIDTH = 24, + parameter BASE = 0 +) +( + //control signals + input clock, //dsp clock + input reset, //active high synchronous reset + input clear, //active high on packet control init + input enable, //active high when streaming enabled + + //user settings bus, controlled through user setting regs API input set_stb, input [7:0] set_addr, input [31:0] set_data, - input run, - + //full rate inputs directly from the RX frontend + input [WIDTH-1:0] frontend_i, + input [WIDTH-1:0] frontend_q, + + //full rate outputs directly to the DDC chain + output [WIDTH-1:0] ddc_in_i, + output [WIDTH-1:0] ddc_in_q, + //strobed samples {I16,Q16} from the RX DDC chain input [31:0] ddc_out_sample, input ddc_out_strobe, //high on valid sample + output ddc_out_enable, //enables DDC module - //strobed baseband samples {I16,Q16} from this module + //strobbed baseband samples {I16,Q16} from this module output [31:0] bb_sample, - output bb_strobe, //high on valid sample + output bb_strobe //high on valid sample +); + + //leave frontend tied to existing ddc chain + assign ddc_in_i = frontend_i; + assign ddc_in_q = frontend_q; + + //ddc enable remains tied to global enable + assign ddc_out_enable = enable; - //debug output (optional) - output [31:0] debug - ); + //below we implement a power trigger between baseband samples and ddc output... reg [8:0] wr_addr; wire [8:0] rd_addr; @@ -69,23 +84,23 @@ module power_trig (.clka(clk),.ena(1),.wea(ddc_out_strobe),.addra(wr_addr),.dia(ddc_out_sample),.doa(), .clkb(clk),.enb(ddc_out_strobe),.web(1'b0),.addrb(rd_addr),.dib(32'hFFFF),.dob(delayed_sample)); - always @(posedge clk) - if(reset | ~run) + always @(posedge clock) + if(reset | ~enable) wr_addr <= 0; else if(ddc_out_strobe) wr_addr <= wr_addr + 1; - always @(posedge clk) - if(reset | ~run) + always @(posedge clock) + if(reset | ~enable) triggerable <= 0; else if(wr_addr == 9'h1FF) // Wait till we're nearly full triggerable <= 1; reg stb_d1, stb_d2; - always @(posedge clk) stb_d1 <= ddc_out_strobe; - always @(posedge clk) stb_d2 <= stb_d1; + always @(posedge clock) stb_d1 <= ddc_out_strobe; + always @(posedge clock) stb_d2 <= stb_d1; assign bb_sample = delayed_sample; assign bb_strobe = stb_d1 & triggered; @@ -96,16 +111,16 @@ module power_trig wire [35:0] prod; reg [31:0] sum; - MULT18X18S mult (.P(prod), .A(mult_in), .B(mult_in), .C(clk), .CE(ddc_out_strobe | stb_d1), .R(reset) ); + MULT18X18S mult (.P(prod), .A(mult_in), .B(mult_in), .C(clock), .CE(ddc_out_strobe | stb_d1), .R(reset) ); - always @(posedge clk) + always @(posedge clock) if(stb_d1) sum <= prod[35:4]; else if(stb_d2) sum <= sum + prod[35:4]; - always @(posedge clk) - if(reset | ~run | ~triggerable) + always @(posedge clock) + if(reset | ~enable | ~triggerable) triggered <= 0; else if(trigger) triggered <= 1; diff --git a/usrp2/sdr_lib/ddc_chain.v b/usrp2/sdr_lib/ddc_chain.v index 800bb5b13..c32c9f491 100644 --- a/usrp2/sdr_lib/ddc_chain.v +++ b/usrp2/sdr_lib/ddc_chain.v @@ -18,14 +18,18 @@ //! The USRP digital down-conversion chain module ddc_chain - #(parameter BASE = 0, parameter DSPNO = 0) + #( + parameter BASE = 0, + parameter DSPNO = 0, + parameter WIDTH = 24 + ) (input clk, input rst, input clr, input set_stb, input [7:0] set_addr, input [31:0] set_data, input set_stb_user, input [7:0] set_addr_user, input [31:0] set_data_user, // From RX frontend - input [23:0] rx_fe_i, - input [23:0] rx_fe_q, + input [WIDTH-1:0] rx_fe_i, + input [WIDTH-1:0] rx_fe_q, // To RX control output [31:0] sample, @@ -34,21 +38,25 @@ module ddc_chain output [31:0] debug ); + localparam cwidth = 25; + localparam zwidth = 24; + + wire ddc_enb; wire [31:0] phase_inc; reg [31:0] phase; wire [17:0] scale_factor; - wire [24:0] i_cordic, q_cordic; - wire [23:0] i_cordic_clip, q_cordic_clip; - wire [23:0] i_cic, q_cic; - wire [23:0] i_hb1, q_hb1; - wire [23:0] i_hb2, q_hb2; + wire [cwidth-1:0] i_cordic, q_cordic; + wire [WIDTH-1:0] i_cordic_clip, q_cordic_clip; + wire [WIDTH-1:0] i_cic, q_cic; + wire [WIDTH-1:0] i_hb1, q_hb1; + wire [WIDTH-1: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] rx_fe_i_mux, rx_fe_q_mux; + reg [WIDTH-1:0] rx_fe_i_mux, rx_fe_q_mux; wire realmode; wire swap_iq; @@ -74,103 +82,107 @@ module ddc_chain if(swap_iq) begin rx_fe_i_mux <= rx_fe_q; - rx_fe_q_mux <= realmode ? 24'd0 : rx_fe_i; + rx_fe_q_mux <= realmode ? 0 : rx_fe_i; end else begin rx_fe_i_mux <= rx_fe_i; - rx_fe_q_mux <= realmode ? 24'd0 : rx_fe_q; + rx_fe_q_mux <= realmode ? 0 : rx_fe_q; end // NCO always @(posedge clk) if(rst) phase <= 0; - else if(~run) + else if(~ddc_enb) phase <= 0; else phase <= phase + phase_inc; - wire [23:0] to_cordic_i, to_cordic_q; + //sign extension of cordic input + wire [WIDTH-1:0] to_ddc_chain_i, to_ddc_chain_q; + wire [cwidth-1:0] to_cordic_i, to_cordic_q; + sign_extend #(.bits_in(WIDTH), .bits_out(cwidth)) sign_extend_cordic_i (.in(to_ddc_chain_i), .out(to_cordic_i)); + sign_extend #(.bits_in(WIDTH), .bits_out(cwidth)) sign_extend_cordic_q (.in(to_ddc_chain_q), .out(to_cordic_q)); // CORDIC 24-bit I/O - cordic_z24 #(.bitwidth(25)) - cordic(.clock(clk), .reset(rst), .enable(run), - .xi({to_cordic_i[23],to_cordic_i}),. yi({to_cordic_q[23],to_cordic_q}), .zi(phase[31:8]), + cordic_z24 #(.bitwidth(cwidth)) + cordic(.clock(clk), .reset(rst), .enable(ddc_enb), + .xi(to_cordic_i),. yi(to_cordic_q), .zi(phase[31:32-zwidth]), .xo(i_cordic),.yo(q_cordic),.zo() ); - clip_reg #(.bits_in(25), .bits_out(24)) clip_i + clip_reg #(.bits_in(cwidth), .bits_out(WIDTH)) clip_i (.clk(clk), .in(i_cordic), .strobe_in(1'b1), .out(i_cordic_clip)); - clip_reg #(.bits_in(25), .bits_out(24)) clip_q + clip_reg #(.bits_in(cwidth), .bits_out(WIDTH)) clip_q (.clk(clk), .in(q_cordic), .strobe_in(1'b1), .out(q_cordic_clip)); // CIC decimator 24 bit I/O - cic_strober cic_strober(.clock(clk),.reset(rst),.enable(run),.rate(cic_decim_rate), + cic_strober cic_strober(.clock(clk),.reset(rst),.enable(ddc_enb),.rate(cic_decim_rate), .strobe_fast(1),.strobe_slow(strobe_cic) ); - cic_decim #(.bw(24)) - decim_i (.clock(clk),.reset(rst),.enable(run), + cic_decim #(.bw(WIDTH)) + decim_i (.clock(clk),.reset(rst),.enable(ddc_enb), .rate(cic_decim_rate),.strobe_in(1'b1),.strobe_out(strobe_cic), .signal_in(i_cordic_clip),.signal_out(i_cic)); - cic_decim #(.bw(24)) - decim_q (.clock(clk),.reset(rst),.enable(run), + cic_decim #(.bw(WIDTH)) + decim_q (.clock(clk),.reset(rst),.enable(ddc_enb), .rate(cic_decim_rate),.strobe_in(1'b1),.strobe_out(strobe_cic), .signal_in(q_cordic_clip),.signal_out(q_cic)); // First (small) halfband 24 bit I/O - small_hb_dec #(.WIDTH(24)) small_hb_i - (.clk(clk),.rst(rst),.bypass(~enable_hb1),.run(run), + small_hb_dec #(.WIDTH(WIDTH)) small_hb_i + (.clk(clk),.rst(rst),.bypass(~enable_hb1),.run(ddc_enb), .stb_in(strobe_cic),.data_in(i_cic),.stb_out(strobe_hb1),.data_out(i_hb1)); - small_hb_dec #(.WIDTH(24)) small_hb_q - (.clk(clk),.rst(rst),.bypass(~enable_hb1),.run(run), + small_hb_dec #(.WIDTH(WIDTH)) small_hb_q + (.clk(clk),.rst(rst),.bypass(~enable_hb1),.run(ddc_enb), .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 #(.WIDTH(24)) hb_i - (.clk(clk),.rst(rst),.bypass(~enable_hb2),.run(run),.cpi(cpi_hb), + hb_dec #(.WIDTH(WIDTH)) hb_i + (.clk(clk),.rst(rst),.bypass(~enable_hb2),.run(ddc_enb),.cpi(cpi_hb), .stb_in(strobe_hb1),.data_in(i_hb1),.stb_out(strobe_hb2),.data_out(i_hb2)); - hb_dec #(.WIDTH(24)) hb_q - (.clk(clk),.rst(rst),.bypass(~enable_hb2),.run(run),.cpi(cpi_hb), + hb_dec #(.WIDTH(WIDTH)) hb_q + (.clk(clk),.rst(rst),.bypass(~enable_hb2),.run(ddc_enb),.cpi(cpi_hb), .stb_in(strobe_hb1),.data_in(q_hb1),.stb_out(),.data_out(q_hb2)); //scalar operation (gain of 6 bits) wire [35:0] prod_i, prod_q; MULT18X18S mult_i - (.P(prod_i), .A(i_hb2[23:6]), .B(scale_factor), .C(clk), .CE(strobe_hb2), .R(rst) ); + (.P(prod_i), .A(i_hb2[WIDTH-1:WIDTH-18]), .B(scale_factor), .C(clk), .CE(strobe_hb2), .R(rst) ); MULT18X18S mult_q - (.P(prod_q), .A(q_hb2[23:6]), .B(scale_factor), .C(clk), .CE(strobe_hb2), .R(rst) ); + (.P(prod_q), .A(q_hb2[WIDTH-1:WIDTH-18]), .B(scale_factor), .C(clk), .CE(strobe_hb2), .R(rst) ); //pipeline for the multiplier (gain of 10 bits) - reg [23:0] prod_reg_i, prod_reg_q; + reg [WIDTH-1:0] prod_reg_i, prod_reg_q; reg strobe_mult; always @(posedge clk) begin strobe_mult <= strobe_hb2; - prod_reg_i <= prod_i[33:10]; - prod_reg_q <= prod_q[33:10]; + prod_reg_i <= prod_i[33:34-WIDTH]; + prod_reg_q <= prod_q[33:34-WIDTH]; end // Round final answer to 16 bits wire [31:0] ddc_chain_out; wire ddc_chain_stb; - round_sd #(.WIDTH_IN(24),.WIDTH_OUT(16)) round_i + round_sd #(.WIDTH_IN(WIDTH),.WIDTH_OUT(16)) round_i (.clk(clk),.reset(rst), .in(prod_reg_i),.strobe_in(strobe_mult), .out(ddc_chain_out[31:16]), .strobe_out(ddc_chain_stb)); - round_sd #(.WIDTH_IN(24),.WIDTH_OUT(16)) round_q + round_sd #(.WIDTH_IN(WIDTH),.WIDTH_OUT(16)) round_q (.clk(clk),.reset(rst), .in(prod_reg_q),.strobe_in(strobe_mult), .out(ddc_chain_out[15:0]), .strobe_out()); - dsp_rx_glue #(.DSPNO(DSPNO)) custom( + dsp_rx_glue #(.DSPNO(DSPNO), .WIDTH(WIDTH)) custom( .clock(clk), .reset(rst), .clear(clr), .enable(run), .set_stb(set_stb_user), .set_addr(set_addr_user), .set_data(set_data_user), .frontend_i(rx_fe_i_mux), .frontend_q(rx_fe_q_mux), - .ddc_in_i(to_cordic_i), .ddc_in_q(to_cordic_q), - .ddc_out_sample(ddc_chain_out), .ddc_out_strobe(ddc_chain_stb), + .ddc_in_i(to_ddc_chain_i), .ddc_in_q(to_ddc_chain_q), + .ddc_out_sample(ddc_chain_out), .ddc_out_strobe(ddc_chain_stb), .ddc_out_enable(ddc_enb), .bb_sample(sample), .bb_strobe(strobe)); assign debug = {enable_hb1, enable_hb2, run, strobe, strobe_cic, strobe_hb1, strobe_hb2}; diff --git a/usrp2/sdr_lib/dsp_rx_glue.v b/usrp2/sdr_lib/dsp_rx_glue.v index e2a1d52b1..038a67a29 100644 --- a/usrp2/sdr_lib/dsp_rx_glue.v +++ b/usrp2/sdr_lib/dsp_rx_glue.v @@ -44,6 +44,7 @@ module dsp_rx_glue //strobed samples {I16,Q16} from the RX DDC chain input [31:0] ddc_out_sample, input ddc_out_strobe, //high on valid sample + output ddc_out_enable, //enables DDC module //strobbed baseband samples {I16,Q16} from this module output [31:0] bb_sample, @@ -60,14 +61,15 @@ module dsp_rx_glue assign ddc_in_q = frontend_q; assign bb_sample = ddc_out_sample; assign bb_strobe = ddc_out_strobe; + assign ddc_out_enable = enable; `else - RX_DSP0_MODULE rx_dsp0_custom + `RX_DSP0_MODULE #(.WIDTH(WIDTH)) rx_dsp0_custom ( .clock(clock), .reset(reset), .clear(clear), .enable(enable), .set_stb(set_stb), .set_addr(set_addr), .set_data(set_data), .frontend_i(frontend_i), .frontend_q(frontend_q), .ddc_in_i(ddc_in_i), .ddc_in_q(ddc_in_q), - .ddc_out_sample(ddc_out_sample), .ddc_out_strobe(ddc_out_strobe), + .ddc_out_sample(ddc_out_sample), .ddc_out_strobe(ddc_out_strobe), .ddc_out_enable(ddc_out_enable), .bb_sample(bb_sample), .bb_strobe(bb_strobe) ); `endif @@ -78,14 +80,15 @@ module dsp_rx_glue assign ddc_in_q = frontend_q; assign bb_sample = ddc_out_sample; assign bb_strobe = ddc_out_strobe; + assign ddc_out_enable = enable; `else - RX_DSP1_MODULE rx_dsp1_custom + `RX_DSP1_MODULE #(.WIDTH(WIDTH)) rx_dsp1_custom ( .clock(clock), .reset(reset), .clear(clear), .enable(enable), .set_stb(set_stb), .set_addr(set_addr), .set_data(set_data), .frontend_i(frontend_i), .frontend_q(frontend_q), .ddc_in_i(ddc_in_i), .ddc_in_q(ddc_in_q), - .ddc_out_sample(ddc_out_sample), .ddc_out_strobe(ddc_out_strobe), + .ddc_out_sample(ddc_out_sample), .ddc_out_strobe(ddc_out_strobe), .ddc_out_enable(ddc_out_enable), .bb_sample(bb_sample), .bb_strobe(bb_strobe) ); `endif diff --git a/usrp2/sdr_lib/dsp_tx_glue.v b/usrp2/sdr_lib/dsp_tx_glue.v index 9af13c6c1..46f6789ee 100644 --- a/usrp2/sdr_lib/dsp_tx_glue.v +++ b/usrp2/sdr_lib/dsp_tx_glue.v @@ -44,6 +44,7 @@ module dsp_tx_glue //strobed samples {I16,Q16} to the TX DUC chain output [31:0] duc_in_sample, input duc_in_strobe, //this is a backpressure signal + output duc_in_enable, //enables DUC module //strobbed baseband samples {I16,Q16} to this module input [31:0] bb_sample, @@ -60,14 +61,15 @@ module dsp_tx_glue assign frontend_q = duc_out_q; assign duc_in_sample = bb_sample; assign bb_strobe = duc_in_strobe; + assign duc_in_enable = enable; `else - TX_DSP0_MODULE tx_dsp0_custom + `TX_DSP0_MODULE #(.WIDTH(WIDTH)) tx_dsp0_custom ( .clock(clock), .reset(reset), .clear(clear), .enable(enable), .set_stb(set_stb), .set_addr(set_addr), .set_data(set_data), .frontend_i(frontend_i), .frontend_q(frontend_q), .duc_out_i(duc_out_i), .duc_out_q(duc_out_q), - .duc_in_sample(duc_in_sample), .duc_in_strobe(duc_in_strobe), + .duc_in_sample(duc_in_sample), .duc_in_strobe(duc_in_strobe), .duc_in_enable(duc_in_enable), .bb_sample(bb_sample), .bb_strobe(bb_strobe) ); `endif @@ -78,14 +80,15 @@ module dsp_tx_glue assign frontend_q = duc_out_q; assign duc_in_sample = bb_sample; assign bb_strobe = duc_in_strobe; + assign duc_in_enable = enable; `else - TX_DSP1_MODULE tx_dsp1_custom + `TX_DSP1_MODULE #(.WIDTH(WIDTH)) tx_dsp1_custom ( .clock(clock), .reset(reset), .clear(clear), .enable(enable), .set_stb(set_stb), .set_addr(set_addr), .set_data(set_data), .frontend_i(frontend_i), .frontend_q(frontend_q), .duc_out_i(duc_out_i), .duc_out_q(duc_out_q), - .duc_in_sample(duc_in_sample), .duc_in_strobe(duc_in_strobe), + .duc_in_sample(duc_in_sample), .duc_in_strobe(duc_in_strobe), .duc_in_enable(duc_in_enable), .bb_sample(bb_sample), .bb_strobe(bb_strobe) ); `endif diff --git a/usrp2/sdr_lib/duc_chain.v b/usrp2/sdr_lib/duc_chain.v index 7a72903a6..bd3402a1f 100644 --- a/usrp2/sdr_lib/duc_chain.v +++ b/usrp2/sdr_lib/duc_chain.v @@ -18,14 +18,18 @@ //! The USRP digital up-conversion chain module duc_chain - #(parameter BASE = 0, parameter DSPNO = 0) + #( + parameter BASE = 0, + parameter DSPNO = 0, + parameter WIDTH = 24 + ) (input clk, input rst, input clr, input set_stb, input [7:0] set_addr, input [31:0] set_data, input set_stb_user, input [7:0] set_addr_user, input [31:0] set_data_user, // To TX frontend - output [23:0] tx_fe_i, - output [23:0] tx_fe_q, + output [WIDTH-1:0] tx_fe_i, + output [WIDTH-1:0] tx_fe_q, // From TX control input [31:0] sample, @@ -34,6 +38,7 @@ module duc_chain output [31:0] debug ); + wire duc_enb; wire [17:0] scale_factor; wire [31:0] phase_inc; reg [31:0] phase; @@ -61,13 +66,13 @@ module duc_chain reg strobe_hb2 = 1; cic_strober #(.WIDTH(8)) - cic_strober(.clock(clk),.reset(rst),.enable(run & ~rate_change),.rate(interp_rate), + cic_strober(.clock(clk),.reset(rst),.enable(duc_enb & ~rate_change),.rate(interp_rate), .strobe_fast(1),.strobe_slow(strobe_cic_pre) ); cic_strober #(.WIDTH(2)) - hb2_strober(.clock(clk),.reset(rst),.enable(run & ~rate_change),.rate(enable_hb2 ? 2 : 1), + hb2_strober(.clock(clk),.reset(rst),.enable(duc_enb & ~rate_change),.rate(enable_hb2 ? 2 : 1), .strobe_fast(strobe_cic_pre),.strobe_slow(strobe_hb2_pre) ); cic_strober #(.WIDTH(2)) - hb1_strober(.clock(clk),.reset(rst),.enable(run & ~rate_change),.rate(enable_hb1 ? 2 : 1), + hb1_strober(.clock(clk),.reset(rst),.enable(duc_enb & ~rate_change),.rate(enable_hb1 ? 2 : 1), .strobe_fast(strobe_hb2_pre),.strobe_slow(strobe_hb1_pre) ); always @(posedge clk) strobe_hb1 <= strobe_hb1_pre; @@ -78,7 +83,7 @@ module duc_chain always @(posedge clk) if(rst) phase <= 0; - else if(~run) + else if(~duc_enb) phase <= 0; else phase <= phase + phase_inc; @@ -96,9 +101,9 @@ module duc_chain // Note that max CIC rate is 128, which would give an overflow on cpo if enable_hb2 is true, // but the default case inside hb_interp handles this - hb_interp #(.IWIDTH(18),.OWIDTH(18),.ACCWIDTH(24)) hb_interp_i + hb_interp #(.IWIDTH(18),.OWIDTH(18),.ACCWIDTH(WIDTH)) hb_interp_i (.clk(clk),.rst(rst),.bypass(~enable_hb1),.cpo(cpo),.stb_in(strobe_hb1),.data_in({bb_i, 2'b0}),.stb_out(strobe_hb2),.data_out(hb1_i)); - hb_interp #(.IWIDTH(18),.OWIDTH(18),.ACCWIDTH(24)) hb_interp_q + hb_interp #(.IWIDTH(18),.OWIDTH(18),.ACCWIDTH(WIDTH)) hb_interp_q (.clk(clk),.rst(rst),.bypass(~enable_hb1),.cpo(cpo),.stb_in(strobe_hb1),.data_in({bb_q, 2'b0}),.stb_out(strobe_hb2),.data_out(hb1_q)); small_hb_int #(.WIDTH(18)) small_hb_interp_i @@ -109,22 +114,22 @@ module duc_chain .output_rate(interp_rate),.stb_out(strobe_cic),.data_out(hb2_q)); cic_interp #(.bw(18),.N(4),.log2_of_max_rate(7)) - cic_interp_i(.clock(clk),.reset(rst),.enable(run & ~rate_change),.rate(interp_rate), + cic_interp_i(.clock(clk),.reset(rst),.enable(duc_enb & ~rate_change),.rate(interp_rate), .strobe_in(strobe_cic),.strobe_out(1), .signal_in(hb2_i),.signal_out(i_interp)); cic_interp #(.bw(18),.N(4),.log2_of_max_rate(7)) - cic_interp_q(.clock(clk),.reset(rst),.enable(run & ~rate_change),.rate(interp_rate), + cic_interp_q(.clock(clk),.reset(rst),.enable(duc_enb & ~rate_change),.rate(interp_rate), .strobe_in(strobe_cic),.strobe_out(1), .signal_in(hb2_q),.signal_out(q_interp)); - localparam cwidth = 24; // was 18 + localparam cwidth = WIDTH; // was 18 localparam zwidth = 24; // was 16 wire [cwidth-1:0] da_c, db_c; cordic_z24 #(.bitwidth(cwidth)) - cordic(.clock(clk), .reset(rst), .enable(run), + cordic(.clock(clk), .reset(rst), .enable(duc_enb), .xi({i_interp,{(cwidth-18){1'b0}}}),.yi({q_interp,{(cwidth-18){1'b0}}}), .zi(phase[31:32-zwidth]), .xo(da_c),.yo(db_c),.zo() ); @@ -147,12 +152,12 @@ module duc_chain .R(rst) // Synchronous reset input ); - dsp_tx_glue #(.DSPNO(DSPNO)) dsp_tx_glue( + dsp_tx_glue #(.DSPNO(DSPNO), .WIDTH(WIDTH)) dsp_tx_glue( .clock(clk), .reset(rst), .clear(clr), .enable(run), .set_stb(set_stb_user), .set_addr(set_addr_user), .set_data(set_data_user), .frontend_i(tx_fe_i), .frontend_q(tx_fe_q), - .duc_out_i(prod_i[33:10]), .duc_out_q(prod_q[33:10]), - .duc_in_sample({bb_i, bb_q}), .duc_in_strobe(strobe_hb1), + .duc_out_i(prod_i[33:34-WIDTH]), .duc_out_q(prod_q[33:34-WIDTH]), + .duc_in_sample({bb_i, bb_q}), .duc_in_strobe(strobe_hb1), .duc_in_enable(duc_enb), .bb_sample(sample), .bb_strobe(strobe)); assign debug = {strobe_cic, strobe_hb1, strobe_hb2,run}; diff --git a/usrp2/vrt/vita_rx_engine_glue.v b/usrp2/vrt/vita_rx_engine_glue.v index 86e3d1114..56447a7aa 100644 --- a/usrp2/vrt/vita_rx_engine_glue.v +++ b/usrp2/vrt/vita_rx_engine_glue.v @@ -65,7 +65,7 @@ module vita_rx_engine_glue .access_skip_read(access_skip_read), .access_adr(access_adr), .access_len(access_len), .access_dat_i(access_dat_i), .access_dat_o(access_dat_o)); `else - RX_ENG0_MODULE #(.BUF_SIZE(BUF_SIZE)) rx_eng0_custom + `RX_ENG0_MODULE #(.BUF_SIZE(BUF_SIZE)) rx_eng0_custom (.clock(clock),.reset(reset),.clear(clear), .set_stb(set_stb_user), .set_addr(set_addr_user), .set_data(set_data_user), .access_we(access_we), .access_stb(access_stb), .access_ok(access_ok), .access_done(access_done), @@ -82,7 +82,7 @@ module vita_rx_engine_glue .access_skip_read(access_skip_read), .access_adr(access_adr), .access_len(access_len), .access_dat_i(access_dat_i), .access_dat_o(access_dat_o)); `else - RX_ENG1_MODULE #(.BUF_SIZE(BUF_SIZE)) rx_eng1_custom + `RX_ENG1_MODULE #(.BUF_SIZE(BUF_SIZE)) rx_eng1_custom (.clock(clock),.reset(reset),.clear(clear), .set_stb(set_stb_user), .set_addr(set_addr_user), .set_data(set_data_user), .access_we(access_we), .access_stb(access_stb), .access_ok(access_ok), .access_done(access_done), diff --git a/usrp2/vrt/vita_tx_engine_glue.v b/usrp2/vrt/vita_tx_engine_glue.v index b0a81c3e9..db0d55dee 100644 --- a/usrp2/vrt/vita_tx_engine_glue.v +++ b/usrp2/vrt/vita_tx_engine_glue.v @@ -69,7 +69,7 @@ module vita_tx_engine_glue .access_skip_read(access_skip_read), .access_adr(access_adr), .access_len(access_len), .access_dat_i(access_dat_i), .access_dat_o(access_dat_o)); `else - TX_ENG0_MODULE #(.BUF_SIZE(BUF_SIZE), .HEADER_OFFSET(HEADER_OFFSET)) tx_eng0_custom + `TX_ENG0_MODULE #(.BUF_SIZE(BUF_SIZE), .HEADER_OFFSET(HEADER_OFFSET)) tx_eng0_custom (.clock(clock),.reset(reset),.clear(clear), .set_stb(set_stb_user), .set_addr(set_addr_user), .set_data(set_data_user), .access_we(access_we), .access_stb(access_stb), .access_ok(access_ok), .access_done(access_done), @@ -86,7 +86,7 @@ module vita_tx_engine_glue .access_skip_read(access_skip_read), .access_adr(access_adr), .access_len(access_len), .access_dat_i(access_dat_i), .access_dat_o(access_dat_o)); `else - TX_ENG1_MODULE #(.BUF_SIZE(BUF_SIZE), .HEADER_OFFSET(HEADER_OFFSET)) tx_eng1_custom + `TX_ENG1_MODULE #(.BUF_SIZE(BUF_SIZE), .HEADER_OFFSET(HEADER_OFFSET)) tx_eng1_custom (.clock(clock),.reset(reset),.clear(clear), .set_stb(set_stb_user), .set_addr(set_addr_user), .set_data(set_data_user), .access_we(access_we), .access_stb(access_stb), .access_ok(access_ok), .access_done(access_done), -- cgit v1.2.3 From bada7617a2941712b68421b647c03623ef21c928 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Sun, 12 Feb 2012 14:17:45 -0800 Subject: dsp rework: full-rate pipelining in vita tx deframer The vita tx deframer can now pass payload at clock rate. This enables TX streaming at interpolations factors of 2. The vector capabilities of TX deframer have been kept in-tact, and should be functional, however, only MAXCHAN=1 has been tested. --- usrp2/vrt/vita_tx_deframer.v | 88 +++++++++++++++++++++++++------------------- 1 file changed, 51 insertions(+), 37 deletions(-) diff --git a/usrp2/vrt/vita_tx_deframer.v b/usrp2/vrt/vita_tx_deframer.v index 62498836f..b187ab97c 100644 --- a/usrp2/vrt/vita_tx_deframer.v +++ b/usrp2/vrt/vita_tx_deframer.v @@ -118,21 +118,7 @@ module vita_tx_deframer <= 0; seqnum_err <= 0; end - else - if((vita_state == VITA_STORE) & fifo_space) - if(vita_eof) - if(eof) - vita_state <= (USE_TRANS_HEADER==1) ? VITA_TRANS_HEADER : VITA_HEADER; - else if(has_trailer_reg) - vita_state <= VITA_TRAILER; - else - vita_state <= VITA_DUMP; - else - begin - vita_state <= VITA_PAYLOAD; - pkt_len <= pkt_len - 1; - end - else if(src_rdy_i) + else if(src_rdy_i & dst_rdy_o) begin //valid read case(vita_state) VITA_TRANS_HEADER : begin @@ -184,14 +170,33 @@ module vita_tx_deframer vita_state <= VITA_TICS2; VITA_TICS2 : vita_state <= VITA_PAYLOAD; - VITA_PAYLOAD : - if(line_done) - begin - vector_phase <= 0; - vita_state <= VITA_STORE; - end - else - vector_phase <= vector_phase + 1; + + VITA_PAYLOAD : begin + + //step through each element until line done, then reset + vector_phase <= (line_done)? 0: vector_phase + 1; + + //decrement the packet count after each line + pkt_len <= (line_done)? pkt_len - 1 : pkt_len; + + //end of frame reached, determine next state + //otherwise, keep processing through the payload + if (line_done && vita_eof) begin + + if (eof) begin + vita_state <= (USE_TRANS_HEADER==1) ? VITA_TRANS_HEADER : VITA_HEADER; + end + else if (has_trailer_reg) begin + vita_state <= VITA_TRAILER; + end + else begin + vita_state <= VITA_DUMP; + end + + end //line_done && vita_eof + + end //end VITA_PAYLOAD + VITA_TRAILER : if(eof) vita_state <= (USE_TRANS_HEADER==1) ? VITA_TRANS_HEADER : VITA_HEADER; @@ -206,11 +211,12 @@ module vita_tx_deframer vita_state <= (USE_TRANS_HEADER==1) ? VITA_TRANS_HEADER : VITA_HEADER; endcase // case (vita_state) + end //valid read + assign line_done = (vector_phase == numchan); wire [FIFOWIDTH-1:0] fifo_i; reg [63:0] send_time; - reg [31:0] sample_a, sample_b, sample_c, sample_d; always @(posedge clk) case(vita_state) @@ -219,28 +225,36 @@ module vita_tx_deframer VITA_TICS2 : send_time[31:0] <= data_i[31:0]; endcase // case (vita_state) - + + //sample registers for de-framing a vector input + reg [31:0] sample_reg [1:0]; always @(posedge clk) - if(vita_state == VITA_PAYLOAD) - case(vector_phase) - 0: sample_a <= data_i[31:0]; - 1: sample_b <= data_i[31:0]; - 2: sample_c <= data_i[31:0]; - 3: sample_d <= data_i[31:0]; - endcase // case (vector_phase) - - wire store = (vita_state == VITA_STORE); + if(src_rdy_i && dst_rdy_o) + sample_reg[vector_phase] <= data_i[31:0]; + + wire store = (vita_state == VITA_PAYLOAD)? (src_rdy_i && line_done) : 0; + assign dst_rdy_o = (vita_state == VITA_PAYLOAD)? fifo_space : 1; + fifo_short #(.WIDTH(FIFOWIDTH)) short_tx_q (.clk(clk), .reset(reset), .clear(clear), .datain(fifo_i), .src_rdy_i(store), .dst_rdy_o(fifo_space), .dataout(sample_fifo_o), .src_rdy_o(sample_fifo_src_rdy_o), .dst_rdy_i(sample_fifo_dst_rdy_i) ); + //assign registered/live data to the samples vector + //the numchan'th sample vector is muxed to live data + wire [(32*MAXCHAN)-1:0] samples; + generate + genvar i; + for (i=0; i < MAXCHAN; i = i +1) begin : assign_samples + wire live_data = (i == (MAXCHAN-1))? 1 : numchan == i; + assign samples[32*i + 31:32*i] = (live_data)? data_i[31:0] : sample_reg[i]; + end + endgenerate + // sob, eob, has_tics (send_at) ignored on all lines except first - assign fifo_i = {sample_d,sample_c,sample_b,sample_a,seqnum_err,has_tics_reg,is_sob_reg,is_eob_reg,eop, + assign fifo_i = {samples,seqnum_err,has_tics_reg,is_sob_reg,is_eob_reg,eop, 12'd0,seqnum_reg[3:0],send_time}; - assign dst_rdy_o = ~(vita_state == VITA_PAYLOAD) & ~((vita_state==VITA_STORE)& ~fifo_space) ; - assign debug = { { 8'b0 }, { 8'b0 }, { eof, line_done, store, fifo_space, src_rdy_i, dst_rdy_o, vector_phase[1:0] }, -- cgit v1.2.3 From 4a27f6e4bdad5e4de743e77f0a998dbe1e852cf0 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Sun, 12 Feb 2012 14:38:35 -0800 Subject: uhd: add over-the-wire option to tx waveforms --- host/examples/tx_waveforms.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/host/examples/tx_waveforms.cpp b/host/examples/tx_waveforms.cpp index 39f70aec6..6a377fdac 100644 --- a/host/examples/tx_waveforms.cpp +++ b/host/examples/tx_waveforms.cpp @@ -90,7 +90,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ uhd::set_thread_priority_safe(); //variables to be set by po - std::string args, wave_type, ant, subdev, ref; + std::string args, wave_type, ant, subdev, ref, otw; size_t spb; double rate, freq, gain, wave_freq, bw; float ampl; @@ -111,6 +111,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ ("wave-type", po::value(&wave_type)->default_value("CONST"), "waveform type (CONST, SQUARE, RAMP, SINE)") ("wave-freq", po::value(&wave_freq)->default_value(0), "waveform frequency in Hz") ("ref", po::value(&ref)->default_value("internal"), "clock reference (internal, external, mimo)") + ("otw", po::value(&otw)->default_value("sc16"), "specify the over-the-wire sample mode") ; po::variables_map vm; po::store(po::parse_command_line(argc, argv, desc), vm); @@ -193,7 +194,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ //create a transmit streamer //linearly map channels (index0 = channel0, index1 = channel1, ...) - uhd::stream_args_t stream_args("fc32"); + uhd::stream_args_t stream_args("fc32", otw); for (size_t chan = 0; chan < usrp->get_tx_num_channels(); chan++) stream_args.channels.push_back(chan); //linear mapping uhd::tx_streamer::sptr tx_stream = usrp->get_tx_stream(stream_args); -- cgit v1.2.3 From 42e906a3345c772f71b57126f754f87c0112d740 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Mon, 13 Feb 2012 10:21:46 -0800 Subject: dsp rework: minor simplification in vita_tx_deframer all n-series devices meet timing --- usrp2/vrt/vita_tx_deframer.v | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/usrp2/vrt/vita_tx_deframer.v b/usrp2/vrt/vita_tx_deframer.v index b187ab97c..6919da11a 100644 --- a/usrp2/vrt/vita_tx_deframer.v +++ b/usrp2/vrt/vita_tx_deframer.v @@ -85,7 +85,6 @@ module vita_tx_deframer localparam VITA_TICS = 6; localparam VITA_TICS2 = 7; localparam VITA_PAYLOAD = 8; - localparam VITA_STORE = 9; localparam VITA_TRAILER = 10; localparam VITA_DUMP = 11; @@ -205,15 +204,13 @@ module vita_tx_deframer VITA_DUMP : if(eof) vita_state <= (USE_TRANS_HEADER==1) ? VITA_TRANS_HEADER : VITA_HEADER; - VITA_STORE : - ; default : vita_state <= (USE_TRANS_HEADER==1) ? VITA_TRANS_HEADER : VITA_HEADER; endcase // case (vita_state) end //valid read - assign line_done = (vector_phase == numchan); + assign line_done = (MAXCHAN == 1)? 1 : (vector_phase == numchan); wire [FIFOWIDTH-1:0] fifo_i; reg [63:0] send_time; -- cgit v1.2.3 From df946523010929944cab487669defec2059951d4 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Mon, 13 Feb 2012 19:22:26 -0800 Subject: uhd: inline time spec accessors for minor improvement --- host/include/uhd/types/time_spec.hpp | 8 ++++++++ host/lib/types/time_spec.cpp | 25 ++++++++++--------------- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/host/include/uhd/types/time_spec.hpp b/host/include/uhd/types/time_spec.hpp index cf8588c5b..e7d7d5ab4 100644 --- a/host/include/uhd/types/time_spec.hpp +++ b/host/include/uhd/types/time_spec.hpp @@ -128,6 +128,14 @@ namespace uhd{ //! Implement less_than_comparable interface UHD_API bool operator<(const time_spec_t &, const time_spec_t &); + UHD_INLINE time_t time_spec_t::get_full_secs(void) const{ + return this->_full_secs; + } + + UHD_INLINE double time_spec_t::get_frac_secs(void) const{ + return this->_frac_secs; + } + } //namespace uhd #endif /* INCLUDED_UHD_TYPES_TIME_SPEC_HPP */ diff --git a/host/lib/types/time_spec.cpp b/host/lib/types/time_spec.cpp index 0c3a3dbea..14b9c988a 100644 --- a/host/lib/types/time_spec.cpp +++ b/host/lib/types/time_spec.cpp @@ -72,8 +72,11 @@ time_spec_t time_spec_t::get_system_time(void){ * Time spec constructors **********************************************************************/ #define time_spec_init(full, frac) { \ - _full_secs = full + time_t(frac); \ - _frac_secs = frac - time_t(frac); \ + const time_t _full = time_t(full); \ + const double _frac = double(frac); \ + const int _frac_int = int(_frac); \ + _full_secs = _full + _frac_int; \ + _frac_secs = _frac - _frac_int; \ if (_frac_secs < 0) {\ _full_secs -= 1; \ _frac_secs += 1; \ @@ -115,15 +118,7 @@ long long time_spec_t::to_ticks(double tick_rate) const{ } double time_spec_t::get_real_secs(void) const{ - return this->_full_secs + this->_frac_secs; -} - -time_t time_spec_t::get_full_secs(void) const{ - return this->_full_secs; -} - -double time_spec_t::get_frac_secs(void) const{ - return this->_frac_secs; + return this->get_full_secs() + this->get_frac_secs(); } /*********************************************************************** @@ -131,16 +126,16 @@ double time_spec_t::get_frac_secs(void) const{ **********************************************************************/ time_spec_t &time_spec_t::operator+=(const time_spec_t &rhs){ time_spec_init( - this->_full_secs + rhs.get_full_secs(), - this->_frac_secs + rhs.get_frac_secs() + this->get_full_secs() + rhs.get_full_secs(), + this->get_frac_secs() + rhs.get_frac_secs() ); return *this; } time_spec_t &time_spec_t::operator-=(const time_spec_t &rhs){ time_spec_init( - this->_full_secs - rhs.get_full_secs(), - this->_frac_secs - rhs.get_frac_secs() + this->get_full_secs() - rhs.get_full_secs(), + this->get_frac_secs() - rhs.get_frac_secs() ); return *this; } -- cgit v1.2.3 From 2f21932ae1e8f7cc584eff791dcd67a8ea2ca144 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Tue, 14 Feb 2012 11:37:12 -0800 Subject: dsp rework: minor fix sph, set has time spec for tsf only --- host/lib/transport/super_recv_packet_handler.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/host/lib/transport/super_recv_packet_handler.hpp b/host/lib/transport/super_recv_packet_handler.hpp index 939e7aeb3..74fbe82fb 100644 --- a/host/lib/transport/super_recv_packet_handler.hpp +++ b/host/lib/transport/super_recv_packet_handler.hpp @@ -408,7 +408,7 @@ private: case PACKET_INLINE_MESSAGE: std::swap(curr_info, next_info); //save progress from curr -> next - curr_info.metadata.has_time_spec = next_info[index].ifpi.has_tsi and next_info[index].ifpi.has_tsf; + curr_info.metadata.has_time_spec = next_info[index].ifpi.has_tsf; curr_info.metadata.time_spec = next_info[index].time; curr_info.metadata.more_fragments = false; curr_info.metadata.fragment_offset = 0; @@ -469,7 +469,7 @@ private: } //set the metadata from the buffer information at index zero - curr_info.metadata.has_time_spec = curr_info[0].ifpi.has_tsi and curr_info[0].ifpi.has_tsf; + curr_info.metadata.has_time_spec = curr_info[0].ifpi.has_tsf; curr_info.metadata.time_spec = curr_info[0].time; curr_info.metadata.more_fragments = false; curr_info.metadata.fragment_offset = 0; -- cgit v1.2.3 From 8bd255c5f6ed586603727ffaa56d1eeb325458af Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Tue, 14 Feb 2012 12:03:52 -0800 Subject: b100: added transport flushes and moved around reset code --- host/lib/usrp/b100/b100_impl.cpp | 15 ++++----------- host/lib/usrp/b100/b100_impl.hpp | 2 -- host/lib/usrp/common/fx2_ctrl.hpp | 3 +++ 3 files changed, 7 insertions(+), 13 deletions(-) diff --git a/host/lib/usrp/b100/b100_impl.cpp b/host/lib/usrp/b100/b100_impl.cpp index 4c9f93249..af10590ac 100644 --- a/host/lib/usrp/b100/b100_impl.cpp +++ b/host/lib/usrp/b100/b100_impl.cpp @@ -181,9 +181,9 @@ b100_impl::b100_impl(const device_addr_t &device_addr){ //load FPGA image, gpif is disabled while loading this->enable_gpif(false); _fx2_ctrl->usrp_load_fpga(b100_fpga_image); + _fx2_ctrl->usrp_fpga_reset(false); //active low reset + _fx2_ctrl->usrp_fpga_reset(true); this->enable_gpif(true); - this->set_reset_fpga(1); - this->set_reset_fpga(0); //create the control transport device_addr_t ctrl_xport_args; @@ -198,12 +198,12 @@ b100_impl::b100_impl(const device_addr_t &device_addr){ 3, 4, //interface, endpoint ctrl_xport_args ); + while (_ctrl_transport->get_recv_buff(0.0)){} //flush ctrl xport //////////////////////////////////////////////////////////////////// // Initialize FPGA wishbone communication //////////////////////////////////////////////////////////////////// _fpga_ctrl = b100_ctrl::make(_ctrl_transport); - this->reset_gpif(6); //always reset first to ensure communication _fpga_ctrl->poke32(B100_REG_GLOBAL_RESET, 0); //global fpga reset this->check_fpga_compat(); //check after reset and making control @@ -234,6 +234,7 @@ b100_impl::b100_impl(const device_addr_t &device_addr){ ), B100_MAX_PKT_BYTE_LIMIT ); + while (_data_transport->get_recv_buff(0.0)){} //flush data xport //////////////////////////////////////////////////////////////////// // Initialize the properties tree @@ -515,10 +516,6 @@ void b100_impl::update_clock_source(const std::string &source){ } ////////////////// some GPIF preparation related stuff ///////////////// -void b100_impl::reset_gpif(const boost::uint16_t ep) { - _fx2_ctrl->usrp_control_write(VRQ_RESET_GPIF, ep, ep, 0, 0); -} - void b100_impl::enable_gpif(const bool en) { _fx2_ctrl->usrp_control_write(VRQ_ENABLE_GPIF, en ? 1 : 0, 0, 0, 0); } @@ -527,10 +524,6 @@ void b100_impl::clear_fpga_fifo(void) { _fx2_ctrl->usrp_control_write(VRQ_CLEAR_FPGA_FIFO, 0, 0, 0, 0); } -void b100_impl::set_reset_fpga(const bool en) { - _fx2_ctrl->usrp_control_write(VRQ_FPGA_SET_RESET, en ? 0 : 1, 0, 0, 0); -} - sensor_value_t b100_impl::get_ref_locked(void){ const bool lock = _clock_ctrl->get_locked(); return sensor_value_t("Ref", lock, "locked", "unlocked"); diff --git a/host/lib/usrp/b100/b100_impl.hpp b/host/lib/usrp/b100/b100_impl.hpp index b71b65562..eab9c750b 100644 --- a/host/lib/usrp/b100/b100_impl.hpp +++ b/host/lib/usrp/b100/b100_impl.hpp @@ -123,10 +123,8 @@ private: void update_rx_subdev_spec(const uhd::usrp::subdev_spec_t &); void update_tx_subdev_spec(const uhd::usrp::subdev_spec_t &); void update_clock_source(const std::string &); - void reset_gpif(const boost::uint16_t); void enable_gpif(const bool); void clear_fpga_fifo(void); - void set_reset_fpga(const bool en); void handle_async_message(uhd::transport::managed_recv_buffer::sptr); uhd::sensor_value_t get_ref_locked(void); void set_rx_fe_corrections(const double); diff --git a/host/lib/usrp/common/fx2_ctrl.hpp b/host/lib/usrp/common/fx2_ctrl.hpp index 691d64275..5e28e8081 100644 --- a/host/lib/usrp/common/fx2_ctrl.hpp +++ b/host/lib/usrp/common/fx2_ctrl.hpp @@ -116,6 +116,9 @@ public: //! enable/disable the tx path virtual void usrp_tx_enable(bool on) = 0; + + //! reset the fpga + virtual void usrp_fpga_reset(bool on) = 0; }; }} //namespace uhd::usrp -- cgit v1.2.3 From 1463a78fd2ebac1985182dede9c3ec1af11a3799 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Tue, 14 Feb 2012 15:01:15 -0800 Subject: b100: reset/reenumerate fx2 for bad endpoint state Determine state of control endpoint, re-enumerate to put in a known state, rerun some initialization code. --- host/lib/usrp/b100/b100_impl.cpp | 19 +++++++++++++++++++ host/lib/usrp/common/fx2_ctrl.cpp | 9 +++++++++ host/lib/usrp/common/fx2_ctrl.hpp | 3 +++ 3 files changed, 31 insertions(+) diff --git a/host/lib/usrp/b100/b100_impl.cpp b/host/lib/usrp/b100/b100_impl.cpp index af10590ac..8b55494c5 100644 --- a/host/lib/usrp/b100/b100_impl.cpp +++ b/host/lib/usrp/b100/b100_impl.cpp @@ -150,6 +150,10 @@ UHD_STATIC_BLOCK(register_b100_device){ * Structors **********************************************************************/ b100_impl::b100_impl(const device_addr_t &device_addr){ + size_t initialization_count = 0; + b100_impl_constructor_begin: + initialization_count++; + _tree = property_tree::make(); //extract the FPGA path for the B100 @@ -205,6 +209,21 @@ b100_impl::b100_impl(const device_addr_t &device_addr){ //////////////////////////////////////////////////////////////////// _fpga_ctrl = b100_ctrl::make(_ctrl_transport); _fpga_ctrl->poke32(B100_REG_GLOBAL_RESET, 0); //global fpga reset + //perform a test peek operation + try{ + _fpga_ctrl->peek32(0); + } + //try reset once in the case of failure + catch(const uhd::exception &e){ + if (initialization_count > 1) throw; + UHD_MSG(warning) << + "The control endpoint was left in a bad state.\n" + "Attempting endpoint re-enumeration...\n" << std::endl; + _fpga_ctrl.reset(); + _ctrl_transport.reset(); + _fx2_ctrl->usrp_fx2_reset(); + goto b100_impl_constructor_begin; + } this->check_fpga_compat(); //check after reset and making control //////////////////////////////////////////////////////////////////// diff --git a/host/lib/usrp/common/fx2_ctrl.cpp b/host/lib/usrp/common/fx2_ctrl.cpp index baf8f5e68..7b8920eb1 100644 --- a/host/lib/usrp/common/fx2_ctrl.cpp +++ b/host/lib/usrp/common/fx2_ctrl.cpp @@ -139,6 +139,15 @@ public: _ctrl_transport = ctrl_transport; } + void usrp_fx2_reset(void){ + unsigned char reset_y = 1; + unsigned char reset_n = 0; + usrp_control_write(FX2_FIRMWARE_LOAD, 0xe600, 0, &reset_y, 1); + usrp_control_write(FX2_FIRMWARE_LOAD, 0xe600, 0, &reset_n, 1); + //wait for things to settle + boost::this_thread::sleep(boost::posix_time::milliseconds(2000)); + } + void usrp_load_firmware(std::string filestring, bool force) { const char *filename = filestring.c_str(); diff --git a/host/lib/usrp/common/fx2_ctrl.hpp b/host/lib/usrp/common/fx2_ctrl.hpp index 5e28e8081..f2e060862 100644 --- a/host/lib/usrp/common/fx2_ctrl.hpp +++ b/host/lib/usrp/common/fx2_ctrl.hpp @@ -39,6 +39,9 @@ public: //! Call init after the fpga is loaded virtual void usrp_init(void) = 0; + //! For emergency situations + virtual void usrp_fx2_reset(void) = 0; + /*! * Load firmware in Intel HEX Format onto device * \param filename name of firmware file -- cgit v1.2.3 From 82d38412e2688bb41967b301ce0de084e82cdeef Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Tue, 14 Feb 2012 16:34:36 -0800 Subject: b100: use frame boundary to calculate frame size --- host/lib/transport/usb_zero_copy_wrapper.cpp | 6 ++++-- host/lib/usrp/b100/io_impl.cpp | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/host/lib/transport/usb_zero_copy_wrapper.cpp b/host/lib/transport/usb_zero_copy_wrapper.cpp index 07105cad3..690e5aaa2 100644 --- a/host/lib/transport/usb_zero_copy_wrapper.cpp +++ b/host/lib/transport/usb_zero_copy_wrapper.cpp @@ -112,6 +112,7 @@ class usb_zero_copy_wrapper : public usb_zero_copy{ public: usb_zero_copy_wrapper(sptr usb_zc, const size_t frame_boundary): _internal_zc(usb_zc), + _frame_boundary(frame_boundary), _available_recv_buffs(this->get_num_recv_frames()), _mrb_pool(this->get_num_recv_frames(), usb_zero_copy_wrapper_mrb(_available_recv_buffs)), _the_only_msb(usb_zero_copy_wrapper_msb(usb_zc, frame_boundary)) @@ -157,7 +158,7 @@ public: } size_t get_recv_frame_size(void) const{ - return _internal_zc->get_recv_frame_size(); + return std::min(_frame_boundary, _internal_zc->get_recv_frame_size()); } managed_send_buffer::sptr get_send_buff(double timeout){ @@ -169,11 +170,12 @@ public: } size_t get_send_frame_size(void) const{ - return _internal_zc->get_send_frame_size(); + return std::min(_frame_boundary, _internal_zc->get_send_frame_size()); } private: sptr _internal_zc; + size_t _frame_boundary; bounded_buffer _available_recv_buffs; std::vector _mrb_pool; usb_zero_copy_wrapper_msb _the_only_msb; diff --git a/host/lib/usrp/b100/io_impl.cpp b/host/lib/usrp/b100/io_impl.cpp index d7effcac1..6f8d3fb52 100644 --- a/host/lib/usrp/b100/io_impl.cpp +++ b/host/lib/usrp/b100/io_impl.cpp @@ -206,7 +206,7 @@ rx_streamer::sptr b100_impl::get_rx_stream(const uhd::stream_args_t &args_){ - sizeof(vrt::if_packet_info_t().cid) //no class id ever used - sizeof(vrt::if_packet_info_t().tsi) //no int time ever used ; - const size_t bpp = B100_MAX_PKT_BYTE_LIMIT - hdr_size; + const size_t bpp = _data_transport->get_recv_frame_size() - hdr_size; const size_t bpi = convert::get_bytes_per_item(args.otw_format); const size_t spp = unsigned(args.args.cast("spp", bpp/bpi)); @@ -263,7 +263,7 @@ tx_streamer::sptr b100_impl::get_tx_stream(const uhd::stream_args_t &args_){ - sizeof(vrt::if_packet_info_t().cid) //no class id ever used - sizeof(vrt::if_packet_info_t().tsi) //no int time ever used ; - static const size_t bpp = B100_MAX_PKT_BYTE_LIMIT - hdr_size; + static const size_t bpp = _data_transport->get_send_frame_size() - hdr_size; const size_t spp = bpp/convert::get_bytes_per_item(args.otw_format); //make the new streamer given the samples per packet -- cgit v1.2.3 From 3060006b35859c8766e00d3b234b51a19aa8595f Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Tue, 14 Feb 2012 18:26:03 -0800 Subject: uhd: added async md user payload and common utils --- host/include/uhd/types/metadata.hpp | 15 ++++-- host/lib/usrp/b100/io_impl.cpp | 26 +++++----- host/lib/usrp/common/async_packet_handler.hpp | 71 +++++++++++++++++++++++++++ host/lib/usrp/e100/io_impl.cpp | 18 ++----- host/lib/usrp/usrp2/io_impl.cpp | 18 ++----- 5 files changed, 100 insertions(+), 48 deletions(-) create mode 100644 host/lib/usrp/common/async_packet_handler.hpp diff --git a/host/include/uhd/types/metadata.hpp b/host/include/uhd/types/metadata.hpp index 269c77c7c..788999900 100644 --- a/host/include/uhd/types/metadata.hpp +++ b/host/include/uhd/types/metadata.hpp @@ -1,5 +1,5 @@ // -// Copyright 2010 Ettus Research LLC +// Copyright 2010-2012 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 @@ -20,6 +20,7 @@ #include #include +#include namespace uhd{ @@ -140,13 +141,21 @@ namespace uhd{ EVENT_CODE_UNDERFLOW = 0x2, //! Packet loss between host and device. EVENT_CODE_SEQ_ERROR = 0x4, - //! Packet had time that was late (or too early). + //! Packet had time that was late. EVENT_CODE_TIME_ERROR = 0x8, //! Underflow occurred inside a packet. EVENT_CODE_UNDERFLOW_IN_PACKET = 0x10, //! Packet loss within a burst. - EVENT_CODE_SEQ_ERROR_IN_BURST = 0x20 + EVENT_CODE_SEQ_ERROR_IN_BURST = 0x20, + //! Some kind of custom user payload + EVENT_CODE_USER_PAYLOAD = 0x40 } event_code; + + /*! + * A special payload populated by custom FPGA fabric. + */ + boost::uint32_t user_payload[4]; + }; } //namespace uhd diff --git a/host/lib/usrp/b100/io_impl.cpp b/host/lib/usrp/b100/io_impl.cpp index 6f8d3fb52..674380cca 100644 --- a/host/lib/usrp/b100/io_impl.cpp +++ b/host/lib/usrp/b100/io_impl.cpp @@ -17,6 +17,7 @@ #include "recv_packet_demuxer.hpp" #include "validate_subdev_spec.hpp" +#include "async_packet_handler.hpp" #include "../../transport/super_recv_packet_handler.hpp" #include "../../transport/super_send_packet_handler.hpp" #include "usrp_commands.h" @@ -47,6 +48,7 @@ struct b100_impl::io_impl{ zero_copy_if::sptr data_transport; bounded_buffer async_msg_fifo; recv_packet_demuxer::sptr demuxer; + double tick_rate; }; /*********************************************************************** @@ -81,24 +83,16 @@ void b100_impl::handle_async_message(managed_recv_buffer::sptr rbuf){ } if (if_packet_info.sid == B100_TX_ASYNC_SID and if_packet_info.packet_type != vrt::if_packet_info_t::PACKET_TYPE_DATA){ + //fill in the async metadata async_metadata_t metadata; - metadata.channel = 0; - metadata.has_time_spec = if_packet_info.has_tsf; - metadata.time_spec = time_spec_t::from_ticks(if_packet_info.tsf, _clock_ctrl->get_fpga_clock_rate()); - metadata.event_code = async_metadata_t::event_code_t(sph::get_context_code(vrt_hdr, if_packet_info)); + load_metadata_from_buff(uhd::wtohx, metadata, if_packet_info, vrt_hdr, _io_impl->tick_rate); + + //push the message onto the queue _io_impl->async_msg_fifo.push_with_pop_on_full(metadata); - if (metadata.event_code & - ( async_metadata_t::EVENT_CODE_UNDERFLOW - | async_metadata_t::EVENT_CODE_UNDERFLOW_IN_PACKET) - ) UHD_MSG(fastpath) << "U"; - else if (metadata.event_code & - ( async_metadata_t::EVENT_CODE_SEQ_ERROR - | async_metadata_t::EVENT_CODE_SEQ_ERROR_IN_BURST) - ) UHD_MSG(fastpath) << "S"; - else if (metadata.event_code & - async_metadata_t::EVENT_CODE_TIME_ERROR - ) UHD_MSG(fastpath) << "L"; + + //print some fastpath messages + standard_async_msg_prints(metadata); } else UHD_MSG(error) << "Unknown async packet" << std::endl; } @@ -117,6 +111,8 @@ void b100_impl::update_rates(void){ } void b100_impl::update_tick_rate(const double rate){ + _io_impl->tick_rate = rate; + //update the tick rate on all existing streamers -> thread safe for (size_t i = 0; i < _rx_streamers.size(); i++){ boost::shared_ptr my_streamer = diff --git a/host/lib/usrp/common/async_packet_handler.hpp b/host/lib/usrp/common/async_packet_handler.hpp new file mode 100644 index 000000000..fef03483f --- /dev/null +++ b/host/lib/usrp/common/async_packet_handler.hpp @@ -0,0 +1,71 @@ +// +// Copyright 2012 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 . +// + +#ifndef INCLUDED_LIBUHD_USRP_COMMON_ASYNC_PACKET_HANDLER_HPP +#define INCLUDED_LIBUHD_USRP_COMMON_ASYNC_PACKET_HANDLER_HPP + +#include +#include +#include +#include +#include + +namespace uhd{ namespace usrp{ + + template + void load_metadata_from_buff( + const to_host_type &to_host, + async_metadata_t &metadata, + const transport::vrt::if_packet_info_t &if_packet_info, + const boost::uint32_t *vrt_hdr, + const double tick_rate, + const size_t channel = 0 + ){ + const boost::uint32_t *payload = vrt_hdr + if_packet_info.num_header_words32; + + //load into metadata + metadata.channel = channel; + metadata.has_time_spec = if_packet_info.has_tsf; + metadata.time_spec = time_spec_t::from_ticks(if_packet_info.tsf, tick_rate); + metadata.event_code = async_metadata_t::event_code_t(to_host(payload[0]) & 0xff); + + //load user payload + for (size_t i = 1; i < if_packet_info.num_payload_words32; i++){ + if (i-1 == 4) break; //limit of 4 words32 + metadata.user_payload[i-1] = to_host(payload[i]); + } + } + + UHD_INLINE void standard_async_msg_prints(const async_metadata_t &metadata) + { + if (metadata.event_code & + ( async_metadata_t::EVENT_CODE_UNDERFLOW + | async_metadata_t::EVENT_CODE_UNDERFLOW_IN_PACKET) + ) UHD_MSG(fastpath) << "U"; + else if (metadata.event_code & + ( async_metadata_t::EVENT_CODE_SEQ_ERROR + | async_metadata_t::EVENT_CODE_SEQ_ERROR_IN_BURST) + ) UHD_MSG(fastpath) << "S"; + else if (metadata.event_code & + async_metadata_t::EVENT_CODE_TIME_ERROR + ) UHD_MSG(fastpath) << "L"; + } + + +}} //namespace uhd::usrp + +#endif /* INCLUDED_LIBUHD_USRP_COMMON_ASYNC_PACKET_HANDLER_HPP */ diff --git a/host/lib/usrp/e100/io_impl.cpp b/host/lib/usrp/e100/io_impl.cpp index b090e45c7..e9608125f 100644 --- a/host/lib/usrp/e100/io_impl.cpp +++ b/host/lib/usrp/e100/io_impl.cpp @@ -17,6 +17,7 @@ #include "recv_packet_demuxer.hpp" #include "validate_subdev_spec.hpp" +#include "async_packet_handler.hpp" #include "../../transport/super_recv_packet_handler.hpp" #include "../../transport/super_send_packet_handler.hpp" #include //ioctl structures and constants @@ -123,26 +124,13 @@ void e100_impl::io_impl::handle_irq(void){ //fill in the async metadata async_metadata_t metadata; - metadata.channel = 0; - metadata.has_time_spec = if_packet_info.has_tsf; - metadata.time_spec = time_spec_t::from_ticks(if_packet_info.tsf, tick_rate); - metadata.event_code = async_metadata_t::event_code_t(sph::get_context_code(data.buf, if_packet_info)); + load_metadata_from_buff(uhd::wtohx, metadata, if_packet_info, data.buf, tick_rate); //push the message onto the queue async_msg_fifo.push_with_pop_on_full(metadata); //print some fastpath messages - if (metadata.event_code & - ( async_metadata_t::EVENT_CODE_UNDERFLOW - | async_metadata_t::EVENT_CODE_UNDERFLOW_IN_PACKET) - ) UHD_MSG(fastpath) << "U"; - else if (metadata.event_code & - ( async_metadata_t::EVENT_CODE_SEQ_ERROR - | async_metadata_t::EVENT_CODE_SEQ_ERROR_IN_BURST) - ) UHD_MSG(fastpath) << "S"; - else if (metadata.event_code & - async_metadata_t::EVENT_CODE_TIME_ERROR - ) UHD_MSG(fastpath) << "L"; + standard_async_msg_prints(metadata); } //prepare for the next round diff --git a/host/lib/usrp/usrp2/io_impl.cpp b/host/lib/usrp/usrp2/io_impl.cpp index 221b747cb..d32ffb62c 100644 --- a/host/lib/usrp/usrp2/io_impl.cpp +++ b/host/lib/usrp/usrp2/io_impl.cpp @@ -16,6 +16,7 @@ // #include "validate_subdev_spec.hpp" +#include "async_packet_handler.hpp" #include "../../transport/super_recv_packet_handler.hpp" #include "../../transport/super_send_packet_handler.hpp" #include "usrp2_impl.hpp" @@ -202,10 +203,7 @@ void usrp2_impl::io_impl::recv_pirate_loop( //fill in the async metadata async_metadata_t metadata; - metadata.channel = index; - metadata.has_time_spec = if_packet_info.has_tsf; - metadata.time_spec = time_spec_t::from_ticks(if_packet_info.tsf, tick_rate); - metadata.event_code = async_metadata_t::event_code_t(sph::get_context_code(vrt_hdr, if_packet_info)); + load_metadata_from_buff(uhd::ntohx, metadata, if_packet_info, vrt_hdr, tick_rate, index); //catch the flow control packets and react if (metadata.event_code == 0){ @@ -216,17 +214,7 @@ void usrp2_impl::io_impl::recv_pirate_loop( //else UHD_MSG(often) << "metadata.event_code " << metadata.event_code << std::endl; async_msg_fifo.push_with_pop_on_full(metadata); - if (metadata.event_code & - ( async_metadata_t::EVENT_CODE_UNDERFLOW - | async_metadata_t::EVENT_CODE_UNDERFLOW_IN_PACKET) - ) UHD_MSG(fastpath) << "U"; - else if (metadata.event_code & - ( async_metadata_t::EVENT_CODE_SEQ_ERROR - | async_metadata_t::EVENT_CODE_SEQ_ERROR_IN_BURST) - ) UHD_MSG(fastpath) << "S"; - else if (metadata.event_code & - async_metadata_t::EVENT_CODE_TIME_ERROR - ) UHD_MSG(fastpath) << "L"; + standard_async_msg_prints(metadata); } else{ //TODO unknown received packet, may want to print error... -- cgit v1.2.3 From 831213bd57f0ac41e88f4b741f22885fb8316399 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Wed, 15 Feb 2012 15:44:24 -0800 Subject: dsp rework: added flusher to vita tx chain on clear --- usrp2/vrt/vita_tx_chain.v | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/usrp2/vrt/vita_tx_chain.v b/usrp2/vrt/vita_tx_chain.v index 9b478081f..82a43d57a 100644 --- a/usrp2/vrt/vita_tx_chain.v +++ b/usrp2/vrt/vita_tx_chain.v @@ -49,27 +49,35 @@ module vita_tx_chain wire clear_seqnum; wire [31:0] current_seqnum; - wire clear; + wire clear, flush; assign clear_o = clear; assign underrun = error; assign message = error_code; - - setting_reg #(.my_addr(BASE+1)) sr + + setting_reg #(.my_addr(BASE+0), .width(1)) sr (.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr), - .in(set_data),.out(),.changed(clear)); + .in(set_data),.out(flush),.changed(clear)); setting_reg #(.my_addr(BASE+2), .at_reset(0)) sr_streamid (.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr), .in(set_data),.out(streamid),.changed(clear_seqnum)); + //flush control - full rate vacuum of input until flush cleared + wire tx_dst_rdy_int, tx_src_rdy_int; + wire [35:0] tx_data_int; + valve36 flusher_valve + (.clk(clk), .reset(reset), .clear(clear & flush), .shutoff(flush), + .data_i(tx_data_i), .src_rdy_i(tx_src_rdy_i), .dst_rdy_o(tx_dst_rdy_o), + .data_o(tx_data_int), .src_rdy_o(tx_src_rdy_int), .dst_rdy_i(tx_dst_rdy_int)); + wire [35:0] tx_data_int1; wire tx_src_rdy_int1, tx_dst_rdy_int1; generate if (FIFOSIZE==0) begin - assign tx_data_int1 = tx_data_i; - assign tx_src_rdy_int1 = tx_src_rdy_i; - assign tx_dst_rdy_o = tx_dst_rdy_int1; + assign tx_data_int1 = tx_data_int; + assign tx_src_rdy_int1 = tx_src_rdy_int; + assign tx_dst_rdy_int = tx_dst_rdy_int1; end else begin wire [FIFOSIZE-1:0] access_adr, access_len; @@ -84,7 +92,7 @@ module vita_tx_chain .access_skip_read(access_skip_read), .access_adr(access_adr), .access_len(access_len), .access_dat_i(dsp_to_buf), .access_dat_o(buf_to_dsp), - .data_i(tx_data_i), .src_rdy_i(tx_src_rdy_i), .dst_rdy_o(tx_dst_rdy_o), + .data_i(tx_data_int), .src_rdy_i(tx_src_rdy_int), .dst_rdy_o(tx_dst_rdy_int), .data_o(tx_data_int0), .src_rdy_o(tx_src_rdy_int0), .dst_rdy_i(tx_dst_rdy_int0)); vita_tx_engine_glue #(.DSPNO(DSP_NUMBER), .MAIN_SETTINGS_BASE(BASE+1), .BUF_SIZE(FIFOSIZE), .HEADER_OFFSET(USE_TRANS_HEADER)) dspengine_tx -- cgit v1.2.3 From 59d06f718130c19f808d898f438a1fcb9cdefc04 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Wed, 15 Feb 2012 15:44:44 -0800 Subject: dsp rework: added flusher to vita tx chain on clear --- host/lib/usrp/cores/rx_dsp_core_200.cpp | 2 +- host/lib/usrp/cores/tx_dsp_core_200.cpp | 11 +++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/host/lib/usrp/cores/rx_dsp_core_200.cpp b/host/lib/usrp/cores/rx_dsp_core_200.cpp index cebf92f6a..0996952ff 100644 --- a/host/lib/usrp/cores/rx_dsp_core_200.cpp +++ b/host/lib/usrp/cores/rx_dsp_core_200.cpp @@ -1,5 +1,5 @@ // -// Copyright 2011 Ettus Research LLC +// Copyright 2011-2012 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 diff --git a/host/lib/usrp/cores/tx_dsp_core_200.cpp b/host/lib/usrp/cores/tx_dsp_core_200.cpp index e25528213..7f02d59ca 100644 --- a/host/lib/usrp/cores/tx_dsp_core_200.cpp +++ b/host/lib/usrp/cores/tx_dsp_core_200.cpp @@ -1,5 +1,5 @@ // -// Copyright 2011 Ettus Research LLC +// Copyright 2011-2012 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 @@ -23,6 +23,7 @@ #include #include #include +#include //sleep #include #include @@ -30,12 +31,12 @@ #define REG_DSP_TX_SCALE_IQ _dsp_base + 4 #define REG_DSP_TX_INTERP _dsp_base + 8 -#define REG_TX_CTRL_CLEAR _ctrl_base + 4 +#define REG_TX_CTRL_CLEAR _ctrl_base + 0 +#define REG_TX_CTRL_FORMAT _ctrl_base + 4 #define REG_TX_CTRL_REPORT_SID _ctrl_base + 8 #define REG_TX_CTRL_POLICY _ctrl_base + 12 #define REG_TX_CTRL_CYCLES_PER_UP _ctrl_base + 16 #define REG_TX_CTRL_PACKETS_PER_UP _ctrl_base + 20 -#define REG_TX_CTRL_FORMAT REG_TX_CTRL_CLEAR //re-use clear address #define FLAG_TX_CTRL_POLICY_WAIT (0x1 << 0) #define FLAG_TX_CTRL_POLICY_NEXT_PACKET (0x1 << 1) @@ -69,7 +70,9 @@ public: } void clear(void){ - _iface->poke32(REG_TX_CTRL_CLEAR, 1); //reset + _iface->poke32(REG_TX_CTRL_CLEAR, 1); //reset and flush technique + boost::this_thread::sleep(boost::posix_time::milliseconds(10)); + _iface->poke32(REG_TX_CTRL_CLEAR, 0); _iface->poke32(REG_TX_CTRL_REPORT_SID, _sid); } -- cgit v1.2.3 From 2ad9e0ad6520adda571de8b1afe9d975cc09d311 Mon Sep 17 00:00:00 2001 From: Matt Ettus Date: Thu, 16 Feb 2012 19:08:31 -0800 Subject: dsp_engine: fix for upper/lower swap, and odd length packets --- usrp2/sdr_lib/dspengine_8to16.v | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/usrp2/sdr_lib/dspengine_8to16.v b/usrp2/sdr_lib/dspengine_8to16.v index ca808d2a6..bc0aa0352 100644 --- a/usrp2/sdr_lib/dspengine_8to16.v +++ b/usrp2/sdr_lib/dspengine_8to16.v @@ -44,13 +44,14 @@ module dspengine_8to16 localparam DSP_IDLE_RD = 1; localparam DSP_PARSE_HEADER = 2; localparam DSP_READ = 3; - localparam DSP_WRITE_1 = 4; - localparam DSP_WRITE_0 = 5; - localparam DSP_READ_TRAILER = 6; - localparam DSP_WRITE_TRAILER = 7; - localparam DSP_WRITE_HEADER = 8; - localparam DSP_DONE = 9; - + localparam DSP_READ_WAIT = 4; + localparam DSP_WRITE_1 = 5; + localparam DSP_WRITE_0 = 6; + localparam DSP_READ_TRAILER = 7; + localparam DSP_WRITE_TRAILER = 8; + localparam DSP_WRITE_HEADER = 9; + localparam DSP_DONE = 10; + // Parse VITA header wire is_if_data = (access_dat_i[31:29] == 3'b000); wire has_streamid = access_dat_i[28]; @@ -74,13 +75,13 @@ module dspengine_8to16 wire [15:0] data_in_lenx2 = {data_in_len[14:0], 1'b0} - is_odd; reg [7:0] i8_0, q8_0; - wire [7:0] i8_1 = access_dat_i[15:8]; - wire [7:0] q8_1 = access_dat_i[7:0]; + wire [7:0] i8_1 = access_dat_i[31:24]; + wire [7:0] q8_1 = access_dat_i[23:16]; reg skip; always @(posedge clk) - { i8_0, q8_0 } <= access_dat_i[31:16]; + { i8_0, q8_0 } <= access_dat_i[15:0]; always @(posedge clk) if(reset | clear) @@ -137,23 +138,26 @@ module dspengine_8to16 DSP_READ : begin - dsp_state <= DSP_WRITE_1; read_adr <= read_adr - 1; + if(odd) + dsp_state <= DSP_READ_WAIT; + else + dsp_state <= DSP_WRITE_1; + odd <= 0; end + DSP_READ_WAIT : + dsp_state <= DSP_WRITE_0; + DSP_WRITE_1 : begin write_adr <= write_adr - 1; - odd <= 0; if(write_adr == (hdr_length_reg+HEADER_OFFSET)) begin write_adr <= HEADER_OFFSET; dsp_state <= DSP_WRITE_HEADER; end - else if(odd) - dsp_state <= DSP_READ; - else - dsp_state <= DSP_WRITE_0; + dsp_state <= DSP_WRITE_0; end DSP_WRITE_0 : -- cgit v1.2.3 From 2e37dd87234e5beddd6f76fcda714916f761f812 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Fri, 17 Feb 2012 16:52:41 -0800 Subject: dsp rework: fix dspengine_8to16 to handle padded packets --- usrp2/sdr_lib/dspengine_8to16.v | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/usrp2/sdr_lib/dspengine_8to16.v b/usrp2/sdr_lib/dspengine_8to16.v index bc0aa0352..85187d78d 100644 --- a/usrp2/sdr_lib/dspengine_8to16.v +++ b/usrp2/sdr_lib/dspengine_8to16.v @@ -102,8 +102,7 @@ module dspengine_8to16 DSP_PARSE_HEADER : begin has_trailer_reg <= has_trailer; - new_header[31:16] <= access_dat_i[31:16]; - new_header[15:0] <= access_len-HEADER_OFFSET; + new_header[31:0] <= access_dat_i[31:0]; hdr_length_reg <= hdr_length; if(~is_if_data | ~convert | ~has_trailer) // ~convert is valid (16 bit mode) but both ~trailer and ~is_if_data are both @@ -111,10 +110,10 @@ module dspengine_8to16 dsp_state <= DSP_WRITE_HEADER; else begin - read_adr <= access_len - 1; // point to trailer + read_adr <= access_dat_i[15:0] + HEADER_OFFSET - 1; // point to trailer dsp_state <= DSP_READ_TRAILER; wait_for_trailer <= 0; - data_in_len <= access_len - hdr_length - HEADER_OFFSET - 1 /*trailer*/; + data_in_len <= access_dat_i[15:0] - hdr_length - 1 /*trailer*/; end end -- cgit v1.2.3 From 8f8ac3397aaa85b64aaa8722efdc1c0c40e93052 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Fri, 17 Feb 2012 16:55:23 -0800 Subject: dsp rework: fix for vita occ trailer packing --- host/lib/transport/gen_vrt_if_packet.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/host/lib/transport/gen_vrt_if_packet.py b/host/lib/transport/gen_vrt_if_packet.py index 245a7ddbd..e28ce3aae 100644 --- a/host/lib/transport/gen_vrt_if_packet.py +++ b/host/lib/transport/gen_vrt_if_packet.py @@ -137,7 +137,7 @@ void vrt::if_hdr_pack_$(suffix)( #if $pred & $tlr_p { const size_t empty_bytes = if_packet_info.num_payload_words32*sizeof(boost::uint32_t) - if_packet_info.num_payload_bytes; - if_packet_info.tlr |= (0x3 << 22) | (occ_table[empty_bytes & 0x3] << 10); + if_packet_info.tlr = (0x3 << 22) | (occ_table[empty_bytes & 0x3] << 10); } packet_buff[$num_header_words+if_packet_info.num_payload_words32] = $(XE_MACRO)(if_packet_info.tlr); #set $flags |= (0x1 << 26); -- cgit v1.2.3