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