hw/ip/usb_fs_nb_pe/rtl/usb_fs_tx.sv Cov: 100%
1: // Copyright lowRISC contributors.
2: // Copyright ETH Zurich.
3: // Copyright Luke Valenty (TinyFPGA project, https://github.com/tinyfpga/TinyFPGA-Bootloader).
4: // Licensed under the Apache License, Version 2.0, see LICENSE for details.
5: // SPDX-License-Identifier: Apache-2.0
6:
7: module usb_fs_tx (
8: // A 48MHz clock is required to receive USB data at 12MHz
9: // it's simpler to juse use 48MHz everywhere
10: input logic clk_i,
11: input logic rst_ni, // asyc reset
12: input logic link_reset_i, // USB reset, sync to 48 MHz, active high
13:
14: // Oscillator test mode (constantly output JK)
15: input logic tx_osc_test_mode_i,
16:
17: // bit strobe from rx to align with senders clock
18: input logic bit_strobe_i,
19:
20: // output enable to take ownership of bus and data out
21: output logic usb_oe_o,
22: output logic usb_d_o,
23: output logic usb_se0_o,
24:
25: // pulse to initiate new packet transmission
26: input logic pkt_start_i,
27: output logic pkt_end_o,
28:
29: // pid_i to send
30: input logic [3:0] pid_i,
31:
32: // tx logic pulls data until there is nothing available
33: input logic tx_data_avail_i,
34: output logic tx_data_get_o,
35: input logic [7:0] tx_data_i
36: );
37:
38:
39: typedef enum logic [2:0] {Idle, Sync, Pid, DataOrCrc160, Crc161, Eop, OscTest} state_e;
40: typedef enum logic [1:0] {OsIdle, OsWaitByte, OsTransmit} out_state_e;
41:
42:
43: /////////////////////////
44: // Signal Declarations //
45: /////////////////////////
46: logic [3:0] pid_q, pid_d;
47: logic bitstuff;
48: logic bitstuff_q;
49: logic bitstuff_q2;
50: logic bitstuff_q3;
51: logic bitstuff_q4;
52:
53: logic [5:0] bit_history;
54:
55: state_e state_d, state_q;
56: out_state_e out_state_d, out_state_q;
57:
58:
59: logic [7:0] data_shift_reg_q, data_shift_reg_d;
60: logic [7:0] oe_shift_reg_q, oe_shift_reg_d;
61: logic [7:0] se0_shift_reg_q, se0_shift_reg_d;
62: logic data_payload_q, data_payload_d;
63: logic tx_data_get_q, tx_data_get_d;
64: logic byte_strobe_q, byte_strobe_d;
65: logic [4:0] bit_history_d, bit_history_q;
66: logic [2:0] bit_count_d, bit_count_q;
67:
68: logic [15:0] crc16_d, crc16_q;
69:
70: logic oe_q, oe_d;
71: logic usb_d_q, usb_d_d;
72: logic usb_se0_q, usb_se0_d;
73: logic [2:0] dp_eop_q, dp_eop_d;
74:
75: logic test_mode_start;
76: logic serial_tx_data;
77: logic serial_tx_oe;
78: logic serial_tx_se0;
79: logic crc16_invert;
80: logic pkt_end;
81: logic out_nrzi_en;
82:
83: // save packet parameters at pkt_start_i
84: always_ff @(posedge clk_i or negedge rst_ni) begin : proc_pid
85: if (!rst_ni) begin
86: pid_q <= 0;
87: end else begin
88: if (link_reset_i) begin
89: pid_q <= 0;
90: end else begin
91: pid_q <= pid_d;
92: end
93: end
94: end
95:
96: assign pid_d = pkt_start_i ? pid_i : pid_q;
97:
98:
99: assign serial_tx_data = data_shift_reg_q[0];
100: assign serial_tx_oe = oe_shift_reg_q[0];
101: assign serial_tx_se0 = se0_shift_reg_q[0];
102:
103:
104: // serialize sync, pid_i, data payload, and crc16
105: assign bit_history = {serial_tx_data, bit_history_q};
106: assign bitstuff = bit_history == 6'b111111;
107:
108: always_ff @(posedge clk_i or negedge rst_ni) begin : proc_bitstuff
109: if (!rst_ni) begin
110: bitstuff_q <= 0;
111: bitstuff_q2 <= 0;
112: bitstuff_q3 <= 0;
113: bitstuff_q4 <= 0;
114: end else begin
115: if (link_reset_i) begin
116: bitstuff_q <= 0;
117: bitstuff_q2 <= 0;
118: bitstuff_q3 <= 0;
119: bitstuff_q4 <= 0;
120: end else begin
121: bitstuff_q <= bitstuff;
122: bitstuff_q2 <= bitstuff_q;
123: bitstuff_q3 <= bitstuff_q2;
124: bitstuff_q4 <= bitstuff_q3;
125: end
126: end
127: end
128:
129: assign pkt_end = bit_strobe_i && se0_shift_reg_q[1:0] == 2'b01;
130: assign pkt_end_o = pkt_end;
131:
132:
133: /////////
134: // FSM //
135: /////////
136: always_comb begin : proc_fsm
137: // Default assignments
138: state_d = state_q;
139: data_shift_reg_d = data_shift_reg_q;
140: oe_shift_reg_d = oe_shift_reg_q;
141: se0_shift_reg_d = se0_shift_reg_q;
142: data_payload_d = data_payload_q;
143: tx_data_get_d = tx_data_get_q;
144: bit_history_d = bit_history_q;
145: bit_count_d = bit_count_q;
146: test_mode_start = 0;
147:
148:
149: unique case (state_q)
150: Idle : begin
151: if (tx_osc_test_mode_i) begin
152: state_d = OscTest;
153: test_mode_start = 1;
154: end else if (pkt_start_i) begin
155: state_d = Sync;
156: end
157: end
158:
159: Sync : begin
160: if (byte_strobe_q) begin
161: state_d = Pid;
162: data_shift_reg_d = 8'b10000000;
163: oe_shift_reg_d = 8'b11111111;
164: se0_shift_reg_d = 8'b00000000;
165: end
166: end
167:
168: Pid : begin
169: if (byte_strobe_q) begin
170: if (pid_q[1:0] == 2'b11) begin
171: state_d = DataOrCrc160;
172: end else begin
173: state_d = Eop;
174: end
175:
176: data_shift_reg_d = {~pid_q, pid_q};
177: oe_shift_reg_d = 8'b11111111;
178: se0_shift_reg_d = 8'b00000000;
179: end
180: end
181:
182: DataOrCrc160 : begin
183: if (byte_strobe_q) begin
184: if (tx_data_avail_i) begin
185: state_d = DataOrCrc160;
186: data_payload_d = 1;
187: tx_data_get_d = 1;
188: data_shift_reg_d = tx_data_i;
189: oe_shift_reg_d = 8'b11111111;
190: se0_shift_reg_d = 8'b00000000;
191: end else begin
192: state_d = Crc161;
193: data_payload_d = 0;
194: tx_data_get_d = 0;
195: data_shift_reg_d = ~{crc16_q[8], crc16_q[9], crc16_q[10], crc16_q[11], crc16_q[12], crc16_q[13], crc16_q[14], crc16_q[15]};
196: oe_shift_reg_d = 8'b11111111;
197: se0_shift_reg_d = 8'b00000000;
198: end
199: end else begin
200: tx_data_get_d = 0;
201: end
202: end
203:
204: Crc161 : begin
205: if (byte_strobe_q) begin
206: state_d = Eop;
207: data_shift_reg_d = ~{crc16_q[0], crc16_q[1], crc16_q[2], crc16_q[3], crc16_q[4], crc16_q[5], crc16_q[6], crc16_q[7]};
208: oe_shift_reg_d = 8'b11111111;
209: se0_shift_reg_d = 8'b00000000;
210: end
211: end
212:
213: Eop : begin
214: if (byte_strobe_q) begin
215: state_d = Idle;
216: oe_shift_reg_d = 8'b00000111;
217: se0_shift_reg_d = 8'b00000111;
218: end
219: end
220:
221: OscTest: begin
222: // Oscillator test mode: toggle constantly
223: if (!tx_osc_test_mode_i && byte_strobe_q) begin
224: oe_shift_reg_d = 8'b00000000;
225: state_d = Idle;
226: end else if (byte_strobe_q) begin
227: data_shift_reg_d = 8'b00000000;
228: oe_shift_reg_d = 8'b11111111;
229: se0_shift_reg_d = 8'b00000000;
230: end
231: end
232: endcase
233:
234: // Logic closely coupled to the FSM
235: if (pkt_start_i) begin
236: // We need to have a inter-packed delay between
237: // 2 and 6.5 bit times (see USB 2.0 spec / 7.1.18.1)
238: // The latency in the rest of the system is approximately (measured)
239: // 3.68 bit-times, so we only introduce 1 bit-time here
240: bit_count_d = 7; // 8-7 = 1
241: bit_history_d = 0;
242:
243: end else if (bit_strobe_i) begin
244: // bitstuff
245: if (bitstuff /* && !serial_tx_se0*/) begin
246: bit_history_d = bit_history[5:1];
247: data_shift_reg_d[0] = 0;
248:
249: // normal deserialize
250: end else begin
251: bit_count_d = bit_count_q + 1;
252:
253: data_shift_reg_d = (data_shift_reg_q >> 1);
254: oe_shift_reg_d = (oe_shift_reg_q >> 1);
255: se0_shift_reg_d = (se0_shift_reg_q >> 1);
256:
257: bit_history_d = bit_history[5:1];
258: end
259: end
260: end
261:
262: always_comb begin : proc_byte_str
263: if (bit_strobe_i && !bitstuff && !pkt_start_i) begin
264: byte_strobe_d = (bit_count_q == 3'b000);
265: end else begin
266: byte_strobe_d = 0;
267: end
268:
269: end
270:
271: assign tx_data_get_o = tx_data_get_q;
272:
273: // calculate crc16
274: assign crc16_invert = serial_tx_data ^ crc16_q[15];
275:
276: always_comb begin : proc_crc16
277: crc16_d = crc16_q; // default assignment
278:
279: if (pkt_start_i) begin
280: crc16_d = 16'b1111111111111111;
281: end
282:
283: if (bit_strobe_i && data_payload_q && !bitstuff_q4 && !pkt_start_i) begin
284: crc16_d = {crc16_q[14:0], 1'b0} ^ ({16{crc16_invert}} & 16'b1000000000000101);
285: end
286: end
287:
288: ///////////////////////
289: // Regular Registers //
290: ///////////////////////
291:
292: always_ff @(posedge clk_i or negedge rst_ni) begin : proc_reg
293: if (!rst_ni) begin
294: state_q <= Idle;
295: data_payload_q <= 0;
296: data_shift_reg_q <= 0;
297: oe_shift_reg_q <= 0;
298: se0_shift_reg_q <= 0;
299: tx_data_get_q <= 0;
300: byte_strobe_q <= 0;
301: bit_history_q <= 0;
302: bit_count_q <= 0;
303: crc16_q <= 0;
304: end else begin
305: if (link_reset_i) begin
306: state_q <= Idle;
307: data_payload_q <= 0;
308: data_shift_reg_q <= 0;
309: oe_shift_reg_q <= 0;
310: se0_shift_reg_q <= 0;
311: tx_data_get_q <= 0;
312: byte_strobe_q <= 0;
313: bit_history_q <= 0;
314: bit_count_q <= 0;
315: crc16_q <= 0;
316: end else begin
317: state_q <= state_d;
318: data_payload_q <= data_payload_d;
319: data_shift_reg_q <= data_shift_reg_d;
320: oe_shift_reg_q <= oe_shift_reg_d;
321: se0_shift_reg_q <= se0_shift_reg_d;
322: tx_data_get_q <= tx_data_get_d;
323: byte_strobe_q <= byte_strobe_d;
324: bit_history_q <= bit_history_d;
325: bit_count_q <= bit_count_d;
326: crc16_q <= crc16_d;
327: end
328: end
329: end
330:
331: ///////////////////////////////////
332: // nrzi and differential driving //
333: ///////////////////////////////////
334:
335: // Output FSM
336: always_comb begin : proc_out_fsm
337: out_state_d = out_state_q;
338: out_nrzi_en = 1'b0;
339:
340: unique case (out_state_q)
341: OsIdle: begin
342: if (pkt_start_i || test_mode_start) begin
343: out_state_d = OsWaitByte;
344: end
345: end
346:
347: OsWaitByte: begin
348: if (byte_strobe_q) begin
349: out_state_d = OsTransmit;
350: end
351: end
352:
353: OsTransmit: begin
354: out_nrzi_en = 1'b1;
355: if ((bit_strobe_i && !serial_tx_oe)) begin
356: out_state_d = OsIdle;
357: end
358: end
359:
360: default : out_state_d = OsIdle;
361: endcase
362: end
363:
364: always_comb begin : proc_diff
365: usb_d_d = usb_d_q;
366: usb_se0_d = usb_se0_q;
367: oe_d = oe_q;
368: dp_eop_d = dp_eop_q;
369:
370: if (pkt_start_i) begin
371: usb_d_d = 1; // J -> first bit will be K (start of sync)
372: dp_eop_d = 3'b100; // Eop: {SE0, SE0, J}
373:
374: end else if (bit_strobe_i && out_nrzi_en) begin
375: oe_d = serial_tx_oe;
376:
377: if (serial_tx_se0) begin
378: // Eop
379: dp_eop_d = dp_eop_q >> 1;
380:
381: if (dp_eop_q[0]) begin
382: // last bit of Eop: J
383: usb_d_d = 1;
384: usb_se0_d = 0;
385: end else begin
386: // first two bits of Eop: SE0
387: usb_se0_d = 1;
388: end
389:
390: end else if (serial_tx_data) begin
391: // value should stay the same, do nothing
392:
393: end else begin
394: usb_d_d = !usb_d_q;
395: end
396:
397: // Set to J state when OE=0 to avoid
398: // glitches
399: if (!oe_d) begin
400: usb_d_d = 1;
401: end
402: end
403:
404: end
405:
406: always_ff @(posedge clk_i or negedge rst_ni) begin : proc_diff_reg
407: if (!rst_ni) begin
408: dp_eop_q <= 0;
409: oe_q <= 0;
410: usb_d_q <= 1; // J state = idle state
411: usb_se0_q <= 0;
412: out_state_q <= OsIdle;
413: end else begin
414: if (link_reset_i) begin
415: dp_eop_q <= 0;
416: oe_q <= 0;
417: usb_d_q <= 1;
418: usb_se0_q <= 0;
419: out_state_q <= OsIdle;
420: end else begin
421: dp_eop_q <= dp_eop_d;
422: oe_q <= oe_d;
423: usb_d_q <= usb_d_d;
424: usb_se0_q <= usb_se0_d;
425: out_state_q <= out_state_d;
426: end
427: end
428: end
429:
430: assign usb_oe_o = oe_q;
431: assign usb_d_o = usb_d_q;
432: assign usb_se0_o = usb_se0_q;
433:
434: endmodule
435: