vt52-fpga  1.0.0 Initial
vt52-fpga is a serial terminal implemented on a FPGA
usb_fs_tx.v
Go to the documentation of this file.
1 module usb_fs_tx (
2  // A 48MHz clock is required to receive USB data at 12MHz
3  // it's simpler to juse use 48MHz everywhere
4  input clk_48mhz,
5  input reset,
6 
7  // bit strobe from rx to align with senders clock
8  input bit_strobe,
9 
10  // output enable to take ownership of bus and data out
11  output reg oe = 0,
12  output reg dp = 0,
13  output reg dn = 0,
14 
15  // pulse to initiate new packet transmission
16  input pkt_start,
17  output pkt_end,
18 
19  // pid to send
20  input [3:0] pid,
21 
22  // tx logic pulls data until there is nothing available
23  input tx_data_avail,
24  output reg tx_data_get = 0,
25  input [7:0] tx_data
26 );
27  wire clk = clk_48mhz;
28 
29  // save packet parameters at pkt_start
30  reg [3:0] pidq = 0;
31 
32  always @(posedge clk) begin
33  if (pkt_start) begin
34  pidq <= pid;
35  end
36  end
37 
38  reg [7:0] data_shift_reg = 0;
39  reg [7:0] oe_shift_reg = 0;
40  reg [7:0] se0_shift_reg = 0;
41 
42 
43  wire serial_tx_data = data_shift_reg[0];
44  wire serial_tx_oe = oe_shift_reg[0];
45  wire serial_tx_se0 = se0_shift_reg[0];
46 
47 
48  // serialize sync, pid, data payload, and crc16
49  reg byte_strobe = 0;
50  reg [2:0] bit_count = 0;
51 
52  reg [4:0] bit_history_q = 0;
53  wire [5:0] bit_history = {serial_tx_data, bit_history_q};
54  wire bitstuff = bit_history == 6'b111111;
55  reg bitstuff_q = 0;
56  reg bitstuff_qq = 0;
57  reg bitstuff_qqq = 0;
58  reg bitstuff_qqqq = 0;
59 
60 
61  always @(posedge clk) begin
62  bitstuff_q <= bitstuff;
63  bitstuff_qq <= bitstuff_q;
64  bitstuff_qqq <= bitstuff_qq;
65  bitstuff_qqqq <= bitstuff_qqq;
66  end
67 
68  assign pkt_end = bit_strobe && se0_shift_reg[1:0] == 2'b01;
69 
70  reg data_payload = 0;
71 
72  reg [31:0] pkt_state = 0;
73  localparam IDLE = 0;
74  localparam SYNC = 1;
75  localparam PID = 2;
76  localparam DATA_OR_CRC16_0 = 3;
77  localparam CRC16_1 = 4;
78  localparam EOP = 5;
79 
80  reg [15:0] crc16 = 0;
81 
82  always @(posedge clk) begin
83  case (pkt_state)
84  IDLE : begin
85  if (pkt_start) begin
86  pkt_state <= SYNC;
87  end
88  end
89 
90  SYNC : begin
91  if (byte_strobe) begin
92  pkt_state <= PID;
93  data_shift_reg <= 8'b10000000;
94  oe_shift_reg <= 8'b11111111;
95  se0_shift_reg <= 8'b00000000;
96  end
97  end
98 
99  PID : begin
100  if (byte_strobe) begin
101  if (pidq[1:0] == 2'b11) begin
102  pkt_state <= DATA_OR_CRC16_0;
103  end else begin
104  pkt_state <= EOP;
105  end
106 
107  data_shift_reg <= {~pidq, pidq};
108  oe_shift_reg <= 8'b11111111;
109  se0_shift_reg <= 8'b00000000;
110  end
111  end
112 
113  DATA_OR_CRC16_0 : begin
114  if (byte_strobe) begin
115  if (tx_data_avail) begin
116  pkt_state <= DATA_OR_CRC16_0;
117  data_payload <= 1;
118  tx_data_get <= 1;
119  data_shift_reg <= tx_data;
120  oe_shift_reg <= 8'b11111111;
121  se0_shift_reg <= 8'b00000000;
122  end else begin
123  pkt_state <= CRC16_1;
124  data_payload <= 0;
125  tx_data_get <= 0;
126  data_shift_reg <= ~{crc16[8], crc16[9], crc16[10], crc16[11], crc16[12], crc16[13], crc16[14], crc16[15]};
127  oe_shift_reg <= 8'b11111111;
128  se0_shift_reg <= 8'b00000000;
129  end
130  end else begin
131  tx_data_get <= 0;
132  end
133  end
134 
135  CRC16_1 : begin
136  if (byte_strobe) begin
137  pkt_state <= EOP;
138  data_shift_reg <= ~{crc16[0], crc16[1], crc16[2], crc16[3], crc16[4], crc16[5], crc16[6], crc16[7]};
139  oe_shift_reg <= 8'b11111111;
140  se0_shift_reg <= 8'b00000000;
141  end
142  end
143 
144  EOP : begin
145  if (byte_strobe) begin
146  pkt_state <= IDLE;
147  oe_shift_reg <= 8'b00000111;
148  se0_shift_reg <= 8'b00000111;
149  end
150  end
151  endcase
152 
153  if (bit_strobe && !bitstuff) begin
154  byte_strobe <= (bit_count == 3'b000);
155  end else begin
156  byte_strobe <= 0;
157  end
158 
159  if (pkt_start) begin
160  bit_count <= 1;
161  bit_history_q <= 0;
162 
163  end else if (bit_strobe) begin
164  // bitstuff
165  if (bitstuff /* && !serial_tx_se0*/) begin
166  bit_history_q <= bit_history[5:1];
167  data_shift_reg[0] <= 0;
168 
169  // normal deserialize
170  end else begin
171  bit_count <= bit_count + 1;
172 
173  data_shift_reg <= (data_shift_reg >> 1);
174  oe_shift_reg <= (oe_shift_reg >> 1);
175  se0_shift_reg <= (se0_shift_reg >> 1);
176 
177  bit_history_q <= bit_history[5:1];
178  end
179  end
180  end
181 
182 
183 
184  // calculate crc16
185  wire crc16_invert = serial_tx_data ^ crc16[15];
186 
187  always @(posedge clk) begin
188  if (pkt_start) begin
189  crc16 <= 16'b1111111111111111;
190  end
191 
192  if (bit_strobe && data_payload && !bitstuff_qqqq && !pkt_start) begin
193  crc16[15] <= crc16[14] ^ crc16_invert;
194  crc16[14] <= crc16[13];
195  crc16[13] <= crc16[12];
196  crc16[12] <= crc16[11];
197  crc16[11] <= crc16[10];
198  crc16[10] <= crc16[9];
199  crc16[9] <= crc16[8];
200  crc16[8] <= crc16[7];
201  crc16[7] <= crc16[6];
202  crc16[6] <= crc16[5];
203  crc16[5] <= crc16[4];
204  crc16[4] <= crc16[3];
205  crc16[3] <= crc16[2];
206  crc16[2] <= crc16[1] ^ crc16_invert;
207  crc16[1] <= crc16[0];
208  crc16[0] <= crc16_invert;
209  end
210  end
211 
212  reg [2:0] dp_eop = 0;
213 
214 
215  // nrzi and differential driving
216  always @(posedge clk) begin
217  if (pkt_start) begin
218  // J
219  dp <= 1;
220  dn <= 0;
221 
222  dp_eop <= 3'b100;
223 
224  end else if (bit_strobe) begin
225  oe <= serial_tx_oe;
226 
227  if (serial_tx_se0) begin
228  dp <= dp_eop[0];
229  dn <= 0;
230 
231  dp_eop <= dp_eop >> 1;
232 
233  end else if (serial_tx_data) begin
234  // value should stay the same, do nothing
235 
236  end else begin
237  dp <= !dp;
238  dn <= !dn;
239  end
240  end
241  end
242 
243 endmodule
module usb_fs_tx(input clk_48mhz, input reset, input bit_strobe, output reg oe=0, output reg dp=0, output reg dn=0, input pkt_start, output pkt_end, input[4] pid, input tx_data_avail, output reg tx_data_get=0, input[8] tx_data)
Definition: usb_fs_tx.v:1
always(posedge clk)
Definition: uart_rx.v:86