//
// usb.sv
//
// For now, just instantiate a USB <-> serial bridge and attach it
// to the output of the tty
//

module max80_usb (
		  input  rst_n,
		  input  clock48,
		  
		  output tty_rxd,
		  input  tty_txd,

		  inout  usb_dp,
		  inout  usb_dn,
		  output usb_pu	// driver for 1.5 kohm pullup
		  );

   //
   // 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_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;

   assign usb_dp = ( rst_n & ~usb_tx_oen ) ? usb_tx_dp : 1'bz;
   assign usb_dn = ( rst_n & ~usb_tx_oen ) ? usb_tx_dn : 1'bz;
   assign usb_pu = ( rst_n & usb_en )      ? 1'b1 : 1'bz;

   usb_fs_phy usb_phy (
		       .clk_i ( clock48 ),
		       .rst_i ( ~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_top #(.BAUDRATE(115200))
   usb_serial (
	       .clk_i             ( clock48 ),
	       .rst_i             ( ~rst_n ),

	       .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 ),

	       .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 ),

	       .tx_i ( tty_txd ),
	       .rx_o ( tty_rxd )
	       );
endmodule // max80_usb
