vt52-fpga  1.0.0 Initial
vt52-fpga is a serial terminal implemented on a FPGA
usb_fs_in_pe.v
Go to the documentation of this file.
1 // The IN Protocol Engine sends data to the host.
2 module usb_fs_in_pe #(
3  parameter NUM_IN_EPS = 11,
4  parameter MAX_IN_PACKET_SIZE = 32
5 ) (
6  input clk,
7  input reset,
8  input [NUM_IN_EPS-1:0] reset_ep,
9  input [6:0] dev_addr,
10 
11 
12  ////////////////////
13  // endpoint interface
14  ////////////////////
15  output reg [NUM_IN_EPS-1:0] in_ep_data_free = 0,
16  input [NUM_IN_EPS-1:0] in_ep_data_put,
17  input [7:0] in_ep_data,
18  input [NUM_IN_EPS-1:0] in_ep_data_done,
19  input [NUM_IN_EPS-1:0] in_ep_stall,
20  output reg [NUM_IN_EPS-1:0] in_ep_acked = 0,
21 
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 
39  ////////////////////
40  // tx path
41  ////////////////////
42 
43  // Strobe to send new packet.
44  output reg tx_pkt_start = 0,
45  input tx_pkt_end,
46 
47 
48  // Packet type to send
49  output reg [3:0] tx_pid = 0,
50 
51  // Data payload to send if any
52  output tx_data_avail,
53  input tx_data_get,
54  output reg [7:0] tx_data,
55 
56  output [7:0] debug
57 );
58 
59  ////////////////////////////////////////////////////////////////////////////////
60  // endpoint state machine
61  ////////////////////////////////////////////////////////////////////////////////
62  reg [1:0] ep_state [NUM_IN_EPS - 1:0];
63  reg [1:0] ep_state_next [NUM_IN_EPS - 1:0];
64 
65  // latched on valid IN token
66  reg [3:0] current_endp = 0;
67 
68  wire [1:0] current_ep_state = ep_state[current_endp][1:0];
69 
70  localparam READY_FOR_PKT = 0;
71  localparam PUTTING_PKT = 1;
72  localparam GETTING_PKT = 2;
73  localparam STALL = 3;
74 
75  assign debug[1:0] = ( current_endp == 1 ) ? current_ep_state : 0;
76 
77 
78  ////////////////////////////////////////////////////////////////////////////////
79  // in transfer state machine
80  ////////////////////////////////////////////////////////////////////////////////
81  localparam IDLE = 0;
82  localparam RCVD_IN = 1;
83  localparam SEND_DATA = 2;
84  localparam WAIT_ACK = 3;
85 
86  reg [1:0] in_xfr_state = IDLE;
87  reg [1:0] in_xfr_state_next;
88 
89  assign debug[3:2] = ( current_endp == 1 ) ? in_xfr_state : 0;
90 
91  reg in_xfr_start = 0;
92  reg in_xfr_end = 0;
93 
94  assign debug[4] = tx_data_avail;
95  assign debug[5] = tx_data_get;
96 
97  // data toggle state
98  reg [NUM_IN_EPS - 1:0] data_toggle = 0;
99 
100  // endpoint data buffer
101  reg [7:0] in_data_buffer [(MAX_IN_PACKET_SIZE * NUM_IN_EPS) - 1:0];
102  // Address registers - one bit longer (6) than required (5) to permit fullness != emptyness
103  reg [5:0] ep_put_addr [NUM_IN_EPS - 1:0];
104  reg [5:0] ep_get_addr [NUM_IN_EPS - 1:0];
105 
106  integer i = 0;
107  initial begin
108  for (i = 0; i < NUM_IN_EPS; i = i + 1) begin
109  ep_put_addr[i] = 0;
110  ep_get_addr[i] = 0;
111  ep_state[i] = 0;
112  end
113  end
114 
115  reg [3:0] in_ep_num = 0;
116 
117  // the actual address (note using only the real 5 bits of the incoming address + the high order buffer select)
118  wire [8:0] buffer_put_addr = {in_ep_num[3:0], ep_put_addr[in_ep_num][4:0]};
119  wire [8:0] buffer_get_addr = {current_endp[3:0], ep_get_addr[current_endp][4:0]};
120 
121  // endpoint data packet buffer has a data packet ready to send
122  reg [NUM_IN_EPS - 1:0] endp_ready_to_send = 0;
123 
124  // endpoint has some space free in its buffer
125  reg [NUM_IN_EPS - 1:0] endp_free = 0;
126 
127  wire token_received =
128  rx_pkt_end &&
129  rx_pkt_valid &&
130  rx_pid[1:0] == 2'b01 &&
131  rx_addr == dev_addr &&
132  rx_endp < NUM_IN_EPS;
133 
134  wire setup_token_received =
135  token_received &&
136  rx_pid[3:2] == 2'b11;
137 
138  wire in_token_received =
139  token_received &&
140  rx_pid[3:2] == 2'b10;
141 
142  wire ack_received =
143  rx_pkt_end &&
144  rx_pkt_valid &&
145  rx_pid == 4'b0010;
146 
147  assign debug[ 6 ] = rx_pkt_start;
148  assign debug[ 7 ] = rx_pkt_end;
149 
150 
151  wire more_data_to_send =
152  ep_get_addr[current_endp][5:0] < ep_put_addr[current_endp][5:0];
153 
154  wire [5:0] current_ep_get_addr = ep_get_addr[current_endp][5:0];
155  wire [5:0] current_ep_put_addr = ep_put_addr[current_endp][5:0];
156 
157 
158 
159 
160  wire tx_data_avail_i =
161  in_xfr_state == SEND_DATA &&
162  more_data_to_send;
163 
164  assign tx_data_avail = tx_data_avail_i;
165 
166 
167 
168  ////////////////////////////////////////////////////////////////////////////////
169  // endpoint state machine
170  ////////////////////////////////////////////////////////////////////////////////
171 
172 
173  genvar ep_num;
174  generate
175  for (ep_num = 0; ep_num < NUM_IN_EPS; ep_num = ep_num + 1) begin
176 
177  // Manage next state
178  always @* begin
179  in_ep_acked[ep_num] <= 0;
180 
181  ep_state_next[ep_num] <= ep_state[ep_num];
182 
183  if (in_ep_stall[ep_num]) begin
184  ep_state_next[ep_num] <= STALL;
185 
186  end else begin
187  case (ep_state[ep_num])
188  READY_FOR_PKT : begin
189  ep_state_next[ep_num] <= PUTTING_PKT;
190  end
191 
192  PUTTING_PKT : begin
193  // if either the user says they're done or the buffer is full, move on to GETTING_PKT
194  if ( ( in_ep_data_done[ep_num] ) || ( ep_put_addr[ep_num][5] ) ) begin
195  ep_state_next[ep_num] <= GETTING_PKT;
196  end else begin
197  ep_state_next[ep_num] <= PUTTING_PKT;
198  end
199  end
200 
201  GETTING_PKT : begin
202  // here we're waiting to send the data out, and receive an ACK token back
203  // No token, and we're here for a while.
204  if (in_xfr_end && current_endp == ep_num) begin
205  ep_state_next[ep_num] <= READY_FOR_PKT;
206  in_ep_acked[ep_num] <= 1;
207 
208  end else begin
209  ep_state_next[ep_num] <= GETTING_PKT;
210  end
211  end
212 
213  STALL : begin
214  if (setup_token_received && rx_endp == ep_num) begin
215  ep_state_next[ep_num] <= READY_FOR_PKT;
216 
217  end else begin
218  ep_state_next[ep_num] <= STALL;
219  end
220  end
221 
222  default begin
223  ep_state_next[ep_num] <= READY_FOR_PKT;
224  end
225  endcase
226  end
227 
228  endp_free[ep_num] = !ep_put_addr[ep_num][5];
229  in_ep_data_free[ep_num] = endp_free[ep_num] && ep_state[ep_num] == PUTTING_PKT;
230  end
231 
232  // Handle the data pointer (advancing and clearing)
233  always @(posedge clk) begin
234  if (reset || reset_ep[ep_num]) begin
235  ep_state[ep_num] <= READY_FOR_PKT;
236 
237  end else begin
238  ep_state[ep_num] <= ep_state_next[ep_num];
239 
240  case (ep_state[ep_num])
241  READY_FOR_PKT : begin
242  // make sure we start with a clear buffer (and the extra bit!)
243  ep_put_addr[ep_num][5:0] <= 0;
244  end
245 
246  PUTTING_PKT : begin
247  // each time we are putting, and there's a data_put signal, increment the address
248  if (in_ep_data_put[ep_num] && ( ~ep_put_addr[ep_num][5] ) ) begin
249  ep_put_addr[ep_num][5:0] <= ep_put_addr[ep_num][5:0] + 1;
250  end
251  end
252 
253  GETTING_PKT : begin
254  end
255 
256  STALL : begin
257  end
258  endcase
259  end
260  end
261  end
262  endgenerate
263 
264  // Decide which in_ep_num we're talking to
265  // Using the data put register is OK here
266  integer ep_num_decoder;
267  always @* begin
268  in_ep_num <= 0;
269 
270  for (ep_num_decoder = 0; ep_num_decoder < NUM_IN_EPS; ep_num_decoder = ep_num_decoder + 1) begin
271  if (in_ep_data_put[ep_num_decoder]) begin
272  in_ep_num <= ep_num_decoder;
273  end
274  end
275  end
276 
277  // Handle putting the new data into the buffer
278  always @(posedge clk) begin
279  case (ep_state[in_ep_num])
280  PUTTING_PKT : begin
281  if (in_ep_data_put[in_ep_num] && !ep_put_addr[in_ep_num][5]) begin
282  in_data_buffer[buffer_put_addr] <= in_ep_data;
283  end
284  end
285  endcase
286  end
287 
288 
289  ////////////////////////////////////////////////////////////////////////////////
290  // in transfer state machine
291  ////////////////////////////////////////////////////////////////////////////////
292 
293  reg rollback_in_xfr;
294 
295  always @* begin
296  in_xfr_state_next <= in_xfr_state;
297  in_xfr_start <= 0;
298  in_xfr_end <= 0;
299  tx_pkt_start <= 0;
300  tx_pid <= 4'b0000;
301  rollback_in_xfr <= 0;
302 
303  case (in_xfr_state)
304  IDLE : begin
305  rollback_in_xfr <= 1;
306 
307  if (in_token_received) begin
308  in_xfr_state_next <= RCVD_IN;
309 
310  end else begin
311  in_xfr_state_next <= IDLE;
312  end
313  end
314 
315  // Got an IN token
316  RCVD_IN : begin
317  tx_pkt_start <= 1;
318 
319  if (ep_state[current_endp] == STALL) begin
320  in_xfr_state_next <= IDLE;
321  tx_pid <= 4'b1110; // STALL
322 
323  end else if (ep_state[current_endp] == GETTING_PKT) begin
324  // if we were in GETTING_PKT (done getting data from the device), Send it!
325  in_xfr_state_next <= SEND_DATA;
326  tx_pid <= {data_toggle[current_endp], 3'b011}; // DATA0/1
327  in_xfr_start <= 1;
328 
329  end else begin
330  in_xfr_state_next <= IDLE;
331  tx_pid <= 4'b1010; // NAK
332  end
333  end
334 
335  SEND_DATA : begin
336  // Send the data from the buffer now (until the out (get) address = the in (put) address)
337  if (!more_data_to_send) begin
338  in_xfr_state_next <= WAIT_ACK;
339 
340  end else begin
341  in_xfr_state_next <= SEND_DATA;
342  end
343  end
344 
345  WAIT_ACK : begin
346  // FIXME: need to handle smash/timeout
347  // Could wait here forever (although another token will come along)
348  if (ack_received) begin
349  in_xfr_state_next <= IDLE;
350  in_xfr_end <= 1;
351 
352  end else if (in_token_received) begin
353  in_xfr_state_next <= RCVD_IN;
354  rollback_in_xfr <= 1;
355 
356  end else if (rx_pkt_end) begin
357  in_xfr_state_next <= IDLE;
358  rollback_in_xfr <= 1;
359 
360  end else begin
361  in_xfr_state_next <= WAIT_ACK;
362  end
363  end
364  endcase
365  end
366 
367  always @(posedge clk)
368  tx_data <= in_data_buffer[buffer_get_addr];
369 
370  integer j;
371  always @(posedge clk) begin
372  if (reset) begin
373  in_xfr_state <= IDLE;
374 
375  end else begin
376  in_xfr_state <= in_xfr_state_next;
377 
378  // tx_data <= in_data_buffer[buffer_get_addr];
379 
380  if (setup_token_received) begin
381  data_toggle[rx_endp] <= 1;
382  end
383 
384  if (in_token_received) begin
385  current_endp <= rx_endp;
386  end
387 
388  if (rollback_in_xfr) begin
389  ep_get_addr[current_endp][5:0] <= 0;
390  end
391 
392  case (in_xfr_state)
393  IDLE : begin
394  end
395 
396  RCVD_IN : begin
397  end
398 
399  SEND_DATA : begin
400  if (tx_data_get && tx_data_avail_i) begin
401  ep_get_addr[current_endp][5:0] <= ep_get_addr[current_endp][5:0] + 1;
402  end
403  end
404 
405  WAIT_ACK : begin
406  if (ack_received) begin
407  data_toggle[current_endp] <= !data_toggle[current_endp];
408  end
409  end
410  endcase
411  end
412 
413  for (j = 0; j < NUM_IN_EPS; j = j + 1) begin
414  if (reset || reset_ep[j]) begin
415  data_toggle[j] <= 0;
416  ep_get_addr[j][5:0] <= 0;
417  end
418  end
419  end
420 
421 endmodule
module usb_fs_in_pe(input clk, input reset, input[NUM_IN_EPS-1:0] reset_ep, input[7] dev_addr, output reg< NUM_IN_EPS-1:0 > in_ep_data_free=0, input[NUM_IN_EPS-1:0] in_ep_data_put, input[8] in_ep_data, input[NUM_IN_EPS-1:0] in_ep_data_done, input[NUM_IN_EPS-1:0] in_ep_stall, output reg< NUM_IN_EPS-1:0 > in_ep_acked=0, 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, output reg tx_pkt_start=0, input tx_pkt_end, output reg< 3:0 > tx_pid=0, output tx_data_avail, input tx_data_get, output reg< 7:0 > tx_data, output[8] debug)
Definition: usb_fs_in_pe.v:5
always(posedge clk)
Definition: uart_rx.v:86