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

Subversion Repositories usb_device_core

[/] [usb_device_core/] [trunk/] [src_v/] [usbf_sie_tx.v] - Blame information for rev 5

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 5 ultra_embe
//-----------------------------------------------------------------
2
//                       USB Device Core
3
//                           V1.0
4
//                     Ultra-Embedded.com
5
//                     Copyright 2014-2019
6
//
7
//                 Email: admin@ultra-embedded.com
8
//
9
//                         License: GPL
10
// If you would like a version with a more permissive license for
11
// use in closed source commercial applications please contact me
12
// for details.
13
//-----------------------------------------------------------------
14
//
15
// This file is open source HDL; you can redistribute it and/or 
16
// modify it under the terms of the GNU General Public License as 
17
// published by the Free Software Foundation; either version 2 of 
18
// the License, or (at your option) any later version.
19
//
20
// This file is distributed in the hope that it will be useful,
21
// but WITHOUT ANY WARRANTY; without even the implied warranty of
22
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23
// GNU General Public License for more details.
24
//
25
// You should have received a copy of the GNU General Public 
26
// License along with this file; if not, write to the Free Software
27
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
28
// USA
29
//-----------------------------------------------------------------
30
 
31
//-----------------------------------------------------------------
32
//                          Generated File
33
//-----------------------------------------------------------------
34
 
35
module usbf_sie_tx
36
(
37
    // Inputs
38
     input           clk_i
39
    ,input           rst_i
40
    ,input           enable_i
41
    ,input           chirp_i
42
    ,input           utmi_txready_i
43
    ,input           tx_valid_i
44
    ,input  [  7:0]  tx_pid_i
45
    ,input           data_valid_i
46
    ,input           data_strb_i
47
    ,input  [  7:0]  data_i
48
    ,input           data_last_i
49
 
50
    // Outputs
51
    ,output [  7:0]  utmi_data_o
52
    ,output          utmi_txvalid_o
53
    ,output          tx_accept_o
54
    ,output          data_accept_o
55
);
56
 
57
 
58
 
