vt52-fpga  1.0.0 Initial
vt52-fpga is a serial terminal implemented on a FPGA
usb_fs_out_pe.v
Go to the documentation of this file.
1 // The OUT Protocol Engine receives data from the host.
2 module usb_fs_out_pe #(
3  parameter NUM_OUT_EPS = 1,
4  parameter MAX_OUT_PACKET_SIZE = 32
5 ) (
6  input clk,
7  input reset,
8  input [NUM_OUT_EPS-1:0] reset_ep,
9  input [6:0] dev_addr,
10 
11  ////////////////////
12  // endpoint interface
13  ////////////////////
14  output [NUM_OUT_EPS-1:0] out_ep_data_avail,
15  output reg [NUM_OUT_EPS-1:0] out_ep_setup = 0,
16  input [NUM_OUT_EPS-1:0] out_ep_data_get,
17  output reg [7:0] out_ep_data,
18  input [NUM_OUT_EPS-1:0] out_ep_stall,
19  output reg [NUM_OUT_EPS-1:0] out_ep_acked = 0,
20  // Added to provide a more constant way of detecting the current OUT EP than data get
21  input [NUM_OUT_EPS-1:0] out_ep_grant,
22 
23  ////////////////////
24  // rx path
25  ////////////////////
26 
27  // Strobed on reception of packet.
28  input rx_pkt_start,
29  input rx_pkt_end,
30  input rx_pkt_valid,
31 
32  // Most recent packet received.
33  input [3:0] rx_pid,
34  input [6:0] rx_addr,
35  input [3:0] rx_endp,
36  input [10:0] rx_frame_num,
37 
38  // rx_data is pushed into endpoint controller.
39  input rx_data_put,
40  input [7:0] rx_data,
41 
42 
43  ////////////////////
44  // tx path
45  ////////////////////
46 
47  // Strobe to send new packet.
48  output reg tx_pkt_start = 0,
49  input tx_pkt_end,
50  output reg [3:0] tx_pid = 0
51 );
52  ////////////////////////////////////////////////////////////////////////////////
53  // endpoint state machine
54  ////////////////////////////////////////////////////////////////////////////////
55  localparam READY_FOR_PKT = 0;
56  localparam PUTTING_PKT = 1;
57  localparam GETTING_PKT = 2;
58  localparam STALL = 3;
59 
60  reg [1:0] ep_state [NUM_OUT_EPS - 1:0];
61  reg [1:0] ep_state_next [NUM_OUT_EPS - 1:0];
62 
63 
64  ////////////////////////////////////////////////////////////////////////////////
65  // out transfer state machine
66  ////////////////////////////////////////////////////////////////////////////////
67  localparam IDLE = 0;
68  localparam RCVD_OUT = 1;
69  localparam RCVD_DATA_START = 2;
70  localparam RCVD_DATA_END = 3;
71 
72  reg [1:0] out_xfr_state = IDLE;
73  reg [1:0] out_xfr_state_next;
74 
75  reg out_xfr_start = 0;
76  reg new_pkt_end = 0;
77  reg rollback_data = 0;
78 
79 
80  reg [3:0] out_ep_num = 0;
81 
82 
83  reg [NUM_OUT_EPS - 1:0] out_ep_data_avail_i = 0;
84  reg [NUM_OUT_EPS - 1:0] out_ep_data_avail_j = 0;
85 
86  // set when the endpoint buffer is unable to receive the out transfer
87  reg nak_out_transfer = 0;
88 
89  // data toggle state
90  reg [NUM_OUT_EPS - 1:0] data_toggle = 0;
91 
92  // latched on valid OUT/SETUP token
93  reg [3:0] current_endp = 0;
94  wire [1:0] current_ep_state = ep_state[current_endp];
95 
96  // endpoint data buffer
97  reg [7:0] out_data_buffer [(MAX_OUT_PACKET_SIZE * NUM_OUT_EPS) - 1:0];
98 
99  // current get_addr when outputting a packet from the buffer
100  reg [5:0] ep_get_addr [NUM_OUT_EPS - 1:0];
101  reg [5:0] ep_get_addr_next [NUM_OUT_EPS - 1:0];
102 
103 
104  // endpoint put_addrs when inputting a packet into the buffer
105  reg [5:0] ep_put_addr [NUM_OUT_EPS - 1:0];
106 
107  // total buffer put addr, uses endpoint number and that endpoints current
108  // put address
109  wire [8:0] buffer_put_addr = {current_endp[3:0], ep_put_addr[current_endp][4:0]};
110  wire [8:0] buffer_get_addr = {out_ep_num[3:0], ep_get_addr[out_ep_num][4:0]};
111 
112  wire token_received =
113  rx_pkt_end &&
114  rx_pkt_valid &&
115  rx_pid[1:0] == 2'b01 &&
116  rx_addr == dev_addr &&
117  rx_endp < NUM_OUT_EPS;
118 
119  wire out_token_received =
120  token_received &&
121  rx_pid[3:2] == 2'b00;
122 
123  wire setup_token_received =
124  token_received &&
125  rx_pid[3:2] == 2'b11;
126 
127  wire invalid_packet_received =
128  rx_pkt_end &&
129  !rx_pkt_valid;
130 
131  wire data_packet_received =
132  rx_pkt_end &&
133  rx_pkt_valid &&
134  rx_pid[2:0] == 3'b011;
135 
136  wire non_data_packet_received =
137  rx_pkt_end &&
138  rx_pkt_valid &&
139  rx_pid[2:0] != 3'b011;
140 
141  //reg last_data_toggle = 0;
142 
143  wire bad_data_toggle =
144  data_packet_received &&
145  rx_pid[3] != data_toggle[rx_endp];
146 
147  //last_data_toggle == data_toggle[current_endp];
148 
149  ////////////////////////////////////////////////////////////////////////////////
150  // endpoint state machine
151  ////////////////////////////////////////////////////////////////////////////////
152 
153  genvar ep_num;
154  generate
155  for (ep_num = 0; ep_num < NUM_OUT_EPS; ep_num = ep_num + 1) begin
156  always @* begin
157 
158  ep_state_next[ep_num] <= ep_state[ep_num];
159 
160  if (out_ep_stall[ep_num]) begin
161  ep_state_next[ep_num] <= STALL;
162 
163  end else begin
164  case (ep_state[ep_num])
165  READY_FOR_PKT : begin
166  if (out_xfr_start && rx_endp == ep_num) begin
167  ep_state_next[ep_num] <= PUTTING_PKT;
168 
169  end else begin
170  ep_state_next[ep_num] <= READY_FOR_PKT;
171  end
172  end
173 
174  PUTTING_PKT : begin
175  if (new_pkt_end && current_endp == ep_num) begin
176  ep_state_next[ep_num] <= GETTING_PKT;
177 
178  end else if (rollback_data && current_endp == ep_num) begin
179  ep_state_next[ep_num] <= READY_FOR_PKT;
180 
181  end else begin
182  ep_state_next[ep_num] <= PUTTING_PKT;
183  end
184  end
185 
186  GETTING_PKT : begin
187 
188  if (ep_get_addr[ep_num][5:0] >= (ep_put_addr[ep_num][5:0] - 6'H2)) begin
189  ep_state_next[ep_num] <= READY_FOR_PKT;
190 
191  end else begin
192  ep_state_next[ep_num] <= GETTING_PKT;
193  end
194  end
195 
196  STALL : begin
197  if (setup_token_received && rx_endp == ep_num) begin
198  ep_state_next[ep_num] <= READY_FOR_PKT;
199 
200  end else begin
201  ep_state_next[ep_num] <= STALL;
202  end
203  end
204 
205  default begin
206  ep_state_next[ep_num] <= READY_FOR_PKT;
207  end
208  endcase
209  end
210 
211  // Determine the next get_address (init, inc, maintain)
212  if (ep_state_next[ep_num][1:0] == READY_FOR_PKT) begin
213  ep_get_addr_next[ep_num][5:0] <= 0;
214  end else if (ep_state_next[ep_num][1:0] == GETTING_PKT && out_ep_data_get[ep_num]) begin
215  ep_get_addr_next[ep_num][5:0] <= ep_get_addr[ep_num][5:0] + 6'H1;
216  end else begin
217  ep_get_addr_next[ep_num][5:0] <= ep_get_addr[ep_num][5:0];
218  end
219 
220  end // end of the always @*
221 
222  // Advance the state to the next one.
223  always @(posedge clk) begin
224  if (reset || reset_ep[ep_num]) begin
225  ep_state[ep_num] <= READY_FOR_PKT;
226  end else begin
227  ep_state[ep_num] <= ep_state_next[ep_num];
228  end
229 
230  ep_get_addr[ep_num][5:0] <= ep_get_addr_next[ep_num][5:0];
231  end
232 
233 
234  assign out_ep_data_avail[ep_num] =
235  (ep_get_addr[ep_num][5:0] < (ep_put_addr[ep_num][5:0] - 6'H2)) &&
236  (ep_state[ep_num][1:0] == GETTING_PKT);
237 
238 
239 
240  end
241  endgenerate
242 
243  integer i;
244  always @(posedge clk) begin
245  if (reset) begin
246  out_ep_setup <= 0;
247 
248  end else begin
249  if (setup_token_received) begin
250  out_ep_setup[rx_endp] <= 1;
251  end else if (out_token_received) begin
252  out_ep_setup[rx_endp] <= 0;
253  end
254  end
255 
256  for (i = 0; i < NUM_OUT_EPS; i = i + 1) begin
257  if (reset_ep[i]) begin
258  out_ep_setup[i] <= 0;
259  end
260  end
261  end
262 
263  always @(posedge clk) out_ep_data <= out_data_buffer[buffer_get_addr][7:0];
264  // use the bus grant line to determine the out_ep_num (where the data is)
265  integer ep_num_decoder;
266  always @* begin
267  out_ep_num <= 0;
268 
269  for (ep_num_decoder = 0; ep_num_decoder < NUM_OUT_EPS; ep_num_decoder = ep_num_decoder + 1) begin
270  if (out_ep_grant[ep_num_decoder]) begin
271  out_ep_num <= ep_num_decoder;
272  end
273  end
274  end
275 
276  ////////////////////////////////////////////////////////////////////////////////
277  // out transfer state machine
278  ////////////////////////////////////////////////////////////////////////////////
279 
280  always @* begin
281  out_ep_acked <= 0;
282  out_xfr_start <= 0;
283  out_xfr_state_next <= out_xfr_state;
284  tx_pkt_start <= 0;
285  tx_pid <= 0;
286  new_pkt_end <= 0;
287  rollback_data <= 0;
288 
289  case (out_xfr_state)
290  IDLE : begin
291  if (out_token_received || setup_token_received) begin
292  out_xfr_state_next <= RCVD_OUT;
293  out_xfr_start <= 1;
294 
295  end else begin
296  out_xfr_state_next <= IDLE;
297  end
298  end
299 
300  RCVD_OUT : begin
301  if (rx_pkt_start) begin
302  out_xfr_state_next <= RCVD_DATA_START;
303 
304  end else begin
305  out_xfr_state_next <= RCVD_OUT;
306  end
307  end
308 
309  RCVD_DATA_START : begin
310  if (bad_data_toggle) begin
311  out_xfr_state_next <= IDLE;
312  rollback_data <= 1;
313  tx_pkt_start <= 1;
314  tx_pid <= 4'b0010; // ACK
315 
316  end else if (invalid_packet_received || non_data_packet_received) begin
317  out_xfr_state_next <= IDLE;
318  rollback_data <= 1;
319 
320  end else if (data_packet_received) begin
321  out_xfr_state_next <= RCVD_DATA_END;
322 
323  end else begin
324  out_xfr_state_next <= RCVD_DATA_START;
325  end
326  end
327 
328  RCVD_DATA_END : begin
329  out_xfr_state_next <= IDLE;
330  tx_pkt_start <= 1;
331 
332  if (ep_state[current_endp] == STALL) begin
333  tx_pid <= 4'b1110; // STALL
334 
335  end else if (nak_out_transfer) begin
336  tx_pid <= 4'b1010; // NAK
337  rollback_data <= 1;
338 
339  end else begin
340  tx_pid <= 4'b0010; // ACK
341  new_pkt_end <= 1;
342  out_ep_acked[current_endp] <= 1;
343 
344  //end else begin
345  // tx_pid <= 4'b0010; // ACK
346  // rollback_data <= 1;
347  end
348  end
349 
350  default begin
351  out_xfr_state_next <= IDLE;
352  end
353  endcase
354  end
355 
356  wire current_ep_busy =
357  (ep_state[current_endp] == GETTING_PKT) ||
358  (ep_state[current_endp] == READY_FOR_PKT);
359 
360  integer j;
361  always @(posedge clk) begin
362  if (reset) begin
363  out_xfr_state <= IDLE;
364  end else begin
365  out_xfr_state <= out_xfr_state_next;
366 
367  if (out_xfr_start) begin
368  current_endp <= rx_endp;
369  //last_data_toggle <= setup_token_received ? 0 : data_toggle[rx_endp];
370  end
371 
372  if (new_pkt_end) begin
373  data_toggle[current_endp] <= !data_toggle[current_endp];
374  end
375 
376  if (setup_token_received) begin
377  data_toggle[rx_endp] <= 0;
378  end
379 
380  case (out_xfr_state)
381  IDLE : begin
382  end
383 
384  RCVD_OUT : begin
385  if (current_ep_busy) begin
386  nak_out_transfer <= 1;
387  end else begin
388  nak_out_transfer <= 0;
389  ep_put_addr[current_endp][5:0] <= 0;
390  end
391  end
392 
393  RCVD_DATA_START : begin
394  if (!nak_out_transfer && rx_data_put && !ep_put_addr[current_endp][5]) begin
395  out_data_buffer[buffer_put_addr][7:0] <= rx_data;
396  end
397 
398  if (!nak_out_transfer && rx_data_put) begin
399  ep_put_addr[current_endp][5:0] <= ep_put_addr[current_endp][5:0] + 6'H1;
400 
401  end
402  end
403 
404  RCVD_DATA_END : begin
405  end
406  endcase
407  end
408 
409  for (j = 0; j < NUM_OUT_EPS; j = j + 1) begin
410  if (reset || reset_ep[j]) begin
411  data_toggle[j] <= 0;
412  ep_put_addr[j][5:0] <= 0;
413  end
414  end
415  end
416 
417 endmodule
module usb_fs_out_pe(input clk, input reset, input[NUM_OUT_EPS-1:0] reset_ep, input[7] dev_addr, output[NUM_OUT_EPS-1:0] out_ep_data_avail, output reg< NUM_OUT_EPS-1:0 > out_ep_setup=0, input[NUM_OUT_EPS-1:0] out_ep_data_get, output reg< 7:0 > out_ep_data, input[NUM_OUT_EPS-1:0] out_ep_stall, output reg< NUM_OUT_EPS-1:0 > out_ep_acked=0, input[NUM_OUT_EPS-1:0] out_ep_grant, input rx_pkt_start, input rx_pkt_end, input rx_pkt_valid, input[4] rx_pid, input[7] rx_addr, input[4] rx_endp, input[10:0] rx_frame_num, input rx_data_put, input[8] rx_data, output reg tx_pkt_start=0, input tx_pkt_end, output reg< 3:0 > tx_pid=0)
Definition: usb_fs_out_pe.v:5
always(posedge clk)
Definition: uart_rx.v:86