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_tx_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
////  TX                                                         ////
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_tx_phy.v,v 1.4 2004/10/19 09:29:07 rudi Exp $
43
//
44
//  $Date: 2004/10/19 09:29:07 $
45
//  $Revision: 1.4 $
46
//  $Author: rudi $
47
//  $Locker:  $
48
//  $State: Exp $
49
//
50
// Change History:
51
//               $Log: usb_tx_phy.v,v $
52
//               Revision 1.4  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.3  2003/10/21 05:58:41  rudi
56
//               usb_rst is no longer or'ed with the incomming reset internally.
57
//               Now usb_rst is simply an output, the application can decide how
58
//               to utilize it.
59
//
60
//               Revision 1.2  2003/10/19 17:40:13  rudi
61
//               - Made core more robust against line noise
62
//               - Added Error Checking and Reporting
63
//               (See README.txt for more info)
64
//
65
//               Revision 1.1.1.1  2002/09/16 14:27:02  rudi
66
//               Created Directory Structure
67
//
68
//
69
//
70
//
71
//
72
//
73
//
74
 
75
`include "timescale.v"
76
 
77
module usb_tx_phy(
78
                clk, rst, fs_ce, phy_mode,
79
 
80
                // Transciever Interface
81
                txdp, txdn, txoe,
82
 
83
                // UTMI Interface
84
                DataOut_i, TxValid_i, TxReady_o
85
                );
86
 
87
input           clk;
88
input           rst;
89
input           fs_ce;
90
input           phy_mode;
91
output          txdp, txdn, txoe;
92
input   [7:0]    DataOut_i;
93
input           TxValid_i;
94
output          TxReady_o;
95
 
96
///////////////////////////////////////////////////////////////////
97
//
98
// Local Wires and Registers
99
//
100
 
101
parameter       IDLE    = 3'd0,
102
                SOP     = 3'h1,
103
                DATA    = 3'h2,
104
                EOP1    = 3'h3,
105
                EOP2    = 3'h4,
106
                WAIT    = 3'h5;
107
 
108
reg             TxReady_o;
109
reg     [2:0]    state, next_state;
110
reg             tx_ready_d;
111
reg             ld_sop_d;
112
reg             ld_data_d;
113
reg             ld_eop_d;
114
reg             tx_ip;
115
reg             tx_ip_sync;
116
reg     [2:0]    bit_cnt;
117
reg     [7:0]    hold_reg;
118
reg     [7:0]    hold_reg_d;
119
 
120
reg             sd_raw_o;
121
wire            hold;
122
reg             data_done;
123
reg             sft_done;
124
reg             sft_done_r;
125
wire            sft_done_e;
126
reg             ld_data;
127
wire            eop_done;
128
reg     [2:0]    one_cnt;
129
wire            stuff;
130
reg             sd_bs_o;
131
reg             sd_nrzi_o;
132
reg             append_eop;
133
reg             append_eop_sync1;
134
reg             append_eop_sync2;
135
reg             append_eop_sync3;
136
reg             append_eop_sync4;
137
reg             txdp, txdn;
138
reg             txoe_r1, txoe_r2;
139
reg             txoe;
140
 
141
///////////////////////////////////////////////////////////////////
142
//
143
// Misc Logic
144
//
145
 
146
`ifdef USB_ASYNC_REST
147
always @(posedge clk or negedge rst)
148
`else
149
always @(posedge clk)
150
`endif
151
        if(!rst)        TxReady_o <= 1'b0;
152
        else            TxReady_o <= tx_ready_d & TxValid_i;
153
 
154
always @(posedge clk) ld_data <= ld_data_d;
155
 
156
///////////////////////////////////////////////////////////////////
157
//
158
// Transmit in progress indicator
159
//
160
 
161
`ifdef USB_ASYNC_REST
162
always @(posedge clk or negedge rst)
163
`else
164
always @(posedge clk)
165
`endif
166
        if(!rst)        tx_ip <= 1'b0;
167
        else
168
        if(ld_sop_d)    tx_ip <= 1'b1;
169
        else
170
        if(eop_done)    tx_ip <= 1'b0;
171
 
172
`ifdef USB_ASYNC_REST
173
always @(posedge clk or negedge rst)
174
`else
175
always @(posedge clk)
176
`endif
177
        if(!rst)                tx_ip_sync <= 1'b0;
178
        else
179
        if(fs_ce)               tx_ip_sync <= tx_ip;
180
 
