Merged features/inband -r4812:5218 into trunk. This group of changes
[debian/gnuradio] / usrp / fpga / inband_lib / chan_fifo_reader.v
1 module chan_fifo_reader 
2   ( input       reset,
3     input       tx_clock,
4     input       tx_strobe,
5     input       [31:0]adc_clock,
6     input       [3:0] samples_format,
7     input       [15:0] fifodata,
8     input       pkt_waiting,
9     output  reg rdreq,
10     output  reg skip,
11     output  reg [15:0]tx_q,
12     output  reg [15:0]tx_i,
13     output  reg overrun,
14     output  reg underrun) ;
15     
16     // Should not be needed if adc clock rate < tx clock rate
17     `define JITTER        5
18     
19     //Samples format
20     // 16 bits interleaved complex samples
21     `define QI16         4'b0
22     
23     // States
24    `define IDLE          4'd0
25    `define READ          4'd1
26    `define HEADER1       4'd2
27    `define HEADER2       4'd3
28    `define TIMESTAMP1    4'd4
29    `define TIMESTAMP2    4'd5
30    `define WAIT          4'd6
31    `define WAITSTROBE    4'd7
32    `define SENDWAIT      4'd8
33    `define SEND          4'd9
34    `define FEED          4'd10
35    `define DISCARD       4'd11
36
37    // State registers
38    reg[3:0] reader_state;
39    reg[3:0] reader_next_state;
40    
41    //Variables
42    reg[8:0] payload_len;
43    reg[8:0] read_len;
44    reg[31:0] timestamp;
45    reg burst;
46    reg qsample;
47    always @(posedge tx_clock)
48    begin
49        if (reset) 
50           begin
51              reader_state <= `IDLE;
52              reader_next_state <= `IDLE;
53              rdreq <= 0;
54              skip <= 0;
55              overrun <= 0;
56              underrun <= 0;
57              burst <= 0;
58              qsample <= 1;
59           end
60        else 
61                  begin
62            reader_state = reader_next_state;
63            case (reader_state)
64                `IDLE:
65                   begin
66                      if (pkt_waiting == 1)
67                        begin
68                           reader_next_state <= `READ;
69                           rdreq <= 1;
70                           underrun <= 0;
71                        end
72                      else if (burst == 1)
73                         underrun <= 1;
74                   end
75
76                                 // Just wait for the fifo data to arrive
77                `READ: 
78                   begin
79                      reader_next_state <= `HEADER1;
80                   end
81                                 
82                                 // First part of the header
83                `HEADER1:
84                   begin
85                      reader_next_state <= `HEADER2;
86                      
87                      //Check Start burst flag
88                      if (fifodata[3] == 1)
89                         burst <= 1;
90                         
91                      if (fifodata[4] == 1)
92                         burst <= 0;
93                   end
94
95                                 // Read payload length
96                `HEADER2:
97                   begin
98                      payload_len <= (fifodata & 16'h1FF);
99                      read_len <= 9'd0;
100                      reader_next_state <= `TIMESTAMP1;
101                   end
102
103                `TIMESTAMP1: 
104                   begin
105                      timestamp <= {fifodata, 16'b0};
106                      rdreq <= 0;
107                      reader_next_state <= `TIMESTAMP2;
108                   end
109                                 
110                `TIMESTAMP2:
111                   begin
112                      timestamp <= timestamp + fifodata;
113                      reader_next_state <= `WAIT;
114                   end
115                                 
116                                 // Decide if we wait, send or discard samples
117                `WAIT: 
118                   begin
119                    // Wait a little bit more
120                      if (timestamp > adc_clock + `JITTER)
121                         reader_next_state <= `WAIT;
122                    // Let's send it
123                    else if ((timestamp < adc_clock + `JITTER 
124                            && timestamp > adc_clock)
125                            || timestamp == 32'hFFFFFFFF)
126                       begin
127                          reader_next_state <= `WAITSTROBE;
128                       end
129                    // Outdated
130                    else if (timestamp < adc_clock)
131                       begin
132                          reader_next_state <= `DISCARD;
133                          skip <= 1;
134                      end
135                  end
136                  
137             // Wait for the transmit chain to be ready
138                `WAITSTROBE:
139                   begin
140                       // If end of payload...
141                      if (read_len == payload_len)
142                         begin
143                            reader_next_state <= `DISCARD;
144                            skip <= (payload_len < 508);
145                         end
146                           
147                       if (tx_strobe == 1)
148                          reader_next_state <= `SENDWAIT;
149                   end
150                
151                `SENDWAIT:
152                   begin
153                      rdreq <= 1;
154                      reader_next_state <= `SEND; 
155                   end
156                
157                                 // Send the samples to the tx_chain
158                `SEND:
159                   begin
160                      reader_next_state <= `WAITSTROBE; 
161                      rdreq <= 0;
162                      read_len <= read_len + 2;
163                      case(samples_format)
164                         `QI16:
165                            begin
166                               tx_q <= qsample ? fifodata : 16'bZ;
167                               tx_i <= ~qsample ? fifodata : 16'bZ;
168                               qsample <= ~ qsample;
169                            end  
170                         default:
171                            begin
172                                // Assume 16 bits complex samples by default
173                               $display ("Error unknown samples format");
174                               tx_q <= qsample ? fifodata : 16'bZ;
175                               tx_i <= ~qsample ? fifodata : 16'bZ;
176                               qsample <= ~ qsample;
177                            end 
178                      endcase
179                   end
180
181                `DISCARD:
182                   begin
183                      skip <= 0;
184                      reader_next_state <= `IDLE;
185                   end
186                
187                default:
188                   begin
189                      $display ("Error unknown state");
190                      reader_state <= `IDLE;
191                      reader_next_state <= `IDLE;
192                   end
193            endcase
194        end
195    end
196  
197 endmodule