hw/ip/usb_fs_nb_pe/rtl/usb_fs_nb_pe.sv Cov: 100%
1: // Copyright lowRISC contributors.
2: // Copyright Luke Valenty (TinyFPGA project)
3: // Licensed under the Apache License, Version 2.0, see LICENSE for details.
4: // SPDX-License-Identifier: Apache-2.0
5:
6: // USB Full Speed Non-Buffered Protocol Engine
7: //
8: // Decodes low level USB link protocol from external usb_fs_tx/rx
9: // Provides upper level with
10: // - OUT endpoint interface (host to device) which also covers SETUP
11: // - IN endpoint interface (device to host)
12: // - Start of Frame interface
13: //
14: // Based on usb_fs_pe.v from the TinyFPGA-Bootloader project but
15: // this version contains no packet buffers
16:
17: module usb_fs_nb_pe #(
18: parameter int unsigned NumOutEps = 2,
19: parameter int unsigned NumInEps = 2,
20: parameter int unsigned MaxPktSizeByte = 32,
21: parameter int unsigned PktW = $clog2(MaxPktSizeByte)
22: ) (
23: input logic clk_48mhz_i,
24: input logic rst_ni, // Async. reset, active low
25: input logic link_reset_i, // USB reset, sync to 48 MHz, active high
26: input logic [6:0] dev_addr_i,
27:
28: input logic cfg_eop_single_bit_i, // 1: detect a single SE0 bit as EOP
29: input logic tx_osc_test_mode_i, // Oscillator test mode (constantly output JK)
30: input logic [NumOutEps-1:0] data_toggle_clear_i, // Clear the data toggles for an EP
31:
32: ////////////////////////////
33: // USB Endpoint Interface //
34: ////////////////////////////
35: ///////////////////////////////
36: // global endpoint interface //
37: ///////////////////////////////
38:
39: // out endpoint interfaces
40: output logic [3:0] out_ep_current_o, // Other signals address to this ep
41: output logic out_ep_data_put_o, // put the data (put addr advances after)
42: output logic [PktW - 1:0] out_ep_put_addr_o, // Offset to put data (0..pktlen)
43: output logic [7:0] out_ep_data_o,
44: output logic out_ep_newpkt_o,// New OUT pkt start (with in_ep_current_o update)
45: output logic out_ep_acked_o, // good termination, device has acked
46: output logic out_ep_rollback_o, // bad termination, discard data
47: output logic [NumOutEps-1:0] out_ep_setup_o,
48: input logic [NumOutEps-1:0] out_ep_full_i, // Cannot accept data
49: input logic [NumOutEps-1:0] out_ep_stall_i, // Stalled
50: input logic [NumOutEps-1:0] out_ep_iso_i, // Configure endpoint in isochronous mode
51:
52: // in endpoint interfaces
53: output logic [3:0] in_ep_current_o, // Other signals addressed to this ep
54: output logic in_ep_rollback_o, // Bad termination, rollback transaction
55: output logic in_ep_acked_o, // good termination, transaction complete
56: output logic [PktW - 1:0] in_ep_get_addr_o, // Offset requested (0..pktlen)
57: output logic in_ep_data_get_o, // Accept data (get_addr advances too)
58: output logic in_ep_newpkt_o, // New IN pkt start (with in_ep_current_o update)
59: input logic [NumInEps-1:0] in_ep_stall_i, // Endpoint in a stall state
60: input logic [NumInEps-1:0] in_ep_has_data_i, // Endpoint has data to supply
61: input logic [7:0] in_ep_data_i, // Data for current get_addr
62: input logic [NumInEps-1:0] in_ep_data_done_i, // Set when out of data
63: input logic [NumInEps-1:0] in_ep_iso_i, // Configure endpoint in isochronous mode
64:
65: // sof interface
66: output logic sof_valid_o,
67: output logic [10:0] frame_index_o,
68:
69: // RX errors
70: output logic rx_crc_err_o,
71: output logic rx_pid_err_o,
72: output logic rx_bitstuff_err_o,
73:
74: ///////////////////////////////////////
75: // USB TX/RX Interface (synchronous) //
76: ///////////////////////////////////////
77: input logic usb_d_i,
78: input logic usb_se0_i,
79:
80: output logic usb_d_o,
81: output logic usb_se0_o,
82: output logic usb_oe_o
83: );
84:
85: import usb_consts_pkg::*;
86:
87: // rx interface
88: logic bit_strobe;
89: logic rx_pkt_start;
90: logic rx_pkt_end;
91: logic [3:0] rx_pid;
92: logic [6:0] rx_addr;
93: logic [3:0] rx_endp;
94: logic [10:0] rx_frame_num;
95: logic rx_data_put;
96: logic [7:0] rx_data;
97: logic rx_pkt_valid;
98:
99: // tx mux
100: logic in_tx_pkt_start;
101: logic [3:0] in_tx_pid;
102: logic out_tx_pkt_start;
103: logic [3:0] out_tx_pid;
104:
105: // tx interface
106: logic tx_pkt_start;
107: logic tx_pkt_end;
108: logic [3:0] tx_pid;
109: logic tx_data_avail;
110: logic tx_data_get;
111: logic [7:0] tx_data;
112:
113: logic usb_oe;
114:
115: // sof interface
116: assign sof_valid_o = rx_pkt_end & rx_pkt_valid & (usb_pid_e'(rx_pid) == UsbPidSof);
117: assign frame_index_o = rx_frame_num;
118: assign usb_oe_o = usb_oe;
119:
120: usb_fs_nb_in_pe #(
121: .NumInEps (NumInEps),
122: .MaxInPktSizeByte (MaxPktSizeByte)
123: ) u_usb_fs_nb_in_pe (
124: .clk_48mhz_i (clk_48mhz_i),
125: .rst_ni (rst_ni),
126: .link_reset_i (link_reset_i),
127: .dev_addr_i (dev_addr_i),
128:
129: // endpoint interface
130: .in_ep_current_o (in_ep_current_o),
131: .in_ep_rollback_o (in_ep_rollback_o),
132: .in_ep_acked_o (in_ep_acked_o),
133: .in_ep_get_addr_o (in_ep_get_addr_o),
134: .in_ep_data_get_o (in_ep_data_get_o),
135: .in_ep_newpkt_o (in_ep_newpkt_o),
136: .in_ep_stall_i (in_ep_stall_i),
137: .in_ep_has_data_i (in_ep_has_data_i),
138: .in_ep_data_i (in_ep_data_i),
139: .in_ep_data_done_i (in_ep_data_done_i),
140: .in_ep_iso_i (in_ep_iso_i),
141:
142: .data_toggle_clear_i (data_toggle_clear_i),
143:
144: // rx path
145: .rx_pkt_start_i (rx_pkt_start),
146: .rx_pkt_end_i (rx_pkt_end),
147: .rx_pkt_valid_i (rx_pkt_valid),
148: .rx_pid_i (rx_pid),
149: .rx_addr_i (rx_addr),
150: .rx_endp_i (rx_endp),
151:
152: // tx path
153: .tx_pkt_start_o (in_tx_pkt_start),
154: .tx_pkt_end_i (tx_pkt_end),
155: .tx_pid_o (in_tx_pid),
156: .tx_data_avail_o (tx_data_avail),
157: .tx_data_get_i (tx_data_get),
158: .tx_data_o (tx_data)
159: );
160:
161: usb_fs_nb_out_pe #(
162: .NumOutEps (NumOutEps),
163: .MaxOutPktSizeByte (MaxPktSizeByte)
164: ) u_usb_fs_nb_out_pe (
165: .clk_48mhz_i (clk_48mhz_i),
166: .rst_ni (rst_ni),
167: .link_reset_i (link_reset_i),
168: .dev_addr_i (dev_addr_i),
169:
170: // endpoint interface
171: .out_ep_current_o (out_ep_current_o),
172: .out_ep_data_put_o (out_ep_data_put_o),
173: .out_ep_put_addr_o (out_ep_put_addr_o),
174: .out_ep_data_o (out_ep_data_o),
175: .out_ep_newpkt_o (out_ep_newpkt_o),
176: .out_ep_acked_o (out_ep_acked_o),
177: .out_ep_rollback_o (out_ep_rollback_o),
178: .out_ep_setup_o (out_ep_setup_o),
179: .out_ep_full_i (out_ep_full_i),
180: .out_ep_stall_i (out_ep_stall_i),
181: .out_ep_iso_i (out_ep_iso_i),
182:
183: .data_toggle_clear_i (data_toggle_clear_i),
184:
185: // rx path
186: .rx_pkt_start_i (rx_pkt_start),
187: .rx_pkt_end_i (rx_pkt_end),
188: .rx_pkt_valid_i (rx_pkt_valid),
189: .rx_pid_i (rx_pid),
190: .rx_addr_i (rx_addr),
191: .rx_endp_i (rx_endp),
192: .rx_data_put_i (rx_data_put),
193: .rx_data_i (rx_data),
194:
195: // tx path
196: .tx_pkt_start_o (out_tx_pkt_start),
197: .tx_pkt_end_i (tx_pkt_end),
198: .tx_pid_o (out_tx_pid)
199: );
200:
201: usb_fs_rx u_usb_fs_rx (
202: .clk_i (clk_48mhz_i),
203: .rst_ni (rst_ni),
204: .link_reset_i (link_reset_i),
205: .cfg_eop_single_bit_i (cfg_eop_single_bit_i),
206: .usb_d_i (usb_d_i),
207: .usb_se0_i (usb_se0_i),
208: .tx_en_i (usb_oe),
209: .bit_strobe_o (bit_strobe),
210: .pkt_start_o (rx_pkt_start),
211: .pkt_end_o (rx_pkt_end),
212: .pid_o (rx_pid),
213: .addr_o (rx_addr),
214: .endp_o (rx_endp),
215: .frame_num_o (rx_frame_num),
216: .rx_data_put_o (rx_data_put),
217: .rx_data_o (rx_data),
218: .valid_packet_o (rx_pkt_valid),
219: .crc_error_o (rx_crc_err_o),
220: .pid_error_o (rx_pid_err_o),
221: .bitstuff_error_o (rx_bitstuff_err_o)
222: );
223:
224: usb_fs_tx_mux u_usb_fs_tx_mux (
225: // interface to IN Protocol Engine
226: .in_tx_pkt_start_i (in_tx_pkt_start),
227: .in_tx_pid_i (in_tx_pid),
228:
229: // interface to OUT Protocol Engine
230: .out_tx_pkt_start_i (out_tx_pkt_start),
231: .out_tx_pid_i (out_tx_pid),
232:
233: // interface to tx module
234: .tx_pkt_start_o (tx_pkt_start),
235: .tx_pid_o (tx_pid)
236: );
237:
238: usb_fs_tx u_usb_fs_tx (
239: .clk_i (clk_48mhz_i),
240: .rst_ni (rst_ni),
241: .link_reset_i (link_reset_i),
242: .tx_osc_test_mode_i (tx_osc_test_mode_i),
243: .bit_strobe_i (bit_strobe),
244: .usb_d_o (usb_d_o),
245: .usb_se0_o (usb_se0_o),
246: .usb_oe_o (usb_oe),
247: .pkt_start_i (tx_pkt_start),
248: .pkt_end_o (tx_pkt_end),
249: .pid_i (tx_pid),
250: .tx_data_avail_i (tx_data_avail),
251: .tx_data_get_o (tx_data_get),
252: .tx_data_i (tx_data)
253: );
254: endmodule
255: