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

Subversion Repositories usb2uart

[/] [usb2uart/] [trunk/] [rtl/] [usb1_phy/] [usb_rx_phy.v] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 dinesha
/////////////////////////////////////////////////////////////////////
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: not supported by cvs2svn $
52
//               Revision 1.4  2003/12/02 04:56:00  rudi
53
//               Fixed a bug reported by Karl C. Posch from Graz University of Technology. Thanks Karl !
54
//
55
//               Revision 1.3  2003/10/19 18:07:45  rudi
56
//               - Fixed Sync Error to be only checked/generated during the sync phase
57
//
58
//               Revision 1.2  2003/10/19 17:40:13  rudi
59
//               - Made core more robust against line noise
60
//               - Added Error Checking and Reporting
61
//               (See README.txt for more info)
62
//
63
//               Revision 1.1.1.1  2002/09/16 14:27:01  rudi
64
//               Created Directory Structure
65
//
66
//
67
//
68
//
69
//
70
//
71
//
72
//
73
 
74
//`include "timescale.v"
75
 
76
module usb_rx_phy(      clk, rst, fs_ce,
77
 
78
                        // Transciever Interface
79
                        rxd, rxdp, rxdn,
80
 
81
                        // UTMI Interface
82
                        RxValid_o, RxActive_o, RxError_o, DataIn_o,
83
                        RxEn_i, LineState);
84
 
85
input           clk;
86
input           rst;
87
output          fs_ce;
88
input           rxd, rxdp, rxdn;
89
output  [7:0]    DataIn_o;
90
output          RxValid_o;
91
output          RxActive_o;
92
output          RxError_o;
93
input           RxEn_i;
94
output  [1:0]    LineState;
95
 
96
///////////////////////////////////////////////////////////////////
97
//
98
// Local Wires and Registers
99
//
100
 
101
reg             rxd_s0, rxd_s1,  rxd_s;
102
reg             rxdp_s0, rxdp_s1, rxdp_s, rxdp_s_r;
103
reg             rxdn_s0, rxdn_s1, rxdn_s, rxdn_s_r;
104
reg             synced_d;
105
wire            k, j, se0;
106
reg             rxd_r;
107
reg             rx_en;
108
reg             rx_active;
109
reg     [2:0]    bit_cnt;
110
reg             rx_valid1, rx_valid;
111
reg             shift_en;
112
reg             sd_r;
113
reg             sd_nrzi;
114
reg     [7:0]    hold_reg;
115
wire            drop_bit;       // Indicates a stuffed bit
116
reg     [2:0]    one_cnt;
117
 
118
reg     [1:0]    dpll_state, dpll_next_state;
119
reg             fs_ce_d;
120
reg             fs_ce;
121
wire            change;
122
wire            lock_en;
123
reg     [2:0]    fs_state, fs_next_state;
124
reg             rx_valid_r;
125
reg             sync_err_d, sync_err;
126
reg             bit_stuff_err;
127
reg             se0_r, byte_err;
128
reg             se0_s;
129
 
130
///////////////////////////////////////////////////////////////////
131
//
132
// Misc Logic
133
//
134
 
135
assign RxActive_o = rx_active;
136
assign RxValid_o = rx_valid;
137
assign RxError_o = sync_err | bit_stuff_err | byte_err;
138
assign DataIn_o = hold_reg;
139
assign LineState = {rxdn_s1, rxdp_s1};
140
 
141
always @(posedge clk)   rx_en <= RxEn_i;
142
always @(posedge clk)   sync_err <= !rx_active & sync_err_d;
143
 
144
///////////////////////////////////////////////////////////////////
145
//
146
// Synchronize Inputs
147
//
148
 
149
// First synchronize to the local system clock to
150
// avoid metastability outside the sync block (*_s0).
151
// Then make sure we see the signal for at least two
152
// clock cycles stable to avoid glitches and noise
153
 
154
always @(posedge clk)   rxd_s0  <= rxd;
155
always @(posedge clk)   rxd_s1  <= rxd_s0;
156
always @(posedge clk)                                                   // Avoid detecting Line Glitches and noise
157
        if(rxd_s0 && rxd_s1)    rxd_s <= 1'b1;
158
        else
159
        if(!rxd_s0 && !rxd_s1)  rxd_s <= 1'b0;
160
 
161
always @(posedge clk)   rxdp_s0  <= rxdp;
162
always @(posedge clk)   rxdp_s1  <= rxdp_s0;
163
always @(posedge clk)   rxdp_s_r <= rxdp_s0 & rxdp_s1;
164
always @(posedge clk)   rxdp_s   <= (rxdp_s0 & rxdp_s1) | rxdp_s_r;     // Avoid detecting Line Glitches and noise
165
 
166
always @(posedge clk)   rxdn_s0  <= rxdn;
167
always @(posedge clk)   rxdn_s1  <= rxdn_s0;
168
always @(posedge clk)   rxdn_s_r <= rxdn_s0 & rxdn_s1;
169
always @(posedge clk)   rxdn_s   <= (rxdn_s0 & rxdn_s1) | rxdn_s_r;     // Avoid detecting Line Glitches and noise
170
 
