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

Subversion Repositories usb_phy

[/] [usb_phy/] [tags/] [start/] [rtl/] [verilog/] [usb_tx_phy.v] - Blame information for rev 2

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

powered by: WebSVN 2.1.0

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