181
// data_done helps us to catch cases where TxValid drops due to
182
// packet end and then gets re-asserted as a new packet starts.
183
// We might not see this because we are still transmitting.
184
// data_done should solve those cases ...
185
`ifdef USB_ASYNC_REST
186
always @(posedge clk or negedge rst)
187
`else
188
always @(posedge clk)
189
`endif
190
        if(!rst)                        data_done <= 1'b0;
191
        else
192
        if(TxValid_i && ! tx_ip)        data_done <= 1'b1;
193
        else
194
        if(!TxValid_i)                  data_done <= 1'b0;
195
 
196
///////////////////////////////////////////////////////////////////
197
//
198
// Shift Register
199
//
200
 
201
`ifdef USB_ASYNC_REST
202
always @(posedge clk or negedge rst)
203
`else
204
always @(posedge clk)
205
`endif
206
        if(!rst)                bit_cnt <= 3'h0;
207
        else
208
        if(!tx_ip_sync)         bit_cnt <= 3'h0;
209
        else
210
        if(fs_ce && !hold)      bit_cnt <= bit_cnt + 3'h1;
211
 
212
assign hold = stuff;
213
 
214
always @(posedge clk)
215
        if(!tx_ip_sync)         sd_raw_o <= 1'b0;
216
        else
217
        case(bit_cnt)   // synopsys full_case parallel_case
218
           3'h0: sd_raw_o <= hold_reg_d[0];
219
           3'h1: sd_raw_o <= hold_reg_d[1];
220
           3'h2: sd_raw_o <= hold_reg_d[2];
221
           3'h3: sd_raw_o <= hold_reg_d[3];
222
           3'h4: sd_raw_o <= hold_reg_d[4];
223
           3'h5: sd_raw_o <= hold_reg_d[5];
224
           3'h6: sd_raw_o <= hold_reg_d[6];
225
           3'h7: sd_raw_o <= hold_reg_d[7];
226
        endcase
227
 
228
always @(posedge clk)
229
        sft_done <= !hold & (bit_cnt == 3'h7);
230
 
231
always @(posedge clk)
232
        sft_done_r <= sft_done;
233
 
234
assign sft_done_e = sft_done & !sft_done_r;
235
 
236
// Out Data Hold Register
237
always @(posedge clk)
238
        if(ld_sop_d)    hold_reg <= 8'h80;
239
        else
240
        if(ld_data)     hold_reg <= DataOut_i;
241
 
242
always @(posedge clk) hold_reg_d <= hold_reg;
243
 
244
///////////////////////////////////////////////////////////////////
245
//
246
// Bit Stuffer
247
//
248
 
249
`ifdef USB_ASYNC_REST
250
always @(posedge clk or negedge rst)
251
`else
252
always @(posedge clk)
253
`endif
254
        if(!rst)        one_cnt <= 3'h0;
255
        else
256
        if(!tx_ip_sync) one_cnt <= 3'h0;
257
        else
258
        if(fs_ce)
259
           begin
260
                if(!sd_raw_o || stuff)  one_cnt <= 3'h0;
261
                else                    one_cnt <= one_cnt + 3'h1;
262
           end
263
 
264
assign stuff = (one_cnt==3'h6);
265
 
266
`ifdef USB_ASYNC_REST
267
always @(posedge clk or negedge rst)
268
`else
269
always @(posedge clk)
270
`endif
271
        if(!rst)        sd_bs_o <= 1'h0;
272
        else
273
        if(fs_ce)       sd_bs_o <= !tx_ip_sync ? 1'b0 : (stuff ? 1'b0 : sd_raw_o);
274
 
275
///////////////////////////////////////////////////////////////////
276
//
277
// NRZI Encoder
278
//
279
 
280
`ifdef USB_ASYNC_REST
281
always @(posedge clk or negedge rst)
282
`else
283
always @(posedge clk)
284
`endif
285
        if(!rst)                        sd_nrzi_o <= 1'b1;
286
        else
287
        if(!tx_ip_sync || !txoe_r1)     sd_nrzi_o <= 1'b1;
288
        else
289
        if(fs_ce)                       sd_nrzi_o <= sd_bs_o ? sd_nrzi_o : ~sd_nrzi_o;
290
 
291
///////////////////////////////////////////////////////////////////
292
//
293
// EOP append logic
294
//
295
 
296
`ifdef USB_ASYNC_REST
297
always @(posedge clk or negedge rst)
298
`else
299
always @(posedge clk)
300
`endif
301
        if(!rst)                append_eop <= 1'b0;
302
        else
303
        if(ld_eop_d)            append_eop <= 1'b1;
304
        else
305
        if(append_eop_sync2)    append_eop <= 1'b0;
306
 
307
`ifdef USB_ASYNC_REST
308
always @(posedge clk or negedge rst)
309
`else
310
always @(posedge clk)
311
`endif
312
        if(!rst)        append_eop_sync1 <= 1'b0;
313
        else
314
        if(fs_ce)       append_eop_sync1 <= append_eop;
315
 
316
`ifdef USB_ASYNC_REST
317
always @(posedge clk or negedge rst)
318
`else
319
always @(posedge clk)
320
`endif
321
        if(!rst)        append_eop_sync2 <= 1'b0;
