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

Subversion Repositories usb2uart

[/] [usb2uart/] [trunk/] [rtl/] [usb1_core/] [usb1_ctrl.v] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 dinesha
/**********************************************************************
2
*  Ported to USB2UART project
3
*  Author:  Dinesh Annayya
4
*           Email:- dinesha@opencores.org
5
*
6
*     Date: 4th Feb 2013
7
*     Changes:
8
*     A. Warning Clean Up
9
*
10
**********************************************************************/
11
/////////////////////////////////////////////////////////////////////
12
////                                                             ////
13
////  Internal Setup Engine                                      ////
14
////                                                             ////
15
////                                                             ////
16
////  Author: Rudolf Usselmann                                   ////
17
////          rudi@asics.ws                                      ////
18
////                                                             ////
19
////                                                             ////
20
////  Downloaded from: http://www.opencores.org/cores/usb1_funct/////
21
////                                                             ////
22
/////////////////////////////////////////////////////////////////////
23
////                                                             ////
24
//// Copyright (C) 2000-2002 Rudolf Usselmann                    ////
25
////                         www.asics.ws                        ////
26
////                         rudi@asics.ws                       ////
27
////                                                             ////
28
//// This source file may be used and distributed without        ////
29
//// restriction provided that this copyright statement is not   ////
30
//// removed from the file and that any derivative work contains ////
31
//// the original copyright notice and the associated disclaimer.////
32
////                                                             ////
33
////     THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY     ////
34
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED   ////
35
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS   ////
36
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR      ////
37
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,         ////
38
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    ////
39
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE   ////
40
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR        ////
41
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF  ////
42
//// LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT  ////
43
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT  ////
44
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE         ////
45
//// POSSIBILITY OF SUCH DAMAGE.                                 ////
46
////                                                             ////
47
/////////////////////////////////////////////////////////////////////
48
 
49
//  CVS Log
50
//
51
//  $Id: usb1_ctrl.v,v 1.2 2002-09-25 06:06:49 rudi Exp $
52
//
53
//  $Date: 2002-09-25 06:06:49 $
54
//  $Revision: 1.2 $
55
//  $Author: rudi $
56
//  $Locker:  $
57
//  $State: Exp $
58
//
59
// Change History:
60
//               $Log: not supported by cvs2svn $
61
//               Revision 1.1.1.1  2002/09/19 12:07:09  rudi
62
//               Initial Checkin
63
//
64
//
65
//
66
//
67
//
68
//
69
 
