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

	`define OP_PING_FIXED				8'd0
	`define OP_PING_FIXED_REPLY			8'd1
	`define OP_WRITE_REG				8'd2
	`define OP_WRITE_REG_MASKED			8'd3
	`define OP_READ_REG					8'd4
	`define OP_READ_REG_REPLY			8'd5
	`define OP_DELAY					8'd12
	
	reg [6:0] 	payload;
	reg [6:0] 	payload_read;
	reg [3:0] 	state;
	reg [15:0]  high;
	reg [15:0]	low;
	reg			pending;
	reg [31:0]  value0;
	reg [31:0]	value1;
	reg [31:0]	value2;
	reg [1:0]   lines_in;
	reg [1:0]	lines_out;
	reg [1:0] 	lines_out_total;
	
	`define JITTER                      5
	`define OP_CODE						31:24
	`define PAYLOAD   					8:2
	
	wire [7:0] ops;
	assign ops = value0[`OP_CODE];
	assign debug = {state[3:0], lines_out[1:0], pending, rx_WR, rx_WR_enabled, value0[2:0], ops[2:0]};
	
	always @(posedge txclk)
		if (reset)
		  begin
			pending <= 0;
		    state <= IDLE;
			skip <= 0;
			rdreq <= 0;
			rx_WR <= 0;
			reg_io_enable <= 0;
			reg_data_in <= 0;
			reg_addr <= 0;
		  end
		else case (state)
			IDLE : begin
				payload_read <= 0;
				skip <= 0;
				lines_in <= 0;
				if (pkt_waiting)
				  begin
					state <= HEADER;
					rdreq <= 1;
				  end
			end
			
			HEADER : begin
				payload <= fifodata[`PAYLOAD];
				state <= TIMESTAMP;
			end
			
			TIMESTAMP : begin
				value0 <= fifodata;
				state <= WAIT;
				rdreq <= 0;
			end
			
			WAIT : begin
  					// Let's send it
                   if ((value0 <= adc_time + `JITTER 
                             && value0 > adc_time)
                             || value0 == 32'hFFFFFFFF)
                       state <= TEST;
                   // Wait a little bit more
                   else if (value0 > adc_time + `JITTER)
                       state <= WAIT; 
                   // Outdated
                   else if (value0 < adc_time)
                     begin
                        state <= IDLE;
                        skip <= 1;
                     end
			end
			
			TEST : begin
				reg_io_enable <= 0;
				rx_WR <= 0;
				rx_WR_done <= 1;
				if (payload_read == payload)
					begin
						skip <= 1;
						state <= IDLE;
						rdreq <= 0;
					end
				else
					begin
						value0 <= fifodata;
						lines_in <= 2'd1;
						rdreq <= 1;
						payload_read <= payload_read + 7'd1;
						lines_out <= 0;
						case (fifodata[`OP_CODE])
							`OP_PING_FIXED: begin
								state <= PING;
							end
							`OP_WRITE_REG: begin
								state <= WRITE_REG;
								pending <= 1;
							end
							`OP_WRITE_REG_MASKED: begin
								state <= WRITE_REG_MASKED;
								pending <= 1;
							end
							`OP_READ_REG: begin
								state <= READ_REG;
							end
							`OP_DELAY: begin
								state <= DELAY;
							end
							default: begin
							//error, skip this packet
								skip <= 1;
								state <= IDLE;
							end
						endcase
					end
			end
			
			SEND: begin
				rdreq <= 0;
				rx_WR_done <= 0;
				if (pending)
					begin
						rx_WR <= 1;
						rx_databus <= high;
						pending <= 0;
						if (lines_out == lines_out_total)
							state <= TEST;
						else case (ops)
							`OP_READ_REG: begin
								state <= READ_REG;
							end
							default: begin
								state <= TEST;
							end
						endcase
					end
				else
					begin
						if (rx_WR_enabled)
						begin
							rx_WR <= 1;
							rx_databus <= low;
							pending <= 1;
							lines_out <= lines_out + 2'd1;
						end
						else
							rx_WR <= 0;
					end
			end
			
			PING: begin
				rx_WR <= 0;
				rdreq <= 0;
				rx_WR_done <= 0;
				lines_out_total <= 2'd1;
				pending <= 0;
				state <= SEND;
				high <= {`OP_PING_FIXED_REPLY, 8'd2};
				low <= value0[15:0];	
			end
			
			READ_REG: begin
				rx_WR <= 0;
				rx_WR_done <= 0;
				rdreq <= 0;
				lines_out_total <= 2'd2;
				pending <= 0;
				state <= SEND;
				if (lines_out == 0)
					begin
						high <= {`OP_READ_REG_REPLY, 8'd6};
						low <= value0[15:0];
						reg_io_enable <= 2'd3;
						reg_addr <= value0[6:0];
					end
				else
					begin		
						high <= reg_data_out[31:16];
						low <= reg_data_out[15:0];
					end
			end
			
			WRITE_REG: begin
				rx_WR <= 0;
				if (pending)
					pending <= 0;
				else
					begin
						if (lines_in == 2'd1)
						begin
							payload_read <= payload_read + 7'd1;
							lines_in <= lines_in + 2'd1;
							value1 <= fifodata;
							rdreq <= 0;
						end
						else
						begin
							reg_io_enable <= 2'd2;
							reg_data_in <= value1;
							reg_addr <= value0[6:0];
							state <= TEST;
						end
					end
			end
			
			WRITE_REG_MASKED: begin
				rx_WR <= 0;
				if (pending)
					pending <= 0;
				else
					begin
						if (lines_in == 2'd1)
						begin
							rdreq <= 1;
							payload_read <= payload_read + 7'd1;
							lines_in <= lines_in + 2'd1;
							value1 <= fifodata;
						end
						else if (lines_in == 2'd2)
						begin
							rdreq <= 0;
							payload_read <= payload_read + 7'd1;
							lines_in <= lines_in + 2'd1;
							value2 <= fifodata;
						end
						else
						begin
							reg_io_enable <= 2'd2;
							reg_data_in <= (value1 & value2);
							reg_addr <= value0[6:0];
							state <= TEST;
						end
					end
			end
			
			DELAY : begin
				rdreq <= 0;
				value1 <= value1 + 32'd1;
				if (value0[15:0] == value1[15:0])
					state <= TEST;
			end
			
			default : begin
				//error state handling
				state <= IDLE;
			end
		endcase
endmodule