322
        else
323
        if(fs_ce)       append_eop_sync2 <= append_eop_sync1;
324
 
325
`ifdef USB_ASYNC_REST
326
always @(posedge clk or negedge rst)
327
`else
328
always @(posedge clk)
329
`endif
330
        if(!rst)        append_eop_sync3 <= 1'b0;
331
        else
332
        if(fs_ce)       append_eop_sync3 <= append_eop_sync2 |
333
                        (append_eop_sync3 & !append_eop_sync4); // Make sure always 2 bit wide
334
 
335
`ifdef USB_ASYNC_REST
336
always @(posedge clk or negedge rst)
337
`else
338
always @(posedge clk)
339
`endif
340
        if(!rst)        append_eop_sync4 <= 1'b0;
341
        else
342
        if(fs_ce)       append_eop_sync4 <= append_eop_sync3;
343
 
344
assign eop_done = append_eop_sync3;
345
 
346
///////////////////////////////////////////////////////////////////
347
//
348
// Output Enable Logic
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)        txoe_r1 <= 1'b0;
357
        else
358
        if(fs_ce)       txoe_r1 <= tx_ip_sync;
359
 
360
`ifdef USB_ASYNC_REST
361
always @(posedge clk or negedge rst)
362
`else
363
always @(posedge clk)
364
`endif
365
        if(!rst)        txoe_r2 <= 1'b0;
366
        else
367
        if(fs_ce)       txoe_r2 <= txoe_r1;
368
 
369
`ifdef USB_ASYNC_REST
370
always @(posedge clk or negedge rst)
371
`else
372
always @(posedge clk)
373
`endif
374
        if(!rst)        txoe <= 1'b1;
375
        else
376
        if(fs_ce)       txoe <= !(txoe_r1 | txoe_r2);
377
 
378
///////////////////////////////////////////////////////////////////
379
//
380
// Output Registers
381
//
382
 
383
`ifdef USB_ASYNC_REST
384
always @(posedge clk or negedge rst)
385
`else
386
always @(posedge clk)
387
`endif
388
        if(!rst)        txdp <= 1'b1;
389
        else
390
        if(fs_ce)       txdp <= phy_mode ?
391
                                        (!append_eop_sync3 &  sd_nrzi_o) :
392
                                        sd_nrzi_o;
393
 
394
`ifdef USB_ASYNC_REST
395
always @(posedge clk or negedge rst)
396
`else
397
always @(posedge clk)
398
`endif
399
        if(!rst)        txdn <= 1'b0;
400
        else
401
        if(fs_ce)       txdn <= phy_mode ?
402
                                        (!append_eop_sync3 & ~sd_nrzi_o) :
403
                                        append_eop_sync3;
404
 
405
///////////////////////////////////////////////////////////////////
406
//
407
// Tx Statemashine
408
//
409
 
410
`ifdef USB_ASYNC_REST
411
always @(posedge clk or negedge rst)
412
`else
413
always @(posedge clk)
414
`endif
415
        if(!rst)        state <= IDLE;
416
        else            state <= next_state;
417
 
418
always @(state or TxValid_i or data_done or sft_done_e or eop_done or fs_ce)
419
   begin
420
        next_state = state;
421
        tx_ready_d = 1'b0;
422
 
423
        ld_sop_d = 1'b0;
424
        ld_data_d = 1'b0;
425
        ld_eop_d = 1'b0;
426
 
427
        case(state)     // synopsys full_case parallel_case
428
           IDLE:
429
                        if(TxValid_i)
430
                           begin
431
                                ld_sop_d = 1'b1;
432
                                next_state = SOP;
433
                           end
434
           SOP:
435
                        if(sft_done_e)
436
                           begin
437
                                tx_ready_d = 1'b1;
438
                                ld_data_d = 1'b1;
439
                                next_state = DATA;
440
                           end
441
           DATA:
442
                   begin
443
                        if(!data_done && sft_done_e)
444
                           begin
445
                                ld_eop_d = 1'b1;
446
                                next_state = EOP1;
447
                           end
448
 
449
                        if(data_done && sft_done_e)
450
                           begin
451
                                tx_ready_d = 1'b1;
452
                                ld_data_d = 1'b1;
453
                           end
454
                   end
455
           EOP1:
456
                        if(eop_done)            next_state = EOP2;
457
           EOP2:
458
                        if(!eop_done && fs_ce)  next_state = WAIT;
459
           WAIT:
460
                        if(fs_ce)               next_state = IDLE;
461
        endcase
462
   end
463
 
464
endmodule
465
 

powered by: WebSVN 2.1.0

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