70
`include "usb1_defines.v"
71
 
72
module usb1_ctrl(       clk, rst,
73
 
74
                        rom_adr, rom_data,
75
 
76
                        ctrl_setup, ctrl_in, ctrl_out,
77
 
78
                        rx_ctrl_data, rx_ctrl_dvalid,rx_ctrl_ddone,
79
 
80
                        ep0_din, ep0_dout, ep0_re, ep0_we, ep0_stat,
81
                        ep0_size,
82
 
83
                        send_stall, frame_no,
84
                        funct_adr, configured, halt,
85
 
86
                        v_set_int, v_set_feature, wValue, wIndex, vendor_data,
87
 
88
               // Register Interface
89
                reg_addr,
90
                reg_rdwrn,
91
                reg_req,
92
                reg_wdata,
93
                reg_rdata,
94
                reg_ack
95
 
96
 
97
                );
98
 
99
input           clk, rst;
100
 
101
output  [6:0]    rom_adr;
102
input   [7:0]    rom_data;
103
 
104
input           ctrl_setup;
105
input           ctrl_in;
106
input           ctrl_out;
107
 
108
 
109
input [7:0]     rx_ctrl_data;
110
input           rx_ctrl_dvalid;
111
input           rx_ctrl_ddone;
112
 
113
input   [7:0]    ep0_din;
114
output  [7:0]    ep0_dout;
115
output          ep0_re, ep0_we;
116
input   [3:0]    ep0_stat;
117
output  [7:0]    ep0_size;
118
 
119
output          send_stall;
120
input   [10:0]   frame_no;
121
output  [6:0]    funct_adr;
122
output          configured, halt;
123
 
124
output          v_set_int;
125
output          v_set_feature;
126
output  [15:0]   wValue;
127
output  [15:0]   wIndex;
128
input   [15:0]   vendor_data;
129
 
130
//-----------------------------------
131
// Register Interface
132
// ----------------------------------
133
output [31:0]   reg_addr;   // Register Address
134
output          reg_rdwrn;  // 0 -> write, 1-> read
135
output          reg_req;    //  Register Req
136
output [31:0]    reg_wdata;  // Register write data
137
input  [31:0]    reg_rdata;  // Register Read Data
138
input           reg_ack;    // Register Ack
139
 
140
 
141
 
142
///////////////////////////////////////////////////////////////////
143
//
144
// Local Wires and Registers
145
//
146
 
147
parameter       IDLE                    =       20'b0000_0000_0000_0000_0001,
148
                GET_HDR                 =       20'b0000_0000_0000_0000_0010,
149
                GET_STATUS_S            =       20'b0000_0000_0000_0000_0100,
150
                CLEAR_FEATURE_S         =       20'b0000_0000_0000_0000_1000,
151
                SET_FEATURE_S           =       20'b0000_0000_0000_0001_0000,
152
                SET_ADDRESS_S           =       20'b0000_0000_0000_0010_0000,
153
                GET_DESCRIPTOR_S        =       20'b0000_0000_0000_0100_0000,
154
                SET_DESCRIPTOR_S        =       20'b0000_0000_0000_1000_0000,
155
                GET_CONFIG_S            =       20'b0000_0000_0001_0000_0000,
156
                SET_CONFIG_S            =       20'b0000_0000_0010_0000_0000,
157
                GET_INTERFACE_S         =       20'b0000_0000_0100_0000_0000,
158
                SET_INTERFACE_S         =       20'b0000_0000_1000_0000_0000,
159
                SYNCH_FRAME_S           =       20'b0000_0001_0000_0000_0000,
160
                WAIT_IN_DATA            =       20'b0000_0010_0000_0000_0000,
161
                STATUS_IN               =       20'b0000_0100_0000_0000_0000,
162
                STATUS_OUT              =       20'b0000_1000_0000_0000_0000,
163
                V_SET_INT_S             =       20'b0001_0000_0000_0000_0000,
164
                V_GET_STATUS_S          =       20'b0010_0000_0000_0000_0000,
165
                V_GET_REG_RDATA_S       =       20'b0100_0000_0000_0000_0000,
166
                V_WAIT_RDATA_DONE_S     =       20'b1000_0000_0000_0000_0000;
167
 
168
 
169
wire    [7:0]    bmReqType, bRequest;
170
wire    [15:0]   wValue, wIndex, wLength;
171
wire            bm_req_dir;
172
wire    [1:0]    bm_req_type;
173
wire    [4:0]    bm_req_recp;
174
 
175
reg             get_status, clear_feature, set_feature, set_address;
176
reg             get_descriptor, set_descriptor, get_config, set_config;
177
reg             get_interface, set_interface, synch_frame;
178
reg             hdr_done_r, config_err;
179
reg             v_set_int, v_set_feature, v_get_status;
180
 
181
reg             v_set_reg_waddr; // Set the Reg Bus Address
182
reg             v_set_reg_raddr; // Set the Reg Bus Address
183
 
184
wire            fifo_re1, fifo_full, fifo_empty;
185
reg             fifo_we_d;
186
reg     [5:0]    data_sel;
187
reg             ep0_we;
188
reg     [7:0]    ep0_dout;
189
reg     [7:0]    ep0_size;
190
reg             send_stall;
191
reg     [19:0]   state, next_state;
192
reg             get_hdr;
193
reg     [7:0]    le;
194
wire            hdr_done;
195
reg             adv;
196
reg     [7:0]    hdr0, hdr1, hdr2, hdr3, hdr4, hdr5, hdr6, hdr7;
197
reg     [6:0]    funct_adr;
198
reg             set_adr_pending;
199
reg     [6:0]    funct_adr_tmp;
200
 
201
reg             in_size_0;
202
reg             in_size_1;
203
reg             in_size_2;
204
reg             in_size_4;
205
wire            high_sel;
206
reg             write_done;
207
 
208
//----------------------------
209
// Register Interface
210
// ----------------------------
211
reg   [31:0]    reg_addr;
212
reg   [31:0]    reg_wdata;
213
reg   [31:0]    reg_rdata_r;
214
reg             reg_req;
215
reg             reg_rdwrn; // 0 - write, 1 -> read
216
reg             reg_wphase; // register write phase
217
reg             reg_rphase; // register read phase
218
reg [3:0]       tx_bcnt; // transmit byte count
219
///////////////////////////////////////////////////////////////////
220
//
221
// FIFO interface
222
//
223
 
224
assign ep0_re = fifo_re1;
225
assign fifo_empty = ep0_stat[1];
226
assign fifo_full = ep0_stat[2];
227
 
228
///////////////////////////////////////////////////////////////////
229
//
230
// Current States
231
//
232
reg     addressed;
233
reg     configured;
234
reg     halt;
235
wire    clr_halt;
236
wire    set_halt=0;      // FIX_ME
237
 
238
// For this implementation we do not implement HALT for the
239
// device nor for any of the endpoints. This is useless for
240
// this device, but can be added here later ...
241
// FYI, we report device/endpoint errors via interrupts,
242
// instead of halting the entire or part of the device, much
243
// nicer for non-critical errors.
244
 
245
assign clr_halt = ctrl_setup;
246
 
247
always @(posedge clk)
248
        if(!rst)        addressed <= #1 1'b0;
249
        else
250
        if(set_address) addressed <= #1 1'b1;
251
 
252
always @(posedge clk)
253
        if(!rst)        configured <= #1 1'b0;
254
        else
255
        if(set_config)  configured <= #1 1'b1;
256
 
257
always @(posedge clk)
258
        if(!rst)        halt <= #1 1'b0;
259
        else
260
        if(clr_halt)    halt <= #1 1'b0;
261
        else
262
        if(set_halt)    halt <= #1 1'b1;
263
 
264
///////////////////////////////////////////////////////////////////
265
//
266
// Descriptor ROM
267
//
268
reg     [6:0]    rom_adr;
269
reg             rom_sel, rom_sel_r;
270
wire            rom_done;
271
reg     [6:0]    rom_size;
272
reg             fifo_we_rom_r;
273
reg             fifo_we_rom_r2;
274
wire            fifo_we_rom;
275
reg     [7:0]    rom_start_d;
276
reg     [6:0]    rom_size_dd;
277
wire    [6:0]    rom_size_d;
278
 
279
always @(wValue)
280
        case(wValue[11:8])              // synopsys full_case parallel_case
281
           4'h1:        rom_start_d = `ROM_START0;
