Initial commit
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
|
||||
The USB 2.0 Function Project Page is:
|
||||
http://www.opencores.org/cores/usb/
|
||||
|
||||
To find out more about me (Rudolf Usselmann), please visit:
|
||||
http://www.asics.ws
|
||||
|
||||
Directory Structure
|
||||
-------------------
|
||||
[core_root]
|
||||
|
|
||||
+-doc Documentation
|
||||
|
|
||||
+-bench--+ Test Bench
|
||||
| +- verilog Verilog Sources
|
||||
| +-vhdl VHDL Sources
|
||||
|
|
||||
+-rtl----+ Core RTL Sources
|
||||
| +-verilog Verilog Sources
|
||||
| +-vhdl VHDL Sources
|
||||
|
|
||||
+-sim----+
|
||||
| +-rtl_sim---+ Functional verification Directory
|
||||
| | +-bin Makefiles/Run Scripts
|
||||
| | +-run Working Directory
|
||||
| |
|
||||
| +-gate_sim--+ Functional & Timing Gate Level
|
||||
| | Verification Directory
|
||||
| +-bin Makefiles/Run Scripts
|
||||
| +-run Working Directory
|
||||
|
|
||||
+-lint--+ Lint Directory Tree
|
||||
| +-bin Makefiles/Run Scripts
|
||||
| +-run Working Directory
|
||||
| +-log Linter log & result files
|
||||
|
|
||||
+-syn---+ Synthesis Directory Tree
|
||||
| +-bin Synthesis Scripts
|
||||
| +-run Working Directory
|
||||
| +-log Synthesis log files
|
||||
| +-out Synthesis Output
|
||||
@@ -0,0 +1,44 @@
|
||||
This file describes the current status of the checked in HDL code.
|
||||
Please submit all bugs/comments/suggestions regarding the USB core
|
||||
to: usb@opencores.org
|
||||
|
||||
Need Help
|
||||
---------
|
||||
I'm looking for help in verifying the core. If you think you can help,
|
||||
please send an email to the list or to me directly.
|
||||
|
||||
|
||||
STATUS
|
||||
======
|
||||
|
||||
Update (8/2/2001)
|
||||
-----------------
|
||||
- Changed Directory Structure
|
||||
|
||||
Initial Release (31/3/2001)
|
||||
---------------------------
|
||||
- This is the second officially available release of the core
|
||||
- It is still under active development
|
||||
- Please do not modify the sources !
|
||||
- Things that are not implemented yet, or are known not to work yet:
|
||||
- There is no logic in the core to "help" suspending it. I'm not
|
||||
quite sure yet what to do in this area. (Suggestions welcomed !)
|
||||
- There has been very little testing done on the core
|
||||
|
||||
Initial Release (28/2/2001)
|
||||
---------------------------
|
||||
- This is the very first officially available release of the core
|
||||
- It is still under active development
|
||||
- Please do not modify the sources !
|
||||
- Things that are not implemented yet, or are known not to work yet:
|
||||
- UTMI line/link control interface is not implemented yet. This includes:
|
||||
- Detection of attach/detach
|
||||
- Speed negotiation (Full/High Speed)
|
||||
- USB reset
|
||||
- USB suspend
|
||||
- There is no logic in the core to "help" suspending it. I'm not
|
||||
quite sure yet what to do in this area. (Suggestions welcomed !)
|
||||
- There is no easy way to configure the core (number of endpoints,
|
||||
buffer size)
|
||||
- There has been absolutely no testing done on the core
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,106 @@
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// USB CRC5 and CRC16 Modules ////
|
||||
//// ////
|
||||
//// ////
|
||||
//// Author: Rudolf Usselmann ////
|
||||
//// rudi@asics.ws ////
|
||||
//// ////
|
||||
//// ////
|
||||
//// Downloaded from: http://www.opencores.org/cores/usb/ ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2000-2003 Rudolf Usselmann ////
|
||||
//// www.asics.ws ////
|
||||
//// rudi@asics.ws ////
|
||||
//// ////
|
||||
//// This source file may be used and distributed without ////
|
||||
//// restriction provided that this copyright statement is not ////
|
||||
//// removed from the file and that any derivative work contains ////
|
||||
//// the original copyright notice and the associated disclaimer.////
|
||||
//// ////
|
||||
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
|
||||
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
|
||||
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
|
||||
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
|
||||
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
|
||||
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
|
||||
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
|
||||
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
|
||||
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
|
||||
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
|
||||
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
|
||||
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
|
||||
//// POSSIBILITY OF SUCH DAMAGE. ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
// CVS Log
|
||||
//
|
||||
// $Id: usbf_crc16.v,v 1.2 2003-10-17 02:36:57 rudi Exp $
|
||||
//
|
||||
// $Date: 2003-10-17 02:36:57 $
|
||||
// $Revision: 1.2 $
|
||||
// $Author: rudi $
|
||||
// $Locker: $
|
||||
// $State: Exp $
|
||||
//
|
||||
// Change History:
|
||||
// $Log: not supported by cvs2svn $
|
||||
// Revision 1.1 2001/08/03 05:30:09 rudi
|
||||
//
|
||||
//
|
||||
// 1) Reorganized directory structure
|
||||
//
|
||||
// Revision 1.0 2001/03/07 09:17:12 rudi
|
||||
//
|
||||
//
|
||||
// Changed all revisions to revision 1.0. This is because OpenCores CVS
|
||||
// interface could not handle the original '0.1' revision ....
|
||||
//
|
||||
// Revision 0.1.0.1 2001/02/28 08:10:42 rudi
|
||||
// Initial Release
|
||||
//
|
||||
//
|
||||
|
||||
`include "usbf_defines.v"
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CRC16
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
module usbf_crc16(crc_in, din, crc_out);
|
||||
input [15:0] crc_in;
|
||||
input [7:0] din;
|
||||
output [15:0] crc_out;
|
||||
|
||||
assign crc_out[0] = din[7] ^ din[6] ^ din[5] ^ din[4] ^ din[3] ^
|
||||
din[2] ^ din[1] ^ din[0] ^ crc_in[8] ^ crc_in[9] ^
|
||||
crc_in[10] ^ crc_in[11] ^ crc_in[12] ^ crc_in[13] ^
|
||||
crc_in[14] ^ crc_in[15];
|
||||
assign crc_out[1] = din[7] ^ din[6] ^ din[5] ^ din[4] ^ din[3] ^ din[2] ^
|
||||
din[1] ^ crc_in[9] ^ crc_in[10] ^ crc_in[11] ^
|
||||
crc_in[12] ^ crc_in[13] ^ crc_in[14] ^ crc_in[15];
|
||||
assign crc_out[2] = din[1] ^ din[0] ^ crc_in[8] ^ crc_in[9];
|
||||
assign crc_out[3] = din[2] ^ din[1] ^ crc_in[9] ^ crc_in[10];
|
||||
assign crc_out[4] = din[3] ^ din[2] ^ crc_in[10] ^ crc_in[11];
|
||||
assign crc_out[5] = din[4] ^ din[3] ^ crc_in[11] ^ crc_in[12];
|
||||
assign crc_out[6] = din[5] ^ din[4] ^ crc_in[12] ^ crc_in[13];
|
||||
assign crc_out[7] = din[6] ^ din[5] ^ crc_in[13] ^ crc_in[14];
|
||||
assign crc_out[8] = din[7] ^ din[6] ^ crc_in[0] ^ crc_in[14] ^ crc_in[15];
|
||||
assign crc_out[9] = din[7] ^ crc_in[1] ^ crc_in[15];
|
||||
assign crc_out[10] = crc_in[2];
|
||||
assign crc_out[11] = crc_in[3];
|
||||
assign crc_out[12] = crc_in[4];
|
||||
assign crc_out[13] = crc_in[5];
|
||||
assign crc_out[14] = crc_in[6];
|
||||
assign crc_out[15] = din[7] ^ din[6] ^ din[5] ^ din[4] ^ din[3] ^ din[2] ^
|
||||
din[1] ^ din[0] ^ crc_in[7] ^ crc_in[8] ^ crc_in[9] ^
|
||||
crc_in[10] ^ crc_in[11] ^ crc_in[12] ^ crc_in[13] ^
|
||||
crc_in[14] ^ crc_in[15];
|
||||
|
||||
endmodule
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// USB CRC5 and CRC16 Modules ////
|
||||
//// ////
|
||||
//// ////
|
||||
//// Author: Rudolf Usselmann ////
|
||||
//// rudi@asics.ws ////
|
||||
//// ////
|
||||
//// ////
|
||||
//// Downloaded from: http://www.opencores.org/cores/usb/ ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2000-2003 Rudolf Usselmann ////
|
||||
//// www.asics.ws ////
|
||||
//// rudi@asics.ws ////
|
||||
//// ////
|
||||
//// This source file may be used and distributed without ////
|
||||
//// restriction provided that this copyright statement is not ////
|
||||
//// removed from the file and that any derivative work contains ////
|
||||
//// the original copyright notice and the associated disclaimer.////
|
||||
//// ////
|
||||
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
|
||||
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
|
||||
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
|
||||
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
|
||||
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
|
||||
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
|
||||
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
|
||||
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
|
||||
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
|
||||
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
|
||||
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
|
||||
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
|
||||
//// POSSIBILITY OF SUCH DAMAGE. ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
// CVS Log
|
||||
//
|
||||
// $Id: usbf_crc5.v,v 1.2 2003-10-17 02:36:57 rudi Exp $
|
||||
//
|
||||
// $Date: 2003-10-17 02:36:57 $
|
||||
// $Revision: 1.2 $
|
||||
// $Author: rudi $
|
||||
// $Locker: $
|
||||
// $State: Exp $
|
||||
//
|
||||
// Change History:
|
||||
// $Log: not supported by cvs2svn $
|
||||
// Revision 1.1 2001/08/03 05:30:09 rudi
|
||||
//
|
||||
//
|
||||
// 1) Reorganized directory structure
|
||||
//
|
||||
// Revision 1.0 2001/03/07 09:17:12 rudi
|
||||
//
|
||||
//
|
||||
// Changed all revisions to revision 1.0. This is because OpenCores CVS
|
||||
// interface could not handle the original '0.1' revision ....
|
||||
//
|
||||
// Revision 0.1.0.1 2001/02/28 08:10:42 rudi
|
||||
// Initial Release
|
||||
//
|
||||
//
|
||||
|
||||
`include "usbf_defines.v"
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CRC5
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
module usbf_crc5(crc_in, din, crc_out);
|
||||
input [4:0] crc_in;
|
||||
input [10:0] din;
|
||||
output [4:0] crc_out;
|
||||
|
||||
assign crc_out[0] = din[10] ^ din[9] ^ din[6] ^ din[5] ^ din[3] ^
|
||||
din[0] ^ crc_in[0] ^ crc_in[3] ^ crc_in[4];
|
||||
|
||||
assign crc_out[1] = din[10] ^ din[7] ^ din[6] ^ din[4] ^ din[1] ^
|
||||
crc_in[0] ^ crc_in[1] ^ crc_in[4];
|
||||
|
||||
assign crc_out[2] = din[10] ^ din[9] ^ din[8] ^ din[7] ^ din[6] ^
|
||||
din[3] ^ din[2] ^ din[0] ^ crc_in[0] ^ crc_in[1] ^
|
||||
crc_in[2] ^ crc_in[3] ^ crc_in[4];
|
||||
|
||||
assign crc_out[3] = din[10] ^ din[9] ^ din[8] ^ din[7] ^ din[4] ^ din[3] ^
|
||||
din[1] ^ crc_in[1] ^ crc_in[2] ^ crc_in[3] ^ crc_in[4];
|
||||
|
||||
assign crc_out[4] = din[10] ^ din[9] ^ din[8] ^ din[5] ^ din[4] ^ din[2] ^
|
||||
crc_in[2] ^ crc_in[3] ^ crc_in[4];
|
||||
|
||||
endmodule
|
||||
|
||||
@@ -0,0 +1,285 @@
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// USB function defines file ////
|
||||
//// ////
|
||||
//// ////
|
||||
//// Author: Rudolf Usselmann ////
|
||||
//// rudi@asics.ws ////
|
||||
//// ////
|
||||
//// ////
|
||||
//// Downloaded from: http://www.opencores.org/cores/usb/ ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2000-2003 Rudolf Usselmann ////
|
||||
//// www.asics.ws ////
|
||||
//// rudi@asics.ws ////
|
||||
//// ////
|
||||
//// This source file may be used and distributed without ////
|
||||
//// restriction provided that this copyright statement is not ////
|
||||
//// removed from the file and that any derivative work contains ////
|
||||
//// the original copyright notice and the associated disclaimer.////
|
||||
//// ////
|
||||
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
|
||||
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
|
||||
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
|
||||
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
|
||||
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
|
||||
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
|
||||
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
|
||||
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
|
||||
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
|
||||
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
|
||||
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
|
||||
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
|
||||
//// POSSIBILITY OF SUCH DAMAGE. ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
// CVS Log
|
||||
//
|
||||
// $Id: usbf_defines.v,v 1.6 2003-10-17 02:36:57 rudi Exp $
|
||||
//
|
||||
// $Date: 2003-10-17 02:36:57 $
|
||||
// $Revision: 1.6 $
|
||||
// $Author: rudi $
|
||||
// $Locker: $
|
||||
// $State: Exp $
|
||||
//
|
||||
// Change History:
|
||||
// $Log: not supported by cvs2svn $
|
||||
// Revision 1.5 2001/11/04 12:22:43 rudi
|
||||
//
|
||||
// - Fixed previous fix (brocke something else ...)
|
||||
// - Majore Synthesis cleanup
|
||||
//
|
||||
// Revision 1.4 2001/09/23 08:39:33 rudi
|
||||
//
|
||||
// Renamed DEBUG and VERBOSE_DEBUG to USBF_DEBUG and USBF_VERBOSE_DEBUG ...
|
||||
//
|
||||
// Revision 1.3 2001/09/13 13:14:02 rudi
|
||||
//
|
||||
// Fixed a problem that would sometimes prevent the core to come out of
|
||||
// reset and immediately be operational ...
|
||||
//
|
||||
// Revision 1.2 2001/08/10 08:48:33 rudi
|
||||
//
|
||||
// - Changed IO names to be more clear.
|
||||
// - Uniquifyed define names to be core specific.
|
||||
//
|
||||
// Revision 1.1 2001/08/03 05:30:09 rudi
|
||||
//
|
||||
//
|
||||
// 1) Reorganized directory structure
|
||||
//
|
||||
// Revision 1.2 2001/03/31 13:00:52 rudi
|
||||
//
|
||||
// - Added Core configuration
|
||||
// - Added handling of OUT packets less than MAX_PL_SZ in DMA mode
|
||||
// - Modified WISHBONE interface and sync logic
|
||||
// - Moved SSRAM outside the core (added interface)
|
||||
// - Many small bug fixes ...
|
||||
//
|
||||
// Revision 1.0 2001/03/07 09:17:12 rudi
|
||||
//
|
||||
//
|
||||
// Changed all revisions to revision 1.0. This is because OpenCores CVS
|
||||
// interface could not handle the original '0.1' revision ....
|
||||
//
|
||||
// Revision 0.2 2001/03/07 09:08:13 rudi
|
||||
//
|
||||
// Added USB control signaling (Line Status) block. Fixed some minor
|
||||
// typos, added resume bit and signal.
|
||||
//
|
||||
// Revision 0.1.0.1 2001/02/28 08:11:35 rudi
|
||||
// Initial Release
|
||||
//
|
||||
//
|
||||
|
||||
`timescale 1ns / 10ps
|
||||
|
||||
// Uncomment the lines below to get various levels of debugging
|
||||
// verbosity ...
|
||||
`define USBF_DEBUG
|
||||
//`define USBF_VERBOSE_DEBUG
|
||||
|
||||
// Uncomment the line below to run the test bench
|
||||
// Comment it out to use your own address parameters ...
|
||||
`define USBF_TEST_IMPL
|
||||
|
||||
// For each endpoint that should actually be instantiated,
|
||||
// set the below define value to a one. Uncomment the define
|
||||
// statement for unused endpoints. The endpoints should be
|
||||
// sequential, e.q. 1,2,3. I have not tested what happens if
|
||||
// you select endpoints in a non sequential manner e.g. 1,4,6
|
||||
// Actual (logical) endpoint IDs are set by the software. There
|
||||
// is no correlation between the physical endpoint number (below)
|
||||
// and the actual (logical) endpoint number.
|
||||
`ifdef USBF_TEST_IMPL
|
||||
// Do not modify this section
|
||||
// this is to run the test bench
|
||||
`define USBF_HAVE_EP1 1
|
||||
`define USBF_HAVE_EP2 1
|
||||
`define USBF_HAVE_EP3 1
|
||||
`else
|
||||
// Modify this section to suit your implementation
|
||||
`define USBF_HAVE_EP1 1
|
||||
`define USBF_HAVE_EP2 1
|
||||
`define USBF_HAVE_EP3 1
|
||||
//`define USBF_HAVE_EP4 1
|
||||
//`define USBF_HAVE_EP5 1
|
||||
//`define USBF_HAVE_EP6 1
|
||||
//`define USBF_HAVE_EP7 1
|
||||
//`define USBF_HAVE_EP8 1
|
||||
//`define USBF_HAVE_EP9 1
|
||||
//`define USBF_HAVE_EP10 1
|
||||
//`define USBF_HAVE_EP11 1
|
||||
//`define USBF_HAVE_EP12 1
|
||||
//`define USBF_HAVE_EP13 1
|
||||
//`define USBF_HAVE_EP14 1
|
||||
//`define USBF_HAVE_EP15 1
|
||||
`endif
|
||||
|
||||
|
||||
// Highest address line number that goes to the USB core
|
||||
// Typically only A0 through A17 are needed, where A17
|
||||
// selects between the internal buffer memory and the
|
||||
// register file.
|
||||
// Implementations may choose to have a more complex address
|
||||
// decoding ....
|
||||
|
||||
`ifdef USBF_TEST_IMPL
|
||||
// Do not modify this section
|
||||
// this is to run the test bench
|
||||
`define USBF_UFC_HADR 17
|
||||
`define USBF_RF_SEL (!wb_addr_i[17])
|
||||
`define USBF_MEM_SEL (wb_addr_i[17])
|
||||
`define USBF_SSRAM_HADR 14
|
||||
//`define USBF_ASYNC_RESET
|
||||
|
||||
`else
|
||||
// Modify this section to suit your implementation
|
||||
`define USBF_UFC_HADR 12
|
||||
// Address Decoding for Register File select
|
||||
`define USBF_RF_SEL (!wb_addr_i[12])
|
||||
// Address Decoding for Buffer Memory select
|
||||
`define USBF_MEM_SEL (wb_addr_i[12])
|
||||
`define USBF_SSRAM_HADR 9
|
||||
// The next statement determines if reset is async or sync.
|
||||
// If the define is uncommented the reset will be ASYNC.
|
||||
//`define USBF_ASYNC_RESET
|
||||
`endif
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Items below this point should NOT be modified by the end user
|
||||
// UNLESS you know exactly what you are doing !
|
||||
// Modify at you own risk !!!
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
// PID Encodings
|
||||
`define USBF_T_PID_OUT 4'b0001
|
||||
`define USBF_T_PID_IN 4'b1001
|
||||
`define USBF_T_PID_SOF 4'b0101
|
||||
`define USBF_T_PID_SETUP 4'b1101
|
||||
`define USBF_T_PID_DATA0 4'b0011
|
||||
`define USBF_T_PID_DATA1 4'b1011
|
||||
`define USBF_T_PID_DATA2 4'b0111
|
||||
`define USBF_T_PID_MDATA 4'b1111
|
||||
`define USBF_T_PID_ACK 4'b0010
|
||||
`define USBF_T_PID_NACK 4'b1010
|
||||
`define USBF_T_PID_STALL 4'b1110
|
||||
`define USBF_T_PID_NYET 4'b0110
|
||||
`define USBF_T_PID_PRE 4'b1100
|
||||
`define USBF_T_PID_ERR 4'b1100
|
||||
`define USBF_T_PID_SPLIT 4'b1000
|
||||
`define USBF_T_PID_PING 4'b0100
|
||||
`define USBF_T_PID_RES 4'b0000
|
||||
|
||||
// The HMS_DEL is a constant for the "Half Micro Second"
|
||||
// Clock pulse generator. This constant specifies how many
|
||||
// Phy clocks there are between two hms_clock pulses. This
|
||||
// constant plus 2 represents the actual delay.
|
||||
// Example: For a 60 Mhz (16.667 nS period) Phy Clock, the
|
||||
// delay must be 30 phy clocks: 500ns / 16.667nS = 30 clocks
|
||||
`define USBF_HMS_DEL 5'h1c
|
||||
|
||||
// After sending Data in response to an IN token from host, the
|
||||
// host must reply with an ack. The host has 622nS in Full Speed
|
||||
// mode and 400nS in High Speed mode to reply. RX_ACK_TO_VAL_FS
|
||||
// and RX_ACK_TO_VAL_HS are the numbers of UTMI clock cycles
|
||||
// minus 2 for Full and High Speed modes.
|
||||
`define USBF_RX_ACK_TO_VAL_FS 8'd36
|
||||
`define USBF_RX_ACK_TO_VAL_HS 8'd22
|
||||
|
||||
|
||||
// After sending an OUT token the host must send a data packet.
|
||||
// The host has 622nS in Full Speed mode and 400nS in High Speed
|
||||
// mode to send the data packet.
|
||||
// TX_DATA_TO_VAL_FS and TX_DATA_TO_VAL_HS are is the numbers of
|
||||
// UTMI clock cycles minus 2.
|
||||
`define USBF_TX_DATA_TO_VAL_FS 8'd36
|
||||
`define USBF_TX_DATA_TO_VAL_HS 8'd22
|
||||
|
||||
|
||||
// --------------------------------------------------
|
||||
// USB Line state & Speed Negotiation Time Values
|
||||
|
||||
|
||||
// Prescaler Clear value.
|
||||
// The prescaler generates a 0.25uS pulse, from a nominal PHY clock of
|
||||
// 60 Mhz. 250nS/16.667ns=15. The prescaler has to be cleared every 15
|
||||
// cycles. Due to the pipeline, subtract 2 from 15, resulting in 13 cycles.
|
||||
// !!! This is the only place that needs to be changed if a PHY with different
|
||||
// !!! clock output is used.
|
||||
`define USBF_T1_PS_250_NS 4'd13
|
||||
|
||||
// uS counter representation of 2.5uS (2.5/0.25=10)
|
||||
`define USBF_T1_C_2_5_US 8'd10
|
||||
|
||||
// uS counter clear value
|
||||
// The uS counter counts the time in 0.25uS intervals. It also generates
|
||||
// a count enable to the mS counter, every 62.5 uS.
|
||||
// The clear value is 62.5uS/0.25uS=250 cycles.
|
||||
`define USBF_T1_C_62_5_US 8'd250
|
||||
|
||||
// mS counter representation of 3.0mS (3.0/0.0625=48)
|
||||
`define USBF_T1_C_3_0_MS 8'd48
|
||||
|
||||
// mS counter representation of 3.125mS (3.125/0.0625=50)
|
||||
`define USBF_T1_C_3_125_MS 8'd50
|
||||
|
||||
// mS counter representation of 5mS (5/0.0625=80)
|
||||
`define USBF_T1_C_5_MS 8'd80
|
||||
|
||||
// Multi purpose Counter Prescaler, generate 2.5 uS period
|
||||
// 2500/16.667ns=150 (minus 2 for pipeline)
|
||||
`define USBF_T2_C_2_5_US 8'd148
|
||||
|
||||
// Generate 0.5mS period from the 2.5 uS clock
|
||||
// 500/2.5 = 200
|
||||
`define USBF_T2_C_0_5_MS 8'd200
|
||||
|
||||
// Indicate when internal wakeup has completed
|
||||
// me_cnt counts 0.5 mS intervals. E.g.: 5.0mS are (5/0.5) 10 ticks
|
||||
// Must be 0 =< 10 mS
|
||||
`define USBF_T2_C_WAKEUP 8'd10
|
||||
|
||||
// Indicate when 100uS have passed
|
||||
// me_ps2 counts 2.5uS intervals. 100uS are (100/2.5) 40 ticks
|
||||
`define USBF_T2_C_100_US 8'd40
|
||||
|
||||
// Indicate when 1.0 mS have passed
|
||||
// me_cnt counts 0.5 mS intervals. 1.0mS are (1/0.5) 2 ticks
|
||||
`define USBF_T2_C_1_0_MS 8'd2
|
||||
|
||||
// Indicate when 1.2 mS have passed
|
||||
// me_cnt counts 0.5 mS intervals. 1.2mS are (1.2/0.5) 2 ticks
|
||||
`define USBF_T2_C_1_2_MS 8'd2
|
||||
|
||||
// Indicate when 100 mS have passed
|
||||
// me_cnt counts 0.5 mS intervals. 100mS are (100/0.5) 200 ticks
|
||||
`define USBF_T2_C_100_MS 8'd200
|
||||
|
||||
@@ -0,0 +1,507 @@
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Endpoint register File ////
|
||||
//// This module contains all registers for ONE endpoint ////
|
||||
//// ////
|
||||
//// Author: Rudolf Usselmann ////
|
||||
//// rudi@asics.ws ////
|
||||
//// ////
|
||||
//// ////
|
||||
//// Downloaded from: http://www.opencores.org/cores/usb/ ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2000-2003 Rudolf Usselmann ////
|
||||
//// www.asics.ws ////
|
||||
//// rudi@asics.ws ////
|
||||
//// ////
|
||||
//// This source file may be used and distributed without ////
|
||||
//// restriction provided that this copyright statement is not ////
|
||||
//// removed from the file and that any derivative work contains ////
|
||||
//// the original copyright notice and the associated disclaimer.////
|
||||
//// ////
|
||||
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
|
||||
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
|
||||
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
|
||||
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
|
||||
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
|
||||
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
|
||||
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
|
||||
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
|
||||
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
|
||||
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
|
||||
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
|
||||
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
|
||||
//// POSSIBILITY OF SUCH DAMAGE. ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
// CVS Log
|
||||
//
|
||||
// $Id: usbf_ep_rf.v,v 1.4 2003-10-17 02:36:57 rudi Exp $
|
||||
//
|
||||
// $Date: 2003-10-17 02:36:57 $
|
||||
// $Revision: 1.4 $
|
||||
// $Author: rudi $
|
||||
// $Locker: $
|
||||
// $State: Exp $
|
||||
//
|
||||
// Change History:
|
||||
// $Log: not supported by cvs2svn $
|
||||
// Revision 1.3 2001/11/04 12:22:44 rudi
|
||||
//
|
||||
// - Fixed previous fix (brocke something else ...)
|
||||
// - Majore Synthesis cleanup
|
||||
//
|
||||
// Revision 1.2 2001/11/03 03:26:22 rudi
|
||||
//
|
||||
// - Fixed several interrupt and error condition reporting bugs
|
||||
//
|
||||
// Revision 1.1 2001/08/03 05:30:09 rudi
|
||||
//
|
||||
//
|
||||
// 1) Reorganized directory structure
|
||||
//
|
||||
// Revision 1.2 2001/03/31 13:00:51 rudi
|
||||
//
|
||||
// - Added Core configuration
|
||||
// - Added handling of OUT packets less than MAX_PL_SZ in DMA mode
|
||||
// - Modified WISHBONE interface and sync logic
|
||||
// - Moved SSRAM outside the core (added interface)
|
||||
// - Many small bug fixes ...
|
||||
//
|
||||
// Revision 1.0 2001/03/07 09:17:12 rudi
|
||||
//
|
||||
//
|
||||
// Changed all revisions to revision 1.0. This is because OpenCores CVS
|
||||
// interface could not handle the original '0.1' revision ....
|
||||
//
|
||||
// Revision 0.1.0.1 2001/02/28 08:10:44 rudi
|
||||
// Initial Release
|
||||
//
|
||||
//
|
||||
|
||||
`include "usbf_defines.v"
|
||||
|
||||
// Endpoint register File
|
||||
module usbf_ep_rf(clk, wclk, rst,
|
||||
|
||||
// Wishbone Interface
|
||||
adr, re, we, din, dout, inta, intb,
|
||||
dma_req, dma_ack,
|
||||
|
||||
// Internal Interface
|
||||
|
||||
idin,
|
||||
ep_sel, ep_match,
|
||||
buf0_rl, buf0_set, buf1_set,
|
||||
uc_bsel_set, uc_dpd_set,
|
||||
|
||||
int_buf1_set, int_buf0_set, int_upid_set,
|
||||
int_crc16_set, int_to_set, int_seqerr_set,
|
||||
out_to_small,
|
||||
|
||||
csr, buf0, buf1, dma_in_buf_sz1, dma_out_buf_avail
|
||||
);
|
||||
|
||||
input clk, wclk, rst;
|
||||
input [1:0] adr;
|
||||
input re;
|
||||
input we;
|
||||
input [31:0] din;
|
||||
output [31:0] dout;
|
||||
output inta, intb;
|
||||
output dma_req;
|
||||
input dma_ack;
|
||||
|
||||
input [31:0] idin; // Data Input
|
||||
input [3:0] ep_sel; // Endpoint Number Input
|
||||
output ep_match; // Asserted to indicate a ep no is matched
|
||||
input buf0_rl; // Reload Buf 0 with original values
|
||||
|
||||
input buf0_set; // Write to buf 0
|
||||
input buf1_set; // Write to buf 1
|
||||
input uc_bsel_set; // Write to the uc_bsel field
|
||||
input uc_dpd_set; // Write to the uc_dpd field
|
||||
input int_buf1_set; // Set buf1 full/empty interrupt
|
||||
input int_buf0_set; // Set buf0 full/empty interrupt
|
||||
input int_upid_set; // Set unsupported PID interrupt
|
||||
input int_crc16_set; // Set CRC16 error interrupt
|
||||
input int_to_set; // Set time out interrupt
|
||||
input int_seqerr_set; // Set PID sequence error interrupt
|
||||
input out_to_small; // OUT packet was to small for DMA operation
|
||||
|
||||
output [31:0] csr; // Internal CSR Output
|
||||
output [31:0] buf0; // Internal Buf 0 Output
|
||||
output [31:0] buf1; // Internal Buf 1 Output
|
||||
output dma_in_buf_sz1; // Indicates that the DMA IN buffer has 1 max_pl_sz
|
||||
// packet available
|
||||
output dma_out_buf_avail;// Indicates that there is space for at least
|
||||
// one MAX_PL_SZ packet in the buffer
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Local Wires and Registers
|
||||
//
|
||||
|
||||
reg [31:0] dout;
|
||||
|
||||
// CSR
|
||||
reg [12:0] csr0;
|
||||
reg ots_stop;
|
||||
reg [12:0] csr1;
|
||||
reg [1:0] uc_bsel, uc_dpd;
|
||||
|
||||
reg [5:0] iena, ienb; // Interrupt enables
|
||||
reg [6:0] int_stat; // Interrupt status
|
||||
|
||||
wire we0, we1, we2, we3;
|
||||
reg [31:0] buf0;
|
||||
reg [31:0] buf1;
|
||||
reg [31:0] buf0_orig;
|
||||
|
||||
reg inta, intb;
|
||||
|
||||
// DMA Logic Registers
|
||||
reg [11:0] dma_out_cnt;
|
||||
wire dma_out_cnt_is_zero;
|
||||
reg dma_out_buf_avail;
|
||||
reg [11:0] dma_out_left;
|
||||
|
||||
reg [11:0] dma_in_cnt;
|
||||
reg dma_in_buf_sz1;
|
||||
|
||||
reg dma_req_r;
|
||||
wire dma_req_d;
|
||||
wire dma_req_in_d;
|
||||
wire dma_req_out_d;
|
||||
reg r1, r2, r4, r5;
|
||||
wire dma_ack_i;
|
||||
reg dma_req_out_hold, dma_req_in_hold ;
|
||||
reg [11:0] buf0_orig_m3;
|
||||
wire dma_req_hold;
|
||||
reg set_r;
|
||||
reg ep_match_r;
|
||||
reg int_re;
|
||||
|
||||
// Aliases
|
||||
wire [31:0] csr;
|
||||
wire [31:0] int;
|
||||
wire dma_en;
|
||||
wire [10:0] max_pl_sz;
|
||||
wire ep_in;
|
||||
wire ep_out;
|
||||
|
||||
assign csr = {uc_bsel, uc_dpd, csr1, 1'h0, ots_stop, csr0};
|
||||
assign int = {2'h0, iena, 2'h0,ienb, 9'h0, int_stat};
|
||||
assign dma_en = csr[15];
|
||||
assign max_pl_sz = csr[10:0];
|
||||
assign ep_in = csr[27:26]==2'b01;
|
||||
assign ep_out = csr[27:26]==2'b10;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// WISHBONE Access
|
||||
//
|
||||
|
||||
always @(adr or csr or int or buf0 or buf1)
|
||||
case(adr) // synopsys full_case parallel_case
|
||||
2'h0: dout = csr;
|
||||
2'h1: dout = int;
|
||||
2'h2: dout = buf0;
|
||||
2'h3: dout = buf1;
|
||||
endcase
|
||||
|
||||
assign we0 = (adr==2'h0) & we;
|
||||
assign we1 = (adr==2'h1) & we;
|
||||
assign we2 = (adr==2'h2) & we;
|
||||
assign we3 = (adr==2'h3) & we;
|
||||
|
||||
// Endpoint CSR Register
|
||||
`ifdef USBF_ASYNC_RESET
|
||||
always @(posedge clk or negedge rst)
|
||||
`else
|
||||
always @(posedge clk)
|
||||
`endif
|
||||
if(!rst)
|
||||
begin
|
||||
csr0 <= 13'h0;
|
||||
csr1 <= 13'h0;
|
||||
ots_stop <= 1'b0;
|
||||
end
|
||||
else
|
||||
if(we0)
|
||||
begin
|
||||
csr0 <= din[12:0];
|
||||
ots_stop <= din[13];
|
||||
csr1 <= din[27:15];
|
||||
end
|
||||
else
|
||||
if(ots_stop && out_to_small)
|
||||
csr1[8:7] <= 2'b01;
|
||||
|
||||
// Endpoint Interrupt Register
|
||||
`ifdef USBF_ASYNC_RESET
|
||||
always @(posedge clk or negedge rst)
|
||||
`else
|
||||
always @(posedge clk)
|
||||
`endif
|
||||
if(!rst)
|
||||
begin
|
||||
ienb <= 6'h0;
|
||||
iena <= 6'h0;
|
||||
end
|
||||
else
|
||||
if(we1)
|
||||
begin
|
||||
ienb <= din[21:16];
|
||||
iena <= din[29:24];
|
||||
end
|
||||
|
||||
// Endpoint Buffer Registers
|
||||
`ifdef USBF_ASYNC_RESET
|
||||
always @(posedge clk or negedge rst)
|
||||
`else
|
||||
always @(posedge clk)
|
||||
`endif
|
||||
if(!rst) buf0 <= 32'hffff_ffff;
|
||||
else
|
||||
if(we2) buf0 <= din;
|
||||
else
|
||||
if(ep_match_r && buf0_rl) buf0 <= buf0_orig;
|
||||
else
|
||||
if(ep_match_r && buf0_set) buf0 <= idin;
|
||||
|
||||
`ifdef USBF_ASYNC_RESET
|
||||
always @(posedge clk or negedge rst)
|
||||
`else
|
||||
always @(posedge clk)
|
||||
`endif
|
||||
if(!rst) buf1 <= 32'hffff_ffff;
|
||||
else
|
||||
if(we3) buf1 <= din;
|
||||
else
|
||||
if(ep_match_r &&
|
||||
(buf1_set || out_to_small)) buf1 <= idin;
|
||||
|
||||
`ifdef USBF_ASYNC_RESET
|
||||
always @(posedge clk or negedge rst)
|
||||
`else
|
||||
always @(posedge clk)
|
||||
`endif
|
||||
if(!rst) buf0_orig <= 32'hffff_ffff;
|
||||
else
|
||||
if(we2) buf0_orig <= din;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Internal Access
|
||||
//
|
||||
|
||||
|
||||
// Indicates that this register file matches the current
|
||||
// endpoint from token
|
||||
assign ep_match = (ep_sel == csr[21:18]);
|
||||
|
||||
always @(posedge clk)
|
||||
ep_match_r <= ep_match;
|
||||
|
||||
always @(posedge clk)
|
||||
int_re <= re & (adr == 2'h1);
|
||||
|
||||
// Interrupt Sources
|
||||
`ifdef USBF_ASYNC_RESET
|
||||
always @(posedge clk or negedge rst)
|
||||
`else
|
||||
always @(posedge clk)
|
||||
`endif
|
||||
if(!rst) int_stat <= 7'h0;
|
||||
else
|
||||
if(int_re) int_stat <= 7'h0;
|
||||
else
|
||||
if(ep_match_r)
|
||||
begin
|
||||
if(out_to_small) int_stat[6] <= 1'b1;
|
||||
if(int_seqerr_set) int_stat[5] <= 1'b1;
|
||||
if(int_buf1_set) int_stat[4] <= 1'b1;
|
||||
if(int_buf0_set) int_stat[3] <= 1'b1;
|
||||
if(int_upid_set) int_stat[2] <= 1'b1;
|
||||
if(int_crc16_set) int_stat[1] <= 1'b1;
|
||||
if(int_to_set) int_stat[0] <= 1'b1;
|
||||
end
|
||||
|
||||
// PID toggle track bits
|
||||
`ifdef USBF_ASYNC_RESET
|
||||
always @(posedge clk or negedge rst)
|
||||
`else
|
||||
always @(posedge clk)
|
||||
`endif
|
||||
if(!rst) uc_dpd <= 2'h0;
|
||||
else
|
||||
if(ep_match_r && uc_dpd_set) uc_dpd <= idin[3:2];
|
||||
|
||||
// Buffer toggle track bits
|
||||
`ifdef USBF_ASYNC_RESET
|
||||
always @(posedge clk or negedge rst)
|
||||
`else
|
||||
always @(posedge clk)
|
||||
`endif
|
||||
if(!rst) uc_bsel <= 2'h0;
|
||||
else
|
||||
if(ep_match_r && uc_bsel_set) uc_bsel <= idin[1:0];
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Endpoint Interrupt Generation
|
||||
//
|
||||
|
||||
always @(posedge wclk)
|
||||
inta <= (int_stat[0] & iena[0]) |
|
||||
(int_stat[1] & iena[1]) |
|
||||
(int_stat[2] & iena[2]) |
|
||||
(int_stat[3] & iena[3]) |
|
||||
(int_stat[4] & iena[3]) |
|
||||
(int_stat[5] & iena[4]) |
|
||||
(int_stat[6] & iena[5]);
|
||||
|
||||
always @(posedge wclk)
|
||||
intb <= (int_stat[0] & ienb[0]) |
|
||||
(int_stat[1] & ienb[1]) |
|
||||
(int_stat[2] & ienb[2]) |
|
||||
(int_stat[3] & ienb[3]) |
|
||||
(int_stat[4] & ienb[3]) |
|
||||
(int_stat[5] & ienb[4]) |
|
||||
(int_stat[6] & ienb[5]);
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Endpoint DMA Request Logic
|
||||
//
|
||||
|
||||
// DMA OUT endpoint counter
|
||||
always @(posedge clk)
|
||||
if(!dma_en) dma_out_cnt <= 12'h0;
|
||||
else
|
||||
if(dma_ack_i) dma_out_cnt <= dma_out_cnt - 12'h1;
|
||||
else
|
||||
if(ep_match_r && (set_r || buf0_set || buf0_rl))
|
||||
dma_out_cnt <= dma_out_cnt + {3'h0, max_pl_sz[10:2]};
|
||||
|
||||
// If buf0_set or buf0_rl was asserted at the same time as dma_ack_i
|
||||
// remember it and perform the add next cycle ...
|
||||
always @(posedge clk)
|
||||
set_r <= dma_ack_i & (buf0_set | buf0_rl);
|
||||
|
||||
// This signal is used to keep dma_req asserted when we know there is
|
||||
// plenty of data in the buffer.
|
||||
// When the buffer is "low", we do one dma_req and wait to see if there
|
||||
// is more data and repeat until the buffer is empty.
|
||||
// This is because of the sync logic - it has to propagate first
|
||||
// before we can determine that the buffer is really empty.
|
||||
always @(posedge wclk)
|
||||
dma_req_out_hold <= |dma_out_cnt[11:2] & ep_out;
|
||||
|
||||
assign dma_out_cnt_is_zero = dma_out_cnt == 12'h0;
|
||||
|
||||
// DMA IN endpoint counter
|
||||
always @(posedge clk)
|
||||
if(!dma_en) dma_in_cnt <= 12'h0;
|
||||
else
|
||||
if(dma_ack_i) dma_in_cnt <= dma_in_cnt + 12'h1;
|
||||
else
|
||||
if(ep_match_r && (set_r || buf0_set || buf0_rl))
|
||||
dma_in_cnt <= dma_in_cnt - {3'h0, max_pl_sz[10:2]};
|
||||
|
||||
// Indicates to Protocol Engine when we have gotten at least one packet in to buffer
|
||||
// This is for IN transfers only
|
||||
always @(posedge clk)
|
||||
dma_in_buf_sz1 <= (dma_in_cnt >= {3'h0,max_pl_sz[10:2]}) &
|
||||
(max_pl_sz[10:0] != 11'h0);
|
||||
|
||||
// Indicates to Protocol Engine that there is space for at least one MAX_PL_SZ
|
||||
// packet in buffer. OUT transfers only.
|
||||
always @(posedge clk)
|
||||
dma_out_left <= (buf0_orig[30:19] - dma_out_cnt);
|
||||
|
||||
always @(posedge clk)
|
||||
dma_out_buf_avail <= (dma_out_left >= {3'h0, max_pl_sz[10:2]});
|
||||
|
||||
// DMA Request Generation
|
||||
assign dma_req_d = dma_en & (dma_req_in_d | dma_req_out_d);
|
||||
|
||||
// For OUT
|
||||
assign dma_req_out_d = ep_out & !dma_out_cnt_is_zero;
|
||||
|
||||
// FOR IN
|
||||
assign dma_req_in_d = ep_in & (dma_in_cnt < buf0_orig[30:19]);
|
||||
|
||||
|
||||
always @(posedge wclk)
|
||||
buf0_orig_m3 <= buf0_orig[30:19] - 12'h3;
|
||||
|
||||
reg dma_req_in_hold2;
|
||||
|
||||
always @(posedge wclk)
|
||||
dma_req_in_hold2 <= (dma_in_cnt < buf0_orig_m3);
|
||||
|
||||
always @(posedge wclk)
|
||||
dma_req_in_hold <= ep_in & |buf0_orig[30:21];
|
||||
|
||||
assign dma_req_hold = ep_out ? dma_req_out_hold : (dma_req_in_hold & dma_req_in_hold2);
|
||||
|
||||
// Generate a Sync. Request
|
||||
assign dma_req = dma_req_r;
|
||||
|
||||
`ifdef USBF_ASYNC_RESET
|
||||
always @(posedge wclk or negedge rst)
|
||||
`else
|
||||
always @(posedge wclk)
|
||||
`endif
|
||||
if(!rst) dma_req_r <= 1'b0;
|
||||
else
|
||||
if(r1 && !r2) dma_req_r <= 1'b1;
|
||||
else
|
||||
if(dma_ack && !dma_req_hold) dma_req_r <= 1'b0;
|
||||
|
||||
always @(posedge wclk)
|
||||
r1 <= dma_req_d & !r2 & !r4 & !r5;
|
||||
|
||||
`ifdef USBF_ASYNC_RESET
|
||||
always @(posedge wclk or negedge rst)
|
||||
`else
|
||||
always @(posedge wclk)
|
||||
`endif
|
||||
if(!rst) r2 <= 1'b0;
|
||||
else
|
||||
if(r1) r2 <= 1'b1;
|
||||
else
|
||||
if(r4) r2 <= 1'b0;
|
||||
|
||||
// Synchronize ACK
|
||||
reg dma_ack_wr1;
|
||||
reg dma_ack_clr1;
|
||||
|
||||
`ifdef USBF_ASYNC_RESET
|
||||
always @(posedge wclk or negedge rst)
|
||||
`else
|
||||
always @(posedge wclk)
|
||||
`endif
|
||||
if(!rst) dma_ack_wr1 <= 1'b0;
|
||||
else
|
||||
if(dma_ack) dma_ack_wr1 <= 1'b1;
|
||||
else
|
||||
if(dma_ack_clr1) dma_ack_wr1 <= 1'b0;
|
||||
|
||||
always @(posedge wclk)
|
||||
dma_ack_clr1 <= r4;
|
||||
|
||||
always @(posedge clk)
|
||||
r4 <= dma_ack_wr1;
|
||||
|
||||
always @(posedge clk)
|
||||
r5 <= r4;
|
||||
|
||||
assign dma_ack_i = r5;
|
||||
|
||||
endmodule
|
||||
|
||||
@@ -0,0 +1,143 @@
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Dummy Endpoint register File ////
|
||||
//// This module contains termination for registers in ONE ////
|
||||
//// endpoint. It is used to replace the actual endpoint ////
|
||||
//// register file for non existing endpoints. ////
|
||||
//// ////
|
||||
//// Author: Rudolf Usselmann ////
|
||||
//// rudi@asics.ws ////
|
||||
//// ////
|
||||
//// ////
|
||||
//// Downloaded from: http://www.opencores.org/cores/usb/ ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2000-2003 Rudolf Usselmann ////
|
||||
//// www.asics.ws ////
|
||||
//// rudi@asics.ws ////
|
||||
//// ////
|
||||
//// This source file may be used and distributed without ////
|
||||
//// restriction provided that this copyright statement is not ////
|
||||
//// removed from the file and that any derivative work contains ////
|
||||
//// the original copyright notice and the associated disclaimer.////
|
||||
//// ////
|
||||
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
|
||||
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
|
||||
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
|
||||
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
|
||||
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
|
||||
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
|
||||
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
|
||||
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
|
||||
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
|
||||
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
|
||||
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
|
||||
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
|
||||
//// POSSIBILITY OF SUCH DAMAGE. ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
// CVS Log
|
||||
//
|
||||
// $Id: usbf_ep_rf_dummy.v,v 1.2 2003-10-17 02:36:57 rudi Exp $
|
||||
//
|
||||
// $Date: 2003-10-17 02:36:57 $
|
||||
// $Revision: 1.2 $
|
||||
// $Author: rudi $
|
||||
// $Locker: $
|
||||
// $State: Exp $
|
||||
//
|
||||
// Change History:
|
||||
// $Log: not supported by cvs2svn $
|
||||
// Revision 1.1 2001/08/03 05:30:09 rudi
|
||||
//
|
||||
//
|
||||
// 1) Reorganized directory structure
|
||||
//
|
||||
// Revision 1.1 2001/03/31 12:45:13 rudi
|
||||
//
|
||||
// This is the endpoint register file for non existing endpoints. It will be used for
|
||||
// endpoints that are commented out in the usd_defines.v file.
|
||||
// It will terminate all outputs to a known good level ...
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
`include "usbf_defines.v"
|
||||
|
||||
// Endpoint register File
|
||||
module usbf_ep_rf_dummy(
|
||||
clk, wclk, rst,
|
||||
|
||||
// Wishbone Interface
|
||||
adr, re, we, din, dout, inta, intb,
|
||||
dma_req, dma_ack,
|
||||
|
||||
// Internal Interface
|
||||
|
||||
idin,
|
||||
ep_sel, ep_match,
|
||||
buf0_rl, buf0_set, buf1_set,
|
||||
uc_bsel_set, uc_dpd_set,
|
||||
|
||||
int_buf1_set, int_buf0_set, int_upid_set,
|
||||
int_crc16_set, int_to_set, int_seqerr_set,
|
||||
out_to_small,
|
||||
|
||||
csr, buf0, buf1, dma_in_buf_sz1, dma_out_buf_avail
|
||||
);
|
||||
|
||||
input clk, wclk, rst;
|
||||
input [1:0] adr;
|
||||
input re;
|
||||
input we;
|
||||
input [31:0] din;
|
||||
output [31:0] dout;
|
||||
output inta, intb;
|
||||
output dma_req;
|
||||
input dma_ack;
|
||||
|
||||
input [31:0] idin; // Data Input
|
||||
input [3:0] ep_sel; // Endpoint Number Input
|
||||
output ep_match; // Asserted to indicate a ep no is matched
|
||||
input buf0_rl; // Reload Buf 0 with original values
|
||||
|
||||
input buf0_set; // Write to buf 0
|
||||
input buf1_set; // Write to buf 1
|
||||
input uc_bsel_set; // Write to the uc_bsel field
|
||||
input uc_dpd_set; // Write to the uc_dpd field
|
||||
input int_buf1_set; // Set buf1 full/empty interrupt
|
||||
input int_buf0_set; // Set buf0 full/empty interrupt
|
||||
input int_upid_set; // Set unsupported PID interrupt
|
||||
input int_crc16_set; // Set CRC16 error interrupt
|
||||
input int_to_set; // Set time out interrupt
|
||||
input int_seqerr_set; // Set PID sequence error interrupt
|
||||
input out_to_small; // OUT packet was to small for DMA operation
|
||||
|
||||
output [31:0] csr; // Internal CSR Output
|
||||
output [31:0] buf0; // Internal Buf 0 Output
|
||||
output [31:0] buf1; // Internal Buf 1 Output
|
||||
output dma_in_buf_sz1; // Indicates that the DMA IN buffer has 1 max_pl_sz
|
||||
// packet available
|
||||
output dma_out_buf_avail;// Indicates that there is space for at least
|
||||
// one MAX_PL_SZ packet in the buffer
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Internal Access
|
||||
//
|
||||
|
||||
assign dout = 32'h0;
|
||||
assign inta = 1'b0;
|
||||
assign intb = 1'b0;
|
||||
assign dma_req = 1'b0;
|
||||
assign ep_match = 1'b0;
|
||||
assign csr = 32'h0;
|
||||
assign buf0 = 32'hffff_ffff;
|
||||
assign buf1 = 32'hffff_ffff;
|
||||
assign dma_in_buf_sz1 = 1'b0;
|
||||
assign dma_out_buf_avail = 1'b0;
|
||||
|
||||
endmodule
|
||||
|
||||
@@ -0,0 +1,627 @@
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Internal DMA Engine ////
|
||||
//// ////
|
||||
//// ////
|
||||
//// Author: Rudolf Usselmann ////
|
||||
//// rudi@asics.ws ////
|
||||
//// ////
|
||||
//// ////
|
||||
//// Downloaded from: http://www.opencores.org/cores/usb/ ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2000-2003 Rudolf Usselmann ////
|
||||
//// www.asics.ws ////
|
||||
//// rudi@asics.ws ////
|
||||
//// ////
|
||||
//// This source file may be used and distributed without ////
|
||||
//// restriction provided that this copyright statement is not ////
|
||||
//// removed from the file and that any derivative work contains ////
|
||||
//// the original copyright notice and the associated disclaimer.////
|
||||
//// ////
|
||||
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
|
||||
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
|
||||
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
|
||||
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
|
||||
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
|
||||
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
|
||||
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
|
||||
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
|
||||
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
|
||||
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
|
||||
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
|
||||
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
|
||||
//// POSSIBILITY OF SUCH DAMAGE. ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
// CVS Log
|
||||
//
|
||||
// $Id: usbf_idma.v,v 1.8 2003-10-17 02:36:57 rudi Exp $
|
||||
//
|
||||
// $Date: 2003-10-17 02:36:57 $
|
||||
// $Revision: 1.8 $
|
||||
// $Author: rudi $
|
||||
// $Locker: $
|
||||
// $State: Exp $
|
||||
//
|
||||
// Change History:
|
||||
// $Log: not supported by cvs2svn $
|
||||
// Revision 1.7 2001/11/04 12:22:45 rudi
|
||||
//
|
||||
// - Fixed previous fix (brocke something else ...)
|
||||
// - Majore Synthesis cleanup
|
||||
//
|
||||
// Revision 1.6 2001/11/03 03:26:22 rudi
|
||||
//
|
||||
// - Fixed several interrupt and error condition reporting bugs
|
||||
//
|
||||
// Revision 1.5 2001/09/24 01:15:28 rudi
|
||||
//
|
||||
// Changed reset to be active high async.
|
||||
//
|
||||
// Revision 1.4 2001/09/23 08:39:33 rudi
|
||||
//
|
||||
// Renamed DEBUG and VERBOSE_DEBUG to USBF_DEBUG and USBF_VERBOSE_DEBUG ...
|
||||
//
|
||||
// Revision 1.3 2001/09/19 14:38:57 rudi
|
||||
//
|
||||
// Fixed TxValid handling bug.
|
||||
//
|
||||
// Revision 1.2 2001/09/13 13:14:02 rudi
|
||||
//
|
||||
// Fixed a problem that would sometimes prevent the core to come out of
|
||||
// reset and immediately be operational ...
|
||||
//
|
||||
// Revision 1.1 2001/08/03 05:30:09 rudi
|
||||
//
|
||||
//
|
||||
// 1) Reorganized directory structure
|
||||
//
|
||||
// Revision 1.2 2001/03/31 13:00:51 rudi
|
||||
//
|
||||
// - Added Core configuration
|
||||
// - Added handling of OUT packets less than MAX_PL_SZ in DMA mode
|
||||
// - Modified WISHBONE interface and sync logic
|
||||
// - Moved SSRAM outside the core (added interface)
|
||||
// - Many small bug fixes ...
|
||||
//
|
||||
// Revision 1.0 2001/03/07 09:17:12 rudi
|
||||
//
|
||||
//
|
||||
// Changed all revisions to revision 1.0. This is because OpenCores CVS
|
||||
// interface could not handle the original '0.1' revision ....
|
||||
//
|
||||
// Revision 0.1.0.1 2001/02/28 08:10:50 rudi
|
||||
// Initial Release
|
||||
//
|
||||
//
|
||||
|
||||
`include "usbf_defines.v"
|
||||
|
||||
module usbf_idma( clk, rst,
|
||||
|
||||
// Packet Disassembler/Assembler interface
|
||||
rx_data_st, rx_data_valid, rx_data_done,
|
||||
send_data, tx_data_st, rd_next,
|
||||
|
||||
// Protocol Engine
|
||||
rx_dma_en, tx_dma_en,
|
||||
abort, idma_done,
|
||||
buf_size, dma_en,
|
||||
send_zero_length,
|
||||
|
||||
// Register File Manager Interface
|
||||
adr, size, sizu_c,
|
||||
|
||||
// Memory Arb interface
|
||||
madr, mdout, mdin, mwe, mreq, mack
|
||||
);
|
||||
|
||||
parameter SSRAM_HADR = 14;
|
||||
|
||||
// Packet Disassembler/Assembler interface
|
||||
input clk, rst;
|
||||
input [7:0] rx_data_st;
|
||||
input rx_data_valid;
|
||||
input rx_data_done;
|
||||
output send_data;
|
||||
output [7:0] tx_data_st;
|
||||
input rd_next;
|
||||
|
||||
// Protocol Engine
|
||||
input rx_dma_en; // Allows the data to be stored
|
||||
input tx_dma_en; // Allows for data to be retrieved
|
||||
input abort; // Abort Transfer (time_out, crc_err or rx_error)
|
||||
output idma_done; // DMA is done
|
||||
input [13:0] buf_size; // Actual buffer size
|
||||
input dma_en; // External DMA enabled
|
||||
input send_zero_length;
|
||||
|
||||
// Register File Manager Interface
|
||||
input [SSRAM_HADR + 2:0] adr; // Byte Address
|
||||
input [13:0] size; // Size in bytes
|
||||
output [10:0] sizu_c; // Up and Down counting size registers, used to update
|
||||
|
||||
// Memory Arb interface
|
||||
output [SSRAM_HADR:0] madr; // word address
|
||||
output [31:0] mdout;
|
||||
input [31:0] mdin;
|
||||
output mwe;
|
||||
output mreq;
|
||||
input mack;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Local Wires and Registers
|
||||
//
|
||||
|
||||
parameter [7:0] // synopsys enum state
|
||||
IDLE = 8'b00000001,
|
||||
WAIT_MRD = 8'b00000010,
|
||||
MEM_WR = 8'b00000100,
|
||||
MEM_WR1 = 8'b00001000,
|
||||
MEM_WR2 = 8'b00010000,
|
||||
MEM_RD1 = 8'b00100000,
|
||||
MEM_RD2 = 8'b01000000,
|
||||
MEM_RD3 = 8'b10000000;
|
||||
|
||||
reg [7:0] /* synopsys enum state */ state, next_state;
|
||||
// synopsys state_vector state
|
||||
|
||||
reg tx_dma_en_r, rx_dma_en_r;
|
||||
|
||||
reg [SSRAM_HADR:0] adr_cw; // Internal word address counter
|
||||
reg [2:0] adr_cb; // Internal byte address counter
|
||||
reg [SSRAM_HADR:0] adrw_next; // next address
|
||||
reg [SSRAM_HADR:0] adrw_next1; // next address (after overrun check)
|
||||
reg [SSRAM_HADR:0] last_buf_adr; // Last Buffer Address
|
||||
reg [2:0] adrb_next; // next byte address
|
||||
reg [13:0] sizd_c; // Internal size counter
|
||||
reg [10:0] sizu_c; // Internal size counter
|
||||
wire adr_incw;
|
||||
wire adr_incb;
|
||||
wire siz_dec;
|
||||
wire siz_inc;
|
||||
|
||||
reg word_done; // Indicates that a word has been
|
||||
// assembled
|
||||
reg mreq_d; // Memory request from State Machine
|
||||
reg [31:0] dtmp_r; // Temp data assembly register
|
||||
reg [31:0] dout_r; // Data output register
|
||||
reg mwe_d; // Memory Write enable
|
||||
reg dtmp_sel; // Selects tmp data register for pre-fetch
|
||||
|
||||
reg sizd_is_zero; // Indicates when all bytes have been
|
||||
// transferred
|
||||
wire sizd_is_zero_d;
|
||||
|
||||
reg [7:0] tx_data_st; // Data output to packet assembler
|
||||
reg [31:0] rd_buf0, rd_buf1; // Mem Rd. buffers for TX
|
||||
reg rd_first; // Indicates initial fill of buffers
|
||||
|
||||
reg idma_done; // DMA transfer is done
|
||||
|
||||
reg mack_r;
|
||||
wire send_data; // Enable UTMI Transmitter
|
||||
reg send_data_r;
|
||||
|
||||
reg word_done_r;
|
||||
reg wr_last;
|
||||
reg wr_last_en;
|
||||
reg wr_done;
|
||||
reg wr_done_r;
|
||||
reg dtmp_sel_r;
|
||||
reg mwe;
|
||||
reg rx_data_done_r2;
|
||||
wire fill_buf0, fill_buf1;
|
||||
wire adrb_is_3;
|
||||
|
||||
reg rx_data_done_r;
|
||||
reg rx_data_valid_r;
|
||||
reg [7:0] rx_data_st_r;
|
||||
|
||||
reg send_zero_length_r;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Memory Arb interface
|
||||
//
|
||||
|
||||
// Memory Request
|
||||
assign mreq = (mreq_d & !mack_r) | word_done_r;
|
||||
|
||||
// Output Data
|
||||
assign mdout = dout_r;
|
||||
|
||||
// Memory Address
|
||||
assign madr = adr_cw;
|
||||
|
||||
always @(posedge clk)
|
||||
mwe <= mwe_d;
|
||||
|
||||
always @(posedge clk)
|
||||
mack_r <= mreq & mack;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Misc Logic
|
||||
//
|
||||
|
||||
always @(posedge clk)
|
||||
rx_data_valid_r <= rx_data_valid;
|
||||
|
||||
always @(posedge clk)
|
||||
rx_data_st_r <= rx_data_st;
|
||||
|
||||
always @(posedge clk)
|
||||
rx_data_done_r <= rx_data_done;
|
||||
|
||||
always @(posedge clk)
|
||||
rx_data_done_r2 <= rx_data_done_r;
|
||||
|
||||
// Generate one cycle pulses for tx and rx dma enable
|
||||
always @(posedge clk)
|
||||
tx_dma_en_r <= tx_dma_en;
|
||||
|
||||
always @(posedge clk)
|
||||
rx_dma_en_r <= rx_dma_en;
|
||||
|
||||
always @(posedge clk)
|
||||
send_zero_length_r <= send_zero_length;
|
||||
|
||||
// address counter
|
||||
always @(posedge clk)
|
||||
if(rx_dma_en_r || tx_dma_en_r) adr_cw <= adr[SSRAM_HADR + 2:2];
|
||||
else adr_cw <= adrw_next1;
|
||||
|
||||
always @(posedge clk)
|
||||
last_buf_adr <= adr + { {SSRAM_HADR+2-13{1'b0}}, buf_size };
|
||||
|
||||
always @(dma_en or adrw_next or last_buf_adr)
|
||||
if(adrw_next == last_buf_adr && dma_en) adrw_next1 = {SSRAM_HADR+1{1'b0}};
|
||||
else adrw_next1 = adrw_next;
|
||||
|
||||
always @(adr_incw or adr_cw)
|
||||
if(adr_incw) adrw_next = adr_cw + {{SSRAM_HADR{1'b0}}, 1'b1};
|
||||
else adrw_next = adr_cw;
|
||||
|
||||
`ifdef USBF_ASYNC_RESET
|
||||
always @(posedge clk or negedge rst)
|
||||
`else
|
||||
always @(posedge clk)
|
||||
`endif
|
||||
if(!rst) adr_cb <= 3'h0;
|
||||
else
|
||||
if(rx_dma_en_r || tx_dma_en_r) adr_cb <= adr[2:0];
|
||||
else adr_cb <= adrb_next;
|
||||
|
||||
always @(adr_incb or adr_cb)
|
||||
if(adr_incb) adrb_next = adr_cb + 3'h1;
|
||||
else adrb_next = adr_cb;
|
||||
|
||||
assign adr_incb = rx_data_valid_r | rd_next;
|
||||
assign adr_incw = !dtmp_sel_r & mack_r;
|
||||
|
||||
// Size Counter (counting backward from input size)
|
||||
`ifdef USBF_ASYNC_RESET
|
||||
always @(posedge clk or negedge rst)
|
||||
`else
|
||||
always @(posedge clk)
|
||||
`endif
|
||||
if(!rst) sizd_c <= 14'h3fff;
|
||||
else
|
||||
if(tx_dma_en || tx_dma_en_r) sizd_c <= size;
|
||||
else
|
||||
if(siz_dec) sizd_c <= sizd_c - 14'h1;
|
||||
|
||||
assign siz_dec = (rd_first & mack_r) | (rd_next & (sizd_c != 14'h0));
|
||||
|
||||
assign sizd_is_zero_d = sizd_c == 14'h0;
|
||||
|
||||
always @(posedge clk)
|
||||
sizd_is_zero <= sizd_is_zero_d;
|
||||
|
||||
// Size Counter (counting up from zero)
|
||||
`ifdef USBF_ASYNC_RESET
|
||||
always @(posedge clk or negedge rst)
|
||||
`else
|
||||
always @(posedge clk)
|
||||
`endif
|
||||
if(!rst) sizu_c <= 11'h0;
|
||||
else
|
||||
// Do I need to add "abort" in the next line ???
|
||||
if(rx_dma_en_r) sizu_c <= 11'h0;
|
||||
else
|
||||
if(siz_inc) sizu_c <= sizu_c + 11'h1;
|
||||
|
||||
assign siz_inc = rx_data_valid_r;
|
||||
|
||||
// DMA Done Indicator
|
||||
always @(posedge clk)
|
||||
idma_done <= (rx_data_done_r | sizd_is_zero_d); // & !tx_dma_en;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// RX Logic
|
||||
//
|
||||
|
||||
always @(posedge clk)
|
||||
dtmp_sel_r <= dtmp_sel;
|
||||
|
||||
// Memory data input
|
||||
always @(posedge clk)
|
||||
if(dtmp_sel_r) dtmp_r <= mdin;
|
||||
else
|
||||
if(rx_data_valid_r)
|
||||
begin
|
||||
if(adr_cb[1:0] == 2'h0) dtmp_r[07:00] <= rx_data_st_r;
|
||||
if(adr_cb[1:0] == 2'h1) dtmp_r[15:08] <= rx_data_st_r;
|
||||
if(adr_cb[1:0] == 2'h2) dtmp_r[23:16] <= rx_data_st_r;
|
||||
if(adr_cb[1:0] == 2'h3) dtmp_r[31:24] <= rx_data_st_r;
|
||||
end
|
||||
|
||||
always @(posedge clk)
|
||||
word_done <= ((adr_cb[1:0] == 2'h3) & rx_data_valid_r) | wr_last;
|
||||
|
||||
always @(posedge clk)
|
||||
word_done_r <= word_done & !word_done_r;
|
||||
|
||||
// Store output data and address when we got a word
|
||||
always @(posedge clk)
|
||||
if(word_done) dout_r <= dtmp_r;
|
||||
|
||||
always @(posedge clk)
|
||||
wr_last <= (adr_cb[1:0] != 2'h0) & !rx_data_valid_r & wr_last_en;
|
||||
|
||||
always @(posedge clk)
|
||||
wr_done_r <= rx_data_done_r;
|
||||
|
||||
always @(posedge clk)
|
||||
wr_done <= wr_done_r;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TX Logic
|
||||
//
|
||||
|
||||
// Fill TX Buffers
|
||||
always @(posedge clk)
|
||||
if(fill_buf0) rd_buf0 <= mdin;
|
||||
|
||||
always @(posedge clk)
|
||||
if(fill_buf1) rd_buf1 <= mdin;
|
||||
|
||||
always @(adrb_next or rd_buf0 or rd_buf1)
|
||||
case(adrb_next[2:0]) // synopsys full_case parallel_case
|
||||
3'h0: tx_data_st = rd_buf0[07:00];
|
||||
3'h1: tx_data_st = rd_buf0[15:08];
|
||||
3'h2: tx_data_st = rd_buf0[23:16];
|
||||
3'h3: tx_data_st = rd_buf0[31:24];
|
||||
3'h4: tx_data_st = rd_buf1[07:00];
|
||||
3'h5: tx_data_st = rd_buf1[15:08];
|
||||
3'h6: tx_data_st = rd_buf1[23:16];
|
||||
3'h7: tx_data_st = rd_buf1[31:24];
|
||||
endcase
|
||||
|
||||
assign fill_buf0 = !adr_cw[0] & mack_r;
|
||||
assign fill_buf1 = adr_cw[0] & mack_r;
|
||||
|
||||
assign adrb_is_3 = adr_cb[1:0] == 2'h3;
|
||||
|
||||
`ifdef USBF_ASYNC_RESET
|
||||
always @(posedge clk or negedge rst)
|
||||
`else
|
||||
always @(posedge clk)
|
||||
`endif
|
||||
if(!rst) send_data_r <= 1'b0;
|
||||
else
|
||||
if(rd_first) send_data_r <= 1'b1;
|
||||
else
|
||||
if(((sizd_c==14'h1) && rd_next) || sizd_is_zero_d) send_data_r <= 1'b0;
|
||||
|
||||
assign send_data = send_data_r | send_zero_length_r;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IDMA Load/Store State Machine
|
||||
//
|
||||
|
||||
// store incoming data to memory until rx_data done
|
||||
// First pre-fetch data from memory, so that bytes can be stuffed properly
|
||||
|
||||
`ifdef USBF_ASYNC_RESET
|
||||
always @(posedge clk or negedge rst)
|
||||
`else
|
||||
always @(posedge clk)
|
||||
`endif
|
||||
if(!rst) state <= IDLE;
|
||||
else state <= next_state;
|
||||
|
||||
always @(state or mack_r or abort or rx_dma_en_r or tx_dma_en_r or
|
||||
sizd_is_zero or wr_last or wr_done or rx_data_done_r2 or
|
||||
rd_next or adrb_is_3 or send_zero_length_r)
|
||||
begin
|
||||
next_state = state; // Default do not change state
|
||||
mreq_d = 1'b0;
|
||||
mwe_d = 1'b0;
|
||||
rd_first = 1'b0;
|
||||
dtmp_sel = 1'b0;
|
||||
wr_last_en = 1'b0;
|
||||
|
||||
case(state) // synopsys full_case parallel_case
|
||||
IDLE:
|
||||
begin
|
||||
|
||||
// synopsys translate_off
|
||||
`ifdef USBF_VERBOSE_DEBUG
|
||||
$display("IDMA: Entered IDLE state (%t)", $time);
|
||||
`endif
|
||||
`ifdef USBF_DEBUG
|
||||
if(rst)
|
||||
begin
|
||||
if(rx_dma_en_r === 1'bx) $display("ERROR: IDMA: IDLE: rx_dma_en_r is unknown. (%t)", $time);
|
||||
if(tx_dma_en_r === 1'bx) $display("ERROR: IDMA: IDLE: tx_dma_en_r is unknown. (%t)", $time);
|
||||
if(abort === 1'bx) $display("ERROR: IDMA: IDLE: abort is unknown. (%t)", $time);
|
||||
end
|
||||
`endif
|
||||
// synopsys translate_on
|
||||
|
||||
if(rx_dma_en_r && !abort)
|
||||
begin
|
||||
next_state = WAIT_MRD;
|
||||
end
|
||||
if(tx_dma_en_r && !abort && !send_zero_length_r)
|
||||
begin
|
||||
next_state = MEM_RD1;
|
||||
end
|
||||
end
|
||||
|
||||
WAIT_MRD: // Pre-fetch a word from memory
|
||||
begin
|
||||
|
||||
// synopsys translate_off
|
||||
`ifdef USBF_VERBOSE_DEBUG
|
||||
$display("IDMA: Entered WAIT_MRD state (%t)", $time);
|
||||
`endif
|
||||
`ifdef USBF_DEBUG
|
||||
if(abort === 1'bx) $display("ERROR: IDMA: WAIT_MRD: abort is unknown. (%t)", $time);
|
||||
if(mack_r === 1'bx) $display("ERROR: IDMA: WAIT_MRD: mack_r is unknown. (%t)", $time);
|
||||
`endif
|
||||
// synopsys translate_on
|
||||
|
||||
if(abort) next_state = IDLE;
|
||||
else
|
||||
if(mack_r) next_state = MEM_WR;
|
||||
else
|
||||
begin
|
||||
dtmp_sel = 1'b1;
|
||||
mreq_d = 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
MEM_WR:
|
||||
begin
|
||||
|
||||
// synopsys translate_off
|
||||
`ifdef USBF_VERBOSE_DEBUG
|
||||
$display("IDMA: Entered MEM_WR state (%t)", $time);
|
||||
`endif
|
||||
`ifdef USBF_DEBUG
|
||||
if(abort === 1'bx) $display("ERROR: IDMA: MEM_WR: abort is unknown. (%t)", $time);
|
||||
if(rx_data_done_r2 === 1'bx) $display("ERROR: IDMA: MEM_WR: rx_data_done_r2 is unknown. (%t)", $time);
|
||||
`endif
|
||||
// synopsys translate_on
|
||||
|
||||
mwe_d = 1'b1;
|
||||
if(abort) next_state = IDLE;
|
||||
else
|
||||
if(rx_data_done_r2)
|
||||
begin
|
||||
wr_last_en = 1'b1;
|
||||
next_state = MEM_WR1;
|
||||
end
|
||||
|
||||
end
|
||||
MEM_WR1:
|
||||
begin
|
||||
|
||||
// synopsys translate_off
|
||||
`ifdef USBF_VERBOSE_DEBUG
|
||||
$display("IDMA: Entered MEM_WR1 state (%t)", $time);
|
||||
`endif
|
||||
`ifdef USBF_DEBUG
|
||||
if(abort === 1'bx) $display("ERROR: IDMA: MEM_WR1: abort is unknown. (%t)", $time);
|
||||
if(wr_last === 1'bx) $display("ERROR: IDMA: MEM_WR1: wr_last is unknown. (%t)", $time);
|
||||
if(wr_done === 1'bx) $display("ERROR: IDMA: MEM_WR1: wr_done is unknown. (%t)", $time);
|
||||
`endif
|
||||
// synopsys translate_on
|
||||
|
||||
mwe_d = 1'b1;
|
||||
wr_last_en = 1'b1;
|
||||
if(abort) next_state = IDLE;
|
||||
else
|
||||
if(wr_last) next_state = MEM_WR2;
|
||||
else
|
||||
if(wr_done) next_state = IDLE;
|
||||
end
|
||||
|
||||
MEM_WR2:
|
||||
begin
|
||||
|
||||
// synopsys translate_off
|
||||
`ifdef USBF_VERBOSE_DEBUG
|
||||
$display("IDMA: Entered MEM_WR2 state (%t)", $time);
|
||||
`endif
|
||||
`ifdef USBF_DEBUG
|
||||
if(mack_r === 1'bx) $display("ERROR: IDMA: MEM_WR2: mack_r is unknown. (%t)", $time);
|
||||
`endif
|
||||
// synopsys translate_on
|
||||
|
||||
mwe_d = 1'b1;
|
||||
if(mack_r) next_state = IDLE;
|
||||
end
|
||||
|
||||
MEM_RD1:
|
||||
begin
|
||||
|
||||
// synopsys translate_off
|
||||
`ifdef USBF_VERBOSE_DEBUG
|
||||
$display("IDMA: Entered MEM_RD1 state (%t)", $time);
|
||||
`endif
|
||||
`ifdef USBF_DEBUG
|
||||
if(abort === 1'bx) $display("ERROR: IDMA: MEM_RD1: abort is unknown. (%t)", $time);
|
||||
if(mack_r === 1'bx) $display("ERROR: IDMA: MEM_RD1: mack_r is unknown. (%t)", $time);
|
||||
`endif
|
||||
// synopsys translate_on
|
||||
|
||||
mreq_d = 1'b1;
|
||||
if(mack_r) rd_first = 1'b1;
|
||||
if(abort) next_state = IDLE;
|
||||
else
|
||||
if(mack_r) next_state = MEM_RD2;
|
||||
end
|
||||
MEM_RD2:
|
||||
begin
|
||||
|
||||
// synopsys translate_off
|
||||
`ifdef USBF_VERBOSE_DEBUG
|
||||
$display("IDMA: Entered MEM_RD2 state (%t)", $time);
|
||||
`endif
|
||||
`ifdef USBF_DEBUG
|
||||
if(abort === 1'bx) $display("ERROR: IDMA: MEM_RD2: abort is unknown. (%t)", $time);
|
||||
if(mack_r === 1'bx) $display("ERROR: IDMA: MEM_RD2: mack_r is unknown. (%t)", $time);
|
||||
`endif
|
||||
// synopsys translate_on
|
||||
|
||||
mreq_d = 1'b1;
|
||||
if(abort) next_state = IDLE;
|
||||
else
|
||||
if(mack_r) next_state = MEM_RD3;
|
||||
end
|
||||
MEM_RD3:
|
||||
begin
|
||||
|
||||
// synopsys translate_off
|
||||
`ifdef USBF_VERBOSE_DEBUG
|
||||
$display("IDMA: Entered MEM_RD3 state (%t)", $time);
|
||||
`endif
|
||||
`ifdef USBF_DEBUG
|
||||
if(abort === 1'bx) $display("ERROR: IDMA: MEM_RD3: abort is unknown. (%t)", $time);
|
||||
if(sizd_is_zero===1'bx) $display("ERROR: IDMA: MEM_RD3: sizd_is_zero is unknown. (%t)", $time);
|
||||
if(adrb_is_3 === 1'bx) $display("ERROR: IDMA: MEM_RD3: adrb_is_3 is unknown. (%t)", $time);
|
||||
if(rd_next === 1'bx) $display("ERROR: IDMA: MEM_RD3: rd_next is unknown. (%t)", $time);
|
||||
`endif
|
||||
// synopsys translate_on
|
||||
|
||||
if(sizd_is_zero || abort) next_state = IDLE;
|
||||
else
|
||||
if(adrb_is_3 && rd_next) next_state = MEM_RD2;
|
||||
end
|
||||
endcase
|
||||
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
@@ -0,0 +1,187 @@
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Memory Buffer Arbiter ////
|
||||
//// Arbitrates between the internal DMA and external bus ////
|
||||
//// interface for the internal buffer memory ////
|
||||
//// ////
|
||||
//// Author: Rudolf Usselmann ////
|
||||
//// rudi@asics.ws ////
|
||||
//// ////
|
||||
//// ////
|
||||
//// Downloaded from: http://www.opencores.org/cores/usb/ ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2000-2003 Rudolf Usselmann ////
|
||||
//// www.asics.ws ////
|
||||
//// rudi@asics.ws ////
|
||||
//// ////
|
||||
//// This source file may be used and distributed without ////
|
||||
//// restriction provided that this copyright statement is not ////
|
||||
//// removed from the file and that any derivative work contains ////
|
||||
//// the original copyright notice and the associated disclaimer.////
|
||||
//// ////
|
||||
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
|
||||
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
|
||||
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
|
||||
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
|
||||
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
|
||||
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
|
||||
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
|
||||
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
|
||||
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
|
||||
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
|
||||
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
|
||||
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
|
||||
//// POSSIBILITY OF SUCH DAMAGE. ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
// CVS Log
|
||||
//
|
||||
// $Id: usbf_mem_arb.v,v 1.3 2003-10-17 02:36:57 rudi Exp $
|
||||
//
|
||||
// $Date: 2003-10-17 02:36:57 $
|
||||
// $Revision: 1.3 $
|
||||
// $Author: rudi $
|
||||
// $Locker: $
|
||||
// $State: Exp $
|
||||
//
|
||||
// Change History:
|
||||
// $Log: not supported by cvs2svn $
|
||||
// Revision 1.2 2001/11/04 12:22:45 rudi
|
||||
//
|
||||
// - Fixed previous fix (brocke something else ...)
|
||||
// - Majore Synthesis cleanup
|
||||
//
|
||||
// Revision 1.1 2001/08/03 05:30:09 rudi
|
||||
//
|
||||
//
|
||||
// 1) Reorganized directory structure
|
||||
//
|
||||
// Revision 1.2 2001/03/31 13:00:51 rudi
|
||||
//
|
||||
// - Added Core configuration
|
||||
// - Added handling of OUT packets less than MAX_PL_SZ in DMA mode
|
||||
// - Modified WISHBONE interface and sync logic
|
||||
// - Moved SSRAM outside the core (added interface)
|
||||
// - Many small bug fixes ...
|
||||
//
|
||||
// Revision 1.0 2001/03/07 09:17:12 rudi
|
||||
//
|
||||
//
|
||||
// Changed all revisions to revision 1.0. This is because OpenCores CVS
|
||||
// interface could not handle the original '0.1' revision ....
|
||||
//
|
||||
// Revision 0.1.0.1 2001/02/28 08:10:52 rudi
|
||||
// Initial Release
|
||||
//
|
||||
//
|
||||
|
||||
`include "usbf_defines.v"
|
||||
|
||||
module usbf_mem_arb( phy_clk, wclk, rst,
|
||||
|
||||
// SSRAM Interface
|
||||
sram_adr, sram_din, sram_dout, sram_re, sram_we,
|
||||
|
||||
// IDMA Memory Interface
|
||||
madr, mdout, mdin, mwe, mreq, mack,
|
||||
|
||||
// WISHBONE Memory Interface
|
||||
wadr, wdout, wdin, wwe, wreq, wack
|
||||
|
||||
);
|
||||
|
||||
parameter SSRAM_HADR = 14;
|
||||
|
||||
input phy_clk, wclk, rst;
|
||||
|
||||
output [SSRAM_HADR:0] sram_adr;
|
||||
input [31:0] sram_din;
|
||||
output [31:0] sram_dout;
|
||||
output sram_re, sram_we;
|
||||
|
||||
input [SSRAM_HADR:0] madr;
|
||||
output [31:0] mdout;
|
||||
input [31:0] mdin;
|
||||
input mwe;
|
||||
input mreq;
|
||||
output mack;
|
||||
|
||||
input [SSRAM_HADR:0] wadr;
|
||||
output [31:0] wdout;
|
||||
input [31:0] wdin;
|
||||
input wwe;
|
||||
input wreq;
|
||||
output wack;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Local Wires and Registers
|
||||
//
|
||||
|
||||
wire wsel;
|
||||
reg [SSRAM_HADR:0] sram_adr;
|
||||
reg [31:0] sram_dout;
|
||||
reg sram_we;
|
||||
wire mack;
|
||||
wire mcyc;
|
||||
reg wack_r;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Memory Arbiter Logic
|
||||
//
|
||||
|
||||
// IDMA has always first priority
|
||||
|
||||
// -----------------------------------------
|
||||
// Ctrl Signals
|
||||
|
||||
assign wsel = (wreq | wack) & !mreq;
|
||||
|
||||
// -----------------------------------------
|
||||
// SSRAM Specific
|
||||
// Data Path
|
||||
always @(wsel or wdin or mdin)
|
||||
if(wsel) sram_dout = wdin;
|
||||
else sram_dout = mdin;
|
||||
|
||||
// Address Path
|
||||
always @(wsel or wadr or madr)
|
||||
if(wsel) sram_adr = wadr;
|
||||
else sram_adr = madr;
|
||||
|
||||
// Write Enable Path
|
||||
always @(wsel or wwe or wreq or mwe or mcyc)
|
||||
if(wsel) sram_we = wreq & wwe;
|
||||
else sram_we = mwe & mcyc;
|
||||
|
||||
assign sram_re = 1'b1;
|
||||
|
||||
// -----------------------------------------
|
||||
// IDMA specific
|
||||
|
||||
assign mdout = sram_din;
|
||||
|
||||
assign mack = mreq;
|
||||
|
||||
assign mcyc = mack; // Qualifier for writes
|
||||
|
||||
// -----------------------------------------
|
||||
// WISHBONE specific
|
||||
assign wdout = sram_din;
|
||||
|
||||
assign wack = wack_r & !mreq;
|
||||
|
||||
`ifdef USBF_ASYNC_RESET
|
||||
always @(posedge phy_clk or negedge rst)
|
||||
`else
|
||||
always @(posedge phy_clk)
|
||||
`endif
|
||||
if(!rst) wack_r <= 1'b0;
|
||||
else wack_r <= wreq & !mreq & !wack;
|
||||
|
||||
endmodule
|
||||
|
||||
@@ -0,0 +1,377 @@
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Packet Assembler ////
|
||||
//// Assembles Token and Data USB packets ////
|
||||
//// ////
|
||||
//// Author: Rudolf Usselmann ////
|
||||
//// rudi@asics.ws ////
|
||||
//// ////
|
||||
//// ////
|
||||
//// Downloaded from: http://www.opencores.org/cores/usb/ ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2000-2003 Rudolf Usselmann ////
|
||||
//// www.asics.ws ////
|
||||
//// rudi@asics.ws ////
|
||||
//// ////
|
||||
//// This source file may be used and distributed without ////
|
||||
//// restriction provided that this copyright statement is not ////
|
||||
//// removed from the file and that any derivative work contains ////
|
||||
//// the original copyright notice and the associated disclaimer.////
|
||||
//// ////
|
||||
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
|
||||
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
|
||||
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
|
||||
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
|
||||
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
|
||||
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
|
||||
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
|
||||
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
|
||||
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
|
||||
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
|
||||
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
|
||||
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
|
||||
//// POSSIBILITY OF SUCH DAMAGE. ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
// CVS Log
|
||||
//
|
||||
// $Id: usbf_pa.v,v 1.6 2003-10-17 02:36:57 rudi Exp $
|
||||
//
|
||||
// $Date: 2003-10-17 02:36:57 $
|
||||
// $Revision: 1.6 $
|
||||
// $Author: rudi $
|
||||
// $Locker: $
|
||||
// $State: Exp $
|
||||
//
|
||||
// Change History:
|
||||
// $Log: not supported by cvs2svn $
|
||||
// Revision 1.5 2001/11/04 12:22:45 rudi
|
||||
//
|
||||
// - Fixed previous fix (brocke something else ...)
|
||||
// - Majore Synthesis cleanup
|
||||
//
|
||||
// Revision 1.4 2001/09/24 01:15:28 rudi
|
||||
//
|
||||
// Changed reset to be active high async.
|
||||
//
|
||||
// Revision 1.3 2001/09/19 14:38:57 rudi
|
||||
//
|
||||
// Fixed TxValid handling bug.
|
||||
//
|
||||
// Revision 1.2 2001/08/10 08:48:33 rudi
|
||||
//
|
||||
// - Changed IO names to be more clear.
|
||||
// - Uniquifyed define names to be core specific.
|
||||
//
|
||||
// Revision 1.1 2001/08/03 05:30:09 rudi
|
||||
//
|
||||
//
|
||||
// 1) Reorganized directory structure
|
||||
//
|
||||
// Revision 1.0 2001/03/07 09:17:12 rudi
|
||||
//
|
||||
//
|
||||
// Changed all revisions to revision 1.0. This is because OpenCores CVS
|
||||
// interface could not handle the original '0.1' revision ....
|
||||
//
|
||||
// Revision 0.1.0.1 2001/02/28 08:10:54 rudi
|
||||
// Initial Release
|
||||
//
|
||||
//
|
||||
|
||||
`include "usbf_defines.v"
|
||||
|
||||
module usbf_pa( clk, rst,
|
||||
|
||||
// UTMI TX I/F
|
||||
tx_data, tx_valid, tx_valid_last, tx_ready,
|
||||
tx_first,
|
||||
|
||||
// Protocol Engine Interface
|
||||
send_token, token_pid_sel,
|
||||
send_data, data_pid_sel,
|
||||
send_zero_length,
|
||||
|
||||
// IDMA Interface
|
||||
tx_data_st, rd_next
|
||||
);
|
||||
|
||||
input clk, rst;
|
||||
|
||||
// UTMI TX Interface
|
||||
output [7:0] tx_data;
|
||||
output tx_valid;
|
||||
output tx_valid_last;
|
||||
input tx_ready;
|
||||
output tx_first;
|
||||
|
||||
// Protocol Engine Interface
|
||||
input send_token;
|
||||
input [1:0] token_pid_sel;
|
||||
input send_data;
|
||||
input [1:0] data_pid_sel;
|
||||
input send_zero_length;
|
||||
|
||||
// IDMA Interface
|
||||
input [7:0] tx_data_st;
|
||||
output rd_next;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Local Wires and Registers
|
||||
//
|
||||
|
||||
parameter [4:0] // synopsys enum state
|
||||
IDLE = 5'b00001,
|
||||
DATA = 5'b00010,
|
||||
CRC1 = 5'b00100,
|
||||
CRC2 = 5'b01000,
|
||||
WAIT = 5'b10000;
|
||||
|
||||
reg [4:0] /* synopsys enum state */ state, next_state;
|
||||
// synopsys state_vector state
|
||||
|
||||
reg last;
|
||||
reg rd_next;
|
||||
|
||||
reg [7:0] token_pid, data_pid; // PIDs from selectors
|
||||
reg [7:0] tx_data_d;
|
||||
reg [7:0] tx_data_data;
|
||||
reg dsel;
|
||||
reg tx_valid_d;
|
||||
reg send_token_r;
|
||||
reg [7:0] tx_spec_data;
|
||||
reg crc_sel1, crc_sel2;
|
||||
reg tx_first_r;
|
||||
reg send_data_r;
|
||||
wire crc16_clr;
|
||||
reg [15:0] crc16;
|
||||
wire [15:0] crc16_next;
|
||||
wire [15:0] crc16_rev;
|
||||
wire crc16_add;
|
||||
reg send_data_r2;
|
||||
reg tx_valid_r;
|
||||
reg tx_valid_r1;
|
||||
reg zero_length_r;
|
||||
reg send_zero_length_r;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Misc Logic
|
||||
//
|
||||
|
||||
always @(posedge clk)
|
||||
send_zero_length_r <= send_zero_length;
|
||||
|
||||
`ifdef USBF_ASYNC_RESET
|
||||
always @(posedge clk or negedge rst)
|
||||
`else
|
||||
always @(posedge clk)
|
||||
`endif
|
||||
if(!rst) zero_length_r <= 1'b0;
|
||||
else
|
||||
if(last) zero_length_r <= 1'b0;
|
||||
else
|
||||
if(crc16_clr) zero_length_r <= send_zero_length_r;
|
||||
|
||||
always @(posedge clk)
|
||||
tx_valid_r1 <= tx_valid;
|
||||
|
||||
always @(posedge clk)
|
||||
tx_valid_r <= tx_valid_r1;
|
||||
|
||||
`ifdef USBF_ASYNC_RESET
|
||||
always @(posedge clk or negedge rst)
|
||||
`else
|
||||
always @(posedge clk)
|
||||
`endif
|
||||
if(!rst) send_token_r <= 1'b0;
|
||||
else
|
||||
if(send_token) send_token_r <= 1'b1;
|
||||
else
|
||||
if(tx_ready) send_token_r <= 1'b0;
|
||||
|
||||
// PID Select
|
||||
always @(token_pid_sel)
|
||||
case(token_pid_sel) // synopsys full_case parallel_case
|
||||
2'd0: token_pid = { ~`USBF_T_PID_ACK, `USBF_T_PID_ACK};
|
||||
2'd1: token_pid = { ~`USBF_T_PID_NACK, `USBF_T_PID_NACK};
|
||||
2'd2: token_pid = {~`USBF_T_PID_STALL, `USBF_T_PID_STALL};
|
||||
2'd3: token_pid = { ~`USBF_T_PID_NYET, `USBF_T_PID_NYET};
|
||||
endcase
|
||||
|
||||
always @(data_pid_sel)
|
||||
case(data_pid_sel) // synopsys full_case parallel_case
|
||||
2'd0: data_pid = { ~`USBF_T_PID_DATA0, `USBF_T_PID_DATA0};
|
||||
2'd1: data_pid = { ~`USBF_T_PID_DATA1, `USBF_T_PID_DATA1};
|
||||
2'd2: data_pid = { ~`USBF_T_PID_DATA2, `USBF_T_PID_DATA2};
|
||||
2'd3: data_pid = { ~`USBF_T_PID_MDATA, `USBF_T_PID_MDATA};
|
||||
endcase
|
||||
|
||||
// Data path Muxes
|
||||
|
||||
always @(send_token or send_token_r or token_pid or tx_data_data)
|
||||
if(send_token || send_token_r) tx_data_d = token_pid;
|
||||
else tx_data_d = tx_data_data;
|
||||
|
||||
always @(dsel or tx_data_st or tx_spec_data)
|
||||
if(dsel) tx_data_data = tx_spec_data;
|
||||
else tx_data_data = tx_data_st;
|
||||
|
||||
always @(crc_sel1 or crc_sel2 or data_pid or crc16_rev)
|
||||
if(!crc_sel1 && !crc_sel2) tx_spec_data = data_pid;
|
||||
else
|
||||
if(crc_sel1) tx_spec_data = crc16_rev[15:8]; // CRC 1
|
||||
else tx_spec_data = crc16_rev[7:0]; // CRC 2
|
||||
|
||||
assign tx_data = tx_data_d;
|
||||
|
||||
// TX Valid assignment
|
||||
assign tx_valid_last = send_token | last;
|
||||
assign tx_valid = tx_valid_d;
|
||||
|
||||
always @(posedge clk)
|
||||
tx_first_r <= send_token | send_data;
|
||||
|
||||
assign tx_first = (send_token | send_data) & ! tx_first_r;
|
||||
|
||||
// CRC Logic
|
||||
always @(posedge clk)
|
||||
send_data_r <= send_data;
|
||||
|
||||
always @(posedge clk)
|
||||
send_data_r2 <= send_data_r;
|
||||
|
||||
assign crc16_clr = send_data & !send_data_r;
|
||||
|
||||
assign crc16_add = !zero_length_r & (send_data_r & !send_data_r2) | (rd_next & !crc_sel1);
|
||||
|
||||
always @(posedge clk)
|
||||
if(crc16_clr) crc16 <= 16'hffff;
|
||||
else
|
||||
if(crc16_add) crc16 <= crc16_next;
|
||||
|
||||
|
||||
usbf_crc16 u1(
|
||||
.crc_in( crc16 ),
|
||||
.din( {tx_data_st[0], tx_data_st[1],
|
||||
tx_data_st[2], tx_data_st[3],
|
||||
tx_data_st[4], tx_data_st[5],
|
||||
tx_data_st[6], tx_data_st[7]} ),
|
||||
.crc_out( crc16_next ) );
|
||||
|
||||
assign crc16_rev[15] = ~crc16[8];
|
||||
assign crc16_rev[14] = ~crc16[9];
|
||||
assign crc16_rev[13] = ~crc16[10];
|
||||
assign crc16_rev[12] = ~crc16[11];
|
||||
assign crc16_rev[11] = ~crc16[12];
|
||||
assign crc16_rev[10] = ~crc16[13];
|
||||
assign crc16_rev[9] = ~crc16[14];
|
||||
assign crc16_rev[8] = ~crc16[15];
|
||||
assign crc16_rev[7] = ~crc16[0];
|
||||
assign crc16_rev[6] = ~crc16[1];
|
||||
assign crc16_rev[5] = ~crc16[2];
|
||||
assign crc16_rev[4] = ~crc16[3];
|
||||
assign crc16_rev[3] = ~crc16[4];
|
||||
assign crc16_rev[2] = ~crc16[5];
|
||||
assign crc16_rev[1] = ~crc16[6];
|
||||
assign crc16_rev[0] = ~crc16[7];
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Transmit/Encode state machine
|
||||
//
|
||||
|
||||
`ifdef USBF_ASYNC_RESET
|
||||
always @(posedge clk or negedge rst)
|
||||
`else
|
||||
always @(posedge clk)
|
||||
`endif
|
||||
if(!rst) state <= IDLE;
|
||||
else state <= next_state;
|
||||
|
||||
always @(state or send_data or tx_ready or tx_valid_r or send_zero_length_r)
|
||||
begin
|
||||
next_state = state; // Default don't change current state
|
||||
tx_valid_d = 1'b0;
|
||||
dsel = 1'b0;
|
||||
rd_next = 1'b0;
|
||||
last = 1'b0;
|
||||
crc_sel1 = 1'b0;
|
||||
crc_sel2 = 1'b0;
|
||||
case(state) // synopsys full_case parallel_case
|
||||
IDLE:
|
||||
begin
|
||||
if(send_zero_length_r && send_data)
|
||||
begin
|
||||
tx_valid_d = 1'b1;
|
||||
next_state = WAIT;
|
||||
dsel = 1'b1;
|
||||
end
|
||||
else
|
||||
if(send_data) // Send DATA packet
|
||||
begin
|
||||
tx_valid_d = 1'b1;
|
||||
next_state = DATA;
|
||||
dsel = 1'b1;
|
||||
end
|
||||
end
|
||||
DATA:
|
||||
begin
|
||||
if(tx_ready && tx_valid_r)
|
||||
rd_next = 1'b1;
|
||||
|
||||
tx_valid_d = 1'b1;
|
||||
if(!send_data && tx_ready && tx_valid_r)
|
||||
begin
|
||||
dsel = 1'b1;
|
||||
crc_sel1 = 1'b1;
|
||||
next_state = CRC1;
|
||||
end
|
||||
end
|
||||
WAIT: // In case of early tx_ready ...
|
||||
begin
|
||||
crc_sel1 = 1'b1;
|
||||
dsel = 1'b1;
|
||||
tx_valid_d = 1'b1;
|
||||
next_state = CRC1;
|
||||
end
|
||||
CRC1:
|
||||
begin
|
||||
dsel = 1'b1;
|
||||
tx_valid_d = 1'b1;
|
||||
if(tx_ready)
|
||||
begin
|
||||
last = 1'b1;
|
||||
crc_sel2 = 1'b1;
|
||||
next_state = CRC2;
|
||||
end
|
||||
else
|
||||
begin
|
||||
tx_valid_d = 1'b1;
|
||||
crc_sel1 = 1'b1;
|
||||
end
|
||||
|
||||
end
|
||||
CRC2:
|
||||
begin
|
||||
dsel = 1'b1;
|
||||
crc_sel2 = 1'b1;
|
||||
if(tx_ready)
|
||||
begin
|
||||
next_state = IDLE;
|
||||
end
|
||||
else
|
||||
begin
|
||||
last = 1'b1;
|
||||
end
|
||||
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
@@ -0,0 +1,428 @@
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Packet Disassembler ////
|
||||
//// Disassembles Token and Data USB packets ////
|
||||
//// ////
|
||||
//// Author: Rudolf Usselmann ////
|
||||
//// rudi@asics.ws ////
|
||||
//// ////
|
||||
//// ////
|
||||
//// Downloaded from: http://www.opencores.org/cores/usb/ ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2000-2003 Rudolf Usselmann ////
|
||||
//// www.asics.ws ////
|
||||
//// rudi@asics.ws ////
|
||||
//// ////
|
||||
//// This source file may be used and distributed without ////
|
||||
//// restriction provided that this copyright statement is not ////
|
||||
//// removed from the file and that any derivative work contains ////
|
||||
//// the original copyright notice and the associated disclaimer.////
|
||||
//// ////
|
||||
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
|
||||
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
|
||||
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
|
||||
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
|
||||
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
|
||||
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
|
||||
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
|
||||
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
|
||||
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
|
||||
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
|
||||
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
|
||||
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
|
||||
//// POSSIBILITY OF SUCH DAMAGE. ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
// CVS Log
|
||||
//
|
||||
// $Id: usbf_pd.v,v 1.7 2003-10-17 02:36:57 rudi Exp $
|
||||
//
|
||||
// $Date: 2003-10-17 02:36:57 $
|
||||
// $Revision: 1.7 $
|
||||
// $Author: rudi $
|
||||
// $Locker: $
|
||||
// $State: Exp $
|
||||
//
|
||||
// Change History:
|
||||
// $Log: not supported by cvs2svn $
|
||||
// Revision 1.5 2001/11/03 03:26:22 rudi
|
||||
//
|
||||
// - Fixed several interrupt and error condition reporting bugs
|
||||
//
|
||||
// Revision 1.4 2001/09/24 01:15:28 rudi
|
||||
//
|
||||
// Changed reset to be active high async.
|
||||
//
|
||||
// Revision 1.3 2001/09/10 15:54:20 rudi
|
||||
//
|
||||
// Fixed crc5 checking.
|
||||
//
|
||||
// Revision 1.2 2001/08/10 08:48:33 rudi
|
||||
//
|
||||
// - Changed IO names to be more clear.
|
||||
// - Uniquifyed define names to be core specific.
|
||||
//
|
||||
// Revision 1.1 2001/08/03 05:30:09 rudi
|
||||
//
|
||||
//
|
||||
// 1) Reorganized directory structure
|
||||
//
|
||||
// Revision 1.2 2001/03/31 13:00:51 rudi
|
||||
//
|
||||
// - Added Core configuration
|
||||
// - Added handling of OUT packets less than MAX_PL_SZ in DMA mode
|
||||
// - Modified WISHBONE interface and sync logic
|
||||
// - Moved SSRAM outside the core (added interface)
|
||||
// - Many small bug fixes ...
|
||||
//
|
||||
// Revision 1.0 2001/03/07 09:17:12 rudi
|
||||
//
|
||||
//
|
||||
// Changed all revisions to revision 1.0. This is because OpenCores CVS
|
||||
// interface could not handle the original '0.1' revision ....
|
||||
//
|
||||
// Revision 0.1.0.1 2001/02/28 08:10:59 rudi
|
||||
// Initial Release
|
||||
//
|
||||
//
|
||||
|
||||
`include "usbf_defines.v"
|
||||
|
||||
module usbf_pd( clk, rst,
|
||||
|
||||
// UTMI RX I/F
|
||||
rx_data, rx_valid, rx_active, rx_err,
|
||||
|
||||
// PID Information
|
||||
pid_OUT, pid_IN, pid_SOF, pid_SETUP,
|
||||
pid_DATA0, pid_DATA1, pid_DATA2, pid_MDATA,
|
||||
pid_ACK, pid_NACK, pid_STALL, pid_NYET,
|
||||
pid_PRE, pid_ERR, pid_SPLIT, pid_PING,
|
||||
pid_cks_err,
|
||||
|
||||
// Token Information
|
||||
token_fadr, token_endp, token_valid, crc5_err,
|
||||
frame_no,
|
||||
|
||||
// Receive Data Output
|
||||
rx_data_st, rx_data_valid, rx_data_done, crc16_err,
|
||||
|
||||
// Misc.
|
||||
seq_err
|
||||
);
|
||||
|
||||
input clk, rst;
|
||||
|
||||
//UTMI RX Interface
|
||||
input [7:0] rx_data;
|
||||
input rx_valid, rx_active, rx_err;
|
||||
|
||||
// Decoded PIDs (used when token_valid is asserted)
|
||||
output pid_OUT, pid_IN, pid_SOF, pid_SETUP;
|
||||
output pid_DATA0, pid_DATA1, pid_DATA2, pid_MDATA;
|
||||
output pid_ACK, pid_NACK, pid_STALL, pid_NYET;
|
||||
output pid_PRE, pid_ERR, pid_SPLIT, pid_PING;
|
||||
output pid_cks_err; // Indicates a PID checksum error
|
||||
|
||||
|
||||
output [6:0] token_fadr; // Function address from token
|
||||
output [3:0] token_endp; // Endpoint number from token
|
||||
output token_valid; // Token is valid
|
||||
output crc5_err; // Token crc5 error
|
||||
output [10:0] frame_no; // Frame number for SOF tokens
|
||||
|
||||
output [7:0] rx_data_st; // Data to memory store unit
|
||||
output rx_data_valid; // Data on rx_data_st is valid
|
||||
output rx_data_done; // Indicates end of a transfer
|
||||
output crc16_err; // Data packet CRC 16 error
|
||||
|
||||
output seq_err; // State Machine Sequence Error
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Local Wires and Registers
|
||||
//
|
||||
|
||||
parameter [3:0] // synopsys enum state
|
||||
IDLE = 4'b0001,
|
||||
ACTIVE = 4'b0010,
|
||||
TOKEN = 4'b0100,
|
||||
DATA = 4'b1000;
|
||||
|
||||
reg [3:0] /* synopsys enum state */ state, next_state;
|
||||
// synopsys state_vector state
|
||||
|
||||
reg [7:0] pid; // Packet PDI
|
||||
reg pid_le_sm; // PID Load enable from State Machine
|
||||
wire pid_ld_en; // Enable loading of PID (all conditions)
|
||||
wire pid_cks_err; // Indicates a pid checksum err
|
||||
|
||||
// Decoded PID values
|
||||
wire pid_OUT, pid_IN, pid_SOF, pid_SETUP;
|
||||
wire pid_DATA0, pid_DATA1, pid_DATA2, pid_MDATA;
|
||||
wire pid_ACK, pid_NACK, pid_STALL, pid_NYET;
|
||||
wire pid_PRE, pid_ERR, pid_SPLIT, pid_PING, pid_RES;
|
||||
wire pid_TOKEN; // All TOKEN packet that we recognize
|
||||
wire pid_DATA; // All DATA packets that we recognize
|
||||
|
||||
reg [7:0] token0, token1; // Token Registers
|
||||
reg token_le_1, token_le_2; // Latch enables for token storage registers
|
||||
wire [4:0] token_crc5;
|
||||
|
||||
reg [7:0] d0, d1, d2; // Data path delay line (used to filter out crcs)
|
||||
reg data_valid_d; // Data Valid output from State Machine
|
||||
reg data_done; // Data cycle complete output from State Machine
|
||||
reg data_valid0; // Data valid delay line
|
||||
reg rxv1;
|
||||
reg rxv2;
|
||||
|
||||
reg seq_err; // State machine sequence error
|
||||
|
||||
reg got_pid_ack;
|
||||
|
||||
reg token_valid_r1;
|
||||
reg token_valid_str1;
|
||||
|
||||
reg rx_active_r;
|
||||
|
||||
wire [4:0] crc5_out;
|
||||
wire [4:0] crc5_out2;
|
||||
wire crc16_clr;
|
||||
reg [15:0] crc16_sum;
|
||||
wire [15:0] crc16_out;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Misc Logic
|
||||
//
|
||||
|
||||
// PID Decoding Logic
|
||||
assign pid_ld_en = pid_le_sm & rx_active & rx_valid;
|
||||
|
||||
`ifdef USBF_ASYNC_RESET
|
||||
always @(posedge clk or negedge rst)
|
||||
`else
|
||||
always @(posedge clk)
|
||||
`endif
|
||||
if(!rst) pid <= 8'hf0;
|
||||
else
|
||||
if(pid_ld_en) pid <= rx_data;
|
||||
|
||||
assign pid_cks_err = (pid[3:0] != ~pid[7:4]);
|
||||
|
||||
assign pid_OUT = pid[3:0] == `USBF_T_PID_OUT;
|
||||
assign pid_IN = pid[3:0] == `USBF_T_PID_IN;
|
||||
assign pid_SOF = pid[3:0] == `USBF_T_PID_SOF;
|
||||
assign pid_SETUP = pid[3:0] == `USBF_T_PID_SETUP;
|
||||
assign pid_DATA0 = pid[3:0] == `USBF_T_PID_DATA0;
|
||||
assign pid_DATA1 = pid[3:0] == `USBF_T_PID_DATA1;
|
||||
assign pid_DATA2 = pid[3:0] == `USBF_T_PID_DATA2;
|
||||
assign pid_MDATA = pid[3:0] == `USBF_T_PID_MDATA;
|
||||
assign pid_ACK = pid[3:0] == `USBF_T_PID_ACK;
|
||||
assign pid_NACK = pid[3:0] == `USBF_T_PID_NACK;
|
||||
assign pid_STALL = pid[3:0] == `USBF_T_PID_STALL;
|
||||
assign pid_NYET = pid[3:0] == `USBF_T_PID_NYET;
|
||||
assign pid_PRE = pid[3:0] == `USBF_T_PID_PRE;
|
||||
assign pid_ERR = pid[3:0] == `USBF_T_PID_ERR;
|
||||
assign pid_SPLIT = pid[3:0] == `USBF_T_PID_SPLIT;
|
||||
assign pid_PING = pid[3:0] == `USBF_T_PID_PING;
|
||||
assign pid_RES = pid[3:0] == `USBF_T_PID_RES;
|
||||
|
||||
assign pid_TOKEN = pid_OUT | pid_IN | pid_SOF | pid_SETUP | pid_PING;
|
||||
assign pid_DATA = pid_DATA0 | pid_DATA1 | pid_DATA2 | pid_MDATA;
|
||||
|
||||
// Token Decoding LOGIC
|
||||
always @(posedge clk)
|
||||
if(token_le_1) token0 <= rx_data;
|
||||
|
||||
always @(posedge clk)
|
||||
if(token_le_2) token1 <= rx_data;
|
||||
|
||||
always @(posedge clk)
|
||||
token_valid_r1 <= token_le_2;
|
||||
|
||||
always @(posedge clk)
|
||||
token_valid_str1 <= token_valid_r1 | got_pid_ack;
|
||||
|
||||
assign token_valid = token_valid_str1;
|
||||
|
||||
// CRC 5 should perform the check in one cycle (flow through logic)
|
||||
// 11 bits and crc5 input, 1 bit output
|
||||
assign crc5_err = token_valid & (crc5_out2 != token_crc5);
|
||||
|
||||
usbf_crc5 u0(
|
||||
.crc_in( 5'h1f ),
|
||||
.din( { token_fadr[0],
|
||||
token_fadr[1],
|
||||
token_fadr[2],
|
||||
token_fadr[3],
|
||||
token_fadr[4],
|
||||
token_fadr[5],
|
||||
token_fadr[6],
|
||||
token_endp[0],
|
||||
token_endp[1],
|
||||
token_endp[2],
|
||||
token_endp[3] } ),
|
||||
.crc_out( crc5_out ) );
|
||||
|
||||
// Invert and reverse result bits
|
||||
assign crc5_out2 = ~{crc5_out[0], crc5_out[1], crc5_out[2], crc5_out[3],
|
||||
crc5_out[4]};
|
||||
|
||||
assign frame_no = { token1[2:0], token0};
|
||||
assign token_fadr = token0[6:0];
|
||||
assign token_endp = {token1[2:0], token0[7]};
|
||||
assign token_crc5 = token1[7:3];
|
||||
|
||||
// Data receiving logic
|
||||
// build a delay line and stop when we are about to get crc
|
||||
`ifdef USBF_ASYNC_RESET
|
||||
always @(posedge clk or negedge rst)
|
||||
`else
|
||||
always @(posedge clk)
|
||||
`endif
|
||||
if(!rst) rxv1 <= 1'b0;
|
||||
else
|
||||
if(data_valid_d) rxv1 <= 1'b1;
|
||||
else
|
||||
if(data_done) rxv1 <= 1'b0;
|
||||
|
||||
`ifdef USBF_ASYNC_RESET
|
||||
always @(posedge clk or negedge rst)
|
||||
`else
|
||||
always @(posedge clk)
|
||||
`endif
|
||||
if(!rst) rxv2 <= 1'b0;
|
||||
else
|
||||
if(rxv1 && data_valid_d)rxv2 <= 1'b1;
|
||||
else
|
||||
if(data_done) rxv2 <= 1'b0;
|
||||
|
||||
always @(posedge clk)
|
||||
data_valid0 <= rxv2 & data_valid_d;
|
||||
|
||||
always @(posedge clk)
|
||||
begin
|
||||
if(data_valid_d) d0 <= rx_data;
|
||||
if(data_valid_d) d1 <= d0;
|
||||
if(data_valid_d) d2 <= d1;
|
||||
end
|
||||
|
||||
assign rx_data_st = d2;
|
||||
assign rx_data_valid = data_valid0;
|
||||
assign rx_data_done = data_done;
|
||||
|
||||
// crc16 accumulates rx_data as long as data_valid_d is asserted.
|
||||
// when data_done is asserted, crc16 reports status, and resets itself
|
||||
// next cycle.
|
||||
always @(posedge clk)
|
||||
rx_active_r <= rx_active;
|
||||
|
||||
assign crc16_clr = rx_active & !rx_active_r;
|
||||
|
||||
always @(posedge clk)
|
||||
if(crc16_clr) crc16_sum <= 16'hffff;
|
||||
else
|
||||
if(data_valid_d) crc16_sum <= crc16_out;
|
||||
|
||||
usbf_crc16 u1(
|
||||
.crc_in( crc16_sum ),
|
||||
.din( {rx_data[0], rx_data[1], rx_data[2], rx_data[3],
|
||||
rx_data[4], rx_data[5], rx_data[6], rx_data[7]} ),
|
||||
.crc_out( crc16_out ) );
|
||||
|
||||
// Verify against polynomial
|
||||
assign crc16_err = data_done & (crc16_sum != 16'h800d);
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Receive/Decode State machine
|
||||
//
|
||||
|
||||
`ifdef USBF_ASYNC_RESET
|
||||
always @(posedge clk or negedge rst)
|
||||
`else
|
||||
always @(posedge clk)
|
||||
`endif
|
||||
if(!rst) state <= IDLE;
|
||||
else state <= next_state;
|
||||
|
||||
always @(state or rx_valid or rx_active or rx_err or pid_ACK or pid_TOKEN
|
||||
or pid_DATA)
|
||||
begin
|
||||
next_state = state; // Default don't change current state
|
||||
pid_le_sm = 1'b0;
|
||||
token_le_1 = 1'b0;
|
||||
token_le_2 = 1'b0;
|
||||
data_valid_d = 1'b0;
|
||||
data_done = 1'b0;
|
||||
seq_err = 1'b0;
|
||||
got_pid_ack = 1'b0;
|
||||
case(state) // synopsys full_case parallel_case
|
||||
IDLE:
|
||||
begin
|
||||
pid_le_sm = 1'b1;
|
||||
if(rx_valid && rx_active) next_state = ACTIVE;
|
||||
end
|
||||
ACTIVE:
|
||||
begin
|
||||
// Received a ACK from Host
|
||||
if(pid_ACK && !rx_err)
|
||||
begin
|
||||
got_pid_ack = 1'b1;
|
||||
if(!rx_active) next_state = IDLE;
|
||||
end
|
||||
else
|
||||
// Receiving a TOKEN
|
||||
if(pid_TOKEN && rx_valid && rx_active && !rx_err)
|
||||
begin
|
||||
token_le_1 = 1'b1;
|
||||
next_state = TOKEN;
|
||||
end
|
||||
else
|
||||
// Receiving DATA
|
||||
if(pid_DATA && rx_valid && rx_active && !rx_err)
|
||||
begin
|
||||
data_valid_d = 1'b1;
|
||||
next_state = DATA;
|
||||
end
|
||||
else
|
||||
if( !rx_active || rx_err ||
|
||||
(rx_valid && !(pid_TOKEN || pid_DATA)) )
|
||||
begin
|
||||
seq_err = !rx_err;
|
||||
if(!rx_active) next_state = IDLE;
|
||||
end
|
||||
end
|
||||
TOKEN:
|
||||
begin
|
||||
if(rx_valid && rx_active && !rx_err)
|
||||
begin
|
||||
token_le_2 = 1'b1;
|
||||
next_state = IDLE;
|
||||
end
|
||||
else
|
||||
if(!rx_active || rx_err)
|
||||
begin
|
||||
seq_err = !rx_err;
|
||||
if(!rx_active) next_state = IDLE;
|
||||
end
|
||||
end
|
||||
DATA:
|
||||
begin
|
||||
if(rx_valid && rx_active && !rx_err) data_valid_d = 1'b1;
|
||||
if(!rx_active || rx_err)
|
||||
begin
|
||||
data_done = 1'b1;
|
||||
if(!rx_active) next_state = IDLE;
|
||||
end
|
||||
end
|
||||
|
||||
endcase
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,474 @@
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Protocol Layer ////
|
||||
//// This block is typically referred to as the SEI in USB ////
|
||||
//// Specification. It encapsulates the Packet Assembler, ////
|
||||
//// disassembler, protocol engine and internal DMA ////
|
||||
//// ////
|
||||
//// Author: Rudolf Usselmann ////
|
||||
//// rudi@asics.ws ////
|
||||
//// ////
|
||||
//// ////
|
||||
//// Downloaded from: http://www.opencores.org/cores/usb/ ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2000-2003 Rudolf Usselmann ////
|
||||
//// www.asics.ws ////
|
||||
//// rudi@asics.ws ////
|
||||
//// ////
|
||||
//// This source file may be used and distributed without ////
|
||||
//// restriction provided that this copyright statement is not ////
|
||||
//// removed from the file and that any derivative work contains ////
|
||||
//// the original copyright notice and the associated disclaimer.////
|
||||
//// ////
|
||||
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
|
||||
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
|
||||
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
|
||||
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
|
||||
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
|
||||
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
|
||||
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
|
||||
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
|
||||
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
|
||||
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
|
||||
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
|
||||
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
|
||||
//// POSSIBILITY OF SUCH DAMAGE. ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
// CVS Log
|
||||
//
|
||||
// $Id: usbf_pl.v,v 1.5 2003-10-17 02:36:57 rudi Exp $
|
||||
//
|
||||
// $Date: 2003-10-17 02:36:57 $
|
||||
// $Revision: 1.5 $
|
||||
// $Author: rudi $
|
||||
// $Locker: $
|
||||
// $State: Exp $
|
||||
//
|
||||
// Change History:
|
||||
// $Log: not supported by cvs2svn $
|
||||
// Revision 1.4 2001/11/04 12:22:45 rudi
|
||||
//
|
||||
// - Fixed previous fix (brocke something else ...)
|
||||
// - Majore Synthesis cleanup
|
||||
//
|
||||
// Revision 1.3 2001/09/24 01:15:28 rudi
|
||||
//
|
||||
// Changed reset to be active high async.
|
||||
//
|
||||
// Revision 1.2 2001/08/10 08:48:33 rudi
|
||||
//
|
||||
// - Changed IO names to be more clear.
|
||||
// - Uniquifyed define names to be core specific.
|
||||
//
|
||||
// Revision 1.1 2001/08/03 05:30:09 rudi
|
||||
//
|
||||
//
|
||||
// 1) Reorganized directory structure
|
||||
//
|
||||
// Revision 1.2 2001/03/31 13:00:52 rudi
|
||||
//
|
||||
// - Added Core configuration
|
||||
// - Added handling of OUT packets less than MAX_PL_SZ in DMA mode
|
||||
// - Modified WISHBONE interface and sync logic
|
||||
// - Moved SSRAM outside the core (added interface)
|
||||
// - Many small bug fixes ...
|
||||
//
|
||||
// Revision 1.0 2001/03/07 09:17:12 rudi
|
||||
//
|
||||
//
|
||||
// Changed all revisions to revision 1.0. This is because OpenCores CVS
|
||||
// interface could not handle the original '0.1' revision ....
|
||||
//
|
||||
// Revision 0.1.0.1 2001/02/28 08:11:11 rudi
|
||||
// Initial Release
|
||||
//
|
||||
//
|
||||
|
||||
`include "usbf_defines.v"
|
||||
|
||||
module usbf_pl( clk, rst,
|
||||
|
||||
// UTMI Interface
|
||||
rx_data, rx_valid, rx_active, rx_err,
|
||||
tx_data, tx_valid, tx_valid_last, tx_ready,
|
||||
tx_first, tx_valid_out,
|
||||
mode_hs, usb_reset, usb_suspend, usb_attached,
|
||||
|
||||
// memory interface
|
||||
madr, mdout, mdin, mwe, mreq, mack,
|
||||
|
||||
// Register File Interface
|
||||
fa, idin,
|
||||
ep_sel, match,
|
||||
dma_in_buf_sz1, dma_out_buf_avail,
|
||||
buf0_rl, buf0_set, buf1_set,
|
||||
uc_bsel_set, uc_dpd_set,
|
||||
|
||||
int_buf1_set, int_buf0_set, int_upid_set,
|
||||
int_crc16_set, int_to_set, int_seqerr_set,
|
||||
out_to_small, csr, buf0, buf1,
|
||||
|
||||
// Misc
|
||||
frm_nat,
|
||||
pid_cs_err, nse_err,
|
||||
crc5_err
|
||||
);
|
||||
|
||||
parameter SSRAM_HADR = 14;
|
||||
|
||||
// UTMI Interface
|
||||
input clk, rst;
|
||||
input [7:0] rx_data;
|
||||
input rx_valid, rx_active, rx_err;
|
||||
output [7:0] tx_data;
|
||||
output tx_valid;
|
||||
output tx_valid_last;
|
||||
input tx_ready;
|
||||
output tx_first;
|
||||
input tx_valid_out;
|
||||
input mode_hs; // High Speed Mode
|
||||
input usb_reset; // USB Reset
|
||||
input usb_suspend; // USB Suspend
|
||||
input usb_attached; // Attached to USB
|
||||
|
||||
// Memory Arbiter Interface
|
||||
output [SSRAM_HADR:0] madr; // word address
|
||||
output [31:0] mdout;
|
||||
input [31:0] mdin;
|
||||
output mwe;
|
||||
output mreq;
|
||||
input mack;
|
||||
|
||||
// Register File interface
|
||||
input [6:0] fa; // Function Address (as set by the controller)
|
||||
output [31:0] idin; // Data Input
|
||||
output [3:0] ep_sel; // Endpoint Number Input
|
||||
input match; // Endpoint Matched
|
||||
input dma_in_buf_sz1;
|
||||
input dma_out_buf_avail;
|
||||
output nse_err; // no such endpoint error
|
||||
|
||||
output buf0_rl; // Reload Buf 0 with original values
|
||||
output buf0_set; // Write to buf 0
|
||||
output buf1_set; // Write to buf 1
|
||||
output uc_bsel_set; // Write to the uc_bsel field
|
||||
output uc_dpd_set; // Write to the uc_dpd field
|
||||
output int_buf1_set; // Set buf1 full/empty interrupt
|
||||
output int_buf0_set; // Set buf0 full/empty interrupt
|
||||
output int_upid_set; // Set unsupported PID interrupt
|
||||
output int_crc16_set; // Set CRC16 error interrupt
|
||||
output int_to_set; // Set time out interrupt
|
||||
output int_seqerr_set; // Set PID sequence error interrupt
|
||||
output out_to_small; // OUT packet was to small for DMA operation
|
||||
|
||||
input [31:0] csr; // Internal CSR Output
|
||||
input [31:0] buf0; // Internal Buf 0 Output
|
||||
input [31:0] buf1; // Internal Buf 1 Output
|
||||
|
||||
// Misc
|
||||
output pid_cs_err; // pid checksum error
|
||||
output crc5_err; // crc5 error
|
||||
output [31:0] frm_nat;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Local Wires and Registers
|
||||
//
|
||||
|
||||
// Packet Disassembler Interface
|
||||
wire clk, rst;
|
||||
wire [7:0] rx_data;
|
||||
wire pid_OUT, pid_IN, pid_SOF, pid_SETUP;
|
||||
wire pid_DATA0, pid_DATA1, pid_DATA2, pid_MDATA;
|
||||
wire pid_ACK, pid_NACK, pid_STALL, pid_NYET;
|
||||
wire pid_PRE, pid_ERR, pid_SPLIT, pid_PING;
|
||||
wire [6:0] token_fadr;
|
||||
wire token_valid;
|
||||
wire crc5_err;
|
||||
wire [10:0] frame_no;
|
||||
wire [7:0] rx_data_st;
|
||||
wire rx_data_valid;
|
||||
wire rx_data_done;
|
||||
wire crc16_err;
|
||||
wire rx_seq_err;
|
||||
|
||||
// Packet Assembler Interface
|
||||
wire send_token;
|
||||
wire [1:0] token_pid_sel;
|
||||
wire send_data;
|
||||
wire [1:0] data_pid_sel;
|
||||
wire [7:0] tx_data_st;
|
||||
wire rd_next;
|
||||
|
||||
// IDMA Interface
|
||||
wire rx_dma_en; // Allows the data to be stored
|
||||
wire tx_dma_en; // Allows for data to be retrieved
|
||||
wire abort; // Abort Transfer (time_out, crc_err or rx_error)
|
||||
wire idma_done; // DMA is done
|
||||
wire [SSRAM_HADR + 2:0] adr; // Byte Address
|
||||
wire [13:0] size; // Size in bytes
|
||||
wire [10:0] sizu_c; // Up and Down counting size registers, used
|
||||
// to update
|
||||
wire [13:0] buf_size; // Actual buffer size
|
||||
wire dma_en; // external dma enabled
|
||||
|
||||
// Memory Arbiter Interface
|
||||
wire [SSRAM_HADR:0] madr; // word address
|
||||
wire [31:0] mdout;
|
||||
wire [31:0] mdin;
|
||||
wire mwe;
|
||||
wire mreq;
|
||||
wire mack;
|
||||
|
||||
// Local signals
|
||||
wire pid_bad, pid_bad1, pid_bad2;
|
||||
|
||||
reg hms_clk; // 0.5 Micro Second Clock
|
||||
reg [4:0] hms_cnt;
|
||||
reg [10:0] frame_no_r; // Current Frame Number register
|
||||
wire frame_no_we;
|
||||
reg frame_no_same; // Indicates current and prev. frame numbers
|
||||
// are equal
|
||||
reg [3:0] mfm_cnt; // Micro Frame Counter
|
||||
reg [11:0] sof_time; // Time since last sof
|
||||
reg clr_sof_time;
|
||||
wire fsel; // This Function is selected
|
||||
wire match_o;
|
||||
|
||||
reg frame_no_we_r;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Misc Logic
|
||||
//
|
||||
|
||||
// PIDs we should never receive
|
||||
assign pid_bad1 = pid_ACK | pid_NACK | pid_STALL | pid_NYET | pid_PRE |
|
||||
pid_ERR | pid_SPLIT;
|
||||
|
||||
// PIDs we should never get in full speed mode (high speed mode only)
|
||||
assign pid_bad2 = !mode_hs & pid_PING;
|
||||
|
||||
// All bad pids
|
||||
assign pid_bad = pid_bad1 | pid_bad2;
|
||||
|
||||
assign match_o = !pid_bad & fsel & match & token_valid & !crc5_err;
|
||||
|
||||
// Frame Number (from SOF token)
|
||||
assign frame_no_we = token_valid & !crc5_err & pid_SOF;
|
||||
|
||||
always @(posedge clk)
|
||||
frame_no_we_r <= frame_no_we;
|
||||
|
||||
`ifdef USBF_ASYNC_RESET
|
||||
always @(posedge clk or negedge rst)
|
||||
`else
|
||||
always @(posedge clk)
|
||||
`endif
|
||||
if(!rst) frame_no_r <= 11'h0;
|
||||
else
|
||||
if(frame_no_we_r) frame_no_r <= frame_no;
|
||||
|
||||
// Micro Frame Counter
|
||||
always @(posedge clk)
|
||||
frame_no_same <= frame_no_we & (frame_no_r == frame_no);
|
||||
|
||||
`ifdef USBF_ASYNC_RESET
|
||||
always @(posedge clk or negedge rst)
|
||||
`else
|
||||
always @(posedge clk)
|
||||
`endif
|
||||
if(!rst) mfm_cnt <= 4'h0;
|
||||
else
|
||||
if(frame_no_we_r && !frame_no_same)
|
||||
mfm_cnt <= 4'h0;
|
||||
else
|
||||
if(frame_no_same) mfm_cnt <= mfm_cnt + 4'h1;
|
||||
|
||||
//SOF delay counter
|
||||
always @(posedge clk)
|
||||
clr_sof_time <= frame_no_we;
|
||||
|
||||
always @(posedge clk)
|
||||
if(clr_sof_time) sof_time <= 12'h0;
|
||||
else
|
||||
if(hms_clk) sof_time <= sof_time + 12'h1;
|
||||
|
||||
assign frm_nat = {mfm_cnt, 1'b0, frame_no_r, 4'h0, sof_time};
|
||||
|
||||
// 0.5 Micro Seconds Clock Generator
|
||||
`ifdef USBF_ASYNC_RESET
|
||||
always @(posedge clk or negedge rst)
|
||||
`else
|
||||
always @(posedge clk)
|
||||
`endif
|
||||
if(!rst) hms_cnt <= 5'h0;
|
||||
else
|
||||
if(hms_clk || frame_no_we_r) hms_cnt <= 5'h0;
|
||||
else hms_cnt <= hms_cnt + 5'h1;
|
||||
|
||||
always @(posedge clk)
|
||||
hms_clk <= (hms_cnt == `USBF_HMS_DEL);
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
// This function is addressed
|
||||
assign fsel = (token_fadr == fa);
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Module Instantiations
|
||||
//
|
||||
|
||||
//Packet Decoder
|
||||
usbf_pd u0( .clk( clk ),
|
||||
.rst( rst ),
|
||||
.rx_data( rx_data ),
|
||||
.rx_valid( rx_valid ),
|
||||
.rx_active( rx_active ),
|
||||
.rx_err( rx_err ),
|
||||
.pid_OUT( pid_OUT ),
|
||||
.pid_IN( pid_IN ),
|
||||
.pid_SOF( pid_SOF ),
|
||||
.pid_SETUP( pid_SETUP ),
|
||||
.pid_DATA0( pid_DATA0 ),
|
||||
.pid_DATA1( pid_DATA1 ),
|
||||
.pid_DATA2( pid_DATA2 ),
|
||||
.pid_MDATA( pid_MDATA ),
|
||||
.pid_ACK( pid_ACK ),
|
||||
.pid_NACK( pid_NACK ),
|
||||
.pid_STALL( pid_STALL ),
|
||||
.pid_NYET( pid_NYET ),
|
||||
.pid_PRE( pid_PRE ),
|
||||
.pid_ERR( pid_ERR ),
|
||||
.pid_SPLIT( pid_SPLIT ),
|
||||
.pid_PING( pid_PING ),
|
||||
.pid_cks_err( pid_cs_err ),
|
||||
.token_fadr( token_fadr ),
|
||||
.token_endp( ep_sel ),
|
||||
.token_valid( token_valid ),
|
||||
.crc5_err( crc5_err ),
|
||||
.frame_no( frame_no ),
|
||||
.rx_data_st( rx_data_st ),
|
||||
.rx_data_valid( rx_data_valid ),
|
||||
.rx_data_done( rx_data_done ),
|
||||
.crc16_err( crc16_err ),
|
||||
.seq_err( rx_seq_err )
|
||||
);
|
||||
|
||||
// Packet Assembler
|
||||
usbf_pa u1( .clk( clk ),
|
||||
.rst( rst ),
|
||||
.tx_data( tx_data ),
|
||||
.tx_valid( tx_valid ),
|
||||
.tx_valid_last( tx_valid_last ),
|
||||
.tx_ready( tx_ready ),
|
||||
.tx_first( tx_first ),
|
||||
.send_token( send_token ),
|
||||
.token_pid_sel( token_pid_sel ),
|
||||
.send_data( send_data ),
|
||||
.data_pid_sel( data_pid_sel ),
|
||||
.send_zero_length( send_zero_length ),
|
||||
.tx_data_st( tx_data_st ),
|
||||
.rd_next( rd_next )
|
||||
);
|
||||
|
||||
// Internal DMA / Memory Arbiter Interface
|
||||
usbf_idma #(SSRAM_HADR)
|
||||
u2( .clk( clk ),
|
||||
.rst( rst ),
|
||||
.rx_data_st( rx_data_st ),
|
||||
.rx_data_valid( rx_data_valid ),
|
||||
.rx_data_done( rx_data_done ),
|
||||
.send_data( send_data ),
|
||||
.tx_data_st( tx_data_st ),
|
||||
.rd_next( rd_next ),
|
||||
.rx_dma_en( rx_dma_en ),
|
||||
.tx_dma_en( tx_dma_en ),
|
||||
.abort( abort ),
|
||||
.idma_done( idma_done ),
|
||||
.adr( adr ),
|
||||
.size( size ),
|
||||
.buf_size( buf_size ),
|
||||
.dma_en( dma_en ),
|
||||
.send_zero_length( send_zero_length ),
|
||||
.madr( madr ),
|
||||
.sizu_c( sizu_c ),
|
||||
.mdout( mdout ),
|
||||
.mdin( mdin ),
|
||||
.mwe( mwe ),
|
||||
.mreq( mreq ),
|
||||
.mack( mack )
|
||||
);
|
||||
|
||||
// Protocol Engine
|
||||
usbf_pe #(SSRAM_HADR)
|
||||
u3( .clk( clk ),
|
||||
.rst( rst ),
|
||||
.tx_valid( tx_valid_out ),
|
||||
.rx_active( rx_active ),
|
||||
.pid_OUT( pid_OUT ),
|
||||
.pid_IN( pid_IN ),
|
||||
.pid_SOF( pid_SOF ),
|
||||
.pid_SETUP( pid_SETUP ),
|
||||
.pid_DATA0( pid_DATA0 ),
|
||||
.pid_DATA1( pid_DATA1 ),
|
||||
.pid_DATA2( pid_DATA2 ),
|
||||
.pid_MDATA( pid_MDATA ),
|
||||
.pid_ACK( pid_ACK ),
|
||||
.pid_NACK( pid_NACK ),
|
||||
.pid_STALL( pid_STALL ),
|
||||
.pid_NYET( pid_NYET ),
|
||||
.pid_PRE( pid_PRE ),
|
||||
.pid_ERR( pid_ERR ),
|
||||
.pid_SPLIT( pid_SPLIT ),
|
||||
.pid_PING( pid_PING ),
|
||||
.mode_hs( mode_hs ),
|
||||
.token_valid( token_valid ),
|
||||
.crc5_err( crc5_err ),
|
||||
.rx_data_valid( rx_data_valid ),
|
||||
.rx_data_done( rx_data_done ),
|
||||
.crc16_err( crc16_err ),
|
||||
.send_token( send_token ),
|
||||
.token_pid_sel( token_pid_sel ),
|
||||
.data_pid_sel( data_pid_sel ),
|
||||
.send_zero_length( send_zero_length ),
|
||||
.rx_dma_en( rx_dma_en ),
|
||||
.tx_dma_en( tx_dma_en ),
|
||||
.abort( abort ),
|
||||
.idma_done( idma_done ),
|
||||
.adr( adr ),
|
||||
.size( size ),
|
||||
.buf_size( buf_size ),
|
||||
.sizu_c( sizu_c ),
|
||||
.dma_en( dma_en ),
|
||||
.fsel( fsel ),
|
||||
.idin( idin ),
|
||||
.ep_sel( ep_sel ),
|
||||
.match( match_o ),
|
||||
.dma_in_buf_sz1( dma_in_buf_sz1 ),
|
||||
.dma_out_buf_avail( dma_out_buf_avail ),
|
||||
.nse_err( nse_err ),
|
||||
.buf0_rl( buf0_rl ),
|
||||
.buf0_set( buf0_set ),
|
||||
.buf1_set( buf1_set ),
|
||||
.uc_bsel_set( uc_bsel_set ),
|
||||
.uc_dpd_set( uc_dpd_set ),
|
||||
.int_buf1_set( int_buf1_set ),
|
||||
.int_buf0_set( int_buf0_set ),
|
||||
.int_upid_set( int_upid_set ),
|
||||
.int_crc16_set( int_crc16_set ),
|
||||
.int_to_set( int_to_set ),
|
||||
.int_seqerr_set( int_seqerr_set ),
|
||||
.out_to_small( out_to_small ),
|
||||
.csr( csr ),
|
||||
.buf0( buf0 ),
|
||||
.buf1( buf1 )
|
||||
);
|
||||
|
||||
endmodule
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,619 @@
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// USB function core ////
|
||||
//// ////
|
||||
//// ////
|
||||
//// Author: Rudolf Usselmann ////
|
||||
//// rudi@asics.ws ////
|
||||
//// ////
|
||||
//// ////
|
||||
//// Downloaded from: http://www.opencores.org/cores/usb/ ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2000-2003 Rudolf Usselmann ////
|
||||
//// www.asics.ws ////
|
||||
//// rudi@asics.ws ////
|
||||
//// ////
|
||||
//// This source file may be used and distributed without ////
|
||||
//// restriction provided that this copyright statement is not ////
|
||||
//// removed from the file and that any derivative work contains ////
|
||||
//// the original copyright notice and the associated disclaimer.////
|
||||
//// ////
|
||||
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
|
||||
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
|
||||
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
|
||||
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
|
||||
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
|
||||
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
|
||||
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
|
||||
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
|
||||
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
|
||||
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
|
||||
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
|
||||
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
|
||||
//// POSSIBILITY OF SUCH DAMAGE. ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
// CVS Log
|
||||
//
|
||||
// $Id: usbf_top.v,v 1.7 2003-11-11 07:15:16 rudi Exp $
|
||||
//
|
||||
// $Date: 2003-11-11 07:15:16 $
|
||||
// $Revision: 1.7 $
|
||||
// $Author: rudi $
|
||||
// $Locker: $
|
||||
// $State: Exp $
|
||||
//
|
||||
// Change History:
|
||||
// $Log: not supported by cvs2svn $
|
||||
// Revision 1.6 2003/10/17 02:36:57 rudi
|
||||
// - Disabling bit stuffing and NRZI encoding during speed negotiation
|
||||
// - Now the core can send zero size packets
|
||||
// - Fixed register addresses for some of the higher endpoints
|
||||
// (conversion between decimal/hex was wrong)
|
||||
// - The core now does properly evaluate the function address to
|
||||
// determine if the packet was intended for it.
|
||||
// - Various other minor bugs and typos
|
||||
//
|
||||
// Revision 1.5 2001/11/04 12:22:45 rudi
|
||||
//
|
||||
// - Fixed previous fix (brocke something else ...)
|
||||
// - Majore Synthesis cleanup
|
||||
//
|
||||
// Revision 1.4 2001/11/03 03:26:23 rudi
|
||||
//
|
||||
// - Fixed several interrupt and error condition reporting bugs
|
||||
//
|
||||
// Revision 1.3 2001/09/24 01:15:28 rudi
|
||||
//
|
||||
// Changed reset to be active high async.
|
||||
//
|
||||
// Revision 1.2 2001/08/10 08:48:33 rudi
|
||||
//
|
||||
// - Changed IO names to be more clear.
|
||||
// - Uniquifyed define names to be core specific.
|
||||
//
|
||||
// Revision 1.1 2001/08/03 05:30:09 rudi
|
||||
//
|
||||
//
|
||||
// 1) Reorganized directory structure
|
||||
//
|
||||
// Revision 1.2 2001/03/31 13:00:52 rudi
|
||||
//
|
||||
// - Added Core configuration
|
||||
// - Added handling of OUT packets less than MAX_PL_SZ in DMA mode
|
||||
// - Modified WISHBONE interface and sync logic
|
||||
// - Moved SSRAM outside the core (added interface)
|
||||
// - Many small bug fixes ...
|
||||
//
|
||||
// Revision 1.0 2001/03/07 09:17:12 rudi
|
||||
//
|
||||
//
|
||||
// Changed all revisions to revision 1.0. This is because OpenCores CVS
|
||||
// interface could not handle the original '0.1' revision ....
|
||||
//
|
||||
// Revision 0.2 2001/03/07 09:08:13 rudi
|
||||
//
|
||||
// Added USB control signaling (Line Status) block. Fixed some minor
|
||||
// typos, added resume bit and signal.
|
||||
//
|
||||
// Revision 0.1.0.1 2001/02/28 08:11:40 rudi
|
||||
// Initial Release
|
||||
//
|
||||
//
|
||||
|
||||
`include "usbf_defines.v"
|
||||
|
||||
module usbf_top(// WISHBONE Interface
|
||||
clk_i, rst_i, wb_addr_i, wb_data_i, wb_data_o,
|
||||
wb_ack_o, wb_we_i, wb_stb_i, wb_cyc_i, inta_o, intb_o,
|
||||
dma_req_o, dma_ack_i, susp_o, resume_req_i,
|
||||
|
||||
// UTMI Interface
|
||||
phy_clk_pad_i, phy_rst_pad_o,
|
||||
DataOut_pad_o, TxValid_pad_o, TxReady_pad_i,
|
||||
|
||||
RxValid_pad_i, RxActive_pad_i, RxError_pad_i,
|
||||
DataIn_pad_i, XcvSelect_pad_o, TermSel_pad_o,
|
||||
SuspendM_pad_o, LineState_pad_i,
|
||||
|
||||
OpMode_pad_o, usb_vbus_pad_i,
|
||||
VControl_Load_pad_o, VControl_pad_o, VStatus_pad_i,
|
||||
|
||||
// Buffer Memory Interface
|
||||
sram_adr_o, sram_data_i, sram_data_o, sram_re_o, sram_we_o
|
||||
|
||||
);
|
||||
|
||||
parameter SSRAM_HADR = `USBF_SSRAM_HADR;
|
||||
input clk_i;
|
||||
input rst_i;
|
||||
input [`USBF_UFC_HADR:0] wb_addr_i;
|
||||
input [31:0] wb_data_i;
|
||||
output [31:0] wb_data_o;
|
||||
output wb_ack_o;
|
||||
input wb_we_i;
|
||||
input wb_stb_i;
|
||||
input wb_cyc_i;
|
||||
output inta_o;
|
||||
output intb_o;
|
||||
output [15:0] dma_req_o;
|
||||
input [15:0] dma_ack_i;
|
||||
output susp_o;
|
||||
input resume_req_i;
|
||||
|
||||
input phy_clk_pad_i;
|
||||
output phy_rst_pad_o;
|
||||
|
||||
output [7:0] DataOut_pad_o;
|
||||
output TxValid_pad_o;
|
||||
input TxReady_pad_i;
|
||||
|
||||
input [7:0] DataIn_pad_i;
|
||||
input RxValid_pad_i;
|
||||
input RxActive_pad_i;
|
||||
input RxError_pad_i;
|
||||
|
||||
output XcvSelect_pad_o;
|
||||
output TermSel_pad_o;
|
||||
output SuspendM_pad_o;
|
||||
input [1:0] LineState_pad_i;
|
||||
output [1:0] OpMode_pad_o;
|
||||
input usb_vbus_pad_i;
|
||||
output VControl_Load_pad_o;
|
||||
output [3:0] VControl_pad_o;
|
||||
input [7:0] VStatus_pad_i;
|
||||
|
||||
output [SSRAM_HADR:0] sram_adr_o;
|
||||
input [31:0] sram_data_i;
|
||||
output [31:0] sram_data_o;
|
||||
output sram_re_o;
|
||||
output sram_we_o;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Local Wires and Registers
|
||||
//
|
||||
|
||||
// UTMI Interface
|
||||
wire [7:0] rx_data;
|
||||
wire rx_valid, rx_active, rx_err;
|
||||
wire [7:0] tx_data;
|
||||
wire tx_valid;
|
||||
wire tx_ready;
|
||||
wire tx_first;
|
||||
wire tx_valid_last;
|
||||
|
||||
// Misc UTMI USB status
|
||||
wire mode_hs; // High Speed Mode
|
||||
wire usb_reset; // USB Reset
|
||||
wire usb_suspend; // USB Sleep
|
||||
wire usb_attached; // Attached to USB
|
||||
wire resume_req; // Resume Request
|
||||
|
||||
// Memory Arbiter Interface
|
||||
wire [SSRAM_HADR:0] madr; // word address
|
||||
wire [31:0] mdout;
|
||||
wire [31:0] mdin;
|
||||
wire mwe;
|
||||
wire mreq;
|
||||
wire mack;
|
||||
wire rst;
|
||||
|
||||
// Wishbone Memory interface
|
||||
wire [`USBF_UFC_HADR:0] ma_adr;
|
||||
wire [31:0] ma2wb_d;
|
||||
wire [31:0] wb2ma_d;
|
||||
wire ma_we;
|
||||
wire ma_req;
|
||||
wire ma_ack;
|
||||
|
||||
// WISHBONE Register File interface
|
||||
wire rf_re;
|
||||
wire rf_we;
|
||||
wire [31:0] wb2rf_d;
|
||||
wire [31:0] rf2wb_d;
|
||||
|
||||
// Internal Register File Interface
|
||||
wire [6:0] funct_adr; // This functions address (set by controller)
|
||||
wire [31:0] idin; // Data Input
|
||||
wire [3:0] ep_sel; // Endpoint Number Input
|
||||
wire match; // Endpoint Matched
|
||||
wire dma_in_buf_sz1;
|
||||
wire dma_out_buf_avail;
|
||||
wire buf0_rl; // Reload Buf 0 with original values
|
||||
wire buf0_set; // Write to buf 0
|
||||
wire buf1_set; // Write to buf 1
|
||||
wire uc_bsel_set; // Write to the uc_bsel field
|
||||
wire uc_dpd_set; // Write to the uc_dpd field
|
||||
wire int_buf1_set; // Set buf1 full/empty interrupt
|
||||
wire int_buf0_set; // Set buf0 full/empty interrupt
|
||||
wire int_upid_set; // Set unsupported PID interrupt
|
||||
wire int_crc16_set; // Set CRC16 error interrupt
|
||||
wire int_to_set; // Set time out interrupt
|
||||
wire int_seqerr_set; // Set PID sequence error interrupt
|
||||
wire out_to_small; // OUT packet was to small for DMA operation
|
||||
wire [31:0] csr; // Internal CSR Output
|
||||
wire [31:0] buf0; // Internal Buf 0 Output
|
||||
wire [31:0] buf1; // Internal Buf 1 Output
|
||||
wire [31:0] frm_nat; // Frame Number and Time Register
|
||||
wire nse_err; // No Such Endpoint Error
|
||||
wire pid_cs_err; // PID CS error
|
||||
wire crc5_err; // CRC5 Error
|
||||
wire rf_resume_req; // Resume Request From main CSR
|
||||
|
||||
reg susp_o;
|
||||
reg [1:0] LineState_r; // Added to make a full synchronizer
|
||||
reg [7:0] VStatus_r; // Added to make a full synchronizer
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Misc Logic
|
||||
//
|
||||
assign rst = rst_i;
|
||||
assign phy_rst_pad_o = rst_i;
|
||||
assign resume_req = resume_req_i;
|
||||
|
||||
always @(posedge clk_i)
|
||||
susp_o <= usb_suspend;
|
||||
|
||||
always @(posedge phy_clk_pad_i) // First Stage Synchronizer
|
||||
LineState_r <= LineState_pad_i;
|
||||
|
||||
always @(posedge phy_clk_pad_i) // First Stage Synchronizer
|
||||
VStatus_r <= VStatus_pad_i;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Module Instantiations
|
||||
//
|
||||
|
||||
reg resume_req_r;
|
||||
reg suspend_clr_wr;
|
||||
wire suspend_clr;
|
||||
|
||||
always @(posedge clk_i)
|
||||
suspend_clr_wr <= suspend_clr;
|
||||
|
||||
`ifdef USBF_ASYNC_RESET
|
||||
always @(posedge clk_i or negedge rst)
|
||||
`else
|
||||
always @(posedge clk_i)
|
||||
`endif
|
||||
if(!rst) resume_req_r <= 1'b0;
|
||||
else
|
||||
if(suspend_clr_wr) resume_req_r <= 1'b0;
|
||||
else
|
||||
if(resume_req) resume_req_r <= 1'b1;
|
||||
|
||||
|
||||
// UTMI Interface
|
||||
usbf_utmi_if u0(
|
||||
.phy_clk( phy_clk_pad_i ),
|
||||
.rst( rst ),
|
||||
.DataOut( DataOut_pad_o ),
|
||||
.TxValid( TxValid_pad_o ),
|
||||
.TxReady( TxReady_pad_i ),
|
||||
.RxValid( RxValid_pad_i ),
|
||||
.RxActive( RxActive_pad_i ),
|
||||
.RxError( RxError_pad_i ),
|
||||
.DataIn( DataIn_pad_i ),
|
||||
.XcvSelect( XcvSelect_pad_o ),
|
||||
.TermSel( TermSel_pad_o ),
|
||||
.SuspendM( SuspendM_pad_o ),
|
||||
.LineState( LineState_pad_i ),
|
||||
.OpMode( OpMode_pad_o ),
|
||||
.usb_vbus( usb_vbus_pad_i ),
|
||||
.rx_data( rx_data ),
|
||||
.rx_valid( rx_valid ),
|
||||
.rx_active( rx_active ),
|
||||
.rx_err( rx_err ),
|
||||
.tx_data( tx_data ),
|
||||
.tx_valid( tx_valid ),
|
||||
.tx_valid_last( tx_valid_last ),
|
||||
.tx_ready( tx_ready ),
|
||||
.tx_first( tx_first ),
|
||||
.mode_hs( mode_hs ),
|
||||
.usb_reset( usb_reset ),
|
||||
.usb_suspend( usb_suspend ),
|
||||
.usb_attached( usb_attached ),
|
||||
.resume_req( resume_req_r ),
|
||||
.suspend_clr( suspend_clr )
|
||||
);
|
||||
|
||||
// Protocol Layer
|
||||
usbf_pl #(SSRAM_HADR)
|
||||
u1( .clk( phy_clk_pad_i ),
|
||||
.rst( rst ),
|
||||
.rx_data( rx_data ),
|
||||
.rx_valid( rx_valid ),
|
||||
.rx_active( rx_active ),
|
||||
.rx_err( rx_err ),
|
||||
.tx_data( tx_data ),
|
||||
.tx_valid( tx_valid ),
|
||||
.tx_valid_last( tx_valid_last ),
|
||||
.tx_ready( tx_ready ),
|
||||
.tx_first( tx_first ),
|
||||
.tx_valid_out( TxValid_pad_o ),
|
||||
.mode_hs( mode_hs ),
|
||||
.usb_reset( usb_reset ),
|
||||
.usb_suspend( usb_suspend ),
|
||||
.usb_attached( usb_attached ),
|
||||
.madr( madr ),
|
||||
.mdout( mdout ),
|
||||
.mdin( mdin ),
|
||||
.mwe( mwe ),
|
||||
.mreq( mreq ),
|
||||
.mack( mack ),
|
||||
.fa( funct_adr ),
|
||||
.dma_in_buf_sz1( dma_in_buf_sz1 ),
|
||||
.dma_out_buf_avail( dma_out_buf_avail ),
|
||||
.idin( idin ),
|
||||
.ep_sel( ep_sel ),
|
||||
.match( match ),
|
||||
.buf0_rl( buf0_rl ),
|
||||
.buf0_set( buf0_set ),
|
||||
.buf1_set( buf1_set ),
|
||||
.uc_bsel_set( uc_bsel_set ),
|
||||
.uc_dpd_set( uc_dpd_set ),
|
||||
.int_buf1_set( int_buf1_set ),
|
||||
.int_buf0_set( int_buf0_set ),
|
||||
.int_upid_set( int_upid_set ),
|
||||
.int_crc16_set( int_crc16_set ),
|
||||
.int_to_set( int_to_set ),
|
||||
.int_seqerr_set( int_seqerr_set ),
|
||||
.out_to_small( out_to_small ),
|
||||
.csr( csr ),
|
||||
.buf0( buf0 ),
|
||||
.buf1( buf1 ),
|
||||
.frm_nat( frm_nat ),
|
||||
.pid_cs_err( pid_cs_err ),
|
||||
.nse_err( nse_err ),
|
||||
.crc5_err( crc5_err )
|
||||
);
|
||||
|
||||
// Memory Arbiter
|
||||
usbf_mem_arb #(SSRAM_HADR)
|
||||
u2( .phy_clk( phy_clk_pad_i ),
|
||||
.wclk( clk_i ),
|
||||
.rst( rst ),
|
||||
|
||||
.sram_adr( sram_adr_o ),
|
||||
.sram_din( sram_data_i ),
|
||||
.sram_dout( sram_data_o ),
|
||||
.sram_re( sram_re_o ),
|
||||
.sram_we( sram_we_o ),
|
||||
|
||||
.madr( madr ),
|
||||
.mdout( mdin ),
|
||||
.mdin( mdout ),
|
||||
.mwe( mwe ),
|
||||
.mreq( mreq ),
|
||||
.mack( mack ),
|
||||
|
||||
.wadr( ma_adr[SSRAM_HADR + 2:2] ),
|
||||
.wdout( ma2wb_d ),
|
||||
.wdin( wb2ma_d ),
|
||||
.wwe( ma_we ),
|
||||
.wreq( ma_req ),
|
||||
.wack( ma_ack )
|
||||
);
|
||||
|
||||
// Register File
|
||||
usbf_rf u4( .clk( phy_clk_pad_i ),
|
||||
.wclk( clk_i ),
|
||||
.rst( rst ),
|
||||
|
||||
.adr( ma_adr[8:2] ),
|
||||
.re( rf_re ),
|
||||
.we( rf_we ),
|
||||
.din( wb2rf_d ),
|
||||
.dout( rf2wb_d ),
|
||||
|
||||
.inta( inta_o ),
|
||||
.intb( intb_o ),
|
||||
.dma_req( dma_req_o ),
|
||||
.dma_ack( dma_ack_i ),
|
||||
.idin( idin ),
|
||||
.ep_sel( ep_sel ),
|
||||
.match( match ),
|
||||
.buf0_rl( buf0_rl ),
|
||||
.buf0_set( buf0_set ),
|
||||
.buf1_set( buf1_set ),
|
||||
.uc_bsel_set( uc_bsel_set ),
|
||||
.uc_dpd_set( uc_dpd_set ),
|
||||
.int_buf1_set( int_buf1_set ),
|
||||
.int_buf0_set( int_buf0_set ),
|
||||
.int_upid_set( int_upid_set ),
|
||||
.int_crc16_set( int_crc16_set ),
|
||||
.int_to_set( int_to_set ),
|
||||
.int_seqerr_set( int_seqerr_set ),
|
||||
.out_to_small( out_to_small ),
|
||||
.csr( csr ),
|
||||
.buf0( buf0 ),
|
||||
.buf1( buf1 ),
|
||||
.funct_adr( funct_adr ),
|
||||
.dma_in_buf_sz1( dma_in_buf_sz1 ),
|
||||
.dma_out_buf_avail( dma_out_buf_avail ),
|
||||
.frm_nat( frm_nat ),
|
||||
.utmi_vend_stat( VStatus_r ),
|
||||
.utmi_vend_ctrl( VControl_pad_o ),
|
||||
.utmi_vend_wr( VControl_Load_pad_o ),
|
||||
.line_stat( LineState_r ),
|
||||
.usb_attached( usb_attached ),
|
||||
.mode_hs( mode_hs ),
|
||||
.suspend( usb_suspend ),
|
||||
.attached( usb_attached ),
|
||||
.usb_reset( usb_reset ),
|
||||
.pid_cs_err( pid_cs_err ),
|
||||
.nse_err( nse_err ),
|
||||
.crc5_err( crc5_err ),
|
||||
.rx_err( rx_err ),
|
||||
.rf_resume_req( rf_resume_req )
|
||||
);
|
||||
|
||||
|
||||
// WISHBONE Interface
|
||||
usbf_wb u5( .phy_clk( phy_clk_pad_i ),
|
||||
.wb_clk( clk_i ),
|
||||
.rst( rst ),
|
||||
.wb_addr_i( wb_addr_i ),
|
||||
.wb_data_i( wb_data_i ),
|
||||
.wb_data_o( wb_data_o ),
|
||||
.wb_ack_o( wb_ack_o ),
|
||||
.wb_we_i( wb_we_i ),
|
||||
.wb_stb_i( wb_stb_i ),
|
||||
.wb_cyc_i( wb_cyc_i ),
|
||||
|
||||
.ma_adr( ma_adr ),
|
||||
.ma_dout( wb2ma_d ),
|
||||
.ma_din( ma2wb_d ),
|
||||
.ma_we( ma_we ),
|
||||
.ma_req( ma_req ),
|
||||
.ma_ack( ma_ack ),
|
||||
|
||||
.rf_re( rf_re ),
|
||||
.rf_we( rf_we ),
|
||||
.rf_dout( wb2rf_d ),
|
||||
.rf_din( rf2wb_d )
|
||||
);
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Initialization
|
||||
// This section does not add any functionality. It is only provided
|
||||
// to make sure that the core is configured properly and to provide
|
||||
// configuration information for simulations.
|
||||
//
|
||||
|
||||
// synopsys translate_off
|
||||
integer ep_cnt, ep_cnt2;
|
||||
reg [15:0] ep_check;
|
||||
initial
|
||||
begin
|
||||
$display("\n");
|
||||
ep_cnt = 1;
|
||||
ep_cnt2 = 0;
|
||||
ep_check = 0;
|
||||
|
||||
`ifdef USBF_HAVE_EP1
|
||||
ep_cnt = ep_cnt + 1;
|
||||
ep_check[ep_cnt2] = 1;
|
||||
`endif
|
||||
ep_cnt2 = ep_cnt2 + 1;
|
||||
`ifdef USBF_HAVE_EP2
|
||||
if(!ep_check[ep_cnt2-1])
|
||||
$display("ERROR: USBF_TOP: Endpoint %0d not defined but endpoint %0d defined", ep_cnt2, ep_cnt2+1);
|
||||
ep_cnt = ep_cnt + 1;
|
||||
ep_check[ep_cnt2] = 1;
|
||||
`endif
|
||||
ep_cnt2 = ep_cnt2 + 1;
|
||||
`ifdef USBF_HAVE_EP3
|
||||
if(!ep_check[ep_cnt2-1])
|
||||
$display("ERROR: USBF_TOP: Endpoint %0d not defined but endpoint %0d defined", ep_cnt2, ep_cnt2+1);
|
||||
ep_cnt = ep_cnt + 1;
|
||||
ep_check[ep_cnt2] = 1;
|
||||
`endif
|
||||
ep_cnt2 = ep_cnt2 + 1;
|
||||
`ifdef USBF_HAVE_EP4
|
||||
if(!ep_check[ep_cnt2-1])
|
||||
$display("ERROR: USBF_TOP: Endpoint %0d not defined but endpoint %0d defined", ep_cnt2, ep_cnt2+1);
|
||||
ep_cnt = ep_cnt + 1;
|
||||
ep_check[ep_cnt2] = 1;
|
||||
`endif
|
||||
ep_cnt2 = ep_cnt2 + 1;
|
||||
`ifdef USBF_HAVE_EP5
|
||||
if(!ep_check[ep_cnt2-1])
|
||||
$display("ERROR: USBF_TOP: Endpoint %0d not defined but endpoint %0d defined", ep_cnt2, ep_cnt2+1);
|
||||
ep_cnt = ep_cnt + 1;
|
||||
ep_check[ep_cnt2] = 1;
|
||||
`endif
|
||||
ep_cnt2 = ep_cnt2 + 1;
|
||||
`ifdef USBF_HAVE_EP6
|
||||
if(!ep_check[ep_cnt2-1])
|
||||
$display("ERROR: USBF_TOP: Endpoint %0d not defined but endpoint %0d defined", ep_cnt2, ep_cnt2+1);
|
||||
ep_cnt = ep_cnt + 1;
|
||||
ep_check[ep_cnt2] = 1;
|
||||
`endif
|
||||
ep_cnt2 = ep_cnt2 + 1;
|
||||
`ifdef USBF_HAVE_EP7
|
||||
if(!ep_check[ep_cnt2-1])
|
||||
$display("ERROR: USBF_TOP: Endpoint %0d not defined but endpoint %0d defined", ep_cnt2, ep_cnt2+1);
|
||||
ep_cnt = ep_cnt + 1;
|
||||
ep_check[ep_cnt2] = 1;
|
||||
`endif
|
||||
ep_cnt2 = ep_cnt2 + 1;
|
||||
`ifdef USBF_HAVE_EP8
|
||||
if(!ep_check[ep_cnt2-1])
|
||||
$display("ERROR: USBF_TOP: Endpoint %0d not defined but endpoint %0d defined", ep_cnt2, ep_cnt2+1);
|
||||
ep_cnt = ep_cnt + 1;
|
||||
ep_check[ep_cnt2] = 1;
|
||||
`endif
|
||||
ep_cnt2 = ep_cnt2 + 1;
|
||||
`ifdef USBF_HAVE_EP9
|
||||
if(!ep_check[ep_cnt2-1])
|
||||
$display("ERROR: USBF_TOP: Endpoint %0d not defined but endpoint %0d defined", ep_cnt2, ep_cnt2+1);
|
||||
ep_cnt = ep_cnt + 1;
|
||||
ep_check[ep_cnt2] = 1;
|
||||
`endif
|
||||
ep_cnt2 = ep_cnt2 + 1;
|
||||
`ifdef USBF_HAVE_EP10
|
||||
if(!ep_check[ep_cnt2-1])
|
||||
$display("ERROR: USBF_TOP: Endpoint %0d not defined but endpoint %0d defined", ep_cnt2, ep_cnt2+1);
|
||||
ep_cnt = ep_cnt + 1;
|
||||
ep_check[ep_cnt2] = 1;
|
||||
`endif
|
||||
ep_cnt2 = ep_cnt2 + 1;
|
||||
`ifdef USBF_HAVE_EP11
|
||||
if(!ep_check[ep_cnt2-1])
|
||||
$display("ERROR: USBF_TOP: Endpoint %0d not defined but endpoint %0d defined", ep_cnt2, ep_cnt2+1);
|
||||
ep_cnt = ep_cnt + 1;
|
||||
ep_check[ep_cnt2] = 1;
|
||||
`endif
|
||||
ep_cnt2 = ep_cnt2 + 1;
|
||||
`ifdef USBF_HAVE_EP12
|
||||
if(!ep_check[ep_cnt2-1])
|
||||
$display("ERROR: USBF_TOP: Endpoint %0d not defined but endpoint %0d defined", ep_cnt2, ep_cnt2+1);
|
||||
ep_cnt = ep_cnt + 1;
|
||||
ep_check[ep_cnt2] = 1;
|
||||
`endif
|
||||
ep_cnt2 = ep_cnt2 + 1;
|
||||
`ifdef USBF_HAVE_EP13
|
||||
if(!ep_check[ep_cnt2-1])
|
||||
$display("ERROR: USBF_TOP: Endpoint %0d not defined but endpoint %0d defined", ep_cnt2, ep_cnt2+1);
|
||||
ep_cnt = ep_cnt + 1;
|
||||
ep_check[ep_cnt2] = 1;
|
||||
`endif
|
||||
ep_cnt2 = ep_cnt2 + 1;
|
||||
`ifdef USBF_HAVE_EP14
|
||||
if(!ep_check[ep_cnt2-1])
|
||||
$display("ERROR: USBF_TOP: Endpoint %0d not defined but endpoint %0d defined", ep_cnt2, ep_cnt2+1);
|
||||
ep_cnt = ep_cnt + 1;
|
||||
ep_check[ep_cnt2] = 1;
|
||||
`endif
|
||||
ep_cnt2 = ep_cnt2 + 1;
|
||||
`ifdef USBF_HAVE_EP15
|
||||
if(!ep_check[ep_cnt2-1])
|
||||
$display("ERROR: USBF_TOP: Endpoint %0d not defined but endpoint %0d defined", ep_cnt2, ep_cnt2+1);
|
||||
ep_cnt = ep_cnt + 1;
|
||||
ep_check[ep_cnt2] = 1;
|
||||
`endif
|
||||
|
||||
$display("");
|
||||
$display("INFO: USB Function core instantiated (%m)");
|
||||
$display(" Supported Endpoints: %0d (0 through %0d)",ep_cnt, ep_cnt-1);
|
||||
$display(" WISHBONE Address bus size: A%0d:0", `USBF_UFC_HADR );
|
||||
$display(" SSRAM Address bus size: A%0d:0", SSRAM_HADR );
|
||||
$display(" Buffer Memory Size: %0d bytes", (1<<SSRAM_HADR+1) * 4 );
|
||||
$display("");
|
||||
|
||||
end
|
||||
|
||||
// synopsys translate_on
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
@@ -0,0 +1,255 @@
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// UTMI Interface ////
|
||||
//// ////
|
||||
//// ////
|
||||
//// Author: Rudolf Usselmann ////
|
||||
//// rudi@asics.ws ////
|
||||
//// ////
|
||||
//// ////
|
||||
//// Downloaded from: http://www.opencores.org/cores/usb/ ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2000-2003 Rudolf Usselmann ////
|
||||
//// www.asics.ws ////
|
||||
//// rudi@asics.ws ////
|
||||
//// ////
|
||||
//// This source file may be used and distributed without ////
|
||||
//// restriction provided that this copyright statement is not ////
|
||||
//// removed from the file and that any derivative work contains ////
|
||||
//// the original copyright notice and the associated disclaimer.////
|
||||
//// ////
|
||||
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
|
||||
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
|
||||
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
|
||||
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
|
||||
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
|
||||
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
|
||||
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
|
||||
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
|
||||
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
|
||||
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
|
||||
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
|
||||
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
|
||||
//// POSSIBILITY OF SUCH DAMAGE. ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
// CVS Log
|
||||
//
|
||||
// $Id: usbf_utmi_if.v,v 1.5 2003-11-11 07:15:16 rudi Exp $
|
||||
//
|
||||
// $Date: 2003-11-11 07:15:16 $
|
||||
// $Revision: 1.5 $
|
||||
// $Author: rudi $
|
||||
// $Locker: $
|
||||
// $State: Exp $
|
||||
//
|
||||
// Change History:
|
||||
// $Log: not supported by cvs2svn $
|
||||
// Revision 1.4 2003/10/17 02:36:57 rudi
|
||||
// - Disabling bit stuffing and NRZI encoding during speed negotiation
|
||||
// - Now the core can send zero size packets
|
||||
// - Fixed register addresses for some of the higher endpoints
|
||||
// (conversion between decimal/hex was wrong)
|
||||
// - The core now does properly evaluate the function address to
|
||||
// determine if the packet was intended for it.
|
||||
// - Various other minor bugs and typos
|
||||
//
|
||||
// Revision 1.3 2001/11/04 12:22:45 rudi
|
||||
//
|
||||
// - Fixed previous fix (brocke something else ...)
|
||||
// - Majore Synthesis cleanup
|
||||
//
|
||||
// Revision 1.2 2001/09/24 01:15:28 rudi
|
||||
//
|
||||
// Changed reset to be active high async.
|
||||
//
|
||||
// Revision 1.1 2001/08/03 05:30:09 rudi
|
||||
//
|
||||
//
|
||||
// 1) Reorganized directory structure
|
||||
//
|
||||
// Revision 1.2 2001/03/31 13:00:52 rudi
|
||||
//
|
||||
// - Added Core configuration
|
||||
// - Added handling of OUT packets less than MAX_PL_SZ in DMA mode
|
||||
// - Modified WISHBONE interface and sync logic
|
||||
// - Moved SSRAM outside the core (added interface)
|
||||
// - Many small bug fixes ...
|
||||
//
|
||||
// Revision 1.0 2001/03/07 09:17:12 rudi
|
||||
//
|
||||
//
|
||||
// Changed all revisions to revision 1.0. This is because OpenCores CVS
|
||||
// interface could not handle the original '0.1' revision ....
|
||||
//
|
||||
// Revision 0.2 2001/03/07 09:08:13 rudi
|
||||
//
|
||||
// Added USB control signaling (Line Status) block. Fixed some minor
|
||||
// typos, added resume bit and signal.
|
||||
//
|
||||
// Revision 0.1.0.1 2001/02/28 08:11:45 rudi
|
||||
// Initial Release
|
||||
//
|
||||
//
|
||||
|
||||
`include "usbf_defines.v"
|
||||
|
||||
module usbf_utmi_if( // UTMI Interface (EXTERNAL)
|
||||
phy_clk, rst,
|
||||
DataOut, TxValid, TxReady,
|
||||
RxValid, RxActive, RxError, DataIn,
|
||||
XcvSelect, TermSel, SuspendM, LineState,
|
||||
OpMode, usb_vbus,
|
||||
|
||||
// Internal Interface
|
||||
rx_data, rx_valid, rx_active, rx_err,
|
||||
tx_data, tx_valid, tx_valid_last, tx_ready,
|
||||
tx_first,
|
||||
|
||||
// Misc Interfaces
|
||||
mode_hs, usb_reset, usb_suspend, usb_attached,
|
||||
resume_req, suspend_clr
|
||||
);
|
||||
|
||||
input phy_clk;
|
||||
//input wclk;
|
||||
input rst;
|
||||
|
||||
output [7:0] DataOut;
|
||||
output TxValid;
|
||||
input TxReady;
|
||||
|
||||
input [7:0] DataIn;
|
||||
input RxValid;
|
||||
input RxActive;
|
||||
input RxError;
|
||||
|
||||
output XcvSelect;
|
||||
output TermSel;
|
||||
output SuspendM;
|
||||
input [1:0] LineState;
|
||||
output [1:0] OpMode;
|
||||
input usb_vbus;
|
||||
|
||||
output [7:0] rx_data;
|
||||
output rx_valid, rx_active, rx_err;
|
||||
input [7:0] tx_data;
|
||||
input tx_valid;
|
||||
input tx_valid_last;
|
||||
output tx_ready;
|
||||
input tx_first;
|
||||
|
||||
output mode_hs; // High Speed Mode
|
||||
output usb_reset; // USB Reset
|
||||
output usb_suspend; // USB Suspend
|
||||
output usb_attached; // Attached to USB
|
||||
input resume_req;
|
||||
|
||||
output suspend_clr;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Local Wires and Registers
|
||||
//
|
||||
reg [7:0] rx_data;
|
||||
reg rx_valid, rx_active, rx_err;
|
||||
reg [7:0] DataOut;
|
||||
reg tx_ready;
|
||||
reg TxValid;
|
||||
wire drive_k;
|
||||
reg drive_k_r;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Misc Logic
|
||||
//
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// RX Interface Input registers
|
||||
//
|
||||
|
||||
`ifdef USBF_ASYNC_RESET
|
||||
always @(posedge phy_clk or negedge rst)
|
||||
`else
|
||||
always @(posedge phy_clk)
|
||||
`endif
|
||||
if(!rst) rx_valid <= 1'b0;
|
||||
else rx_valid <= RxValid;
|
||||
|
||||
`ifdef USBF_ASYNC_RESET
|
||||
always @(posedge phy_clk or negedge rst)
|
||||
`else
|
||||
always @(posedge phy_clk)
|
||||
`endif
|
||||
if(!rst) rx_active <= 1'b0;
|
||||
else rx_active <= RxActive;
|
||||
|
||||
`ifdef USBF_ASYNC_RESET
|
||||
always @(posedge phy_clk or negedge rst)
|
||||
`else
|
||||
always @(posedge phy_clk)
|
||||
`endif
|
||||
if(!rst) rx_err <= 1'b0;
|
||||
else rx_err <= RxError;
|
||||
|
||||
always @(posedge phy_clk)
|
||||
rx_data <= DataIn;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TX Interface Output/Input registers
|
||||
//
|
||||
|
||||
always @(posedge phy_clk)
|
||||
if(TxReady || tx_first) DataOut <= tx_data;
|
||||
else
|
||||
if(drive_k) DataOut <= 8'h00;
|
||||
|
||||
always @(posedge phy_clk)
|
||||
tx_ready <= TxReady;
|
||||
|
||||
always @(posedge phy_clk)
|
||||
drive_k_r <= drive_k;
|
||||
|
||||
|
||||
`ifdef USBF_ASYNC_RESET
|
||||
always @(posedge phy_clk or negedge rst)
|
||||
`else
|
||||
always @(posedge phy_clk)
|
||||
`endif
|
||||
if(!rst) TxValid <= 1'b0;
|
||||
else
|
||||
TxValid <= tx_valid | drive_k | tx_valid_last | (TxValid & !(TxReady | drive_k_r));
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Line Status Signaling & Speed Negotiation Block
|
||||
//
|
||||
|
||||
usbf_utmi_ls u0(
|
||||
.clk( phy_clk ),
|
||||
.rst( rst ),
|
||||
.resume_req( resume_req ),
|
||||
.rx_active( rx_active ),
|
||||
.tx_ready( tx_ready ),
|
||||
.drive_k( drive_k ),
|
||||
.XcvSelect( XcvSelect ),
|
||||
.TermSel( TermSel ),
|
||||
.SuspendM( SuspendM ),
|
||||
.LineState( LineState ),
|
||||
.OpMode( OpMode ),
|
||||
.usb_vbus( usb_vbus ),
|
||||
.mode_hs( mode_hs ),
|
||||
.usb_reset( usb_reset ),
|
||||
.usb_suspend( usb_suspend ),
|
||||
.usb_attached( usb_attached ),
|
||||
.suspend_clr( suspend_clr )
|
||||
);
|
||||
|
||||
endmodule
|
||||
|
||||
@@ -0,0 +1,651 @@
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// UTMI Line Status & Speed Negotiation block ////
|
||||
//// ////
|
||||
//// ////
|
||||
//// Author: Rudolf Usselmann ////
|
||||
//// rudi@asics.ws ////
|
||||
//// ////
|
||||
//// ////
|
||||
//// Downloaded from: http://www.opencores.org/cores/usb/ ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2000-2003 Rudolf Usselmann ////
|
||||
//// www.asics.ws ////
|
||||
//// rudi@asics.ws ////
|
||||
//// ////
|
||||
//// This source file may be used and distributed without ////
|
||||
//// restriction provided that this copyright statement is not ////
|
||||
//// removed from the file and that any derivative work contains ////
|
||||
//// the original copyright notice and the associated disclaimer.////
|
||||
//// ////
|
||||
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
|
||||
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
|
||||
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
|
||||
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
|
||||
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
|
||||
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
|
||||
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
|
||||
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
|
||||
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
|
||||
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
|
||||
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
|
||||
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
|
||||
//// POSSIBILITY OF SUCH DAMAGE. ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
// CVS Log
|
||||
//
|
||||
// $Id: usbf_utmi_ls.v,v 1.6 2003-11-11 07:15:16 rudi Exp $
|
||||
//
|
||||
// $Date: 2003-11-11 07:15:16 $
|
||||
// $Revision: 1.6 $
|
||||
// $Author: rudi $
|
||||
// $Locker: $
|
||||
// $State: Exp $
|
||||
//
|
||||
// Change History:
|
||||
// $Log: not supported by cvs2svn $
|
||||
// Revision 1.5 2003/10/17 02:36:57 rudi
|
||||
// - Disabling bit stuffing and NRZI encoding during speed negotiation
|
||||
// - Now the core can send zero size packets
|
||||
// - Fixed register addresses for some of the higher endpoints
|
||||
// (conversion between decimal/hex was wrong)
|
||||
// - The core now does properly evaluate the function address to
|
||||
// determine if the packet was intended for it.
|
||||
// - Various other minor bugs and typos
|
||||
//
|
||||
// Revision 1.4 2001/11/04 12:22:45 rudi
|
||||
//
|
||||
// - Fixed previous fix (brocke something else ...)
|
||||
// - Majore Synthesis cleanup
|
||||
//
|
||||
// Revision 1.3 2001/09/24 01:15:28 rudi
|
||||
//
|
||||
// Changed reset to be active high async.
|
||||
//
|
||||
// Revision 1.2 2001/08/10 08:48:33 rudi
|
||||
//
|
||||
// - Changed IO names to be more clear.
|
||||
// - Uniquifyed define names to be core specific.
|
||||
//
|
||||
// Revision 1.1 2001/08/03 05:30:09 rudi
|
||||
//
|
||||
//
|
||||
// 1) Reorganized directory structure
|
||||
//
|
||||
// Revision 1.2 2001/03/31 13:00:52 rudi
|
||||
//
|
||||
// - Added Core configuration
|
||||
// - Added handling of OUT packets less than MAX_PL_SZ in DMA mode
|
||||
// - Modified WISHBONE interface and sync logic
|
||||
// - Moved SSRAM outside the core (added interface)
|
||||
// - Many small bug fixes ...
|
||||
//
|
||||
// Revision 1.1 2001/03/07 09:08:13 rudi
|
||||
//
|
||||
// Added USB control signaling (Line Status) block. Fixed some minor
|
||||
// typos, added resume bit and signal.
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
|
||||
`include "usbf_defines.v"
|
||||
|
||||
module usbf_utmi_ls( clk, rst,
|
||||
|
||||
resume_req,
|
||||
|
||||
// UTMI Interface
|
||||
rx_active, tx_ready, drive_k,
|
||||
XcvSelect, TermSel, SuspendM, LineState, OpMode,
|
||||
usb_vbus,
|
||||
|
||||
// Misc Interfaces
|
||||
mode_hs, usb_reset, usb_suspend, usb_attached,
|
||||
suspend_clr
|
||||
);
|
||||
|
||||
input clk;
|
||||
//input wclk;
|
||||
input rst;
|
||||
|
||||
input resume_req;
|
||||
input rx_active, tx_ready;
|
||||
|
||||
output drive_k;
|
||||
output XcvSelect;
|
||||
output TermSel;
|
||||
output SuspendM;
|
||||
input [1:0] LineState;
|
||||
output [1:0] OpMode;
|
||||
input usb_vbus;
|
||||
|
||||
output mode_hs; // High Speed Mode
|
||||
output usb_reset; // USB Reset
|
||||
output usb_suspend; // USB Suspend
|
||||
output usb_attached; // Attached to USB
|
||||
|
||||
output suspend_clr;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Parameters
|
||||
//
|
||||
parameter [14:0] // synopsys enum state
|
||||
POR = 15'b000_0000_0000_0001,
|
||||
NORMAL = 15'b000_0000_0000_0010,
|
||||
RES_SUSP = 15'b000_0000_0000_0100,
|
||||
SUSPEND = 15'b000_0000_0000_1000,
|
||||
RESUME = 15'b000_0000_0001_0000,
|
||||
RESUME_REQUEST = 15'b000_0000_0010_0000,
|
||||
RESUME_WAIT = 15'b000_0000_0100_0000,
|
||||
RESUME_SIG = 15'b000_0000_1000_0000,
|
||||
ATTACH = 15'b000_0001_0000_0000,
|
||||
RESET = 15'b000_0010_0000_0000,
|
||||
SPEED_NEG = 15'b000_0100_0000_0000,
|
||||
SPEED_NEG_K = 15'b000_1000_0000_0000,
|
||||
SPEED_NEG_J = 15'b001_0000_0000_0000,
|
||||
SPEED_NEG_HS = 15'b010_0000_0000_0000,
|
||||
SPEED_NEG_FS = 15'b100_0000_0000_0000;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Local Wires and Registers
|
||||
//
|
||||
|
||||
reg [14:0] /* synopsys enum state */ state, next_state;
|
||||
// synopsys state_vector state
|
||||
|
||||
reg [1:0] line_state_r;
|
||||
|
||||
reg mode_hs, mode_set_hs, mode_set_fs;
|
||||
reg usb_suspend, suspend_set, suspend_clr;
|
||||
reg usb_attached, attached_set, attached_clr;
|
||||
reg TermSel, fs_term_on, fs_term_off;
|
||||
reg XcvSelect, xcv_set_hs, xcv_set_fs;
|
||||
reg [1:0] OpMode;
|
||||
reg bit_stuff_on, bit_stuff_off;
|
||||
reg usb_reset, usb_reset_d;
|
||||
|
||||
wire ls_se0, ls_j, ls_k, ls_se1;
|
||||
reg ls_k_r, ls_j_r, ls_se0_r;
|
||||
reg ls_idle_r;
|
||||
wire ls_idle;
|
||||
reg idle_long;
|
||||
wire idle_long_set, idle_long_clr;
|
||||
wire k_long, j_long, se0_long;
|
||||
|
||||
reg drive_k, drive_k_d;
|
||||
|
||||
reg [3:0] ps_cnt;
|
||||
reg ps_cnt_clr;
|
||||
reg idle_cnt_clr;
|
||||
reg idle_cnt1_clr;
|
||||
reg [7:0] idle_cnt1, idle_cnt1_next;
|
||||
reg T1_gt_2_5_uS, T1_st_3_0_mS, T1_gt_3_0_mS;
|
||||
reg T1_gt_3_125_mS, T1_gt_5_0_mS;
|
||||
reg [7:0] me_ps;
|
||||
reg me_cnt_clr;
|
||||
reg me_ps_2_5_us;
|
||||
reg [7:0] me_ps2;
|
||||
reg me_ps2_0_5_ms;
|
||||
reg [7:0] me_cnt;
|
||||
reg me_cnt_100_ms;
|
||||
reg T2_gt_100_uS, T2_wakeup, T2_gt_1_0_mS, T2_gt_1_2_mS;
|
||||
|
||||
reg [2:0] chirp_cnt;
|
||||
reg chirp_cnt_clr, chirp_cnt_inc;
|
||||
reg chirp_cnt_is_6;
|
||||
|
||||
reg resume_req_s1;
|
||||
reg resume_req_s;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Misc Logic
|
||||
//
|
||||
|
||||
always @(posedge clk)
|
||||
drive_k <= drive_k_d;
|
||||
|
||||
assign SuspendM = (usb_suspend & !resume_req_s) | (LineState == 2'b10);
|
||||
|
||||
always @(posedge clk)
|
||||
resume_req_s1 <= resume_req;
|
||||
|
||||
always @(posedge clk)
|
||||
resume_req_s <= resume_req_s1;
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// USB State/Operation Mode JK Flops
|
||||
always @(posedge clk)
|
||||
if(mode_set_fs) mode_hs <= 1'b0;
|
||||
else
|
||||
if(mode_set_hs) mode_hs <= 1'b1;
|
||||
|
||||
always @(posedge clk)
|
||||
if(suspend_clr) usb_suspend <= 1'b0;
|
||||
else
|
||||
if(suspend_set) usb_suspend <= 1'b1;
|
||||
|
||||
always @(posedge clk)
|
||||
if(attached_clr) usb_attached <= 1'b0;
|
||||
else
|
||||
if(attached_set) usb_attached <= 1'b1;
|
||||
|
||||
always @(posedge clk)
|
||||
if(fs_term_off) TermSel <= 1'b0;
|
||||
else
|
||||
if(fs_term_on) TermSel <= 1'b1;
|
||||
|
||||
always @(posedge clk)
|
||||
if(xcv_set_fs) XcvSelect <= 1'b1;
|
||||
else
|
||||
if(xcv_set_hs) XcvSelect <= 1'b0;
|
||||
|
||||
always @(posedge clk)
|
||||
if(bit_stuff_off) OpMode <= 2'b10;
|
||||
else
|
||||
if(bit_stuff_on) OpMode <= 2'b00;
|
||||
|
||||
always @(posedge clk)
|
||||
usb_reset <= usb_reset_d;
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// Line State Detector
|
||||
|
||||
always @(posedge clk)
|
||||
line_state_r <= LineState;
|
||||
|
||||
assign ls_se0 = (line_state_r == 2'b00);
|
||||
assign ls_j = (line_state_r == 2'b01);
|
||||
assign ls_k = (line_state_r == 2'b10);
|
||||
assign ls_se1 = (line_state_r == 2'b11);
|
||||
|
||||
assign ls_idle = mode_hs ? ls_se0 : ls_j;
|
||||
|
||||
// Idle Detection
|
||||
// Idle Has to persist for at least two cycles in a roe in the
|
||||
// same state to recognized
|
||||
always @(posedge clk)
|
||||
ls_idle_r <= ls_idle;
|
||||
|
||||
assign idle_long_set = ls_idle & ls_idle_r;
|
||||
assign idle_long_clr = !ls_idle & !ls_idle_r;
|
||||
|
||||
`ifdef USBF_ASYNC_RESET
|
||||
always @(posedge clk or negedge rst)
|
||||
`else
|
||||
always @(posedge clk)
|
||||
`endif
|
||||
if(!rst) idle_long <= 1'b0;
|
||||
else
|
||||
if(idle_long_clr) idle_long <= 1'b0;
|
||||
else
|
||||
if(idle_long_set) idle_long <= 1'b1;
|
||||
|
||||
// Detect Signals for two cycles ina row before making a transaction ...
|
||||
always @(posedge clk)
|
||||
ls_k_r <= ls_k;
|
||||
|
||||
always @(posedge clk)
|
||||
ls_j_r <= ls_j;
|
||||
|
||||
always @(posedge clk)
|
||||
ls_se0_r <= ls_se0;
|
||||
|
||||
assign k_long = ls_k & ls_k_r;
|
||||
assign j_long = ls_j & ls_j_r;
|
||||
assign se0_long = ls_se0 & ls_se0_r;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Counters
|
||||
//
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// idle Counter
|
||||
|
||||
// Pre-Scaler
|
||||
// Generates a 0.25 uS Count Enable (ps_cnt_clr)
|
||||
always @(posedge clk)
|
||||
if(!idle_long || idle_cnt_clr || ps_cnt_clr) ps_cnt <= 4'd0;
|
||||
else ps_cnt <= ps_cnt + 4'd1;
|
||||
|
||||
always @(posedge clk) // Clear the pre-scaler in 250 nS intervals
|
||||
ps_cnt_clr <= (ps_cnt == `USBF_T1_PS_250_NS);
|
||||
|
||||
// Count uS
|
||||
always @(posedge clk)
|
||||
if(!idle_long || idle_cnt1_clr || idle_cnt_clr) idle_cnt1 <= 8'h0;
|
||||
else
|
||||
if(!T1_gt_5_0_mS && ps_cnt_clr) idle_cnt1 <= idle_cnt1_next;
|
||||
|
||||
always @(posedge clk)
|
||||
idle_cnt1_next <= idle_cnt1 + 8'h1;
|
||||
|
||||
always @(posedge clk) // Clear the uS counter every 62.5 uS
|
||||
idle_cnt1_clr <= idle_cnt1 == `USBF_T1_C_62_5_US;
|
||||
|
||||
always @(posedge clk) // Greater Than 2.5uS (Actual Time will be T0+2.75uS)
|
||||
T1_gt_2_5_uS <= !idle_cnt_clr & (idle_cnt1 > `USBF_T1_C_2_5_US);
|
||||
|
||||
always @(posedge clk) // Smaller Than 3 mS (Actual Time will be 0-2.9375mS)
|
||||
T1_st_3_0_mS <= !idle_cnt_clr & (idle_cnt1 < `USBF_T1_C_3_0_MS);
|
||||
|
||||
always @(posedge clk) // Greater Than 3 mS (Actual Time will be T0+3.0625mS)
|
||||
T1_gt_3_0_mS <= !idle_cnt_clr & (idle_cnt1 > `USBF_T1_C_3_0_MS);
|
||||
|
||||
always @(posedge clk) // Greater Than 3.125 mS (Actual Time will be T0+3.1875uS)
|
||||
T1_gt_3_125_mS <= !idle_cnt_clr & (idle_cnt1 > `USBF_T1_C_3_125_MS);
|
||||
|
||||
always @(posedge clk) // Greater Than 3.125 mS (Actual Time will be T0+3.1875uS)
|
||||
T1_gt_5_0_mS <= !idle_cnt_clr & (idle_cnt1 > `USBF_T1_C_5_MS);
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// Misc Events Counter
|
||||
|
||||
// Pre-scaler - 2.5uS
|
||||
always @(posedge clk)
|
||||
if(me_cnt_clr || me_ps_2_5_us) me_ps <= 8'h0;
|
||||
else me_ps <= me_ps + 8'h1;
|
||||
|
||||
always @(posedge clk) // Generate a pulse every 2.5 uS
|
||||
me_ps_2_5_us <= (me_ps == `USBF_T2_C_2_5_US);
|
||||
|
||||
// Second Pre-scaler - 0.5mS
|
||||
always @(posedge clk)
|
||||
if(me_cnt_clr || me_ps2_0_5_ms ) me_ps2 <= 8'h0;
|
||||
else
|
||||
if(me_ps_2_5_us) me_ps2 <= me_ps2 + 8'h1;
|
||||
|
||||
always @(posedge clk) // Generate a pulse every 0.5 mS
|
||||
me_ps2_0_5_ms <= (me_ps2 == `USBF_T2_C_0_5_MS) & !me_ps2_0_5_ms;
|
||||
|
||||
// final misc Counter
|
||||
always @(posedge clk)
|
||||
if(me_cnt_clr) me_cnt <= 8'h0;
|
||||
else
|
||||
if(!me_cnt_100_ms && me_ps2_0_5_ms) me_cnt <= me_cnt + 8'h1;
|
||||
|
||||
always @(posedge clk) // Indicate when 100uS have passed
|
||||
T2_gt_100_uS <= !me_cnt_clr & (me_ps2 > `USBF_T2_C_100_US); // Actual Time: 102.5 uS
|
||||
|
||||
always @(posedge clk) // Indicate when wakeup period has passed
|
||||
T2_wakeup <= !me_cnt_clr & (me_cnt > `USBF_T2_C_WAKEUP);
|
||||
|
||||
always @(posedge clk) // Indicate when 1 mS has passed
|
||||
T2_gt_1_0_mS <= !me_cnt_clr & (me_cnt > `USBF_T2_C_1_0_MS); // Actual Time: 1.5 mS
|
||||
|
||||
always @(posedge clk) // Indicate when 1.2 mS has passed
|
||||
T2_gt_1_2_mS <= !me_cnt_clr & (me_cnt > `USBF_T2_C_1_2_MS); // Actual Time: 1.5 mS
|
||||
|
||||
always @(posedge clk) // Generate a pulse after 100 mS
|
||||
me_cnt_100_ms <= !me_cnt_clr & (me_cnt == `USBF_T2_C_100_MS); // Actual Time: 100 mS
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// Chirp Counter
|
||||
|
||||
always @(posedge clk)
|
||||
if(chirp_cnt_clr) chirp_cnt <= 3'h0;
|
||||
else
|
||||
if(chirp_cnt_inc) chirp_cnt <= chirp_cnt + 3'h1;
|
||||
|
||||
always @(posedge clk)
|
||||
chirp_cnt_is_6 <= (chirp_cnt == 3'h6);
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Main State Machine
|
||||
//
|
||||
|
||||
`ifdef USBF_ASYNC_RESET
|
||||
always @(posedge clk or negedge rst)
|
||||
`else
|
||||
always @(posedge clk)
|
||||
`endif
|
||||
if(!rst) state <= POR;
|
||||
else
|
||||
if(usb_vbus) state <= POR;
|
||||
else state <= next_state;
|
||||
|
||||
always @(state or mode_hs or idle_long or resume_req_s or me_cnt_100_ms or
|
||||
j_long or k_long or se0_long or ls_se0 or
|
||||
T1_gt_2_5_uS or T1_st_3_0_mS or T1_gt_3_0_mS or
|
||||
T1_gt_5_0_mS or T2_gt_100_uS or T2_wakeup or T2_gt_1_0_mS or
|
||||
T2_gt_1_2_mS or chirp_cnt_is_6)
|
||||
begin
|
||||
next_state = state; // Default don't change state
|
||||
|
||||
mode_set_hs = 1'b0;
|
||||
mode_set_fs = 1'b0;
|
||||
suspend_set = 1'b0;
|
||||
suspend_clr = 1'b0;
|
||||
attached_set = 1'b0;
|
||||
attached_clr = 1'b0;
|
||||
usb_reset_d = 1'b0;
|
||||
|
||||
fs_term_on = 1'b0;
|
||||
fs_term_off = 1'b0;
|
||||
xcv_set_hs = 1'b0;
|
||||
xcv_set_fs = 1'b0;
|
||||
bit_stuff_on = 1'b0;
|
||||
bit_stuff_off = 1'b0;
|
||||
|
||||
idle_cnt_clr = 1'b0;
|
||||
me_cnt_clr = 1'b0;
|
||||
drive_k_d = 1'b0;
|
||||
chirp_cnt_clr = 1'b0;
|
||||
chirp_cnt_inc = 1'b0;
|
||||
|
||||
case(state) // synopsys full_case parallel_case
|
||||
POR: // Power On/Reset
|
||||
begin
|
||||
me_cnt_clr = 1'b1;
|
||||
xcv_set_fs = 1'b1;
|
||||
fs_term_on = 1'b1;
|
||||
mode_set_fs = 1'b1;
|
||||
attached_clr = 1'b1;
|
||||
bit_stuff_on = 1'b0;
|
||||
suspend_clr = 1'b1;
|
||||
next_state = ATTACH;
|
||||
end
|
||||
|
||||
NORMAL: // Normal Operation
|
||||
begin
|
||||
if(!mode_hs && T1_gt_2_5_uS && T1_st_3_0_mS && !idle_long)
|
||||
begin
|
||||
me_cnt_clr = 1'b1;
|
||||
next_state = RESET;
|
||||
end
|
||||
else
|
||||
if(!mode_hs && T1_gt_3_0_mS)
|
||||
begin
|
||||
idle_cnt_clr = 1'b1;
|
||||
suspend_set = 1'b1;
|
||||
next_state = SUSPEND;
|
||||
end
|
||||
else
|
||||
if(mode_hs && T1_gt_3_0_mS)
|
||||
begin // Switch to FS mode, and decide
|
||||
// if it's a RESET or SUSPEND
|
||||
me_cnt_clr = 1'b1;
|
||||
xcv_set_fs = 1'b1;
|
||||
fs_term_on = 1'b1;
|
||||
next_state = RES_SUSP;
|
||||
end
|
||||
end
|
||||
|
||||
RES_SUSP: // Decide if it's a Reset or Suspend Signaling
|
||||
begin // We are now in FS mode, wait 100uS first
|
||||
if(T2_gt_100_uS && se0_long)
|
||||
begin
|
||||
me_cnt_clr = 1'b1;
|
||||
next_state = RESET;
|
||||
end
|
||||
else
|
||||
if(T2_gt_100_uS && j_long)
|
||||
begin
|
||||
idle_cnt_clr = 1'b1;
|
||||
suspend_set = 1'b1;
|
||||
next_state = SUSPEND;
|
||||
end
|
||||
end
|
||||
|
||||
SUSPEND: // In Suspend
|
||||
begin
|
||||
if(T1_gt_2_5_uS && se0_long)
|
||||
begin
|
||||
suspend_clr = 1'b1;
|
||||
me_cnt_clr = 1'b1;
|
||||
next_state = RESET;
|
||||
end
|
||||
else
|
||||
if(k_long) // Start Resuming
|
||||
next_state = RESUME;
|
||||
else
|
||||
if(T1_gt_5_0_mS && resume_req_s)
|
||||
next_state = RESUME_REQUEST;
|
||||
end
|
||||
|
||||
RESUME:
|
||||
begin
|
||||
suspend_clr = 1'b1;
|
||||
if(ls_se0)
|
||||
begin
|
||||
if(mode_hs)
|
||||
begin // Switch Back to HS mode
|
||||
xcv_set_hs = 1'b1;
|
||||
fs_term_off = 1'b1;
|
||||
end
|
||||
bit_stuff_on = 1'b1; // Enable Bit Stuffing and NRZI encoding
|
||||
me_cnt_clr = 1'b1;
|
||||
next_state = RESUME_WAIT;
|
||||
end
|
||||
end
|
||||
|
||||
RESUME_WAIT:
|
||||
begin
|
||||
if(T2_gt_100_uS) next_state = NORMAL;
|
||||
end
|
||||
|
||||
RESUME_REQUEST: // Function Resume Request
|
||||
begin
|
||||
suspend_clr = 1'b1;
|
||||
// Wait for internal wake up
|
||||
if(T2_wakeup)
|
||||
begin
|
||||
fs_term_on = 1'b1; // Switch Termination to Full Speed
|
||||
bit_stuff_off = 1'b1; // disable Bit Stuffing and NRZI encoding
|
||||
me_cnt_clr = 1'b1;
|
||||
next_state = RESUME_SIG;
|
||||
end
|
||||
end
|
||||
|
||||
RESUME_SIG: // Signal resume
|
||||
begin
|
||||
// Drive Resume ('K') for 1-15 mS
|
||||
drive_k_d = 1'b1;
|
||||
// Stop driving after 1.5 mS
|
||||
if(T2_gt_1_0_mS) next_state = RESUME;
|
||||
end
|
||||
|
||||
ATTACH: // Attach To USB Detected
|
||||
begin
|
||||
idle_cnt_clr = 1'b1;
|
||||
if(me_cnt_100_ms)
|
||||
//if(me_cnt_100_ms && j_long)
|
||||
begin
|
||||
attached_set = 1'b1;
|
||||
next_state = NORMAL;
|
||||
end
|
||||
/*
|
||||
if(me_cnt_100_ms && se0_long)
|
||||
begin
|
||||
attached_set = 1'b1;
|
||||
me_cnt_clr = 1'b1;
|
||||
next_state = RESET;
|
||||
end
|
||||
*/
|
||||
end
|
||||
|
||||
RESET: // In Reset
|
||||
begin
|
||||
usb_reset_d = 1'b1; // Assert Internal USB Reset
|
||||
xcv_set_hs = 1'b1; // Switch xcvr to HS mode
|
||||
fs_term_on = 1'b1; // Turn FS termination On
|
||||
mode_set_fs = 1'b1; // Change mode to FS
|
||||
bit_stuff_off = 1'b1; // disable Bit Stuffing and NRZI encoding
|
||||
// Get out of reset after 1.5 mS
|
||||
if(T2_gt_1_0_mS)
|
||||
begin
|
||||
me_cnt_clr = 1'b1;
|
||||
next_state = SPEED_NEG;
|
||||
end
|
||||
end
|
||||
|
||||
SPEED_NEG: // Speed Negotiation
|
||||
begin
|
||||
drive_k_d = 1'b1;
|
||||
chirp_cnt_clr = 1'b1;
|
||||
// Start looking for 'K' after 1.5 mS
|
||||
if(T2_gt_1_2_mS) next_state = SPEED_NEG_K;
|
||||
end
|
||||
|
||||
SPEED_NEG_K:
|
||||
begin
|
||||
if(chirp_cnt_is_6) next_state = SPEED_NEG_HS;
|
||||
else
|
||||
begin
|
||||
if(k_long)
|
||||
begin
|
||||
chirp_cnt_inc = 1'b1;
|
||||
next_state = SPEED_NEG_J;
|
||||
end
|
||||
if(se0_long)
|
||||
next_state = SPEED_NEG_FS;
|
||||
end
|
||||
end
|
||||
|
||||
SPEED_NEG_J:
|
||||
begin
|
||||
if(chirp_cnt_is_6) next_state = SPEED_NEG_HS;
|
||||
else
|
||||
begin
|
||||
if(j_long)
|
||||
begin
|
||||
chirp_cnt_inc = 1'b1;
|
||||
next_state = SPEED_NEG_K;
|
||||
end
|
||||
if(se0_long)
|
||||
next_state = SPEED_NEG_FS;
|
||||
end
|
||||
end
|
||||
|
||||
SPEED_NEG_HS:
|
||||
begin
|
||||
bit_stuff_on = 1'b1; // Enable Bit Stuffing and NRZI encoding
|
||||
xcv_set_hs = 1'b1; // Switch xcvr to HS mode
|
||||
fs_term_off = 1'b1; // Turn FS termination Off
|
||||
mode_set_hs = 1'b1; // Change mode to HS
|
||||
if(se0_long) next_state = NORMAL;
|
||||
end
|
||||
|
||||
SPEED_NEG_FS:
|
||||
begin
|
||||
bit_stuff_on = 1'b1; // Enable Bit Stuffing and NRZI encoding
|
||||
xcv_set_fs = 1'b1; // Switch xcvr to FS mode
|
||||
fs_term_on = 1'b1; // Turn FS termination On
|
||||
mode_set_fs = 1'b1; // Change mode to FS
|
||||
next_state = NORMAL;
|
||||
end
|
||||
|
||||
endcase
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
@@ -0,0 +1,273 @@
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// WISHBONE Interface ////
|
||||
//// This is the external bus interface, that is WISHBONE ////
|
||||
//// SoC compliant. ////
|
||||
//// ////
|
||||
//// ////
|
||||
//// Author: Rudolf Usselmann ////
|
||||
//// rudi@asics.ws ////
|
||||
//// ////
|
||||
//// ////
|
||||
//// Downloaded from: http://www.opencores.org/cores/usb/ ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2000-2003 Rudolf Usselmann ////
|
||||
//// www.asics.ws ////
|
||||
//// rudi@asics.ws ////
|
||||
//// ////
|
||||
//// This source file may be used and distributed without ////
|
||||
//// restriction provided that this copyright statement is not ////
|
||||
//// removed from the file and that any derivative work contains ////
|
||||
//// the original copyright notice and the associated disclaimer.////
|
||||
//// ////
|
||||
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
|
||||
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
|
||||
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
|
||||
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
|
||||
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
|
||||
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
|
||||
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
|
||||
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
|
||||
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
|
||||
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
|
||||
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
|
||||
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
|
||||
//// POSSIBILITY OF SUCH DAMAGE. ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
// CVS Log
|
||||
//
|
||||
// $Id: usbf_wb.v,v 1.4 2003-10-17 02:36:57 rudi Exp $
|
||||
//
|
||||
// $Date: 2003-10-17 02:36:57 $
|
||||
// $Revision: 1.4 $
|
||||
// $Author: rudi $
|
||||
// $Locker: $
|
||||
// $State: Exp $
|
||||
//
|
||||
// Change History:
|
||||
// $Log: not supported by cvs2svn $
|
||||
// Revision 1.3 2001/09/24 01:15:28 rudi
|
||||
//
|
||||
// Changed reset to be active high async.
|
||||
//
|
||||
// Revision 1.2 2001/08/10 08:48:33 rudi
|
||||
//
|
||||
// - Changed IO names to be more clear.
|
||||
// - Uniquifyed define names to be core specific.
|
||||
//
|
||||
// Revision 1.1 2001/08/03 05:30:09 rudi
|
||||
//
|
||||
//
|
||||
// 1) Reorganized directory structure
|
||||
//
|
||||
// Revision 1.2 2001/03/31 13:00:52 rudi
|
||||
//
|
||||
// - Added Core configuration
|
||||
// - Added handling of OUT packets less than MAX_PL_SZ in DMA mode
|
||||
// - Modified WISHBONE interface and sync logic
|
||||
// - Moved SSRAM outside the core (added interface)
|
||||
// - Many small bug fixes ...
|
||||
//
|
||||
// Revision 1.0 2001/03/07 09:17:12 rudi
|
||||
//
|
||||
//
|
||||
// Changed all revisions to revision 1.0. This is because OpenCores CVS
|
||||
// interface could not handle the original '0.1' revision ....
|
||||
//
|
||||
// Revision 0.1.0.1 2001/02/28 08:11:47 rudi
|
||||
// Initial Release
|
||||
//
|
||||
//
|
||||
|
||||
`include "usbf_defines.v"
|
||||
|
||||
module usbf_wb( // WISHBONE Interface
|
||||
wb_clk, phy_clk, rst, wb_addr_i, wb_data_i, wb_data_o,
|
||||
wb_ack_o, wb_we_i, wb_stb_i, wb_cyc_i,
|
||||
|
||||
// Memory Arbiter Interface
|
||||
ma_adr, ma_dout, ma_din, ma_we, ma_req, ma_ack,
|
||||
|
||||
// Register File interface
|
||||
rf_re, rf_we, rf_din, rf_dout);
|
||||
|
||||
input wb_clk, phy_clk;
|
||||
input rst;
|
||||
input [`USBF_UFC_HADR:0] wb_addr_i;
|
||||
input [31:0] wb_data_i;
|
||||
output [31:0] wb_data_o;
|
||||
output wb_ack_o;
|
||||
input wb_we_i;
|
||||
input wb_stb_i;
|
||||
input wb_cyc_i;
|
||||
|
||||
// Memory Arbiter Interface
|
||||
output [`USBF_UFC_HADR:0] ma_adr;
|
||||
output [31:0] ma_dout;
|
||||
input [31:0] ma_din;
|
||||
output ma_we;
|
||||
output ma_req;
|
||||
input ma_ack;
|
||||
|
||||
// Register File interface
|
||||
output rf_re;
|
||||
output rf_we;
|
||||
input [31:0] rf_din;
|
||||
output [31:0] rf_dout;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Local Wires and Registers
|
||||
//
|
||||
|
||||
parameter [5:0] // synopsys enum state
|
||||
IDLE = 6'b00_0001,
|
||||
MA_WR = 6'b00_0010,
|
||||
MA_RD = 6'b00_0100,
|
||||
W0 = 6'b00_1000,
|
||||
W1 = 6'b01_0000,
|
||||
W2 = 6'b10_0000;
|
||||
|
||||
reg [5:0] /* synopsys enum state */ state, next_state;
|
||||
// synopsys state_vector state
|
||||
|
||||
reg wb_req_s1;
|
||||
reg wb_ack_d, wb_ack_s1, wb_ack_s1a, wb_ack_s2;
|
||||
reg ma_we;
|
||||
reg rf_re, rf_we_d;
|
||||
reg ma_req;
|
||||
reg wb_ack_o;
|
||||
reg [31:0] wb_data_o;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Interface Logic
|
||||
//
|
||||
|
||||
assign ma_adr = wb_addr_i;
|
||||
assign ma_dout = wb_data_i;
|
||||
assign rf_dout = wb_data_i;
|
||||
|
||||
always @(posedge wb_clk)
|
||||
if( `USBF_RF_SEL ) wb_data_o <= rf_din;
|
||||
else wb_data_o <= ma_din;
|
||||
|
||||
// Sync WISHBONE Request
|
||||
always @(posedge phy_clk)
|
||||
wb_req_s1 <= wb_stb_i & wb_cyc_i;
|
||||
|
||||
// Sync WISHBONE Ack
|
||||
always @(posedge wb_clk)
|
||||
wb_ack_s1 <= wb_ack_d;
|
||||
|
||||
always @(posedge wb_clk)
|
||||
wb_ack_o <= wb_ack_s1 & !wb_ack_s2 & !wb_ack_o;
|
||||
|
||||
always @(posedge wb_clk)
|
||||
wb_ack_s1a <= wb_ack_s1;
|
||||
|
||||
always @(posedge wb_clk)
|
||||
wb_ack_s2 <= wb_ack_s1a;
|
||||
|
||||
assign rf_we = rf_we_d;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Interface State Machine
|
||||
//
|
||||
|
||||
`ifdef USBF_ASYNC_RESET
|
||||
always @(posedge phy_clk or negedge rst)
|
||||
`else
|
||||
always @(posedge phy_clk)
|
||||
`endif
|
||||
if(!rst) state <= IDLE;
|
||||
else state <= next_state;
|
||||
|
||||
always @(state or wb_req_s1 or wb_addr_i or ma_ack or wb_we_i)
|
||||
begin
|
||||
next_state = state;
|
||||
ma_req = 1'b0;
|
||||
ma_we = 1'b0;
|
||||
wb_ack_d = 1'b0;
|
||||
rf_re = 1'b0;
|
||||
rf_we_d = 1'b0;
|
||||
|
||||
case(state) // synopsys full_case parallel_case
|
||||
IDLE:
|
||||
begin
|
||||
if(wb_req_s1 && `USBF_MEM_SEL && wb_we_i)
|
||||
begin
|
||||
ma_req = 1'b1;
|
||||
ma_we = 1'b1;
|
||||
next_state = MA_WR;
|
||||
end
|
||||
if(wb_req_s1 && `USBF_MEM_SEL && !wb_we_i)
|
||||
begin
|
||||
ma_req = 1'b1;
|
||||
next_state = MA_RD;
|
||||
end
|
||||
if(wb_req_s1 && `USBF_RF_SEL && wb_we_i)
|
||||
begin
|
||||
rf_we_d = 1'b1;
|
||||
next_state = W0;
|
||||
end
|
||||
if(wb_req_s1 && `USBF_RF_SEL && !wb_we_i)
|
||||
begin
|
||||
rf_re = 1'b1;
|
||||
next_state = W0;
|
||||
end
|
||||
end
|
||||
|
||||
MA_WR:
|
||||
begin
|
||||
if(!ma_ack)
|
||||
begin
|
||||
ma_req = 1'b1;
|
||||
ma_we = 1'b1;
|
||||
end
|
||||
else
|
||||
begin
|
||||
wb_ack_d = 1'b1;
|
||||
next_state = W1;
|
||||
end
|
||||
end
|
||||
|
||||
MA_RD:
|
||||
begin
|
||||
if(!ma_ack)
|
||||
begin
|
||||
ma_req = 1'b1;
|
||||
end
|
||||
else
|
||||
begin
|
||||
wb_ack_d = 1'b1;
|
||||
next_state = W1;
|
||||
end
|
||||
end
|
||||
|
||||
W0:
|
||||
begin
|
||||
wb_ack_d = 1'b1;
|
||||
next_state = W1;
|
||||
end
|
||||
|
||||
W1:
|
||||
begin
|
||||
next_state = W2;
|
||||
end
|
||||
|
||||
W2:
|
||||
begin
|
||||
next_state = IDLE;
|
||||
end
|
||||
|
||||
endcase
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
@@ -0,0 +1,129 @@
|
||||
###############################################################################
|
||||
#
|
||||
# Actual Synthesis Script
|
||||
#
|
||||
# This script does the actual synthesis
|
||||
#
|
||||
# Author: Rudolf Usselmann
|
||||
# rudi@asics.ws
|
||||
#
|
||||
# Revision:
|
||||
# 3/7/01 RU Initial Sript
|
||||
#
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
# ==============================================
|
||||
# Setup Design Parameters
|
||||
source ../bin/design_spec.dc
|
||||
|
||||
# ==============================================
|
||||
# Setup Libraries
|
||||
source ../bin/lib_spec.dc
|
||||
|
||||
# ==============================================
|
||||
# Setup File IO
|
||||
|
||||
set junk_file /dev/null
|
||||
append log_file ../log/$active_design "_cmp.log"
|
||||
append pre_comp_db_file ../out/$design_name "_pre.db"
|
||||
append post_comp_db_file ../out/$design_name ".db"
|
||||
append post_syn_verilog_file ../out/$design_name "_ps.v"
|
||||
|
||||
sh rm -f $log_file
|
||||
|
||||
# ==============================================
|
||||
# Setup Misc Variables
|
||||
|
||||
set hdlin_enable_vpp true ;# Important - this enables 'ifdefs
|
||||
|
||||
# Turn off automatic wire load selection, as this always (WHY ???) defaults to "zero_load"
|
||||
#set auto_wire_load_selection false
|
||||
|
||||
# ==============================================
|
||||
# Read Design
|
||||
|
||||
echo "+++++++++ Reading Design ..." >> $log_file
|
||||
read_file $pre_comp_db_file >> $log_file
|
||||
|
||||
# ==============================================
|
||||
# Operating conditions
|
||||
|
||||
echo "+++++++++ Setting up Operation Conditions ..." >> $log_file
|
||||
current_design $design_name
|
||||
set_operating_conditions WORST >> $log_file
|
||||
#set_wire_load_mode enclosed >> $log_file
|
||||
set_wire_load_mode top >> $log_file
|
||||
set_wire_load_model -name suggested_40K >> $log_file
|
||||
|
||||
# ==============================================
|
||||
# Setup Clocks and Resets
|
||||
|
||||
echo "+++++++++ Setting up Clocks ..." >> $log_file
|
||||
|
||||
set_drive 0 [find port {*clk_i}]
|
||||
|
||||
# !!! Phy Clock !!!
|
||||
set clock_period2 16
|
||||
create_clock -period $clock_period2 phy_clk
|
||||
set_clock_skew -uncertainty 0.5 phy_clk
|
||||
set_clock_transition 0.9 phy_clk
|
||||
set_dont_touch_network phy_clk
|
||||
|
||||
# !!! WISHBONE Clock !!!
|
||||
set clock_period 5
|
||||
create_clock -period $clock_period clk_i
|
||||
set_clock_skew -uncertainty 0.1 clk_i
|
||||
set_clock_transition 0.5 clk_i
|
||||
set_dont_touch_network clk_i
|
||||
|
||||
# !!! Reset !!!
|
||||
set_drive 0 [find port {rst*}]
|
||||
set_dont_touch_network [find port {rst*}]
|
||||
|
||||
# ==============================================
|
||||
# Setup IOs
|
||||
|
||||
echo "+++++++++ Setting up IOs ..." >> $log_file
|
||||
|
||||
# Need to spell out external IOs
|
||||
|
||||
set_driving_cell -cell NAND2D2 -pin Z [all_inputs] >> $junk_file
|
||||
set_load 0.2 [all_outputs]
|
||||
|
||||
set_input_delay -max 1 -clock clk_i [all_inputs]
|
||||
set_output_delay -max 1 -clock clk_i [all_outputs]
|
||||
|
||||
set_input_delay -max 1 -clock phy_clk [all_inputs]
|
||||
set_output_delay -max 1 -clock phy_clk [all_outputs]
|
||||
|
||||
# ==============================================
|
||||
# Setup Area Constrains
|
||||
set_max_area 0.0
|
||||
|
||||
# ==============================================
|
||||
# Force Ultra
|
||||
set_ultra_optimization -f
|
||||
|
||||
# ==============================================
|
||||
# Compile Design
|
||||
|
||||
echo "+++++++++ Starting Compile ..." >> $log_file
|
||||
#compile -map_effort medium -area_effort medium -ungroup_all >> $log_file
|
||||
compile -map_effort low -area_effort low >> $log_file
|
||||
#compile -map_effort high -area_effort high -auto_ungroup >> $log_file
|
||||
|
||||
# ==============================================
|
||||
# Write Out the optimized design
|
||||
|
||||
echo "+++++++++ Saving Optimized Design ..." >> $log_file
|
||||
write_file -format verilog -output $post_syn_verilog_file
|
||||
write_file -hierarchy -format db -output $post_comp_db_file
|
||||
|
||||
# ==============================================
|
||||
# Create Some Basic Reports
|
||||
|
||||
echo "+++++++++ Reporting Final Results ..." >> $log_file
|
||||
report_timing -nworst 10 >> $log_file
|
||||
report_area >> $log_file
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
###############################################################################
|
||||
#
|
||||
# Design Specification
|
||||
#
|
||||
# Author: Rudolf Usselmann
|
||||
# rudi@asics.ws
|
||||
#
|
||||
# Revision:
|
||||
# 3/7/01 RU Initial Sript
|
||||
#
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
# ==============================================
|
||||
# Setup Design Parameters
|
||||
|
||||
set design_files {usbf_crc5 usbf_crc16 usbf_mem_arb usbf_ep_rf usbf_pa usbf_ep_rf_dummy usbf_pd usbf_rf usbf_utmi_ls usbf_utmi_if usbf_idma usbf_pe usbf_wb usbf_pl usbf_top}
|
||||
set design_name usbf_top
|
||||
set active_design usbf_top
|
||||
|
||||
# Next Statement defines all clocks and resets in the design
|
||||
set special_net {rst_i clk_i phy_clk}
|
||||
|
||||
# Source Directory
|
||||
set hdl_src_dir ../../rtl/verilog/
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
###############################################################################
|
||||
#
|
||||
# Library Specification
|
||||
#
|
||||
# Author: Rudolf Usselmann
|
||||
# rudi@asics.ws
|
||||
#
|
||||
# Revision:
|
||||
# 3/7/01 RU Initial Sript
|
||||
#
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
# ==============================================
|
||||
# Setup Libraries
|
||||
|
||||
set search_path [list $search_path . \
|
||||
/tools/dc_libraries/umc/umc_0.18/UMCL18U250D2_2.1/design_compiler/ \
|
||||
$hdl_src_dir]
|
||||
|
||||
set snps [getenv "SYNOPSYS"]
|
||||
|
||||
set synthetic_library ""
|
||||
append synthetic_library $snps "/libraries/syn/dw01.sldb "
|
||||
append synthetic_library $snps "/libraries/syn/dw02.sldb "
|
||||
append synthetic_library $snps "/libraries/syn/dw03.sldb "
|
||||
append synthetic_library $snps "/libraries/syn/dw04.sldb "
|
||||
append synthetic_library $snps "/libraries/syn/dw05.sldb "
|
||||
append synthetic_library $snps "/libraries/syn/dw06.sldb "
|
||||
append synthetic_library $snps "/libraries/syn/dw07.sldb "
|
||||
|
||||
set target_library { umcl18u250t2_typ.db }
|
||||
set link_library ""
|
||||
append link_library $target_library " " $synthetic_library
|
||||
set symbol_library { umcl18u250t2.sdb }
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
###############################################################################
|
||||
#
|
||||
# Pre Synthesis Script
|
||||
#
|
||||
# This script only reads in the design and saves it in a DB file
|
||||
#
|
||||
# Author: Rudolf Usselmann
|
||||
# rudi@asics.ws
|
||||
#
|
||||
# Revision:
|
||||
# 3/7/01 RU Initial Sript
|
||||
#
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
# ==============================================
|
||||
# Setup Design Parameters
|
||||
source ../bin/design_spec.dc
|
||||
|
||||
# ==============================================
|
||||
# Setup Libraries
|
||||
source ../bin/lib_spec.dc
|
||||
|
||||
# ==============================================
|
||||
# Setup File IO
|
||||
|
||||
append log_file ../log/$active_design "_pre.log"
|
||||
append pre_comp_db_file ../out/$design_name "_pre.db"
|
||||
sh rm -f $log_file
|
||||
|
||||
# ==============================================
|
||||
# Setup Misc Variables
|
||||
|
||||
set hdlin_enable_vpp true ;# Important - this enables 'ifdefs
|
||||
|
||||
# ==============================================
|
||||
# Read Design
|
||||
|
||||
echo "+++++++++ Analyzing all design files ..." >> $log_file
|
||||
|
||||
foreach module $design_files {
|
||||
echo "+++++++++ Reading: $module" >> $log_file
|
||||
echo +++++++++ Reading: $module
|
||||
set module_file_name ""
|
||||
append module_file_name $module ".v"
|
||||
analyze -f verilog $module_file_name >> $log_file
|
||||
elaborate $module >> $log_file
|
||||
}
|
||||
|
||||
set current_design $active_design
|
||||
|
||||
echo "+++++++++ Linking Design ..." >> $log_file
|
||||
link >> $log_file
|
||||
|
||||
echo "+++++++++ Uniquifying Design ..." >> $log_file
|
||||
uniquify >> $log_file
|
||||
|
||||
echo "+++++++++ Checking Design ..." >> $log_file
|
||||
check_design >> $log_file
|
||||
|
||||
# ==============================================
|
||||
# Save Design
|
||||
echo "+++++++++ Saving Design ..." >> $log_file
|
||||
write_file -hierarchy -format db -output $pre_comp_db_file
|
||||
|
||||
|
||||
Reference in New Issue
Block a user