../src/lowrisc_ip_usb_fs_nb_pe_0.1/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: unique case (state_q)
149: Idle : begin
150: if (tx_osc_test_mode_i) begin
151: state_d = OscTest;
152: test_mode_start = 1;
153: end else if (pkt_start_i) begin
154: state_d = Sync;
155: end
156: end
157:
158: Sync : begin
159: if (byte_strobe_q) begin
160: state_d = Pid;
161: data_shift_reg_d = 8'b10000000;
162: oe_shift_reg_d = 8'b11111111;
163: se0_shift_reg_d = 8'b00000000;
164: end
165: end
166:
167: Pid : begin
168: if (byte_strobe_q) begin
169: if (pid_q[1:0] == 2'b11) begin
170: state_d = DataOrCrc160;
171: end else begin
172: state_d = Eop;
173: end
174:
175: data_shift_reg_d = {~pid_q, pid_q};
176: oe_shift_reg_d = 8'b11111111;
177: se0_shift_reg_d = 8'b00000000;
178: end
179: end
180:
181: DataOrCrc160 : begin
182: if (byte_strobe_q) begin
183: if (tx_data_avail_i) begin
184: state_d = DataOrCrc160;
185: data_payload_d = 1;
186: tx_data_get_d = 1;
187: data_shift_reg_d = tx_data_i;
188: oe_shift_reg_d = 8'b11111111;
189: se0_shift_reg_d = 8'b00000000;
190: end else begin
191: state_d = Crc161;
192: data_payload_d = 0;
193: tx_data_get_d = 0;
194: data_shift_reg_d = ~{crc16_q[8], crc16_q[9], crc16_q[10], crc16_q[11],
195: 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],
208: crc16_q[4], crc16_q[5], crc16_q[6], crc16_q[7]};
209: oe_shift_reg_d = 8'b11111111;
210: se0_shift_reg_d = 8'b00000000;
211: end
212: end
213:
214: Eop : begin
215: if (byte_strobe_q) begin
216: state_d = Idle;
217: oe_shift_reg_d = 8'b00000111;
218: se0_shift_reg_d = 8'b00000111;
219: end
220: end
221:
222: OscTest: begin
223: // Oscillator test mode: toggle constantly
224: if (!tx_osc_test_mode_i && byte_strobe_q) begin
225: oe_shift_reg_d = 8'b00000000;
226: state_d = Idle;
227: end else if (byte_strobe_q) begin
228: data_shift_reg_d = 8'b00000000;
229: oe_shift_reg_d = 8'b11111111;
230: se0_shift_reg_d = 8'b00000000;
231: end
232: end
233:
234: default: state_d = Idle;
235: endcase
236:
237: // Logic closely coupled to the FSM
238: if (pkt_start_i) begin
239: // We need to have a inter-packed delay between
240: // 2 and 6.5 bit times (see USB 2.0 spec / 7.1.18.1)
241: // The latency in the rest of the system is approximately (measured)
242: // 3.68 bit-times, so we only introduce 1 bit-time here
243: bit_count_d = 7; // 8-7 = 1
244: bit_history_d = 0;
245:
246: end else if (bit_strobe_i) begin
247: // bitstuff
248: if (bitstuff /* && !serial_tx_se0*/) begin
249: bit_history_d = bit_history[5:1];
250: data_shift_reg_d[0] = 0;
251:
252: // normal deserialize
253: end else begin
254: bit_count_d = bit_count_q + 1;
255:
256: data_shift_reg_d = (data_shift_reg_q >> 1);
257: oe_shift_reg_d = (oe_shift_reg_q >> 1);
258: se0_shift_reg_d = (se0_shift_reg_q >> 1);
259:
260: bit_history_d = bit_history[5:1];
261: end
262: end
263: end
264:
265: always_comb begin : proc_byte_str
266: if (bit_strobe_i && !bitstuff && !pkt_start_i) begin
267: byte_strobe_d = (bit_count_q == 3'b000);
268: end else begin
269: byte_strobe_d = 0;
270: end
271:
272: end
273:
274: assign tx_data_get_o = tx_data_get_q;
275:
276: // calculate crc16
277: assign crc16_invert = serial_tx_data ^ crc16_q[15];
278:
279: always_comb begin : proc_crc16
280: crc16_d = crc16_q; // default assignment
281:
282: if (pkt_start_i) begin
283: crc16_d = 16'b1111111111111111;
284: end
285:
286: if (bit_strobe_i && data_payload_q && !bitstuff_q4 && !pkt_start_i) begin
287: crc16_d = {crc16_q[14:0], 1'b0} ^ ({16{crc16_invert}} & 16'b1000000000000101);
288: end
289: end
290:
291: ///////////////////////
292: // Regular Registers //
293: ///////////////////////
294:
295: always_ff @(posedge clk_i or negedge rst_ni) begin : proc_reg
296: if (!rst_ni) begin
297: state_q <= Idle;
298: data_payload_q <= 0;
299: data_shift_reg_q <= 0;
300: oe_shift_reg_q <= 0;
301: se0_shift_reg_q <= 0;
302: tx_data_get_q <= 0;
303: byte_strobe_q <= 0;
304: bit_history_q <= 0;
305: bit_count_q <= 0;
306: crc16_q <= 0;
307: end else begin
308: if (link_reset_i) begin
309: state_q <= Idle;
310: data_payload_q <= 0;
311: data_shift_reg_q <= 0;
312: oe_shift_reg_q <= 0;
313: se0_shift_reg_q <= 0;
314: tx_data_get_q <= 0;
315: byte_strobe_q <= 0;
316: bit_history_q <= 0;
317: bit_count_q <= 0;
318: crc16_q <= 0;
319: end else begin
320: state_q <= state_d;
321: data_payload_q <= data_payload_d;
322: data_shift_reg_q <= data_shift_reg_d;
323: oe_shift_reg_q <= oe_shift_reg_d;
324: se0_shift_reg_q <= se0_shift_reg_d;
325: tx_data_get_q <= tx_data_get_d;
326: byte_strobe_q <= byte_strobe_d;
327: bit_history_q <= bit_history_d;
328: bit_count_q <= bit_count_d;
329: crc16_q <= crc16_d;
330: end
331: end
332: end
333:
334: ///////////////////////////////////
335: // nrzi and differential driving //
336: ///////////////////////////////////
337:
338: // Output FSM
339: always_comb begin : proc_out_fsm
340: out_state_d = out_state_q;
341: out_nrzi_en = 1'b0;
342:
343: unique case (out_state_q)
344: OsIdle: begin
345: if (pkt_start_i || test_mode_start) begin
346: out_state_d = OsWaitByte;
347: end
348: end
349:
350: OsWaitByte: begin
351: if (byte_strobe_q) begin
352: out_state_d = OsTransmit;
353: end
354: end
355:
356: OsTransmit: begin
357: out_nrzi_en = 1'b1;
358: if ((bit_strobe_i && !serial_tx_oe)) begin
359: out_state_d = OsIdle;
360: end
361: end
362:
363: default : out_state_d = OsIdle;
364: endcase
365: end
366:
367: always_comb begin : proc_diff
368: usb_d_d = usb_d_q;
369: usb_se0_d = usb_se0_q;
370: oe_d = oe_q;
371: dp_eop_d = dp_eop_q;
372:
373: if (pkt_start_i) begin
374: usb_d_d = 1; // J -> first bit will be K (start of sync)
375: dp_eop_d = 3'b100; // Eop: {SE0, SE0, J}
376:
377: end else if (bit_strobe_i && out_nrzi_en) begin
378: oe_d = serial_tx_oe;
379:
380: if (serial_tx_se0) begin
381: // Eop
382: dp_eop_d = dp_eop_q >> 1;
383:
384: if (dp_eop_q[0]) begin
385: // last bit of Eop: J
386: usb_d_d = 1;
387: usb_se0_d = 0;
388: end else begin
389: // first two bits of Eop: SE0
390: usb_se0_d = 1;
391: end
392:
393: end else if (serial_tx_data) begin
394: // value should stay the same, do nothing
395:
396: end else begin
397: usb_d_d = !usb_d_q;
398: end
399:
400: // Set to J state when OE=0 to avoid
401: // glitches
402: if (!oe_d) begin
403: usb_d_d = 1;
404: end
405: end
406:
407: end
408:
409: always_ff @(posedge clk_i or negedge rst_ni) begin : proc_diff_reg
410: if (!rst_ni) begin
411: dp_eop_q <= 0;
412: oe_q <= 0;
413: usb_d_q <= 1; // J state = idle state
414: usb_se0_q <= 0;
415: out_state_q <= OsIdle;
416: end else begin
417: if (link_reset_i) begin
418: dp_eop_q <= 0;
419: oe_q <= 0;
420: usb_d_q <= 1;
421: usb_se0_q <= 0;
422: out_state_q <= OsIdle;
423: end else begin
424: dp_eop_q <= dp_eop_d;
425: oe_q <= oe_d;
426: usb_d_q <= usb_d_d;
427: usb_se0_q <= usb_se0_d;
428: out_state_q <= out_state_d;
429: end
430: end
431: end
432:
433: assign usb_oe_o = oe_q;
434: assign usb_d_o = usb_d_q;
435: assign usb_se0_o = usb_se0_q;
436:
437: endmodule
438: