Imported Upstream version 3.0
[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.  Each fifo line is 2 bytes
24 // Fifo has 1024 or 2048 lines
25
26 `include "../../firmware/include/fpga_regs_common.v"
27 `include "../../firmware/include/fpga_regs_standard.v"
28
29 module rx_buffer
30   ( input usbclk,
31     input bus_reset,  // Not used in RX
32     input reset,  // DSP side reset (used here), do not reset registers
33     input reset_regs, //Only reset registers
34     output [15:0] usbdata,
35     input RD,
36     output wire have_pkt_rdy,
37     output reg rx_overrun,
38     input wire [3:0] channels,
39     input wire [15:0] ch_0,
40     input wire [15:0] ch_1,
41     input wire [15:0] ch_2,
42     input wire [15:0] ch_3,
43     input wire [15:0] ch_4,
44     input wire [15:0] ch_5,
45     input wire [15:0] ch_6,
46     input wire [15:0] ch_7,
47     input rxclk,
48     input rxstrobe,
49     input clear_status,
50     input [6:0] serial_addr, input [31:0] serial_data, input serial_strobe,
51     output [15:0] debugbus
52     );
53
54    wire [15:0] fifodata, fifodata_8;
55    reg [15:0]  fifodata_16;
56    
57    wire [11:0] rxfifolevel;
58    wire rx_empty, rx_full;
59
60    wire bypass_hb, want_q;
61    wire [4:0] bitwidth;
62    wire [3:0] bitshift;
63    
64    setting_reg #(`FR_RX_FORMAT) sr_rxformat(.clock(rxclk),.reset(reset_regs),
65                                             .strobe(serial_strobe),.addr(serial_addr),.in(serial_data),
66                                             .out({bypass_hb,want_q,bitwidth,bitshift}));
67
68    // Receive FIFO (ADC --> USB)
69
70    // 257 Bug Fix
71    reg [8:0] read_count;
72    always @(negedge usbclk)
73      if(bus_reset)
74        read_count <= #1 9'd0;
75      else if(RD & ~read_count[8])
76        read_count <= #1 read_count + 9'd1;
77      else
78        read_count <= #1 RD ? read_count : 9'b0;
79    
80    // Detect overrun
81    always @(posedge rxclk)
82      if(reset)
83        rx_overrun <= 1'b0;
84      else if(rxstrobe & (store_next != 0))
85        rx_overrun <= 1'b1;
86      else if(clear_status)
87        rx_overrun <= 1'b0;
88
89    reg [3:0] store_next;
90    always @(posedge rxclk)
91      if(reset)
92        store_next <= #1 4'd0;
93      else if(rxstrobe & (store_next == 0))
94        store_next <= #1 4'd1;
95      else if(~rx_full & (store_next == channels))
96        store_next <= #1 4'd0;
97      else if(~rx_full & (bitwidth == 5'd8) & (store_next == (channels>>1)))
98        store_next <= #1 4'd0;
99      else if(~rx_full & (store_next != 0))
100        store_next <= #1 store_next + 4'd1;
101
102    assign    fifodata = (bitwidth == 5'd8) ? fifodata_8 : fifodata_16;
103
104    assign    fifodata_8 = {round_8(top),round_8(bottom)};
105    reg [15:0] top,bottom;
106
107    function [7:0] round_8;
108       input [15:0] in_val;
109
110       round_8 = in_val[15:8] + (in_val[15] & |in_val[7:0]);
111    endfunction // round_8
112       
113    always @*
114      case(store_next)
115        4'd1 : begin
116           bottom = ch_0;
117           top = ch_1;
118        end
119        4'd2 : begin
120           bottom = ch_2;
121           top = ch_3;
122        end
123        4'd3 : begin
124           bottom = ch_4;
125           top = ch_5;
126        end
127        4'd4 : begin
128           bottom = ch_6;
129           top = ch_7;
130        end
131        default : begin
132           top = 16'hFFFF;
133           bottom = 16'hFFFF;
134        end
135      endcase // case(store_next)
136    
137    always @*
138      case(store_next)
139        4'd1 : fifodata_16 = ch_0;
140        4'd2 : fifodata_16 = ch_1;
141        4'd3 : fifodata_16 = ch_2;
142        4'd4 : fifodata_16 = ch_3;
143        4'd5 : fifodata_16 = ch_4;
144        4'd6 : fifodata_16 = ch_5;
145        4'd7 : fifodata_16 = ch_6;
146        4'd8 : fifodata_16 = ch_7;
147        default : fifodata_16 = 16'hFFFF;
148      endcase // case(store_next)
149    
150    fifo_4k rxfifo 
151      ( .data ( fifodata ),
152        .wrreq (~rx_full & (store_next != 0)),
153        .wrclk ( rxclk ),
154
155        .q ( usbdata ),
156        .rdreq ( RD & ~read_count[8] ), 
157        .rdclk ( ~usbclk ),
158        
159        .aclr ( reset ),  // This one is asynchronous, so we can use either reset
160        
161        .rdempty ( rx_empty ),
162        .rdusedw ( rxfifolevel ),
163        .wrfull ( rx_full ),
164        .wrusedw (  )
165        );
166    
167    assign have_pkt_rdy = (rxfifolevel >= 256);
168
169    // Debugging Aids
170    assign debugbus[0] = RD;
171    assign debugbus[1] = rx_overrun;
172    assign debugbus[2] = read_count[8];
173    assign debugbus[3] = rx_full;
174    assign debugbus[4] = rxstrobe;
175    assign debugbus[5] = usbclk;
176    assign debugbus[6] = have_pkt_rdy;
177    assign debugbus[10:7] = store_next;
178    //assign debugbus[15:11] = rxfifolevel[4:0];
179    assign debugbus[15:11] = bitwidth;
180    
181 endmodule // rx_buffer
182