Imported Upstream version 3.2.2
[debian/gnuradio] / usrp / fpga / inband_lib / cmd_reader.v
1 module cmd_reader
2    (//System
3     input reset, input txclk, input [31:0] timestamp_clock,
4     //FX2 Side
5     output reg skip, output reg rdreq, 
6     input [31:0] fifodata, input pkt_waiting,
7     //Rx side
8     input rx_WR_enabled, output reg [15:0] rx_databus,
9     output reg rx_WR, output reg rx_WR_done,
10     //register io
11     input wire [31:0] reg_data_out, output reg [31:0] reg_data_in,
12     output reg [6:0] reg_addr, output reg [1:0] reg_io_enable,
13     output wire [14:0] debug, output reg stop, output reg [15:0] stop_time);
14         
15    // States
16    parameter IDLE                       =   4'd0;
17    parameter HEADER                     =   4'd1;
18    parameter TIMESTAMP                  =   4'd2;
19    parameter WAIT                       =   4'd3;
20    parameter TEST                       =   4'd4;
21    parameter SEND                       =   4'd5;
22    parameter PING                       =   4'd6;
23    parameter WRITE_REG                  =   4'd7;
24    parameter WRITE_REG_MASKED           =   4'd8;
25    parameter READ_REG                   =   4'd9;
26    parameter DELAY                      =   4'd14;              
27
28    `define OP_PING_FIXED                    8'd0
29    `define OP_PING_FIXED_REPLY              8'd1
30    `define OP_WRITE_REG                     8'd2
31    `define OP_WRITE_REG_MASKED              8'd3
32    `define OP_READ_REG                      8'd4
33    `define OP_READ_REG_REPLY                8'd5
34    `define OP_DELAY                         8'd12
35         
36    reg [6:0]   payload;
37    reg [6:0]   payload_read;
38    reg [3:0]   state;
39    reg [15:0]  high;
40    reg [15:0]  low;
41    reg         pending;
42    reg [31:0]  value0;
43    reg [31:0]  value1;
44    reg [31:0]  value2;
45    reg [1:0]   lines_in;
46    reg [1:0]   lines_out;
47    reg [1:0]   lines_out_total;
48         
49    `define JITTER                           5
50    `define OP_CODE                          31:24
51    `define PAYLOAD                          8:2
52         
53    wire [7:0] ops;
54    assign ops = value0[`OP_CODE];
55    assign debug = {state[3:0], lines_out[1:0], pending, rx_WR, rx_WR_enabled, value0[2:0], ops[2:0]};
56         
57    always @(posedge txclk)
58        if (reset)
59          begin
60            pending <= 0;
61            state <= IDLE;
62            skip <= 0;
63            rdreq <= 0;
64            rx_WR <= 0;
65            reg_io_enable <= 0;
66            reg_data_in <= 0;
67            reg_addr <= 0;
68            stop <= 0;
69           end
70         else case (state)
71           IDLE : 
72             begin
73               payload_read <= 0;
74               skip <= 0;
75               lines_in <= 0;
76               if(pkt_waiting)
77                 begin
78                   state <= HEADER;
79                   rdreq <= 1;
80                 end
81              end
82           
83           HEADER : 
84             begin
85               payload <= fifodata[`PAYLOAD];
86               state <= TIMESTAMP;
87             end
88           
89           TIMESTAMP : 
90             begin
91               value0 <= fifodata;
92               state <= WAIT;
93               rdreq <= 0;
94             end
95                         
96           WAIT : 
97             begin
98               // Let's send it
99               if ((value0 <= timestamp_clock + `JITTER 
100                  && value0 > timestamp_clock)
101                  || value0 == 32'hFFFFFFFF)
102                   state <= TEST;
103               // Wait a little bit more
104               else if (value0 > timestamp_clock + `JITTER)
105                   state <= WAIT; 
106               // Outdated
107               else if (value0 < timestamp_clock)
108                 begin
109                   state <= IDLE;
110                   skip <= 1;
111                 end
112             end
113                         
114           TEST : 
115             begin
116               reg_io_enable <= 0;
117               rx_WR <= 0;
118               rx_WR_done <= 1;
119               stop <= 0;
120               if (payload_read == payload)
121                 begin
122                   skip <= 1;
123                   state <= IDLE;
124                   rdreq <= 0;
125                 end
126               else
127                 begin
128                   value0 <= fifodata;
129                   lines_in <= 2'd1;
130                   rdreq <= 1;
131                   payload_read <= payload_read + 7'd1;
132                   lines_out <= 0;
133                   case (fifodata[`OP_CODE])
134                     `OP_PING_FIXED: 
135                       begin
136                         state <= PING;
137                       end
138                     `OP_WRITE_REG: 
139                       begin
140                         state <= WRITE_REG;
141                         pending <= 1;
142                       end
143                     `OP_WRITE_REG_MASKED: 
144                       begin
145                         state <= WRITE_REG_MASKED;
146                         pending <= 1;
147                       end
148                     `OP_READ_REG: 
149                       begin
150                         state <= READ_REG;
151                       end
152                     `OP_DELAY: 
153                       begin
154                         state <= DELAY;
155                       end
156                     default: 
157                       begin
158                       //error, skip this packet
159                         skip <= 1;
160                         state <= IDLE;
161                       end
162                   endcase
163                 end
164               end
165                         
166             SEND: 
167               begin
168                 rdreq <= 0;
169                 rx_WR_done <= 0;
170                 if (pending)
171                   begin
172                     rx_WR <= 1;
173                     rx_databus <= high;
174                     pending <= 0;
175                     if (lines_out == lines_out_total)
176                         state <= TEST;
177                     else case (ops)
178                         `OP_READ_REG: 
179                           begin
180                             state <= READ_REG;
181                           end
182                          default: 
183                            begin
184                              state <= TEST;
185                            end
186                     endcase
187                   end
188                 else
189                   begin
190                     if (rx_WR_enabled)
191                       begin
192                         rx_WR <= 1;
193                         rx_databus <= low;
194                         pending <= 1;
195                         lines_out <= lines_out + 2'd1;
196                       end
197                     else
198                         rx_WR <= 0;
199                   end
200                 end
201                         
202             PING: 
203               begin
204                 rx_WR <= 0;
205                 rdreq <= 0;
206                 rx_WR_done <= 0;
207                 lines_out_total <= 2'd1;
208                 pending <= 0; 
209                 state <= SEND;
210                 high <= {`OP_PING_FIXED_REPLY, 8'd2};
211                 low <= value0[15:0];    
212               end
213                         
214             READ_REG: 
215               begin
216                 rx_WR <= 0;
217                 rx_WR_done <= 0;
218                 rdreq <= 0;
219                 lines_out_total <= 2'd2;
220                 pending <= 0;
221                 state <= SEND;
222                 if (lines_out == 0)
223                   begin
224                     high <= {`OP_READ_REG_REPLY, 8'd6};
225                     low <= value0[15:0];
226                     reg_io_enable <= 2'd3;
227                     reg_addr <= value0[6:0];
228                   end
229                 else
230                   begin         
231                     high <= reg_data_out[31:16];
232                     low <= reg_data_out[15:0];
233                   end
234              end    
235                         
236             WRITE_REG: 
237               begin
238                 rx_WR <= 0;
239                 if (pending)
240                     pending <= 0;
241                 else
242                   begin
243                     if (lines_in == 2'd1)
244                       begin
245                         payload_read <= payload_read + 7'd1;
246                         lines_in <= lines_in + 2'd1;
247                         value1 <= fifodata;
248                         rdreq <= 0;
249                       end
250                     else
251                       begin
252                         reg_io_enable <= 2'd2;
253                         reg_data_in <= value1;
254                         reg_addr <= value0[6:0];
255                         state <= TEST;
256                       end
257                   end
258               end
259                         
260             WRITE_REG_MASKED: 
261               begin
262                 rx_WR <= 0;
263                 if (pending)
264                     pending <= 0;
265                 else
266                   begin
267                     if (lines_in == 2'd1)
268                       begin
269                         rdreq <= 1;
270                         payload_read <= payload_read + 7'd1;
271                         lines_in <= lines_in + 2'd1;
272                         value1 <= fifodata;
273                       end
274                     else if (lines_in == 2'd2)
275                       begin
276                         rdreq <= 0;
277                         payload_read <= payload_read + 7'd1;
278                         lines_in <= lines_in + 2'd1;
279                         value2 <= fifodata;
280                       end
281                     else
282                       begin
283                         reg_io_enable <= 2'd2;
284                         reg_data_in <= (value1 & value2);
285                         reg_addr <= value0[6:0];
286                         state <= TEST;
287                       end
288                   end
289               end
290                         
291             DELAY : 
292               begin
293                 rdreq <= 0;
294                 stop <= 1;
295                 stop_time <= value0[15:0];
296                 state <= TEST;
297               end
298                         
299             default : 
300               begin
301                 //error state handling
302                 state <= IDLE;
303               end
304         endcase
305 endmodule