Imported Upstream version 3.2.2
[debian/gnuradio] / usrp / fpga / sdr_lib / rx_buffer.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, the fifo has 4096 lines of 18 bits each
24
25 `include "../../firmware/include/fpga_regs_common.v"
26 `include "../../firmware/include/fpga_regs_standard.v"
27
28 module rx_buffer
29   ( // Read/USB side
30     input usbclk,
31     input bus_reset,
32     output [15:0] usbdata,
33     input RD,
34     output reg have_pkt_rdy,
35     output reg rx_overrun,
36     input clear_status,
37     // Write/DSP side
38     input rxclk,
39     input reset,  // DSP side reset (used here), do not reset registers
40     input rxstrobe,
41     input wire [3:0] channels,
42     input wire [15:0] ch_0,
43     input wire [15:0] ch_1,
44     input wire [15:0] ch_2,
45     input wire [15:0] ch_3,
46     input wire [15:0] ch_4,
47     input wire [15:0] ch_5,
48     input wire [15:0] ch_6,
49     input wire [15:0] ch_7,
50     // Settings, on rxclk also
51     input [6:0] serial_addr, input [31:0] serial_data, input serial_strobe,
52     input reset_regs, //Only reset registers
53     output [31:0] debugbus
54     );
55    
56    wire [15:0]    fifodata, fifodata_8;
57    reg [15:0]     fifodata_16;
58    
59    wire [11:0]    rxfifolevel;
60    wire           rx_full;
61    
62    wire           bypass_hb, want_q;
63    wire [4:0]     bitwidth;
64    wire [3:0]     bitshift;
65    
66    setting_reg #(`FR_RX_FORMAT) sr_rxformat(.clock(rxclk),.reset(reset_regs),
67                                             .strobe(serial_strobe),.addr(serial_addr),.in(serial_data),
68                                             .out({bypass_hb,want_q,bitwidth,bitshift}));
69
70    // USB Read Side of FIFO
71    always @(negedge usbclk)
72      have_pkt_rdy <= (rxfifolevel >= 256);
73
74    // 257 Bug Fix
75    reg [8:0]      read_count;
76    always @(negedge usbclk)
77      if(bus_reset)
78        read_count <= 0;
79      else if(RD)
80        read_count <= read_count + 1;
81      else
82        read_count <= 0;
83    
84    // FIFO
85    wire           ch0_in, ch0_out, iq_out;
86    assign         ch0_in = (phase == 1);
87
88    fifo_4k_18 rxfifo 
89      ( // DSP Write Side
90        .data ( {ch0_in, phase[0], fifodata} ),
91        .wrreq (~rx_full & (phase != 0)),
92        .wrclk ( rxclk ),
93        .wrfull ( rx_full ),
94        .wrempty ( ),
95        .wrusedw ( ),
96        // USB Read Side
97        .q ( {ch0_out,iq_out,usbdata} ),
98        .rdreq ( RD & ~read_count[8] ), 
99        .rdclk ( ~usbclk ),
100        .rdfull ( ),
101        .rdempty ( ),
102        .rdusedw ( rxfifolevel ),
103        // Async, shared
104        .aclr ( reset ) );
105
106    // DSP Write Side of FIFO
107    reg [15:0] ch_0_reg;
108    reg [15:0] ch_1_reg;
109    reg [15:0] ch_2_reg;
110    reg [15:0] ch_3_reg;
111    reg [15:0] ch_4_reg;
112    reg [15:0] ch_5_reg;
113    reg [15:0] ch_6_reg;
114    reg [15:0] ch_7_reg;
115
116    always @(posedge rxclk)
117      if (rxstrobe)
118        begin
119          ch_0_reg <= ch_0;
120          ch_1_reg <= ch_1;
121          ch_2_reg <= ch_2;
122          ch_3_reg <= ch_3;
123          ch_4_reg <= ch_4;
124          ch_5_reg <= ch_5;
125          ch_6_reg <= ch_6;
126          ch_7_reg <= ch_7;
127        end
128
129    reg [3:0] phase;
130    always @(posedge rxclk)
131      if(reset)
132        phase <= 4'd0;
133      else if(phase == 0)
134        begin
135           if(rxstrobe)
136             phase <= 4'd1;
137        end
138      else if(~rx_full)
139        if(phase == ((bitwidth == 5'd8) ? (channels>>1) : channels))
140          phase <= 4'd0;
141        else
142          phase <= phase + 4'd1;
143    
144    assign    fifodata = (bitwidth == 5'd8) ? fifodata_8 : fifodata_16;
145    
146    assign    fifodata_8 = {round_8(top),round_8(bottom)};
147    reg [15:0] top,bottom;
148    
149    function [7:0] round_8;
150       input [15:0] in_val;
151       
152       round_8 = in_val[15:8] + (in_val[15] & |in_val[7:0]);
153    endfunction // round_8
154       
155    always @*
156      case(phase)
157        4'd1 : begin
158           bottom = ch_0_reg;
159           top = ch_1_reg;
160        end
161        4'd2 : begin
162           bottom = ch_2_reg;
163           top = ch_3_reg;
164        end
165        4'd3 : begin
166           bottom = ch_4_reg;
167           top = ch_5_reg;
168        end
169        4'd4 : begin
170           bottom = ch_6_reg;
171           top = ch_7_reg;
172        end
173        default : begin
174           top = 16'hFFFF;
175           bottom = 16'hFFFF;
176        end
177      endcase // case(phase)
178    
179    always @*
180      case(phase)
181        4'd1 : fifodata_16 = ch_0_reg;
182        4'd2 : fifodata_16 = ch_1_reg;
183        4'd3 : fifodata_16 = ch_2_reg;
184        4'd4 : fifodata_16 = ch_3_reg;
185        4'd5 : fifodata_16 = ch_4_reg;
186        4'd6 : fifodata_16 = ch_5_reg;
187        4'd7 : fifodata_16 = ch_6_reg;
188        4'd8 : fifodata_16 = ch_7_reg;
189        default : fifodata_16 = 16'hFFFF;
190      endcase // case(phase)
191    
192    // Detect overrun
193    reg clear_status_dsp, rx_overrun_dsp;
194    always @(posedge rxclk)
195      clear_status_dsp <= clear_status;
196
197    always @(negedge usbclk)
198      rx_overrun <= rx_overrun_dsp;
199
200    always @(posedge rxclk)
201      if(reset)
202        rx_overrun_dsp <= 1'b0;
203      else if(rxstrobe & (phase != 0))
204        rx_overrun_dsp <= 1'b1;
205      else if(clear_status_dsp)
206        rx_overrun_dsp <= 1'b0;
207
208    // Debug bus
209    //
210    // 15:0  rxclk  domain => TXA 15:0
211    // 31:16 usbclk domain => RXA 15:0
212    
213    assign debugbus[0]     = reset;
214    assign debugbus[1]     = reset_regs;
215    assign debugbus[2]     = rxstrobe;
216    assign debugbus[6:3]   = channels;
217    assign debugbus[7]     = rx_full;
218    assign debugbus[11:8]  = phase;
219    assign debugbus[12]    = ch0_in;
220    assign debugbus[13]    = clear_status_dsp;
221    assign debugbus[14]    = rx_overrun_dsp;
222    assign debugbus[15]    = rxclk;
223
224    assign debugbus[16]    = bus_reset;   
225    assign debugbus[17]    = RD;
226    assign debugbus[18]    = have_pkt_rdy;
227    assign debugbus[19]    = rx_overrun;
228    assign debugbus[20]    = read_count[0];
229    assign debugbus[21]    = read_count[8];
230    assign debugbus[22]    = ch0_out;
231    assign debugbus[23]    = iq_out;
232    assign debugbus[24]    = clear_status;
233    assign debugbus[30:25] = 0;   
234    assign debugbus[31]    = usbclk;
235    
236 endmodule // rx_buffer
237