diff options
Diffstat (limited to 'sdr_lib/bus_interface.v')
-rwxr-xr-x | sdr_lib/bus_interface.v | 213 |
1 files changed, 213 insertions, 0 deletions
diff --git a/sdr_lib/bus_interface.v b/sdr_lib/bus_interface.v new file mode 100755 index 000000000..3f5f748d5 --- /dev/null +++ b/sdr_lib/bus_interface.v @@ -0,0 +1,213 @@ +// -*- 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 4 bytes +// Fifo has 1024 or 2048 lines + +module bus_interface + ( input usbclk, + input reset, + inout [15:0] usbdata, // TRISTATE + input wire [5:0] usbctl, + output wire [5:0] usbrdy, + output [31:0] txdata, + input [31:0] rxdata, + input txclk, + input txstrobe, + input rxclk, + input rxstrobe, + output [11:0] debugbus, + input clear_status + ); + + parameter IN_CHANNELS = 1; + parameter OUT_CHANNELS = 1; + parameter bitmask = (IN_CHANNELS*2)-1; + + wire have_space, have_pkt_rdy; + wire WR, RD, OE; + reg tx_underrun, rx_overrun; + + assign WR = usbctl[0]; + assign RD = usbctl[1]; + assign OE = usbctl[2]; + + assign usbrdy[0] = have_space; + assign usbrdy[1] = have_pkt_rdy; + assign usbrdy[2] = tx_underrun; + assign usbrdy[3] = rx_overrun; + + reg [IN_CHANNELS*2*16-1:0] fifo_in; + wire [OUT_CHANNELS*2*16-1:0] fifo_out; + + wire [15:0] usbdata_in = usbdata; + + reg select_out; + reg select_in; + + reg commit; + reg rd_next; + reg [15:0] usbdata_out; + wire [10:0] txfifolevel,rxfifolevel; + reg [8:0] write_count; + wire tx_empty; + wire tx_full; + wire rx_empty; + wire rx_full; + wire [31:0] txd; + wire rdreq; + + // Tri-state bus macro + bustri bustri(.data(usbdata_out), + .enabledt(OE), + .tridata(usbdata) ); + + ////////////////////////////////////////////// + // TX Side (USB --> DAC) + always @(posedge usbclk, posedge reset) + begin + if(reset) + begin + fifo_in <= #1 0; + write_count <= #1 0; + end + else + if(WR & ~write_count[8]) + begin + case(write_count[0]) + 1'b0 : fifo_in[31:16] <= #1 usbdata_in; // I + 1'b1 : fifo_in[15:0] <= #1 usbdata_in; // Q + endcase + write_count <= #1 write_count + 9'd1; + end + else + write_count <= #1 WR ? write_count : 9'b0; + end + + always @(posedge usbclk) + if(reset) + commit <= #1 1'b0; + else + if(write_count[0] && ~write_count[8] && WR) + commit <= #1 1'b1; + else + commit <= #1 1'b0; + + assign rdreq = txstrobe & !tx_empty; + assign txdata = tx_empty ? 32'b0 : txd; + + always @(posedge txclk) + if(reset) + tx_underrun <= 1'b0; + else if(txstrobe & tx_empty) + tx_underrun <= 1'b1; + else if(clear_status) + tx_underrun <= 1'b0; + + fifo_1c_2k txfifo (.data ( fifo_in ), + .wrreq ( commit ), + .wrclk ( usbclk ), + + .q ( txd ), + .rdreq ( rdreq), + .rdclk ( txclk ), + + .aclr ( reset ), + + .rdempty ( tx_empty ), + .rdusedw ( ), + .wrfull ( tx_full ), + .wrusedw ( txfifolevel ) + ); + + assign have_space = (txfifolevel <= (2048-128)); + + ////////////////////////////// + // Receive FIFO (ADC --> USB) + + always @(posedge rxclk) + if(reset) + rx_overrun <= 1'b0; + else if(rxstrobe & rx_full) + rx_overrun <= 1'b1; + else if(clear_status) + rx_overrun <= 1'b0; + + always @(select_out, fifo_out) + case(select_out) + 0 : usbdata_out = fifo_out[31:16]; // I + 1 : usbdata_out = fifo_out[15:0]; // Q + endcase + +/* + always @(posedge usbclk, posedge reset) + if(reset) + usbdata_out <= #1 16'b0; + else + if(select_out) + usbdata_out = fifo_out[31:16]; + else + usbdata_out = fifo_out[15:0]; + */ + + always @(negedge usbclk, posedge reset) + if(reset) + select_out <= #1 1'b0; + else if(~RD) + select_out <= #1 1'b0; + else + select_out <= #1 ~select_out; + + fifo_1c_2k rxfifo (.data ( rxdata ), // counter ), + .wrreq (rxstrobe & ~rx_full ), + .wrclk ( rxclk ), + + .q ( fifo_out ), + .rdreq ( select_out ),// & RD ), // FIXME + .rdclk ( usbclk ), + + .aclr ( reset ), + + .rdempty ( rx_empty ), + .rdusedw ( rxfifolevel ), + .wrfull ( rx_full ), + .wrusedw ( ) + ); + + assign have_pkt_rdy = (rxfifolevel >= 128); + + // Debugging Aids + assign debugbus[0] = tx_underrun; + assign debugbus[1] = rx_overrun; + assign debugbus[2] = tx_empty; + assign debugbus[3] = tx_full; + assign debugbus[4] = rx_empty; + assign debugbus[5] = rx_full; + assign debugbus[6] = txstrobe; + assign debugbus[7] = rxstrobe; + assign debugbus[8] = select_out; + assign debugbus[9] = rxstrobe & ~rx_full; + assign debugbus[10] = have_space; + assign debugbus[11] = have_pkt_rdy; + +endmodule // bus_interface + |