3 // USRP - Universal Software Radio Peripheral
5 // Copyright (C) 2003 Matt Ettus
7 // This program is free software; you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License as published by
9 // the Free Software Foundation; either version 2 of the License, or
10 // (at your option) any later version.
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details.
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 51 Franklin Street, Boston, MA 02110-1301 USA
22 // Interface to Cypress FX2 bus
23 // A packet is 512 Bytes. Each fifo line is 2 bytes
24 // Fifo has 1024 or 2048 lines
29 input bus_reset, // Used here for the 257-Hack to fix the FX2 bug
32 output reg have_space,
33 output reg tx_underrun,
38 input reset, // standard DSP-side reset
39 input wire [3:0] channels,
40 output reg [15:0] tx_i_0,
41 output reg [15:0] tx_q_0,
42 output reg [15:0] tx_i_1,
43 output reg [15:0] tx_q_1,
46 output [31:0] debugbus
49 wire [11:0] txfifolevel;
57 reg [15:0] usbdata_reg;
59 reg [8:0] write_count;
61 always @(posedge usbclk)
62 have_space <= (txfifolevel < (4092-256)); // be extra conservative
64 always @(posedge usbclk)
67 usbdata_reg <= usbdata;
70 always @(posedge usbclk)
74 write_count <= write_count + 1;
78 always @(posedge usbclk)
79 sop <= WR & ~wr_reg; // Edge detect
84 .data ( {sop,write_count[0],usbdata_reg} ),
85 .wrreq ( wr_reg & ~write_count[8] ),
89 .wrusedw ( txfifolevel ),
91 .q ( {sop_f, iq_f, fifodata} ),
95 .rdempty ( tx_empty ),
101 always @(posedge txclk)
104 {tx_i_0,tx_q_0,tx_i_1,tx_q_1} <= 64'h0;
107 else if(phase == channels)
116 4'd0 : tx_i_0 <= fifodata;
117 4'd1 : tx_q_0 <= fifodata;
118 4'd2 : tx_i_1 <= fifodata;
119 4'd3 : tx_q_1 <= fifodata;
120 endcase // case(phase)
121 phase <= phase + 4'd1;
124 assign rdreq = ((phase != channels) & ~tx_empty);
126 // Detect Underruns, cross clock domains
127 reg clear_status_dsp, tx_underrun_dsp;
128 always @(posedge txclk)
129 clear_status_dsp <= clear_status;
131 always @(posedge usbclk)
132 tx_underrun <= tx_underrun_dsp;
134 always @(posedge txclk)
136 tx_underrun_dsp <= 1'b0;
137 else if(txstrobe & (phase != channels))
138 tx_underrun_dsp <= 1'b1;
139 else if(clear_status_dsp)
140 tx_underrun_dsp <= 1'b0;
144 // 15:0 txclk domain => TXA [15:0]
145 // 31:16 usbclk domain => RXA [15:0]
147 assign debugbus[0] = reset;
148 assign debugbus[1] = txstrobe;
149 assign debugbus[2] = rdreq;
150 assign debugbus[6:3] = phase;
151 assign debugbus[7] = tx_empty;
152 assign debugbus[8] = tx_underrun_dsp;
153 assign debugbus[9] = iq_f;
154 assign debugbus[10] = sop_f;
155 assign debugbus[14:11] = 0;
156 assign debugbus[15] = txclk;
158 assign debugbus[16] = bus_reset;
159 assign debugbus[17] = WR;
160 assign debugbus[18] = wr_reg;
161 assign debugbus[19] = have_space;
162 assign debugbus[20] = write_count[8];
163 assign debugbus[21] = write_count[0];
164 assign debugbus[22] = sop;
165 assign debugbus[23] = tx_underrun;
166 assign debugbus[30:24] = 0;
167 assign debugbus[31] = usbclk;
169 endmodule // tx_buffer