59
//-----------------------------------------------------------------
60
// Defines:
61
//-----------------------------------------------------------------
62
`include "usbf_defs.v"
63
 
64
localparam STATE_W                       = 3;
65
localparam STATE_TX_IDLE                 = 3'd0;
66
localparam STATE_TX_PID                  = 3'd1;
67
localparam STATE_TX_DATA                 = 3'd2;
68
localparam STATE_TX_CRC1                 = 3'd3;
69
localparam STATE_TX_CRC2                 = 3'd4;
70
localparam STATE_TX_DONE                 = 3'd5;
71
localparam STATE_TX_CHIRP                = 3'd6;
72
 
73
reg [STATE_W-1:0] state_q;
74
reg [STATE_W-1:0] next_state_r;
75
 
76
//-----------------------------------------------------------------
77
// Wire / Regs
78
//-----------------------------------------------------------------
79
reg last_q;
80
 
81
//-----------------------------------------------------------------
82
// Request Type
83
//-----------------------------------------------------------------
84
reg data_pid_q;
85
reg data_zlp_q;
86
 
87
always @ (posedge clk_i or posedge rst_i)
88
if (rst_i)
89
begin
90
    data_pid_q <= 1'b0;
91
    data_zlp_q <= 1'b0;
92
end
93
else if (!enable_i)
94
begin
95
    data_pid_q <= 1'b0;
96
    data_zlp_q <= 1'b0;
97
end
98
else if (tx_valid_i && tx_accept_o)
99
begin
100
    case (tx_pid_i)
101
 
102
    `PID_MDATA, `PID_DATA2, `PID_DATA0, `PID_DATA1:
103
    begin
104
        data_pid_q <= 1'b1;
105
        data_zlp_q <= data_valid_i && (data_strb_i == 1'b0) && data_last_i;
106
    end
107
 
108
    default :
109
    begin
110
        data_pid_q <= 1'b0;
111
        data_zlp_q <= 1'b0;
112
    end
113
    endcase
114
end
115
else if (next_state_r == STATE_TX_CRC1)
116
begin
117
    data_pid_q <= 1'b0;
118
    data_zlp_q <= 1'b0;
119
end
120
 
121
assign tx_accept_o = (state_q == STATE_TX_IDLE);
122
 
123
//-----------------------------------------------------------------
124
// Next state
125
//-----------------------------------------------------------------
126
always @ *
127
begin
128
    next_state_r = state_q;
129
 
130
    //-----------------------------------------
131
    // State Machine
132
    //-----------------------------------------
133
    case (state_q)
134
 
135
    //-----------------------------------------
136
    // IDLE
137
    //-----------------------------------------
138
    STATE_TX_IDLE :
139
    begin
140
        if (chirp_i)
141
            next_state_r  = STATE_TX_CHIRP;
142
        else if (tx_valid_i)
143
            next_state_r  = STATE_TX_PID;
144
    end
145
 
146
    //-----------------------------------------
147
    // TX_PID
148
    //-----------------------------------------
149
    STATE_TX_PID :
150
    begin
151
        // Data accepted
152
        if (utmi_txready_i)
153
        begin
154
            if (data_zlp_q)
155
                next_state_r = STATE_TX_CRC1;
156
            else if (data_pid_q)
157
                next_state_r = STATE_TX_DATA;
158
            else
159
                next_state_r = STATE_TX_DONE;
160
        end
161
    end
162
 
163
    //-----------------------------------------
164
    // TX_DATA
165
    //-----------------------------------------
166
    STATE_TX_DATA :
167
    begin
168
        // Data accepted
169
        if (utmi_txready_i)
170
        begin
171
            // Generate CRC16 at end of packet
172
            if (data_last_i)
173
                next_state_r  = STATE_TX_CRC1;
174
        end
175
    end
176
 
177
    //-----------------------------------------
178
    // TX_CRC1 (first byte)
179
    //-----------------------------------------
180
    STATE_TX_CRC1 :
181
    begin
182
        // Data sent?
183
        if (utmi_txready_i)
184
            next_state_r  = STATE_TX_CRC2;
185
    end
186
 
187
    //-----------------------------------------
188
    // TX_CRC (second byte)
189
    //-----------------------------------------
190
    STATE_TX_CRC2 :
191
    begin
192
        // Data sent?
193
        if (utmi_txready_i)
194
            next_state_r  = STATE_TX_DONE;
195
    end
196
 
197
    //-----------------------------------------
198
    // TX_DONE
199
    //-----------------------------------------
200
    STATE_TX_DONE :
201
    begin
202
        // Data sent?
203
        if (!utmi_txvalid_o || utmi_txready_i)
204
            next_state_r  = STATE_TX_IDLE;
205
    end
206
 
207
    //-----------------------------------------
208
    // TX_CHIRP
209
    //-----------------------------------------
210
    STATE_TX_CHIRP :
211
    begin
212
        if (!chirp_i)
213
            next_state_r  = STATE_TX_IDLE;
214
    end
215
 
216
    default :
217
       ;
218
 
219
    endcase
220
 
221
    // USB reset but not chirping...
222
    if (!enable_i && !chirp_i)
223
        next_state_r  = STATE_TX_IDLE;
224
end
225
 
226
// Update state
227
always @ (posedge clk_i or posedge rst_i)
228
if (rst_i)
229
    state_q   <= STATE_TX_IDLE;
230
else
231
    state_q   <= next_state_r;
232
 
233
//-----------------------------------------------------------------
234
// Data Input
235
//-----------------------------------------------------------------
236
reg       input_valid_r;
237
reg [7:0] input_byte_r;
238
reg       input_last_r;
239
always @ *
240
begin
241
    input_valid_r = data_strb_i & data_pid_q;
242
    input_byte_r  = data_i;
243
    input_last_r  = data_last_i;
244
end
245
 
246
reg data_accept_r;
247
always @ *
248
begin
249
    if (state_q == STATE_TX_DATA)
250
        data_accept_r = utmi_txready_i;
251
    else if (state_q == STATE_TX_PID && data_zlp_q)
252
        data_accept_r = utmi_txready_i;
253
    else
254
        data_accept_r = 1'b0;
255
end
256
 
257
assign data_accept_o = data_accept_r;
258
 
259
//-----------------------------------------------------------------
260
// CRC16: Generate CRC16 on outgoing data
261
//-----------------------------------------------------------------
262
reg [15:0]  crc_sum_q;
263
wire [15:0] crc_out_w;
264
reg         crc_err_q;
265
 
266
usbf_crc16
267
u_crc16
268
(
269
    .crc_in_i(crc_sum_q),
270
    .din_i(utmi_data_o),
271
    .crc_out_o(crc_out_w)
272
);
273
 
274
always @ (posedge clk_i or posedge rst_i)
275
if (rst_i)
276
    crc_sum_q   <= 16'hFFFF;
277
else if (state_q == STATE_TX_IDLE)
278
    crc_sum_q   <= 16'hFFFF;
279
else if (state_q == STATE_TX_DATA && utmi_txvalid_o && utmi_txready_i)
280
    crc_sum_q   <= crc_out_w;
281
 
282
//-----------------------------------------------------------------
283
// Output
284
//-----------------------------------------------------------------
285
reg       valid_q;
286
reg [7:0] data_q;
287
 
288
always @ (posedge clk_i or posedge rst_i)
289
if (rst_i)
290
begin
291
    valid_q <= 1'b0;
292
    data_q  <= 8'b0;
293
    last_q  <= 1'b0;
294
end
295
else if (!enable_i)
296
begin
297
    valid_q <= 1'b0;
298
    data_q  <= 8'b0;
299
    last_q  <= 1'b0;
300
end
301
else if (tx_valid_i && tx_accept_o)
302
begin
303
    valid_q <= 1'b1;
304
    data_q  <= tx_pid_i;
305
    last_q  <= 1'b0;
306
end
307
else if (utmi_txready_i)
308
begin
309
    valid_q <= 1'b0;
310
    data_q  <= 8'b0;
311
    last_q  <= 1'b0;
312
end
313
 
314
reg       utmi_txvalid_r;
315
reg [7:0] utmi_data_r;
316
 
317
always @ *
318
begin
319
    if (state_q == STATE_TX_CHIRP)
320
    begin
321
        utmi_txvalid_r = 1'b1;
322
        utmi_data_r    = 8'b0;
323
    end
324
    else if (state_q == STATE_TX_CRC1)
325
    begin
326
        utmi_txvalid_r = 1'b1;
327
        utmi_data_r    = crc_sum_q[7:0] ^ 8'hFF;
328
    end
329
    else if (state_q == STATE_TX_CRC2)
330
    begin
331
        utmi_txvalid_r = 1'b1;
332
        utmi_data_r    = crc_sum_q[15:8] ^ 8'hFF;
333
    end
334
    else if (state_q == STATE_TX_DATA)
335
    begin
336
        utmi_txvalid_r = data_valid_i;
337
        utmi_data_r    = data_i;
338
    end
339
    else
340
    begin
341
        utmi_txvalid_r = valid_q;
342
        utmi_data_r    = data_q;
343
    end
344
end
345
 
346
assign utmi_txvalid_o = utmi_txvalid_r;
347
assign utmi_data_o    = utmi_data_r;
348
 
349
 
350
endmodule

powered by: WebSVN 2.1.0

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