171
assign k = !rxdp_s &  rxdn_s;
172
assign j =  rxdp_s & !rxdn_s;
173
assign se0 = !rxdp_s & !rxdn_s;
174
 
175
always @(posedge clk)   if(fs_ce)       se0_s <= se0;
176
 
177
///////////////////////////////////////////////////////////////////
178
//
179
// DPLL
180
//
181
 
182
// This design uses a clock enable to do 12Mhz timing and not a
183
// real 12Mhz clock. Everything always runs at 48Mhz. We want to
184
// make sure however, that the clock enable is always exactly in
185
// the middle between two virtual 12Mhz rising edges.
186
// We monitor rxdp and rxdn for any changes and do the appropiate
187
// adjustments.
188
// In addition to the locking done in the dpll FSM, we adjust the
189
// final latch enable to compensate for various sync registers ...
190
 
191
// Allow lockinf only when we are receiving
192
assign  lock_en = rx_en;
193
 
194
always @(posedge clk)   rxd_r <= rxd_s;
195
 
196
// Edge detector
197
assign change = rxd_r != rxd_s;
198
 
199
// DPLL FSM
200
`ifdef USB_ASYNC_REST
201
always @(posedge clk or negedge rst)
202
`else
203
always @(posedge clk)
204
`endif
205
        if(!rst)        dpll_state <= 2'h1;
206
        else            dpll_state <= dpll_next_state;
207
 
208
always @(dpll_state or lock_en or change)
209
   begin
210
        fs_ce_d = 1'b0;
211
        case(dpll_state)        // synopsys full_case parallel_case
212
           2'h0:
213
                if(lock_en && change)   dpll_next_state = 2'h0;
214
                else                    dpll_next_state = 2'h1;
215
           2'h1:begin
216
                fs_ce_d = 1'b1;
217
                if(lock_en && change)   dpll_next_state = 2'h3;
218
                else                    dpll_next_state = 2'h2;
219
                end
220
           2'h2:
221
                if(lock_en && change)   dpll_next_state = 2'h0;
222
                else                    dpll_next_state = 2'h3;
223
           2'h3:
224
                if(lock_en && change)   dpll_next_state = 2'h0;
225
                else                    dpll_next_state = 2'h0;
226
        endcase
227
   end
228
 
229
// Compensate for sync registers at the input - allign full speed
230
// clock enable to be in the middle between two bit changes ...
231
reg     fs_ce_r1, fs_ce_r2;
232
 
233
always @(posedge clk)   fs_ce_r1 <= fs_ce_d;
234
always @(posedge clk)   fs_ce_r2 <= fs_ce_r1;
235
always @(posedge clk)   fs_ce <= fs_ce_r2;
236
 
237
 
238
///////////////////////////////////////////////////////////////////
239
//
240
// Find Sync Pattern FSM
241
//
242
 
243
parameter       FS_IDLE = 3'h0,
244
                K1      = 3'h1,
245
                J1      = 3'h2,
246
                K2      = 3'h3,
247
                J2      = 3'h4,
248
                K3      = 3'h5,
249
                J3      = 3'h6,
250
                K4      = 3'h7;
251
 
252
`ifdef USB_ASYNC_REST
253
always @(posedge clk or negedge rst)
254
`else
255
always @(posedge clk)
256
`endif
257
        if(!rst)        fs_state <= FS_IDLE;
258
        else            fs_state <= fs_next_state;
259
 
260
/***********************************************************
261
       Dinesh.A, 7th Feb 2013
262
       Sync Detection, when following pattern detected
263
          k,j,k,j,k,j,k,k
264
       Where k =1; if  rxdp == 0  and rxdn == 1
265
       Where j =1; if  rxdp == 1  and rxdn == 0
266
************************************************************/
267
always @(fs_state or fs_ce or k or j or rx_en or rx_active or se0 or se0_s)
268
   begin
269
        synced_d = 1'b0;
270
        sync_err_d = 1'b0;
271
        fs_next_state = fs_state;
272
        if(fs_ce && !rx_active && !se0 && !se0_s)
273
           case(fs_state)       // synopsys full_case parallel_case
274
                FS_IDLE:
275
                     begin
276
                        if(k && rx_en)  fs_next_state = K1;
277
                     end
278
                K1:
279
                     begin
280
                        if(j && rx_en)  fs_next_state = J1;
281
                        else
282
                           begin
283
                                        sync_err_d = 1'b1;
284
                                        fs_next_state = FS_IDLE;
285
                           end
286
                     end
287
                J1:
288
                     begin
289
                        if(k && rx_en)  fs_next_state = K2;
290
                        else
291
                           begin
292
                                        sync_err_d = 1'b1;
293
                                        fs_next_state = FS_IDLE;
294
                           end
295
                     end
296
                K2:
297
                     begin
298
                        if(j && rx_en)  fs_next_state = J2;
299
                        else
300
                           begin
301
                                        sync_err_d = 1'b1;
302
                                        fs_next_state = FS_IDLE;
303
                           end
304
                     end
305
                J2:
306
                     begin
307
                        if(k && rx_en)  fs_next_state = K3;
