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

Subversion Repositories usb1_funct

[/] [usb1_funct/] [trunk/] [rtl/] [verilog/] [usb1_pa.v] - Blame information for rev 10

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 rudi
/////////////////////////////////////////////////////////////////////
2
////                                                             ////
3
////  Packet Assembler                                           ////
4
////  Assembles Token and Data USB packets                       ////
5
////                                                             ////
6
////  Author: Rudolf Usselmann                                   ////
7
////          rudi@asics.ws                                      ////
8
////                                                             ////
9
////                                                             ////
10
////  Downloaded from: http://www.opencores.org/cores/usb1_funct/////
11
////                                                             ////
12
/////////////////////////////////////////////////////////////////////
13
////                                                             ////
14
//// Copyright (C) 2000-2002 Rudolf Usselmann                    ////
15
////                         www.asics.ws                        ////
16
////                         rudi@asics.ws                       ////
17
////                                                             ////
18
//// This source file may be used and distributed without        ////
19
//// restriction provided that this copyright statement is not   ////
20
//// removed from the file and that any derivative work contains ////
21
//// the original copyright notice and the associated disclaimer.////
22
////                                                             ////
23
////     THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY     ////
24
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED   ////
25
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS   ////
26
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR      ////
27
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,         ////
28
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    ////
29
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE   ////
30
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR        ////
31
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF  ////
32
//// LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT  ////
33
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT  ////
34
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE         ////
35
//// POSSIBILITY OF SUCH DAMAGE.                                 ////
36
////                                                             ////
37
/////////////////////////////////////////////////////////////////////
38
 
39
//  CVS Log
40
//
41
//  $Id: usb1_pa.v,v 1.1.1.1 2002-09-19 12:07:13 rudi Exp $
42
//
43
//  $Date: 2002-09-19 12:07:13 $
44
//  $Revision: 1.1.1.1 $
45
//  $Author: rudi $
46
//  $Locker:  $
47
//  $State: Exp $
48
//
49
// Change History:
50
//               $Log: not supported by cvs2svn $
51
//
52
//
53
//
54
//
55
//
56
//
57
 
