Imported Upstream version 3.0.2
[debian/gnuradio] / usrp / fpga / sdr_lib / bus_interface.v
1 // -*- verilog -*-
2 //
3 //  USRP - Universal Software Radio Peripheral
4 //
5 //  Copyright (C) 2003 Matt Ettus
6 //
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.
11 //
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.
16 //
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
20 //
21
22 // Interface to Cypress FX2 bus
23 // A packet is 512 Bytes.  Each fifo line is 4 bytes
24 // Fifo has 1024 or 2048 lines
25
26 module bus_interface
27   (     input usbclk,
28         input reset,
29         inout [15:0] usbdata,   // TRISTATE
30         input wire [5:0] usbctl,
31         output wire [5:0] usbrdy,
32         output [31:0] txdata,
33         input [31:0] rxdata,
34         input txclk,
35         input txstrobe,
36         input rxclk,
37         input rxstrobe,
38         output [11:0] debugbus,
39         input clear_status
40         );
41
42    parameter   IN_CHANNELS = 1;
43    parameter   OUT_CHANNELS = 1;
44    parameter   bitmask = (IN_CHANNELS*2)-1;
45
46    wire have_space, have_pkt_rdy;
47    wire WR, RD, OE;
48    reg tx_underrun, rx_overrun;
49    
50    assign WR = usbctl[0];
51    assign RD = usbctl[1];
52    assign OE = usbctl[2];
53    
54    assign usbrdy[0] = have_space;
55    assign usbrdy[1] = have_pkt_rdy;
56    assign usbrdy[2] = tx_underrun;
57    assign usbrdy[3] = rx_overrun;
58    
59    reg [IN_CHANNELS*2*16-1:0] fifo_in;
60    wire [OUT_CHANNELS*2*16-1:0] fifo_out;
61    
62    wire [15:0] usbdata_in = usbdata;
63    
64    reg select_out;
65    reg select_in;
66    
67    reg commit;
68    reg rd_next;
69    reg [15:0] usbdata_out;
70    wire [10:0] txfifolevel,rxfifolevel;
71    reg [8:0] write_count;
72    wire tx_empty;
73    wire tx_full;
74    wire rx_empty;
75    wire rx_full;
76    wire [31:0] txd;
77    wire rdreq;
78         
79    // Tri-state bus macro
80    bustri bustri(.data(usbdata_out),
81                  .enabledt(OE),
82                  .tridata(usbdata)  );
83
84    //////////////////////////////////////////////
85    // TX Side (USB --> DAC)
86    always @(posedge usbclk, posedge reset)
87      begin
88         if(reset)
89           begin
90              fifo_in <= #1 0;
91              write_count <= #1 0;
92           end
93         else 
94           if(WR & ~write_count[8])
95             begin
96                case(write_count[0])
97                  1'b0 : fifo_in[31:16] <= #1 usbdata_in;  // I
98                  1'b1 : fifo_in[15:0] <= #1 usbdata_in;   // Q
99                endcase
100                write_count <= #1 write_count + 9'd1;
101             end
102           else
103             write_count <= #1 WR ? write_count : 9'b0;
104      end
105    
106    always @(posedge usbclk)
107      if(reset)
108        commit <= #1 1'b0;
109      else
110        if(write_count[0] && ~write_count[8] && WR)
111          commit <= #1 1'b1;
112        else 
113          commit <= #1 1'b0;
114    
115    assign rdreq = txstrobe & !tx_empty;
116    assign txdata = tx_empty ? 32'b0 : txd;
117    
118    always @(posedge txclk)
119      if(reset)
120        tx_underrun <= 1'b0;
121      else if(txstrobe & tx_empty)
122        tx_underrun <= 1'b1;
123      else if(clear_status)
124        tx_underrun <= 1'b0;
125
126    fifo_1c_2k   txfifo (.data ( fifo_in ),
127                         .wrreq ( commit ),
128                         .wrclk ( usbclk ),
129
130                         .q ( txd ),                     
131                         .rdreq ( rdreq),
132                         .rdclk ( txclk ),
133                         
134                         .aclr ( reset ),
135
136                         .rdempty ( tx_empty ),
137                         .rdusedw (  ),
138                         .wrfull ( tx_full ),
139                         .wrusedw ( txfifolevel )
140                         );
141    
142    assign have_space = (txfifolevel <= (2048-128));
143    
144    //////////////////////////////
145    // Receive FIFO (ADC --> USB)
146
147    always @(posedge rxclk)
148      if(reset)
149        rx_overrun <= 1'b0;
150      else if(rxstrobe & rx_full)
151        rx_overrun <= 1'b1;
152      else if(clear_status)
153        rx_overrun <= 1'b0;
154
155    always @(select_out, fifo_out)
156      case(select_out)
157        0 : usbdata_out = fifo_out[31:16];  // I
158        1 : usbdata_out = fifo_out[15:0];   // Q
159      endcase
160   
161 /*
162         always @(posedge usbclk, posedge reset)
163         if(reset)
164                 usbdata_out <= #1 16'b0;
165         else
166                 if(select_out)
167                         usbdata_out = fifo_out[31:16];
168                 else
169                         usbdata_out = fifo_out[15:0];
170         */
171          
172    always @(negedge usbclk, posedge reset)
173      if(reset)
174        select_out <= #1 1'b0;
175      else if(~RD)
176        select_out <= #1 1'b0;
177      else 
178        select_out <= #1 ~select_out;
179  
180    fifo_1c_2k   rxfifo (.data ( rxdata ), // counter ),
181                         .wrreq (rxstrobe & ~rx_full ),
182                         .wrclk ( rxclk ),
183                         
184                         .q ( fifo_out ),
185                         .rdreq ( select_out ),// & RD ), // FIXME
186                         .rdclk ( usbclk ),
187                         
188                         .aclr ( reset ),
189                         
190                         .rdempty ( rx_empty ),
191                         .rdusedw ( rxfifolevel ),
192                         .wrfull ( rx_full ),
193                         .wrusedw (  )
194                         );
195    
196    assign have_pkt_rdy = (rxfifolevel >= 128);
197
198    // Debugging Aids
199    assign debugbus[0] = tx_underrun;
200    assign debugbus[1] = rx_overrun;
201    assign debugbus[2] = tx_empty;
202    assign debugbus[3] = tx_full;
203    assign debugbus[4] = rx_empty;
204    assign debugbus[5] = rx_full;
205    assign debugbus[6] = txstrobe;
206    assign debugbus[7] = rxstrobe;
207    assign debugbus[8] = select_out;
208    assign debugbus[9] = rxstrobe & ~rx_full;
209    assign debugbus[10] = have_space;
210    assign debugbus[11] = have_pkt_rdy;
211    
212 endmodule // bus_interface
213