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

Subversion Repositories opb_usblite

[/] [opb_usblite/] [trunk/] [pcores/] [opb_usblite_v1_00_a/] [hdl/] [verilog/] [usb_rx_phy.v] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 rehnmaak
/////////////////////////////////////////////////////////////////////
2
////                                                             ////
3
////  USB 1.1 PHY                                                ////
4
////  RX & DPLL                                                  ////
5
////                                                             ////
6
////                                                             ////
7
////  Author: Rudolf Usselmann                                   ////
8
////          rudi@asics.ws                                      ////
9
////                                                             ////
10
////                                                             ////
11
////  Downloaded from: http://www.opencores.org/cores/usb_phy/   ////
12
////                                                             ////
13
/////////////////////////////////////////////////////////////////////
14
////                                                             ////
15
//// Copyright (C) 2000-2002 Rudolf Usselmann                    ////
16
////                         www.asics.ws                        ////
17
////                         rudi@asics.ws                       ////
18
////                                                             ////
19
//// This source file may be used and distributed without        ////
20
//// restriction provided that this copyright statement is not   ////
21
//// removed from the file and that any derivative work contains ////
22
//// the original copyright notice and the associated disclaimer.////
23
////                                                             ////
24
////     THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY     ////
25
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED   ////
26
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS   ////
27
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR      ////
28
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,         ////
29
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    ////
30
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE   ////
31
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR        ////
32
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF  ////
33
//// LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT  ////
34
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT  ////
35
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE         ////
36
//// POSSIBILITY OF SUCH DAMAGE.                                 ////
37
////                                                             ////
38
/////////////////////////////////////////////////////////////////////
39
 
40
//  CVS Log
41
//
42
//  $Id: usb_rx_phy.v,v 1.5 2004/10/19 09:29:07 rudi Exp $
43
//
44
//  $Date: 2004/10/19 09:29:07 $
45
//  $Revision: 1.5 $
46
//  $Author: rudi $
47
//  $Locker:  $
48
//  $State: Exp $
49
//
50
// Change History:
51
//               $Log: usb_rx_phy.v,v $
52
//               Revision 1.5  2004/10/19 09:29:07  rudi
53
//               Fixed DPLL alignment in the rx_phy and bit stuffing errors in the tx_phy (if last bit bit was a stuff bit in a packet it was omitted).
54
//
55
//               Revision 1.4  2003/12/02 04:56:00  rudi
56
//               Fixed a bug reported by Karl C. Posch from Graz University of Technology. Thanks Karl !
57
//
58
//               Revision 1.3  2003/10/19 18:07:45  rudi
59
//               - Fixed Sync Error to be only checked/generated during the sync phase
60
//
61
//               Revision 1.2  2003/10/19 17:40:13  rudi
62
//               - Made core more robust against line noise
63
//               - Added Error Checking and Reporting
64
//               (See README.txt for more info)
65
//
66
//               Revision 1.1.1.1  2002/09/16 14:27:01  rudi
67
//               Created Directory Structure
68
//
69
//
70
//
71
//
72
//
73
//
74
//
75
//
76
 