58
`include "usb1_defines.v"
59
 
60
module usb1_pa( clk, rst,
61
 
62
                // UTMI TX I/F
63
                tx_data, tx_valid, tx_valid_last, tx_ready,
64
                tx_first,
65
 
66
                // Protocol Engine Interface
67
                send_token, token_pid_sel,
68
                send_data, data_pid_sel,
69
 
70
                // IDMA Interface
71
                tx_data_st, rd_next,
72
 
73
                ep_empty
74
                );
75
 
76
input           clk, rst;
77
 
78
// UTMI TX Interface
79
output  [7:0]    tx_data;
80
output          tx_valid;
81
output          tx_valid_last;
82
input           tx_ready;
83
output          tx_first;
84
 
85
// Protocol Engine Interface
86
input           send_token;
87
input   [1:0]    token_pid_sel;
88
input           send_data;
89
input   [1:0]    data_pid_sel;
90
 
91
// IDMA Interface
92
input   [7:0]    tx_data_st;
93
output          rd_next;
94
 
95
input           ep_empty;
96
 
97
///////////////////////////////////////////////////////////////////
98
//
99
// Local Wires and Registers
100
//
101
 
102
parameter       [3:0]    // synopsys enum state
103
                IDLE   = 4'b0001,
104
                DATA   = 4'b0010,
105
                CRC1   = 4'b0100,
106
                CRC2   = 4'b1000;
107
 
108
reg     [3:0]    /* synopsys enum state */ state, next_state;
109
// synopsys state_vector state
110
 
111
reg             last;
112
reg             rd_next;
113
 
114
reg     [7:0]    token_pid, data_pid;    // PIDs from selectors
115
reg     [7:0]    tx_data_d;
116
reg     [7:0]    tx_data_data;
117
reg             dsel;
118
reg             tx_valid_d;
119
reg             send_token_r;
120
reg     [7:0]    tx_spec_data;
121
reg             crc_sel1, crc_sel2;
122
reg             tx_first_r;
123
reg             send_data_r;
124
wire            crc16_clr;
125
reg     [15:0]   crc16;
126
wire    [15:0]   crc16_next;
127
wire    [15:0]   crc16_rev;
128
reg             crc16_add;
129
reg             send_data_r2;
130
reg             tx_valid_r;
131
reg             tx_valid_r1;
132
 
133
wire            zero_length;
134
 
135
///////////////////////////////////////////////////////////////////
136
//
137
// Misc Logic
138
//
139
reg             zero_length_r;
140
assign          zero_length = ep_empty;
141
 
142
always @(posedge clk or negedge rst)
143
        if(!rst)        zero_length_r <= #1 1'b0;
144
        else
145
        if(last)        zero_length_r <= #1 1'b0;
146
        else
147
        if(crc16_clr)   zero_length_r <= #1 zero_length;
148
 
149
always @(posedge clk)
150
        tx_valid_r1 <= #1 tx_valid;
151
 
152
always @(posedge clk)
153
        tx_valid_r <= #1 tx_valid_r1;
154
 
155
always @(posedge clk or negedge rst)
156
        if(!rst)        send_token_r <= #1 1'b0;
157
        else
158
        if(send_token)  send_token_r <= #1 1'b1;
159
        else
160
        if(tx_ready)    send_token_r <= #1 1'b0;
161
 
162
// PID Select
163
always @(token_pid_sel)
164
        case(token_pid_sel)             // synopsys full_case parallel_case
165
           2'd0: token_pid = {  ~`USBF_T_PID_ACK,   `USBF_T_PID_ACK};
166
           2'd1: token_pid = { ~`USBF_T_PID_NACK,  `USBF_T_PID_NACK};
167
           2'd2: token_pid = {~`USBF_T_PID_STALL, `USBF_T_PID_STALL};
168
           2'd3: token_pid = { ~`USBF_T_PID_NYET,  `USBF_T_PID_NYET};
169
        endcase
170
 
171
always @(data_pid_sel)
172
        case(data_pid_sel)              // synopsys full_case parallel_case
173
           2'd0: data_pid = { ~`USBF_T_PID_DATA0, `USBF_T_PID_DATA0};
174
           2'd1: data_pid = { ~`USBF_T_PID_DATA1, `USBF_T_PID_DATA1};
175
           2'd2: data_pid = { ~`USBF_T_PID_DATA2, `USBF_T_PID_DATA2};
176
           2'd3: data_pid = { ~`USBF_T_PID_MDATA, `USBF_T_PID_MDATA};
177
        endcase
178
 
179
// Data path Muxes
180
 
181
always @(send_token or send_token_r or token_pid or tx_data_data)
182
        if(send_token | send_token_r)   tx_data_d = token_pid;
183
        else                            tx_data_d = tx_data_data;
184
 
185
always @(dsel or tx_data_st or tx_spec_data)
186
        if(dsel)        tx_data_data = tx_spec_data;
187
        else            tx_data_data = tx_data_st;
188
 
189
always @(crc_sel1 or crc_sel2 or data_pid or crc16_rev)
190
        if(!crc_sel1 & !crc_sel2)       tx_spec_data = data_pid;
191
        else
192
        if(crc_sel1)                    tx_spec_data = crc16_rev[15:8]; // CRC 1
193
        else                            tx_spec_data = crc16_rev[7:0];   // CRC 2
194
 
195
assign tx_data = tx_data_d;
196
 
197
// TX Valid assignment
198
assign tx_valid_last = send_token | last;
199
assign tx_valid = tx_valid_d;
200
 
201
always @(posedge clk)
202
        tx_first_r <= #1 send_token | send_data;
203
 
204
assign tx_first = (send_token | send_data) & ! tx_first_r;
205
 
206
// CRC Logic
207
always @(posedge clk)
208
        send_data_r <= #1 send_data;
209
 
210
always @(posedge clk)
211
        send_data_r2 <= #1 send_data_r;
212
 
213
assign crc16_clr = send_data & !send_data_r;
214
 
215
always @(posedge clk)
216
        crc16_add <= #1 !zero_length_r &
217
                        ((send_data_r & !send_data_r2) | (rd_next & !crc_sel1));
218
 
219
always @(posedge clk)
220
        if(crc16_clr)           crc16 <= #1 16'hffff;
221
        else
222
        if(crc16_add)           crc16 <= #1 crc16_next;
223
 
224
usb1_crc16 u1(
225
        .crc_in(        crc16           ),
226
        .din(   {tx_data_st[0], tx_data_st[1],
227
                tx_data_st[2], tx_data_st[3],
228
                tx_data_st[4], tx_data_st[5],
229
                tx_data_st[6], tx_data_st[7]}   ),
230
        .crc_out(       crc16_next              ) );
231
 
232
assign crc16_rev[15] = ~crc16[8];
233
assign crc16_rev[14] = ~crc16[9];
234
assign crc16_rev[13] = ~crc16[10];
235
assign crc16_rev[12] = ~crc16[11];
236
assign crc16_rev[11] = ~crc16[12];
237
assign crc16_rev[10] = ~crc16[13];
238
assign crc16_rev[9]  = ~crc16[14];
239
assign crc16_rev[8]  = ~crc16[15];
240
assign crc16_rev[7]  = ~crc16[0];
241
assign crc16_rev[6]  = ~crc16[1];
242
assign crc16_rev[5]  = ~crc16[2];
243
assign crc16_rev[4]  = ~crc16[3];
244
assign crc16_rev[3]  = ~crc16[4];
245
assign crc16_rev[2]  = ~crc16[5];
246
assign crc16_rev[1]  = ~crc16[6];
247
assign crc16_rev[0]  = ~crc16[7];
248
 
249
///////////////////////////////////////////////////////////////////
250
//
251
// Transmit/Encode state machine
252
//
253
 
254
always @(posedge clk or negedge rst)
255
        if(!rst)        state <= #1 IDLE;
256
        else            state <= #1 next_state;
257
 
258
always @(state or send_data or tx_ready or tx_valid_r or zero_length)
259
   begin
260
        next_state = state;     // Default don't change current state
261
        tx_valid_d = 1'b0;
262
        dsel = 1'b0;
263
        rd_next = 1'b0;
264
        last = 1'b0;
265
        crc_sel1 = 1'b0;
266
        crc_sel2 = 1'b0;
267
        case(state)             // synopsys full_case parallel_case
268
           IDLE:
269
                   begin
270
                        if(zero_length & send_data)
271
                           begin
272
                                tx_valid_d = 1'b1;
273
                                dsel = 1'b1;
274
                                next_state = CRC1;
275
                           end
276
                        else
277
                        if(send_data)           // Send DATA packet
278
                           begin
279
                                tx_valid_d = 1'b1;
280
                                dsel = 1'b1;
281
                                next_state = DATA;
282
                           end
283
                   end
284
           DATA:
285
                   begin
286
                        if(tx_ready & tx_valid_r)
287
                                rd_next = 1'b1;
288
 
289
                        tx_valid_d = 1'b1;
290
                        if(!send_data & tx_ready & tx_valid_r)
291
                           begin
292
                                dsel = 1'b1;
293
                                crc_sel1 = 1'b1;
294
                                next_state = CRC1;
295
                           end
296
                   end
297
           CRC1:
298
                   begin
299
                        dsel = 1'b1;
300
                        tx_valid_d = 1'b1;
301
                        if(tx_ready)
302
                           begin
303
                                last = 1'b1;
304
                                crc_sel2 = 1'b1;
305
                                next_state = CRC2;
306
                           end
307
                        else
308
                           begin
309
                                tx_valid_d = 1'b1;
310
                                crc_sel1 = 1'b1;
311
                           end
312
 
313
                   end
314
           CRC2:
315
                   begin
316
                        dsel = 1'b1;
317
                        crc_sel2 = 1'b1;
318
                        if(tx_ready)
319
                           begin
320
                                next_state = IDLE;
321
                           end
322
                        else
323
                           begin
324
                                last = 1'b1;
325
                           end
326
 
327
                   end
328
        endcase
329
   end
330
 
331
endmodule
332
 

powered by: WebSVN 2.1.0

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