// -*- 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., 51 Franklin Street, Boston, MA 02110-1301 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) begin load_next <= #1 load_next + 4'd1; case(load_next) 4'd0 : tx_i_0 <= #1 tx_empty ? 16'd0 : fifodata; 4'd1 : tx_q_0 <= #1 tx_empty ? 16'd0 : fifodata; 4'd2 : tx_i_1 <= #1 tx_empty ? 16'd0 : fifodata; 4'd3 : tx_q_1 <= #1 tx_empty ? 16'd0 : fifodata; 4'd4 : tx_i_2 <= #1 tx_empty ? 16'd0 : fifodata; 4'd5 : tx_q_2 <= #1 tx_empty ? 16'd0 : fifodata; 4'd6 : tx_i_3 <= #1 tx_empty ? 16'd0 : fifodata; 4'd7 : tx_q_3 <= #1 tx_empty ? 16'd0 : fifodata; endcase // case(load_next) end // if (load_next != channels) 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