77
`include "timescale.v"
78
 
79
module usb_rx_phy(      clk, rst, fs_ce,
80
 
81
                        // Transciever Interface
82
                        rxd, rxdp, rxdn,
83
 
84
                        // UTMI Interface
85
                        RxValid_o, RxActive_o, RxError_o, DataIn_o,
86
                        RxEn_i, LineState);
87
 
88
input           clk;
89
input           rst;
90
output          fs_ce;
91
input           rxd, rxdp, rxdn;
92
output  [7:0]    DataIn_o;
93
output          RxValid_o;
94
output          RxActive_o;
95
output          RxError_o;
96
input           RxEn_i;
97
output  [1:0]    LineState;
98
 
99
///////////////////////////////////////////////////////////////////
100
//
101
// Local Wires and Registers
102
//
103
 
104
reg             rxd_s0, rxd_s1,  rxd_s;
105
reg             rxdp_s0, rxdp_s1, rxdp_s, rxdp_s_r;
106
reg             rxdn_s0, rxdn_s1, rxdn_s, rxdn_s_r;
107
reg             synced_d;
108
wire            k, j, se0;
109
reg             rxd_r;
110
reg             rx_en;
111
reg             rx_active;
112
reg     [2:0]    bit_cnt;
113
reg             rx_valid1, rx_valid;
114
reg             shift_en;
115
reg             sd_r;
116
reg             sd_nrzi;
117
reg     [7:0]    hold_reg;
118
wire            drop_bit;       // Indicates a stuffed bit
119
reg     [2:0]    one_cnt;
120
 
121
reg     [1:0]    dpll_state, dpll_next_state;
122
reg             fs_ce_d;
123
reg             fs_ce;
124
wire            change;
125
wire            lock_en;
126
reg     [2:0]    fs_state, fs_next_state;
127
reg             rx_valid_r;
128
reg             sync_err_d, sync_err;
129
reg             bit_stuff_err;
130
reg             se0_r, byte_err;
131
reg             se0_s;
132
 
133
///////////////////////////////////////////////////////////////////
134
//
135
// Misc Logic
136
//
137
 
138
assign RxActive_o = rx_active;
139
assign RxValid_o = rx_valid;
140
assign RxError_o = sync_err | bit_stuff_err | byte_err;
141
assign DataIn_o = hold_reg;
142
assign LineState = {rxdn_s1, rxdp_s1};
143
 
144
always @(posedge clk)   rx_en <= RxEn_i;
145
always @(posedge clk)   sync_err <= !rx_active & sync_err_d;
146
 
147
///////////////////////////////////////////////////////////////////
148
//
149
// Synchronize Inputs
150
//
151
 
152
// First synchronize to the local system clock to
153
// avoid metastability outside the sync block (*_s0).
154
// Then make sure we see the signal for at least two
155
// clock cycles stable to avoid glitches and noise
156
 
157
always @(posedge clk)   rxd_s0  <= rxd;
158
always @(posedge clk)   rxd_s1  <= rxd_s0;
159
always @(posedge clk)                                                   // Avoid detecting Line Glitches and noise
160
        if(rxd_s0 && rxd_s1)    rxd_s <= 1'b1;
161
        else
162
        if(!rxd_s0 && !rxd_s1)  rxd_s <= 1'b0;
163
 
164
always @(posedge clk)   rxdp_s0  <= rxdp;
165
always @(posedge clk)   rxdp_s1  <= rxdp_s0;
166
always @(posedge clk)   rxdp_s_r <= rxdp_s0 & rxdp_s1;
167
always @(posedge clk)   rxdp_s   <= (rxdp_s0 & rxdp_s1) | rxdp_s_r;     // Avoid detecting Line Glitches and noise
168
 
169
always @(posedge clk)   rxdn_s0  <= rxdn;
170
always @(posedge clk)   rxdn_s1  <= rxdn_s0;
171
always @(posedge clk)   rxdn_s_r <= rxdn_s0 & rxdn_s1;
172
always @(posedge clk)   rxdn_s   <= (rxdn_s0 & rxdn_s1) | rxdn_s_r;     // Avoid detecting Line Glitches and noise
173
 
174
assign k = !rxdp_s &  rxdn_s;
175
assign j =  rxdp_s & !rxdn_s;
176
assign se0 = !rxdp_s & !rxdn_s;
177
 
178
always @(posedge clk)   if(fs_ce)       se0_s <= se0;
179
 
180
///////////////////////////////////////////////////////////////////
181
//
182
// DPLL
183
//
184
 
185
// This design uses a clock enable to do 12Mhz timing and not a
186
// real 12Mhz clock. Everything always runs at 48Mhz. We want to
187
// make sure however, that the clock enable is always exactly in
188
// the middle between two virtual 12Mhz rising edges.
189
// We monitor rxdp and rxdn for any changes and do the appropiate
190
// adjustments.
191
// In addition to the locking done in the dpll FSM, we adjust the
192
// final latch enable to compensate for various sync registers ...
193
 
194
// Allow lockinf only when we are receiving
195
assign  lock_en = rx_en;
196
 
197
always @(posedge clk)   rxd_r <= rxd_s;
198
 
199
// Edge detector
200
assign change = rxd_r != rxd_s;
201
 
202
// DPLL FSM
203
`ifdef USB_ASYNC_REST
204
always @(posedge clk or negedge rst)
205
`else
206
always @(posedge clk)
207
`endif
208
        if(!rst)        dpll_state <= 2'h1;
