// // usb.sv // // For now, just instantiate a USB <-> serial bridge and attach it // to the output of the tty // module max80_usb #( parameter [2:0] channels = 3'd4 ) ( input hard_rst_n, input clock48, input rst_n, input sys_clk, input cpu_valid_usbdesc, input cpu_valid_cdc, input [31:0] cpu_addr, output [31:0] cpu_rdata_usbdesc, output [31:0] cpu_rdata_cdc, input [31:0] cpu_wdata, input [3:0] cpu_wstrb, output [channels-1:0] irq, output tty_rxd_break, // Break on channel 0 inout usb_dp, // Single ended D+ inout usb_dn, // Single ended D- input usb_rx, // Differential input input usb_rx_ok, // Differential input available output usb_pu // Driver for 1.5 kohm pullup ); // // BREAK status by channel // wire [channels-1:0] recv_break; assign tty_rxd_break = recv_break[0]; // = system soft reset // // UTMI interface to PHY // wire [7:0] utmi_data_out; wire [1:0] utmi_op_mode; wire [1:0] utmi_xcvrselect; wire utmi_termselect; wire utmi_dppulldown; wire utmi_dmpulldown; wire [7:0] utmi_data_in; wire utmi_txvalid; wire utmi_txready; wire utmi_rxvalid; wire utmi_rxactive; wire utmi_rxerror; wire [1:0] utmi_linestate; // // USB hardware interface to PHY // wire usb_rx_rcv = usb_rx_ok ? usb_rx : usb_dp & ~usb_dn; wire usb_rx_dp = usb_dp; wire usb_rx_dn = usb_dn; wire usb_tx_dp; wire usb_tx_dn; wire usb_tx_oen; wire usb_en; // // Reset: reset USB on hard_rst# but synchronize to the USB clock // reg usb_rst_n; always @(negedge hard_rst_n or posedge clock48) if (~hard_rst_n) usb_rst_n <= 1'b0; else usb_rst_n <= 1'b1; // // I/O pins to PHY // assign usb_dp = ( usb_rst_n & ~usb_tx_oen ) ? usb_tx_dp : 1'bz; assign usb_dn = ( usb_rst_n & ~usb_tx_oen ) ? usb_tx_dn : 1'bz; assign usb_pu = ( usb_rst_n & usb_en ) ? 1'b1 : 1'bz; usb_fs_phy usb_phy ( .clk_i ( clock48 ), .rst_i ( ~usb_rst_n ), .utmi_data_out_i ( utmi_data_out ), .utmi_txvalid_i ( utmi_txvalid ), .utmi_op_mode_i ( utmi_op_mode ), .utmi_xcvrselect_i ( utmi_xcvrselect ), .utmi_termselect_i ( utmi_termselect ), .utmi_dppulldown_i ( utmi_dppulldown ), .utmi_dmpulldown_i ( utmi_dmpulldown ), .usb_rx_rcv_i ( usb_rx_rcv ), .usb_rx_dp_i ( usb_rx_dp ), .usb_rx_dn_i ( usb_rx_dn ), .usb_reset_assert_i ( 1'b0 ), .utmi_data_in_o ( utmi_data_in ), .utmi_txready_o ( utmi_txready ), .utmi_rxvalid_o ( utmi_rxvalid ), .utmi_rxactive_o ( utmi_rxactive ), .utmi_rxerror_o ( utmi_rxerror ), .utmi_linestate_o ( utmi_linestate ), .usb_tx_dp_o ( usb_tx_dp ), .usb_tx_dn_o ( usb_tx_dn ), .usb_tx_oen_o ( usb_tx_oen ), .usb_reset_detect_o ( ), .usb_en_o ( usb_en ) ); usb_cdc_core #(.channels(channels)) usb_serial ( .clk_i ( clock48 ), .rst_i ( ~usb_rst_n ), .enable_i ( 1'b1 ), .utmi_data_in_i ( utmi_data_in ), .utmi_txready_i ( utmi_txready ), .utmi_rxvalid_i ( utmi_rxvalid ), .utmi_rxactive_i ( utmi_rxactive ), .utmi_rxerror_i ( utmi_rxerror ), .utmi_linestate_i ( utmi_linestate ), .utmi_data_out_o ( utmi_data_out ), .utmi_txvalid_o ( utmi_txvalid ), .utmi_op_mode_o ( utmi_op_mode ), .utmi_xcvrselect_o ( utmi_xcvrselect ), .utmi_termselect_o ( utmi_termselect ), .utmi_dppulldown_o ( utmi_dppulldown ), .utmi_dmpulldown_o ( utmi_dmpulldown ), .rst_n ( rst_n ), .sys_clk ( sys_clk ), .cpu_valid_usbdesc ( cpu_valid_usbdesc ), .cpu_valid_cdc ( cpu_valid_cdc ), .cpu_addr ( cpu_addr ), .cpu_rdata_usbdesc ( cpu_rdata_usbdesc ), .cpu_rdata_cdc ( cpu_rdata_cdc ), .cpu_wdata ( cpu_wdata ), .cpu_wstrb ( cpu_wstrb ), .irq ( irq ), .recv_break_o ( recv_break ) ); endmodule // max80_usb