OpenCores
URL https://opencores.org/ocsvn/usb_device_core/usb_device_core/trunk

Subversion Repositories usb_device_core

[/] [usb_device_core/] [trunk/] [src_v/] [usbf_sie_rx.v] - Blame information for rev 5

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 5 ultra_embe
//-----------------------------------------------------------------
2
//                       USB Device Core
3
//                           V1.0
4
//                     Ultra-Embedded.com
5
//                     Copyright 2014-2019
6
//
7
//                 Email: admin@ultra-embedded.com
8
//
9
//                         License: GPL
10
// If you would like a version with a more permissive license for
11
// use in closed source commercial applications please contact me
12
// for details.
13
//-----------------------------------------------------------------
14
//
15
// This file is open source HDL; you can redistribute it and/or 
16
// modify it under the terms of the GNU General Public License as 
17
// published by the Free Software Foundation; either version 2 of 
18
// the License, or (at your option) any later version.
19
//
20
// This file is distributed in the hope that it will be useful,
21
// but WITHOUT ANY WARRANTY; without even the implied warranty of
22
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23
// GNU General Public License for more details.
24
//
25
// You should have received a copy of the GNU General Public 
26
// License along with this file; if not, write to the Free Software
27
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
28
// USA
29
//-----------------------------------------------------------------
30
 
31
//-----------------------------------------------------------------
32
//                          Generated File
33
//-----------------------------------------------------------------
34
 
35
module usbf_sie_rx
36
(
37
    // Inputs
38
     input           clk_i
39
    ,input           rst_i
40
    ,input           enable_i
41
    ,input  [  7:0]  utmi_data_i
42
    ,input           utmi_rxvalid_i
43
    ,input           utmi_rxactive_i
44
    ,input  [  6:0]  current_addr_i
45
 
46
    // Outputs
47
    ,output [  7:0]  pid_o
48
    ,output          frame_valid_o
49
    ,output [ 10:0]  frame_number_o
50
    ,output          token_valid_o
51
    ,output [  6:0]  token_addr_o
52
    ,output [  3:0]  token_ep_o
53
    ,output          token_crc_err_o
54
    ,output          handshake_valid_o
55
    ,output          data_valid_o
56
    ,output          data_strb_o
57
    ,output [  7:0]  data_o
58
    ,output          data_last_o
59
    ,output          data_crc_err_o
60
    ,output          data_complete_o
61
);
62
 
63
 
64
 
