../src/lowrisc_ip_usb_fs_nb_pe_0.1/rtl/usb_fs_nb_pe.sv Cov: 100%

   1: // Copyright lowRISC contributors.
   2: // Copyright Luke Valenty (TinyFPGA project)
   3: // Licensed under the Apache License, Version 2.0, see LICENSE for details.
   4: // SPDX-License-Identifier: Apache-2.0
   5: 
   6: // USB Full Speed Non-Buffered Protocol Engine
   7: //
   8: // Decodes low level USB link protocol from external usb_fs_tx/rx
   9: // Provides upper level with
  10: // - OUT endpoint interface (host to device) which also covers SETUP
  11: // - IN endpoint interface (device to host)
  12: // - Start of Frame interface
  13: //
  14: // Based on usb_fs_pe.v from the TinyFPGA-Bootloader project but
  15: // this version contains no packet buffers
  16: 
  17: module usb_fs_nb_pe #(
  18:   parameter int unsigned NumOutEps = 2,
  19:   parameter int unsigned NumInEps = 2,
  20:   parameter int unsigned MaxPktSizeByte = 32,
  21:   localparam int unsigned PktW = $clog2(MaxPktSizeByte) // derived parameter
  22: ) (
  23:   input  logic                   clk_48mhz_i,
  24:   input  logic                   rst_ni,        // Async. reset, active low
  25:   input  logic                   link_reset_i,  // USB reset, sync to 48 MHz, active high
  26:   input  logic [6:0]             dev_addr_i,
  27: 
  28:   input  logic                   cfg_eop_single_bit_i, // 1: detect a single SE0 bit as EOP
  29:   input  logic                   tx_osc_test_mode_i, // Oscillator test mode (constantly output JK)
  30:   input  logic [NumOutEps-1:0]   data_toggle_clear_i, // Clear the data toggles for an EP
  31: 
  32:   ////////////////////////////
  33:   // USB Endpoint Interface //
  34:   ////////////////////////////
  35:   ///////////////////////////////
  36:   // global endpoint interface //
  37:   ///////////////////////////////
  38: 
  39:   // out endpoint interfaces
  40:   output logic [3:0]             out_ep_current_o, // Other signals address to this ep
  41:   output logic                   out_ep_data_put_o, // put the data (put addr advances after)
  42:   output logic [PktW - 1:0]      out_ep_put_addr_o, // Offset to put data (0..pktlen)
  43:   output logic [7:0]             out_ep_data_o,
  44:   output logic                   out_ep_newpkt_o,// New OUT pkt start (with in_ep_current_o update)
  45:   output logic                   out_ep_acked_o, // good termination, device has acked
  46:   output logic                   out_ep_rollback_o, // bad termination, discard data
  47:   output logic [NumOutEps-1:0]   out_ep_setup_o,
  48:   input  logic [NumOutEps-1:0]   out_ep_full_i, // Cannot accept data
  49:   input  logic [NumOutEps-1:0]   out_ep_stall_i, // Stalled
  50:   input  logic [NumOutEps-1:0]   out_ep_iso_i, // Configure endpoint in isochronous mode
  51: 
  52:   // in endpoint interfaces
  53:   output logic [3:0]             in_ep_current_o, // Other signals addressed to this ep
  54:   output logic                   in_ep_rollback_o, // Bad termination, rollback transaction
  55:   output logic                   in_ep_acked_o, // good termination, transaction complete
  56:   output logic [PktW - 1:0]      in_ep_get_addr_o, // Offset requested (0..pktlen)
  57:   output logic                   in_ep_data_get_o, // Accept data (get_addr advances too)
  58:   output logic                   in_ep_newpkt_o, // New IN pkt start (with in_ep_current_o update)
  59:   input  logic [NumInEps-1:0]    in_ep_stall_i, // Endpoint in a stall state
  60:   input  logic [NumInEps-1:0]    in_ep_has_data_i, // Endpoint has data to supply
  61:   input  logic [7:0]             in_ep_data_i, // Data for current get_addr
  62:   input  logic [NumInEps-1:0]    in_ep_data_done_i, // Set when out of data
  63:   input  logic  [NumInEps-1:0]   in_ep_iso_i, // Configure endpoint in isochronous mode
  64: 
  65:   // sof interface
  66:   output logic                   sof_valid_o,
  67:   output logic [10:0]            frame_index_o,
  68: 
  69:   // RX errors
  70:   output logic                   rx_crc_err_o,
  71:   output logic                   rx_pid_err_o,
  72:   output logic                   rx_bitstuff_err_o,
  73: 
  74:   ///////////////////////////////////////
  75:   // USB TX/RX Interface (synchronous) //
  76:   ///////////////////////////////////////
  77:   input  logic                   usb_d_i,
  78:   input  logic                   usb_se0_i,
  79: 
  80:   output logic                   usb_d_o,
  81:   output logic                   usb_se0_o,
  82:   output logic                   usb_oe_o
  83: );
  84: 
  85:   import usb_consts_pkg::*;
  86: 
  87:   // rx interface
  88:   logic bit_strobe;
  89:   logic rx_pkt_start;
  90:   logic rx_pkt_end;
  91:   logic [3:0] rx_pid;
  92:   logic [6:0] rx_addr;
  93:   logic [3:0] rx_endp;
  94:   logic [10:0] rx_frame_num;
  95:   logic rx_data_put;
  96:   logic [7:0] rx_data;
  97:   logic rx_pkt_valid;
  98: 
  99:   // tx mux
 100:   logic in_tx_pkt_start;
 101:   logic [3:0] in_tx_pid;
 102:   logic out_tx_pkt_start;
 103:   logic [3:0] out_tx_pid;
 104: 
 105:   // tx interface
 106:   logic tx_pkt_start;
 107:   logic tx_pkt_end;
 108:   logic [3:0] tx_pid;
 109:   logic tx_data_avail;
 110:   logic tx_data_get;
 111:   logic [7:0] tx_data;
 112: 
 113:   logic usb_oe;
 114: 
 115:   // sof interface
 116:   assign sof_valid_o = rx_pkt_end & rx_pkt_valid & (usb_pid_e'(rx_pid) == UsbPidSof);
 117:   assign frame_index_o = rx_frame_num;
 118:   assign usb_oe_o = usb_oe;
 119: 
 120:   usb_fs_nb_in_pe #(
 121:     .NumInEps           (NumInEps),
 122:     .MaxInPktSizeByte   (MaxPktSizeByte)
 123:   ) u_usb_fs_nb_in_pe (
 124:     .clk_48mhz_i           (clk_48mhz_i),
 125:     .rst_ni                (rst_ni),
 126:     .link_reset_i          (link_reset_i),
 127:     .dev_addr_i            (dev_addr_i),
 128: 
 129:     // endpoint interface
 130:     .in_ep_current_o       (in_ep_current_o),
 131:     .in_ep_rollback_o      (in_ep_rollback_o),
 132:     .in_ep_acked_o         (in_ep_acked_o),
 133:     .in_ep_get_addr_o      (in_ep_get_addr_o),
 134:     .in_ep_data_get_o      (in_ep_data_get_o),
 135:     .in_ep_newpkt_o        (in_ep_newpkt_o),
 136:     .in_ep_stall_i         (in_ep_stall_i),
 137:     .in_ep_has_data_i      (in_ep_has_data_i),
 138:     .in_ep_data_i          (in_ep_data_i),
 139:     .in_ep_data_done_i     (in_ep_data_done_i),
 140:     .in_ep_iso_i           (in_ep_iso_i),
 141: 
 142:     .data_toggle_clear_i   (data_toggle_clear_i),
 143: 
 144:     // rx path
 145:     .rx_pkt_start_i        (rx_pkt_start),
 146:     .rx_pkt_end_i          (rx_pkt_end),
 147:     .rx_pkt_valid_i        (rx_pkt_valid),
 148:     .rx_pid_i              (rx_pid),
 149:     .rx_addr_i             (rx_addr),
 150:     .rx_endp_i             (rx_endp),
 151: 
 152:     // tx path
 153:     .tx_pkt_start_o        (in_tx_pkt_start),
 154:     .tx_pkt_end_i          (tx_pkt_end),
 155:     .tx_pid_o              (in_tx_pid),
 156:     .tx_data_avail_o       (tx_data_avail),
 157:     .tx_data_get_i         (tx_data_get),
 158:     .tx_data_o             (tx_data)
 159:   );
 160: 
 161:   usb_fs_nb_out_pe #(
 162:     .NumOutEps           (NumOutEps),
 163:     .MaxOutPktSizeByte   (MaxPktSizeByte)
 164:   ) u_usb_fs_nb_out_pe (
 165:     .clk_48mhz_i            (clk_48mhz_i),
 166:     .rst_ni                 (rst_ni),
 167:     .link_reset_i           (link_reset_i),
 168:     .dev_addr_i             (dev_addr_i),
 169: 
 170:     // endpoint interface
 171:     .out_ep_current_o       (out_ep_current_o),
 172:     .out_ep_data_put_o      (out_ep_data_put_o),
 173:     .out_ep_put_addr_o      (out_ep_put_addr_o),
 174:     .out_ep_data_o          (out_ep_data_o),
 175:     .out_ep_newpkt_o        (out_ep_newpkt_o),
 176:     .out_ep_acked_o         (out_ep_acked_o),
 177:     .out_ep_rollback_o      (out_ep_rollback_o),
 178:     .out_ep_setup_o         (out_ep_setup_o),
 179:     .out_ep_full_i          (out_ep_full_i),
 180:     .out_ep_stall_i         (out_ep_stall_i),
 181:     .out_ep_iso_i           (out_ep_iso_i),
 182: 
 183:     .data_toggle_clear_i    (data_toggle_clear_i),
 184: 
 185:     // rx path
 186:     .rx_pkt_start_i         (rx_pkt_start),
 187:     .rx_pkt_end_i           (rx_pkt_end),
 188:     .rx_pkt_valid_i         (rx_pkt_valid),
 189:     .rx_pid_i               (rx_pid),
 190:     .rx_addr_i              (rx_addr),
 191:     .rx_endp_i              (rx_endp),
 192:     .rx_data_put_i          (rx_data_put),
 193:     .rx_data_i              (rx_data),
 194: 
 195:     // tx path
 196:     .tx_pkt_start_o         (out_tx_pkt_start),
 197:     .tx_pkt_end_i           (tx_pkt_end),
 198:     .tx_pid_o               (out_tx_pid)
 199:   );
 200: 
 201:   usb_fs_rx u_usb_fs_rx (
 202:     .clk_i                  (clk_48mhz_i),
 203:     .rst_ni                 (rst_ni),
 204:     .link_reset_i           (link_reset_i),
 205:     .cfg_eop_single_bit_i   (cfg_eop_single_bit_i),
 206:     .usb_d_i                (usb_d_i),
 207:     .usb_se0_i              (usb_se0_i),
 208:     .tx_en_i                (usb_oe),
 209:     .bit_strobe_o           (bit_strobe),
 210:     .pkt_start_o            (rx_pkt_start),
 211:     .pkt_end_o              (rx_pkt_end),
 212:     .pid_o                  (rx_pid),
 213:     .addr_o                 (rx_addr),
 214:     .endp_o                 (rx_endp),
 215:     .frame_num_o            (rx_frame_num),
 216:     .rx_data_put_o          (rx_data_put),
 217:     .rx_data_o              (rx_data),
 218:     .valid_packet_o         (rx_pkt_valid),
 219:     .crc_error_o            (rx_crc_err_o),
 220:     .pid_error_o            (rx_pid_err_o),
 221:     .bitstuff_error_o       (rx_bitstuff_err_o)
 222:   );
 223: 
 224:   usb_fs_tx_mux u_usb_fs_tx_mux (
 225:     // interface to IN Protocol Engine
 226:     .in_tx_pkt_start_i  (in_tx_pkt_start),
 227:     .in_tx_pid_i        (in_tx_pid),
 228: 
 229:     // interface to OUT Protocol Engine
 230:     .out_tx_pkt_start_i (out_tx_pkt_start),
 231:     .out_tx_pid_i       (out_tx_pid),
 232: 
 233:     // interface to tx module
 234:     .tx_pkt_start_o     (tx_pkt_start),
 235:     .tx_pid_o           (tx_pid)
 236:   );
 237: 
 238:   usb_fs_tx u_usb_fs_tx (
 239:     .clk_i                  (clk_48mhz_i),
 240:     .rst_ni                 (rst_ni),
 241:     .link_reset_i           (link_reset_i),
 242:     .tx_osc_test_mode_i     (tx_osc_test_mode_i),
 243:     .bit_strobe_i           (bit_strobe),
 244:     .usb_d_o                (usb_d_o),
 245:     .usb_se0_o              (usb_se0_o),
 246:     .usb_oe_o               (usb_oe),
 247:     .pkt_start_i            (tx_pkt_start),
 248:     .pkt_end_o              (tx_pkt_end),
 249:     .pid_i                  (tx_pid),
 250:     .tx_data_avail_i        (tx_data_avail),
 251:     .tx_data_get_o          (tx_data_get),
 252:     .tx_data_i              (tx_data)
 253:   );
 254: endmodule
 255: