2 parameter MAX_IN_PACKET_SIZE = 32,
3 parameter MAX_OUT_PACKET_SIZE = 32
14 input out_ep_data_avail,
16 output out_ep_data_get,
17 input [7:0] out_ep_data,
27 input in_ep_data_free,
28 output in_ep_data_put,
29 output reg [7:0] in_ep_data = 0,
30 output in_ep_data_done,
31 output reg in_ep_stall,
38 localparam DATA_IN = 2;
39 localparam DATA_OUT = 3;
40 localparam STATUS_IN = 4;
41 localparam STATUS_OUT = 5;
43 reg [5:0] ctrl_xfr_state = IDLE;
44 reg [5:0] ctrl_xfr_state_next;
48 reg setup_stage_end = 0;
49 reg data_stage_end = 0;
50 reg status_stage_end = 0;
51 reg send_zero_length_data_pkt = 0;
56 reg [6:0] dev_addr_i = 0;
57 assign dev_addr = dev_addr_i;
59 assign out_ep_req = out_ep_data_avail;
60 assign out_ep_data_get = out_ep_data_avail;
61 reg out_ep_data_valid = 0;
62 always @(posedge clk) out_ep_data_valid <= out_ep_data_avail && out_ep_grant;
65 reg [3:0] setup_data_addr = 0;
66 reg [9:0] raw_setup_data [7:0];
68 wire [7:0] bmRequestType = raw_setup_data[0];
69 wire [7:0] bRequest = raw_setup_data[1];
70 wire [15:0] wValue = {raw_setup_data[3][7:0], raw_setup_data[2][7:0]};
71 wire [15:0] wIndex = {raw_setup_data[5][7:0], raw_setup_data[4][7:0]};
72 wire [15:0] wLength = {raw_setup_data[7][7:0], raw_setup_data[6][7:0]};
80 .in(out_ep_data_avail),
86 .in(out_ep_data_avail),
90 assign out_ep_stall = 1'b0;
92 wire setup_pkt_start = pkt_start && out_ep_setup;
95 wire has_data_stage = |wLength;
98 assign out_data_stage = has_data_stage && !bmRequestType[7];
101 assign in_data_stage = has_data_stage && bmRequestType[7];
103 reg [7:0] bytes_sent = 0;
104 reg [6:0] rom_length = 0;
106 wire wLength_is_large = |wLength[15:7];
109 (bytes_sent >= rom_length) ||
110 (!wLength_is_large && bytes_sent >= wLength[7:0]);
112 wire more_data_to_send =
115 wire in_data_transfer_done;
120 .out(in_data_transfer_done)
123 assign in_ep_data_done = (in_data_transfer_done && ctrl_xfr_state == DATA_IN) || send_zero_length_data_pkt;
125 assign in_ep_req = ctrl_xfr_state == DATA_IN && more_data_to_send;
126 assign in_ep_data_put = ctrl_xfr_state == DATA_IN && more_data_to_send && in_ep_data_free;
129 reg [6:0] rom_addr = 0;
131 reg save_dev_addr = 0;
132 reg [6:0] new_dev_addr = 0;
140 setup_stage_end <= 0;
142 status_stage_end <= 0;
143 send_zero_length_data_pkt <= 0;
145 case (ctrl_xfr_state)
147 if (setup_pkt_start) begin
148 ctrl_xfr_state_next <= SETUP;
150 ctrl_xfr_state_next <= IDLE;
156 setup_stage_end <= 1;
158 if (in_data_stage) begin
159 ctrl_xfr_state_next <= DATA_IN;
161 end
else if (out_data_stage) begin
162 ctrl_xfr_state_next <= DATA_OUT;
165 ctrl_xfr_state_next <= STATUS_IN;
166 send_zero_length_data_pkt <= 1;
170 ctrl_xfr_state_next <= SETUP;
175 if (in_ep_stall) begin
176 ctrl_xfr_state_next <= IDLE;
178 status_stage_end <= 1;
180 end
else if (in_ep_acked && all_data_sent) begin
181 ctrl_xfr_state_next <= STATUS_OUT;
185 ctrl_xfr_state_next <= DATA_IN;
190 if (out_ep_acked) begin
191 ctrl_xfr_state_next <= STATUS_IN;
192 send_zero_length_data_pkt <= 1;
196 ctrl_xfr_state_next <= DATA_OUT;
201 if (in_ep_acked) begin
202 ctrl_xfr_state_next <= IDLE;
203 status_stage_end <= 1;
206 ctrl_xfr_state_next <= STATUS_IN;
211 if (out_ep_acked) begin
212 ctrl_xfr_state_next <= IDLE;
213 status_stage_end <= 1;
216 ctrl_xfr_state_next <= STATUS_OUT;
221 ctrl_xfr_state_next <= IDLE;
226 always @(posedge clk) begin
228 ctrl_xfr_state <= IDLE;
230 ctrl_xfr_state <= ctrl_xfr_state_next;
234 always @(posedge clk) begin
237 if (out_ep_setup && out_ep_data_valid) begin
238 raw_setup_data[setup_data_addr] <= out_ep_data;
239 setup_data_addr <= setup_data_addr + 1;
242 if (setup_stage_end) begin
292 new_dev_addr <= wValue[6:0];
332 if (ctrl_xfr_state == DATA_IN && more_data_to_send && in_ep_grant && in_ep_data_free) begin
333 rom_addr <= rom_addr + 1;
334 bytes_sent <= bytes_sent + 1;
337 if (status_stage_end) begin
338 setup_data_addr <= 0;
343 if (save_dev_addr) begin
345 dev_addr_i <= new_dev_addr;
351 setup_data_addr <= 0;
357 `define CDC_ACM_ENDPOINT 2
358 `define CDC_RX_ENDPOINT 1
359 `define CDC_TX_ENDPOINT 1
365 'h000 : in_ep_data <= 18;
366 'h001 : in_ep_data <= 1; // bDescriptorType
367 'h002 : in_ep_data <=
'h00; // bcdUSB[0]
368 'h003 : in_ep_data <=
'h02; // bcdUSB[1]
369 'h004 : in_ep_data <=
'h02; // bDeviceClass (Communications Device Class)
370 'h005 : in_ep_data <=
'h00; // bDeviceSubClass (Abstract Control Model)
371 'h006 : in_ep_data <=
'h00; // bDeviceProtocol (No class specific protocol required)
372 'h007 : in_ep_data <= MAX_IN_PACKET_SIZE;
374 'h008 : in_ep_data <= 'h50;
375 'h009 : in_ep_data <= 'h1d;
376 'h00A : in_ep_data <= 'h30;
377 'h00B : in_ep_data <= 'h61;
379 'h00C : in_ep_data <= 0; // bcdDevice[0]
380 'h00D : in_ep_data <= 0;
381 'h00E : in_ep_data <= 0; // iManufacturer
382 'h00F : in_ep_data <= 0;
383 'h010 : in_ep_data <= 0; // iSerialNumber
384 'h011 : in_ep_data <= 1;
387 'h012 : in_ep_data <= 9; // bLength
388 'h013 : in_ep_data <= 2;
389 'h014 : in_ep_data <= (9+9+5+5+4+5+7+9+7+7); // wTotalLength[0]
390 'h015 : in_ep_data <= 0;
391 'h016 : in_ep_data <= 2; // bNumInterfaces
392 'h017 : in_ep_data <= 1;
393 'h018 : in_ep_data <= 0; // iConfiguration
394 'h019 : in_ep_data <=
'hC0; // bmAttributes
395 'h01A : in_ep_data <= 50;
398 'h01B : in_ep_data <= 9; // bLength
399 'h01C : in_ep_data <= 4;
400 'h01D : in_ep_data <= 0; // bInterfaceNumber
401 'h01E : in_ep_data <= 0;
402 'h01F : in_ep_data <= 1; // bNumEndpoints
403 'h020 : in_ep_data <= 2;
404 'h021 : in_ep_data <= 2; // bInterfaceSubClass (Abstract Control Model)
405 'h022 : in_ep_data <= 0;
406 'h023 : in_ep_data <= 0; // iInterface
408 // CDC Header Functional Descriptor, CDC Spec 5.2.3.1, Table 26
409 'h024 : in_ep_data <= 5;
410 'h025 : in_ep_data <= 'h24;
411 'h026 : in_ep_data <= 'h00;
412 'h027 : in_ep_data <= 'h10;
413 'h028 : in_ep_data <= 'h01;
416 'h029 : in_ep_data <= 5; // bFunctionLength
417 'h02A : in_ep_data <=
'h24; // bDescriptorType
418 'h02B : in_ep_data <=
'h01; // bDescriptorSubtype
419 'h02C : in_ep_data <=
'h00; // bmCapabilities
420 'h02D : in_ep_data <= 1;
423 'h02E : in_ep_data <= 4; // bFunctionLength
424 'h02F : in_ep_data <=
'h24; // bDescriptorType
425 'h030 : in_ep_data <=
'h02; // bDescriptorSubtype
426 'h031 : in_ep_data <=
'h06; // bmCapabilities
428 // Union Functional Descriptor, CDC Spec 5.2.3.8, Table 33
429 'h032 : in_ep_data <= 5;
430 'h033 : in_ep_data <= 'h24;
431 'h034 : in_ep_data <= 'h06;
432 'h035 : in_ep_data <= 0; // bMasterInterface
433 'h036 : in_ep_data <= 1;
436 'h037 : in_ep_data <= 7; // bLength
437 'h038 : in_ep_data <= 5;
438 'h039 : in_ep_data <= `CDC_ACM_ENDPOINT | 'h80;
439 'h03A : in_ep_data <= 'h03;
440 'h03B : in_ep_data <= 8; // wMaxPacketSize[0]
441 'h03C : in_ep_data <= 0;
442 'h03D : in_ep_data <= 64; // bInterval
444 // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
445 'h03E : in_ep_data <= 9;
446 'h03F : in_ep_data <= 4; // bDescriptorType
447 'h040 : in_ep_data <= 1;
448 'h041 : in_ep_data <= 0; // bAlternateSetting
449 'h042 : in_ep_data <= 2;
450 'h043 : in_ep_data <= 'h0A;
451 'h044 : in_ep_data <= 'h00;
452 'h045 : in_ep_data <= 'h00;
453 'h046 : in_ep_data <= 0; // iInterface
455 // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
456 'h047 : in_ep_data <= 7;
457 'h048 : in_ep_data <= 5; // bDescriptorType
459 'h04A : in_ep_data <= 'h02;
460 'h04B : in_ep_data <= MAX_IN_PACKET_SIZE; // wMaxPacketSize[0]
461 'h04C : in_ep_data <= 0;
462 'h04D : in_ep_data <= 0; // bInterval
464 // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
465 'h04E : in_ep_data <= 7;
466 'h04F : in_ep_data <= 5; // bDescriptorType
468 'h051 : in_ep_data <=
'h02; // bmAttributes (0x02=bulk)
470 'h052 : in_ep_data <= MAX_OUT_PACKET_SIZE;
471 'h053 : in_ep_data <= 0; // wMaxPacketSize[1]
472 'h054 : in_ep_data <= 0;
475 'h055 : in_ep_data <= 'h80;
476 'h056 : in_ep_data <= 'h25;
477 'h057 : in_ep_data <= 'h00;
478 'h058 : in_ep_data <= 'h00;
479 'h059 : in_ep_data <= 1; // bCharFormat (1 stop bit)
480 'h05A : in_ep_data <= 0;
481 'h05B : in_ep_data <= 8; // bDataBits (8 bits)
module falling_edge_detector(input clk, input in, output out)
module usb_serial_ctrl_ep(input clk, input reset, output[7] dev_addr, output out_ep_req, input out_ep_grant, input out_ep_data_avail, input out_ep_setup, output out_ep_data_get, input[8] out_ep_data, output out_ep_stall, input out_ep_acked, output in_ep_req, input in_ep_grant, input in_ep_data_free, output in_ep_data_put, output reg< 7:0 > in_ep_data=0, output in_ep_data_done, output reg in_ep_stall, input in_ep_acked)
module rising_edge_detector(input clk, input in, output out)