diff options
Diffstat (limited to 'sdr_lib/tx_buffer.v')
-rw-r--r-- | sdr_lib/tx_buffer.v | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/sdr_lib/tx_buffer.v b/sdr_lib/tx_buffer.v new file mode 100644 index 000000000..cae6607b3 --- /dev/null +++ b/sdr_lib/tx_buffer.v @@ -0,0 +1,138 @@ +// -*- verilog -*- +// +// USRP - Universal Software Radio Peripheral +// +// Copyright (C) 2003 Matt Ettus +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// + +// Interface to Cypress FX2 bus +// A packet is 512 Bytes. Each fifo line is 2 bytes +// Fifo has 1024 or 2048 lines + +module tx_buffer + ( input usbclk, + input bus_reset, // Used here for the 257-Hack to fix the FX2 bug + input reset, // standard DSP-side reset + input [15:0] usbdata, + input wire WR, + output wire have_space, + output reg tx_underrun, + input wire [3:0] channels, + output reg [15:0] tx_i_0, + output reg [15:0] tx_q_0, + output reg [15:0] tx_i_1, + output reg [15:0] tx_q_1, + output reg [15:0] tx_i_2, + output reg [15:0] tx_q_2, + output reg [15:0] tx_i_3, + output reg [15:0] tx_q_3, + input txclk, + input txstrobe, + input clear_status, + output wire tx_empty, + output [11:0] debugbus + ); + + wire [11:0] txfifolevel; + reg [8:0] write_count; + wire tx_full; + wire [15:0] fifodata; + wire rdreq; + + reg [3:0] load_next; + + // DAC Side of FIFO + assign rdreq = ((load_next != channels) & !tx_empty); + + always @(posedge txclk) + if(reset) + begin + {tx_i_0,tx_q_0,tx_i_1,tx_q_1,tx_i_2,tx_q_2,tx_i_3,tx_q_3} + <= #1 128'h0; + load_next <= #1 4'd0; + end + else + if((load_next != channels) & !tx_empty) + begin + load_next <= #1 load_next + 4'd1; + case(load_next) + 4'd0 : tx_i_0 <= #1 fifodata; + 4'd1 : tx_q_0 <= #1 fifodata; + 4'd2 : tx_i_1 <= #1 fifodata; + 4'd3 : tx_q_1 <= #1 fifodata; + 4'd4 : tx_i_2 <= #1 fifodata; + 4'd5 : tx_q_2 <= #1 fifodata; + 4'd6 : tx_i_3 <= #1 fifodata; + 4'd7 : tx_q_3 <= #1 fifodata; + endcase // case(load_next) + end // if ((load_next != channels) & !tx_empty) + else if(txstrobe & (load_next == channels)) + begin + load_next <= #1 4'd0; + end + + // USB Side of FIFO + assign have_space = (txfifolevel <= (4095-256)); + + always @(posedge usbclk) + if(bus_reset) // Use bus reset because this is on usbclk + write_count <= #1 0; + else if(WR & ~write_count[8]) + write_count <= #1 write_count + 9'd1; + else + write_count <= #1 WR ? write_count : 9'b0; + + // Detect Underruns + always @(posedge txclk) + if(reset) + tx_underrun <= 1'b0; + else if(txstrobe & (load_next != channels)) + tx_underrun <= 1'b1; + else if(clear_status) + tx_underrun <= 1'b0; + + // FIFO + fifo_4k txfifo + ( .data ( usbdata ), + .wrreq ( WR & ~write_count[8] ), + .wrclk ( usbclk ), + + .q ( fifodata ), + .rdreq ( rdreq ), + .rdclk ( txclk ), + + .aclr ( reset ), // asynch, so we can use either + + .rdempty ( tx_empty ), + .rdusedw ( ), + .wrfull ( tx_full ), + .wrusedw ( txfifolevel ) + ); + + // Debugging Aids + assign debugbus[0] = WR; + assign debugbus[1] = have_space; + assign debugbus[2] = tx_empty; + assign debugbus[3] = tx_full; + assign debugbus[4] = tx_underrun; + assign debugbus[5] = write_count[8]; + assign debugbus[6] = txstrobe; + assign debugbus[7] = rdreq; + assign debugbus[11:8] = load_next; + +endmodule // tx_buffer + |