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

Subversion Repositories usb_phy

[/] [usb_phy/] [tags/] [start/] [rtl/] [verilog/] [usb_rx_phy.v] - Blame information for rev 12

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

powered by: WebSVN 2.1.0

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