282
           4'h2:        rom_start_d = `ROM_START1;
283
           4'h3:
284
                case(wValue[3:0])        // synopsys full_case parallel_case
285
                   4'h0:        rom_start_d = `ROM_START2A;
286
                   4'h1:        rom_start_d = `ROM_START2B;
287
                   4'h2:        rom_start_d = `ROM_START2C;
288
                   4'h3:        rom_start_d = `ROM_START2D;
289
                   default:     rom_start_d = `ROM_START2A;
290
                endcase
291
           default:     rom_start_d = 7'h00;
292
        endcase
293
 
294
always @(wValue)
295
        case(wValue[11:8])              // synopsys full_case parallel_case
296
           4'h1:        rom_size_dd = `ROM_SIZE0;
297
           4'h2:        rom_size_dd = `ROM_SIZE1;
298
           4'h3:
299
                case(wValue[3:0])        // synopsys full_case parallel_case
300
                   4'h0:        rom_size_dd = `ROM_SIZE2A;
301
                   4'h1:        rom_size_dd = `ROM_SIZE2B;
302
                   4'h2:        rom_size_dd = `ROM_SIZE2C;
303
                   4'h3:        rom_size_dd = `ROM_SIZE2D;
304
                   default:     rom_size_dd = `ROM_SIZE2A;
305
                endcase
306
           default:     rom_size_dd = 7'h01;
307
        endcase
308
 
309
assign rom_size_d = (rom_size_dd > wLength[6:0]) ? wLength[6:0] : rom_size_dd;
310
 
311
always @(posedge clk)
312
        rom_sel_r <= #1 rom_sel;
313
 
314
always @(posedge clk)
315
        if(!rst)                        rom_adr <= #1 7'h0;
316
        else
317
        if(rom_sel & !rom_sel_r)        rom_adr <= #1 rom_start_d;
318
        else
319
        if(rom_sel & !fifo_full)        rom_adr <= #1 rom_adr + 7'h1;
320
 
321
always @(posedge clk)
322
        if(!rst)                        rom_size <= #1 7'h0;
323
        else
324
        if(rom_sel & !rom_sel_r)        rom_size <= #1 rom_size_d;
325
        else
326
        if(rom_sel & !fifo_full)        rom_size <= #1 rom_size - 7'h01;
327
 
328
always @(posedge clk)
329
        fifo_we_rom_r <= #1 rom_sel;
330
 
331
always @(posedge clk)
332
        fifo_we_rom_r2 <= #1 fifo_we_rom_r;
333
 
334
assign fifo_we_rom = rom_sel & fifo_we_rom_r2;
335
 
336
assign rom_done = (rom_size == 7'h0) & !(rom_sel & !rom_sel_r);
337
 
338
///////////////////////////////////////////////////////////////////
339
//
340
// Get Header
341
//
342
 
343
assign fifo_re1 = (get_hdr | reg_wphase) & !fifo_empty;
344
 
345
always @(posedge clk)
346
        adv <= #1 get_hdr & !fifo_empty & !adv;
347
 
348
always @(posedge clk)
349
        if(!rst)        le <= #1 8'h0;
350
        else
351
        if(!get_hdr)    le <= #1 8'h0;
352
        else
353
        if(!(|le))      le <= #1 8'h1;
354
        else
355
        if(fifo_re1 && get_hdr) le <= #1 {le[6:0], 1'b0};
356
 
357
always @(posedge clk)
358
        if(le[0])        hdr0 <= #1 ep0_din;
359
 
360
always @(posedge clk)
361
        if(le[1])       hdr1 <= #1 ep0_din;
362
 
363
always @(posedge clk)
364
        if(le[2])       hdr2 <= #1 ep0_din;
365
 
366
always @(posedge clk)
367
        if(le[3])       hdr3 <= #1 ep0_din;
368
 
369
always @(posedge clk)
370
        if(le[4])       hdr4 <= #1 ep0_din;
371
 
372
always @(posedge clk)
373
        if(le[5])       hdr5 <= #1 ep0_din;
374
 
375
always @(posedge clk)
376
        if(le[6])       hdr6 <= #1 ep0_din;
377
 
378
always @(posedge clk)
379
        if(le[7])       hdr7 <= #1 ep0_din;
380
 
381
assign hdr_done = le[7] & fifo_re1 & get_hdr;
382
 
383
///////////////////////////////////////////////////////////////////
384
//
385
// Send Data to Host
386
//
387
parameter       ZERO_DATA       =       6'b000001,
388
                ZERO_ONE_DATA   =       6'b000010,
389
                CONFIG_DATA     =       6'b000100,
390
                SYNC_FRAME_DATA =       6'b001000,
391
                VEND_DATA       =       6'b010000,
392
                REG_RDATA       =       6'b100000;
393
 
394
assign high_sel = write_done;
395
 
396
always @(posedge clk)
397
        case(data_sel)          // synopsys full_case parallel_case
398
           ZERO_DATA:           ep0_dout <= #1 rom_sel ? rom_data : 8'h0;
399
           ZERO_ONE_DATA:       ep0_dout <= #1 high_sel ? 8'h1 : 8'h0;
400
           CONFIG_DATA:         ep0_dout <= #1 {7'h0, configured};      // return configuration
401
           SYNC_FRAME_DATA:     ep0_dout <= #1 high_sel ? {5'h0, frame_no[10:8]} : frame_no[7:0];
402
           VEND_DATA:           ep0_dout <= #1 high_sel ? vendor_data[15:8] : vendor_data[7:0];
403
           REG_RDATA:           ep0_dout <= #1 (tx_bcnt==0) ? reg_rdata_r[31:24] :
404
                                               (tx_bcnt==1) ? reg_rdata_r[23:16] :
405
                                               (tx_bcnt==2) ? reg_rdata_r[15:8] : reg_rdata_r[7:0];
406
        endcase
407
 
408
always @(posedge clk)
409
        ep0_we <= #1 (fifo_we_d & !write_done) | fifo_we_rom;
410
 
411
always @(posedge clk)
412
        if(in_size_0)           ep0_size <= #1 8'h0;
413
        else if(in_size_1)      ep0_size <= #1 8'h1;
414
        else if(in_size_2)      ep0_size <= #1 8'h2;
415
        else if(in_size_4)      ep0_size <= #1 8'h4;
416
        else
417
        if(rom_sel)     ep0_size <= #1 {1'b0, rom_size_d};
418
 
419
 
420
always @(posedge clk) begin
421
   if(!rst) begin
422
       tx_bcnt    <= 0;
423
       write_done <= 0;
424
    end else begin
425
       if(state == IDLE)  begin
426
          tx_bcnt <= 0;
427
          write_done <= 0;
428
      end else if((ep0_size == (tx_bcnt+1))  && (!fifo_full && fifo_we_d))
429
          write_done <= 1;
430
      else if(!fifo_full && fifo_we_d )
431
          tx_bcnt <= tx_bcnt+1;
432
      else
433
          write_done <= 0;
434
   end
435
end
436
 
437
///////////////////////////////////////////////////////////////////
438
//
439
// Decode Header
440
//
441
 
442
// Valid bRequest Codes
443
parameter       GET_STATUS      =       8'h00,
444
                CLEAR_FEATURE   =       8'h01,
445
                SET_FEATURE     =       8'h03,
446
                SET_ADDRESS     =       8'h05,
447
                GET_DESCRIPTOR  =       8'h06,
448
                SET_DESCRIPTOR  =       8'h07,
449
                GET_CONFIG      =       8'h08,
450
                SET_CONFIG      =       8'h09,
451
                GET_INTERFACE   =       8'h0a,
452
                SET_INTERFACE   =       8'h0b,
453
                SYNCH_FRAME     =       8'h0c,
454
                CUSTOM_REG_WADDR=       8'h10, // Added by Dinesh-A, 19th Feb 2013
455
                CUSTOM_REG_RADDR=       8'h11; // Added by Dinesh-A, 19th Feb 2013
456
 
457
parameter       V_SET_INT       =       8'h0f;
458
 
459
/*************************************************
460
*  Author: Dinesh-A: 18th Feb 2013
461
*  Setup Byte Details
462
Byte    Field   Description
463
 
464
           Bit 7: Request direction (0=Host to device – Out, 1=Device to host – In).
465
           Bits 5-6: Request type (0=standard, 1=class, 2=vendor, 3=reserved).
466
           Bits 0-4: Recipient (0=device, 1=interface, 2=endpoint,3=other).
467
1       bRequest         The actual request (see the Standard Device Request Codes table [9.2.1.5].
468
2       wValueL  A word-size value that varies according to the request. For example,
469
        in the CLEAR_FEATURE request the value is used to select the feature,
470
        in the GET_DESCRIPTOR request the value indicates the descriptor type and in the
471
        SET_ADDRESS request the value contains the device address.
472
3       wValueH The upper byte of the Value word.
473
4       wIndexL  A word-size value that varies according to the request.
474
        The index is generally used to specify an endpoint or an interface.
475
5       wIndexH The upper byte of the Index word.
476
6       wLengthL  A word-size value that indicates the number of bytes to be transferred if there is a data stage.
477
7       wLengthH  The upper byte of the Length word.
478
**************************************************/
479
/*******
480
bRequest                       Value
481
GET_STATUS                     0
482
CLEAR_FEATURE                  1
483
Reserved for future use        2
484
SET_FEATURE                    3
485
Reserved for future use        4
486
SET_ADDRESS                    5
487
GET_DESCRIPTOR                 6
488
SET_DESCRIPTOR                 7
489
GET_CONFIGURATION              8
490
SET_CONFIGURATION              9
491
GET_INTERFACE                  10
492
SET_INTERFACE                  11
493
SYNCH_FRAME                    12
494
 
495
*******************************/
496
 
497
assign bmReqType = hdr0;
498
assign bm_req_dir = bmReqType[7];       // 0-Host to device; 1-device to host 
499
assign bm_req_type = bmReqType[6:5];    // 0-standard; 1-class; 2-vendor; 3-RESERVED
500
assign bm_req_recp = bmReqType[4:0];     // 0-device; 1-interface; 2-endpoint; 3-other
501
                                        // 4..31-reserved
502
assign bRequest =  hdr1;
503
assign wValue   = {hdr3, hdr2};
504
assign wIndex   = {hdr5, hdr4};
505
assign wLength  = {hdr7, hdr6};
506
 
507
always @(posedge clk)
508
        hdr_done_r <= #1 hdr_done;
509
 
510
// Standard commands that MUST support
511
always @(posedge clk)
512
        get_status <= #1        hdr_done & (bRequest == GET_STATUS) & (bm_req_type==2'h0);
513
 
514
always @(posedge clk)
515
        clear_feature <= #1     hdr_done & (bRequest == CLEAR_FEATURE) & (bm_req_type==2'h0);
516
 
517
always @(posedge clk)
518
        set_feature <= #1       hdr_done & (bRequest == SET_FEATURE) & (bm_req_type==2'h0);
519
 
520
always @(posedge clk)
521
        set_address <= #1       hdr_done & (bRequest == SET_ADDRESS) & (bm_req_type==2'h0);
522
 
523
always @(posedge clk)
524
        get_descriptor <= #1    hdr_done & (bRequest == GET_DESCRIPTOR) & (bm_req_type==2'h0);
525
 
526
always @(posedge clk)
527
        set_descriptor <= #1    hdr_done & (bRequest == SET_DESCRIPTOR) & (bm_req_type==2'h0);
528
 
529
always @(posedge clk)
530
        get_config <= #1        hdr_done & (bRequest == GET_CONFIG) & (bm_req_type==2'h0);
531
 
532
always @(posedge clk)
533
        set_config <= #1        hdr_done & (bRequest == SET_CONFIG) & (bm_req_type==2'h0);
534
 
535
always @(posedge clk)
536
        get_interface <= #1     hdr_done & (bRequest == GET_INTERFACE) & (bm_req_type==2'h0);
537
 
538
always @(posedge clk)
539
        set_interface <= #1     hdr_done & (bRequest == SET_INTERFACE) & (bm_req_type==2'h0);
540
 
541
always @(posedge clk)
542
        synch_frame <= #1       hdr_done & (bRequest == SYNCH_FRAME) & (bm_req_type==2'h0);
543
 
544
always @(posedge clk)
545
        v_set_int <= #1         hdr_done & (bRequest == V_SET_INT) & (bm_req_type==2'h2);
546
 
547
always @(posedge clk)
548
        v_set_feature <= #1     hdr_done & (bRequest == SET_FEATURE) & (bm_req_type==2'h2);
549
 
550
always @(posedge clk)
551
        v_get_status <= #1      hdr_done & (bRequest == GET_STATUS) & (bm_req_type==2'h2);
552
always @(posedge clk)
553
        v_set_reg_waddr <= #1   hdr_done & (bRequest == CUSTOM_REG_WADDR) & (bm_req_type==2'h2);
554
always @(posedge clk)
555
        v_set_reg_raddr <= #1   hdr_done & (bRequest == CUSTOM_REG_RADDR) & (bm_req_type==2'h2);
556
 
557
always @(posedge clk)
558
        if(v_set_reg_waddr || v_set_reg_raddr) reg_addr  <= {hdr2,hdr3,hdr4,hdr5};
559
 
560
reg [1:0] reg_byte_cnt;
561
always @(posedge clk) begin
562
   if(!rst) begin
563
       reg_byte_cnt <= 2'b0;
564
   end else begin
565
      if(v_set_reg_waddr) begin
566
          reg_wphase      <= 1;
567
          reg_byte_cnt    <= 0;
568
      end else if(reg_byte_cnt == 2'b11 && fifo_re1) begin
569
          reg_wphase  <= 0;
570
          reg_byte_cnt    <= 0;
571
      end else if(reg_wphase && fifo_re1) begin
572
         reg_byte_cnt <= reg_byte_cnt+1;
573
      end
574
   end
575
end
576
 
577
 
578
always @(posedge clk)
579
      if(reg_wphase && fifo_re1) reg_wdata  <= {reg_wdata[23:0],ep0_din[7:0]};
580
 
581
always @(posedge clk)
582
      if(reg_rdwrn && reg_ack) reg_rdata_r  <= {reg_rdata};
583
 
584
always @(posedge clk) begin
585
   if(!rst) begin
586
      reg_req  <= 0;
587
   end else begin
588
      if(fifo_re1 && reg_wphase && reg_byte_cnt== 2'b11) reg_req  <= 1;
589
      else if(v_set_reg_raddr)         reg_req  <= 1;
590
      else reg_req <= 0;
591
   end
592
end
593
 
594
always @(posedge clk)
595
        if(v_set_reg_raddr)      reg_rdwrn <= 1'b1 ;
596
        else if(v_set_reg_waddr) reg_rdwrn <= 1'b0 ;
597
 
598
// A config err must cause the device to send a STALL for an ACK
599
always @(posedge clk)
600
        config_err <= #1 hdr_done_r & !(get_status | clear_feature |
601
                        set_feature | set_address | get_descriptor |
602
                        set_descriptor | get_config | set_config |
603
                        get_interface | set_interface | synch_frame |
604
                        v_set_int | v_set_feature | v_get_status | v_set_reg_waddr | v_set_reg_raddr);
605
 
606
always @(posedge clk)
607
        send_stall <= #1 config_err;
608
 
609
///////////////////////////////////////////////////////////////////
610
//
611
// Set address
612
//
613
 
614
always @(posedge clk)
615
        if(!rst)                                set_adr_pending <= #1 1'b0;
616
        else
617
        if(ctrl_in | ctrl_out | ctrl_setup)     set_adr_pending <= #1 1'b0;
618
        else
619
        if(set_address)                         set_adr_pending <= #1 1'b1;
620
 
621
always @(posedge clk)
622
        if(!rst)                        funct_adr_tmp <= #1 7'h0;
623
        else
624
        if(set_address)                 funct_adr_tmp <= #1 wValue[6:0];
625
 
626
always @(posedge clk)
627
        if(!rst)                        funct_adr <= #1 7'h0;
628
        else
629
        if(set_adr_pending & ctrl_in)   funct_adr <= #1 funct_adr_tmp;
630
 
631
///////////////////////////////////////////////////////////////////
632
//
633
// Main FSM
634
//
635
 
636
always @(posedge clk)
637
        if(!rst)        state <= #1 IDLE;
638
        else            state <= next_state;
639
 
640
always @(state or ctrl_setup or ctrl_in or ctrl_out or hdr_done or
641
        fifo_full or rom_done or write_done or wValue or bm_req_recp or
642
        get_status or clear_feature or set_feature or set_address or
643
        get_descriptor or set_descriptor or get_config or set_config or
644
        get_interface or set_interface or synch_frame or v_set_int or
645
        v_set_feature or v_get_status or v_set_reg_waddr or v_set_reg_raddr, reg_ack
646
        )
647
   begin
648
        next_state = state;
649
        get_hdr  = 1'b0;
650
        data_sel = ZERO_DATA;
651
        fifo_we_d = 1'b0;
652
        in_size_0 = 1'b0;
653
        in_size_1 = 1'b0;
654
        in_size_2 = 1'b0;
655
        in_size_4 = 1'b0;
656
        rom_sel = 1'b0;
657
 
658
        case(state)     // synopsys full_case parallel_case
659
 
660
                // Wait for Setup token
661
           IDLE:
662
                   begin
663
                        if(ctrl_setup)          next_state = GET_HDR;
664
                        if(get_status)          next_state = GET_STATUS_S;
665
                        if(clear_feature)       next_state = CLEAR_FEATURE_S;
666
                        if(set_feature)         next_state = SET_FEATURE_S;
667
                        if(set_address)         next_state = SET_ADDRESS_S;
668
                        if(get_descriptor)      next_state = GET_DESCRIPTOR_S;
669
                        if(set_descriptor)      next_state = SET_DESCRIPTOR_S;
670
                        if(get_config)          next_state = GET_CONFIG_S;
671
                        if(set_config)          next_state = SET_CONFIG_S;
672
                        if(get_interface)       next_state = GET_INTERFACE_S;
673
                        if(set_interface)       next_state = SET_INTERFACE_S;
674
                        if(synch_frame)         next_state = SYNCH_FRAME_S;
675
                        if(v_set_int)           next_state = V_SET_INT_S;
676
                        if(v_set_feature)       next_state = V_SET_INT_S;
677
                        if(v_get_status)        next_state = V_GET_STATUS_S;
678
                        if(v_set_reg_waddr)     next_state = STATUS_IN;
679
                        if(v_set_reg_raddr)     next_state = V_WAIT_RDATA_DONE_S;
680
                   end
681
 
682
                // Retrieve Setup Header
683
           GET_HDR:
684
                   begin
685
                        get_hdr = 1'b1;
686
                        if(hdr_done)    next_state = IDLE;
687
                   end
688
 
689
 
690
                // Actions for supported commands
691
           GET_STATUS_S:
692
                   begin
693
                        // Returns to host
694
                        // 16'h0001 for device
695
                        // 16'h0000 for interface
696
                        // 16'h0000 for endpoint
697
                        if(bm_req_recp == 5'h00)        data_sel = ZERO_ONE_DATA;
698
                        else                            data_sel = ZERO_DATA;
699
 
700
                        in_size_2 = 1'b1;
701
                        if(!fifo_full)
702
                           begin
703
                                fifo_we_d = 1'b1;
704
                                if(write_done)  next_state = WAIT_IN_DATA;
705
                           end
706
 
707
                   end
708
           V_GET_STATUS_S:
709
                   begin
710
                        data_sel = VEND_DATA;
711
                        in_size_2 = 1'b1;
712
                        if(!fifo_full)
713
                           begin
714
                                fifo_we_d = 1'b1;
715
                                if(write_done)  next_state = WAIT_IN_DATA;
716
                           end
717
                   end
718
 
719
        V_WAIT_RDATA_DONE_S: begin // Wait for Register Read Access Completion
720
                     if(reg_ack)
721
                        next_state = V_GET_REG_RDATA_S;
722
                   end
723
 
724
           V_GET_REG_RDATA_S: // Register Access Read Data
725
                   begin
726
                        data_sel = REG_RDATA;
727
                        in_size_4 = 1'b1;
728
                        if(!fifo_full)
729
                           begin
730
                                fifo_we_d = 1'b1;
731
                                if(write_done)  next_state = WAIT_IN_DATA;
732
                           end
733
                   end
734
           CLEAR_FEATURE_S:
735
                   begin
736
                        // just ignore this for now
737
                        next_state = STATUS_IN;
738
                   end
739
 
740
           SET_FEATURE_S:
741
                   begin
742
                        // just ignore this for now
743
                        next_state = STATUS_IN;
744
                   end
745
 
746
           SET_ADDRESS_S:
747
                   begin
748
                        // done elsewhere ....
749
                        next_state = STATUS_IN;
750
                   end
751
 
752
           GET_DESCRIPTOR_S:
753
                   begin
754
                        if(     wValue[15:8] == 8'h01 |
755
                                wValue[15:8] == 8'h02 |
756
                                wValue[15:8] == 8'h03   )
757
                                rom_sel = 1'b1;
758
                        else
759
                                next_state = IDLE;
760
 
761
                        if(rom_done)
762
                                next_state = IDLE;
763
                   end
764
 
765
           SET_DESCRIPTOR_S:
766
                   begin
767
                        // This doesn't do anything since we do not support
768
                        // setting the descriptor
769
                        next_state = IDLE;
770
                   end
771
 
772
           GET_CONFIG_S:
773
                   begin
774
                        // Send one byte back that indicates current status
775
                        in_size_1 = 1'b1;
776
                        data_sel = CONFIG_DATA;
777
                        if(!fifo_full)
778
                           begin
779
                                fifo_we_d = 1'b1;
780
                                next_state = WAIT_IN_DATA;
781
                           end
782
                   end
783
 
784
           SET_CONFIG_S:
785
                   begin
786
                        // done elsewhere ....
787
                        next_state = STATUS_IN;
788
                   end
789
 
790
           GET_INTERFACE_S:
791
                   begin
792
                        // Return interface '0'
793
                        in_size_1 = 1'b1;
794
                        if(!fifo_full)
795
                           begin
796
                                fifo_we_d = 1'b1;
797
                                next_state = WAIT_IN_DATA;
798
                           end
799
                   end
800
 
801
           SET_INTERFACE_S:
802
                   begin
803
                        // just ignore this for now
804
                        next_state = STATUS_IN;
805
                   end
806
 
807
           SYNCH_FRAME_S:
808
                   begin
809
                        // Return Frame current frame number
810
                        data_sel = SYNC_FRAME_DATA;
811
                        in_size_2 = 1'b1;
812
                        if(!fifo_full)
813
                           begin
814
                                fifo_we_d = 1'b1;
815
                                if(write_done)  next_state = WAIT_IN_DATA;
816
                           end
817
                   end
818
 
819
           V_SET_INT_S:
820
                   begin
821
                        // done elsewhere ....
822
                        next_state = STATUS_IN;
823
                   end
824
 
825
           WAIT_IN_DATA:
826
                   begin
827
                        if(ctrl_in)     next_state = STATUS_OUT;
828
                   end
829
 
830
           STATUS_IN:
831
                   begin
832
                        in_size_0 = 1'b1;
833
                        if(ctrl_in)     next_state = IDLE;
834
                   end
835
 
836
           STATUS_OUT:
837
                   begin
838
                        if(ctrl_out)    next_state = IDLE;
839
                   end
840
        endcase
841
   end
842
 
843
endmodule
844
 

powered by: WebSVN 2.1.0

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