123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142 |
- /*
- * soc_usb.v
- *
- * vim: ts=4 sw=4
- *
- * Copyright (C) 2020 Sylvain Munaut <tnt@246tNt.com>
- * SPDX-License-Identifier: CERN-OHL-P-2.0
- */
- `default_nettype none
- module soc_usb #(
- parameter integer DW = 32
- )(
- // USB
- inout wire usb_dp,
- inout wire usb_dn,
- output wire usb_pu,
- // Wishbone slave
- input wire [ 11:0] wb_addr,
- output wire [DW-1:0] wb_rdata,
- input wire [DW-1:0] wb_wdata,
- input wire wb_we,
- input wire [1:0] wb_cyc,
- output wire [1:0] wb_ack,
- // Clock / Reset
- input wire clk_sys,
- input wire clk_48m,
- input wire rst
- );
- // Signals
- // -------
- // Bus OR
- wire [DW-1:0] wb_rdata_i[0:1];
- // Wishbone in 48 MHz domain
- wire [11:0] ub_addr;
- wire [15:0] ub_wdata;
- wire [15:0] ub_rdata;
- wire ub_cyc;
- wire ub_we;
- wire ub_ack;
- // EP Buffer
- wire [ 8:0] ep_tx_addr_0;
- wire [31:0] ep_tx_data_0;
- wire ep_tx_we_0;
- wire [ 8:0] ep_rx_addr_0;
- wire [31:0] ep_rx_data_1;
- wire ep_rx_re_0;
- reg ack_ep;
- // Cross-clock
- // -----------
- // Bring control reg wishbone to 48 MHz domain
- xclk_wb #(
- .DW(16),
- .AW(12)
- ) wb_48m_xclk_I (
- .s_addr (wb_addr[11:0]),
- .s_wdata (wb_wdata[15:0]),
- .s_rdata (wb_rdata_i[0][15:0]),
- .s_cyc (wb_cyc[0]),
- .s_ack (wb_ack[0]),
- .s_we (wb_we),
- .s_clk (clk_sys),
- .m_addr (ub_addr),
- .m_wdata (ub_wdata),
- .m_rdata (ub_rdata),
- .m_cyc (ub_cyc),
- .m_ack (ub_ack),
- .m_we (ub_we),
- .m_clk (clk_48m),
- .rst (rst)
- );
- if (DW != 16)
- assign wb_rdata_i[0][DW-1:16] = 0;
- // Core
- // ----
- usb #(
- .EPDW(32)
- ) usb_I (
- .pad_dp (usb_dp),
- .pad_dn (usb_dn),
- .pad_pu (usb_pu),
- .ep_tx_addr_0 (ep_tx_addr_0),
- .ep_tx_data_0 (ep_tx_data_0),
- .ep_tx_we_0 (ep_tx_we_0),
- .ep_rx_addr_0 (ep_rx_addr_0),
- .ep_rx_data_1 (ep_rx_data_1),
- .ep_rx_re_0 (ep_rx_re_0),
- .ep_clk (clk_sys),
- .wb_addr (ub_addr),
- .wb_rdata (ub_rdata),
- .wb_wdata (ub_wdata),
- .wb_we (ub_we),
- .wb_cyc (ub_cyc),
- .wb_ack (ub_ack),
- .clk (clk_48m),
- .rst (rst)
- );
- // EP data
- // -------
- assign ep_tx_addr_0 = wb_addr[8:0];
- assign ep_rx_addr_0 = wb_addr[8:0];
- assign ep_tx_data_0 = wb_wdata;
- assign wb_rdata_i[1] = ack_ep ? ep_rx_data_1 : 32'h00000000;
- assign ep_tx_we_0 = wb_cyc[1] & wb_we & ~ack_ep;
- assign ep_rx_re_0 = 1'b1;
- assign wb_ack[1] = ack_ep;
- always @(posedge clk_sys or posedge rst)
- if (rst)
- ack_ep <= 1'b0;
- else
- ack_ep <= wb_cyc[1] & ~ack_ep;
- // Bus read data
- // -------------
- assign wb_rdata = wb_rdata_i[0] | wb_rdata_i[1];
- endmodule // soc_usb
|