65
//-----------------------------------------------------------------
66
// Defines:
67
//-----------------------------------------------------------------
68
`include "usbf_defs.v"
69
 
70
localparam STATE_W                       = 4;
71
localparam STATE_RX_IDLE                 = 4'd0;
72
localparam STATE_RX_TOKEN2               = 4'd1;
73
localparam STATE_RX_TOKEN3               = 4'd2;
74
localparam STATE_RX_TOKEN_COMPLETE       = 4'd3;
75
localparam STATE_RX_SOF2                 = 4'd4;
76
localparam STATE_RX_SOF3                 = 4'd5;
77
localparam STATE_RX_DATA                 = 4'd6;
78
localparam STATE_RX_DATA_COMPLETE        = 4'd7;
79
localparam STATE_RX_IGNORED              = 4'd8;
80
reg [STATE_W-1:0] state_q;
81
 
82
//-----------------------------------------------------------------
83
// Wire / Regs
84
//-----------------------------------------------------------------
85
`define USB_FRAME_W    11
86
reg [`USB_FRAME_W-1:0]      frame_num_q;
87
 
88
`define USB_DEV_W      7
89
reg [`USB_DEV_W-1:0]        token_dev_q;
90
 
91
`define USB_EP_W       4
92
reg [`USB_EP_W-1:0]         token_ep_q;
93
 
94
`define USB_PID_W      8
95
reg [`USB_PID_W-1:0]        token_pid_q;
96
 
97
//-----------------------------------------------------------------
98
// Data delay (to strip the CRC16 trailing bytes)
99
//-----------------------------------------------------------------
100
reg [31:0] data_buffer_q;
101
reg [3:0]  data_valid_q;
102
reg [3:0]  rx_active_q;
103
 
104
wire shift_en_w = (utmi_rxvalid_i & utmi_rxactive_i) || !utmi_rxactive_i;
105
 
106
always @ (posedge clk_i or posedge rst_i)
107
if (rst_i)
108
    data_buffer_q <= 32'b0;
109
else if (shift_en_w)
110
    data_buffer_q <= {utmi_data_i, data_buffer_q[31:8]};
111
 
112
always @ (posedge clk_i or posedge rst_i)
113
if (rst_i)
114
    data_valid_q <= 4'b0;
115
else if (shift_en_w)
116
    data_valid_q <= {(utmi_rxvalid_i & utmi_rxactive_i), data_valid_q[3:1]};
117
else
118
    data_valid_q <= {data_valid_q[3:1], 1'b0};
119
 
120
reg [1:0] data_crc_q;
121
always @ (posedge clk_i or posedge rst_i)
122
if (rst_i)
123
    data_crc_q <= 2'b0;
124
else if (shift_en_w)
125
    data_crc_q <= {!utmi_rxactive_i, data_crc_q[1]};
126
 
127
always @ (posedge clk_i or posedge rst_i)
128
if (rst_i)
129
    rx_active_q <= 4'b0;
130
else
131
    rx_active_q <= {utmi_rxactive_i, rx_active_q[3:1]};
132
 
133
wire [7:0] data_w       = data_buffer_q[7:0];
134
wire       data_ready_w = data_valid_q[0];
135
wire       crc_byte_w   = data_crc_q[0];
136
wire       rx_active_w  = rx_active_q[0];
137
 
138
wire       address_match_w = (token_dev_q == current_addr_i);
139
 
140
//-----------------------------------------------------------------
141
// Next state
142
//-----------------------------------------------------------------
143
reg [STATE_W-1:0] next_state_r;
144
 
145
always @ *
146
begin
147
    next_state_r = state_q;
148
 
149
    case (state_q)
150
 
151
    //-----------------------------------------
152
    // IDLE
153
    //-----------------------------------------
154
    STATE_RX_IDLE :
155
    begin
156
       if (data_ready_w)
157
       begin
158
           // Decode PID
159
           case (data_w)
160
 
161
              `PID_OUT, `PID_IN, `PID_SETUP, `PID_PING:
162
                    next_state_r  = STATE_RX_TOKEN2;
163
 
164
              `PID_SOF:
165
                    next_state_r  = STATE_RX_SOF2;
166
 
167
              `PID_DATA0, `PID_DATA1, `PID_DATA2, `PID_MDATA:
168
              begin
169
                    next_state_r  = STATE_RX_DATA;
170
              end
171
 
172
              `PID_ACK, `PID_NAK, `PID_STALL, `PID_NYET:
173
                    next_state_r  = STATE_RX_IDLE;
174
 
175
              default : // SPLIT / ERR
176
                    next_state_r  = STATE_RX_IGNORED;
177
           endcase
178
       end
179
    end
180
 
181
    //-----------------------------------------
182
    // RX_IGNORED: Unknown / unsupported
183
    //-----------------------------------------
184
    STATE_RX_IGNORED :
185
    begin
186
        // Wait until the end of the packet
187
        if (!rx_active_w)
188
           next_state_r = STATE_RX_IDLE;
189
    end
190
 
191
    //-----------------------------------------
192
    // SOF (BYTE 2)
193
    //-----------------------------------------
194
    STATE_RX_SOF2 :
195
    begin
196
       if (data_ready_w)
197
           next_state_r = STATE_RX_SOF3;
198
       else if (!rx_active_w)
199
           next_state_r = STATE_RX_IDLE;
200
    end
201
 
202
    //-----------------------------------------
203
    // SOF (BYTE 3)
204
    //-----------------------------------------
205
    STATE_RX_SOF3 :
206
    begin
207
       if (data_ready_w || !rx_active_w)
208
           next_state_r = STATE_RX_IDLE;
209
    end
210
 
211
    //-----------------------------------------
212
    // TOKEN (IN/OUT/SETUP) (Address/Endpoint)
213
    //-----------------------------------------
214
    STATE_RX_TOKEN2 :
215
    begin
216
       if (data_ready_w)
217
           next_state_r = STATE_RX_TOKEN3;
218
       else if (!rx_active_w)
219
           next_state_r = STATE_RX_IDLE;
220
    end
221
 
222
    //-----------------------------------------
223
    // TOKEN (IN/OUT/SETUP) (Endpoint/CRC)
224
    //-----------------------------------------
225
    STATE_RX_TOKEN3 :
226
    begin
227
       if (data_ready_w)
228
           next_state_r = STATE_RX_TOKEN_COMPLETE;
229
       else if (!rx_active_w)
230
           next_state_r = STATE_RX_IDLE;
231
    end
232
 
233
    //-----------------------------------------
234
    // RX_TOKEN_COMPLETE
235
    //-----------------------------------------
236
    STATE_RX_TOKEN_COMPLETE :
237
    begin
238
        next_state_r  = STATE_RX_IDLE;
239
    end
240
 
241
    //-----------------------------------------
242
    // RX_DATA
243
    //-----------------------------------------
244
    STATE_RX_DATA :
245
    begin
246
       // Receive complete
247
       if (crc_byte_w)
248
            next_state_r = STATE_RX_DATA_COMPLETE;
249
    end
250
 
251
    //-----------------------------------------
252
    // RX_DATA_COMPLETE
253
    //-----------------------------------------
254
    STATE_RX_DATA_COMPLETE :
255
    begin
256
        if (!rx_active_w)
257
            next_state_r = STATE_RX_IDLE;
258
    end
259
 
260
    default :
261
       ;
262
 
263
    endcase
264
end
265
 
266
// Update state
267
always @ (posedge clk_i or posedge rst_i)
268
if (rst_i)
269
    state_q   <= STATE_RX_IDLE;
270
else if (!enable_i)
271
    state_q   <= STATE_RX_IDLE;
272
else
273
    state_q   <= next_state_r;
274
 
275
//-----------------------------------------------------------------
276
// Handshake:
277
//-----------------------------------------------------------------
278
reg handshake_valid_q;
279
 
280
always @ (posedge clk_i or posedge rst_i)
281
if (rst_i)
282
    handshake_valid_q <= 1'b0;
283
else if (state_q == STATE_RX_IDLE && data_ready_w)
284
begin
285
    case (data_w)
286
    `PID_ACK, `PID_NAK, `PID_STALL, `PID_NYET:
287
        handshake_valid_q <= address_match_w;
288
    default :
289
        handshake_valid_q <= 1'b0;
290
    endcase
291
end
292
else
293
    handshake_valid_q <= 1'b0;
294
 
295
assign handshake_valid_o = handshake_valid_q;
296
 
297
//-----------------------------------------------------------------
298
// SOF: Frame number
299
//-----------------------------------------------------------------
300
always @ (posedge clk_i or posedge rst_i)
301
if (rst_i)
302
    frame_num_q         <= `USB_FRAME_W'b0;
303
else if (state_q == STATE_RX_SOF2 && data_ready_w)
304
    frame_num_q         <= {3'b0, data_w};
305
else if (state_q == STATE_RX_SOF3 && data_ready_w)
306
    frame_num_q         <= {data_w[2:0], frame_num_q[7:0]};
307
else if (!enable_i)
308
    frame_num_q         <= `USB_FRAME_W'b0;
309
 
310
assign frame_number_o = frame_num_q;
311
 
312
reg frame_valid_q;
313
 
314
always @ (posedge clk_i or posedge rst_i)
315
if (rst_i)
316
    frame_valid_q <= 1'b0;
317
else
318
    frame_valid_q <= (state_q == STATE_RX_SOF3 && data_ready_w);
319
 
320
assign frame_valid_o = frame_valid_q;
321
 
322
//-----------------------------------------------------------------
323
// Token: PID
324
//-----------------------------------------------------------------
325
always @ (posedge clk_i or posedge rst_i)
326
if (rst_i)
327
    token_pid_q <= `USB_PID_W'b0;
328
else if (state_q == STATE_RX_IDLE && data_ready_w)
329
    token_pid_q <= data_w;
330
else if (!enable_i)
331
    token_pid_q <= `USB_PID_W'b0;
332
 
333
assign pid_o = token_pid_q;
334
 
335
reg token_valid_q;
336
 
337
always @ (posedge clk_i or posedge rst_i)
338
if (rst_i)
339
    token_valid_q <= 1'b0;
340
else
341
    token_valid_q <= (state_q == STATE_RX_TOKEN_COMPLETE) && address_match_w;
342
 
343
assign token_valid_o = token_valid_q;
344
 
345
//-----------------------------------------------------------------
346
// Token: Device Address
347
//-----------------------------------------------------------------
348
always @ (posedge clk_i or posedge rst_i)
349
if (rst_i)
350
    token_dev_q <= `USB_DEV_W'b0;
351
else if (state_q == STATE_RX_TOKEN2 && data_ready_w)
352
    token_dev_q <= data_w[6:0];
353
else if (!enable_i)
354
    token_dev_q <= `USB_DEV_W'b0;
355
 
356
assign token_addr_o = token_dev_q;
357
 
358
//-----------------------------------------------------------------
359
// Token: Endpoint
360
//-----------------------------------------------------------------
361
always @ (posedge clk_i or posedge rst_i)
362
if (rst_i)
363
    token_ep_q      <= `USB_EP_W'b0;
364
else if (state_q == STATE_RX_TOKEN2 && data_ready_w)
365
    token_ep_q[0]   <= data_w[7];
366
else if (state_q == STATE_RX_TOKEN3 && data_ready_w)
367
    token_ep_q[3:1] <= data_w[2:0];
368
else if (!enable_i)
369
    token_ep_q      <= `USB_EP_W'b0;
370
 
371
assign token_ep_o = token_ep_q;
372
assign token_crc_err_o = 1'b0;
373
 
374
wire [7:0] input_data_w  = data_w;
375
wire       input_ready_w = state_q == STATE_RX_DATA && data_ready_w && !crc_byte_w;
376
 
377
//-----------------------------------------------------------------
378
// CRC16: Generate CRC16 on incoming data bytes
379
//-----------------------------------------------------------------
380
reg [15:0]  crc_sum_q;
381
wire [15:0] crc_out_w;
382
reg         crc_err_q;
383
 
384
usbf_crc16
385
u_crc16
386
(
387
    .crc_in_i(crc_sum_q),
388
    .din_i(data_w),
389
    .crc_out_o(crc_out_w)
390
);
391
 
392
always @ (posedge clk_i or posedge rst_i)
393
if (rst_i)
394
    crc_sum_q   <= 16'hFFFF;
395
else if (state_q == STATE_RX_IDLE)
396
    crc_sum_q   <= 16'hFFFF;
397
else if (data_ready_w)
398
    crc_sum_q   <= crc_out_w;
399
 
400
always @ (posedge clk_i or posedge rst_i)
401
if (rst_i)
402
    crc_err_q   <= 1'b0;
403
else if (state_q == STATE_RX_IDLE)
404
    crc_err_q   <= 1'b0;
405
else if (state_q == STATE_RX_DATA_COMPLETE && next_state_r == STATE_RX_IDLE)
406
    crc_err_q   <= (crc_sum_q != 16'hB001);
407
 
408
assign data_crc_err_o = crc_err_q;
409
 
410
reg data_complete_q;
411
 
412
always @ (posedge clk_i or posedge rst_i)
413
if (rst_i)
414
    data_complete_q   <= 1'b0;
415
else if (state_q == STATE_RX_DATA_COMPLETE && next_state_r == STATE_RX_IDLE)
416
    data_complete_q   <= 1'b1;
417
else
418
    data_complete_q   <= 1'b0;
419
 
420
assign data_complete_o = data_complete_q;
421
 
422
reg data_zlp_q;
423
 
424
always @ (posedge clk_i or posedge rst_i)
425
if (rst_i)
426
    data_zlp_q   <= 1'b0;
427
else if (state_q == STATE_RX_IDLE && next_state_r == STATE_RX_DATA)
428
    data_zlp_q   <= 1'b1;
429
else if (input_ready_w)
430
    data_zlp_q   <= 1'b0;
431
 
432
//-----------------------------------------------------------------
433
// Data Output
434
//-----------------------------------------------------------------
435
reg        valid_q;
436
reg        last_q;
437
reg [7:0]  data_q;
438
reg        mask_q;
439
 
440
always @ (posedge clk_i or posedge rst_i)
441
if (rst_i)
442
begin
443
    valid_q  <= 1'b0;
444
    data_q   <= 8'b0;
445
    mask_q   <= 1'b0;
446
    last_q   <= 1'b0;
447
end
448
else
449
begin
450
    valid_q  <= input_ready_w || ((state_q == STATE_RX_DATA) && crc_byte_w && data_zlp_q);
451
    data_q   <= input_data_w;
452
    mask_q   <= input_ready_w;
453
    last_q   <= (state_q == STATE_RX_DATA) && crc_byte_w;
454
end
455
 
456
// Data
457
assign data_valid_o = valid_q;
458
assign data_strb_o  = mask_q;
459
assign data_o       = data_q;
460
assign data_last_o  = last_q | crc_byte_w;
461
 
462
 
463
endmodule

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.