vt52-fpga  1.0.0 Initial
vt52-fpga is a serial terminal implemented on a FPGA
usb_uart.v
Go to the documentation of this file.
1 /*
2  usb_uart
3 
4  Luke Valenti's USB module, as adapted by Lawrie Griffiths.
5 
6  This module was originally tinyfpga_bootloader.v in Luke's code.
7 
8  It creates the endpoint modules and the protocol engine to run things. Whereas
9  the original creates a usb_spi_bridge, this one creates a usb_uart_bridge.
10 
11  Instanciation template
12 
13  ----------------------------------------------------
14  usb_uart uart (
15  .clk_48mhz (clk_48mhz),
16  .reset (reset),
17 
18  // pins - these must be connected properly to the outside world. See below.
19  .usb_p_tx(usb_p_tx),
20  .usb_n_tx(usb_n_tx),
21  .usb_p_rx(usb_p_rx),
22  .usb_n_rx(usb_n_rx),
23  .usb_tx_en(usb_tx_en),
24 
25  // uart pipeline in
26  .uart_in_data( uart_in_data ),
27  .uart_in_valid( uart_in_valid ),
28  .uart_in_ready( uart_in_ready ),
29 
30  // uart pipeline out
31  .uart_out_data( uart_out_data ),
32  .uart_out_valid( uart_out_valid ),
33  .uart_out_ready( uart_out_ready ),
34 
35  .debug( debug )
36  );
37 
38  ----------------------------------------------------
39 
40  Then, the actual physical pins need some special handling. Get some
41  help from the device.
42 
43  ----------------------------------------------------
44  assign usb_p_rx = usb_tx_en ? 1'b1 : usb_p_in;
45  assign usb_n_rx = usb_tx_en ? 1'b0 : usb_n_in;
46 
47  SB_IO #(
48  .PIN_TYPE(6'b 1010_01), // PIN_OUTPUT_TRISTATE - PIN_INPUT
49  .PULLUP(1'b 0)
50  )
51  iobuf_usbp
52  (
53  .PACKAGE_PIN(pin_usbp),
54  .OUTPUT_ENABLE(usb_tx_en),
55  .D_OUT_0(usb_p_tx),
56  .D_IN_0(usb_p_in)
57  );
58 
59  SB_IO #(
60  .PIN_TYPE(6'b 1010_01), // PIN_OUTPUT_TRISTATE - PIN_INPUT
61  .PULLUP(1'b 0)
62  )
63  iobuf_usbn
64  (
65  .PACKAGE_PIN(pin_usbn),
66  .OUTPUT_ENABLE(usb_tx_en),
67  .D_OUT_0(usb_n_tx),
68  .D_IN_0(usb_n_in)
69  );
70  ----------------------------------------------------
71 
72 It should be noted that there are no other invocations of usb stuff other than
73 usb_uart.v. Since it's the top, I'm going to put some doc in here.
74 
75 General note: USB communications happen over endpoints. The OUT endpoints are out
76 with respect to the HOST, and IN endpoints are in with respect to the HOST.
77 
78 Files:
79 
80 usb_uart.v - top level module creates the end points clusters, (usb_serial_ctrl_ep,
81  usb_uart_bridge_ep) and the main protocol engine (usb_fs_pe - passing
82  in the in (3) and out (2) count, along with the actual usb signal
83  lines). Also, all the end point signals are connected to the protocol
84  engine in its invocation. The serial end point cluster and the control
85  end point cluster have two endpoints each - one in and one out.
86 
87 usb_serial_ctrl_ep - serial control logic. Two end point interfaces are (one in one
88  out) passed in with their various signal lines. Contains all the
89  USB setup logic. Returns the configuration etc. Vendor 50 1D
90  Product 30 61. Two interfaces. Descriptors. Obviously the main
91  configuration file.
92 
93 usb_uart_bridge.v - where the data action is for us. Is passed in the out endpoint
94  and the in endpoint, and also the (strange) UART interface signals
95  (uart_we, uart_re, uart_di, uart_do, uart_wait). So this translates
96  between endpoint talk and UART talk.
97 
98 usb_fs_pe.v - full speed protocol engine - instanciates all the endpoints, making
99  arrays of in and out end point signals. Also is passed in are all
100  the actual interfaces to the end points.
101 
102  Creates the in and out arbitors (usb_fs_in_arb, usb_fs_out_arb)
103 
104  Creates the in protocol engine (usb_fs_in_pe), and the out protocol
105  engine (usb_fs_out_pe)
106 
107  Creates the receiver and transmitter (usb_fs_rx, usb_fs_tx)
108 
109  Creates the tx mux and the rx mux which permit the different engines
110  to talk.
111 
112 usb_fs_in_pe.v - in protocol engine
113 
114 usb_fs_out_pe.v - out protocol engine
115 
116 usb_fs_rx.v - Actual rx logic
117 
118 usb_fs_tx.v - Actual tx logic
119 
120 edge_detect.v - rising and falling edge detectors
121 
122 serial.v - width adapter (x widths to y widths)
123 
124 */
125 
126 module usb_uart (
127  input clk_48mhz,
128  input reset,
129 
130  // USB lines. Split into input vs. output and oe control signal to maintain
131  // highest level of compatibility with synthesis tools.
132  output usb_p_tx,
133  output usb_n_tx,
134  input usb_p_rx,
135  input usb_n_rx,
136  output usb_tx_en,
137 
138  // uart pipeline in (into the module, out of the device, into the host)
139  input [7:0] uart_in_data,
140  input uart_in_valid,
141  output uart_in_ready,
142 
143  // uart pipeline out (out of the host, into the device, out of the module)
144  output [7:0] uart_out_data,
145  output uart_out_valid,
146  input uart_out_ready,
147 
148  output [11:0] debug
149 );
150 
151  ////////////////////////////////////////////////////////////////////////////////
152  ////////////////////////////////////////////////////////////////////////////////
153  ////////
154  //////// usb engine
155  ////////
156  ////////////////////////////////////////////////////////////////////////////////
157  ////////////////////////////////////////////////////////////////////////////////
158 
159  wire [6:0] dev_addr;
160  wire [7:0] out_ep_data;
161 
162  wire ctrl_out_ep_req;
163  wire ctrl_out_ep_grant;
164  wire ctrl_out_ep_data_avail;
165  wire ctrl_out_ep_setup;
166  wire ctrl_out_ep_data_get;
167  wire ctrl_out_ep_stall;
168  wire ctrl_out_ep_acked;
169 
170  wire ctrl_in_ep_req;
171  wire ctrl_in_ep_grant;
172  wire ctrl_in_ep_data_free;
173  wire ctrl_in_ep_data_put;
174  wire [7:0] ctrl_in_ep_data;
175  wire ctrl_in_ep_data_done;
176  wire ctrl_in_ep_stall;
177  wire ctrl_in_ep_acked;
178 
179 
180  wire serial_out_ep_req;
181  wire serial_out_ep_grant;
182  wire serial_out_ep_data_avail;
183  wire serial_out_ep_setup;
184  wire serial_out_ep_data_get;
185  wire serial_out_ep_stall;
186  wire serial_out_ep_acked;
187 
188  wire serial_in_ep_req;
189  wire serial_in_ep_grant;
190  wire serial_in_ep_data_free;
191  wire serial_in_ep_data_put;
192  wire [7:0] serial_in_ep_data;
193  wire serial_in_ep_data_done;
194  wire serial_in_ep_stall;
195  wire serial_in_ep_acked;
196 
197  wire sof_valid;
198  wire [10:0] frame_index;
199 
200  reg [31:0] host_presence_timer = 0;
201  reg host_presence_timeout = 0;
202 
203  usb_serial_ctrl_ep ctrl_ep_inst (
204  .clk(clk_48mhz),
205  .reset(reset),
206  .dev_addr(dev_addr),
207 
208  // out endpoint interface
209  .out_ep_req(ctrl_out_ep_req),
210  .out_ep_grant(ctrl_out_ep_grant),
211  .out_ep_data_avail(ctrl_out_ep_data_avail),
212  .out_ep_setup(ctrl_out_ep_setup),
213  .out_ep_data_get(ctrl_out_ep_data_get),
214  .out_ep_data(out_ep_data),
215  .out_ep_stall(ctrl_out_ep_stall),
216  .out_ep_acked(ctrl_out_ep_acked),
217 
218 
219  // in endpoint interface
220  .in_ep_req(ctrl_in_ep_req),
221  .in_ep_grant(ctrl_in_ep_grant),
222  .in_ep_data_free(ctrl_in_ep_data_free),
223  .in_ep_data_put(ctrl_in_ep_data_put),
224  .in_ep_data(ctrl_in_ep_data),
225  .in_ep_data_done(ctrl_in_ep_data_done),
226  .in_ep_stall(ctrl_in_ep_stall),
227  .in_ep_acked(ctrl_in_ep_acked)
228  );
229 
230  usb_uart_bridge_ep usb_uart_bridge_ep_inst (
231  .clk(clk_48mhz),
232  .reset(reset),
233 
234  // out endpoint interface
235  .out_ep_req(serial_out_ep_req),
236  .out_ep_grant(serial_out_ep_grant),
237  .out_ep_data_avail(serial_out_ep_data_avail),
238  .out_ep_setup(serial_out_ep_setup),
239  .out_ep_data_get(serial_out_ep_data_get),
240  .out_ep_data(out_ep_data),
241  .out_ep_stall(serial_out_ep_stall),
242  .out_ep_acked(serial_out_ep_acked),
243 
244  // in endpoint interface
245  .in_ep_req(serial_in_ep_req),
246  .in_ep_grant(serial_in_ep_grant),
247  .in_ep_data_free(serial_in_ep_data_free),
248  .in_ep_data_put(serial_in_ep_data_put),
249  .in_ep_data(serial_in_ep_data),
250  .in_ep_data_done(serial_in_ep_data_done),
251  .in_ep_stall(serial_in_ep_stall),
252  .in_ep_acked(serial_in_ep_acked),
253 
254  // uart pipeline in
255  .uart_in_data( uart_in_data ),
256  .uart_in_valid( uart_in_valid ),
257  .uart_in_ready( uart_in_ready ),
258 
259  // uart pipeline out
260  .uart_out_data( uart_out_data ),
261  .uart_out_valid( uart_out_valid ),
262  .uart_out_ready( uart_out_ready ),
263 
264  .debug(debug[3:0])
265  );
266 
267  wire nak_in_ep_grant;
268  wire nak_in_ep_data_free;
269  wire nak_in_ep_acked;
270 
271  usb_fs_pe #(
272  .NUM_OUT_EPS(5'd2),
273  .NUM_IN_EPS(5'd3)
274  ) usb_fs_pe_inst (
275  .clk(clk_48mhz),
276  .reset(reset),
277 
278  .usb_p_tx(usb_p_tx),
279  .usb_n_tx(usb_n_tx),
280  .usb_p_rx(usb_p_rx),
281  .usb_n_rx(usb_n_rx),
282  .usb_tx_en(usb_tx_en),
283 
284  .dev_addr(dev_addr),
285 
286  // out endpoint interfaces
287  .out_ep_req({serial_out_ep_req, ctrl_out_ep_req}),
288  .out_ep_grant({serial_out_ep_grant, ctrl_out_ep_grant}),
289  .out_ep_data_avail({serial_out_ep_data_avail, ctrl_out_ep_data_avail}),
290  .out_ep_setup({serial_out_ep_setup, ctrl_out_ep_setup}),
291  .out_ep_data_get({serial_out_ep_data_get, ctrl_out_ep_data_get}),
292  .out_ep_data(out_ep_data),
293  .out_ep_stall({serial_out_ep_stall, ctrl_out_ep_stall}),
294  .out_ep_acked({serial_out_ep_acked, ctrl_out_ep_acked}),
295 
296  // in endpoint interfaces
297  .in_ep_req({1'b0, serial_in_ep_req, ctrl_in_ep_req}),
298  .in_ep_grant({nak_in_ep_grant, serial_in_ep_grant, ctrl_in_ep_grant}),
299  .in_ep_data_free({nak_in_ep_data_free, serial_in_ep_data_free, ctrl_in_ep_data_free}),
300  .in_ep_data_put({1'b0, serial_in_ep_data_put, ctrl_in_ep_data_put}),
301  .in_ep_data({8'b0, serial_in_ep_data[7:0], ctrl_in_ep_data[7:0]}),
302  .in_ep_data_done({1'b0, serial_in_ep_data_done, ctrl_in_ep_data_done}),
303  .in_ep_stall({1'b0, serial_in_ep_stall, ctrl_in_ep_stall}),
304  .in_ep_acked({nak_in_ep_acked, serial_in_ep_acked, ctrl_in_ep_acked}),
305 
306  // sof interface
307  .sof_valid(sof_valid),
308  .frame_index(frame_index),
309 
310  // Debug
311  .debug(debug[11:4])
312  );
313 
314 
315  ////////////////////////////////////////////////////////////////////////////////
316  // host presence detection
317  ////////////////////////////////////////////////////////////////////////////////
318 
319  always @(posedge clk_48mhz) begin
320  if (sof_valid) begin
321  host_presence_timer <= 0;
322  host_presence_timeout <= 0;
323  end else begin
324  host_presence_timer <= host_presence_timer + 1;
325  end
326 
327  if (host_presence_timer > 48000000) begin
328  host_presence_timeout <= 1;
329  end
330  end
331 endmodule
module usb_uart(input clk_48mhz, input reset, output usb_p_tx, output usb_n_tx, input usb_p_rx, input usb_n_rx, output usb_tx_en, input[8] uart_in_data, input uart_in_valid, output uart_in_ready, output[8] uart_out_data, output uart_out_valid, input uart_out_ready, output[11:0] debug)
Definition: usb_uart.v:126
module usb_uart_bridge_ep(input clk, input reset, 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[8] in_ep_data, output in_ep_data_done, output in_ep_stall, input in_ep_acked, input[8] uart_in_data, input uart_in_valid, output uart_in_ready, output[8] uart_out_data, output uart_out_valid, input uart_out_ready, output[4] debug)
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 usb_fs_pe(input clk, input[7] dev_addr, input reset, input[NUM_OUT_EPS-1:0] out_ep_req, output[NUM_OUT_EPS-1:0] out_ep_grant, output[NUM_OUT_EPS-1:0] out_ep_data_avail, output[NUM_OUT_EPS-1:0] out_ep_setup, input[NUM_OUT_EPS-1:0] out_ep_data_get, output[8] out_ep_data, input[NUM_OUT_EPS-1:0] out_ep_stall, output[NUM_OUT_EPS-1:0] out_ep_acked, input[NUM_IN_EPS-1:0] in_ep_req, output[NUM_IN_EPS-1:0] in_ep_grant, output[NUM_IN_EPS-1:0] in_ep_data_free, input[NUM_IN_EPS-1:0] in_ep_data_put, input[(NUM_IN_EPS *8) -1:0] in_ep_data, input[NUM_IN_EPS-1:0] in_ep_data_done, input[NUM_IN_EPS-1:0] in_ep_stall, output[NUM_IN_EPS-1:0] in_ep_acked, output sof_valid, output[10:0] frame_index, output usb_p_tx, output usb_n_tx, input usb_p_rx, input usb_n_rx, output usb_tx_en, output[8] debug)
Definition: usb_fs_pe.v:4
always(posedge clk)
Definition: uart_rx.v:86