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

Subversion Repositories usb_phy

[/] [usb_phy/] [trunk/] [rtl/] [verilog/] [usb_rx_phy.v] - Blame information for rev 7

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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