/* * ut_pkt.v * * USB Packet Receiver * * vim: ts=4 sw=4 * * Copyright (C) 2022 Sylvain Munaut * SPDX-License-Identifier: CERN-OHL-P-2.0 */ `default_nettype none module ut_pkt ( // Bus interface output wire [31:0] bus_rdata, input wire [31:0] bus_wdata, input wire bus_we_csr, // USB tap input wire tap_dp, input wire tap_dn, // Data stream output wire [7:0] stream_data, output wire stream_stb, // Clock / Reset input wire clk_1x, input wire clk_2x, input wire rst ); // Signals // ------- // Control reg ctrl_active; // PHY wire phy_rx_dp; wire phy_rx_dn; wire phy_rx_chg; // RX Low-Level wire [1:0] ll_sym; wire ll_bit; wire ll_valid; wire ll_eop; wire ll_sync; wire ll_bs_skip; wire ll_bs_err; // Packet (clk_2x domain) wire p2x_start; wire p2x_done_ok; wire p2x_done_err; wire [3:0] p2x_pid; wire p2x_is_sof; wire p2x_is_token; wire p2x_is_data; wire p2x_is_handshake; wire [10:0] p2x_frameno; wire [6:0] p2x_addr; wire [3:0] p2x_endp; wire [7:0] p2x_data; wire p2x_data_stb; // Packet (clk_1x domain) wire p1x_start; wire p1x_done_ok; wire p1x_done_err; wire [3:0] p1x_pid; wire p1x_is_sof; wire p1x_is_token; wire p1x_is_data; wire p1x_is_handshake; wire [10:0] p1x_frameno; wire [6:0] p1x_addr; wire [3:0] p1x_endp; wire [7:0] p1x_data; wire p1x_data_stb; // Bus Interface // ------------- assign bus_rdata = { 31'h00000000, ctrl_active }; always @(posedge clk_1x or posedge rst) if (rst) ctrl_active <= 1'b0; else if (bus_we_csr) ctrl_active <= bus_wdata[0]; // PHY // --- usb_phy #( .TARGET("ICE40") ) phy_I ( .pad_dp (tap_dp), .pad_dn (tap_dn), .rx_dp (phy_rx_dp), .rx_dn (phy_rx_dn), .rx_chg (phy_rx_chg), .tx_dp (1'b0), .tx_dn (1'b0), .tx_en (1'b0), .clk (clk_2x), .rst (rst) ); // Low-Level RX // ------------ usb_rx_ll rx_ll_I ( .phy_rx_dp (phy_rx_dp), .phy_rx_dn (phy_rx_dn), .phy_rx_chg (phy_rx_chg), .ll_sym (ll_sym), .ll_bit (ll_bit), .ll_valid (ll_valid), .ll_eop (ll_eop), .ll_sync (ll_sync), .ll_bs_skip (ll_bs_skip), .ll_bs_err (ll_bs_err), .clk (clk_2x), .rst (rst) ); // Packet RX // --------- usb_rx_pkt rx_pkt_I ( .ll_sym (ll_sym), .ll_bit (ll_bit), .ll_valid (ll_valid), .ll_eop (ll_eop), .ll_sync (ll_sync), .ll_bs_skip (ll_bs_skip), .ll_bs_err (ll_bs_err), .pkt_start (p2x_start), .pkt_done_ok (p2x_done_ok), .pkt_done_err (p2x_done_err), .pkt_pid (p2x_pid), .pkt_is_sof (p2x_is_sof), .pkt_is_token (p2x_is_token), .pkt_is_data (p2x_is_data), .pkt_is_handshake (p2x_is_handshake), .pkt_frameno (p2x_frameno), .pkt_addr (p2x_addr), .pkt_endp (p2x_endp), .pkt_data (p2x_data), .pkt_data_stb (p2x_data_stb), .inhibit (~ctrl_active), .clk (clk_2x), .rst (rst) ); // Cross-Clock // ----------- ut_pkt_xclk xclk_I ( .pi_start (p2x_start), .pi_done_ok (p2x_done_ok), .pi_done_err (p2x_done_err), .pi_pid (p2x_pid), .pi_is_sof (p2x_is_sof), .pi_is_token (p2x_is_token), .pi_is_data (p2x_is_data), .pi_is_handshake (p2x_is_handshake), .pi_frameno (p2x_frameno), .pi_addr (p2x_addr), .pi_endp (p2x_endp), .pi_data (p2x_data), .pi_data_stb (p2x_data_stb), .pi_clk (clk_2x), .po_start (p1x_start), .po_done_ok (p1x_done_ok), .po_done_err (p1x_done_err), .po_pid (p1x_pid), .po_is_sof (p1x_is_sof), .po_is_token (p1x_is_token), .po_is_data (p1x_is_data), .po_is_handshake (p1x_is_handshake), .po_frameno (p1x_frameno), .po_addr (p1x_addr), .po_endp (p1x_endp), .po_data (p1x_data), .po_data_stb (p1x_data_stb), .po_clk (clk_1x), .rst (rst) ); // Stream Generator // ---------------- ut_pkt_stream stream_I ( .phy_rx_dp (phy_rx_dp), .phy_rx_dn (phy_rx_dn), .pkt_start (p1x_start), .pkt_done_ok (p1x_done_ok), .pkt_done_err (p1x_done_err), .pkt_pid (p1x_pid), .pkt_is_sof (p1x_is_sof), .pkt_is_token (p1x_is_token), .pkt_is_data (p1x_is_data), .pkt_is_handshake (p1x_is_handshake), .pkt_frameno (p1x_frameno), .pkt_addr (p1x_addr), .pkt_endp (p1x_endp), .pkt_data (p1x_data), .pkt_data_stb (p1x_data_stb), .stream_data (stream_data), .stream_stb (stream_stb), .ctrl_active (ctrl_active), .clk (clk_1x), .rst (rst) ); endmodule // ut_pkt