Imported Upstream version 3.2.2
[debian/gnuradio] / usrp / fpga / inband_lib / rx_buffer_inband.v
1 //`include "../../firmware/include/fpga_regs_common.v"\r
2 //`include "../../firmware/include/fpga_regs_standard.v"\r
3 module rx_buffer_inband\r
4   ( input usbclk,\r
5     input bus_reset,\r
6     input reset,  // DSP side reset (used here), do not reset registers\r
7     input reset_regs, //Only reset registers\r
8     output [15:0] usbdata,\r
9     input RD,\r
10     output wire have_pkt_rdy,\r
11     output reg rx_overrun,\r
12     input wire [3:0] channels,\r
13     input wire [15:0] ch_0,\r
14     input wire [15:0] ch_1,\r
15     input wire [15:0] ch_2,\r
16     input wire [15:0] ch_3,\r
17     input wire [15:0] ch_4,\r
18     input wire [15:0] ch_5,\r
19     input wire [15:0] ch_6,\r
20     input wire [15:0] ch_7,\r
21     input rxclk,\r
22     input rxstrobe,\r
23     input clear_status,\r
24     input [6:0] serial_addr, \r
25     input [31:0] serial_data, \r
26     input serial_strobe,\r
27     output wire [15:0] debugbus,\r
28         \r
29     //Connection with tx_inband\r
30     input rx_WR,\r
31     input [15:0] rx_databus,\r
32     input rx_WR_done,\r
33     output reg rx_WR_enabled,\r
34     //signal strength\r
35     input wire [31:0] rssi_0, input wire [31:0] rssi_1,\r
36     input wire [31:0] rssi_2, input wire [31:0] rssi_3,\r
37     input wire [1:0] tx_underrun\r
38     );\r
39     \r
40     parameter NUM_CHAN = 1;\r
41     genvar i ;\r
42     \r
43     // FX2 Bug Fix\r
44     reg [8:0] read_count;\r
45     always @(negedge usbclk)\r
46         if(bus_reset)\r
47             read_count <= #1 9'd0;\r
48         else if(RD & ~read_count[8])\r
49             read_count <= #1 read_count + 9'd1;\r
50         else\r
51             read_count <= #1 RD ? read_count : 9'b0;\r
52        \r
53         // Time counter\r
54         reg [31:0] timestamp_clock;\r
55         always @(posedge rxclk)\r
56                 if (reset)\r
57                         timestamp_clock <= 0;\r
58                 else\r
59                         timestamp_clock <= timestamp_clock + 1;\r
60      \r
61   // USB side fifo\r
62   wire [11:0] rdusedw;\r
63   wire [11:0] wrusedw;\r
64   wire [15:0] fifodata;\r
65   wire [15:0] fifodata_il[0:NUM_CHAN];\r
66   wire WR;\r
67   wire have_space;\r
68   reg sel;\r
69   reg wr;\r
70 \r
71   always@(posedge rxclk)\r
72     begin\r
73       if(reset)\r
74         begin\r
75           sel<=1;\r
76           wr<=0;\r
77         end\r
78       else if(rxstrobe)\r
79         begin\r
80           sel<=0;\r
81           wr<=1;\r
82         end\r
83       else if(wr&~sel)\r
84           sel<=1;\r
85       else if(wr&sel)\r
86           wr<=0;\r
87       else\r
88           wr<=0;\r
89     end\r
90 \r
91   assign fifodata_il[0] = (sel)?ch_1:ch_0;\r
92   assign fifodata_il[1] = (sel)?ch_3:ch_2;\r
93 \r
94   fifo_4kx16_dc rx_usb_fifo (\r
95     .aclr ( reset ),\r
96     .data ( fifodata ),\r
97     .rdclk ( ~usbclk ),\r
98     .rdreq ( RD & ~read_count[8] ),\r
99     .wrclk ( rxclk ),\r
100     .wrreq ( WR ),\r
101     .q ( usbdata ),\r
102     .rdempty (  ),\r
103     .rdusedw ( rdusedw ),\r
104     .wrfull (  ),\r
105     .wrusedw ( wrusedw ) );\r
106     \r
107   assign have_pkt_rdy = (rdusedw >= 12'd256);\r
108   assign have_space = (wrusedw < 12'd760);\r
109          \r
110   // Rx side fifos\r
111   // These are of size [NUM_CHAN:0] because the extra channel is used for the\r
112   // RX command channel.  If there were no command channel, they would be\r
113   // NUM_CHAN-1.\r
114   wire chan_rdreq;\r
115   wire [15:0] chan_fifodata;\r
116   wire [9:0] chan_usedw;\r
117   wire [NUM_CHAN:0] chan_empty;\r
118   wire [3:0] rd_select;\r
119   wire [NUM_CHAN:0] rx_full;\r
120          \r
121   packet_builder #(NUM_CHAN) rx_pkt_builer (\r
122     .rxclk ( rxclk ),\r
123     .reset ( reset ),\r
124     .timestamp_clock ( timestamp_clock ),\r
125     .channels ( NUM_CHAN ),\r
126     .chan_rdreq ( chan_rdreq ),\r
127     .chan_fifodata ( chan_fifodata ),\r
128     .chan_empty ( chan_empty ),\r
129     .rd_select ( rd_select ),\r
130     .chan_usedw ( chan_usedw ),\r
131     .WR ( WR ),\r
132     .fifodata ( fifodata ),\r
133     .have_space ( have_space ),\r
134       .rssi_0(rssi_0), .rssi_1(rssi_1),\r
135       .rssi_2(rssi_2),.rssi_3(rssi_3), .debugbus(debug),\r
136       .underrun(tx_underrun));\r
137          \r
138   // Detect overrun\r
139   always @(posedge rxclk)\r
140     if(reset)\r
141       rx_overrun <= 1'b0;\r
142     else if(rx_full[0])\r
143       rx_overrun <= 1'b1;\r
144     else if(clear_status)\r
145       rx_overrun <= 1'b0;\r
146 \r
147                 \r
148   // FIXME: what is the purpose of these two lines?\r
149   wire [15:0]ch[NUM_CHAN:0];\r
150   assign ch[0] = ch_0;\r
151         \r
152   wire cmd_empty;\r
153         \r
154   always @(posedge rxclk)\r
155     if(reset)\r
156       rx_WR_enabled <= 1;\r
157     else if(cmd_empty)\r
158       rx_WR_enabled <= 1;\r
159     else if(rx_WR_done)\r
160       rx_WR_enabled <= 0;\r
161 \r
162 \r
163   // Of Size 0:NUM_CHAN due to extra command channel.\r
164   wire [15:0] dataout [0:NUM_CHAN];\r
165   wire [9:0]  usedw     [0:NUM_CHAN];\r
166   wire empty[0:NUM_CHAN];\r
167         \r
168   generate for (i = 0 ; i < NUM_CHAN; i = i + 1)\r
169     begin : generate_channel_fifos\r
170 \r
171       wire rdreq;\r
172 \r
173       assign rdreq = (rd_select == i) & chan_rdreq;\r
174 \r
175       fifo_1kx16 rx_chan_fifo (\r
176       .aclr ( reset ),\r
177       .clock ( rxclk ),\r
178       .data ( fifodata_il[i] ),\r
179       .rdreq ( rdreq ),\r
180       .wrreq ( ~rx_full[i] & wr),\r
181       .empty (empty[i]),\r
182       .full (rx_full[i]),\r
183       .q ( dataout[i]),\r
184       .usedw ( usedw[i]),\r
185       .almost_empty(chan_empty[i])\r
186       );\r
187     end\r
188   endgenerate\r
189         \r
190   wire [7:0] debug;\r
191          \r
192   fifo_1kx16 rx_cmd_fifo (\r
193     .aclr ( reset ),\r
194     .clock ( rxclk ),\r
195     .data ( rx_databus ),\r
196     .rdreq ( (rd_select == NUM_CHAN) & chan_rdreq ),\r
197     .wrreq ( rx_WR & rx_WR_enabled),\r
198     .empty ( cmd_empty),\r
199     .full ( rx_full[NUM_CHAN] ),\r
200     .q ( dataout[NUM_CHAN]),\r
201     .usedw ( usedw[NUM_CHAN] )\r
202   );\r
203         \r
204   assign chan_empty[NUM_CHAN] = cmd_empty | rx_WR_enabled;\r
205   assign chan_fifodata = dataout[rd_select];\r
206   assign chan_usedw = usedw[rd_select];\r
207   assign debugbus = {4'd0, rxclk, rxstrobe, rx_full[0], rx_full[1], sel, wr};\r
208 \r
209 endmodule\r