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

Subversion Repositories usb2uart

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

powered by: WebSVN 2.1.0

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