/////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////
|
//// ////
|
//// ////
|
//// USB 1.1 function IP core ////
|
//// USB 1.1 function IP core ////
|
//// ////
|
//// ////
|
//// ////
|
//// ////
|
//// Author: Rudolf Usselmann ////
|
//// Author: Rudolf Usselmann ////
|
//// rudi@asics.ws ////
|
//// rudi@asics.ws ////
|
//// ////
|
//// ////
|
//// ////
|
//// ////
|
//// Downloaded from: http://www.opencores.org/cores/usb1_funct/////
|
//// Downloaded from: http://www.opencores.org/cores/usb1_funct/////
|
//// ////
|
//// ////
|
/////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////
|
//// ////
|
//// ////
|
//// Copyright (C) 2000-2002 Rudolf Usselmann ////
|
//// Copyright (C) 2000-2002 Rudolf Usselmann ////
|
//// www.asics.ws ////
|
//// www.asics.ws ////
|
//// rudi@asics.ws ////
|
//// rudi@asics.ws ////
|
//// ////
|
//// ////
|
//// This source file may be used and distributed without ////
|
//// This source file may be used and distributed without ////
|
//// restriction provided that this copyright statement is not ////
|
//// restriction provided that this copyright statement is not ////
|
//// removed from the file and that any derivative work contains ////
|
//// removed from the file and that any derivative work contains ////
|
//// the original copyright notice and the associated disclaimer.////
|
//// the original copyright notice and the associated disclaimer.////
|
//// ////
|
//// ////
|
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
|
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
|
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
|
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
|
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
|
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
|
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
|
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
|
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
|
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
|
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
|
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
|
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
|
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
|
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
|
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
|
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
|
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
|
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
|
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
|
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
|
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
|
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
|
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
|
//// POSSIBILITY OF SUCH DAMAGE. ////
|
//// POSSIBILITY OF SUCH DAMAGE. ////
|
//// ////
|
//// ////
|
/////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////
|
|
|
// CVS Log
|
// CVS Log
|
//
|
//
|
// $Id: usb1_core.v,v 1.2 2002-10-11 05:48:20 rudi Exp $
|
// $Id: usb1_core.v,v 1.2 2002-10-11 05:48:20 rudi Exp $
|
//
|
//
|
// $Date: 2002-10-11 05:48:20 $
|
// $Date: 2002-10-11 05:48:20 $
|
// $Revision: 1.2 $
|
// $Revision: 1.2 $
|
// $Author: rudi $
|
// $Author: rudi $
|
// $Locker: $
|
// $Locker: $
|
// $State: Exp $
|
// $State: Exp $
|
//
|
//
|
// Change History:
|
// Change History:
|
// $Log: not supported by cvs2svn $
|
// $Log: not supported by cvs2svn $
|
// Revision 1.1 2002/09/25 06:06:49 rudi
|
// Revision 1.1 2002/09/25 06:06:49 rudi
|
// - Added New Top Level
|
// - Added New Top Level
|
// - Remove old top level and associated files
|
// - Remove old top level and associated files
|
// - Moved FIFOs to "Generic FIFOs" project
|
// - Moved FIFOs to "Generic FIFOs" project
|
//
|
//
|
//
|
//
|
//
|
//
|
//
|
//
|
//
|
//
|
//
|
//
|
//
|
//
|
|
|
`include "usb1_defines.v"
|
`include "usb1_defines.v"
|
|
|
/*
|
/*
|
|
|
// USB PHY Interface
|
// USB PHY Interface
|
tx_dp, tx_dn, tx_oe,
|
tx_dp, tx_dn, tx_oe,
|
rx_d, rx_dp, rx_dn,
|
rx_d, rx_dp, rx_dn,
|
These pins are a semi-standard interface to USB 1.1 transceivers.
|
These pins are a semi-standard interface to USB 1.1 transceivers.
|
Just match up the signal names with the IOs of the transceiver.
|
Just match up the signal names with the IOs of the transceiver.
|
|
|
// USB Misc
|
// USB Misc
|
phy_tx_mode, usb_rst,
|
phy_tx_mode, usb_rst,
|
The PHY supports single ended and differential output to the
|
The PHY supports single ended and differential output to the
|
transceiver Depending on which device you are using, you have
|
transceiver Depending on which device you are using, you have
|
to tie the phy_tx_mode high or low.
|
to tie the phy_tx_mode high or low.
|
usb_rst is asserted whenever the host signals reset on the USB
|
usb_rst is asserted whenever the host signals reset on the USB
|
bus. The USB core will internally reset itself automatically.
|
bus. The USB core will internally reset itself automatically.
|
This output is provided for external logic that needs to be
|
This output is provided for external logic that needs to be
|
reset when the USB bus is reset.
|
reset when the USB bus is reset.
|
|
|
// Interrupts
|
// Interrupts
|
dropped_frame, misaligned_frame,
|
dropped_frame, misaligned_frame,
|
crc16_err,
|
crc16_err,
|
dropped_frame, misaligned_frame are interrupt to indicate error
|
dropped_frame, misaligned_frame are interrupt to indicate error
|
conditions in Block Frame mode.
|
conditions in Block Frame mode.
|
crc16_err, indicates when a crc 16 error was detected on the
|
crc16_err, indicates when a crc 16 error was detected on the
|
payload of a USB packet.
|
payload of a USB packet.
|
|
|
// Vendor Features
|
// Vendor Features
|
v_set_int, v_set_feature, wValue,
|
v_set_int, v_set_feature, wValue,
|
wIndex, vendor_data,
|
wIndex, vendor_data,
|
This signals allow to control vendor specific registers and logic
|
This signals allow to control vendor specific registers and logic
|
that can be manipulated and monitored via the control endpoint
|
that can be manipulated and monitored via the control endpoint
|
through vendor defined commands.
|
through vendor defined commands.
|
|
|
// USB Status
|
// USB Status
|
usb_busy, ep_sel,
|
usb_busy, ep_sel,
|
usb_busy is asserted when the USB core is busy transferring
|
usb_busy is asserted when the USB core is busy transferring
|
data ep_sel indicated the endpoint that is currently busy.
|
data ep_sel indicated the endpoint that is currently busy.
|
This information might be useful if one desires to reset/clear
|
This information might be useful if one desires to reset/clear
|
the attached FIFOs and want to do this when the endpoint is idle.
|
the attached FIFOs and want to do this when the endpoint is idle.
|
|
|
// Endpoint Interface
|
// Endpoint Interface
|
This implementation supports 8 endpoints. Endpoint 0 is the
|
This implementation supports 8 endpoints. Endpoint 0 is the
|
control endpoint and used internally. Endpoints 1-7 are available
|
control endpoint and used internally. Endpoints 1-7 are available
|
to the user. replace 'N' with the endpoint number.
|
to the user. replace 'N' with the endpoint number.
|
|
|
epN_cfg,
|
epN_cfg,
|
This is a constant input used to configure the endpoint by ORing
|
This is a constant input used to configure the endpoint by ORing
|
these defines together and adding the max packet size for this
|
these defines together and adding the max packet size for this
|
endpoint:
|
endpoint:
|
`IN and `OUT select the transfer direction for this endpoint
|
`IN and `OUT select the transfer direction for this endpoint
|
`ISO, `BULK and `INT determine the endpoint type
|
`ISO, `BULK and `INT determine the endpoint type
|
|
|
Example: "`BULK | `IN | 14'd064" defines a BULK IN endpoint with
|
Example: "`BULK | `IN | 14'd064" defines a BULK IN endpoint with
|
max packet size of 64 bytes
|
max packet size of 64 bytes
|
|
|
epN_din, epN_we, epN_full,
|
epN_din, epN_we, epN_full,
|
This is the OUT FIFO interface. If this is a IN endpoint, ground
|
This is the OUT FIFO interface. If this is a IN endpoint, ground
|
all unused inputs and leave outputs unconnected.
|
all unused inputs and leave outputs unconnected.
|
|
|
epN_dout, epN_re, epN_empty,
|
epN_dout, epN_re, epN_empty,
|
this is the IN FIFO interface. If this is a OUT endpoint ground
|
this is the IN FIFO interface. If this is a OUT endpoint ground
|
all unused inputs and leave outputs unconnected.
|
all unused inputs and leave outputs unconnected.
|
|
|
epN_bf_en, epN_bf_size,
|
epN_bf_en, epN_bf_size,
|
These two constant configure the Block Frame feature.
|
These two constant configure the Block Frame feature.
|
|
|
*/
|
*/
|
|
|
|
|
module usb1_core(clk_i, rst_i,
|
module usb1_core(clk_i, rst_i,
|
|
|
// USB PHY Interface
|
// USB PHY Interface
|
tx_dp, tx_dn, tx_oe,
|
tx_dp, tx_dn, tx_oe,
|
rx_d, rx_dp, rx_dn,
|
rx_d, rx_dp, rx_dn,
|
|
|
// USB Misc
|
// USB Misc
|
phy_tx_mode, usb_rst,
|
phy_tx_mode, usb_rst,
|
|
|
// Interrupts
|
// Interrupts
|
dropped_frame, misaligned_frame,
|
dropped_frame, misaligned_frame,
|
crc16_err,
|
crc16_err,
|
|
|
// Vendor Features
|
// Vendor Features
|
v_set_int, v_set_feature, wValue,
|
v_set_int, v_set_feature, wValue,
|
wIndex, vendor_data,
|
wIndex, vendor_data,
|
|
|
// USB Status
|
// USB Status
|
usb_busy, ep_sel,
|
usb_busy, ep_sel,
|
|
|
// Endpoint Interface
|
// Endpoint Interface
|
ep1_cfg,
|
ep1_cfg,
|
ep1_din, ep1_we, ep1_full,
|
ep1_din, ep1_we, ep1_full,
|
ep1_dout, ep1_re, ep1_empty,
|
ep1_dout, ep1_re, ep1_empty,
|
ep1_bf_en, ep1_bf_size,
|
ep1_bf_en, ep1_bf_size,
|
|
|
ep2_cfg,
|
ep2_cfg,
|
ep2_din, ep2_we, ep2_full,
|
ep2_din, ep2_we, ep2_full,
|
ep2_dout, ep2_re, ep2_empty,
|
ep2_dout, ep2_re, ep2_empty,
|
ep2_bf_en, ep2_bf_size,
|
ep2_bf_en, ep2_bf_size,
|
|
|
ep3_cfg,
|
ep3_cfg,
|
ep3_din, ep3_we, ep3_full,
|
ep3_din, ep3_we, ep3_full,
|
ep3_dout, ep3_re, ep3_empty,
|
ep3_dout, ep3_re, ep3_empty,
|
ep3_bf_en, ep3_bf_size,
|
ep3_bf_en, ep3_bf_size,
|
|
|
ep4_cfg,
|
ep4_cfg,
|
ep4_din, ep4_we, ep4_full,
|
ep4_din, ep4_we, ep4_full,
|
ep4_dout, ep4_re, ep4_empty,
|
ep4_dout, ep4_re, ep4_empty,
|
ep4_bf_en, ep4_bf_size,
|
ep4_bf_en, ep4_bf_size,
|
|
|
ep5_cfg,
|
ep5_cfg,
|
ep5_din, ep5_we, ep5_full,
|
ep5_din, ep5_we, ep5_full,
|
ep5_dout, ep5_re, ep5_empty,
|
ep5_dout, ep5_re, ep5_empty,
|
ep5_bf_en, ep5_bf_size,
|
ep5_bf_en, ep5_bf_size,
|
|
|
ep6_cfg,
|
ep6_cfg,
|
ep6_din, ep6_we, ep6_full,
|
ep6_din, ep6_we, ep6_full,
|
ep6_dout, ep6_re, ep6_empty,
|
ep6_dout, ep6_re, ep6_empty,
|
ep6_bf_en, ep6_bf_size,
|
ep6_bf_en, ep6_bf_size,
|
|
|
ep7_cfg,
|
ep7_cfg,
|
ep7_din, ep7_we, ep7_full,
|
ep7_din, ep7_we, ep7_full,
|
ep7_dout, ep7_re, ep7_empty,
|
ep7_dout, ep7_re, ep7_empty,
|
ep7_bf_en, ep7_bf_size
|
ep7_bf_en, ep7_bf_size
|
|
|
);
|
);
|
|
|
input clk_i;
|
input clk_i;
|
input rst_i;
|
input rst_i;
|
|
|
output tx_dp, tx_dn, tx_oe;
|
output tx_dp, tx_dn, tx_oe;
|
input rx_d, rx_dp, rx_dn;
|
input rx_d, rx_dp, rx_dn;
|
|
|
input phy_tx_mode;
|
input phy_tx_mode;
|
output usb_rst;
|
output usb_rst;
|
output dropped_frame, misaligned_frame;
|
output dropped_frame, misaligned_frame;
|
output crc16_err;
|
output crc16_err;
|
|
|
output v_set_int;
|
output v_set_int;
|
output v_set_feature;
|
output v_set_feature;
|
output [15:0] wValue;
|
output [15:0] wValue;
|
output [15:0] wIndex;
|
output [15:0] wIndex;
|
input [15:0] vendor_data;
|
input [15:0] vendor_data;
|
|
|
output usb_busy;
|
output usb_busy;
|
output [3:0] ep_sel;
|
output [3:0] ep_sel;
|
|
|
// Endpoint Interfaces
|
// Endpoint Interfaces
|
input [13:0] ep1_cfg;
|
input [13:0] ep1_cfg;
|
input [7:0] ep1_din;
|
input [7:0] ep1_din;
|
output [7:0] ep1_dout;
|
output [7:0] ep1_dout;
|
output ep1_we, ep1_re;
|
output ep1_we, ep1_re;
|
input ep1_empty, ep1_full;
|
input ep1_empty, ep1_full;
|
input ep1_bf_en;
|
input ep1_bf_en;
|
input [6:0] ep1_bf_size;
|
input [6:0] ep1_bf_size;
|
|
|
input [13:0] ep2_cfg;
|
input [13:0] ep2_cfg;
|
input [7:0] ep2_din;
|
input [7:0] ep2_din;
|
output [7:0] ep2_dout;
|
output [7:0] ep2_dout;
|
output ep2_we, ep2_re;
|
output ep2_we, ep2_re;
|
input ep2_empty, ep2_full;
|
input ep2_empty, ep2_full;
|
input ep2_bf_en;
|
input ep2_bf_en;
|
input [6:0] ep2_bf_size;
|
input [6:0] ep2_bf_size;
|
|
|
input [13:0] ep3_cfg;
|
input [13:0] ep3_cfg;
|
input [7:0] ep3_din;
|
input [7:0] ep3_din;
|
output [7:0] ep3_dout;
|
output [7:0] ep3_dout;
|
output ep3_we, ep3_re;
|
output ep3_we, ep3_re;
|
input ep3_empty, ep3_full;
|
input ep3_empty, ep3_full;
|
input ep3_bf_en;
|
input ep3_bf_en;
|
input [6:0] ep3_bf_size;
|
input [6:0] ep3_bf_size;
|
|
|
input [13:0] ep4_cfg;
|
input [13:0] ep4_cfg;
|
input [7:0] ep4_din;
|
input [7:0] ep4_din;
|
output [7:0] ep4_dout;
|
output [7:0] ep4_dout;
|
output ep4_we, ep4_re;
|
output ep4_we, ep4_re;
|
input ep4_empty, ep4_full;
|
input ep4_empty, ep4_full;
|
input ep4_bf_en;
|
input ep4_bf_en;
|
input [6:0] ep4_bf_size;
|
input [6:0] ep4_bf_size;
|
|
|
input [13:0] ep5_cfg;
|
input [13:0] ep5_cfg;
|
input [7:0] ep5_din;
|
input [7:0] ep5_din;
|
output [7:0] ep5_dout;
|
output [7:0] ep5_dout;
|
output ep5_we, ep5_re;
|
output ep5_we, ep5_re;
|
input ep5_empty, ep5_full;
|
input ep5_empty, ep5_full;
|
input ep5_bf_en;
|
input ep5_bf_en;
|
input [6:0] ep5_bf_size;
|
input [6:0] ep5_bf_size;
|
|
|
input [13:0] ep6_cfg;
|
input [13:0] ep6_cfg;
|
input [7:0] ep6_din;
|
input [7:0] ep6_din;
|
output [7:0] ep6_dout;
|
output [7:0] ep6_dout;
|
output ep6_we, ep6_re;
|
output ep6_we, ep6_re;
|
input ep6_empty, ep6_full;
|
input ep6_empty, ep6_full;
|
input ep6_bf_en;
|
input ep6_bf_en;
|
input [6:0] ep6_bf_size;
|
input [6:0] ep6_bf_size;
|
|
|
input [13:0] ep7_cfg;
|
input [13:0] ep7_cfg;
|
input [7:0] ep7_din;
|
input [7:0] ep7_din;
|
output [7:0] ep7_dout;
|
output [7:0] ep7_dout;
|
output ep7_we, ep7_re;
|
output ep7_we, ep7_re;
|
input ep7_empty, ep7_full;
|
input ep7_empty, ep7_full;
|
input ep7_bf_en;
|
input ep7_bf_en;
|
input [6:0] ep7_bf_size;
|
input [6:0] ep7_bf_size;
|
|
|
///////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////
|
//
|
//
|
// Local Wires and Registers
|
// Local Wires and Registers
|
//
|
//
|
|
|
// UTMI Interface
|
// UTMI Interface
|
wire [7:0] DataOut;
|
wire [7:0] DataOut;
|
wire TxValid;
|
wire TxValid;
|
wire TxReady;
|
wire TxReady;
|
wire [7:0] DataIn;
|
wire [7:0] DataIn;
|
wire RxValid;
|
wire RxValid;
|
wire RxActive;
|
wire RxActive;
|
wire RxError;
|
wire RxError;
|
wire [1:0] LineState;
|
wire [1:0] LineState;
|
|
|
wire [7:0] rx_data;
|
wire [7:0] rx_data;
|
wire rx_valid, rx_active, rx_err;
|
wire rx_valid, rx_active, rx_err;
|
wire [7:0] tx_data;
|
wire [7:0] tx_data;
|
wire tx_valid;
|
wire tx_valid;
|
wire tx_ready;
|
wire tx_ready;
|
wire tx_first;
|
wire tx_first;
|
wire tx_valid_last;
|
wire tx_valid_last;
|
|
|
// Internal Register File Interface
|
// Internal Register File Interface
|
wire [6:0] funct_adr; // This functions address (set by controller)
|
wire [6:0] funct_adr; // This functions address (set by controller)
|
wire [3:0] ep_sel; // Endpoint Number Input
|
wire [3:0] ep_sel; // Endpoint Number Input
|
wire crc16_err; // Set CRC16 error interrupt
|
wire crc16_err; // Set CRC16 error interrupt
|
wire int_to_set; // Set time out interrupt
|
wire int_to_set; // Set time out interrupt
|
wire int_seqerr_set; // Set PID sequence error interrupt
|
wire int_seqerr_set; // Set PID sequence error interrupt
|
wire [31:0] frm_nat; // Frame Number and Time Register
|
wire [31:0] frm_nat; // Frame Number and Time Register
|
wire nse_err; // No Such Endpoint Error
|
wire nse_err; // No Such Endpoint Error
|
wire pid_cs_err; // PID CS error
|
wire pid_cs_err; // PID CS error
|
wire crc5_err; // CRC5 Error
|
wire crc5_err; // CRC5 Error
|
|
|
reg [7:0] tx_data_st;
|
reg [7:0] tx_data_st;
|
wire [7:0] rx_data_st;
|
wire [7:0] rx_data_st;
|
reg [13:0] cfg;
|
reg [13:0] cfg;
|
reg ep_empty;
|
reg ep_empty;
|
reg ep_full;
|
reg ep_full;
|
wire [7:0] rx_size;
|
wire [7:0] rx_size;
|
wire rx_done;
|
wire rx_done;
|
|
|
wire [7:0] ep0_din;
|
wire [7:0] ep0_din;
|
wire [7:0] ep0_dout;
|
wire [7:0] ep0_dout;
|
wire ep0_re, ep0_we;
|
wire ep0_re, ep0_we;
|
wire [13:0] ep0_cfg;
|
wire [13:0] ep0_cfg;
|
wire [7:0] ep0_size;
|
wire [7:0] ep0_size;
|
wire [7:0] ep0_ctrl_dout, ep0_ctrl_din;
|
wire [7:0] ep0_ctrl_dout, ep0_ctrl_din;
|
wire ep0_ctrl_re, ep0_ctrl_we;
|
wire ep0_ctrl_re, ep0_ctrl_we;
|
wire [3:0] ep0_ctrl_stat;
|
wire [3:0] ep0_ctrl_stat;
|
|
|
wire ctrl_setup, ctrl_in, ctrl_out;
|
wire ctrl_setup, ctrl_in, ctrl_out;
|
wire send_stall;
|
wire send_stall;
|
wire token_valid;
|
wire token_valid;
|
reg rst_local; // internal reset
|
reg rst_local; // internal reset
|
wire dropped_frame;
|
wire dropped_frame;
|
wire misaligned_frame;
|
wire misaligned_frame;
|
wire v_set_int;
|
wire v_set_int;
|
wire v_set_feature;
|
wire v_set_feature;
|
wire [15:0] wValue;
|
wire [15:0] wValue;
|
wire [15:0] wIndex;
|
wire [15:0] wIndex;
|
|
|
reg ep_bf_en;
|
reg ep_bf_en;
|
reg [6:0] ep_bf_size;
|
reg [6:0] ep_bf_size;
|
wire [6:0] rom_adr;
|
wire [6:0] rom_adr;
|
wire [7:0] rom_data;
|
wire [7:0] rom_data;
|
|
|
///////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////
|
//
|
//
|
// Misc Logic
|
// Misc Logic
|
//
|
//
|
|
|
// Endpoint type and Max transfer size
|
// Endpoint type and Max transfer size
|
assign ep0_cfg = `CTRL | ep0_size;
|
assign ep0_cfg = `CTRL | ep0_size;
|
|
|
always @(posedge clk_i)
|
always @(posedge clk_i)
|
rst_local <= #1 rst_i & ~usb_rst;
|
rst_local <= #1 rst_i & ~usb_rst;
|
|
|
///////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////
|
//
|
//
|
// Module Instantiations
|
// Module Instantiations
|
//
|
//
|
|
|
usb_phy phy(
|
usb_phy phy(
|
.clk( clk_i ),
|
.clk( clk_i ),
|
.rst( rst_i ), // ONLY external reset
|
.rst( rst_i ), // ONLY external reset
|
.phy_tx_mode( phy_tx_mode ),
|
.phy_tx_mode( phy_tx_mode ),
|
.usb_rst( usb_rst ),
|
.usb_rst( usb_rst ),
|
|
|
// Transceiver Interface
|
// Transceiver Interface
|
.rxd( rx_d ),
|
.rxd( rx_d ),
|
.rxdp( rx_dp ),
|
.rxdp( rx_dp ),
|
.rxdn( rx_dn ),
|
.rxdn( rx_dn ),
|
.txdp( tx_dp ),
|
.txdp( tx_dp ),
|
.txdn( tx_dn ),
|
.txdn( tx_dn ),
|
.txoe( tx_oe ),
|
.txoe( tx_oe ),
|
|
|
// UTMI Interface
|
// UTMI Interface
|
.DataIn_o( DataIn ),
|
.DataIn_o( DataIn ),
|
.RxValid_o( RxValid ),
|
.RxValid_o( RxValid ),
|
.RxActive_o( RxActive ),
|
.RxActive_o( RxActive ),
|
.RxError_o( RxError ),
|
.RxError_o( RxError ),
|
.DataOut_i( DataOut ),
|
.DataOut_i( DataOut ),
|
.TxValid_i( TxValid ),
|
.TxValid_i( TxValid ),
|
.TxReady_o( TxReady ),
|
.TxReady_o( TxReady ),
|
.LineState_o( LineState )
|
.LineState_o( LineState )
|
);
|
);
|
|
|
// UTMI Interface
|
// UTMI Interface
|
usb1_utmi_if u0(
|
usb1_utmi_if u0(
|
.phy_clk( clk_i ),
|
.phy_clk( clk_i ),
|
.rst( rst_local ),
|
.rst( rst_local ),
|
.DataOut( DataOut ),
|
.DataOut( DataOut ),
|
.TxValid( TxValid ),
|
.TxValid( TxValid ),
|
.TxReady( TxReady ),
|
.TxReady( TxReady ),
|
.RxValid( RxValid ),
|
.RxValid( RxValid ),
|
.RxActive( RxActive ),
|
.RxActive( RxActive ),
|
.RxError( RxError ),
|
.RxError( RxError ),
|
.DataIn( DataIn ),
|
.DataIn( DataIn ),
|
.rx_data( rx_data ),
|
.rx_data( rx_data ),
|
.rx_valid( rx_valid ),
|
.rx_valid( rx_valid ),
|
.rx_active( rx_active ),
|
.rx_active( rx_active ),
|
.rx_err( rx_err ),
|
.rx_err( rx_err ),
|
.tx_data( tx_data ),
|
.tx_data( tx_data ),
|
.tx_valid( tx_valid ),
|
.tx_valid( tx_valid ),
|
.tx_valid_last( tx_valid_last ),
|
.tx_valid_last( tx_valid_last ),
|
.tx_ready( tx_ready ),
|
.tx_ready( tx_ready ),
|
.tx_first( tx_first )
|
.tx_first( tx_first )
|
);
|
);
|
|
|
// Protocol Layer
|
// Protocol Layer
|
usb1_pl u1( .clk( clk_i ),
|
usb1_pl u1( .clk( clk_i ),
|
.rst( rst_local ),
|
.rst( rst_local ),
|
.rx_data( rx_data ),
|
.rx_data( rx_data ),
|
.rx_valid( rx_valid ),
|
.rx_valid( rx_valid ),
|
.rx_active( rx_active ),
|
.rx_active( rx_active ),
|
.rx_err( rx_err ),
|
.rx_err( rx_err ),
|
.tx_data( tx_data ),
|
.tx_data( tx_data ),
|
.tx_valid( tx_valid ),
|
.tx_valid( tx_valid ),
|
.tx_valid_last( tx_valid_last ),
|
.tx_valid_last( tx_valid_last ),
|
.tx_ready( tx_ready ),
|
.tx_ready( tx_ready ),
|
.tx_first( tx_first ),
|
.tx_first( tx_first ),
|
.tx_valid_out( TxValid ),
|
.tx_valid_out( TxValid ),
|
.token_valid( token_valid ),
|
.token_valid( token_valid ),
|
.fa( funct_adr ),
|
.fa( funct_adr ),
|
.ep_sel( ep_sel ),
|
.ep_sel( ep_sel ),
|
.x_busy( usb_busy ),
|
.x_busy( usb_busy ),
|
.int_crc16_set( crc16_err ),
|
.int_crc16_set( crc16_err ),
|
.int_to_set( int_to_set ),
|
.int_to_set( int_to_set ),
|
.int_seqerr_set( int_seqerr_set ),
|
.int_seqerr_set( int_seqerr_set ),
|
.frm_nat( frm_nat ),
|
.frm_nat( frm_nat ),
|
.pid_cs_err( pid_cs_err ),
|
.pid_cs_err( pid_cs_err ),
|
.nse_err( nse_err ),
|
.nse_err( nse_err ),
|
.crc5_err( crc5_err ),
|
.crc5_err( crc5_err ),
|
.rx_size( rx_size ),
|
.rx_size( rx_size ),
|
.rx_done( rx_done ),
|
.rx_done( rx_done ),
|
.ctrl_setup( ctrl_setup ),
|
.ctrl_setup( ctrl_setup ),
|
.ctrl_in( ctrl_in ),
|
.ctrl_in( ctrl_in ),
|
.ctrl_out( ctrl_out ),
|
.ctrl_out( ctrl_out ),
|
.ep_bf_en( ep_bf_en ),
|
.ep_bf_en( ep_bf_en ),
|
.ep_bf_size( ep_bf_size ),
|
.ep_bf_size( ep_bf_size ),
|
.dropped_frame( dropped_frame ),
|
.dropped_frame( dropped_frame ),
|
.misaligned_frame( misaligned_frame ),
|
.misaligned_frame( misaligned_frame ),
|
.csr( cfg ),
|
.csr( cfg ),
|
.tx_data_st( tx_data_st ),
|
.tx_data_st( tx_data_st ),
|
.rx_data_st( rx_data_st ),
|
.rx_data_st( rx_data_st ),
|
.idma_re( idma_re ),
|
.idma_re( idma_re ),
|
.idma_we( idma_we ),
|
.idma_we( idma_we ),
|
.ep_empty( ep_empty ),
|
.ep_empty( ep_empty ),
|
.ep_full( ep_full ),
|
.ep_full( ep_full ),
|
.send_stall( send_stall )
|
.send_stall( send_stall )
|
);
|
);
|
|
|
usb1_ctrl u4( .clk( clk_i ),
|
usb1_ctrl u4( .clk( clk_i ),
|
.rst( rst_local ),
|
.rst( rst_local ),
|
|
|
.rom_adr( rom_adr ),
|
.rom_adr( rom_adr ),
|
.rom_data( rom_data ),
|
.rom_data( rom_data ),
|
|
|
.ctrl_setup( ctrl_setup ),
|
.ctrl_setup( ctrl_setup ),
|
.ctrl_in( ctrl_in ),
|
.ctrl_in( ctrl_in ),
|
.ctrl_out( ctrl_out ),
|
.ctrl_out( ctrl_out ),
|
|
|
.ep0_din( ep0_ctrl_dout ),
|
.ep0_din( ep0_ctrl_dout ),
|
.ep0_dout( ep0_ctrl_din ),
|
.ep0_dout( ep0_ctrl_din ),
|
.ep0_re( ep0_ctrl_re ),
|
.ep0_re( ep0_ctrl_re ),
|
.ep0_we( ep0_ctrl_we ),
|
.ep0_we( ep0_ctrl_we ),
|
.ep0_stat( ep0_ctrl_stat ),
|
.ep0_stat( ep0_ctrl_stat ),
|
.ep0_size( ep0_size ),
|
.ep0_size( ep0_size ),
|
|
|
.send_stall( send_stall ),
|
.send_stall( send_stall ),
|
.frame_no( frm_nat[26:16] ),
|
.frame_no( frm_nat[26:16] ),
|
.funct_adr( funct_adr ),
|
.funct_adr( funct_adr ),
|
.configured( ),
|
.configured( ),
|
.halt( ),
|
.halt( ),
|
|
|
.v_set_int( v_set_int ),
|
.v_set_int( v_set_int ),
|
.v_set_feature( v_set_feature ),
|
.v_set_feature( v_set_feature ),
|
.wValue( wValue ),
|
.wValue( wValue ),
|
.wIndex( wIndex ),
|
.wIndex( wIndex ),
|
.vendor_data( vendor_data )
|
.vendor_data( vendor_data )
|
);
|
);
|
|
|
|
|
usb1_rom1 rom1( .clk( clk_i ),
|
usb1_rom1 rom1( .clk( clk_i ),
|
.adr( rom_adr ),
|
.adr( rom_adr ),
|
.dout( rom_data )
|
.dout( rom_data )
|
);
|
);
|
|
|
// CTRL Endpoint FIFO
|
// CTRL Endpoint FIFO
|
generic_fifo_sc_a #(8,6,0) u10(
|
generic_fifo_sc_a #(8,6,0) u10(
|
.clk( clk_i ),
|
.clk( clk_i ),
|
.rst( rst_i ),
|
.rst( rst_i ),
|
.clr( usb_rst ),
|
.clr( usb_rst ),
|
.din( rx_data_st ),
|
.din( rx_data_st ),
|
.we( ep0_we ),
|
.we( ep0_we ),
|
.dout( ep0_ctrl_dout ),
|
.dout( ep0_ctrl_dout ),
|
.re( ep0_ctrl_re ),
|
.re( ep0_ctrl_re ),
|
.full_r( ),
|
.full_r( ),
|
.empty_r( ),
|
.empty_r( ),
|
.full( ep0_full ),
|
.full( ep0_full ),
|
.empty( ep0_ctrl_stat[1] ),
|
.empty( ep0_ctrl_stat[1] ),
|
.full_n( ),
|
.full_n( ),
|
.empty_n( ),
|
.empty_n( ),
|
.full_n_r( ),
|
.full_n_r( ),
|
.empty_n_r( ),
|
.empty_n_r( ),
|
.level( )
|
.level( )
|
);
|
);
|
|
|
generic_fifo_sc_a #(8,6,0) u11(
|
generic_fifo_sc_a #(8,6,0) u11(
|
.clk( clk_i ),
|
.clk( clk_i ),
|
.rst( rst_i ),
|
.rst( rst_i ),
|
.clr( usb_rst ),
|
.clr( usb_rst ),
|
.din( ep0_ctrl_din ),
|
.din( ep0_ctrl_din ),
|
.we( ep0_ctrl_we ),
|
.we( ep0_ctrl_we ),
|
.dout( ep0_dout ),
|
.dout( ep0_dout ),
|
.re( ep0_re ),
|
.re( ep0_re ),
|
.full_r( ),
|
.full_r( ),
|
.empty_r( ),
|
.empty_r( ),
|
.full( ep0_ctrl_stat[2] ),
|
.full( ep0_ctrl_stat[2] ),
|
.empty( ep0_empty ),
|
.empty( ep0_empty ),
|
.full_n( ),
|
.full_n( ),
|
.empty_n( ),
|
.empty_n( ),
|
.full_n_r( ),
|
.full_n_r( ),
|
.empty_n_r( ),
|
.empty_n_r( ),
|
.level( )
|
.level( )
|
);
|
);
|
|
|
///////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////
|
//
|
//
|
// Endpoint FIFO Interfaces
|
// Endpoint FIFO Interfaces
|
//
|
//
|
|
|
always @(ep_sel or ep0_cfg or ep1_cfg or ep2_cfg or ep3_cfg or
|
always @(ep_sel or ep0_cfg or ep1_cfg or ep2_cfg or ep3_cfg or
|
ep4_cfg or ep5_cfg or ep6_cfg or ep7_cfg)
|
ep4_cfg or ep5_cfg or ep6_cfg or ep7_cfg)
|
case(ep_sel) // synopsys full_case parallel_case
|
case(ep_sel) // synopsys full_case parallel_case
|
4'h0: cfg = ep0_cfg;
|
4'h0: cfg = ep0_cfg;
|
4'h1: cfg = ep1_cfg;
|
4'h1: cfg = ep1_cfg;
|
4'h2: cfg = ep2_cfg;
|
4'h2: cfg = ep2_cfg;
|
4'h3: cfg = ep3_cfg;
|
4'h3: cfg = ep3_cfg;
|
4'h4: cfg = ep4_cfg;
|
4'h4: cfg = ep4_cfg;
|
4'h5: cfg = ep5_cfg;
|
4'h5: cfg = ep5_cfg;
|
4'h6: cfg = ep6_cfg;
|
4'h6: cfg = ep6_cfg;
|
4'h7: cfg = ep7_cfg;
|
4'h7: cfg = ep7_cfg;
|
endcase
|
endcase
|
|
|
// In endpoints only
|
// In endpoints only
|
always @(posedge clk_i)
|
always @(posedge clk_i)
|
case(ep_sel) // synopsys full_case parallel_case
|
case(ep_sel) // synopsys full_case parallel_case
|
4'h0: tx_data_st <= #1 ep0_dout;
|
4'h0: tx_data_st <= #1 ep0_dout;
|
4'h1: tx_data_st <= #1 ep1_din;
|
4'h1: tx_data_st <= #1 ep1_din;
|
4'h2: tx_data_st <= #1 ep2_din;
|
4'h2: tx_data_st <= #1 ep2_din;
|
4'h3: tx_data_st <= #1 ep3_din;
|
4'h3: tx_data_st <= #1 ep3_din;
|
4'h4: tx_data_st <= #1 ep4_din;
|
4'h4: tx_data_st <= #1 ep4_din;
|
4'h5: tx_data_st <= #1 ep5_din;
|
4'h5: tx_data_st <= #1 ep5_din;
|
4'h6: tx_data_st <= #1 ep6_din;
|
4'h6: tx_data_st <= #1 ep6_din;
|
4'h7: tx_data_st <= #1 ep7_din;
|
4'h7: tx_data_st <= #1 ep7_din;
|
endcase
|
endcase
|
|
|
// In endpoints only
|
// In endpoints only
|
always @(posedge clk_i)
|
always @(posedge clk_i)
|
case(ep_sel) // synopsys full_case parallel_case
|
case(ep_sel) // synopsys full_case parallel_case
|
4'h0: ep_empty <= #1 ep0_empty;
|
4'h0: ep_empty <= #1 ep0_empty;
|
4'h1: ep_empty <= #1 ep1_empty;
|
4'h1: ep_empty <= #1 ep1_empty;
|
4'h2: ep_empty <= #1 ep2_empty;
|
4'h2: ep_empty <= #1 ep2_empty;
|
4'h3: ep_empty <= #1 ep3_empty;
|
4'h3: ep_empty <= #1 ep3_empty;
|
4'h4: ep_empty <= #1 ep4_empty;
|
4'h4: ep_empty <= #1 ep4_empty;
|
4'h5: ep_empty <= #1 ep5_empty;
|
4'h5: ep_empty <= #1 ep5_empty;
|
4'h6: ep_empty <= #1 ep6_empty;
|
4'h6: ep_empty <= #1 ep6_empty;
|
4'h7: ep_empty <= #1 ep7_empty;
|
4'h7: ep_empty <= #1 ep7_empty;
|
endcase
|
endcase
|
|
|
// OUT endpoints only
|
// OUT endpoints only
|
always @(ep_sel or ep0_full or ep1_full or ep2_full or ep3_full or
|
always @(ep_sel or ep0_full or ep1_full or ep2_full or ep3_full or
|
ep4_full or ep5_full or ep6_full or ep7_full)
|
ep4_full or ep5_full or ep6_full or ep7_full)
|
case(ep_sel) // synopsys full_case parallel_case
|
case(ep_sel) // synopsys full_case parallel_case
|
4'h0: ep_full = ep0_full;
|
4'h0: ep_full = ep0_full;
|
4'h1: ep_full = ep1_full;
|
4'h1: ep_full = ep1_full;
|
4'h2: ep_full = ep2_full;
|
4'h2: ep_full = ep2_full;
|
4'h3: ep_full = ep3_full;
|
4'h3: ep_full = ep3_full;
|
4'h4: ep_full = ep4_full;
|
4'h4: ep_full = ep4_full;
|
4'h5: ep_full = ep5_full;
|
4'h5: ep_full = ep5_full;
|
4'h6: ep_full = ep6_full;
|
4'h6: ep_full = ep6_full;
|
4'h7: ep_full = ep7_full;
|
4'h7: ep_full = ep7_full;
|
endcase
|
endcase
|
|
|
always @(posedge clk_i)
|
always @(posedge clk_i)
|
case(ep_sel) // synopsys full_case parallel_case
|
case(ep_sel) // synopsys full_case parallel_case
|
4'h0: ep_bf_en = 1'b0;
|
4'h0: ep_bf_en = 1'b0;
|
4'h1: ep_bf_en = ep1_bf_en;
|
4'h1: ep_bf_en = ep1_bf_en;
|
4'h2: ep_bf_en = ep2_bf_en;
|
4'h2: ep_bf_en = ep2_bf_en;
|
4'h3: ep_bf_en = ep3_bf_en;
|
4'h3: ep_bf_en = ep3_bf_en;
|
4'h4: ep_bf_en = ep4_bf_en;
|
4'h4: ep_bf_en = ep4_bf_en;
|
4'h5: ep_bf_en = ep5_bf_en;
|
4'h5: ep_bf_en = ep5_bf_en;
|
4'h6: ep_bf_en = ep6_bf_en;
|
4'h6: ep_bf_en = ep6_bf_en;
|
4'h7: ep_bf_en = ep7_bf_en;
|
4'h7: ep_bf_en = ep7_bf_en;
|
endcase
|
endcase
|
|
|
always @(posedge clk_i)
|
always @(posedge clk_i)
|
case(ep_sel) // synopsys full_case parallel_case
|
case(ep_sel) // synopsys full_case parallel_case
|
4'h1: ep_bf_size = ep1_bf_size;
|
4'h1: ep_bf_size = ep1_bf_size;
|
4'h2: ep_bf_size = ep2_bf_size;
|
4'h2: ep_bf_size = ep2_bf_size;
|
4'h3: ep_bf_size = ep3_bf_size;
|
4'h3: ep_bf_size = ep3_bf_size;
|
4'h4: ep_bf_size = ep4_bf_size;
|
4'h4: ep_bf_size = ep4_bf_size;
|
4'h5: ep_bf_size = ep5_bf_size;
|
4'h5: ep_bf_size = ep5_bf_size;
|
4'h6: ep_bf_size = ep6_bf_size;
|
4'h6: ep_bf_size = ep6_bf_size;
|
4'h7: ep_bf_size = ep7_bf_size;
|
4'h7: ep_bf_size = ep7_bf_size;
|
endcase
|
endcase
|
|
|
assign ep1_dout = rx_data_st;
|
assign ep1_dout = rx_data_st;
|
assign ep2_dout = rx_data_st;
|
assign ep2_dout = rx_data_st;
|
assign ep3_dout = rx_data_st;
|
assign ep3_dout = rx_data_st;
|
assign ep4_dout = rx_data_st;
|
assign ep4_dout = rx_data_st;
|
assign ep5_dout = rx_data_st;
|
assign ep5_dout = rx_data_st;
|
assign ep6_dout = rx_data_st;
|
assign ep6_dout = rx_data_st;
|
assign ep7_dout = rx_data_st;
|
assign ep7_dout = rx_data_st;
|
|
|
assign ep0_re = idma_re & (ep_sel == 4'h00);
|
assign ep0_re = idma_re & (ep_sel == 4'h00);
|
assign ep1_re = idma_re & (ep_sel == 4'h01) & !ep1_empty;
|
assign ep1_re = idma_re & (ep_sel == 4'h01) & !ep1_empty;
|
assign ep2_re = idma_re & (ep_sel == 4'h02) & !ep2_empty;
|
assign ep2_re = idma_re & (ep_sel == 4'h02) & !ep2_empty;
|
assign ep3_re = idma_re & (ep_sel == 4'h03) & !ep3_empty;
|
assign ep3_re = idma_re & (ep_sel == 4'h03) & !ep3_empty;
|
assign ep4_re = idma_re & (ep_sel == 4'h04) & !ep4_empty;
|
assign ep4_re = idma_re & (ep_sel == 4'h04) & !ep4_empty;
|
assign ep5_re = idma_re & (ep_sel == 4'h05) & !ep5_empty;
|
assign ep5_re = idma_re & (ep_sel == 4'h05) & !ep5_empty;
|
assign ep6_re = idma_re & (ep_sel == 4'h06) & !ep6_empty;
|
assign ep6_re = idma_re & (ep_sel == 4'h06) & !ep6_empty;
|
assign ep7_re = idma_re & (ep_sel == 4'h07) & !ep7_empty;
|
assign ep7_re = idma_re & (ep_sel == 4'h07) & !ep7_empty;
|
|
|
assign ep0_we = idma_we & (ep_sel == 4'h00);
|
assign ep0_we = idma_we & (ep_sel == 4'h00);
|
assign ep1_we = idma_we & (ep_sel == 4'h01) & !ep1_full;
|
assign ep1_we = idma_we & (ep_sel == 4'h01) & !ep1_full;
|
assign ep2_we = idma_we & (ep_sel == 4'h02) & !ep2_full;
|
assign ep2_we = idma_we & (ep_sel == 4'h02) & !ep2_full;
|
assign ep3_we = idma_we & (ep_sel == 4'h03) & !ep3_full;
|
assign ep3_we = idma_we & (ep_sel == 4'h03) & !ep3_full;
|
assign ep4_we = idma_we & (ep_sel == 4'h04) & !ep4_full;
|
assign ep4_we = idma_we & (ep_sel == 4'h04) & !ep4_full;
|
assign ep5_we = idma_we & (ep_sel == 4'h05) & !ep5_full;
|
assign ep5_we = idma_we & (ep_sel == 4'h05) & !ep5_full;
|
assign ep6_we = idma_we & (ep_sel == 4'h06) & !ep6_full;
|
assign ep6_we = idma_we & (ep_sel == 4'h06) & !ep6_full;
|
assign ep7_we = idma_we & (ep_sel == 4'h07) & !ep7_full;
|
assign ep7_we = idma_we & (ep_sel == 4'h07) & !ep7_full;
|
|
|
endmodule
|
endmodule
|
|
|
|
|