Merged r6749:6763 from jcorgan/t179. Fixes ticket:179. New RBFs synthesized with...
[debian/gnuradio] / usrp / fpga / inband_lib / chan_fifo_reader.v
1 module chan_fifo_reader 
2   ( reset, tx_clock, tx_strobe, adc_time, samples_format,
3     fifodata, pkt_waiting, rdreq, skip, tx_q, tx_i,
4     underrun, tx_empty, debug, rssi, threshhold, rssi_wait) ;
5
6     input   wire                     reset ;
7     input   wire                     tx_clock ;
8     input   wire                     tx_strobe ; //signal to output tx_i and tx_q
9     input   wire              [31:0] adc_time ; //current time
10     input   wire               [3:0] samples_format ;// not useful at this point
11     input   wire              [31:0] fifodata ; //the data input
12     input   wire                     pkt_waiting ; //signal the next packet is ready
13     output  reg                      rdreq ; //actually an ack to the current fifodata
14     output  reg                      skip ; //finish reading current packet
15     output  reg               [15:0] tx_q ; //top 16 bit output of fifodata
16     output  reg               [15:0] tx_i ; //bottom 16 bit output of fifodata
17     output  reg                      underrun ; 
18     output  reg                      tx_empty ; //cause 0 to be the output
19     input       wire                      [31:0] rssi;
20     input       wire                      [31:0] threshhold;
21         input   wire                      [31:0] rssi_wait;
22
23         output wire [14:0] debug;
24         assign debug = {reader_state, trash, skip, timestamp[4:0], adc_time[4:0]};
25     // Should not be needed if adc clock rate < tx clock rate
26     // Used only to debug
27     `define JITTER                   5
28     
29     //Samples format
30     // 16 bits interleaved complex samples
31     `define QI16                     4'b0
32     
33     // States
34     parameter IDLE           =     3'd0;    
35         parameter HEADER         =     3'd1;
36     parameter TIMESTAMP      =     3'd2;
37     parameter WAIT           =     3'd3;
38     parameter WAITSTROBE     =     3'd4;
39     parameter SEND           =     3'd5;
40
41     // Header format
42     `define PAYLOAD                  8:2
43     `define ENDOFBURST               27
44     `define STARTOFBURST            28
45     `define RSSI_FLAG                            26
46         
47
48     /* State registers */
49     reg                        [2:0] reader_state;
50         /* Local registers */  
51     reg                        [6:0] payload_len;
52     reg                        [6:0] read_len;
53     reg                       [31:0] timestamp;
54     reg                              burst;
55         reg                                                              trash;
56         reg                                                              rssi_flag;
57         reg                                               [31:0] time_wait;
58    
59     always @(posedge tx_clock)
60     begin
61         if (reset) 
62           begin
63             reader_state <= IDLE;
64             rdreq <= 0;
65             skip <= 0;
66             underrun <= 0;
67             burst <= 0;
68             tx_empty <= 1;
69             tx_q <= 0;
70             tx_i <= 0;
71                         trash <= 0;
72                         rssi_flag <= 0;
73                         time_wait <= 0;
74          end
75        else 
76                    begin
77            case (reader_state)
78                IDLE:
79                begin
80                                 /*
81                                  * reset all the variables and wait for a tx_strobe
82                                  * it is assumed that the ram connected to this fifo_reader 
83                                  * is a short hand fifo meaning that the header to the next packet
84                                  * is already available to this fifo_reader when pkt_waiting is on
85                                  */
86                    skip <=0;
87                                    time_wait <= 0;
88                    if (pkt_waiting == 1)
89                      begin
90                         reader_state <= HEADER;
91                         rdreq <= 1;
92                         underrun <= 0;
93                      end
94                    if (burst == 1 && pkt_waiting == 0)
95                         underrun <= 1;
96                         
97                    if (tx_strobe == 1)
98                        tx_empty <= 1 ;
99                end
100
101                                    /* Process header */
102                HEADER:
103                begin
104                    if (tx_strobe == 1)
105                        tx_empty <= 1 ;
106                    
107                    rssi_flag <= fifodata[`RSSI_FLAG]&fifodata[`STARTOFBURST];
108                    //Check Start/End burst flag
109                    if  (fifodata[`STARTOFBURST] == 1 
110                        && fifodata[`ENDOFBURST] == 1)
111                        burst <= 0;
112                    else if (fifodata[`STARTOFBURST] == 1)
113                        burst <= 1;
114                    else if (fifodata[`ENDOFBURST] == 1)
115                        burst <= 0;
116
117                                         if (trash == 1 && fifodata[`STARTOFBURST] == 0)
118                                         begin
119                                                 skip <= 1;
120                                                 reader_state <= IDLE;
121                                                 rdreq <= 0;
122                                         end 
123                     else
124                                         begin   
125                                 payload_len <= fifodata[`PAYLOAD] ;
126                                 read_len <= 0;
127                         rdreq <= 1;
128                                                 reader_state <= TIMESTAMP;
129                                         end
130                end
131
132                TIMESTAMP: 
133                begin
134                    timestamp <= fifodata;
135                    reader_state <= WAIT;
136                    if (tx_strobe == 1)
137                        tx_empty <= 1 ;
138                    rdreq <= 0;
139                end
140                                 
141                                    // Decide if we wait, send or discard samples
142                WAIT: 
143                begin
144                    if (tx_strobe == 1)
145                        tx_empty <= 1 ;
146                     
147                    time_wait <= time_wait + 32'd1;
148                                    // Outdated
149                    if ((timestamp < adc_time) ||
150                                                         (time_wait >= rssi_wait && rssi_wait != 0 && rssi_flag))
151                      begin
152                                                 trash <= 1;
153                         reader_state <= IDLE;
154                         skip <= 1;
155                      end  
156                    // Let's send it                                     
157                    else if ((timestamp <= adc_time + `JITTER 
158                              && timestamp > adc_time)
159                              || timestamp == 32'hFFFFFFFF)
160                                         begin
161                                                 if (rssi <= threshhold || rssi_flag == 0)
162                                                   begin
163                                                     trash <= 0;
164                             reader_state <= WAITSTROBE; 
165                           end
166                                                 else
167                                                     reader_state <= WAIT;
168                                         end
169                                    else
170                                                 reader_state <= WAIT;
171                    // Wait a little bit more
172                    //else if (timestamp > adc_time + `JITTER)
173                    //    reader_state <= WAIT;
174                end
175                  
176                // Wait for the transmit chain to be ready
177                WAITSTROBE:
178                begin
179                    // If end of payload...
180                    if (read_len == payload_len)
181                      begin
182                        reader_state <= IDLE;
183                        skip <= 1;
184                        if (tx_strobe == 1)
185                            tx_empty <= 1 ;
186                      end  
187                    else if (tx_strobe == 1)
188                      begin
189                        reader_state <= SEND;
190                        rdreq <= 1;
191                      end
192                end
193                
194                            // Send the samples to the tx_chain
195                SEND:
196                begin
197                    reader_state <= WAITSTROBE; 
198                    read_len <= read_len + 7'd1;
199                    tx_empty <= 0;
200                    rdreq <= 0;
201                    
202                    case(samples_format)
203                        `QI16:
204                         begin
205                             tx_i <= fifodata[15:0];
206                             tx_q <= fifodata[31:16];
207                         end
208                         
209                         // Assume 16 bits complex samples by default
210                         default:
211                         begin
212                             tx_i <= fifodata[15:0];
213                             tx_q <= fifodata[31:16];
214                         end 
215                    endcase
216                end
217                
218                default:
219                begin
220                                         //error handling
221                    reader_state <= IDLE;
222                end
223            endcase
224        end
225    end
226  
227 endmodule