209
        else            dpll_state <= dpll_next_state;
210
 
211
always @(dpll_state or lock_en or change)
212
   begin
213
        fs_ce_d = 1'b0;
214
        case(dpll_state)        // synopsys full_case parallel_case
215
           2'h0:
216
                if(lock_en && change)   dpll_next_state = 2'h0;
217
                else                    dpll_next_state = 2'h1;
218
           2'h1:begin
219
                fs_ce_d = 1'b1;
220
                if(lock_en && change)   dpll_next_state = 2'h3;
221
                else                    dpll_next_state = 2'h2;
222
                end
223
           2'h2:
224
                if(lock_en && change)   dpll_next_state = 2'h0;
225
                else                    dpll_next_state = 2'h3;
226
           2'h3:
227
                if(lock_en && change)   dpll_next_state = 2'h0;
228
                else                    dpll_next_state = 2'h0;
229
        endcase
230
   end
231
 
232
// Compensate for sync registers at the input - allign full speed
233
// clock enable to be in the middle between two bit changes ...
234
reg     fs_ce_r1, fs_ce_r2;
235
 
236
always @(posedge clk)   fs_ce_r1 <= fs_ce_d;
237
always @(posedge clk)   fs_ce_r2 <= fs_ce_r1;
238
always @(posedge clk)   fs_ce <= fs_ce_r2;
239
 
240
 
241
///////////////////////////////////////////////////////////////////
242
//
243
// Find Sync Pattern FSM
244
//
245
 
246
parameter       FS_IDLE = 3'h0,
247
                K1      = 3'h1,
248
                J1      = 3'h2,
249
                K2      = 3'h3,
250
                J2      = 3'h4,
251
                K3      = 3'h5,
252
                J3      = 3'h6,
253
                K4      = 3'h7;
254
 
255
`ifdef USB_ASYNC_REST
256
always @(posedge clk or negedge rst)
257
`else
258
always @(posedge clk)
259
`endif
260
        if(!rst)        fs_state <= FS_IDLE;
261
        else            fs_state <= fs_next_state;
262
 
263
always @(fs_state or fs_ce or k or j or rx_en or rx_active or se0 or se0_s)
264
   begin
265
        synced_d = 1'b0;
266
        sync_err_d = 1'b0;
267
        fs_next_state = fs_state;
268
        if(fs_ce && !rx_active && !se0 && !se0_s)
269
           case(fs_state)       // synopsys full_case parallel_case
270
                FS_IDLE:
271
                     begin
272
                        if(k && rx_en)  fs_next_state = K1;
273
                     end
274
                K1:
275
                     begin
276
                        if(j && rx_en)  fs_next_state = J1;
277
                        else
278
                           begin
279
                                        sync_err_d = 1'b1;
280
                                        fs_next_state = FS_IDLE;
281
                           end
282
                     end
283
                J1:
284
                     begin
285
                        if(k && rx_en)  fs_next_state = K2;
286
                        else
287
                           begin
288
                                        sync_err_d = 1'b1;
289
                                        fs_next_state = FS_IDLE;
290
                           end
291
                     end
292
                K2:
293
                     begin
294
                        if(j && rx_en)  fs_next_state = J2;
295
                        else
296
                           begin
297
                                        sync_err_d = 1'b1;
298
                                        fs_next_state = FS_IDLE;
299
                           end
300
                     end
301
                J2:
302
                     begin
303
                        if(k && rx_en)  fs_next_state = K3;
304
                        else
305
                           begin
306
                                        sync_err_d = 1'b1;
307
                                        fs_next_state = FS_IDLE;
308
                           end
309
                     end
310
                K3:
311
                     begin
312
                        if(j && rx_en)  fs_next_state = J3;
313
                        else
314
                        if(k && rx_en)
315
                           begin
316
                                        fs_next_state = FS_IDLE;        // Allow missing first K-J
317
                                        synced_d = 1'b1;
318
                           end
319
                        else
320
                           begin
321
                                        sync_err_d = 1'b1;
322
                                        fs_next_state = FS_IDLE;
323
                           end
324
                     end
325
                J3:
326
                     begin
327
                        if(k && rx_en)  fs_next_state = K4;
328
                        else
329
                           begin
330
                                        sync_err_d = 1'b1;
331
                                        fs_next_state = FS_IDLE;
332
                           end
333
                     end
334
                K4:
335
                     begin
336
                        if(k)   synced_d = 1'b1;
337
                        fs_next_state = FS_IDLE;
338
                     end
339
           endcase
340
   end
341
 
342
///////////////////////////////////////////////////////////////////
343
//
344
// Generate RxActive
345
//
346
 
347
`ifdef USB_ASYNC_REST
348
always @(posedge clk or negedge rst)
349
`else
350
always @(posedge clk)
351
`endif
352
        if(!rst)                rx_active <= 1'b0;