308
                        else
309
                           begin
310
                                        sync_err_d = 1'b1;
311
                                        fs_next_state = FS_IDLE;
312
                           end
313
                     end
314
                K3:
315
                     begin
316
                        if(j && rx_en)  fs_next_state = J3;
317
                        else
318
                        if(k && rx_en)
319
                           begin
320
                                        fs_next_state = FS_IDLE;        // Allow missing first K-J
321
                                        synced_d = 1'b1;
322
                           end
323
                        else
324
                           begin
325
                                        sync_err_d = 1'b1;
326
                                        fs_next_state = FS_IDLE;
327
                           end
328
                     end
329
                J3:
330
                     begin
331
                        if(k && rx_en)  fs_next_state = K4;
332
                        else
333
                           begin
334
                                        sync_err_d = 1'b1;
335
                                        fs_next_state = FS_IDLE;
336
                           end
337
                     end
338
                K4:
339
                     begin
340
                        if(k)   synced_d = 1'b1;
341
                        fs_next_state = FS_IDLE;
342
                     end
343
           endcase
344
   end
345
 
346
///////////////////////////////////////////////////////////////////
347
//
348
// Generate RxActive
349
//
350
 
351
`ifdef USB_ASYNC_REST
352
always @(posedge clk or negedge rst)
353
`else
354
always @(posedge clk)
355
`endif
356
        if(!rst)                rx_active <= 1'b0;
357
        else
358
        if(synced_d && rx_en)   rx_active <= 1'b1;
359
        else
360
        if(se0 && rx_valid_r)   rx_active <= 1'b0;
361
 
362
always @(posedge clk)
363
        if(rx_valid)    rx_valid_r <= 1'b1;
364
        else
365
        if(fs_ce)       rx_valid_r <= 1'b0;
366
 
367
///////////////////////////////////////////////////////////////////
368
//
369
// NRZI Decoder
370
//
371
 
372
always @(posedge clk)
373
        if(fs_ce)       sd_r <= rxd_s;
374
 
375
`ifdef USB_ASYNC_REST
376
always @(posedge clk or negedge rst)
377
`else
378
always @(posedge clk)
379
`endif
380
        if(!rst)                sd_nrzi <= 1'b0;
381
        else
382
        if(!rx_active)          sd_nrzi <= 1'b1;
383
        else
384
        if(rx_active && fs_ce)  sd_nrzi <= !(rxd_s ^ sd_r);
385
 
386
///////////////////////////////////////////////////////////////////
387
//
388
// Bit Stuff Detect
389
//
390
 
391
`ifdef USB_ASYNC_REST
392
always @(posedge clk or negedge rst)
393
`else
394
always @(posedge clk)
395
`endif
396
        if(!rst)        one_cnt <= 3'h0;
397
        else
398
        if(!shift_en)   one_cnt <= 3'h0;
399
        else
400
        if(fs_ce)
401
           begin
402
                if(!sd_nrzi || drop_bit)        one_cnt <= 3'h0;
403
                else                            one_cnt <= one_cnt + 3'h1;
404
           end
405
 
406
assign drop_bit = (one_cnt==3'h6);
407
 
408
always @(posedge clk)   bit_stuff_err <= drop_bit & sd_nrzi & fs_ce & !se0 & rx_active; // Bit Stuff Error
409
 
410
///////////////////////////////////////////////////////////////////
411
//
412
// Serial => Parallel converter
413
//
414
 
415
always @(posedge clk)
416
        if(fs_ce)       shift_en <= synced_d | rx_active;
417
 
418
always @(posedge clk)
419
        if(fs_ce && shift_en && !drop_bit)
420
                hold_reg <= {sd_nrzi, hold_reg[7:1]};
421
 
422
///////////////////////////////////////////////////////////////////
423
//
424
// Generate RxValid
425
//
426
 
427
`ifdef USB_ASYNC_REST
428
always @(posedge clk or negedge rst)
429
`else
430
always @(posedge clk)
431
`endif
432
        if(!rst)                bit_cnt <= 3'b0;
433
        else
434
        if(!shift_en)           bit_cnt <= 3'h0;
435
        else
436
        if(fs_ce && !drop_bit)  bit_cnt <= bit_cnt + 3'h1;
437
 
438
`ifdef USB_ASYNC_REST
439
always @(posedge clk or negedge rst)
440
`else
441
always @(posedge clk)
442
`endif
443
        if(!rst)                                        rx_valid1 <= 1'b0;
444
        else
445
        if(fs_ce && !drop_bit && (bit_cnt==3'h7))       rx_valid1 <= 1'b1;
446
        else
447
        if(rx_valid1 && fs_ce && !drop_bit)             rx_valid1 <= 1'b0;
448
 
449
always @(posedge clk)   rx_valid <= !drop_bit & rx_valid1 & fs_ce;
450
 
451
always @(posedge clk)   se0_r <= se0;
452
 
453
always @(posedge clk)   byte_err <= se0 & !se0_r & (|bit_cnt[2:1]) & rx_active;
454
 
455
endmodule
456
 

powered by: WebSVN 2.1.0

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