353
        else
354
        if(synced_d && rx_en)   rx_active <= 1'b1;
355
        else
356
        if(se0 && rx_valid_r)   rx_active <= 1'b0;
357
 
358
always @(posedge clk)
359
        if(rx_valid)    rx_valid_r <= 1'b1;
360
        else
361
        if(fs_ce)       rx_valid_r <= 1'b0;
362
 
363
///////////////////////////////////////////////////////////////////
364
//
365
// NRZI Decoder
366
//
367
 
368
always @(posedge clk)
369
        if(fs_ce)       sd_r <= rxd_s;
370
 
371
`ifdef USB_ASYNC_REST
372
always @(posedge clk or negedge rst)
373
`else
374
always @(posedge clk)
375
`endif
376
        if(!rst)                sd_nrzi <= 1'b0;
377
        else
378
        if(!rx_active)          sd_nrzi <= 1'b1;
379
        else
380
        if(rx_active && fs_ce)  sd_nrzi <= !(rxd_s ^ sd_r);
381
 
382
///////////////////////////////////////////////////////////////////
383
//
384
// Bit Stuff Detect
385
//
386
 
387
`ifdef USB_ASYNC_REST
388
always @(posedge clk or negedge rst)
389
`else
390
always @(posedge clk)
391
`endif
392
        if(!rst)        one_cnt <= 3'h0;
393
        else
394
        if(!shift_en)   one_cnt <= 3'h0;
395
        else
396
        if(fs_ce)
397
           begin
398
                if(!sd_nrzi || drop_bit)        one_cnt <= 3'h0;
399
                else                            one_cnt <= one_cnt + 3'h1;
400
           end
401
 
402
assign drop_bit = (one_cnt==3'h6);
403
 
404
always @(posedge clk)   bit_stuff_err <= drop_bit & sd_nrzi & fs_ce & !se0 & rx_active; // Bit Stuff Error
405
 
406
///////////////////////////////////////////////////////////////////
407
//
408
// Serial => Parallel converter
409
//
410
 
411
always @(posedge clk)
412
        if(fs_ce)       shift_en <= synced_d | rx_active;
413
 
414
always @(posedge clk)
415
        if(fs_ce && shift_en && !drop_bit)
416
                hold_reg <= {sd_nrzi, hold_reg[7:1]};
417
 
418
///////////////////////////////////////////////////////////////////
419
//
420
// Generate RxValid
421
//
422
 
423
`ifdef USB_ASYNC_REST
424
always @(posedge clk or negedge rst)
425
`else
426
always @(posedge clk)
427
`endif
428
        if(!rst)                bit_cnt <= 3'b0;
429
        else
430
        if(!shift_en)           bit_cnt <= 3'h0;
431
        else
432
        if(fs_ce && !drop_bit)  bit_cnt <= bit_cnt + 3'h1;
433
 
434
`ifdef USB_ASYNC_REST
435
always @(posedge clk or negedge rst)
436
`else
437
always @(posedge clk)
438
`endif
439
        if(!rst)                                        rx_valid1 <= 1'b0;
440
        else
441
        if(fs_ce && !drop_bit && (bit_cnt==3'h7))       rx_valid1 <= 1'b1;
442
        else
443
        if(rx_valid1 && fs_ce && !drop_bit)             rx_valid1 <= 1'b0;
444
 
445
always @(posedge clk)   rx_valid <= !drop_bit & rx_valid1 & fs_ce;
446
 
447
always @(posedge clk)   se0_r <= se0;
448
 
449
always @(posedge clk)   byte_err <= se0 & !se0_r & (|bit_cnt[2:1]) & rx_active;
450
 
451
endmodule
452
 

powered by: WebSVN 2.1.0

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